Gentoo Archives: gentoo-commits

From: "Gordon Malm (gengor)" <gengor@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1482 - in hardened/2.6/tags: . 2.6.26-10
Date: Wed, 21 Jan 2009 00:14:03
Message-Id: E1LPQgj-0000Oj-RX@stork.gentoo.org
1 Author: gengor
2 Date: 2009-01-21 00:11:21 +0000 (Wed, 21 Jan 2009)
3 New Revision: 1482
4
5 Added:
6 hardened/2.6/tags/2.6.26-10/
7 hardened/2.6/tags/2.6.26-10/0000_README
8 hardened/2.6/tags/2.6.26-10/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
9 hardened/2.6/tags/2.6.26-10/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
10 hardened/2.6/tags/2.6.26-10/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
11 hardened/2.6/tags/2.6.26-10/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
12 hardened/2.6/tags/2.6.26-10/1405_i-oat-fix-async_tx.callback-checking.patch
13 hardened/2.6/tags/2.6.26-10/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
14 hardened/2.6/tags/2.6.26-10/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
15 hardened/2.6/tags/2.6.26-10/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
16 hardened/2.6/tags/2.6.26-10/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
17 hardened/2.6/tags/2.6.26-10/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch
18 hardened/2.6/tags/2.6.26-10/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
19 hardened/2.6/tags/2.6.26-10/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch
20 hardened/2.6/tags/2.6.26-10/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
21 hardened/2.6/tags/2.6.26-10/1414_acpi-avoid-empty-file-name-in-sysfs.patch
22 hardened/2.6/tags/2.6.26-10/1415_block-fix-nr_phys_segments-miscalculation-bug.patch
23 hardened/2.6/tags/2.6.26-10/1416_dm-raid1-flush-workqueue-before-destruction.patch
24 hardened/2.6/tags/2.6.26-10/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch
25 hardened/2.6/tags/2.6.26-10/1418_touch_mnt_namespace-when-the-mount-flags-change.patch
26 hardened/2.6/tags/2.6.26-10/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
27 hardened/2.6/tags/2.6.26-10/1420_usb-ehci-fix-divide-by-zero-bug.patch
28 hardened/2.6/tags/2.6.26-10/1421_usb-ehci-fix-handling-of-dead-controllers.patch
29 hardened/2.6/tags/2.6.26-10/1422_usb-fix-ps3-usb-shutdown-problems.patch
30 hardened/2.6/tags/2.6.26-10/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
31 hardened/2.6/tags/2.6.26-10/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
32 hardened/2.6/tags/2.6.26-10/1425_enforce-a-minimum-sg_io-timeout.patch
33 hardened/2.6/tags/2.6.26-10/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
34 hardened/2.6/tags/2.6.26-10/4420_grsec-2.1.12-2.6.26.6-200810131006.patch
35 hardened/2.6/tags/2.6.26-10/4421_grsec-remove-localversion-grsec.patch
36 hardened/2.6/tags/2.6.26-10/4422_grsec-mute-warnings.patch
37 hardened/2.6/tags/2.6.26-10/4425_grsec-pax-without-grsec.patch
38 hardened/2.6/tags/2.6.26-10/4430_grsec-kconfig-default-gids.patch
39 hardened/2.6/tags/2.6.26-10/4435_grsec-kconfig-gentoo.patch
40 hardened/2.6/tags/2.6.26-10/4440_selinux-avc_audit-log-curr_ip.patch
41 hardened/2.6/tags/2.6.26-10/4445_disable-compat_vdso.patch
42 hardened/2.6/tags/2.6.26-10/4450_pax-2.6.26.7-test32-to-test33.patch
43 hardened/2.6/tags/2.6.26-10/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch
44 hardened/2.6/tags/2.6.26-10/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
45 Log:
46 Tag 2.6.26-10 hardened-extras patchset
47
48 Added: hardened/2.6/tags/2.6.26-10/0000_README
49 ===================================================================
50 --- hardened/2.6/tags/2.6.26-10/0000_README (rev 0)
51 +++ hardened/2.6/tags/2.6.26-10/0000_README 2009-01-21 00:11:21 UTC (rev 1482)
52 @@ -0,0 +1,74 @@
53 +README
54 +-----------------------------------------------------------------------------
55 +
56 +Individual Patch Descriptions:
57 +-----------------------------------------------------------------------------
58 +Patch: 1401* -> 1413*
59 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
60 + a=commit;h=ff413e9814b3914ddf3d4634e9a6cc1c6b21e787
61 +Desc: Backported subset of 2.6.27.6 -stable release patches
62 +
63 +Patch: 1414* -> 1423*
64 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
65 + a=commit;h=526550b7f86d9d395ee1b27ed804e6ffc3feb17c
66 +Desc: Backported subset of 2.6.27.7 -stable release patches
67 +
68 +Patch: 1424* -> 1425*
69 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
70 + a=commit;h=2ef6627be7502193f7c42f694a651fa710507089
71 +Desc: Backported subset of 2.6.27.9 -stable release patches
72 +
73 +Patch: 1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
74 +From: Wei Yongjun <yjwei@××××××××××.com>
75 +Desc: Avoid memory overflow while FWD-TSN chunk received with bad stream ID
76 + (bug #254907)
77 +
78 +Patch: 4420_grsec-2.1.12-2.6.26.6-200810131006.patch
79 +From: http://www.grsecurity.net
80 +Desc: hardened-sources base patch from upstream grsecurity
81 +
82 +Patch: 4421_grsec-remove-localversion-grsec.patch
83 +From: Kerin Millar <kerframil@×××××.com>
84 +Desc: Removes grsecurity's localversion-grsec file
85 +
86 +Patch: 4422_grsec-mute-warnings.patch
87 +From: Alexander Gabert <gaberta@××××××××.de>
88 + Gordon Malm <gengor@g.o>
89 +Desc: Removes verbose compile warning settings from grsecurity, restores
90 + mainline Linux kernel behavior
91 +
92 +Patch: 4425_grsec-pax-without-grsec.patch
93 +From: Gordon Malm <gengor@g.o>
94 +Desc: Allows PaX features to be selected without enabling GRKERNSEC
95 +
96 +Patch: 4430_grsec-kconfig-default-gids.patch
97 +From: Kerin Millar <kerframil@×××××.com>
98 +Desc: Sets sane(r) default GIDs on various grsecurity group-dependent
99 + features
100 +
101 +Patch: 4435_grsec-kconfig-gentoo.patch
102 +From: Gordon Malm <gengor@g.o>
103 + Kerin Millar <kerframil@×××××.com>
104 +Desc: Adds Hardened Gentoo [server/workstation] security levels, sets
105 + Hardened Gentoo [workstation] as default
106 +
107 +Patch: 4440_selinux-avc_audit-log-curr_ip.patch
108 +From: Gordon Malm <gengor@g.o>
109 +Desc: Configurable option to add src IP address to SELinux log messages
110 +
111 +Patch: 4445_disable-compat_vdso.patch
112 +From: Gordon Malm <gengor@g.o>
113 + Kerin Millar <kerframil@×××××.com>
114 +Desc: Disables VDSO_COMPAT operation completely
115 +
116 +Patch: 4450_pax-2.6.26.7-test32-to-test33.patch
117 +From: Gordon Malm <gengor@g.o>
118 +Desc: Adds PaX changes from pax-2.6.26.7-test33
119 +
120 +Patch: 4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch
121 +From: Gordon Malm <gengor@g.o>
122 +Desc: Make selection of PAX_REFCOUNT depend on X86 (bug #246763)
123 +
124 +Patch: 4460_pax-fix-mmap-BUG_ON-task-size-check.patch
125 +From: Gordon Malm <gengor@g.o>
126 +Desc: Fix incorrect vma task size check under SEGMEXEC
127
128 Added: hardened/2.6/tags/2.6.26-10/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
129 ===================================================================
130 --- hardened/2.6/tags/2.6.26-10/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch (rev 0)
131 +++ hardened/2.6/tags/2.6.26-10/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch 2009-01-21 00:11:21 UTC (rev 1482)
132 @@ -0,0 +1,65 @@
133 +Added-By: Gordon Malm <gengor@g.o>
134 +
135 +---
136 +
137 +From jejb@××××××.org Mon Nov 10 15:14:35 2008
138 +From: Li Zefan <lizf@××××××××××.com>
139 +Date: Fri, 7 Nov 2008 00:05:48 GMT
140 +Subject: cgroups: fix invalid cgrp->dentry before cgroup has been completely removed
141 +To: stable@××××××.org
142 +Message-ID: <200811070005.mA705mbU003066@×××××××××××.org>
143 +
144 +From: Li Zefan <lizf@××××××××××.com>
145 +
146 +commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream
147 +
148 +This fixes an oops when reading /proc/sched_debug.
149 +
150 +A cgroup won't be removed completely until finishing cgroup_diput(), so we
151 +shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a
152 +group is being removed while cgroup_path() gets called, we may trigger
153 +NULL dereference BUG.
154 +
155 +The bug can be reproduced:
156 +
157 + # cat test.sh
158 + #!/bin/sh
159 + mount -t cgroup -o cpu xxx /mnt
160 + for (( ; ; ))
161 + {
162 + mkdir /mnt/sub
163 + rmdir /mnt/sub
164 + }
165 + # ./test.sh &
166 + # cat /proc/sched_debug
167 +
168 +BUG: unable to handle kernel NULL pointer dereference at 00000038
169 +IP: [<c045a47f>] cgroup_path+0x39/0x90
170 +..
171 +Call Trace:
172 + [<c0420344>] ? print_cfs_rq+0x6e/0x75d
173 + [<c0421160>] ? sched_debug_show+0x72d/0xc1e
174 +..
175 +
176 +Signed-off-by: Li Zefan <lizf@××××××××××.com>
177 +Acked-by: Paul Menage <menage@××××××.com>
178 +Cc: Peter Zijlstra <a.p.zijlstra@××××××.nl>
179 +Cc: Ingo Molnar <mingo@××××.hu>
180 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
181 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
182 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
183 +
184 +---
185 + kernel/cgroup.c | 1 -
186 + 1 file changed, 1 deletion(-)
187 +
188 +--- a/kernel/cgroup.c
189 ++++ b/kernel/cgroup.c
190 +@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *un
191 + list_del(&cgrp->sibling);
192 + spin_lock(&cgrp->dentry->d_lock);
193 + d = dget(cgrp->dentry);
194 +- cgrp->dentry = NULL;
195 + spin_unlock(&d->d_lock);
196 +
197 + cgroup_d_remove_dir(d);
198
199 Added: hardened/2.6/tags/2.6.26-10/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
200 ===================================================================
201 --- hardened/2.6/tags/2.6.26-10/1402_cpqarry-fix-return-value-of-cpqarray_init.patch (rev 0)
202 +++ hardened/2.6/tags/2.6.26-10/1402_cpqarry-fix-return-value-of-cpqarray_init.patch 2009-01-21 00:11:21 UTC (rev 1482)
203 @@ -0,0 +1,55 @@
204 +Added-By: Gordon Malm <gengor@g.o>
205 +
206 +---
207 +
208 +From 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 Mon Sep 17 00:00:00 2001
209 +From: Andrey Borzenkov <arvidjaar@××××.ru>
210 +Date: Thu, 6 Nov 2008 12:53:15 -0800
211 +Subject: cpqarry: fix return value of cpqarray_init()
212 +
213 +From: Andrey Borzenkov <arvidjaar@××××.ru>
214 +
215 +commit 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 upstream.
216 +
217 +As reported by Dick Gevers on Compaq ProLiant:
218 +
219 +Oct 13 18:06:51 dvgcpl kernel: Compaq SMART2 Driver (v 2.6.0)
220 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: 'cpqarray'->init
221 +suspiciously returned 1, it should follow 0/-E convention
222 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: loading module anyway...
223 +Oct 13 18:06:51 dvgcpl kernel: Pid: 315, comm: modprobe Not tainted
224 +2.6.27-desktop-0.rc8.2mnb #1
225 +Oct 13 18:06:51 dvgcpl kernel: [<c0380612>] ? printk+0x18/0x1e
226 +Oct 13 18:06:51 dvgcpl kernel: [<c0158f85>] sys_init_module+0x155/0x1c0
227 +Oct 13 18:06:51 dvgcpl kernel: [<c0103f06>] syscall_call+0x7/0xb
228 +Oct 13 18:06:51 dvgcpl kernel: =======================
229 +
230 +Make it return 0 on success and -ENODEV if no array was found.
231 +
232 +Reported-by: Dick Gevers <dvgevers@××××××.nl>
233 +Signed-off-by: Andrey Borzenkov <arvidjaar@××××.ru>
234 +Cc: Jens Axboe <jens.axboe@××××××.com>
235 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
236 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
237 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
238 +
239 +---
240 + drivers/block/cpqarray.c | 7 ++++++-
241 + 1 file changed, 6 insertions(+), 1 deletion(-)
242 +
243 +--- a/drivers/block/cpqarray.c
244 ++++ b/drivers/block/cpqarray.c
245 +@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
246 + num_cntlrs_reg++;
247 + }
248 +
249 +- return(num_cntlrs_reg);
250 ++ if (num_cntlrs_reg)
251 ++ return 0;
252 ++ else {
253 ++ pci_unregister_driver(&cpqarray_pci_driver);
254 ++ return -ENODEV;
255 ++ }
256 + }
257 +
258 + /* Function to find the first free pointer into our hba[] array */
259
260 Added: hardened/2.6/tags/2.6.26-10/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
261 ===================================================================
262 --- hardened/2.6/tags/2.6.26-10/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch (rev 0)
263 +++ hardened/2.6/tags/2.6.26-10/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch 2009-01-21 00:11:21 UTC (rev 1482)
264 @@ -0,0 +1,82 @@
265 +Added-By: Gordon Malm <gengor@g.o>
266 +
267 +---
268 +
269 +From jejb@××××××.org Mon Nov 10 15:08:55 2008
270 +From: Arthur Jones <ajones@××××××××.com>
271 +Date: Fri, 7 Nov 2008 00:05:17 GMT
272 +Subject: ext3: wait on all pending commits in ext3_sync_fs
273 +To: stable@××××××.org
274 +Message-ID: <200811070005.mA705Htq002320@×××××××××××.org>
275 +
276 +From: Arthur Jones <ajones@××××××××.com>
277 +
278 +commit c87591b719737b4e91eb1a9fa8fd55a4ff1886d6 upstream
279 +
280 +In ext3_sync_fs, we only wait for a commit to finish if we started it, but
281 +there may be one already in progress which will not be synced.
282 +
283 +In the case of a data=ordered umount with pending long symlinks which are
284 +delayed due to a long list of other I/O on the backing block device, this
285 +causes the buffer associated with the long symlinks to not be moved to the
286 +inode dirty list in the second phase of fsync_super. Then, before they
287 +can be dirtied again, kjournald exits, seeing the UMOUNT flag and the
288 +dirty pages are never written to the backing block device, causing long
289 +symlink corruption and exposing new or previously freed block data to
290 +userspace.
291 +
292 +This can be reproduced with a script created
293 +by Eric Sandeen <sandeen@××××××.com>:
294 +
295 + #!/bin/bash
296 +
297 + umount /mnt/test2
298 + mount /dev/sdb4 /mnt/test2
299 + rm -f /mnt/test2/*
300 + dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512
301 + touch
302 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
303 + ln -s
304 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
305 + /mnt/test2/link
306 + umount /mnt/test2
307 + mount /dev/sdb4 /mnt/test2
308 + ls /mnt/test2/
309 + umount /mnt/test2
310 +
311 +To ensure all commits are synced, we flush all journal commits now when
312 +sync_fs'ing ext3.
313 +
314 +Signed-off-by: Arthur Jones <ajones@××××××××.com>
315 +Cc: Eric Sandeen <sandeen@××××××.com>
316 +Cc: Theodore Ts'o <tytso@×××.edu>
317 +Cc: <linux-ext4@×××××××××××.org>
318 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
319 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
320 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
321 +
322 +---
323 + fs/ext3/super.c | 11 +++++------
324 + 1 file changed, 5 insertions(+), 6 deletions(-)
325 +
326 +--- a/fs/ext3/super.c
327 ++++ b/fs/ext3/super.c
328 +@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct sup
329 +
330 + static int ext3_sync_fs(struct super_block *sb, int wait)
331 + {
332 +- tid_t target;
333 +-
334 + sb->s_dirt = 0;
335 +- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
336 +- if (wait)
337 +- log_wait_commit(EXT3_SB(sb)->s_journal, target);
338 +- }
339 ++ if (wait)
340 ++ ext3_force_commit(sb);
341 ++ else
342 ++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
343 ++
344 + return 0;
345 + }
346 +
347
348 Added: hardened/2.6/tags/2.6.26-10/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
349 ===================================================================
350 --- hardened/2.6/tags/2.6.26-10/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch (rev 0)
351 +++ hardened/2.6/tags/2.6.26-10/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch 2009-01-21 00:11:21 UTC (rev 1482)
352 @@ -0,0 +1,48 @@
353 +Added-By: Gordon Malm <gengor@g.o>
354 +
355 +---
356 +
357 +From jkosina@××××.cz Tue Nov 11 15:52:41 2008
358 +From: Jiri Kosina <jkosina@××××.cz>
359 +Date: Tue, 11 Nov 2008 23:45:38 +0100 (CET)
360 +Subject: HID: fix incorrent length condition in hidraw_write()
361 +To: stable@××××××.org
362 +Cc: Paul Stoffregen <paul@××××.com>
363 +Message-ID: <alpine.LNX.1.10.0811112344180.24889@××××××××××.cz>
364 +
365 +From: Jiri Kosina <jkosina@××××.cz>
366 +
367 +upstream commit 2b107d629dc0c35de606bb7b010b829cd247a93a
368 +
369 +From: Jiri Kosina <jkosina@××××.cz>
370 +
371 +The bound check on the buffer length
372 +
373 + if (count > HID_MIN_BUFFER_SIZE)
374 +
375 +is of course incorrent, the proper check is
376 +
377 + if (count > HID_MAX_BUFFER_SIZE)
378 +
379 +Fix it.
380 +
381 +Reported-by: Jerry Ryle <jerry@×××××××××.com>
382 +Signed-off-by: Jiri Kosina <jkosina@××××.cz>
383 +Cc: Paul Stoffregen <paul@××××.com>
384 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
385 +
386 +---
387 + drivers/hid/hidraw.c | 2 +-
388 + 1 file changed, 1 insertion(+), 1 deletion(-)
389 +
390 +--- a/drivers/hid/hidraw.c
391 ++++ b/drivers/hid/hidraw.c
392 +@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file
393 + if (!dev->hid_output_raw_report)
394 + return -ENODEV;
395 +
396 +- if (count > HID_MIN_BUFFER_SIZE) {
397 ++ if (count > HID_MAX_BUFFER_SIZE) {
398 + printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
399 + task_pid_nr(current));
400 + return -EINVAL;
401
402 Added: hardened/2.6/tags/2.6.26-10/1405_i-oat-fix-async_tx.callback-checking.patch
403 ===================================================================
404 --- hardened/2.6/tags/2.6.26-10/1405_i-oat-fix-async_tx.callback-checking.patch (rev 0)
405 +++ hardened/2.6/tags/2.6.26-10/1405_i-oat-fix-async_tx.callback-checking.patch 2009-01-21 00:11:21 UTC (rev 1482)
406 @@ -0,0 +1,48 @@
407 +Added-By: Gordon Malm <gengor@g.o>
408 +
409 +Note: Backported to earlier kernels. Original message included below.
410 +
411 +---
412 +
413 +From jejb@××××××.org Tue Nov 11 10:17:05 2008
414 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
415 +Date: Tue, 11 Nov 2008 17:50:05 GMT
416 +Subject: I/OAT: fix async_tx.callback checking
417 +To: jejb@××××××.org, stable@××××××.org
418 +Message-ID: <200811111750.mABHo5Ai025612@×××××××××××.org>
419 +
420 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
421 +
422 +commit 12ccea24e309d815d058cdc6ee8bf2c4b85f0c5f upstream
423 +
424 +async_tx.callback should be checked for the first
425 +not the last descriptor in the chain.
426 +
427 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
428 +Signed-off-by: David S. Miller <davem@×××××××××.net>
429 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
430 +
431 +---
432 + drivers/dma/ioat_dma.c | 4 ++--
433 + 1 file changed, 2 insertions(+), 2 deletions(-)
434 +
435 +--- a/drivers/dma/ioat_dma.c
436 ++++ b/drivers/dma/ioat_dma.c
437 +@@ -251,7 +251,7 @@ static dma_cookie_t ioat1_tx_submit(stru
438 + } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan)));
439 +
440 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
441 +- if (new->async_tx.callback) {
442 ++ if (first->async_tx.callback) {
443 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
444 + if (first != new) {
445 + /* move callback into to last desc */
446 +@@ -336,7 +336,7 @@ static dma_cookie_t ioat2_tx_submit(stru
447 + } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan)));
448 +
449 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
450 +- if (new->async_tx.callback) {
451 ++ if (first->async_tx.callback) {
452 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
453 + if (first != new) {
454 + /* move callback into to last desc */
455
456 Added: hardened/2.6/tags/2.6.26-10/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
457 ===================================================================
458 --- hardened/2.6/tags/2.6.26-10/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch (rev 0)
459 +++ hardened/2.6/tags/2.6.26-10/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch 2009-01-21 00:11:21 UTC (rev 1482)
460 @@ -0,0 +1,54 @@
461 +Added-By: Gordon Malm <gengor@g.o>
462 +
463 +Note: Backported to earlier kernels. Original message below.
464 +
465 +---
466 +
467 +From jejb@××××××.org Tue Nov 11 10:15:37 2008
468 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
469 +Date: Tue, 11 Nov 2008 17:50:09 GMT
470 +Subject: I/OAT: fix channel resources free for not allocated channels
471 +To: stable@××××××.org
472 +Message-ID: <200811111750.mABHo9IU025655@×××××××××××.org>
473 +
474 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
475 +
476 +commit c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca upstream
477 +
478 +If the ioatdma driver is loaded but not used it does not allocate descriptors.
479 +Before it frees channel resources it should first be sure
480 +that they have been previously allocated.
481 +
482 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
483 +Tested-by: Tom Picard <tom.s.picard@×××××.com>
484 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
485 +Signed-off-by: David S. Miller <davem@×××××××××.net>
486 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
487 +
488 +---
489 + drivers/dma/ioat_dma.c | 7 +++++++
490 + 1 file changed, 7 insertions(+)
491 +
492 +--- a/drivers/dma/ioat_dma.c
493 ++++ b/drivers/dma/ioat_dma.c
494 +@@ -524,6 +524,12 @@ static void ioat_dma_free_chan_resources
495 + struct ioat_desc_sw *desc, *_desc;
496 + int in_use_descs = 0;
497 +
498 ++ /* Before freeing channel resources first check
499 ++ * if they have been previously allocated for this channel.
500 ++ */
501 ++ if (ioat_chan->desccount == 0)
502 ++ return;
503 ++
504 + tasklet_disable(&ioat_chan->cleanup_task);
505 + ioat_dma_memcpy_cleanup(ioat_chan);
506 +
507 +@@ -585,6 +591,7 @@ static void ioat_dma_free_chan_resources
508 + ioat_chan->last_completion = ioat_chan->completion_addr = 0;
509 + ioat_chan->pending = 0;
510 + ioat_chan->dmacount = 0;
511 ++ ioat_chan->desccount = 0;
512 + }
513 +
514 + /**
515
516 Added: hardened/2.6/tags/2.6.26-10/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
517 ===================================================================
518 --- hardened/2.6/tags/2.6.26-10/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch (rev 0)
519 +++ hardened/2.6/tags/2.6.26-10/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch 2009-01-21 00:11:21 UTC (rev 1482)
520 @@ -0,0 +1,89 @@
521 +Added-By: Gordon Malm <gengor@g.o>
522 +
523 +---
524 +
525 +From jejb@××××××.org Tue Nov 11 10:16:31 2008
526 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
527 +Date: Tue, 11 Nov 2008 17:50:07 GMT
528 +Subject: I/OAT: fix dma_pin_iovec_pages() error handling
529 +To: stable@××××××.org
530 +Message-ID: <200811111750.mABHo7v5025633@×××××××××××.org>
531 +
532 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
533 +
534 +commit c2c0b4c5434c0a25f7f7796b29155d53805909f5 upstream
535 +
536 +Error handling needs to be modified in dma_pin_iovec_pages().
537 +It should return NULL instead of ERR_PTR
538 +(pinned_list is checked for NULL in tcp_recvmsg() to determine
539 +if iovec pages have been successfully pinned down).
540 +In case of error for the first iovec,
541 +local_list->nr_iovecs needs to be initialized.
542 +
543 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
544 +Signed-off-by: David S. Miller <davem@×××××××××.net>
545 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
546 +
547 +---
548 + drivers/dma/iovlock.c | 17 ++++++-----------
549 + 1 file changed, 6 insertions(+), 11 deletions(-)
550 +
551 +--- a/drivers/dma/iovlock.c
552 ++++ b/drivers/dma/iovlock.c
553 +@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pa
554 + int nr_iovecs = 0;
555 + int iovec_len_used = 0;
556 + int iovec_pages_used = 0;
557 +- long err;
558 +
559 + /* don't pin down non-user-based iovecs */
560 + if (segment_eq(get_fs(), KERNEL_DS))
561 +@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa
562 + local_list = kmalloc(sizeof(*local_list)
563 + + (nr_iovecs * sizeof (struct dma_page_list))
564 + + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
565 +- if (!local_list) {
566 +- err = -ENOMEM;
567 ++ if (!local_list)
568 + goto out;
569 +- }
570 +
571 + /* list of pages starts right after the page list array */
572 + pages = (struct page **) &local_list->page_list[nr_iovecs];
573 +
574 ++ local_list->nr_iovecs = 0;
575 ++
576 + for (i = 0; i < nr_iovecs; i++) {
577 + struct dma_page_list *page_list = &local_list->page_list[i];
578 +
579 + len -= iov[i].iov_len;
580 +
581 +- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
582 +- err = -EFAULT;
583 ++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
584 + goto unpin;
585 +- }
586 +
587 + page_list->nr_pages = num_pages_spanned(&iov[i]);
588 + page_list->base_address = iov[i].iov_base;
589 +@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa
590 + NULL);
591 + up_read(&current->mm->mmap_sem);
592 +
593 +- if (ret != page_list->nr_pages) {
594 +- err = -ENOMEM;
595 ++ if (ret != page_list->nr_pages)
596 + goto unpin;
597 +- }
598 +
599 + local_list->nr_iovecs = i + 1;
600 + }
601 +@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa
602 + unpin:
603 + dma_unpin_iovec_pages(local_list);
604 + out:
605 +- return ERR_PTR(err);
606 ++ return NULL;
607 + }
608 +
609 + void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
610
611 Added: hardened/2.6/tags/2.6.26-10/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
612 ===================================================================
613 --- hardened/2.6/tags/2.6.26-10/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch (rev 0)
614 +++ hardened/2.6/tags/2.6.26-10/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch 2009-01-21 00:11:21 UTC (rev 1482)
615 @@ -0,0 +1,51 @@
616 +Added-By: Gordon Malm <gengor@g.o>
617 +
618 +---
619 +
620 +From jejb@××××××.org Tue Nov 11 09:53:44 2008
621 +From: David Woodhouse <David.Woodhouse@×××××.com>
622 +Date: Fri, 7 Nov 2008 00:08:59 GMT
623 +Subject: JFFS2: Fix lack of locking in thread_should_wake()
624 +To: stable@××××××.org
625 +Message-ID: <200811070008.mA708xQE008191@×××××××××××.org>
626 +
627 +From: David Woodhouse <David.Woodhouse@×××××.com>
628 +
629 +commit b27cf88e9592953ae292d05324887f2f44979433 upstream
630 +
631 +The thread_should_wake() function trawls through the list of 'very
632 +dirty' eraseblocks, determining whether the background GC thread should
633 +wake. Doing this without holding the appropriate locks is a bad idea.
634 +
635 +OLPC Trac #8615
636 +
637 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
638 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
639 +
640 +---
641 + fs/jffs2/background.c | 10 +++++-----
642 + 1 file changed, 5 insertions(+), 5 deletions(-)
643 +
644 +--- a/fs/jffs2/background.c
645 ++++ b/fs/jffs2/background.c
646 +@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(
647 + for (;;) {
648 + allow_signal(SIGHUP);
649 + again:
650 ++ spin_lock(&c->erase_completion_lock);
651 + if (!jffs2_thread_should_wake(c)) {
652 + set_current_state (TASK_INTERRUPTIBLE);
653 ++ spin_unlock(&c->erase_completion_lock);
654 + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
655 +- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
656 +- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
657 +- matter - We don't care if we miss a wakeup, because the GC thread
658 +- is only an optimisation anyway. */
659 + schedule();
660 +- }
661 ++ } else
662 ++ spin_unlock(&c->erase_completion_lock);
663 ++
664 +
665 + /* This thread is purely an optimisation. But if it runs when
666 + other things could be running, it actually makes things a
667
668 Added: hardened/2.6/tags/2.6.26-10/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
669 ===================================================================
670 --- hardened/2.6/tags/2.6.26-10/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch (rev 0)
671 +++ hardened/2.6/tags/2.6.26-10/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch 2009-01-21 00:11:21 UTC (rev 1482)
672 @@ -0,0 +1,70 @@
673 +Added-By: Gordon Malm <gengor@g.o>
674 +
675 +---
676 +
677 +From jejb@××××××.org Tue Nov 11 09:53:08 2008
678 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
679 +Date: Fri, 7 Nov 2008 00:08:19 GMT
680 +Subject: JFFS2: fix race condition in jffs2_lzo_compress()
681 +To: stable@××××××.org
682 +Message-ID: <200811070008.mA708Jdo007031@×××××××××××.org>
683 +
684 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
685 +
686 +commit dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 upstream
687 +
688 +deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However,
689 +jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the
690 +compressed data from lzo_compress_buf. Correct this by moving the mutex
691 +unlock after the copy.
692 +
693 +In addition, document what deflate_mutex actually protects.
694 +
695 +Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
696 +Acked-by: Richard Purdie <rpurdie@××××××××××.com>
697 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
698 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
699 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
700 +
701 +---
702 + fs/jffs2/compr_lzo.c | 15 +++++++++------
703 + 1 file changed, 9 insertions(+), 6 deletions(-)
704 +
705 +--- a/fs/jffs2/compr_lzo.c
706 ++++ b/fs/jffs2/compr_lzo.c
707 +@@ -19,7 +19,7 @@
708 +
709 + static void *lzo_mem;
710 + static void *lzo_compress_buf;
711 +-static DEFINE_MUTEX(deflate_mutex);
712 ++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
713 +
714 + static void free_workspace(void)
715 + {
716 +@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned c
717 +
718 + mutex_lock(&deflate_mutex);
719 + ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
720 +- mutex_unlock(&deflate_mutex);
721 +-
722 + if (ret != LZO_E_OK)
723 +- return -1;
724 ++ goto fail;
725 +
726 + if (compress_size > *dstlen)
727 +- return -1;
728 ++ goto fail;
729 +
730 + memcpy(cpage_out, lzo_compress_buf, compress_size);
731 +- *dstlen = compress_size;
732 ++ mutex_unlock(&deflate_mutex);
733 +
734 ++ *dstlen = compress_size;
735 + return 0;
736 ++
737 ++ fail:
738 ++ mutex_unlock(&deflate_mutex);
739 ++ return -1;
740 + }
741 +
742 + static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
743
744 Added: hardened/2.6/tags/2.6.26-10/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch
745 ===================================================================
746 --- hardened/2.6/tags/2.6.26-10/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch (rev 0)
747 +++ hardened/2.6/tags/2.6.26-10/1410_keys-make-request-key-instantiate-the-per-user-keyrings.patch 2009-01-21 00:11:21 UTC (rev 1482)
748 @@ -0,0 +1,63 @@
749 +Added-By: Gordon Malm <gengor@g.o>
750 +
751 +---
752 +
753 +From 1f8f5cf6e4f038552a3e47b66085452c08556d71 Mon Sep 17 00:00:00 2001
754 +From: David Howells <dhowells@××××××.com>
755 +Date: Mon, 10 Nov 2008 19:00:05 +0000
756 +Subject: KEYS: Make request key instantiate the per-user keyrings
757 +
758 +From: David Howells <dhowells@××××××.com>
759 +
760 +commit 1f8f5cf6e4f038552a3e47b66085452c08556d71 upstream
761 +
762 +Make request_key() instantiate the per-user keyrings so that it doesn't oops
763 +if it needs to get hold of the user session keyring because there isn't a
764 +session keyring in place.
765 +
766 +Signed-off-by: David Howells <dhowells@××××××.com>
767 +Tested-by: Steve French <smfrench@×××××.com>
768 +Tested-by: Rutger Nijlunsing <rutger.nijlunsing@×××××.com>
769 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
770 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
771 +
772 +---
773 + security/keys/internal.h | 1 +
774 + security/keys/process_keys.c | 2 +-
775 + security/keys/request_key.c | 4 ++++
776 + 3 files changed, 6 insertions(+), 1 deletion(-)
777 +
778 +--- a/security/keys/internal.h
779 ++++ b/security/keys/internal.h
780 +@@ -107,6 +107,7 @@ extern key_ref_t search_process_keyrings
781 +
782 + extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check);
783 +
784 ++extern int install_user_keyrings(struct task_struct *tsk);
785 + extern int install_thread_keyring(struct task_struct *tsk);
786 + extern int install_process_keyring(struct task_struct *tsk);
787 +
788 +--- a/security/keys/process_keys.c
789 ++++ b/security/keys/process_keys.c
790 +@@ -40,7 +40,7 @@ struct key_user root_key_user = {
791 + /*
792 + * install user and user session keyrings for a particular UID
793 + */
794 +-static int install_user_keyrings(struct task_struct *tsk)
795 ++int install_user_keyrings(struct task_struct *tsk)
796 + {
797 + struct user_struct *user = tsk->user;
798 + struct key *uid_keyring, *session_keyring;
799 +--- a/security/keys/request_key.c
800 ++++ b/security/keys/request_key.c
801 +@@ -74,6 +74,10 @@ static int call_sbin_request_key(struct
802 +
803 + kenter("{%d},{%d},%s", key->serial, authkey->serial, op);
804 +
805 ++ ret = install_user_keyrings(tsk);
806 ++ if (ret < 0)
807 ++ goto error_alloc;
808 ++
809 + /* allocate a new session keyring */
810 + sprintf(desc, "_req.%u", key->serial);
811 +
812
813 Added: hardened/2.6/tags/2.6.26-10/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
814 ===================================================================
815 --- hardened/2.6/tags/2.6.26-10/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch (rev 0)
816 +++ hardened/2.6/tags/2.6.26-10/1411_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch 2009-01-21 00:11:21 UTC (rev 1482)
817 @@ -0,0 +1,51 @@
818 +Added-By: Gordon Malm <gengor@g.o>
819 +
820 +Note: Changed patch slightly to eliminate fuzz.
821 +
822 +---
823 +
824 +From jejb@××××××.org Tue Nov 11 09:47:32 2008
825 +From: Andre Noll <maan@×××××××××××.org>
826 +Date: Fri, 7 Nov 2008 00:07:46 GMT
827 +Subject: md: linear: Fix a division by zero bug for very small arrays.
828 +To: stable@××××××.org
829 +Message-ID: <200811070007.mA707k6d006270@×××××××××××.org>
830 +
831 +From: Andre Noll <maan@×××××××××××.org>
832 +
833 +commit f1cd14ae52985634d0389e934eba25b5ecf24565 upstream
834 +
835 +Date: Thu, 6 Nov 2008 19:41:24 +1100
836 +Subject: md: linear: Fix a division by zero bug for very small arrays.
837 +
838 +We currently oops with a divide error on starting a linear software
839 +raid array consisting of at least two very small (< 500K) devices.
840 +
841 +The bug is caused by the calculation of the hash table size which
842 +tries to compute sector_div(sz, base) with "base" being zero due to
843 +the small size of the component devices of the array.
844 +
845 +Fix this by requiring the hash spacing to be at least one which
846 +implies that also "base" is non-zero.
847 +
848 +This bug has existed since about 2.6.14.
849 +
850 +Signed-off-by: Andre Noll <maan@×××××××××××.org>
851 +Signed-off-by: NeilBrown <neilb@××××.de>
852 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
853 +
854 +---
855 + drivers/md/linear.c | 2 ++
856 + 1 file changed, 2 insertions(+)
857 +
858 +--- a/drivers/md/linear.c
859 ++++ b/drivers/md/linear.c
860 +@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_
861 +
862 + min_spacing = conf->array_size;
863 + sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
864 ++ if (min_spacing == 0)
865 ++ min_spacing = 1;
866 +
867 + /* min_spacing is the minimum spacing that will fit the hash
868 + * table in one PAGE. This may be much smaller than needed.
869
870 Added: hardened/2.6/tags/2.6.26-10/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch
871 ===================================================================
872 --- hardened/2.6/tags/2.6.26-10/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch (rev 0)
873 +++ hardened/2.6/tags/2.6.26-10/1412_mmc-increase-sd-write-timeout-for-crappy-cards.patch 2009-01-21 00:11:21 UTC (rev 1482)
874 @@ -0,0 +1,42 @@
875 +Added-By: Gordon Malm <gengor@g.o>
876 +
877 +---
878 +
879 +From 493890e75d98810a3470b4aae23be628ee5e9667 Mon Sep 17 00:00:00 2001
880 +From: Pierre Ossman <drzeus@××××××.cx>
881 +Date: Sun, 26 Oct 2008 12:37:25 +0100
882 +Subject: mmc: increase SD write timeout for crappy cards
883 +
884 +From: Pierre Ossman <drzeus@××××××.cx>
885 +
886 +commit 493890e75d98810a3470b4aae23be628ee5e9667 upstream.
887 +
888 +It seems that some cards are slightly out of spec and occasionally
889 +will not be able to complete a write in the alloted 250 ms [1].
890 +Incease the timeout slightly to allow even these cards to function
891 +properly.
892 +
893 +[1] http://lkml.org/lkml/2008/9/23/390
894 +
895 +Signed-off-by: Pierre Ossman <drzeus@××××××.cx>
896 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
897 +
898 +---
899 + drivers/mmc/core/core.c | 6 +++++-
900 + 1 file changed, 5 insertions(+), 1 deletion(-)
901 +
902 +--- a/drivers/mmc/core/core.c
903 ++++ b/drivers/mmc/core/core.c
904 +@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_dat
905 + (card->host->ios.clock / 1000);
906 +
907 + if (data->flags & MMC_DATA_WRITE)
908 +- limit_us = 250000;
909 ++ /*
910 ++ * The limit is really 250 ms, but that is
911 ++ * insufficient for some crappy cards.
912 ++ */
913 ++ limit_us = 300000;
914 + else
915 + limit_us = 100000;
916 +
917
918 Added: hardened/2.6/tags/2.6.26-10/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
919 ===================================================================
920 --- hardened/2.6/tags/2.6.26-10/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch (rev 0)
921 +++ hardened/2.6/tags/2.6.26-10/1413_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch 2009-01-21 00:11:21 UTC (rev 1482)
922 @@ -0,0 +1,213 @@
923 +Added-By: Gordon Malm <gengor@g.o>
924 +
925 +Backported to earlier kernels. Original message included below.
926 +
927 +---
928 +
929 +From jejb@××××××.org Tue Nov 11 09:59:05 2008
930 +From: Miklos Szeredi <mszeredi@××××.cz>
931 +Date: Sun, 9 Nov 2008 19:50:02 GMT
932 +Subject: net: unix: fix inflight counting bug in garbage collector
933 +To: stable@××××××.org
934 +Message-ID: <200811091950.mA9Jo2iL003804@×××××××××××.org>
935 +
936 +From: Miklos Szeredi <mszeredi@××××.cz>
937 +
938 +commit 6209344f5a3795d34b7f2c0061f49802283b6bdd upstream
939 +
940 +Previously I assumed that the receive queues of candidates don't
941 +change during the GC. This is only half true, nothing can be received
942 +from the queues (see comment in unix_gc()), but buffers could be added
943 +through the other half of the socket pair, which may still have file
944 +descriptors referring to it.
945 +
946 +This can result in inc_inflight_move_tail() erronously increasing the
947 +"inflight" counter for a unix socket for which dec_inflight() wasn't
948 +previously called. This in turn can trigger the "BUG_ON(total_refs <
949 +inflight_refs)" in a later garbage collection run.
950 +
951 +Fix this by only manipulating the "inflight" counter for sockets which
952 +are candidates themselves. Duplicating the file references in
953 +unix_attach_fds() is also needed to prevent a socket becoming a
954 +candidate for GC while the skb that contains it is not yet queued.
955 +
956 +Reported-by: Andrea Bittau <a.bittau@×××××××××.uk>
957 +Signed-off-by: Miklos Szeredi <mszeredi@××××.cz>
958 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
959 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
960 +
961 +---
962 + include/net/af_unix.h | 1 +
963 + net/unix/af_unix.c | 31 ++++++++++++++++++++++++-------
964 + net/unix/garbage.c | 49 +++++++++++++++++++++++++++++++++++++------------
965 + 3 files changed, 62 insertions(+), 19 deletions(-)
966 +
967 +--- a/include/net/af_unix.h
968 ++++ b/include/net/af_unix.h
969 +@@ -54,6 +54,7 @@ struct unix_sock {
970 + atomic_t inflight;
971 + spinlock_t lock;
972 + unsigned int gc_candidate : 1;
973 ++ unsigned int gc_maybe_cycle : 1;
974 + wait_queue_head_t peer_wait;
975 + };
976 + #define unix_sk(__sk) ((struct unix_sock *)__sk)
977 +--- a/net/unix/af_unix.c
978 ++++ b/net/unix/af_unix.c
979 +@@ -1302,14 +1302,23 @@ static void unix_destruct_fds(struct sk_
980 + sock_wfree(skb);
981 + }
982 +
983 +-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
984 ++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
985 + {
986 + int i;
987 ++
988 ++ /*
989 ++ * Need to duplicate file references for the sake of garbage
990 ++ * collection. Otherwise a socket in the fps might become a
991 ++ * candidate for GC while the skb is not yet queued.
992 ++ */
993 ++ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
994 ++ if (!UNIXCB(skb).fp)
995 ++ return -ENOMEM;
996 ++
997 + for (i=scm->fp->count-1; i>=0; i--)
998 + unix_inflight(scm->fp->fp[i]);
999 +- UNIXCB(skb).fp = scm->fp;
1000 + skb->destructor = unix_destruct_fds;
1001 +- scm->fp = NULL;
1002 ++ return 0;
1003 + }
1004 +
1005 + /*
1006 +@@ -1368,8 +1377,11 @@ static int unix_dgram_sendmsg(struct kio
1007 + goto out;
1008 +
1009 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1010 +- if (siocb->scm->fp)
1011 +- unix_attach_fds(siocb->scm, skb);
1012 ++ if (siocb->scm->fp) {
1013 ++ err = unix_attach_fds(siocb->scm, skb);
1014 ++ if (err)
1015 ++ goto out_free;
1016 ++ }
1017 + unix_get_secdata(siocb->scm, skb);
1018 +
1019 + skb_reset_transport_header(skb);
1020 +@@ -1538,8 +1550,13 @@ static int unix_stream_sendmsg(struct ki
1021 + size = min_t(int, size, skb_tailroom(skb));
1022 +
1023 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1024 +- if (siocb->scm->fp)
1025 +- unix_attach_fds(siocb->scm, skb);
1026 ++ if (siocb->scm->fp) {
1027 ++ err = unix_attach_fds(siocb->scm, skb);
1028 ++ if (err) {
1029 ++ kfree_skb(skb);
1030 ++ goto out_err;
1031 ++ }
1032 ++ }
1033 +
1034 + if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
1035 + kfree_skb(skb);
1036 +--- a/net/unix/garbage.c
1037 ++++ b/net/unix/garbage.c
1038 +@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x
1039 + */
1040 + struct sock *sk = unix_get_socket(*fp++);
1041 + if (sk) {
1042 +- hit = true;
1043 +- func(unix_sk(sk));
1044 ++ struct unix_sock *u = unix_sk(sk);
1045 ++
1046 ++ /*
1047 ++ * Ignore non-candidates, they could
1048 ++ * have been added to the queues after
1049 ++ * starting the garbage collection
1050 ++ */
1051 ++ if (u->gc_candidate) {
1052 ++ hit = true;
1053 ++ func(u);
1054 ++ }
1055 + }
1056 + }
1057 + if (hit && hitlist != NULL) {
1058 +@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struc
1059 + {
1060 + atomic_inc(&u->inflight);
1061 + /*
1062 +- * If this is still a candidate, move it to the end of the
1063 +- * list, so that it's checked even if it was already passed
1064 +- * over
1065 ++ * If this still might be part of a cycle, move it to the end
1066 ++ * of the list, so that it's checked even if it was already
1067 ++ * passed over
1068 + */
1069 +- if (u->gc_candidate)
1070 ++ if (u->gc_maybe_cycle)
1071 + list_move_tail(&u->link, &gc_candidates);
1072 + }
1073 +
1074 +@@ -267,6 +276,7 @@ void unix_gc(void)
1075 + struct unix_sock *next;
1076 + struct sk_buff_head hitlist;
1077 + struct list_head cursor;
1078 ++ LIST_HEAD(not_cycle_list);
1079 +
1080 + spin_lock(&unix_gc_lock);
1081 +
1082 +@@ -282,10 +292,14 @@ void unix_gc(void)
1083 + *
1084 + * Holding unix_gc_lock will protect these candidates from
1085 + * being detached, and hence from gaining an external
1086 +- * reference. This also means, that since there are no
1087 +- * possible receivers, the receive queues of these sockets are
1088 +- * static during the GC, even though the dequeue is done
1089 +- * before the detach without atomicity guarantees.
1090 ++ * reference. Since there are no possible receivers, all
1091 ++ * buffers currently on the candidates' queues stay there
1092 ++ * during the garbage collection.
1093 ++ *
1094 ++ * We also know that no new candidate can be added onto the
1095 ++ * receive queues. Other, non candidate sockets _can_ be
1096 ++ * added to queue, so we must make sure only to touch
1097 ++ * candidates.
1098 + */
1099 + list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
1100 + int total_refs;
1101 +@@ -299,6 +313,7 @@ void unix_gc(void)
1102 + if (total_refs == inflight_refs) {
1103 + list_move_tail(&u->link, &gc_candidates);
1104 + u->gc_candidate = 1;
1105 ++ u->gc_maybe_cycle = 1;
1106 + }
1107 + }
1108 +
1109 +@@ -325,14 +340,24 @@ void unix_gc(void)
1110 + list_move(&cursor, &u->link);
1111 +
1112 + if (atomic_read(&u->inflight) > 0) {
1113 +- list_move_tail(&u->link, &gc_inflight_list);
1114 +- u->gc_candidate = 0;
1115 ++ list_move_tail(&u->link, &not_cycle_list);
1116 ++ u->gc_maybe_cycle = 0;
1117 + scan_children(&u->sk, inc_inflight_move_tail, NULL);
1118 + }
1119 + }
1120 + list_del(&cursor);
1121 +
1122 + /*
1123 ++ * not_cycle_list contains those sockets which do not make up a
1124 ++ * cycle. Restore these to the inflight list.
1125 ++ */
1126 ++ while (!list_empty(&not_cycle_list)) {
1127 ++ u = list_entry(not_cycle_list.next, struct unix_sock, link);
1128 ++ u->gc_candidate = 0;
1129 ++ list_move_tail(&u->link, &gc_inflight_list);
1130 ++ }
1131 ++
1132 ++ /*
1133 + * Now gc_candidates contains only garbage. Restore original
1134 + * inflight counters for these as well, and remove the skbuffs
1135 + * which are creating the cycle(s).
1136
1137 Added: hardened/2.6/tags/2.6.26-10/1414_acpi-avoid-empty-file-name-in-sysfs.patch
1138 ===================================================================
1139 --- hardened/2.6/tags/2.6.26-10/1414_acpi-avoid-empty-file-name-in-sysfs.patch (rev 0)
1140 +++ hardened/2.6/tags/2.6.26-10/1414_acpi-avoid-empty-file-name-in-sysfs.patch 2009-01-21 00:11:21 UTC (rev 1482)
1141 @@ -0,0 +1,81 @@
1142 +Added-By: Gordon Malm <gengor@g.o>
1143 +
1144 +---
1145 +
1146 +From 4feba70a2c1a1a0c96909f657f48b2e11e682370 Mon Sep 17 00:00:00 2001
1147 +From: Peter Gruber <nokos@×××.net>
1148 +Date: Mon, 27 Oct 2008 23:59:36 -0400
1149 +Subject: ACPI: avoid empty file name in sysfs
1150 +
1151 +From: Peter Gruber <nokos@×××.net>
1152 +
1153 +commit 4feba70a2c1a1a0c96909f657f48b2e11e682370 upstream.
1154 +
1155 +Since commit bc45b1d39a925b56796bebf8a397a0491489d85c acpi tables are
1156 +allowed to have an empty signature and /sys/firmware/acpi/tables uses the
1157 +signature as filename. Applications using naive recursion through /sys
1158 +loop forever. A possible solution would be: (replacing the zero length
1159 +filename with the string "NULL")
1160 +
1161 +http://bugzilla.kernel.org/show_bug.cgi?id=11539
1162 +
1163 +Acked-by: Zhang Rui <rui.zhang@×××××.com>
1164 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
1165 +Signed-off-by: Len Brown <len.brown@×××××.com>
1166 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1167 +
1168 +---
1169 + drivers/acpi/system.c | 25 +++++++++++++++++--------
1170 + 1 file changed, 17 insertions(+), 8 deletions(-)
1171 +
1172 +--- a/drivers/acpi/system.c
1173 ++++ b/drivers/acpi/system.c
1174 +@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct ko
1175 + container_of(bin_attr, struct acpi_table_attr, attr);
1176 + struct acpi_table_header *table_header = NULL;
1177 + acpi_status status;
1178 ++ char name[ACPI_NAME_SIZE];
1179 ++
1180 ++ if (strncmp(table_attr->name, "NULL", 4))
1181 ++ memcpy(name, table_attr->name, ACPI_NAME_SIZE);
1182 ++ else
1183 ++ memcpy(name, "\0\0\0\0", 4);
1184 +
1185 + status =
1186 +- acpi_get_table(table_attr->name, table_attr->instance,
1187 ++ acpi_get_table(name, table_attr->instance,
1188 + &table_header);
1189 + if (ACPI_FAILURE(status))
1190 + return -ENODEV;
1191 +@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct
1192 + struct acpi_table_header *header = NULL;
1193 + struct acpi_table_attr *attr = NULL;
1194 +
1195 +- memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
1196 ++ if (table_header->signature[0] != '\0')
1197 ++ memcpy(table_attr->name, table_header->signature,
1198 ++ ACPI_NAME_SIZE);
1199 ++ else
1200 ++ memcpy(table_attr->name, "NULL", 4);
1201 +
1202 + list_for_each_entry(attr, &acpi_table_attr_list, node) {
1203 +- if (!memcmp(table_header->signature, attr->name,
1204 +- ACPI_NAME_SIZE))
1205 ++ if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
1206 + if (table_attr->instance < attr->instance)
1207 + table_attr->instance = attr->instance;
1208 + }
1209 + table_attr->instance++;
1210 +
1211 + if (table_attr->instance > 1 || (table_attr->instance == 1 &&
1212 +- !acpi_get_table(table_header->
1213 +- signature, 2,
1214 +- &header)))
1215 +- sprintf(table_attr->name + 4, "%d", table_attr->instance);
1216 ++ !acpi_get_table
1217 ++ (table_header->signature, 2, &header)))
1218 ++ sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
1219 ++ table_attr->instance);
1220 +
1221 + table_attr->attr.size = 0;
1222 + table_attr->attr.read = acpi_table_show;
1223
1224 Added: hardened/2.6/tags/2.6.26-10/1415_block-fix-nr_phys_segments-miscalculation-bug.patch
1225 ===================================================================
1226 --- hardened/2.6/tags/2.6.26-10/1415_block-fix-nr_phys_segments-miscalculation-bug.patch (rev 0)
1227 +++ hardened/2.6/tags/2.6.26-10/1415_block-fix-nr_phys_segments-miscalculation-bug.patch 2009-01-21 00:11:21 UTC (rev 1482)
1228 @@ -0,0 +1,126 @@
1229 +Added-By: Gordon Malm <gengor@g.o>
1230 +
1231 +---
1232 +
1233 +From knikanth@××××.de Thu Nov 13 14:07:47 2008
1234 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1235 +Date: Wed, 12 Nov 2008 11:33:54 +0530
1236 +Subject: block: fix nr_phys_segments miscalculation bug
1237 +To: Greg KH <greg@×××××.com>
1238 +Cc: stable@××××××.org, FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1239 +Message-ID: <200811121133.55404.knikanth@××××.de>
1240 +Content-Disposition: inline
1241 +
1242 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1243 +
1244 +commit 8677142710516d986d932d6f1fba7be8382c1fec upstream
1245 +backported by Nikanth Karthikesan <knikanth@××××.de> to the 2.6.27.y tree.
1246 +
1247 +block: fix nr_phys_segments miscalculation bug
1248 +
1249 +This fixes the bug reported by Nikanth Karthikesan <knikanth@××××.de>:
1250 +
1251 +http://lkml.org/lkml/2008/10/2/203
1252 +
1253 +The root cause of the bug is that blk_phys_contig_segment
1254 +miscalculates q->max_segment_size.
1255 +
1256 +blk_phys_contig_segment checks:
1257 +
1258 +req->biotail->bi_size + next_req->bio->bi_size > q->max_segment_size
1259 +
1260 +But blk_recalc_rq_segments might expect that req->biotail and the
1261 +previous bio in the req are supposed be merged into one
1262 +segment. blk_recalc_rq_segments might also expect that next_req->bio
1263 +and the next bio in the next_req are supposed be merged into one
1264 +segment. In such case, we merge two requests that can't be merged
1265 +here. Later, blk_rq_map_sg gives more segments than it should.
1266 +
1267 +We need to keep track of segment size in blk_recalc_rq_segments and
1268 +use it to see if two requests can be merged. This patch implements it
1269 +in the similar way that we used to do for hw merging (virtual
1270 +merging).
1271 +
1272 +Signed-off-by: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
1273 +Signed-off-by: Jens Axboe <jens.axboe@××××××.com>
1274 +Cc: Nikanth Karthikesan <knikanth@××××.de>
1275 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1276 +
1277 +---
1278 + block/blk-merge.c | 19 +++++++++++++++++--
1279 + include/linux/bio.h | 7 +++++++
1280 + 2 files changed, 24 insertions(+), 2 deletions(-)
1281 +
1282 +--- a/block/blk-merge.c
1283 ++++ b/block/blk-merge.c
1284 +@@ -95,6 +95,9 @@ new_hw_segment:
1285 + nr_hw_segs++;
1286 + }
1287 +
1288 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
1289 ++ rq->bio->bi_seg_front_size = seg_size;
1290 ++
1291 + nr_phys_segs++;
1292 + bvprv = bv;
1293 + seg_size = bv->bv_len;
1294 +@@ -106,6 +109,10 @@ new_hw_segment:
1295 + rq->bio->bi_hw_front_size = hw_seg_size;
1296 + if (hw_seg_size > rq->biotail->bi_hw_back_size)
1297 + rq->biotail->bi_hw_back_size = hw_seg_size;
1298 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
1299 ++ rq->bio->bi_seg_front_size = seg_size;
1300 ++ if (seg_size > rq->biotail->bi_seg_back_size)
1301 ++ rq->biotail->bi_seg_back_size = seg_size;
1302 + rq->nr_phys_segments = nr_phys_segs;
1303 + rq->nr_hw_segments = nr_hw_segs;
1304 + }
1305 +@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struc
1306 +
1307 + if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
1308 + return 0;
1309 +- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
1310 ++ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
1311 ++ q->max_segment_size)
1312 + return 0;
1313 +
1314 + /*
1315 +@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct r
1316 + {
1317 + int total_phys_segments;
1318 + int total_hw_segments;
1319 ++ unsigned int seg_size =
1320 ++ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
1321 +
1322 + /*
1323 + * First check if the either of the requests are re-queued
1324 +@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct r
1325 + return 0;
1326 +
1327 + total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
1328 +- if (blk_phys_contig_segment(q, req->biotail, next->bio))
1329 ++ if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
1330 ++ if (req->nr_phys_segments == 1)
1331 ++ req->bio->bi_seg_front_size = seg_size;
1332 ++ if (next->nr_phys_segments == 1)
1333 ++ next->biotail->bi_seg_back_size = seg_size;
1334 + total_phys_segments--;
1335 ++ }
1336 +
1337 + if (total_phys_segments > q->max_phys_segments)
1338 + return 0;
1339 +--- a/include/linux/bio.h
1340 ++++ b/include/linux/bio.h
1341 +@@ -98,6 +98,13 @@ struct bio {
1342 + unsigned int bi_size; /* residual I/O count */
1343 +
1344 + /*
1345 ++ * To keep track of the max segment size, we account for the
1346 ++ * sizes of the first and last mergeable segments in this bio.
1347 ++ */
1348 ++ unsigned int bi_seg_front_size;
1349 ++ unsigned int bi_seg_back_size;
1350 ++
1351 ++ /*
1352 + * To keep track of the max hw size, we account for the
1353 + * sizes of the first and last virtually mergeable segments
1354 + * in this bio
1355
1356 Added: hardened/2.6/tags/2.6.26-10/1416_dm-raid1-flush-workqueue-before-destruction.patch
1357 ===================================================================
1358 --- hardened/2.6/tags/2.6.26-10/1416_dm-raid1-flush-workqueue-before-destruction.patch (rev 0)
1359 +++ hardened/2.6/tags/2.6.26-10/1416_dm-raid1-flush-workqueue-before-destruction.patch 2009-01-21 00:11:21 UTC (rev 1482)
1360 @@ -0,0 +1,34 @@
1361 +Added-By: Gordon Malm <gengor@g.o>
1362 +
1363 +---
1364 +
1365 +From 18776c7316545482a02bfaa2629a2aa1afc48357 Mon Sep 17 00:00:00 2001
1366 +From: Mikulas Patocka <mpatocka@××××××.com>
1367 +Date: Thu, 13 Nov 2008 23:38:52 +0000
1368 +Subject: dm raid1: flush workqueue before destruction
1369 +
1370 +From: Mikulas Patocka <mpatocka@××××××.com>
1371 +
1372 +commit 18776c7316545482a02bfaa2629a2aa1afc48357 upstream.
1373 +
1374 +We queue work on keventd queue --- so this queue must be flushed in the
1375 +destructor. Otherwise, keventd could access mirror_set after it was freed.
1376 +
1377 +Signed-off-by: Mikulas Patocka <mpatocka@××××××.com>
1378 +Signed-off-by: Alasdair G Kergon <agk@××××××.com>
1379 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1380 +
1381 +---
1382 + drivers/md/dm-raid1.c | 1 +
1383 + 1 file changed, 1 insertion(+)
1384 +
1385 +--- a/drivers/md/dm-raid1.c
1386 ++++ b/drivers/md/dm-raid1.c
1387 +@@ -1598,6 +1598,7 @@ static void mirror_dtr(struct dm_target
1388 +
1389 + del_timer_sync(&ms->timer);
1390 + flush_workqueue(ms->kmirrord_wq);
1391 ++ flush_scheduled_work();
1392 + dm_kcopyd_client_destroy(ms->kcopyd_client);
1393 + destroy_workqueue(ms->kmirrord_wq);
1394 + free_context(ms, ti, ms->nr_mirrors);
1395
1396 Added: hardened/2.6/tags/2.6.26-10/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch
1397 ===================================================================
1398 --- hardened/2.6/tags/2.6.26-10/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch (rev 0)
1399 +++ hardened/2.6/tags/2.6.26-10/1417_net-fix-proc-net-snmp-as-memory-corruptor.patch 2009-01-21 00:11:21 UTC (rev 1482)
1400 @@ -0,0 +1,104 @@
1401 +Added-By: Gordon Malm <gengor@g.o>
1402 +
1403 +Note: Backported to earlier kernels. Original message included below.
1404 +
1405 +---
1406 +
1407 +From b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 Mon Sep 17 00:00:00 2001
1408 +From: Eric Dumazet <dada1@×××××××××.com>
1409 +Date: Mon, 10 Nov 2008 21:43:08 -0800
1410 +Subject: net: fix /proc/net/snmp as memory corruptor
1411 +
1412 +From: Eric Dumazet <dada1@×××××××××.com>
1413 +
1414 +commit b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 upstream.
1415 +
1416 +icmpmsg_put() can happily corrupt kernel memory, using a static
1417 +table and forgetting to reset an array index in a loop.
1418 +
1419 +Remove the static array since its not safe without proper locking.
1420 +
1421 +Signed-off-by: Alexey Dobriyan <adobriyan@×××××.com>
1422 +Signed-off-by: Eric Dumazet <dada1@×××××××××.com>
1423 +Signed-off-by: David S. Miller <davem@×××××××××.net>
1424 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1425 +
1426 +---
1427 + net/ipv4/proc.c | 58 ++++++++++++++++++++++++++++----------------------------
1428 + 1 file changed, 30 insertions(+), 28 deletions(-)
1429 +
1430 +--- a/net/ipv4/proc.c
1431 ++++ b/net/ipv4/proc.c
1432 +@@ -262,42 +262,44 @@ static const struct snmp_mib snmp4_net_l
1433 + SNMP_MIB_SENTINEL
1434 + };
1435 +
1436 +-static void icmpmsg_put(struct seq_file *seq)
1437 ++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
1438 ++ unsigned short *type, int count)
1439 + {
1440 +-#define PERLINE 16
1441 +-
1442 +- int j, i, count;
1443 +- static int out[PERLINE];
1444 +-
1445 +- count = 0;
1446 +- for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
1447 +-
1448 +- if (snmp_fold_field((void **) icmpmsg_statistics, i))
1449 +- out[count++] = i;
1450 +- if (count < PERLINE)
1451 +- continue;
1452 ++ int j;
1453 +
1454 +- seq_printf(seq, "\nIcmpMsg:");
1455 +- for (j = 0; j < PERLINE; ++j)
1456 +- seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In",
1457 +- i & 0xff);
1458 +- seq_printf(seq, "\nIcmpMsg: ");
1459 +- for (j = 0; j < PERLINE; ++j)
1460 +- seq_printf(seq, " %lu",
1461 +- snmp_fold_field((void **) icmpmsg_statistics,
1462 +- out[j]));
1463 +- seq_putc(seq, '\n');
1464 +- }
1465 + if (count) {
1466 + seq_printf(seq, "\nIcmpMsg:");
1467 + for (j = 0; j < count; ++j)
1468 +- seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" :
1469 +- "In", out[j] & 0xff);
1470 ++ seq_printf(seq, " %sType%u",
1471 ++ type[j] & 0x100 ? "Out" : "In",
1472 ++ type[j] & 0xff);
1473 + seq_printf(seq, "\nIcmpMsg:");
1474 + for (j = 0; j < count; ++j)
1475 +- seq_printf(seq, " %lu", snmp_fold_field((void **)
1476 +- icmpmsg_statistics, out[j]));
1477 ++ seq_printf(seq, " %lu", vals[j]);
1478 ++ }
1479 ++}
1480 ++
1481 ++static void icmpmsg_put(struct seq_file *seq)
1482 ++{
1483 ++#define PERLINE 16
1484 ++
1485 ++ int i, count;
1486 ++ unsigned short type[PERLINE];
1487 ++ unsigned long vals[PERLINE], val;
1488 ++
1489 ++ count = 0;
1490 ++ for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
1491 ++ val = snmp_fold_field((void **) icmpmsg_statistics, i);
1492 ++ if (val) {
1493 ++ type[count] = i;
1494 ++ vals[count++] = val;
1495 ++ }
1496 ++ if (count == PERLINE) {
1497 ++ icmpmsg_put_line(seq, vals, type, count);
1498 ++ count = 0;
1499 ++ }
1500 + }
1501 ++ icmpmsg_put_line(seq, vals, type, count);
1502 +
1503 + #undef PERLINE
1504 + }
1505
1506 Added: hardened/2.6/tags/2.6.26-10/1418_touch_mnt_namespace-when-the-mount-flags-change.patch
1507 ===================================================================
1508 --- hardened/2.6/tags/2.6.26-10/1418_touch_mnt_namespace-when-the-mount-flags-change.patch (rev 0)
1509 +++ hardened/2.6/tags/2.6.26-10/1418_touch_mnt_namespace-when-the-mount-flags-change.patch 2009-01-21 00:11:21 UTC (rev 1482)
1510 @@ -0,0 +1,43 @@
1511 +Added-By: Gordon Malm <gengor@g.o>
1512 +
1513 +---
1514 +
1515 +From 0e55a7cca4b66f625d67b292f80b6a976e77c51b Mon Sep 17 00:00:00 2001
1516 +From: Dan Williams <dan.j.williams@×××××.com>
1517 +Date: Fri, 26 Sep 2008 19:01:20 -0700
1518 +Subject: touch_mnt_namespace when the mount flags change
1519 +
1520 +From: Dan Williams <dan.j.williams@×××××.com>
1521 +
1522 +commit 0e55a7cca4b66f625d67b292f80b6a976e77c51b upstream
1523 +
1524 +Daemons that need to be launched while the rootfs is read-only can now
1525 +poll /proc/mounts to be notified when their O_RDWR requests may no
1526 +longer end in EROFS.
1527 +
1528 +Cc: Kay Sievers <kay.sievers@××××.org>
1529 +Cc: Neil Brown <neilb@××××.de>
1530 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
1531 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1532 +
1533 +---
1534 + fs/namespace.c | 7 ++++++-
1535 + 1 file changed, 6 insertions(+), 1 deletion(-)
1536 +
1537 +--- a/fs/namespace.c
1538 ++++ b/fs/namespace.c
1539 +@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct na
1540 + if (!err)
1541 + nd->path.mnt->mnt_flags = mnt_flags;
1542 + up_write(&sb->s_umount);
1543 +- if (!err)
1544 ++ if (!err) {
1545 + security_sb_post_remount(nd->path.mnt, flags, data);
1546 ++
1547 ++ spin_lock(&vfsmount_lock);
1548 ++ touch_mnt_namespace(nd->path.mnt->mnt_ns);
1549 ++ spin_unlock(&vfsmount_lock);
1550 ++ }
1551 + return err;
1552 + }
1553 +
1554
1555 Added: hardened/2.6/tags/2.6.26-10/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
1556 ===================================================================
1557 --- hardened/2.6/tags/2.6.26-10/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch (rev 0)
1558 +++ hardened/2.6/tags/2.6.26-10/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch 2009-01-21 00:11:21 UTC (rev 1482)
1559 @@ -0,0 +1,75 @@
1560 +Added-By: Gordon Malm <gengor@g.o>
1561 +
1562 +Note: Backported to kernel 2.6.26. Original message included below.
1563 +
1564 +---
1565 +
1566 +From 352d026338378b1f13f044e33c1047da6e470056 Mon Sep 17 00:00:00 2001
1567 +From: Alan Stern <stern@×××××××××××××××.edu>
1568 +Date: Wed, 29 Oct 2008 15:16:58 -0400
1569 +Subject: USB: don't register endpoints for interfaces that are going away
1570 +
1571 +From: Alan Stern <stern@×××××××××××××××.edu>
1572 +
1573 +commit 352d026338378b1f13f044e33c1047da6e470056 upstream.
1574 +
1575 +This patch (as1155) fixes a bug in usbcore. When interfaces are
1576 +deleted, either because the device was disconnected or because of a
1577 +configuration change, the extra attribute files and child endpoint
1578 +devices may get left behind. This is because the core removes them
1579 +before calling device_del(). But during device_del(), after the
1580 +driver is unbound the core will reinstall altsetting 0 and recreate
1581 +those extra attributes and children.
1582 +
1583 +The patch prevents this by adding a flag to record when the interface
1584 +is in the midst of being unregistered. When the flag is set, the
1585 +attribute files and child devices will not be created.
1586 +
1587 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
1588 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1589 +
1590 +---
1591 + drivers/usb/core/message.c | 1 +
1592 + drivers/usb/core/sysfs.c | 2 +-
1593 + include/linux/usb.h | 2 ++
1594 + 3 files changed, 4 insertions(+), 1 deletion(-)
1595 +
1596 +--- a/drivers/usb/core/message.c
1597 ++++ b/drivers/usb/core/message.c
1598 +@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_devic
1599 + continue;
1600 + dev_dbg(&dev->dev, "unregistering interface %s\n",
1601 + interface->dev.bus_id);
1602 ++ interface->unregistering = 1;
1603 + usb_remove_sysfs_intf_files(interface);
1604 + device_del(&interface->dev);
1605 + }
1606 +--- a/drivers/usb/core/sysfs.c
1607 ++++ b/drivers/usb/core/sysfs.c
1608 +@@ -816,7 +816,7 @@ int usb_create_sysfs_intf_files(struct u
1609 + struct usb_host_interface *alt = intf->cur_altsetting;
1610 + int retval;
1611 +
1612 +- if (intf->sysfs_files_created)
1613 ++ if (intf->sysfs_files_created || intf->unregistering)
1614 + return 0;
1615 +
1616 + /* The interface string may be present in some altsettings
1617 +--- a/include/linux/usb.h
1618 ++++ b/include/linux/usb.h
1619 +@@ -108,6 +108,7 @@ enum usb_interface_condition {
1620 + * (in probe()), bound to a driver, or unbinding (in disconnect())
1621 + * @is_active: flag set when the interface is bound and not suspended.
1622 + * @sysfs_files_created: sysfs attributes exist
1623 ++ * @unregistering: flag set when the interface is being unregistered
1624 + * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
1625 + * capability during autosuspend.
1626 + * @dev: driver model's view of this device
1627 +@@ -159,6 +160,7 @@ struct usb_interface {
1628 + enum usb_interface_condition condition; /* state of binding */
1629 + unsigned is_active:1; /* the interface is not suspended */
1630 + unsigned sysfs_files_created:1; /* the sysfs attributes exist */
1631 ++ unsigned unregistering:1; /* unregistration is in progress */
1632 + unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
1633 +
1634 + struct device dev; /* interface specific device info */
1635
1636 Added: hardened/2.6/tags/2.6.26-10/1420_usb-ehci-fix-divide-by-zero-bug.patch
1637 ===================================================================
1638 --- hardened/2.6/tags/2.6.26-10/1420_usb-ehci-fix-divide-by-zero-bug.patch (rev 0)
1639 +++ hardened/2.6/tags/2.6.26-10/1420_usb-ehci-fix-divide-by-zero-bug.patch 2009-01-21 00:11:21 UTC (rev 1482)
1640 @@ -0,0 +1,46 @@
1641 +Added-By: Gordon Malm <gengor@g.o>
1642 +
1643 +---
1644 +
1645 +From 372dd6e8ed924e876f3beb598721e813ad7fa323 Mon Sep 17 00:00:00 2001
1646 +From: Alan Stern <stern@×××××××××××××××.edu>
1647 +Date: Wed, 12 Nov 2008 17:02:57 -0500
1648 +Subject: USB: EHCI: fix divide-by-zero bug
1649 +
1650 +From: Alan Stern <stern@×××××××××××××××.edu>
1651 +
1652 +commit 372dd6e8ed924e876f3beb598721e813ad7fa323 upstream.
1653 +
1654 +This patch (as1164) fixes a bug in the EHCI scheduler. The interval
1655 +value it uses is already in linear format, not logarithmically coded.
1656 +The existing code can sometimes crash the system by trying to divide
1657 +by zero.
1658 +
1659 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
1660 +Cc: David Brownell <david-b@×××××××.net>
1661 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1662 +
1663 +---
1664 + drivers/usb/host/ehci-sched.c | 4 ++--
1665 + 1 file changed, 2 insertions(+), 2 deletions(-)
1666 +
1667 +--- a/drivers/usb/host/ehci-sched.c
1668 ++++ b/drivers/usb/host/ehci-sched.c
1669 +@@ -918,7 +918,7 @@ iso_stream_init (
1670 + */
1671 + stream->usecs = HS_USECS_ISO (maxp);
1672 + bandwidth = stream->usecs * 8;
1673 +- bandwidth /= 1 << (interval - 1);
1674 ++ bandwidth /= interval;
1675 +
1676 + } else {
1677 + u32 addr;
1678 +@@ -951,7 +951,7 @@ iso_stream_init (
1679 + } else
1680 + stream->raw_mask = smask_out [hs_transfers - 1];
1681 + bandwidth = stream->usecs + stream->c_usecs;
1682 +- bandwidth /= 1 << (interval + 2);
1683 ++ bandwidth /= interval << 3;
1684 +
1685 + /* stream->splits gets created from raw_mask later */
1686 + stream->address = cpu_to_hc32(ehci, addr);
1687
1688 Added: hardened/2.6/tags/2.6.26-10/1421_usb-ehci-fix-handling-of-dead-controllers.patch
1689 ===================================================================
1690 --- hardened/2.6/tags/2.6.26-10/1421_usb-ehci-fix-handling-of-dead-controllers.patch (rev 0)
1691 +++ hardened/2.6/tags/2.6.26-10/1421_usb-ehci-fix-handling-of-dead-controllers.patch 2009-01-21 00:11:21 UTC (rev 1482)
1692 @@ -0,0 +1,93 @@
1693 +Added-By: Gordon Malm <gengor@g.o>
1694 +
1695 +---
1696 +
1697 +From 67b2e029743a52670d77864723b4d0d40f7733b5 Mon Sep 17 00:00:00 2001
1698 +From: Alan Stern <stern@×××××××××××××××.edu>
1699 +Date: Wed, 12 Nov 2008 17:04:53 -0500
1700 +Subject: USB: EHCI: fix handling of dead controllers
1701 +
1702 +From: Alan Stern <stern@×××××××××××××××.edu>
1703 +
1704 +commit 67b2e029743a52670d77864723b4d0d40f7733b5 upstream.
1705 +
1706 +This patch (as1165) makes a few small changes in the logic used by
1707 +ehci-hcd when it encounters a controller error:
1708 +
1709 + Instead of printing out the masked status, it prints the
1710 + original status as read directly from the hardware.
1711 +
1712 + It doesn't check for the STS_HALT status bit before taking
1713 + action. The mere fact that the STS_FATAL bit is set means
1714 + that something bad has happened and the controller needs to
1715 + be reset. With the old code this test could never succeed
1716 + because the STS_HALT bit was masked out from the status.
1717 +
1718 +I anticipate that this will prevent the occasional "irq X: nobody cared"
1719 +problem people encounter when their EHCI controllers die.
1720 +
1721 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
1722 +Cc: David Brownell <david-b@×××××××.net>
1723 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1724 +
1725 +---
1726 + drivers/usb/host/ehci-hcd.c | 25 ++++++++++++-------------
1727 + 1 file changed, 12 insertions(+), 13 deletions(-)
1728 +
1729 +--- a/drivers/usb/host/ehci-hcd.c
1730 ++++ b/drivers/usb/host/ehci-hcd.c
1731 +@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd
1732 + static irqreturn_t ehci_irq (struct usb_hcd *hcd)
1733 + {
1734 + struct ehci_hcd *ehci = hcd_to_ehci (hcd);
1735 +- u32 status, pcd_status = 0, cmd;
1736 ++ u32 status, masked_status, pcd_status = 0, cmd;
1737 + int bh;
1738 +
1739 + spin_lock (&ehci->lock);
1740 +@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_
1741 + goto dead;
1742 + }
1743 +
1744 +- status &= INTR_MASK;
1745 +- if (!status) { /* irq sharing? */
1746 ++ masked_status = status & INTR_MASK;
1747 ++ if (!masked_status) { /* irq sharing? */
1748 + spin_unlock(&ehci->lock);
1749 + return IRQ_NONE;
1750 + }
1751 +
1752 + /* clear (just) interrupts */
1753 +- ehci_writel(ehci, status, &ehci->regs->status);
1754 ++ ehci_writel(ehci, masked_status, &ehci->regs->status);
1755 + cmd = ehci_readl(ehci, &ehci->regs->command);
1756 + bh = 0;
1757 +
1758 +@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_
1759 +
1760 + /* PCI errors [4.15.2.4] */
1761 + if (unlikely ((status & STS_FATAL) != 0)) {
1762 ++ ehci_err(ehci, "fatal error\n");
1763 + dbg_cmd (ehci, "fatal", ehci_readl(ehci,
1764 + &ehci->regs->command));
1765 + dbg_status (ehci, "fatal", status);
1766 +- if (status & STS_HALT) {
1767 +- ehci_err (ehci, "fatal error\n");
1768 ++ ehci_halt(ehci);
1769 + dead:
1770 +- ehci_reset (ehci);
1771 +- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
1772 +- /* generic layer kills/unlinks all urbs, then
1773 +- * uses ehci_stop to clean up the rest
1774 +- */
1775 +- bh = 1;
1776 +- }
1777 ++ ehci_reset(ehci);
1778 ++ ehci_writel(ehci, 0, &ehci->regs->configured_flag);
1779 ++ /* generic layer kills/unlinks all urbs, then
1780 ++ * uses ehci_stop to clean up the rest
1781 ++ */
1782 ++ bh = 1;
1783 + }
1784 +
1785 + if (bh)
1786
1787 Added: hardened/2.6/tags/2.6.26-10/1422_usb-fix-ps3-usb-shutdown-problems.patch
1788 ===================================================================
1789 --- hardened/2.6/tags/2.6.26-10/1422_usb-fix-ps3-usb-shutdown-problems.patch (rev 0)
1790 +++ hardened/2.6/tags/2.6.26-10/1422_usb-fix-ps3-usb-shutdown-problems.patch 2009-01-21 00:11:21 UTC (rev 1482)
1791 @@ -0,0 +1,64 @@
1792 +Added-By: Gordon Malm <gengor@g.o>
1793 +
1794 +---
1795 +
1796 +From ddcb01ff9bf49c4dbbb058423559f7bc90b89374 Mon Sep 17 00:00:00 2001
1797 +From: Geoff Levand <geoffrey.levand@×××××××.com>
1798 +Date: Fri, 31 Oct 2008 13:52:54 -0700
1799 +Subject: USB: Fix PS3 USB shutdown problems
1800 +
1801 +From: Geoff Levand <geoffrey.levand@×××××××.com>
1802 +
1803 +commit ddcb01ff9bf49c4dbbb058423559f7bc90b89374 upstream.
1804 +
1805 +Add ehci_shutdown() or ohci_shutdown() calls to the USB
1806 +PS3 bus glue. ehci_shutdown() and ohci_shutdown() do some
1807 +controller specific cleanups not done by usb_remove_hcd().
1808 +
1809 +Fixes errors on shutdown or reboot similar to these:
1810 +
1811 + ps3-ehci-driver sb_07: HC died; cleaning up
1812 + irq 51: nobody cared (try booting with the "irqpoll" option)
1813 +
1814 +Related bugzilla reports:
1815 +
1816 + http://bugzilla.kernel.org/show_bug.cgi?id=11819
1817 + http://bugzilla.terrasoftsolutions.com/show_bug.cgi?id=317
1818 +
1819 +Signed-off-by: Geoff Levand <geoffrey.levand@×××××××.com>
1820 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1821 +
1822 +---
1823 + drivers/usb/host/ehci-ps3.c | 1 +
1824 + drivers/usb/host/ohci-ps3.c | 3 ++-
1825 + 2 files changed, 3 insertions(+), 1 deletion(-)
1826 +
1827 +--- a/drivers/usb/host/ehci-ps3.c
1828 ++++ b/drivers/usb/host/ehci-ps3.c
1829 +@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_sy
1830 +
1831 + tmp = hcd->irq;
1832 +
1833 ++ ehci_shutdown(hcd);
1834 + usb_remove_hcd(hcd);
1835 +
1836 + ps3_system_bus_set_driver_data(dev, NULL);
1837 +--- a/drivers/usb/host/ohci-ps3.c
1838 ++++ b/drivers/usb/host/ohci-ps3.c
1839 +@@ -192,7 +192,7 @@ fail_start:
1840 + return result;
1841 + }
1842 +
1843 +-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
1844 ++static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
1845 + {
1846 + unsigned int tmp;
1847 + struct usb_hcd *hcd =
1848 +@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_s
1849 +
1850 + tmp = hcd->irq;
1851 +
1852 ++ ohci_shutdown(hcd);
1853 + usb_remove_hcd(hcd);
1854 +
1855 + ps3_system_bus_set_driver_data(dev, NULL);
1856
1857 Added: hardened/2.6/tags/2.6.26-10/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
1858 ===================================================================
1859 --- hardened/2.6/tags/2.6.26-10/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch (rev 0)
1860 +++ hardened/2.6/tags/2.6.26-10/1423_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch 2009-01-21 00:11:21 UTC (rev 1482)
1861 @@ -0,0 +1,135 @@
1862 +Added-By: Gordon Malm <gengor@g.o>
1863 +
1864 +---
1865 +
1866 +From 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 Mon Sep 17 00:00:00 2001
1867 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
1868 +Date: Fri, 14 Nov 2008 10:46:59 -0300
1869 +Subject: V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble
1870 +
1871 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
1872 +
1873 +commit 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 upstream.
1874 +
1875 +This bug were supposed to be fixed by 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1,
1876 +where a call to NULL happens.
1877 +
1878 +Not all tvaudio chips allow controlling bass/treble. So, the driver
1879 +has a table with a flag to indicate if the chip does support it.
1880 +
1881 +Unfortunately, the handling of this logic were broken for a very long
1882 +time (probably since the first module version). Due to that, an OOPS
1883 +were generated for devices that don't support bass/treble.
1884 +
1885 +This were the resulting OOPS message before the patch, with debug messages
1886 +enabled:
1887 +
1888 +tvaudio' 1-005b: VIDIOC_S_CTRL
1889 +BUG: unable to handle kernel NULL pointer dereference at 00000000
1890 +IP: [<00000000>]
1891 +*pde = 22fda067 *pte = 00000000
1892 +Oops: 0000 [#1] SMP
1893 +Modules linked in: snd_hda_intel snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
1894 +snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_hwdep snd soundcore tuner_simple tuner_types tea5767 tuner
1895 +tvaudio bttv bridgebnep rfcomm l2cap bluetooth it87 hwmon_vid hwmon fuse sunrpc ipt_REJECT
1896 +nf_conntrack_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack
1897 +ip6table_filter ip6_tables x_tables ipv6 dm_mirrordm_multipath dm_mod configfs videodev v4l1_compat
1898 +ir_common 8139cp compat_ioctl32 v4l2_common 8139too videobuf_dma_sg videobuf_core mii btcx_risc tveeprom
1899 +i915 button snd_page_alloc serio_raw drm pcspkr i2c_algo_bit i2c_i801 i2c_core iTCO_wdt
1900 +iTCO_vendor_support sr_mod cdrom sg ata_generic pata_acpi ata_piix libata sd_mod scsi_mod ext3 jbdmbcache
1901 +uhci_hcd ohci_hcd ehci_hcd [last unloaded: soundcore]
1902 +
1903 +Pid: 15413, comm: qv4l2 Not tainted (2.6.25.14-108.fc9.i686 #1)
1904 +EIP: 0060:[<00000000>] EFLAGS: 00210246 CPU: 0
1905 +EIP is at 0x0
1906 +EAX: 00008000 EBX: ebd21600 ECX: e2fd9ec4 EDX: 00200046
1907 +ESI: f8c0f0c4 EDI: f8c0f0c4 EBP: e2fd9d50 ESP: e2fd9d2c
1908 + DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
1909 +Process qv4l2 (pid: 15413, ti=e2fd9000 task=ebe44000 task.ti=e2fd9000)
1910 +Stack: f8c0c6ae e2ff2a00 00000d00 e2fd9ec4 ebc4e000 e2fd9d5c f8c0c448 00000000
1911 + f899c12a e2fd9d5c f899c154 e2fd9d68 e2fd9d80 c0560185 e2fd9d88 f8f3e1d8
1912 + f8f3e1dc ebc4e034 f8f3e18c e2fd9ec4 00000000 e2fd9d90 f899c286 c008561c
1913 +Call Trace:
1914 + [<f8c0c6ae>] ? chip_command+0x266/0x4b6 [tvaudio]
1915 + [<f8c0c448>] ? chip_command+0x0/0x4b6 [tvaudio]
1916 + [<f899c12a>] ? i2c_cmd+0x0/0x2f [i2c_core]
1917 + [<f899c154>] ? i2c_cmd+0x2a/0x2f [i2c_core]
1918 + [<c0560185>] ? device_for_each_child+0x21/0x49
1919 + [<f899c286>] ? i2c_clients_command+0x1c/0x1e [i2c_core]
1920 + [<f8f283d8>] ? bttv_call_i2c_clients+0x14/0x16 [bttv]
1921 + [<f8f23601>] ? bttv_s_ctrl+0x1bc/0x313 [bttv]
1922 + [<f8f23445>] ? bttv_s_ctrl+0x0/0x313 [bttv]
1923 + [<f8b6096d>] ? __video_do_ioctl+0x1f84/0x3726 [videodev]
1924 + [<c05abb4e>] ? sock_aio_write+0x100/0x10d
1925 + [<c041b23e>] ? kmap_atomic_prot+0x1dd/0x1df
1926 + [<c043a0c9>] ? enqueue_hrtimer+0xc2/0xcd
1927 + [<c04f4fa4>] ? copy_from_user+0x39/0x121
1928 + [<f8b622b9>] ? __video_ioctl2+0x1aa/0x24a [videodev]
1929 + [<c04054fd>] ? do_notify_resume+0x768/0x795
1930 + [<c043c0f7>] ? getnstimeofday+0x34/0xd1
1931 + [<c0437b77>] ? autoremove_wake_function+0x0/0x33
1932 + [<f8b62368>] ? video_ioctl2+0xf/0x13 [videodev]
1933 + [<c048c6f0>] ? vfs_ioctl+0x50/0x69
1934 + [<c048c942>] ? do_vfs_ioctl+0x239/0x24c
1935 + [<c048c995>] ? sys_ioctl+0x40/0x5b
1936 + [<c0405bf2>] ? syscall_call+0x7/0xb
1937 + [<c0620000>] ? cpuid4_cache_sysfs_exit+0x3d/0x69
1938 + =======================
1939 +Code: Bad EIP value.
1940 +EIP: [<00000000>] 0x0 SS:ESP 0068:e2fd9d2c
1941 +
1942 +Signed-off-by: Mauro Carvalho Chehab <mchehab@××××××.com>
1943 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
1944 +
1945 +---
1946 + drivers/media/video/tvaudio.c | 15 +++++++--------
1947 + 1 file changed, 7 insertions(+), 8 deletions(-)
1948 +
1949 +--- a/drivers/media/video/tvaudio.c
1950 ++++ b/drivers/media/video/tvaudio.c
1951 +@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPS
1952 + return 0;
1953 + }
1954 + case V4L2_CID_AUDIO_BASS:
1955 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1956 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1957 + break;
1958 + ctrl->value = chip->bass;
1959 + return 0;
1960 + case V4L2_CID_AUDIO_TREBLE:
1961 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1962 +- return -EINVAL;
1963 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1964 ++ break;
1965 + ctrl->value = chip->treble;
1966 + return 0;
1967 + }
1968 +@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPS
1969 + return 0;
1970 + }
1971 + case V4L2_CID_AUDIO_BASS:
1972 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1973 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1974 + break;
1975 + chip->bass = ctrl->value;
1976 + chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
1977 +
1978 + return 0;
1979 + case V4L2_CID_AUDIO_TREBLE:
1980 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1981 +- return -EINVAL;
1982 +-
1983 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1984 ++ break;
1985 + chip->treble = ctrl->value;
1986 + chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
1987 +
1988 +@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_clien
1989 + break;
1990 + case V4L2_CID_AUDIO_BASS:
1991 + case V4L2_CID_AUDIO_TREBLE:
1992 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
1993 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
1994 + return -EINVAL;
1995 + break;
1996 + default:
1997
1998 Added: hardened/2.6/tags/2.6.26-10/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
1999 ===================================================================
2000 --- hardened/2.6/tags/2.6.26-10/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch (rev 0)
2001 +++ hardened/2.6/tags/2.6.26-10/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch 2009-01-21 00:11:21 UTC (rev 1482)
2002 @@ -0,0 +1,45 @@
2003 +Added-By: Gordon Malm <gengor@g.o>
2004 +
2005 +---
2006 +
2007 +From 17b24b3c97498935a2ef9777370b1151dfed3f6f Mon Sep 17 00:00:00 2001
2008 +From: Chas Williams <chas@××××××××××××.mil>
2009 +Date: Thu, 4 Dec 2008 14:58:13 -0800
2010 +Subject: ATM: CVE-2008-5079: duplicate listen() on socket corrupts the vcc table
2011 +
2012 +From: Chas Williams <chas@××××××××××××.mil>
2013 +
2014 +commit 17b24b3c97498935a2ef9777370b1151dfed3f6f upstream.
2015 +
2016 +As reported by Hugo Dias that it is possible to cause a local denial
2017 +of service attack by calling the svc_listen function twice on the same
2018 +socket and reading /proc/net/atm/*vc
2019 +
2020 +Signed-off-by: Chas Williams <chas@××××××××××××.mil>
2021 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2022 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2023 +
2024 +---
2025 +
2026 +--- a/net/atm/svc.c
2027 ++++ b/net/atm/svc.c
2028 +@@ -293,7 +293,10 @@ static int svc_listen(struct socket *soc
2029 + error = -EINVAL;
2030 + goto out;
2031 + }
2032 +- vcc_insert_socket(sk);
2033 ++ if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
2034 ++ error = -EADDRINUSE;
2035 ++ goto out;
2036 ++ }
2037 + set_bit(ATM_VF_WAITING, &vcc->flags);
2038 + prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
2039 + sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
2040 +@@ -307,6 +310,7 @@ static int svc_listen(struct socket *soc
2041 + goto out;
2042 + }
2043 + set_bit(ATM_VF_LISTEN,&vcc->flags);
2044 ++ vcc_insert_socket(sk);
2045 + sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
2046 + error = -sk->sk_err;
2047 + out:
2048
2049 Added: hardened/2.6/tags/2.6.26-10/1425_enforce-a-minimum-sg_io-timeout.patch
2050 ===================================================================
2051 --- hardened/2.6/tags/2.6.26-10/1425_enforce-a-minimum-sg_io-timeout.patch (rev 0)
2052 +++ hardened/2.6/tags/2.6.26-10/1425_enforce-a-minimum-sg_io-timeout.patch 2009-01-21 00:11:21 UTC (rev 1482)
2053 @@ -0,0 +1,64 @@
2054 +Added-By: Gordon Malm <gengor@g.o>
2055 +
2056 +---
2057 +
2058 +From f2f1fa78a155524b849edf359e42a3001ea652c0 Mon Sep 17 00:00:00 2001
2059 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
2060 +Date: Fri, 5 Dec 2008 14:49:18 -0800
2061 +Subject: Enforce a minimum SG_IO timeout
2062 +
2063 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
2064 +
2065 +commit f2f1fa78a155524b849edf359e42a3001ea652c0 upstream.
2066 +
2067 +There's no point in having too short SG_IO timeouts, since if the
2068 +command does end up timing out, we'll end up through the reset sequence
2069 +that is several seconds long in order to abort the command that timed
2070 +out.
2071 +
2072 +As a result, shorter timeouts than a few seconds simply do not make
2073 +sense, as the recovery would be longer than the timeout itself.
2074 +
2075 +Add a BLK_MIN_SG_TIMEOUT to match the existign BLK_DEFAULT_SG_TIMEOUT.
2076 +
2077 +Suggested-by: Alan Cox <alan@××××××××××××××××.uk>
2078 +Acked-by: Tejun Heo <tj@××××××.org>
2079 +Acked-by: Jens Axboe <jens.axboe@××××××.com>
2080 +Cc: Jeff Garzik <jeff@××××××.org>
2081 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2082 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2083 +
2084 +---
2085 +
2086 +--- a/block/bsg.c
2087 ++++ b/block/bsg.c
2088 +@@ -202,6 +202,8 @@ static int blk_fill_sgv4_hdr_rq(struct r
2089 + rq->timeout = q->sg_timeout;
2090 + if (!rq->timeout)
2091 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
2092 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
2093 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
2094 +
2095 + return 0;
2096 + }
2097 +--- a/block/scsi_ioctl.c
2098 ++++ b/block/scsi_ioctl.c
2099 +@@ -208,6 +208,8 @@ static int blk_fill_sghdr_rq(struct requ
2100 + rq->timeout = q->sg_timeout;
2101 + if (!rq->timeout)
2102 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
2103 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
2104 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
2105 +
2106 + return 0;
2107 + }
2108 +--- a/include/linux/blkdev.h
2109 ++++ b/include/linux/blkdev.h
2110 +@@ -623,6 +623,7 @@ extern unsigned long blk_max_low_pfn, bl
2111 + * default timeout for SG_IO if none specified
2112 + */
2113 + #define BLK_DEFAULT_SG_TIMEOUT (60 * HZ)
2114 ++#define BLK_MIN_SG_TIMEOUT (7 * HZ)
2115 +
2116 + #ifdef CONFIG_BOUNCE
2117 + extern int init_emergency_isa_pool(void);
2118
2119 Added: hardened/2.6/tags/2.6.26-10/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
2120 ===================================================================
2121 --- hardened/2.6/tags/2.6.26-10/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch (rev 0)
2122 +++ hardened/2.6/tags/2.6.26-10/1506_sctp-avoid_memory_overflow_with_bad_stream_ID.patch 2009-01-21 00:11:21 UTC (rev 1482)
2123 @@ -0,0 +1,80 @@
2124 +Added-By: Gordon Malm <gengor@g.o>
2125 +
2126 +Note: Re-diffed to eliminate failed hunks.
2127 +
2128 +---
2129 +
2130 +From: Wei Yongjun <yjwei@××××××××××.com>
2131 +Date: Fri, 26 Dec 2008 00:58:11 +0000 (-0800)
2132 +Subject: sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
2133 +X-Git-Tag: v2.6.29-rc1~581^2~75
2134 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9fcb95a105758b81ef0131cd18e2db5149f13e95
2135 +
2136 +sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
2137 +
2138 +If FWD-TSN chunk is received with bad stream ID, the sctp will not do the
2139 +validity check, this may cause memory overflow when overwrite the TSN of
2140 +the stream ID.
2141 +
2142 +The FORWARD-TSN chunk is like this:
2143 +
2144 +FORWARD-TSN chunk
2145 + Type = 192
2146 + Flags = 0
2147 + Length = 172
2148 + NewTSN = 99
2149 + Stream = 10000
2150 + StreamSequence = 0xFFFF
2151 +
2152 +This patch fix this problem by discard the chunk if stream ID is not
2153 +less than MIS.
2154 +
2155 +Signed-off-by: Wei Yongjun <yjwei@××××××××××.com>
2156 +Signed-off-by: Vlad Yasevich <vladislav.yasevich@××.com>
2157 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2158 +---
2159 +
2160 +--- a/net/sctp/sm_statefuns.c
2161 ++++ b/net/sctp/sm_statefuns.c
2162 +@@ -3641,6 +3641,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
2163 + {
2164 + struct sctp_chunk *chunk = arg;
2165 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
2166 ++ struct sctp_fwdtsn_skip *skip;
2167 + __u16 len;
2168 + __u32 tsn;
2169 +
2170 +@@ -3670,6 +3671,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
2171 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
2172 + goto discard_noforce;
2173 +
2174 ++ /* Silently discard the chunk if stream-id is not valid */
2175 ++ sctp_walk_fwdtsn(skip, chunk) {
2176 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
2177 ++ goto discard_noforce;
2178 ++ }
2179 ++
2180 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
2181 + if (len > sizeof(struct sctp_fwdtsn_hdr))
2182 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
2183 +@@ -3701,6 +3708,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
2184 + {
2185 + struct sctp_chunk *chunk = arg;
2186 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
2187 ++ struct sctp_fwdtsn_skip *skip;
2188 + __u16 len;
2189 + __u32 tsn;
2190 +
2191 +@@ -3730,6 +3738,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
2192 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
2193 + goto gen_shutdown;
2194 +
2195 ++ /* Silently discard the chunk if stream-id is not valid */
2196 ++ sctp_walk_fwdtsn(skip, chunk) {
2197 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
2198 ++ goto gen_shutdown;
2199 ++ }
2200 ++
2201 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
2202 + if (len > sizeof(struct sctp_fwdtsn_hdr))
2203 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
2204
2205 Added: hardened/2.6/tags/2.6.26-10/4420_grsec-2.1.12-2.6.26.6-200810131006.patch
2206 ===================================================================
2207 --- hardened/2.6/tags/2.6.26-10/4420_grsec-2.1.12-2.6.26.6-200810131006.patch (rev 0)
2208 +++ hardened/2.6/tags/2.6.26-10/4420_grsec-2.1.12-2.6.26.6-200810131006.patch 2009-01-21 00:11:21 UTC (rev 1482)
2209 @@ -0,0 +1,37662 @@
2210 +diff -urNp linux-2.6.26.6/arch/alpha/kernel/module.c linux-2.6.26.6/arch/alpha/kernel/module.c
2211 +--- linux-2.6.26.6/arch/alpha/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
2212 ++++ linux-2.6.26.6/arch/alpha/kernel/module.c 2008-10-11 21:54:18.000000000 -0400
2213 +@@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
2214 +
2215 + /* The small sections were sorted to the end of the segment.
2216 + The following should definitely cover them. */
2217 +- gp = (u64)me->module_core + me->core_size - 0x8000;
2218 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
2219 + got = sechdrs[me->arch.gotsecindex].sh_addr;
2220 +
2221 + for (i = 0; i < n; i++) {
2222 +diff -urNp linux-2.6.26.6/arch/alpha/kernel/osf_sys.c linux-2.6.26.6/arch/alpha/kernel/osf_sys.c
2223 +--- linux-2.6.26.6/arch/alpha/kernel/osf_sys.c 2008-10-08 23:24:05.000000000 -0400
2224 ++++ linux-2.6.26.6/arch/alpha/kernel/osf_sys.c 2008-10-11 21:54:18.000000000 -0400
2225 +@@ -1227,6 +1227,10 @@ arch_get_unmapped_area(struct file *filp
2226 + merely specific addresses, but regions of memory -- perhaps
2227 + this feature should be incorporated into all ports? */
2228 +
2229 ++#ifdef CONFIG_PAX_RANDMMAP
2230 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2231 ++#endif
2232 ++
2233 + if (addr) {
2234 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
2235 + if (addr != (unsigned long) -ENOMEM)
2236 +@@ -1234,8 +1238,8 @@ arch_get_unmapped_area(struct file *filp
2237 + }
2238 +
2239 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
2240 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
2241 +- len, limit);
2242 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
2243 ++
2244 + if (addr != (unsigned long) -ENOMEM)
2245 + return addr;
2246 +
2247 +diff -urNp linux-2.6.26.6/arch/alpha/kernel/ptrace.c linux-2.6.26.6/arch/alpha/kernel/ptrace.c
2248 +--- linux-2.6.26.6/arch/alpha/kernel/ptrace.c 2008-10-08 23:24:05.000000000 -0400
2249 ++++ linux-2.6.26.6/arch/alpha/kernel/ptrace.c 2008-10-11 21:54:18.000000000 -0400
2250 +@@ -15,6 +15,7 @@
2251 + #include <linux/slab.h>
2252 + #include <linux/security.h>
2253 + #include <linux/signal.h>
2254 ++#include <linux/grsecurity.h>
2255 +
2256 + #include <asm/uaccess.h>
2257 + #include <asm/pgtable.h>
2258 +@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
2259 + size_t copied;
2260 + long ret;
2261 +
2262 ++ if (gr_handle_ptrace(child, request))
2263 ++ return -EPERM;
2264 ++
2265 + switch (request) {
2266 + /* When I and D space are separate, these will need to be fixed. */
2267 + case PTRACE_PEEKTEXT: /* read word at location addr. */
2268 +diff -urNp linux-2.6.26.6/arch/alpha/mm/fault.c linux-2.6.26.6/arch/alpha/mm/fault.c
2269 +--- linux-2.6.26.6/arch/alpha/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2270 ++++ linux-2.6.26.6/arch/alpha/mm/fault.c 2008-10-11 21:54:18.000000000 -0400
2271 +@@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
2272 + __reload_thread(pcb);
2273 + }
2274 +
2275 ++#ifdef CONFIG_PAX_PAGEEXEC
2276 ++/*
2277 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
2278 ++ *
2279 ++ * returns 1 when task should be killed
2280 ++ * 2 when patched PLT trampoline was detected
2281 ++ * 3 when unpatched PLT trampoline was detected
2282 ++ */
2283 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
2284 ++{
2285 ++
2286 ++#ifdef CONFIG_PAX_EMUPLT
2287 ++ int err;
2288 ++
2289 ++ do { /* PaX: patched PLT emulation #1 */
2290 ++ unsigned int ldah, ldq, jmp;
2291 ++
2292 ++ err = get_user(ldah, (unsigned int *)regs->pc);
2293 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
2294 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
2295 ++
2296 ++ if (err)
2297 ++ break;
2298 ++
2299 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
2300 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
2301 ++ jmp == 0x6BFB0000U)
2302 ++ {
2303 ++ unsigned long r27, addr;
2304 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
2305 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
2306 ++
2307 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
2308 ++ err = get_user(r27, (unsigned long *)addr);
2309 ++ if (err)
2310 ++ break;
2311 ++
2312 ++ regs->r27 = r27;
2313 ++ regs->pc = r27;
2314 ++ return 2;
2315 ++ }
2316 ++ } while (0);
2317 ++
2318 ++ do { /* PaX: patched PLT emulation #2 */
2319 ++ unsigned int ldah, lda, br;
2320 ++
2321 ++ err = get_user(ldah, (unsigned int *)regs->pc);
2322 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
2323 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
2324 ++
2325 ++ if (err)
2326 ++ break;
2327 ++
2328 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
2329 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
2330 ++ (br & 0xFFE00000U) == 0xC3E00000U)
2331 ++ {
2332 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
2333 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
2334 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
2335 ++
2336 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
2337 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
2338 ++ return 2;
2339 ++ }
2340 ++ } while (0);
2341 ++
2342 ++ do { /* PaX: unpatched PLT emulation */
2343 ++ unsigned int br;
2344 ++
2345 ++ err = get_user(br, (unsigned int *)regs->pc);
2346 ++
2347 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
2348 ++ unsigned int br2, ldq, nop, jmp;
2349 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
2350 ++
2351 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
2352 ++ err = get_user(br2, (unsigned int *)addr);
2353 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
2354 ++ err |= get_user(nop, (unsigned int *)(addr+8));
2355 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
2356 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
2357 ++
2358 ++ if (err)
2359 ++ break;
2360 ++
2361 ++ if (br2 == 0xC3600000U &&
2362 ++ ldq == 0xA77B000CU &&
2363 ++ nop == 0x47FF041FU &&
2364 ++ jmp == 0x6B7B0000U)
2365 ++ {
2366 ++ regs->r28 = regs->pc+4;
2367 ++ regs->r27 = addr+16;
2368 ++ regs->pc = resolver;
2369 ++ return 3;
2370 ++ }
2371 ++ }
2372 ++ } while (0);
2373 ++#endif
2374 ++
2375 ++ return 1;
2376 ++}
2377 ++
2378 ++void pax_report_insns(void *pc, void *sp)
2379 ++{
2380 ++ unsigned long i;
2381 ++
2382 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2383 ++ for (i = 0; i < 5; i++) {
2384 ++ unsigned int c;
2385 ++ if (get_user(c, (unsigned int *)pc+i))
2386 ++ printk(KERN_CONT "???????? ");
2387 ++ else
2388 ++ printk(KERN_CONT "%08x ", c);
2389 ++ }
2390 ++ printk("\n");
2391 ++}
2392 ++#endif
2393 +
2394 + /*
2395 + * This routine handles page faults. It determines the address,
2396 +@@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
2397 + good_area:
2398 + si_code = SEGV_ACCERR;
2399 + if (cause < 0) {
2400 +- if (!(vma->vm_flags & VM_EXEC))
2401 ++ if (!(vma->vm_flags & VM_EXEC)) {
2402 ++
2403 ++#ifdef CONFIG_PAX_PAGEEXEC
2404 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
2405 ++ goto bad_area;
2406 ++
2407 ++ up_read(&mm->mmap_sem);
2408 ++ switch (pax_handle_fetch_fault(regs)) {
2409 ++
2410 ++#ifdef CONFIG_PAX_EMUPLT
2411 ++ case 2:
2412 ++ case 3:
2413 ++ return;
2414 ++#endif
2415 ++
2416 ++ }
2417 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
2418 ++ do_group_exit(SIGKILL);
2419 ++#else
2420 + goto bad_area;
2421 ++#endif
2422 ++
2423 ++ }
2424 + } else if (!cause) {
2425 + /* Allow reads even for write-only mappings */
2426 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
2427 +diff -urNp linux-2.6.26.6/arch/arm/mm/mmap.c linux-2.6.26.6/arch/arm/mm/mmap.c
2428 +--- linux-2.6.26.6/arch/arm/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
2429 ++++ linux-2.6.26.6/arch/arm/mm/mmap.c 2008-10-11 21:54:19.000000000 -0400
2430 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
2431 + if (len > TASK_SIZE)
2432 + return -ENOMEM;
2433 +
2434 ++#ifdef CONFIG_PAX_RANDMMAP
2435 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2436 ++#endif
2437 ++
2438 + if (addr) {
2439 + if (do_align)
2440 + addr = COLOUR_ALIGN(addr, pgoff);
2441 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
2442 + return addr;
2443 + }
2444 + if (len > mm->cached_hole_size) {
2445 +- start_addr = addr = mm->free_area_cache;
2446 ++ start_addr = addr = mm->free_area_cache;
2447 + } else {
2448 +- start_addr = addr = TASK_UNMAPPED_BASE;
2449 +- mm->cached_hole_size = 0;
2450 ++ start_addr = addr = mm->mmap_base;
2451 ++ mm->cached_hole_size = 0;
2452 + }
2453 +
2454 + full_search:
2455 +@@ -91,8 +95,8 @@ full_search:
2456 + * Start a new search - just in case we missed
2457 + * some holes.
2458 + */
2459 +- if (start_addr != TASK_UNMAPPED_BASE) {
2460 +- start_addr = addr = TASK_UNMAPPED_BASE;
2461 ++ if (start_addr != mm->mmap_base) {
2462 ++ start_addr = addr = mm->mmap_base;
2463 + mm->cached_hole_size = 0;
2464 + goto full_search;
2465 + }
2466 +diff -urNp linux-2.6.26.6/arch/avr32/mm/fault.c linux-2.6.26.6/arch/avr32/mm/fault.c
2467 +--- linux-2.6.26.6/arch/avr32/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2468 ++++ linux-2.6.26.6/arch/avr32/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2469 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
2470 +
2471 + int exception_trace = 1;
2472 +
2473 ++#ifdef CONFIG_PAX_PAGEEXEC
2474 ++void pax_report_insns(void *pc, void *sp)
2475 ++{
2476 ++ unsigned long i;
2477 ++
2478 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2479 ++ for (i = 0; i < 20; i++) {
2480 ++ unsigned char c;
2481 ++ if (get_user(c, (unsigned char *)pc+i))
2482 ++ printk(KERN_CONT "???????? ");
2483 ++ else
2484 ++ printk(KERN_CONT "%02x ", c);
2485 ++ }
2486 ++ printk("\n");
2487 ++}
2488 ++#endif
2489 ++
2490 + /*
2491 + * This routine handles page faults. It determines the address and the
2492 + * problem, and then passes it off to one of the appropriate routines.
2493 +@@ -157,6 +174,16 @@ bad_area:
2494 + up_read(&mm->mmap_sem);
2495 +
2496 + if (user_mode(regs)) {
2497 ++
2498 ++#ifdef CONFIG_PAX_PAGEEXEC
2499 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
2500 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
2501 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
2502 ++ do_group_exit(SIGKILL);
2503 ++ }
2504 ++ }
2505 ++#endif
2506 ++
2507 + if (exception_trace && printk_ratelimit())
2508 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
2509 + "sp %08lx ecr %lu\n",
2510 +diff -urNp linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c
2511 +--- linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c 2008-10-08 23:24:05.000000000 -0400
2512 ++++ linux-2.6.26.6/arch/ia64/ia32/binfmt_elf32.c 2008-10-11 21:54:19.000000000 -0400
2513 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
2514 +
2515 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
2516 +
2517 ++#ifdef CONFIG_PAX_ASLR
2518 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
2519 ++
2520 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
2521 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
2522 ++#endif
2523 ++
2524 + /* Ugly but avoids duplication */
2525 + #include "../../../fs/binfmt_elf.c"
2526 +
2527 +diff -urNp linux-2.6.26.6/arch/ia64/ia32/ia32priv.h linux-2.6.26.6/arch/ia64/ia32/ia32priv.h
2528 +--- linux-2.6.26.6/arch/ia64/ia32/ia32priv.h 2008-10-08 23:24:05.000000000 -0400
2529 ++++ linux-2.6.26.6/arch/ia64/ia32/ia32priv.h 2008-10-11 21:54:19.000000000 -0400
2530 +@@ -303,7 +303,14 @@ struct old_linux32_dirent {
2531 + #define ELF_DATA ELFDATA2LSB
2532 + #define ELF_ARCH EM_386
2533 +
2534 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
2535 ++#ifdef CONFIG_PAX_RANDUSTACK
2536 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
2537 ++#else
2538 ++#define __IA32_DELTA_STACK 0UL
2539 ++#endif
2540 ++
2541 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
2542 ++
2543 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
2544 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
2545 +
2546 +diff -urNp linux-2.6.26.6/arch/ia64/kernel/module.c linux-2.6.26.6/arch/ia64/kernel/module.c
2547 +--- linux-2.6.26.6/arch/ia64/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
2548 ++++ linux-2.6.26.6/arch/ia64/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
2549 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
2550 + void
2551 + module_free (struct module *mod, void *module_region)
2552 + {
2553 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
2554 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
2555 + unw_remove_unwind_table(mod->arch.init_unw_table);
2556 + mod->arch.init_unw_table = NULL;
2557 + }
2558 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
2559 + }
2560 +
2561 + static inline int
2562 ++in_init_rx (const struct module *mod, uint64_t addr)
2563 ++{
2564 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
2565 ++}
2566 ++
2567 ++static inline int
2568 ++in_init_rw (const struct module *mod, uint64_t addr)
2569 ++{
2570 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
2571 ++}
2572 ++
2573 ++static inline int
2574 + in_init (const struct module *mod, uint64_t addr)
2575 + {
2576 +- return addr - (uint64_t) mod->module_init < mod->init_size;
2577 ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
2578 ++}
2579 ++
2580 ++static inline int
2581 ++in_core_rx (const struct module *mod, uint64_t addr)
2582 ++{
2583 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
2584 ++}
2585 ++
2586 ++static inline int
2587 ++in_core_rw (const struct module *mod, uint64_t addr)
2588 ++{
2589 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
2590 + }
2591 +
2592 + static inline int
2593 + in_core (const struct module *mod, uint64_t addr)
2594 + {
2595 +- return addr - (uint64_t) mod->module_core < mod->core_size;
2596 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
2597 + }
2598 +
2599 + static inline int
2600 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
2601 + break;
2602 +
2603 + case RV_BDREL:
2604 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
2605 ++ if (in_init_rx(mod, val))
2606 ++ val -= (uint64_t) mod->module_init_rx;
2607 ++ else if (in_init_rw(mod, val))
2608 ++ val -= (uint64_t) mod->module_init_rw;
2609 ++ else if (in_core_rx(mod, val))
2610 ++ val -= (uint64_t) mod->module_core_rx;
2611 ++ else if (in_core_rw(mod, val))
2612 ++ val -= (uint64_t) mod->module_core_rw;
2613 + break;
2614 +
2615 + case RV_LTV:
2616 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
2617 + * addresses have been selected...
2618 + */
2619 + uint64_t gp;
2620 +- if (mod->core_size > MAX_LTOFF)
2621 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
2622 + /*
2623 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
2624 + * at the end of the module.
2625 + */
2626 +- gp = mod->core_size - MAX_LTOFF / 2;
2627 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
2628 + else
2629 +- gp = mod->core_size / 2;
2630 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
2631 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
2632 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
2633 + mod->arch.gp = gp;
2634 + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
2635 + }
2636 +diff -urNp linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c
2637 +--- linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c 2008-10-08 23:24:05.000000000 -0400
2638 ++++ linux-2.6.26.6/arch/ia64/kernel/sys_ia64.c 2008-10-11 21:54:19.000000000 -0400
2639 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
2640 + if (REGION_NUMBER(addr) == RGN_HPAGE)
2641 + addr = 0;
2642 + #endif
2643 ++
2644 ++#ifdef CONFIG_PAX_RANDMMAP
2645 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
2646 ++ addr = mm->free_area_cache;
2647 ++ else
2648 ++#endif
2649 ++
2650 + if (!addr)
2651 + addr = mm->free_area_cache;
2652 +
2653 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
2654 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2655 + /* At this point: (!vma || addr < vma->vm_end). */
2656 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
2657 +- if (start_addr != TASK_UNMAPPED_BASE) {
2658 ++ if (start_addr != mm->mmap_base) {
2659 + /* Start a new search --- just in case we missed some holes. */
2660 +- addr = TASK_UNMAPPED_BASE;
2661 ++ addr = mm->mmap_base;
2662 + goto full_search;
2663 + }
2664 + return -ENOMEM;
2665 +diff -urNp linux-2.6.26.6/arch/ia64/mm/fault.c linux-2.6.26.6/arch/ia64/mm/fault.c
2666 +--- linux-2.6.26.6/arch/ia64/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2667 ++++ linux-2.6.26.6/arch/ia64/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2668 +@@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned
2669 + return pte_present(pte);
2670 + }
2671 +
2672 ++#ifdef CONFIG_PAX_PAGEEXEC
2673 ++void pax_report_insns(void *pc, void *sp)
2674 ++{
2675 ++ unsigned long i;
2676 ++
2677 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2678 ++ for (i = 0; i < 8; i++) {
2679 ++ unsigned int c;
2680 ++ if (get_user(c, (unsigned int *)pc+i))
2681 ++ printk(KERN_CONT "???????? ");
2682 ++ else
2683 ++ printk(KERN_CONT "%08x ", c);
2684 ++ }
2685 ++ printk("\n");
2686 ++}
2687 ++#endif
2688 ++
2689 + void __kprobes
2690 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
2691 + {
2692 +@@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
2693 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
2694 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
2695 +
2696 +- if ((vma->vm_flags & mask) != mask)
2697 ++ if ((vma->vm_flags & mask) != mask) {
2698 ++
2699 ++#ifdef CONFIG_PAX_PAGEEXEC
2700 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
2701 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
2702 ++ goto bad_area;
2703 ++
2704 ++ up_read(&mm->mmap_sem);
2705 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
2706 ++ do_group_exit(SIGKILL);
2707 ++ }
2708 ++#endif
2709 ++
2710 + goto bad_area;
2711 +
2712 ++ }
2713 ++
2714 + survive:
2715 + /*
2716 + * If for any reason at all we couldn't handle the fault, make
2717 +diff -urNp linux-2.6.26.6/arch/ia64/mm/init.c linux-2.6.26.6/arch/ia64/mm/init.c
2718 +--- linux-2.6.26.6/arch/ia64/mm/init.c 2008-10-08 23:24:05.000000000 -0400
2719 ++++ linux-2.6.26.6/arch/ia64/mm/init.c 2008-10-11 21:54:19.000000000 -0400
2720 +@@ -122,6 +122,19 @@ ia64_init_addr_space (void)
2721 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
2722 + vma->vm_end = vma->vm_start + PAGE_SIZE;
2723 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
2724 ++
2725 ++#ifdef CONFIG_PAX_PAGEEXEC
2726 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
2727 ++ vma->vm_flags &= ~VM_EXEC;
2728 ++
2729 ++#ifdef CONFIG_PAX_MPROTECT
2730 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
2731 ++ vma->vm_flags &= ~VM_MAYEXEC;
2732 ++#endif
2733 ++
2734 ++ }
2735 ++#endif
2736 ++
2737 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2738 + down_write(&current->mm->mmap_sem);
2739 + if (insert_vm_struct(current->mm, vma)) {
2740 +diff -urNp linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c
2741 +--- linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c 2008-10-08 23:24:05.000000000 -0400
2742 ++++ linux-2.6.26.6/arch/mips/kernel/binfmt_elfn32.c 2008-10-11 21:54:19.000000000 -0400
2743 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
2744 + #undef ELF_ET_DYN_BASE
2745 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
2746 +
2747 ++#ifdef CONFIG_PAX_ASLR
2748 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2749 ++
2750 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2751 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2752 ++#endif
2753 ++
2754 + #include <asm/processor.h>
2755 + #include <linux/module.h>
2756 + #include <linux/elfcore.h>
2757 +diff -urNp linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c
2758 +--- linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c 2008-10-08 23:24:05.000000000 -0400
2759 ++++ linux-2.6.26.6/arch/mips/kernel/binfmt_elfo32.c 2008-10-11 21:54:19.000000000 -0400
2760 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
2761 + #undef ELF_ET_DYN_BASE
2762 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
2763 +
2764 ++#ifdef CONFIG_PAX_ASLR
2765 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
2766 ++
2767 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2768 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
2769 ++#endif
2770 ++
2771 + #include <asm/processor.h>
2772 + #include <linux/module.h>
2773 + #include <linux/elfcore.h>
2774 +diff -urNp linux-2.6.26.6/arch/mips/kernel/syscall.c linux-2.6.26.6/arch/mips/kernel/syscall.c
2775 +--- linux-2.6.26.6/arch/mips/kernel/syscall.c 2008-10-08 23:24:05.000000000 -0400
2776 ++++ linux-2.6.26.6/arch/mips/kernel/syscall.c 2008-10-11 21:54:19.000000000 -0400
2777 +@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
2778 + do_color_align = 0;
2779 + if (filp || (flags & MAP_SHARED))
2780 + do_color_align = 1;
2781 ++
2782 ++#ifdef CONFIG_PAX_RANDMMAP
2783 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2784 ++#endif
2785 ++
2786 + if (addr) {
2787 + if (do_color_align)
2788 + addr = COLOUR_ALIGN(addr, pgoff);
2789 +@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
2790 + (!vmm || addr + len <= vmm->vm_start))
2791 + return addr;
2792 + }
2793 +- addr = TASK_UNMAPPED_BASE;
2794 ++ addr = current->mm->mmap_base;
2795 + if (do_color_align)
2796 + addr = COLOUR_ALIGN(addr, pgoff);
2797 + else
2798 +diff -urNp linux-2.6.26.6/arch/mips/mm/fault.c linux-2.6.26.6/arch/mips/mm/fault.c
2799 +--- linux-2.6.26.6/arch/mips/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2800 ++++ linux-2.6.26.6/arch/mips/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2801 +@@ -26,6 +26,23 @@
2802 + #include <asm/ptrace.h>
2803 + #include <asm/highmem.h> /* For VMALLOC_END */
2804 +
2805 ++#ifdef CONFIG_PAX_PAGEEXEC
2806 ++void pax_report_insns(void *pc)
2807 ++{
2808 ++ unsigned long i;
2809 ++
2810 ++ printk(KERN_ERR "PAX: bytes at PC: ");
2811 ++ for (i = 0; i < 5; i++) {
2812 ++ unsigned int c;
2813 ++ if (get_user(c, (unsigned int *)pc+i))
2814 ++ printk(KERN_CONT "???????? ");
2815 ++ else
2816 ++ printk(KERN_CONT "%08x ", c);
2817 ++ }
2818 ++ printk("\n");
2819 ++}
2820 ++#endif
2821 ++
2822 + /*
2823 + * This routine handles page faults. It determines the address,
2824 + * and the problem, and then passes it off to one of the appropriate
2825 +diff -urNp linux-2.6.26.6/arch/parisc/kernel/module.c linux-2.6.26.6/arch/parisc/kernel/module.c
2826 +--- linux-2.6.26.6/arch/parisc/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
2827 ++++ linux-2.6.26.6/arch/parisc/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
2828 +@@ -73,16 +73,38 @@
2829 +
2830 + /* three functions to determine where in the module core
2831 + * or init pieces the location is */
2832 ++static inline int in_init_rx(struct module *me, void *loc)
2833 ++{
2834 ++ return (loc >= me->module_init_rx &&
2835 ++ loc < (me->module_init_rx + me->init_size_rx));
2836 ++}
2837 ++
2838 ++static inline int in_init_rw(struct module *me, void *loc)
2839 ++{
2840 ++ return (loc >= me->module_init_rw &&
2841 ++ loc < (me->module_init_rw + me->init_size_rw));
2842 ++}
2843 ++
2844 + static inline int in_init(struct module *me, void *loc)
2845 + {
2846 +- return (loc >= me->module_init &&
2847 +- loc <= (me->module_init + me->init_size));
2848 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
2849 ++}
2850 ++
2851 ++static inline int in_core_rx(struct module *me, void *loc)
2852 ++{
2853 ++ return (loc >= me->module_core_rx &&
2854 ++ loc < (me->module_core_rx + me->core_size_rx));
2855 ++}
2856 ++
2857 ++static inline int in_core_rw(struct module *me, void *loc)
2858 ++{
2859 ++ return (loc >= me->module_core_rw &&
2860 ++ loc < (me->module_core_rw + me->core_size_rw));
2861 + }
2862 +
2863 + static inline int in_core(struct module *me, void *loc)
2864 + {
2865 +- return (loc >= me->module_core &&
2866 +- loc <= (me->module_core + me->core_size));
2867 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
2868 + }
2869 +
2870 + static inline int in_local(struct module *me, void *loc)
2871 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
2872 + }
2873 +
2874 + /* align things a bit */
2875 +- me->core_size = ALIGN(me->core_size, 16);
2876 +- me->arch.got_offset = me->core_size;
2877 +- me->core_size += gots * sizeof(struct got_entry);
2878 +-
2879 +- me->core_size = ALIGN(me->core_size, 16);
2880 +- me->arch.fdesc_offset = me->core_size;
2881 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
2882 +-
2883 +- me->core_size = ALIGN(me->core_size, 16);
2884 +- me->arch.stub_offset = me->core_size;
2885 +- me->core_size += stubs * sizeof(struct stub_entry);
2886 +-
2887 +- me->init_size = ALIGN(me->init_size, 16);
2888 +- me->arch.init_stub_offset = me->init_size;
2889 +- me->init_size += init_stubs * sizeof(struct stub_entry);
2890 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
2891 ++ me->arch.got_offset = me->core_size_rw;
2892 ++ me->core_size_rw += gots * sizeof(struct got_entry);
2893 ++
2894 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
2895 ++ me->arch.fdesc_offset = me->core_size_rw;
2896 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
2897 ++
2898 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
2899 ++ me->arch.stub_offset = me->core_size_rx;
2900 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
2901 ++
2902 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
2903 ++ me->arch.init_stub_offset = me->init_size_rx;
2904 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
2905 +
2906 + me->arch.got_max = gots;
2907 + me->arch.fdesc_max = fdescs;
2908 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
2909 +
2910 + BUG_ON(value == 0);
2911 +
2912 +- got = me->module_core + me->arch.got_offset;
2913 ++ got = me->module_core_rw + me->arch.got_offset;
2914 + for (i = 0; got[i].addr; i++)
2915 + if (got[i].addr == value)
2916 + goto out;
2917 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
2918 + #ifdef CONFIG_64BIT
2919 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
2920 + {
2921 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
2922 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
2923 +
2924 + if (!value) {
2925 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
2926 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
2927 +
2928 + /* Create new one */
2929 + fdesc->addr = value;
2930 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
2931 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
2932 + return (Elf_Addr)fdesc;
2933 + }
2934 + #endif /* CONFIG_64BIT */
2935 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
2936 + if(init_section) {
2937 + i = me->arch.init_stub_count++;
2938 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
2939 +- stub = me->module_init + me->arch.init_stub_offset +
2940 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
2941 + i * sizeof(struct stub_entry);
2942 + } else {
2943 + i = me->arch.stub_count++;
2944 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
2945 +- stub = me->module_core + me->arch.stub_offset +
2946 ++ stub = me->module_core_rx + me->arch.stub_offset +
2947 + i * sizeof(struct stub_entry);
2948 + }
2949 +
2950 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
2951 +
2952 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
2953 + end = table + sechdrs[me->arch.unwind_section].sh_size;
2954 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
2955 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
2956 +
2957 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
2958 + me->arch.unwind_section, table, end, gp);
2959 +diff -urNp linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c
2960 +--- linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c 2008-10-08 23:24:05.000000000 -0400
2961 ++++ linux-2.6.26.6/arch/parisc/kernel/sys_parisc.c 2008-10-11 21:54:19.000000000 -0400
2962 +@@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
2963 + if (flags & MAP_FIXED)
2964 + return addr;
2965 + if (!addr)
2966 +- addr = TASK_UNMAPPED_BASE;
2967 ++ addr = current->mm->mmap_base;
2968 +
2969 + if (filp) {
2970 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
2971 +diff -urNp linux-2.6.26.6/arch/parisc/kernel/traps.c linux-2.6.26.6/arch/parisc/kernel/traps.c
2972 +--- linux-2.6.26.6/arch/parisc/kernel/traps.c 2008-10-08 23:24:05.000000000 -0400
2973 ++++ linux-2.6.26.6/arch/parisc/kernel/traps.c 2008-10-11 21:54:19.000000000 -0400
2974 +@@ -732,9 +732,7 @@ void handle_interruption(int code, struc
2975 +
2976 + down_read(&current->mm->mmap_sem);
2977 + vma = find_vma(current->mm,regs->iaoq[0]);
2978 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
2979 +- && (vma->vm_flags & VM_EXEC)) {
2980 +-
2981 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
2982 + fault_address = regs->iaoq[0];
2983 + fault_space = regs->iasq[0];
2984 +
2985 +diff -urNp linux-2.6.26.6/arch/parisc/mm/fault.c linux-2.6.26.6/arch/parisc/mm/fault.c
2986 +--- linux-2.6.26.6/arch/parisc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
2987 ++++ linux-2.6.26.6/arch/parisc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
2988 +@@ -16,6 +16,7 @@
2989 + #include <linux/sched.h>
2990 + #include <linux/interrupt.h>
2991 + #include <linux/module.h>
2992 ++#include <linux/unistd.h>
2993 +
2994 + #include <asm/uaccess.h>
2995 + #include <asm/traps.h>
2996 +@@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
2997 + static unsigned long
2998 + parisc_acctyp(unsigned long code, unsigned int inst)
2999 + {
3000 +- if (code == 6 || code == 16)
3001 ++ if (code == 6 || code == 7 || code == 16)
3002 + return VM_EXEC;
3003 +
3004 + switch (inst & 0xf0000000) {
3005 +@@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
3006 + }
3007 + #endif
3008 +
3009 ++#ifdef CONFIG_PAX_PAGEEXEC
3010 ++/*
3011 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
3012 ++ *
3013 ++ * returns 1 when task should be killed
3014 ++ * 2 when rt_sigreturn trampoline was detected
3015 ++ * 3 when unpatched PLT trampoline was detected
3016 ++ */
3017 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
3018 ++{
3019 ++
3020 ++#ifdef CONFIG_PAX_EMUPLT
3021 ++ int err;
3022 ++
3023 ++ do { /* PaX: unpatched PLT emulation */
3024 ++ unsigned int bl, depwi;
3025 ++
3026 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
3027 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
3028 ++
3029 ++ if (err)
3030 ++ break;
3031 ++
3032 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
3033 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
3034 ++
3035 ++ err = get_user(ldw, (unsigned int *)addr);
3036 ++ err |= get_user(bv, (unsigned int *)(addr+4));
3037 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
3038 ++
3039 ++ if (err)
3040 ++ break;
3041 ++
3042 ++ if (ldw == 0x0E801096U &&
3043 ++ bv == 0xEAC0C000U &&
3044 ++ ldw2 == 0x0E881095U)
3045 ++ {
3046 ++ unsigned int resolver, map;
3047 ++
3048 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
3049 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
3050 ++ if (err)
3051 ++ break;
3052 ++
3053 ++ regs->gr[20] = instruction_pointer(regs)+8;
3054 ++ regs->gr[21] = map;
3055 ++ regs->gr[22] = resolver;
3056 ++ regs->iaoq[0] = resolver | 3UL;
3057 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
3058 ++ return 3;
3059 ++ }
3060 ++ }
3061 ++ } while (0);
3062 ++#endif
3063 ++
3064 ++#ifdef CONFIG_PAX_EMUTRAMP
3065 ++
3066 ++#ifndef CONFIG_PAX_EMUSIGRT
3067 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
3068 ++ return 1;
3069 ++#endif
3070 ++
3071 ++ do { /* PaX: rt_sigreturn emulation */
3072 ++ unsigned int ldi1, ldi2, bel, nop;
3073 ++
3074 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
3075 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
3076 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
3077 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
3078 ++
3079 ++ if (err)
3080 ++ break;
3081 ++
3082 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
3083 ++ ldi2 == 0x3414015AU &&
3084 ++ bel == 0xE4008200U &&
3085 ++ nop == 0x08000240U)
3086 ++ {
3087 ++ regs->gr[25] = (ldi1 & 2) >> 1;
3088 ++ regs->gr[20] = __NR_rt_sigreturn;
3089 ++ regs->gr[31] = regs->iaoq[1] + 16;
3090 ++ regs->sr[0] = regs->iasq[1];
3091 ++ regs->iaoq[0] = 0x100UL;
3092 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
3093 ++ regs->iasq[0] = regs->sr[2];
3094 ++ regs->iasq[1] = regs->sr[2];
3095 ++ return 2;
3096 ++ }
3097 ++ } while (0);
3098 ++#endif
3099 ++
3100 ++ return 1;
3101 ++}
3102 ++
3103 ++void pax_report_insns(void *pc, void *sp)
3104 ++{
3105 ++ unsigned long i;
3106 ++
3107 ++ printk(KERN_ERR "PAX: bytes at PC: ");
3108 ++ for (i = 0; i < 5; i++) {
3109 ++ unsigned int c;
3110 ++ if (get_user(c, (unsigned int *)pc+i))
3111 ++ printk(KERN_CONT "???????? ");
3112 ++ else
3113 ++ printk(KERN_CONT "%08x ", c);
3114 ++ }
3115 ++ printk("\n");
3116 ++}
3117 ++#endif
3118 ++
3119 + void do_page_fault(struct pt_regs *regs, unsigned long code,
3120 + unsigned long address)
3121 + {
3122 +@@ -165,8 +276,33 @@ good_area:
3123 +
3124 + acc_type = parisc_acctyp(code,regs->iir);
3125 +
3126 +- if ((vma->vm_flags & acc_type) != acc_type)
3127 ++ if ((vma->vm_flags & acc_type) != acc_type) {
3128 ++
3129 ++#ifdef CONFIG_PAX_PAGEEXEC
3130 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
3131 ++ (address & ~3UL) == instruction_pointer(regs))
3132 ++ {
3133 ++ up_read(&mm->mmap_sem);
3134 ++ switch (pax_handle_fetch_fault(regs)) {
3135 ++
3136 ++#ifdef CONFIG_PAX_EMUPLT
3137 ++ case 3:
3138 ++ return;
3139 ++#endif
3140 ++
3141 ++#ifdef CONFIG_PAX_EMUTRAMP
3142 ++ case 2:
3143 ++ return;
3144 ++#endif
3145 ++
3146 ++ }
3147 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
3148 ++ do_group_exit(SIGKILL);
3149 ++ }
3150 ++#endif
3151 ++
3152 + goto bad_area;
3153 ++ }
3154 +
3155 + /*
3156 + * If for any reason at all we couldn't handle the fault, make
3157 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/module_32.c linux-2.6.26.6/arch/powerpc/kernel/module_32.c
3158 +--- linux-2.6.26.6/arch/powerpc/kernel/module_32.c 2008-10-08 23:24:05.000000000 -0400
3159 ++++ linux-2.6.26.6/arch/powerpc/kernel/module_32.c 2008-10-11 21:54:19.000000000 -0400
3160 +@@ -175,7 +175,7 @@ int module_frob_arch_sections(Elf32_Ehdr
3161 + me->arch.core_plt_section = i;
3162 + }
3163 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
3164 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
3165 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
3166 + return -ENOEXEC;
3167 + }
3168 +
3169 +@@ -216,11 +216,16 @@ static uint32_t do_plt_call(void *locati
3170 +
3171 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
3172 + /* Init, or core PLT? */
3173 +- if (location >= mod->module_core
3174 +- && location < mod->module_core + mod->core_size)
3175 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
3176 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
3177 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
3178 +- else
3179 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
3180 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
3181 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
3182 ++ else {
3183 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
3184 ++ return ~0UL;
3185 ++ }
3186 +
3187 + /* Find this entry, or if that fails, the next avail. entry */
3188 + while (entry->jump[0]) {
3189 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/signal_32.c linux-2.6.26.6/arch/powerpc/kernel/signal_32.c
3190 +--- linux-2.6.26.6/arch/powerpc/kernel/signal_32.c 2008-10-08 23:24:05.000000000 -0400
3191 ++++ linux-2.6.26.6/arch/powerpc/kernel/signal_32.c 2008-10-11 21:54:19.000000000 -0400
3192 +@@ -743,7 +743,7 @@ int handle_rt_signal32(unsigned long sig
3193 + /* Save user registers on the stack */
3194 + frame = &rt_sf->uc.uc_mcontext;
3195 + addr = frame;
3196 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
3197 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
3198 + if (save_user_regs(regs, frame, 0))
3199 + goto badframe;
3200 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
3201 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/signal_64.c linux-2.6.26.6/arch/powerpc/kernel/signal_64.c
3202 +--- linux-2.6.26.6/arch/powerpc/kernel/signal_64.c 2008-10-08 23:24:05.000000000 -0400
3203 ++++ linux-2.6.26.6/arch/powerpc/kernel/signal_64.c 2008-10-11 21:54:19.000000000 -0400
3204 +@@ -371,7 +371,7 @@ int handle_rt_signal64(int signr, struct
3205 + current->thread.fpscr.val = 0;
3206 +
3207 + /* Set up to return from userspace. */
3208 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
3209 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
3210 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
3211 + } else {
3212 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
3213 +diff -urNp linux-2.6.26.6/arch/powerpc/kernel/vdso.c linux-2.6.26.6/arch/powerpc/kernel/vdso.c
3214 +--- linux-2.6.26.6/arch/powerpc/kernel/vdso.c 2008-10-08 23:24:05.000000000 -0400
3215 ++++ linux-2.6.26.6/arch/powerpc/kernel/vdso.c 2008-10-11 21:54:19.000000000 -0400
3216 +@@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
3217 + vdso_base = VDSO32_MBASE;
3218 + #endif
3219 +
3220 +- current->mm->context.vdso_base = 0;
3221 ++ current->mm->context.vdso_base = ~0UL;
3222 +
3223 + /* vDSO has a problem and was disabled, just don't "enable" it for the
3224 + * process
3225 +@@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
3226 + */
3227 + down_write(&mm->mmap_sem);
3228 + vdso_base = get_unmapped_area(NULL, vdso_base,
3229 +- vdso_pages << PAGE_SHIFT, 0, 0);
3230 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
3231 + if (IS_ERR_VALUE(vdso_base)) {
3232 + rc = vdso_base;
3233 + goto fail_mmapsem;
3234 +diff -urNp linux-2.6.26.6/arch/powerpc/mm/fault.c linux-2.6.26.6/arch/powerpc/mm/fault.c
3235 +--- linux-2.6.26.6/arch/powerpc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
3236 ++++ linux-2.6.26.6/arch/powerpc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
3237 +@@ -29,6 +29,10 @@
3238 + #include <linux/module.h>
3239 + #include <linux/kprobes.h>
3240 + #include <linux/kdebug.h>
3241 ++#include <linux/slab.h>
3242 ++#include <linux/pagemap.h>
3243 ++#include <linux/compiler.h>
3244 ++#include <linux/unistd.h>
3245 +
3246 + #include <asm/page.h>
3247 + #include <asm/pgtable.h>
3248 +@@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
3249 + }
3250 + #endif
3251 +
3252 ++#ifdef CONFIG_PAX_EMUSIGRT
3253 ++void pax_syscall_close(struct vm_area_struct *vma)
3254 ++{
3255 ++ vma->vm_mm->call_syscall = 0UL;
3256 ++}
3257 ++
3258 ++static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
3259 ++{
3260 ++ unsigned int *kaddr;
3261 ++
3262 ++ vmf->page = alloc_page(GFP_HIGHUSER);
3263 ++ if (!vmf->page)
3264 ++ return VM_FAULT_OOM;
3265 ++
3266 ++ kaddr = kmap(vmf->page);
3267 ++ memset(kaddr, 0, PAGE_SIZE);
3268 ++ kaddr[0] = 0x44000002U; /* sc */
3269 ++ __flush_dcache_icache(kaddr);
3270 ++ kunmap(vmf->page);
3271 ++ return VM_FAULT_MAJOR;
3272 ++}
3273 ++
3274 ++static struct vm_operations_struct pax_vm_ops = {
3275 ++ .close = pax_syscall_close,
3276 ++ .fault = pax_syscall_fault
3277 ++};
3278 ++
3279 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3280 ++{
3281 ++ int ret;
3282 ++
3283 ++ vma->vm_mm = current->mm;
3284 ++ vma->vm_start = addr;
3285 ++ vma->vm_end = addr + PAGE_SIZE;
3286 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3287 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
3288 ++ vma->vm_ops = &pax_vm_ops;
3289 ++
3290 ++ ret = insert_vm_struct(current->mm, vma);
3291 ++ if (ret)
3292 ++ return ret;
3293 ++
3294 ++ ++current->mm->total_vm;
3295 ++ return 0;
3296 ++}
3297 ++#endif
3298 ++
3299 ++#ifdef CONFIG_PAX_PAGEEXEC
3300 ++/*
3301 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
3302 ++ *
3303 ++ * returns 1 when task should be killed
3304 ++ * 2 when patched GOT trampoline was detected
3305 ++ * 3 when patched PLT trampoline was detected
3306 ++ * 4 when unpatched PLT trampoline was detected
3307 ++ * 5 when sigreturn trampoline was detected
3308 ++ * 6 when rt_sigreturn trampoline was detected
3309 ++ */
3310 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
3311 ++{
3312 ++
3313 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3314 ++ int err;
3315 ++#endif
3316 ++
3317 ++#ifdef CONFIG_PAX_EMUPLT
3318 ++ do { /* PaX: patched GOT emulation */
3319 ++ unsigned int blrl;
3320 ++
3321 ++ err = get_user(blrl, (unsigned int *)regs->nip);
3322 ++
3323 ++ if (!err && blrl == 0x4E800021U) {
3324 ++ unsigned long temp = regs->nip;
3325 ++
3326 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
3327 ++ regs->link = temp + 4UL;
3328 ++ return 2;
3329 ++ }
3330 ++ } while (0);
3331 ++
3332 ++ do { /* PaX: patched PLT emulation #1 */
3333 ++ unsigned int b;
3334 ++
3335 ++ err = get_user(b, (unsigned int *)regs->nip);
3336 ++
3337 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
3338 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
3339 ++ return 3;
3340 ++ }
3341 ++ } while (0);
3342 ++
3343 ++ do { /* PaX: unpatched PLT emulation #1 */
3344 ++ unsigned int li, b;
3345 ++
3346 ++ err = get_user(li, (unsigned int *)regs->nip);
3347 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3348 ++
3349 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3350 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3351 ++ unsigned long addr = b | 0xFC000000UL;
3352 ++
3353 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3354 ++ err = get_user(rlwinm, (unsigned int *)addr);
3355 ++ err |= get_user(add, (unsigned int *)(addr+4));
3356 ++ err |= get_user(li2, (unsigned int *)(addr+8));
3357 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
3358 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
3359 ++ err |= get_user(li3, (unsigned int *)(addr+20));
3360 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
3361 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
3362 ++
3363 ++ if (err)
3364 ++ break;
3365 ++
3366 ++ if (rlwinm == 0x556C083CU &&
3367 ++ add == 0x7D6C5A14U &&
3368 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3369 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3370 ++ mtctr == 0x7D8903A6U &&
3371 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3372 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3373 ++ bctr == 0x4E800420U)
3374 ++ {
3375 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3376 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3377 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3378 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3379 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3380 ++ regs->nip = regs->ctr;
3381 ++ return 4;
3382 ++ }
3383 ++ }
3384 ++ } while (0);
3385 ++
3386 ++#if 0
3387 ++ do { /* PaX: unpatched PLT emulation #2 */
3388 ++ unsigned int lis, lwzu, b, bctr;
3389 ++
3390 ++ err = get_user(lis, (unsigned int *)regs->nip);
3391 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
3392 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
3393 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
3394 ++
3395 ++ if (err)
3396 ++ break;
3397 ++
3398 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
3399 ++ (lwzu & 0xU) == 0xU &&
3400 ++ (b & 0xFC000003U) == 0x48000000U &&
3401 ++ bctr == 0x4E800420U)
3402 ++ {
3403 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3404 ++ unsigned long addr = b | 0xFC000000UL;
3405 ++
3406 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3407 ++ err = get_user(addis, (unsigned int *)addr);
3408 ++ err |= get_user(addi, (unsigned int *)(addr+4));
3409 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
3410 ++ err |= get_user(add, (unsigned int *)(addr+12));
3411 ++ err |= get_user(li2, (unsigned int *)(addr+16));
3412 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
3413 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
3414 ++ err |= get_user(li3, (unsigned int *)(addr+28));
3415 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
3416 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
3417 ++
3418 ++ if (err)
3419 ++ break;
3420 ++
3421 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3422 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
3423 ++ rlwinm == 0x556C083CU &&
3424 ++ add == 0x7D6C5A14U &&
3425 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3426 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3427 ++ mtctr == 0x7D8903A6U &&
3428 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3429 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3430 ++ bctr == 0x4E800420U)
3431 ++ {
3432 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3433 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3434 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3435 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3436 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3437 ++ regs->nip = regs->ctr;
3438 ++ return 4;
3439 ++ }
3440 ++ }
3441 ++ } while (0);
3442 ++#endif
3443 ++
3444 ++ do { /* PaX: unpatched PLT emulation #3 */
3445 ++ unsigned int li, b;
3446 ++
3447 ++ err = get_user(li, (unsigned int *)regs->nip);
3448 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3449 ++
3450 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3451 ++ unsigned int addis, lwz, mtctr, bctr;
3452 ++ unsigned long addr = b | 0xFC000000UL;
3453 ++
3454 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3455 ++ err = get_user(addis, (unsigned int *)addr);
3456 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
3457 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
3458 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
3459 ++
3460 ++ if (err)
3461 ++ break;
3462 ++
3463 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3464 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
3465 ++ mtctr == 0x7D6903A6U &&
3466 ++ bctr == 0x4E800420U)
3467 ++ {
3468 ++ unsigned int r11;
3469 ++
3470 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3471 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3472 ++
3473 ++ err = get_user(r11, (unsigned int *)addr);
3474 ++ if (err)
3475 ++ break;
3476 ++
3477 ++ regs->gpr[PT_R11] = r11;
3478 ++ regs->ctr = r11;
3479 ++ regs->nip = r11;
3480 ++ return 4;
3481 ++ }
3482 ++ }
3483 ++ } while (0);
3484 ++#endif
3485 ++
3486 ++#ifdef CONFIG_PAX_EMUSIGRT
3487 ++ do { /* PaX: sigreturn emulation */
3488 ++ unsigned int li, sc;
3489 ++
3490 ++ err = get_user(li, (unsigned int *)regs->nip);
3491 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3492 ++
3493 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
3494 ++ struct vm_area_struct *vma;
3495 ++ unsigned long call_syscall;
3496 ++
3497 ++ down_read(&current->mm->mmap_sem);
3498 ++ call_syscall = current->mm->call_syscall;
3499 ++ up_read(&current->mm->mmap_sem);
3500 ++ if (likely(call_syscall))
3501 ++ goto emulate;
3502 ++
3503 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3504 ++
3505 ++ down_write(&current->mm->mmap_sem);
3506 ++ if (current->mm->call_syscall) {
3507 ++ call_syscall = current->mm->call_syscall;
3508 ++ up_write(&current->mm->mmap_sem);
3509 ++ if (vma)
3510 ++ kmem_cache_free(vm_area_cachep, vma);
3511 ++ goto emulate;
3512 ++ }
3513 ++
3514 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3515 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
3516 ++ up_write(&current->mm->mmap_sem);
3517 ++ if (vma)
3518 ++ kmem_cache_free(vm_area_cachep, vma);
3519 ++ return 1;
3520 ++ }
3521 ++
3522 ++ if (pax_insert_vma(vma, call_syscall)) {
3523 ++ up_write(&current->mm->mmap_sem);
3524 ++ kmem_cache_free(vm_area_cachep, vma);
3525 ++ return 1;
3526 ++ }
3527 ++
3528 ++ current->mm->call_syscall = call_syscall;
3529 ++ up_write(&current->mm->mmap_sem);
3530 ++
3531 ++emulate:
3532 ++ regs->gpr[PT_R0] = __NR_sigreturn;
3533 ++ regs->nip = call_syscall;
3534 ++ return 5;
3535 ++ }
3536 ++ } while (0);
3537 ++
3538 ++ do { /* PaX: rt_sigreturn emulation */
3539 ++ unsigned int li, sc;
3540 ++
3541 ++ err = get_user(li, (unsigned int *)regs->nip);
3542 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3543 ++
3544 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
3545 ++ struct vm_area_struct *vma;
3546 ++ unsigned int call_syscall;
3547 ++
3548 ++ down_read(&current->mm->mmap_sem);
3549 ++ call_syscall = current->mm->call_syscall;
3550 ++ up_read(&current->mm->mmap_sem);
3551 ++ if (likely(call_syscall))
3552 ++ goto rt_emulate;
3553 ++
3554 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3555 ++
3556 ++ down_write(&current->mm->mmap_sem);
3557 ++ if (current->mm->call_syscall) {
3558 ++ call_syscall = current->mm->call_syscall;
3559 ++ up_write(&current->mm->mmap_sem);
3560 ++ if (vma)
3561 ++ kmem_cache_free(vm_area_cachep, vma);
3562 ++ goto rt_emulate;
3563 ++ }
3564 ++
3565 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3566 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
3567 ++ up_write(&current->mm->mmap_sem);
3568 ++ if (vma)
3569 ++ kmem_cache_free(vm_area_cachep, vma);
3570 ++ return 1;
3571 ++ }
3572 ++
3573 ++ if (pax_insert_vma(vma, call_syscall)) {
3574 ++ up_write(&current->mm->mmap_sem);
3575 ++ kmem_cache_free(vm_area_cachep, vma);
3576 ++ return 1;
3577 ++ }
3578 ++
3579 ++ current->mm->call_syscall = call_syscall;
3580 ++ up_write(&current->mm->mmap_sem);
3581 ++
3582 ++rt_emulate:
3583 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
3584 ++ regs->nip = call_syscall;
3585 ++ return 6;
3586 ++ }
3587 ++ } while (0);
3588 ++#endif
3589 ++
3590 ++ return 1;
3591 ++}
3592 ++
3593 ++void pax_report_insns(void *pc, void *sp)
3594 ++{
3595 ++ unsigned long i;
3596 ++
3597 ++ printk(KERN_ERR "PAX: bytes at PC: ");
3598 ++ for (i = 0; i < 5; i++) {
3599 ++ unsigned int c;
3600 ++ if (get_user(c, (unsigned int *)pc+i))
3601 ++ printk(KERN_CONT "???????? ");
3602 ++ else
3603 ++ printk(KERN_CONT "%08x ", c);
3604 ++ }
3605 ++ printk("\n");
3606 ++}
3607 ++#endif
3608 ++
3609 + /*
3610 + * Check whether the instruction at regs->nip is a store using
3611 + * an update addressing form which will update r1.
3612 +@@ -157,7 +518,7 @@ int __kprobes do_page_fault(struct pt_re
3613 + * indicate errors in DSISR but can validly be set in SRR1.
3614 + */
3615 + if (trap == 0x400)
3616 +- error_code &= 0x48200000;
3617 ++ error_code &= 0x58200000;
3618 + else
3619 + is_write = error_code & DSISR_ISSTORE;
3620 + #else
3621 +@@ -355,6 +716,37 @@ bad_area:
3622 + bad_area_nosemaphore:
3623 + /* User mode accesses cause a SIGSEGV */
3624 + if (user_mode(regs)) {
3625 ++
3626 ++#ifdef CONFIG_PAX_PAGEEXEC
3627 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
3628 ++#ifdef CONFIG_PPC64
3629 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
3630 ++#else
3631 ++ if (is_exec && regs->nip == address) {
3632 ++#endif
3633 ++ switch (pax_handle_fetch_fault(regs)) {
3634 ++
3635 ++#ifdef CONFIG_PAX_EMUPLT
3636 ++ case 2:
3637 ++ case 3:
3638 ++ case 4:
3639 ++ return 0;
3640 ++#endif
3641 ++
3642 ++#ifdef CONFIG_PAX_EMUSIGRT
3643 ++ case 5:
3644 ++ case 6:
3645 ++ return 0;
3646 ++#endif
3647 ++
3648 ++ }
3649 ++
3650 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
3651 ++ do_group_exit(SIGKILL);
3652 ++ }
3653 ++ }
3654 ++#endif
3655 ++
3656 + _exception(SIGSEGV, regs, code, address);
3657 + return 0;
3658 + }
3659 +diff -urNp linux-2.6.26.6/arch/powerpc/mm/mmap.c linux-2.6.26.6/arch/powerpc/mm/mmap.c
3660 +--- linux-2.6.26.6/arch/powerpc/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
3661 ++++ linux-2.6.26.6/arch/powerpc/mm/mmap.c 2008-10-11 21:54:19.000000000 -0400
3662 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
3663 + */
3664 + if (mmap_is_legacy()) {
3665 + mm->mmap_base = TASK_UNMAPPED_BASE;
3666 ++
3667 ++#ifdef CONFIG_PAX_RANDMMAP
3668 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
3669 ++ mm->mmap_base += mm->delta_mmap;
3670 ++#endif
3671 ++
3672 + mm->get_unmapped_area = arch_get_unmapped_area;
3673 + mm->unmap_area = arch_unmap_area;
3674 + } else {
3675 + mm->mmap_base = mmap_base();
3676 ++
3677 ++#ifdef CONFIG_PAX_RANDMMAP
3678 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
3679 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
3680 ++#endif
3681 ++
3682 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
3683 + mm->unmap_area = arch_unmap_area_topdown;
3684 + }
3685 +diff -urNp linux-2.6.26.6/arch/ppc/mm/fault.c linux-2.6.26.6/arch/ppc/mm/fault.c
3686 +--- linux-2.6.26.6/arch/ppc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
3687 ++++ linux-2.6.26.6/arch/ppc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
3688 +@@ -25,6 +25,10 @@
3689 + #include <linux/interrupt.h>
3690 + #include <linux/highmem.h>
3691 + #include <linux/module.h>
3692 ++#include <linux/slab.h>
3693 ++#include <linux/pagemap.h>
3694 ++#include <linux/compiler.h>
3695 ++#include <linux/unistd.h>
3696 +
3697 + #include <asm/page.h>
3698 + #include <asm/pgtable.h>
3699 +@@ -48,6 +52,363 @@ unsigned long pte_misses; /* updated by
3700 + unsigned long pte_errors; /* updated by do_page_fault() */
3701 + unsigned int probingmem;
3702 +
3703 ++#ifdef CONFIG_PAX_EMUSIGRT
3704 ++void pax_syscall_close(struct vm_area_struct *vma)
3705 ++{
3706 ++ vma->vm_mm->call_syscall = 0UL;
3707 ++}
3708 ++
3709 ++static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
3710 ++{
3711 ++ unsigned int *kaddr;
3712 ++
3713 ++ vmf->page = alloc_page(GFP_HIGHUSER);
3714 ++ if (!vmf->page)
3715 ++ return VM_FAULT_OOM;
3716 ++
3717 ++ kaddr = kmap(vmf->page);
3718 ++ memset(kaddr, 0, PAGE_SIZE);
3719 ++ kaddr[0] = 0x44000002U; /* sc */
3720 ++ __flush_dcache_icache(kaddr);
3721 ++ kunmap(vmf->page);
3722 ++ return VM_FAULT_MAJOR;
3723 ++}
3724 ++
3725 ++static struct vm_operations_struct pax_vm_ops = {
3726 ++ .close = pax_syscall_close,
3727 ++ .fault = pax_syscall_fault
3728 ++};
3729 ++
3730 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
3731 ++{
3732 ++ int ret;
3733 ++
3734 ++ vma->vm_mm = current->mm;
3735 ++ vma->vm_start = addr;
3736 ++ vma->vm_end = addr + PAGE_SIZE;
3737 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
3738 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
3739 ++ vma->vm_ops = &pax_vm_ops;
3740 ++
3741 ++ ret = insert_vm_struct(current->mm, vma);
3742 ++ if (ret)
3743 ++ return ret;
3744 ++
3745 ++ ++current->mm->total_vm;
3746 ++ return 0;
3747 ++}
3748 ++#endif
3749 ++
3750 ++#ifdef CONFIG_PAX_PAGEEXEC
3751 ++/*
3752 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
3753 ++ *
3754 ++ * returns 1 when task should be killed
3755 ++ * 2 when patched GOT trampoline was detected
3756 ++ * 3 when patched PLT trampoline was detected
3757 ++ * 4 when unpatched PLT trampoline was detected
3758 ++ * 5 when sigreturn trampoline was detected
3759 ++ * 6 when rt_sigreturn trampoline was detected
3760 ++ */
3761 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
3762 ++{
3763 ++
3764 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
3765 ++ int err;
3766 ++#endif
3767 ++
3768 ++#ifdef CONFIG_PAX_EMUPLT
3769 ++ do { /* PaX: patched GOT emulation */
3770 ++ unsigned int blrl;
3771 ++
3772 ++ err = get_user(blrl, (unsigned int *)regs->nip);
3773 ++
3774 ++ if (!err && blrl == 0x4E800021U) {
3775 ++ unsigned long temp = regs->nip;
3776 ++
3777 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
3778 ++ regs->link = temp + 4UL;
3779 ++ return 2;
3780 ++ }
3781 ++ } while (0);
3782 ++
3783 ++ do { /* PaX: patched PLT emulation #1 */
3784 ++ unsigned int b;
3785 ++
3786 ++ err = get_user(b, (unsigned int *)regs->nip);
3787 ++
3788 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
3789 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
3790 ++ return 3;
3791 ++ }
3792 ++ } while (0);
3793 ++
3794 ++ do { /* PaX: unpatched PLT emulation #1 */
3795 ++ unsigned int li, b;
3796 ++
3797 ++ err = get_user(li, (unsigned int *)regs->nip);
3798 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3799 ++
3800 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3801 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3802 ++ unsigned long addr = b | 0xFC000000UL;
3803 ++
3804 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3805 ++ err = get_user(rlwinm, (unsigned int *)addr);
3806 ++ err |= get_user(add, (unsigned int *)(addr+4));
3807 ++ err |= get_user(li2, (unsigned int *)(addr+8));
3808 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
3809 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
3810 ++ err |= get_user(li3, (unsigned int *)(addr+20));
3811 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
3812 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
3813 ++
3814 ++ if (err)
3815 ++ break;
3816 ++
3817 ++ if (rlwinm == 0x556C083CU &&
3818 ++ add == 0x7D6C5A14U &&
3819 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3820 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3821 ++ mtctr == 0x7D8903A6U &&
3822 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3823 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3824 ++ bctr == 0x4E800420U)
3825 ++ {
3826 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3827 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3828 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3829 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3830 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3831 ++ regs->nip = regs->ctr;
3832 ++ return 4;
3833 ++ }
3834 ++ }
3835 ++ } while (0);
3836 ++
3837 ++#if 0
3838 ++ do { /* PaX: unpatched PLT emulation #2 */
3839 ++ unsigned int lis, lwzu, b, bctr;
3840 ++
3841 ++ err = get_user(lis, (unsigned int *)regs->nip);
3842 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
3843 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
3844 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
3845 ++
3846 ++ if (err)
3847 ++ break;
3848 ++
3849 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
3850 ++ (lwzu & 0xU) == 0xU &&
3851 ++ (b & 0xFC000003U) == 0x48000000U &&
3852 ++ bctr == 0x4E800420U)
3853 ++ {
3854 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
3855 ++ unsigned long addr = b | 0xFC000000UL;
3856 ++
3857 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3858 ++ err = get_user(addis, (unsigned int *)addr);
3859 ++ err |= get_user(addi, (unsigned int *)(addr+4));
3860 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
3861 ++ err |= get_user(add, (unsigned int *)(addr+12));
3862 ++ err |= get_user(li2, (unsigned int *)(addr+16));
3863 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
3864 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
3865 ++ err |= get_user(li3, (unsigned int *)(addr+28));
3866 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
3867 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
3868 ++
3869 ++ if (err)
3870 ++ break;
3871 ++
3872 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3873 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
3874 ++ rlwinm == 0x556C083CU &&
3875 ++ add == 0x7D6C5A14U &&
3876 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
3877 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
3878 ++ mtctr == 0x7D8903A6U &&
3879 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
3880 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
3881 ++ bctr == 0x4E800420U)
3882 ++ {
3883 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3884 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3885 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
3886 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3887 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
3888 ++ regs->nip = regs->ctr;
3889 ++ return 4;
3890 ++ }
3891 ++ }
3892 ++ } while (0);
3893 ++#endif
3894 ++
3895 ++ do { /* PaX: unpatched PLT emulation #3 */
3896 ++ unsigned int li, b;
3897 ++
3898 ++ err = get_user(li, (unsigned int *)regs->nip);
3899 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
3900 ++
3901 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
3902 ++ unsigned int addis, lwz, mtctr, bctr;
3903 ++ unsigned long addr = b | 0xFC000000UL;
3904 ++
3905 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
3906 ++ err = get_user(addis, (unsigned int *)addr);
3907 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
3908 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
3909 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
3910 ++
3911 ++ if (err)
3912 ++ break;
3913 ++
3914 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
3915 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
3916 ++ mtctr == 0x7D6903A6U &&
3917 ++ bctr == 0x4E800420U)
3918 ++ {
3919 ++ unsigned int r11;
3920 ++
3921 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3922 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
3923 ++
3924 ++ err = get_user(r11, (unsigned int *)addr);
3925 ++ if (err)
3926 ++ break;
3927 ++
3928 ++ regs->gpr[PT_R11] = r11;
3929 ++ regs->ctr = r11;
3930 ++ regs->nip = r11;
3931 ++ return 4;
3932 ++ }
3933 ++ }
3934 ++ } while (0);
3935 ++#endif
3936 ++
3937 ++#ifdef CONFIG_PAX_EMUSIGRT
3938 ++ do { /* PaX: sigreturn emulation */
3939 ++ unsigned int li, sc;
3940 ++
3941 ++ err = get_user(li, (unsigned int *)regs->nip);
3942 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3943 ++
3944 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
3945 ++ struct vm_area_struct *vma;
3946 ++ unsigned long call_syscall;
3947 ++
3948 ++ down_read(&current->mm->mmap_sem);
3949 ++ call_syscall = current->mm->call_syscall;
3950 ++ up_read(&current->mm->mmap_sem);
3951 ++ if (likely(call_syscall))
3952 ++ goto emulate;
3953 ++
3954 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3955 ++
3956 ++ down_write(&current->mm->mmap_sem);
3957 ++ if (current->mm->call_syscall) {
3958 ++ call_syscall = current->mm->call_syscall;
3959 ++ up_write(&current->mm->mmap_sem);
3960 ++ if (vma)
3961 ++ kmem_cache_free(vm_area_cachep, vma);
3962 ++ goto emulate;
3963 ++ }
3964 ++
3965 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
3966 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
3967 ++ up_write(&current->mm->mmap_sem);
3968 ++ if (vma)
3969 ++ kmem_cache_free(vm_area_cachep, vma);
3970 ++ return 1;
3971 ++ }
3972 ++
3973 ++ if (pax_insert_vma(vma, call_syscall)) {
3974 ++ up_write(&current->mm->mmap_sem);
3975 ++ kmem_cache_free(vm_area_cachep, vma);
3976 ++ return 1;
3977 ++ }
3978 ++
3979 ++ current->mm->call_syscall = call_syscall;
3980 ++ up_write(&current->mm->mmap_sem);
3981 ++
3982 ++emulate:
3983 ++ regs->gpr[PT_R0] = __NR_sigreturn;
3984 ++ regs->nip = call_syscall;
3985 ++ return 5;
3986 ++ }
3987 ++ } while (0);
3988 ++
3989 ++ do { /* PaX: rt_sigreturn emulation */
3990 ++ unsigned int li, sc;
3991 ++
3992 ++ err = get_user(li, (unsigned int *)regs->nip);
3993 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
3994 ++
3995 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
3996 ++ struct vm_area_struct *vma;
3997 ++ unsigned int call_syscall;
3998 ++
3999 ++ down_read(&current->mm->mmap_sem);
4000 ++ call_syscall = current->mm->call_syscall;
4001 ++ up_read(&current->mm->mmap_sem);
4002 ++ if (likely(call_syscall))
4003 ++ goto rt_emulate;
4004 ++
4005 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4006 ++
4007 ++ down_write(&current->mm->mmap_sem);
4008 ++ if (current->mm->call_syscall) {
4009 ++ call_syscall = current->mm->call_syscall;
4010 ++ up_write(&current->mm->mmap_sem);
4011 ++ if (vma)
4012 ++ kmem_cache_free(vm_area_cachep, vma);
4013 ++ goto rt_emulate;
4014 ++ }
4015 ++
4016 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4017 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
4018 ++ up_write(&current->mm->mmap_sem);
4019 ++ if (vma)
4020 ++ kmem_cache_free(vm_area_cachep, vma);
4021 ++ return 1;
4022 ++ }
4023 ++
4024 ++ if (pax_insert_vma(vma, call_syscall)) {
4025 ++ up_write(&current->mm->mmap_sem);
4026 ++ kmem_cache_free(vm_area_cachep, vma);
4027 ++ return 1;
4028 ++ }
4029 ++
4030 ++ current->mm->call_syscall = call_syscall;
4031 ++ up_write(&current->mm->mmap_sem);
4032 ++
4033 ++rt_emulate:
4034 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
4035 ++ regs->nip = call_syscall;
4036 ++ return 6;
4037 ++ }
4038 ++ } while (0);
4039 ++#endif
4040 ++
4041 ++ return 1;
4042 ++}
4043 ++
4044 ++void pax_report_insns(void *pc, void *sp)
4045 ++{
4046 ++ unsigned long i;
4047 ++
4048 ++ printk(KERN_ERR "PAX: bytes at PC: ");
4049 ++ for (i = 0; i < 5; i++) {
4050 ++ unsigned int c;
4051 ++ if (get_user(c, (unsigned int *)pc+i))
4052 ++ printk(KERN_CONT "???????? ");
4053 ++ else
4054 ++ printk(KERN_CONT "%08x ", c);
4055 ++ }
4056 ++ printk("\n");
4057 ++}
4058 ++#endif
4059 ++
4060 + /*
4061 + * Check whether the instruction at regs->nip is a store using
4062 + * an update addressing form which will update r1.
4063 +@@ -109,7 +470,7 @@ int do_page_fault(struct pt_regs *regs,
4064 + * indicate errors in DSISR but can validly be set in SRR1.
4065 + */
4066 + if (TRAP(regs) == 0x400)
4067 +- error_code &= 0x48200000;
4068 ++ error_code &= 0x58200000;
4069 + else
4070 + is_write = error_code & 0x02000000;
4071 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
4072 +@@ -204,15 +565,14 @@ good_area:
4073 + pte_t *ptep;
4074 + pmd_t *pmdp;
4075 +
4076 +-#if 0
4077 ++#if 1
4078 + /* It would be nice to actually enforce the VM execute
4079 + permission on CPUs which can do so, but far too
4080 + much stuff in userspace doesn't get the permissions
4081 + right, so we let any page be executed for now. */
4082 + if (! (vma->vm_flags & VM_EXEC))
4083 + goto bad_area;
4084 +-#endif
4085 +-
4086 ++#else
4087 + /* Since 4xx/Book-E supports per-page execute permission,
4088 + * we lazily flush dcache to icache. */
4089 + ptep = NULL;
4090 +@@ -235,6 +595,7 @@ good_area:
4091 + pte_unmap_unlock(ptep, ptl);
4092 + }
4093 + #endif
4094 ++#endif
4095 + /* a read */
4096 + } else {
4097 + /* protection fault */
4098 +@@ -278,6 +639,33 @@ bad_area:
4099 +
4100 + /* User mode accesses cause a SIGSEGV */
4101 + if (user_mode(regs)) {
4102 ++
4103 ++#ifdef CONFIG_PAX_PAGEEXEC
4104 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
4105 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
4106 ++ switch (pax_handle_fetch_fault(regs)) {
4107 ++
4108 ++#ifdef CONFIG_PAX_EMUPLT
4109 ++ case 2:
4110 ++ case 3:
4111 ++ case 4:
4112 ++ return 0;
4113 ++#endif
4114 ++
4115 ++#ifdef CONFIG_PAX_EMUSIGRT
4116 ++ case 5:
4117 ++ case 6:
4118 ++ return 0;
4119 ++#endif
4120 ++
4121 ++ }
4122 ++
4123 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
4124 ++ do_group_exit(SIGKILL);
4125 ++ }
4126 ++ }
4127 ++#endif
4128 ++
4129 + _exception(SIGSEGV, regs, code, address);
4130 + return 0;
4131 + }
4132 +diff -urNp linux-2.6.26.6/arch/s390/kernel/module.c linux-2.6.26.6/arch/s390/kernel/module.c
4133 +--- linux-2.6.26.6/arch/s390/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
4134 ++++ linux-2.6.26.6/arch/s390/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
4135 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
4136 +
4137 + /* Increase core size by size of got & plt and set start
4138 + offsets for got and plt. */
4139 +- me->core_size = ALIGN(me->core_size, 4);
4140 +- me->arch.got_offset = me->core_size;
4141 +- me->core_size += me->arch.got_size;
4142 +- me->arch.plt_offset = me->core_size;
4143 +- me->core_size += me->arch.plt_size;
4144 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
4145 ++ me->arch.got_offset = me->core_size_rw;
4146 ++ me->core_size_rw += me->arch.got_size;
4147 ++ me->arch.plt_offset = me->core_size_rx;
4148 ++ me->core_size_rx += me->arch.plt_size;
4149 + return 0;
4150 + }
4151 +
4152 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4153 + if (info->got_initialized == 0) {
4154 + Elf_Addr *gotent;
4155 +
4156 +- gotent = me->module_core + me->arch.got_offset +
4157 ++ gotent = me->module_core_rw + me->arch.got_offset +
4158 + info->got_offset;
4159 + *gotent = val;
4160 + info->got_initialized = 1;
4161 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4162 + else if (r_type == R_390_GOTENT ||
4163 + r_type == R_390_GOTPLTENT)
4164 + *(unsigned int *) loc =
4165 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
4166 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
4167 + else if (r_type == R_390_GOT64 ||
4168 + r_type == R_390_GOTPLT64)
4169 + *(unsigned long *) loc = val;
4170 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4171 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
4172 + if (info->plt_initialized == 0) {
4173 + unsigned int *ip;
4174 +- ip = me->module_core + me->arch.plt_offset +
4175 ++ ip = me->module_core_rx + me->arch.plt_offset +
4176 + info->plt_offset;
4177 + #ifndef CONFIG_64BIT
4178 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
4179 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4180 + val = me->arch.plt_offset - me->arch.got_offset +
4181 + info->plt_offset + rela->r_addend;
4182 + else
4183 +- val = (Elf_Addr) me->module_core +
4184 ++ val = (Elf_Addr) me->module_core_rx +
4185 + me->arch.plt_offset + info->plt_offset +
4186 + rela->r_addend - loc;
4187 + if (r_type == R_390_PLT16DBL)
4188 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4189 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
4190 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
4191 + val = val + rela->r_addend -
4192 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
4193 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
4194 + if (r_type == R_390_GOTOFF16)
4195 + *(unsigned short *) loc = val;
4196 + else if (r_type == R_390_GOTOFF32)
4197 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
4198 + break;
4199 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
4200 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
4201 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
4202 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
4203 + rela->r_addend - loc;
4204 + if (r_type == R_390_GOTPC)
4205 + *(unsigned int *) loc = val;
4206 +diff -urNp linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c
4207 +--- linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c 2008-10-08 23:24:05.000000000 -0400
4208 ++++ linux-2.6.26.6/arch/sparc/kernel/sys_sparc.c 2008-10-11 21:54:19.000000000 -0400
4209 +@@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
4210 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
4211 + return -ENOMEM;
4212 + if (!addr)
4213 +- addr = TASK_UNMAPPED_BASE;
4214 ++ addr = current->mm->mmap_base;
4215 +
4216 + if (flags & MAP_SHARED)
4217 + addr = COLOUR_ALIGN(addr);
4218 +diff -urNp linux-2.6.26.6/arch/sparc/Makefile linux-2.6.26.6/arch/sparc/Makefile
4219 +--- linux-2.6.26.6/arch/sparc/Makefile 2008-10-08 23:24:05.000000000 -0400
4220 ++++ linux-2.6.26.6/arch/sparc/Makefile 2008-10-11 21:54:19.000000000 -0400
4221 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
4222 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
4223 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
4224 + CORE_Y := $(core-y)
4225 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
4226 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
4227 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
4228 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
4229 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
4230 +diff -urNp linux-2.6.26.6/arch/sparc/mm/fault.c linux-2.6.26.6/arch/sparc/mm/fault.c
4231 +--- linux-2.6.26.6/arch/sparc/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
4232 ++++ linux-2.6.26.6/arch/sparc/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
4233 +@@ -21,6 +21,9 @@
4234 + #include <linux/interrupt.h>
4235 + #include <linux/module.h>
4236 + #include <linux/kdebug.h>
4237 ++#include <linux/slab.h>
4238 ++#include <linux/pagemap.h>
4239 ++#include <linux/compiler.h>
4240 +
4241 + #include <asm/system.h>
4242 + #include <asm/page.h>
4243 +@@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
4244 + return safe_compute_effective_address(regs, insn);
4245 + }
4246 +
4247 ++#ifdef CONFIG_PAX_PAGEEXEC
4248 ++void pax_emuplt_close(struct vm_area_struct *vma)
4249 ++{
4250 ++ vma->vm_mm->call_dl_resolve = 0UL;
4251 ++}
4252 ++
4253 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4254 ++{
4255 ++ unsigned int *kaddr;
4256 ++
4257 ++ vmf->page = alloc_page(GFP_HIGHUSER);
4258 ++ if (!vmf->page)
4259 ++ return VM_FAULT_OOM;
4260 ++
4261 ++ kaddr = kmap(vmf->page);
4262 ++ memset(kaddr, 0, PAGE_SIZE);
4263 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
4264 ++ flush_dcache_page(vmf->page);
4265 ++ kunmap(vmf->page);
4266 ++ return VM_FAULT_MAJOR;
4267 ++}
4268 ++
4269 ++static struct vm_operations_struct pax_vm_ops = {
4270 ++ .close = pax_emuplt_close,
4271 ++ .fault = pax_emuplt_fault
4272 ++};
4273 ++
4274 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4275 ++{
4276 ++ int ret;
4277 ++
4278 ++ vma->vm_mm = current->mm;
4279 ++ vma->vm_start = addr;
4280 ++ vma->vm_end = addr + PAGE_SIZE;
4281 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4282 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4283 ++ vma->vm_ops = &pax_vm_ops;
4284 ++
4285 ++ ret = insert_vm_struct(current->mm, vma);
4286 ++ if (ret)
4287 ++ return ret;
4288 ++
4289 ++ ++current->mm->total_vm;
4290 ++ return 0;
4291 ++}
4292 ++
4293 ++/*
4294 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
4295 ++ *
4296 ++ * returns 1 when task should be killed
4297 ++ * 2 when patched PLT trampoline was detected
4298 ++ * 3 when unpatched PLT trampoline was detected
4299 ++ */
4300 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
4301 ++{
4302 ++
4303 ++#ifdef CONFIG_PAX_EMUPLT
4304 ++ int err;
4305 ++
4306 ++ do { /* PaX: patched PLT emulation #1 */
4307 ++ unsigned int sethi1, sethi2, jmpl;
4308 ++
4309 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
4310 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
4311 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
4312 ++
4313 ++ if (err)
4314 ++ break;
4315 ++
4316 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4317 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
4318 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
4319 ++ {
4320 ++ unsigned int addr;
4321 ++
4322 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4323 ++ addr = regs->u_regs[UREG_G1];
4324 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4325 ++ regs->pc = addr;
4326 ++ regs->npc = addr+4;
4327 ++ return 2;
4328 ++ }
4329 ++ } while (0);
4330 ++
4331 ++ { /* PaX: patched PLT emulation #2 */
4332 ++ unsigned int ba;
4333 ++
4334 ++ err = get_user(ba, (unsigned int *)regs->pc);
4335 ++
4336 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4337 ++ unsigned int addr;
4338 ++
4339 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4340 ++ regs->pc = addr;
4341 ++ regs->npc = addr+4;
4342 ++ return 2;
4343 ++ }
4344 ++ }
4345 ++
4346 ++ do { /* PaX: patched PLT emulation #3 */
4347 ++ unsigned int sethi, jmpl, nop;
4348 ++
4349 ++ err = get_user(sethi, (unsigned int *)regs->pc);
4350 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
4351 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
4352 ++
4353 ++ if (err)
4354 ++ break;
4355 ++
4356 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4357 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4358 ++ nop == 0x01000000U)
4359 ++ {
4360 ++ unsigned int addr;
4361 ++
4362 ++ addr = (sethi & 0x003FFFFFU) << 10;
4363 ++ regs->u_regs[UREG_G1] = addr;
4364 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
4365 ++ regs->pc = addr;
4366 ++ regs->npc = addr+4;
4367 ++ return 2;
4368 ++ }
4369 ++ } while (0);
4370 ++
4371 ++ do { /* PaX: unpatched PLT emulation step 1 */
4372 ++ unsigned int sethi, ba, nop;
4373 ++
4374 ++ err = get_user(sethi, (unsigned int *)regs->pc);
4375 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
4376 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
4377 ++
4378 ++ if (err)
4379 ++ break;
4380 ++
4381 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4382 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4383 ++ nop == 0x01000000U)
4384 ++ {
4385 ++ unsigned int addr, save, call;
4386 ++
4387 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
4388 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
4389 ++ else
4390 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
4391 ++
4392 ++ err = get_user(save, (unsigned int *)addr);
4393 ++ err |= get_user(call, (unsigned int *)(addr+4));
4394 ++ err |= get_user(nop, (unsigned int *)(addr+8));
4395 ++ if (err)
4396 ++ break;
4397 ++
4398 ++ if (save == 0x9DE3BFA8U &&
4399 ++ (call & 0xC0000000U) == 0x40000000U &&
4400 ++ nop == 0x01000000U)
4401 ++ {
4402 ++ struct vm_area_struct *vma;
4403 ++ unsigned long call_dl_resolve;
4404 ++
4405 ++ down_read(&current->mm->mmap_sem);
4406 ++ call_dl_resolve = current->mm->call_dl_resolve;
4407 ++ up_read(&current->mm->mmap_sem);
4408 ++ if (likely(call_dl_resolve))
4409 ++ goto emulate;
4410 ++
4411 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4412 ++
4413 ++ down_write(&current->mm->mmap_sem);
4414 ++ if (current->mm->call_dl_resolve) {
4415 ++ call_dl_resolve = current->mm->call_dl_resolve;
4416 ++ up_write(&current->mm->mmap_sem);
4417 ++ if (vma)
4418 ++ kmem_cache_free(vm_area_cachep, vma);
4419 ++ goto emulate;
4420 ++ }
4421 ++
4422 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4423 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4424 ++ up_write(&current->mm->mmap_sem);
4425 ++ if (vma)
4426 ++ kmem_cache_free(vm_area_cachep, vma);
4427 ++ return 1;
4428 ++ }
4429 ++
4430 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
4431 ++ up_write(&current->mm->mmap_sem);
4432 ++ kmem_cache_free(vm_area_cachep, vma);
4433 ++ return 1;
4434 ++ }
4435 ++
4436 ++ current->mm->call_dl_resolve = call_dl_resolve;
4437 ++ up_write(&current->mm->mmap_sem);
4438 ++
4439 ++emulate:
4440 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4441 ++ regs->pc = call_dl_resolve;
4442 ++ regs->npc = addr+4;
4443 ++ return 3;
4444 ++ }
4445 ++ }
4446 ++ } while (0);
4447 ++
4448 ++ do { /* PaX: unpatched PLT emulation step 2 */
4449 ++ unsigned int save, call, nop;
4450 ++
4451 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
4452 ++ err |= get_user(call, (unsigned int *)regs->pc);
4453 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
4454 ++ if (err)
4455 ++ break;
4456 ++
4457 ++ if (save == 0x9DE3BFA8U &&
4458 ++ (call & 0xC0000000U) == 0x40000000U &&
4459 ++ nop == 0x01000000U)
4460 ++ {
4461 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
4462 ++
4463 ++ regs->u_regs[UREG_RETPC] = regs->pc;
4464 ++ regs->pc = dl_resolve;
4465 ++ regs->npc = dl_resolve+4;
4466 ++ return 3;
4467 ++ }
4468 ++ } while (0);
4469 ++#endif
4470 ++
4471 ++ return 1;
4472 ++}
4473 ++
4474 ++void pax_report_insns(void *pc, void *sp)
4475 ++{
4476 ++ unsigned long i;
4477 ++
4478 ++ printk(KERN_ERR "PAX: bytes at PC: ");
4479 ++ for (i = 0; i < 5; i++) {
4480 ++ unsigned int c;
4481 ++ if (get_user(c, (unsigned int *)pc+i))
4482 ++ printk(KERN_CONT "???????? ");
4483 ++ else
4484 ++ printk(KERN_CONT "%08x ", c);
4485 ++ }
4486 ++ printk("\n");
4487 ++}
4488 ++#endif
4489 ++
4490 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
4491 + unsigned long address)
4492 + {
4493 +@@ -231,6 +477,24 @@ good_area:
4494 + if(!(vma->vm_flags & VM_WRITE))
4495 + goto bad_area;
4496 + } else {
4497 ++
4498 ++#ifdef CONFIG_PAX_PAGEEXEC
4499 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
4500 ++ up_read(&mm->mmap_sem);
4501 ++ switch (pax_handle_fetch_fault(regs)) {
4502 ++
4503 ++#ifdef CONFIG_PAX_EMUPLT
4504 ++ case 2:
4505 ++ case 3:
4506 ++ return;
4507 ++#endif
4508 ++
4509 ++ }
4510 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
4511 ++ do_group_exit(SIGKILL);
4512 ++ }
4513 ++#endif
4514 ++
4515 + /* Allow reads even for write-only mappings */
4516 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
4517 + goto bad_area;
4518 +diff -urNp linux-2.6.26.6/arch/sparc/mm/init.c linux-2.6.26.6/arch/sparc/mm/init.c
4519 +--- linux-2.6.26.6/arch/sparc/mm/init.c 2008-10-08 23:24:05.000000000 -0400
4520 ++++ linux-2.6.26.6/arch/sparc/mm/init.c 2008-10-11 21:54:19.000000000 -0400
4521 +@@ -311,6 +311,9 @@ extern void device_scan(void);
4522 + pgprot_t PAGE_SHARED __read_mostly;
4523 + EXPORT_SYMBOL(PAGE_SHARED);
4524 +
4525 ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
4526 ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
4527 ++
4528 + void __init paging_init(void)
4529 + {
4530 + switch(sparc_cpu_model) {
4531 +@@ -336,17 +339,17 @@ void __init paging_init(void)
4532 +
4533 + /* Initialize the protection map with non-constant, MMU dependent values. */
4534 + protection_map[0] = PAGE_NONE;
4535 +- protection_map[1] = PAGE_READONLY;
4536 +- protection_map[2] = PAGE_COPY;
4537 +- protection_map[3] = PAGE_COPY;
4538 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
4539 ++ protection_map[2] = PAGE_COPY_NOEXEC;
4540 ++ protection_map[3] = PAGE_COPY_NOEXEC;
4541 + protection_map[4] = PAGE_READONLY;
4542 + protection_map[5] = PAGE_READONLY;
4543 + protection_map[6] = PAGE_COPY;
4544 + protection_map[7] = PAGE_COPY;
4545 + protection_map[8] = PAGE_NONE;
4546 +- protection_map[9] = PAGE_READONLY;
4547 +- protection_map[10] = PAGE_SHARED;
4548 +- protection_map[11] = PAGE_SHARED;
4549 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
4550 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
4551 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
4552 + protection_map[12] = PAGE_READONLY;
4553 + protection_map[13] = PAGE_READONLY;
4554 + protection_map[14] = PAGE_SHARED;
4555 +diff -urNp linux-2.6.26.6/arch/sparc/mm/srmmu.c linux-2.6.26.6/arch/sparc/mm/srmmu.c
4556 +--- linux-2.6.26.6/arch/sparc/mm/srmmu.c 2008-10-08 23:24:05.000000000 -0400
4557 ++++ linux-2.6.26.6/arch/sparc/mm/srmmu.c 2008-10-11 21:54:19.000000000 -0400
4558 +@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
4559 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
4560 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
4561 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
4562 ++
4563 ++#ifdef CONFIG_PAX_PAGEEXEC
4564 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
4565 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
4566 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
4567 ++#endif
4568 ++
4569 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
4570 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
4571 +
4572 +diff -urNp linux-2.6.26.6/arch/sparc64/kernel/Makefile linux-2.6.26.6/arch/sparc64/kernel/Makefile
4573 +--- linux-2.6.26.6/arch/sparc64/kernel/Makefile 2008-10-08 23:24:05.000000000 -0400
4574 ++++ linux-2.6.26.6/arch/sparc64/kernel/Makefile 2008-10-11 21:54:19.000000000 -0400
4575 +@@ -3,7 +3,7 @@
4576 + #
4577 +
4578 + EXTRA_AFLAGS := -ansi
4579 +-EXTRA_CFLAGS := -Werror
4580 ++#EXTRA_CFLAGS := -Werror
4581 +
4582 + extra-y := head.o init_task.o vmlinux.lds
4583 +
4584 +diff -urNp linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c
4585 +--- linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c 2008-10-08 23:24:05.000000000 -0400
4586 ++++ linux-2.6.26.6/arch/sparc64/kernel/sys_sparc.c 2008-10-11 21:54:19.000000000 -0400
4587 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
4588 + /* We do not accept a shared mapping if it would violate
4589 + * cache aliasing constraints.
4590 + */
4591 +- if ((flags & MAP_SHARED) &&
4592 ++ if ((filp || (flags & MAP_SHARED)) &&
4593 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4594 + return -EINVAL;
4595 + return addr;
4596 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
4597 + if (filp || (flags & MAP_SHARED))
4598 + do_color_align = 1;
4599 +
4600 ++#ifdef CONFIG_PAX_RANDMMAP
4601 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
4602 ++#endif
4603 ++
4604 + if (addr) {
4605 + if (do_color_align)
4606 + addr = COLOUR_ALIGN(addr, pgoff);
4607 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
4608 + }
4609 +
4610 + if (len > mm->cached_hole_size) {
4611 +- start_addr = addr = mm->free_area_cache;
4612 ++ start_addr = addr = mm->free_area_cache;
4613 + } else {
4614 +- start_addr = addr = TASK_UNMAPPED_BASE;
4615 ++ start_addr = addr = mm->mmap_base;
4616 + mm->cached_hole_size = 0;
4617 + }
4618 +
4619 +@@ -174,8 +178,8 @@ full_search:
4620 + vma = find_vma(mm, VA_EXCLUDE_END);
4621 + }
4622 + if (unlikely(task_size < addr)) {
4623 +- if (start_addr != TASK_UNMAPPED_BASE) {
4624 +- start_addr = addr = TASK_UNMAPPED_BASE;
4625 ++ if (start_addr != mm->mmap_base) {
4626 ++ start_addr = addr = mm->mmap_base;
4627 + mm->cached_hole_size = 0;
4628 + goto full_search;
4629 + }
4630 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
4631 + /* We do not accept a shared mapping if it would violate
4632 + * cache aliasing constraints.
4633 + */
4634 +- if ((flags & MAP_SHARED) &&
4635 ++ if ((filp || (flags & MAP_SHARED)) &&
4636 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
4637 + return -EINVAL;
4638 + return addr;
4639 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
4640 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
4641 + sysctl_legacy_va_layout) {
4642 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
4643 ++
4644 ++#ifdef CONFIG_PAX_RANDMMAP
4645 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
4646 ++ mm->mmap_base += mm->delta_mmap;
4647 ++#endif
4648 ++
4649 + mm->get_unmapped_area = arch_get_unmapped_area;
4650 + mm->unmap_area = arch_unmap_area;
4651 + } else {
4652 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
4653 + gap = (task_size / 6 * 5);
4654 +
4655 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
4656 ++
4657 ++#ifdef CONFIG_PAX_RANDMMAP
4658 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
4659 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
4660 ++#endif
4661 ++
4662 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
4663 + mm->unmap_area = arch_unmap_area_topdown;
4664 + }
4665 +diff -urNp linux-2.6.26.6/arch/sparc64/mm/fault.c linux-2.6.26.6/arch/sparc64/mm/fault.c
4666 +--- linux-2.6.26.6/arch/sparc64/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
4667 ++++ linux-2.6.26.6/arch/sparc64/mm/fault.c 2008-10-11 21:54:19.000000000 -0400
4668 +@@ -20,6 +20,9 @@
4669 + #include <linux/kprobes.h>
4670 + #include <linux/kallsyms.h>
4671 + #include <linux/kdebug.h>
4672 ++#include <linux/slab.h>
4673 ++#include <linux/pagemap.h>
4674 ++#include <linux/compiler.h>
4675 +
4676 + #include <asm/page.h>
4677 + #include <asm/pgtable.h>
4678 +@@ -262,6 +265,367 @@ cannot_handle:
4679 + unhandled_fault (address, current, regs);
4680 + }
4681 +
4682 ++#ifdef CONFIG_PAX_PAGEEXEC
4683 ++#ifdef CONFIG_PAX_EMUPLT
4684 ++static void pax_emuplt_close(struct vm_area_struct *vma)
4685 ++{
4686 ++ vma->vm_mm->call_dl_resolve = 0UL;
4687 ++}
4688 ++
4689 ++static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
4690 ++{
4691 ++ unsigned int *kaddr;
4692 ++
4693 ++ vmf->page = alloc_page(GFP_HIGHUSER);
4694 ++ if (!vmf->page)
4695 ++ return VM_FAULT_OOM;
4696 ++
4697 ++ kaddr = kmap(vmf->page);
4698 ++ memset(kaddr, 0, PAGE_SIZE);
4699 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
4700 ++ flush_dcache_page(vmf->page);
4701 ++ kunmap(vmf->page);
4702 ++ return VM_FAULT_MAJOR;
4703 ++}
4704 ++
4705 ++static struct vm_operations_struct pax_vm_ops = {
4706 ++ .close = pax_emuplt_close,
4707 ++ .fault = pax_emuplt_fault
4708 ++};
4709 ++
4710 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
4711 ++{
4712 ++ int ret;
4713 ++
4714 ++ vma->vm_mm = current->mm;
4715 ++ vma->vm_start = addr;
4716 ++ vma->vm_end = addr + PAGE_SIZE;
4717 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
4718 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
4719 ++ vma->vm_ops = &pax_vm_ops;
4720 ++
4721 ++ ret = insert_vm_struct(current->mm, vma);
4722 ++ if (ret)
4723 ++ return ret;
4724 ++
4725 ++ ++current->mm->total_vm;
4726 ++ return 0;
4727 ++}
4728 ++#endif
4729 ++
4730 ++/*
4731 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
4732 ++ *
4733 ++ * returns 1 when task should be killed
4734 ++ * 2 when patched PLT trampoline was detected
4735 ++ * 3 when unpatched PLT trampoline was detected
4736 ++ */
4737 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
4738 ++{
4739 ++
4740 ++#ifdef CONFIG_PAX_EMUPLT
4741 ++ int err;
4742 ++
4743 ++ do { /* PaX: patched PLT emulation #1 */
4744 ++ unsigned int sethi1, sethi2, jmpl;
4745 ++
4746 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
4747 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4748 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
4749 ++
4750 ++ if (err)
4751 ++ break;
4752 ++
4753 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4754 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
4755 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
4756 ++ {
4757 ++ unsigned long addr;
4758 ++
4759 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
4760 ++ addr = regs->u_regs[UREG_G1];
4761 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4762 ++ regs->tpc = addr;
4763 ++ regs->tnpc = addr+4;
4764 ++ return 2;
4765 ++ }
4766 ++ } while (0);
4767 ++
4768 ++ { /* PaX: patched PLT emulation #2 */
4769 ++ unsigned int ba;
4770 ++
4771 ++ err = get_user(ba, (unsigned int *)regs->tpc);
4772 ++
4773 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
4774 ++ unsigned long addr;
4775 ++
4776 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4777 ++ regs->tpc = addr;
4778 ++ regs->tnpc = addr+4;
4779 ++ return 2;
4780 ++ }
4781 ++ }
4782 ++
4783 ++ do { /* PaX: patched PLT emulation #3 */
4784 ++ unsigned int sethi, jmpl, nop;
4785 ++
4786 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
4787 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
4788 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4789 ++
4790 ++ if (err)
4791 ++ break;
4792 ++
4793 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4794 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
4795 ++ nop == 0x01000000U)
4796 ++ {
4797 ++ unsigned long addr;
4798 ++
4799 ++ addr = (sethi & 0x003FFFFFU) << 10;
4800 ++ regs->u_regs[UREG_G1] = addr;
4801 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
4802 ++ regs->tpc = addr;
4803 ++ regs->tnpc = addr+4;
4804 ++ return 2;
4805 ++ }
4806 ++ } while (0);
4807 ++
4808 ++ do { /* PaX: patched PLT emulation #4 */
4809 ++ unsigned int mov1, call, mov2;
4810 ++
4811 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
4812 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
4813 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
4814 ++
4815 ++ if (err)
4816 ++ break;
4817 ++
4818 ++ if (mov1 == 0x8210000FU &&
4819 ++ (call & 0xC0000000U) == 0x40000000U &&
4820 ++ mov2 == 0x9E100001U)
4821 ++ {
4822 ++ unsigned long addr;
4823 ++
4824 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
4825 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
4826 ++ regs->tpc = addr;
4827 ++ regs->tnpc = addr+4;
4828 ++ return 2;
4829 ++ }
4830 ++ } while (0);
4831 ++
4832 ++ do { /* PaX: patched PLT emulation #5 */
4833 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
4834 ++
4835 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
4836 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4837 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
4838 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
4839 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
4840 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
4841 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
4842 ++
4843 ++ if (err)
4844 ++ break;
4845 ++
4846 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4847 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4848 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
4849 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
4850 ++ sllx == 0x83287020 &&
4851 ++ jmpl == 0x81C04005U &&
4852 ++ nop == 0x01000000U)
4853 ++ {
4854 ++ unsigned long addr;
4855 ++
4856 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
4857 ++ regs->u_regs[UREG_G1] <<= 32;
4858 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
4859 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4860 ++ regs->tpc = addr;
4861 ++ regs->tnpc = addr+4;
4862 ++ return 2;
4863 ++ }
4864 ++ } while (0);
4865 ++
4866 ++ do { /* PaX: patched PLT emulation #6 */
4867 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
4868 ++
4869 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
4870 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
4871 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
4872 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
4873 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
4874 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
4875 ++
4876 ++ if (err)
4877 ++ break;
4878 ++
4879 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
4880 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
4881 ++ sllx == 0x83287020 &&
4882 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
4883 ++ jmpl == 0x81C04005U &&
4884 ++ nop == 0x01000000U)
4885 ++ {
4886 ++ unsigned long addr;
4887 ++
4888 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
4889 ++ regs->u_regs[UREG_G1] <<= 32;
4890 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
4891 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
4892 ++ regs->tpc = addr;
4893 ++ regs->tnpc = addr+4;
4894 ++ return 2;
4895 ++ }
4896 ++ } while (0);
4897 ++
4898 ++ do { /* PaX: patched PLT emulation #7 */
4899 ++ unsigned int sethi, ba, nop;
4900 ++
4901 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
4902 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
4903 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4904 ++
4905 ++ if (err)
4906 ++ break;
4907 ++
4908 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4909 ++ (ba & 0xFFF00000U) == 0x30600000U &&
4910 ++ nop == 0x01000000U)
4911 ++ {
4912 ++ unsigned long addr;
4913 ++
4914 ++ addr = (sethi & 0x003FFFFFU) << 10;
4915 ++ regs->u_regs[UREG_G1] = addr;
4916 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4917 ++ regs->tpc = addr;
4918 ++ regs->tnpc = addr+4;
4919 ++ return 2;
4920 ++ }
4921 ++ } while (0);
4922 ++
4923 ++ do { /* PaX: unpatched PLT emulation step 1 */
4924 ++ unsigned int sethi, ba, nop;
4925 ++
4926 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
4927 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
4928 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
4929 ++
4930 ++ if (err)
4931 ++ break;
4932 ++
4933 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
4934 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
4935 ++ nop == 0x01000000U)
4936 ++ {
4937 ++ unsigned long addr;
4938 ++ unsigned int save, call;
4939 ++
4940 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
4941 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
4942 ++ else
4943 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
4944 ++
4945 ++ err = get_user(save, (unsigned int *)addr);
4946 ++ err |= get_user(call, (unsigned int *)(addr+4));
4947 ++ err |= get_user(nop, (unsigned int *)(addr+8));
4948 ++ if (err)
4949 ++ break;
4950 ++
4951 ++ if (save == 0x9DE3BFA8U &&
4952 ++ (call & 0xC0000000U) == 0x40000000U &&
4953 ++ nop == 0x01000000U)
4954 ++ {
4955 ++ struct vm_area_struct *vma;
4956 ++ unsigned long call_dl_resolve;
4957 ++
4958 ++ down_read(&current->mm->mmap_sem);
4959 ++ call_dl_resolve = current->mm->call_dl_resolve;
4960 ++ up_read(&current->mm->mmap_sem);
4961 ++ if (likely(call_dl_resolve))
4962 ++ goto emulate;
4963 ++
4964 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
4965 ++
4966 ++ down_write(&current->mm->mmap_sem);
4967 ++ if (current->mm->call_dl_resolve) {
4968 ++ call_dl_resolve = current->mm->call_dl_resolve;
4969 ++ up_write(&current->mm->mmap_sem);
4970 ++ if (vma)
4971 ++ kmem_cache_free(vm_area_cachep, vma);
4972 ++ goto emulate;
4973 ++ }
4974 ++
4975 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
4976 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
4977 ++ up_write(&current->mm->mmap_sem);
4978 ++ if (vma)
4979 ++ kmem_cache_free(vm_area_cachep, vma);
4980 ++ return 1;
4981 ++ }
4982 ++
4983 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
4984 ++ up_write(&current->mm->mmap_sem);
4985 ++ kmem_cache_free(vm_area_cachep, vma);
4986 ++ return 1;
4987 ++ }
4988 ++
4989 ++ current->mm->call_dl_resolve = call_dl_resolve;
4990 ++ up_write(&current->mm->mmap_sem);
4991 ++
4992 ++emulate:
4993 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
4994 ++ regs->tpc = call_dl_resolve;
4995 ++ regs->tnpc = addr+4;
4996 ++ return 3;
4997 ++ }
4998 ++ }
4999 ++ } while (0);
5000 ++
5001 ++ do { /* PaX: unpatched PLT emulation step 2 */
5002 ++ unsigned int save, call, nop;
5003 ++
5004 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
5005 ++ err |= get_user(call, (unsigned int *)regs->tpc);
5006 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
5007 ++ if (err)
5008 ++ break;
5009 ++
5010 ++ if (save == 0x9DE3BFA8U &&
5011 ++ (call & 0xC0000000U) == 0x40000000U &&
5012 ++ nop == 0x01000000U)
5013 ++ {
5014 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
5015 ++
5016 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
5017 ++ regs->tpc = dl_resolve;
5018 ++ regs->tnpc = dl_resolve+4;
5019 ++ return 3;
5020 ++ }
5021 ++ } while (0);
5022 ++#endif
5023 ++
5024 ++ return 1;
5025 ++}
5026 ++
5027 ++void pax_report_insns(void *pc, void *sp)
5028 ++{
5029 ++ unsigned long i;
5030 ++
5031 ++ printk(KERN_ERR "PAX: bytes at PC: ");
5032 ++ for (i = 0; i < 5; i++) {
5033 ++ unsigned int c;
5034 ++ if (get_user(c, (unsigned int *)pc+i))
5035 ++ printk(KERN_CONT "???????? ");
5036 ++ else
5037 ++ printk(KERN_CONT "%08x ", c);
5038 ++ }
5039 ++ printk("\n");
5040 ++}
5041 ++#endif
5042 ++
5043 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
5044 + {
5045 + struct mm_struct *mm = current->mm;
5046 +@@ -303,8 +667,10 @@ asmlinkage void __kprobes do_sparc64_fau
5047 + goto intr_or_no_mm;
5048 +
5049 + if (test_thread_flag(TIF_32BIT)) {
5050 +- if (!(regs->tstate & TSTATE_PRIV))
5051 ++ if (!(regs->tstate & TSTATE_PRIV)) {
5052 + regs->tpc &= 0xffffffff;
5053 ++ regs->tnpc &= 0xffffffff;
5054 ++ }
5055 + address &= 0xffffffff;
5056 + }
5057 +
5058 +@@ -321,6 +687,29 @@ asmlinkage void __kprobes do_sparc64_fau
5059 + if (!vma)
5060 + goto bad_area;
5061 +
5062 ++#ifdef CONFIG_PAX_PAGEEXEC
5063 ++ /* PaX: detect ITLB misses on non-exec pages */
5064 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
5065 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
5066 ++ {
5067 ++ if (address != regs->tpc)
5068 ++ goto good_area;
5069 ++
5070 ++ up_read(&mm->mmap_sem);
5071 ++ switch (pax_handle_fetch_fault(regs)) {
5072 ++
5073 ++#ifdef CONFIG_PAX_EMUPLT
5074 ++ case 2:
5075 ++ case 3:
5076 ++ return;
5077 ++#endif
5078 ++
5079 ++ }
5080 ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
5081 ++ do_group_exit(SIGKILL);
5082 ++ }
5083 ++#endif
5084 ++
5085 + /* Pure DTLB misses do not tell us whether the fault causing
5086 + * load/store/atomic was a write or not, it only says that there
5087 + * was no match. So in such a case we (carefully) read the
5088 +diff -urNp linux-2.6.26.6/arch/sparc64/mm/Makefile linux-2.6.26.6/arch/sparc64/mm/Makefile
5089 +--- linux-2.6.26.6/arch/sparc64/mm/Makefile 2008-10-08 23:24:05.000000000 -0400
5090 ++++ linux-2.6.26.6/arch/sparc64/mm/Makefile 2008-10-11 21:54:19.000000000 -0400
5091 +@@ -2,7 +2,7 @@
5092 + #
5093 +
5094 + EXTRA_AFLAGS := -ansi
5095 +-EXTRA_CFLAGS := -Werror
5096 ++#EXTRA_CFLAGS := -Werror
5097 +
5098 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
5099 +
5100 +diff -urNp linux-2.6.26.6/arch/um/sys-i386/syscalls.c linux-2.6.26.6/arch/um/sys-i386/syscalls.c
5101 +--- linux-2.6.26.6/arch/um/sys-i386/syscalls.c 2008-10-08 23:24:05.000000000 -0400
5102 ++++ linux-2.6.26.6/arch/um/sys-i386/syscalls.c 2008-10-11 21:55:07.000000000 -0400
5103 +@@ -10,6 +10,21 @@
5104 + #include "asm/uaccess.h"
5105 + #include "asm/unistd.h"
5106 +
5107 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
5108 ++{
5109 ++ unsigned long pax_task_size = TASK_SIZE;
5110 ++
5111 ++#ifdef CONFIG_PAX_SEGMEXEC
5112 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
5113 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
5114 ++#endif
5115 ++
5116 ++ if (len > pax_task_size || addr > pax_task_size - len)
5117 ++ return -EINVAL;
5118 ++
5119 ++ return 0;
5120 ++}
5121 ++
5122 + /*
5123 + * Perform the select(nd, in, out, ex, tv) and mmap() system
5124 + * calls. Linux/i386 didn't use to be able to handle more than
5125 +diff -urNp linux-2.6.26.6/arch/v850/kernel/module.c linux-2.6.26.6/arch/v850/kernel/module.c
5126 +--- linux-2.6.26.6/arch/v850/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
5127 ++++ linux-2.6.26.6/arch/v850/kernel/module.c 2008-10-11 21:54:19.000000000 -0400
5128 +@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
5129 + tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
5130 +
5131 + /* Init, or core PLT? */
5132 +- if (location >= mod->module_core
5133 +- && location < mod->module_core + mod->core_size)
5134 ++ if (location >= mod->module_core_rx
5135 ++ && location < mod->module_core_rx + mod->core_size_rx)
5136 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
5137 + else
5138 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
5139 +diff -urNp linux-2.6.26.6/arch/x86/boot/bitops.h linux-2.6.26.6/arch/x86/boot/bitops.h
5140 +--- linux-2.6.26.6/arch/x86/boot/bitops.h 2008-10-08 23:24:05.000000000 -0400
5141 ++++ linux-2.6.26.6/arch/x86/boot/bitops.h 2008-10-11 21:54:19.000000000 -0400
5142 +@@ -26,7 +26,7 @@ static inline int variable_test_bit(int
5143 + u8 v;
5144 + const u32 *p = (const u32 *)addr;
5145 +
5146 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5147 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
5148 + return v;
5149 + }
5150 +
5151 +@@ -37,7 +37,7 @@ static inline int variable_test_bit(int
5152 +
5153 + static inline void set_bit(int nr, void *addr)
5154 + {
5155 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5156 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
5157 + }
5158 +
5159 + #endif /* BOOT_BITOPS_H */
5160 +diff -urNp linux-2.6.26.6/arch/x86/boot/boot.h linux-2.6.26.6/arch/x86/boot/boot.h
5161 +--- linux-2.6.26.6/arch/x86/boot/boot.h 2008-10-08 23:24:05.000000000 -0400
5162 ++++ linux-2.6.26.6/arch/x86/boot/boot.h 2008-10-11 21:54:19.000000000 -0400
5163 +@@ -78,7 +78,7 @@ static inline void io_delay(void)
5164 + static inline u16 ds(void)
5165 + {
5166 + u16 seg;
5167 +- asm("movw %%ds,%0" : "=rm" (seg));
5168 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
5169 + return seg;
5170 + }
5171 +
5172 +@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
5173 + static inline int memcmp(const void *s1, const void *s2, size_t len)
5174 + {
5175 + u8 diff;
5176 +- asm("repe; cmpsb; setnz %0"
5177 ++ asm volatile("repe; cmpsb; setnz %0"
5178 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
5179 + return diff;
5180 + }
5181 +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
5182 +--- linux-2.6.26.6/arch/x86/boot/compressed/head_32.S 2008-10-08 23:24:05.000000000 -0400
5183 ++++ linux-2.6.26.6/arch/x86/boot/compressed/head_32.S 2008-10-11 21:54:19.000000000 -0400
5184 +@@ -70,7 +70,7 @@ startup_32:
5185 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
5186 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
5187 + #else
5188 +- movl $LOAD_PHYSICAL_ADDR, %ebx
5189 ++ movl $____LOAD_PHYSICAL_ADDR, %ebx
5190 + #endif
5191 +
5192 + /* Replace the compressed data size with the uncompressed size */
5193 +@@ -105,7 +105,7 @@ startup_32:
5194 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
5195 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
5196 + #else
5197 +- movl $LOAD_PHYSICAL_ADDR, %ebp
5198 ++ movl $____LOAD_PHYSICAL_ADDR, %ebp
5199 + #endif
5200 +
5201 + /*
5202 +@@ -159,16 +159,15 @@ relocated:
5203 + * and where it was actually loaded.
5204 + */
5205 + movl %ebp, %ebx
5206 +- subl $LOAD_PHYSICAL_ADDR, %ebx
5207 ++ subl $____LOAD_PHYSICAL_ADDR, %ebx
5208 + jz 2f /* Nothing to be done if loaded at compiled addr. */
5209 + /*
5210 + * Process relocations.
5211 + */
5212 +
5213 + 1: subl $4, %edi
5214 +- movl 0(%edi), %ecx
5215 +- testl %ecx, %ecx
5216 +- jz 2f
5217 ++ movl (%edi), %ecx
5218 ++ jecxz 2f
5219 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
5220 + jmp 1b
5221 + 2:
5222 +diff -urNp linux-2.6.26.6/arch/x86/boot/compressed/misc.c linux-2.6.26.6/arch/x86/boot/compressed/misc.c
5223 +--- linux-2.6.26.6/arch/x86/boot/compressed/misc.c 2008-10-08 23:24:05.000000000 -0400
5224 ++++ linux-2.6.26.6/arch/x86/boot/compressed/misc.c 2008-10-11 21:54:19.000000000 -0400
5225 +@@ -410,7 +410,7 @@ static void parse_elf(void *output)
5226 + case PT_LOAD:
5227 + #ifdef CONFIG_RELOCATABLE
5228 + dest = output;
5229 +- dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
5230 ++ dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
5231 + #else
5232 + dest = (void *)(phdr->p_paddr);
5233 + #endif
5234 +@@ -459,7 +459,7 @@ asmlinkage void decompress_kernel(void *
5235 + if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
5236 + error("Destination address too large");
5237 + #ifndef CONFIG_RELOCATABLE
5238 +- if ((u32)output != LOAD_PHYSICAL_ADDR)
5239 ++ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
5240 + error("Wrong destination address");
5241 + #endif
5242 + #endif
5243 +diff -urNp linux-2.6.26.6/arch/x86/boot/compressed/relocs.c linux-2.6.26.6/arch/x86/boot/compressed/relocs.c
5244 +--- linux-2.6.26.6/arch/x86/boot/compressed/relocs.c 2008-10-08 23:24:05.000000000 -0400
5245 ++++ linux-2.6.26.6/arch/x86/boot/compressed/relocs.c 2008-10-11 21:54:19.000000000 -0400
5246 +@@ -10,9 +10,13 @@
5247 + #define USE_BSD
5248 + #include <endian.h>
5249 +
5250 ++#include "../../../../include/linux/autoconf.h"
5251 ++
5252 ++#define MAX_PHDRS 100
5253 + #define MAX_SHDRS 100
5254 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5255 + static Elf32_Ehdr ehdr;
5256 ++static Elf32_Phdr phdr[MAX_PHDRS];
5257 + static Elf32_Shdr shdr[MAX_SHDRS];
5258 + static Elf32_Sym *symtab[MAX_SHDRS];
5259 + static Elf32_Rel *reltab[MAX_SHDRS];
5260 +@@ -241,6 +245,34 @@ static void read_ehdr(FILE *fp)
5261 + }
5262 + }
5263 +
5264 ++static void read_phdrs(FILE *fp)
5265 ++{
5266 ++ int i;
5267 ++ if (ehdr.e_phnum > MAX_PHDRS) {
5268 ++ die("%d program headers supported: %d\n",
5269 ++ ehdr.e_phnum, MAX_PHDRS);
5270 ++ }
5271 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
5272 ++ die("Seek to %d failed: %s\n",
5273 ++ ehdr.e_phoff, strerror(errno));
5274 ++ }
5275 ++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
5276 ++ die("Cannot read ELF program headers: %s\n",
5277 ++ strerror(errno));
5278 ++ }
5279 ++ for(i = 0; i < ehdr.e_phnum; i++) {
5280 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
5281 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
5282 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
5283 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
5284 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
5285 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
5286 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
5287 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
5288 ++ }
5289 ++
5290 ++}
5291 ++
5292 + static void read_shdrs(FILE *fp)
5293 + {
5294 + int i;
5295 +@@ -327,6 +359,8 @@ static void read_symtabs(FILE *fp)
5296 + static void read_relocs(FILE *fp)
5297 + {
5298 + int i,j;
5299 ++ uint32_t base;
5300 ++
5301 + for(i = 0; i < ehdr.e_shnum; i++) {
5302 + if (shdr[i].sh_type != SHT_REL) {
5303 + continue;
5304 +@@ -344,8 +378,17 @@ static void read_relocs(FILE *fp)
5305 + die("Cannot read symbol table: %s\n",
5306 + strerror(errno));
5307 + }
5308 ++ base = 0;
5309 ++ for (j = 0; j < ehdr.e_phnum; j++) {
5310 ++ if (phdr[j].p_type != PT_LOAD )
5311 ++ continue;
5312 ++ 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)
5313 ++ continue;
5314 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
5315 ++ break;
5316 ++ }
5317 + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
5318 +- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
5319 ++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
5320 + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
5321 + }
5322 + }
5323 +@@ -482,6 +525,23 @@ static void walk_relocs(void (*visit)(El
5324 + if (sym->st_shndx == SHN_ABS) {
5325 + continue;
5326 + }
5327 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
5328 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
5329 ++ continue;
5330 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
5331 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
5332 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
5333 ++ continue;
5334 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
5335 ++ continue;
5336 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
5337 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
5338 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
5339 ++ continue;
5340 ++ }
5341 ++ if (!strcmp(sec_name(sym->st_shndx), ".text"))
5342 ++ continue;
5343 ++#endif
5344 + if (r_type == R_386_PC32) {
5345 + /* PC relative relocations don't need to be adjusted */
5346 + }
5347 +@@ -609,6 +669,7 @@ int main(int argc, char **argv)
5348 + fname, strerror(errno));
5349 + }
5350 + read_ehdr(fp);
5351 ++ read_phdrs(fp);
5352 + read_shdrs(fp);
5353 + read_strtabs(fp);
5354 + read_symtabs(fp);
5355 +diff -urNp linux-2.6.26.6/arch/x86/boot/cpucheck.c linux-2.6.26.6/arch/x86/boot/cpucheck.c
5356 +--- linux-2.6.26.6/arch/x86/boot/cpucheck.c 2008-10-08 23:24:05.000000000 -0400
5357 ++++ linux-2.6.26.6/arch/x86/boot/cpucheck.c 2008-10-11 21:54:19.000000000 -0400
5358 +@@ -76,7 +76,7 @@ static int has_fpu(void)
5359 + u16 fcw = -1, fsw = -1;
5360 + u32 cr0;
5361 +
5362 +- asm("movl %%cr0,%0" : "=r" (cr0));
5363 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
5364 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
5365 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
5366 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
5367 +@@ -92,7 +92,7 @@ static int has_eflag(u32 mask)
5368 + {
5369 + u32 f0, f1;
5370 +
5371 +- asm("pushfl ; "
5372 ++ asm volatile("pushfl ; "
5373 + "pushfl ; "
5374 + "popl %0 ; "
5375 + "movl %0,%1 ; "
5376 +@@ -117,7 +117,7 @@ static void get_flags(void)
5377 + set_bit(X86_FEATURE_FPU, cpu.flags);
5378 +
5379 + if (has_eflag(X86_EFLAGS_ID)) {
5380 +- asm("cpuid"
5381 ++ asm volatile("cpuid"
5382 + : "=a" (max_intel_level),
5383 + "=b" (cpu_vendor[0]),
5384 + "=d" (cpu_vendor[1]),
5385 +@@ -126,7 +126,7 @@ static void get_flags(void)
5386 +
5387 + if (max_intel_level >= 0x00000001 &&
5388 + max_intel_level <= 0x0000ffff) {
5389 +- asm("cpuid"
5390 ++ asm volatile("cpuid"
5391 + : "=a" (tfms),
5392 + "=c" (cpu.flags[4]),
5393 + "=d" (cpu.flags[0])
5394 +@@ -138,7 +138,7 @@ static void get_flags(void)
5395 + cpu.model += ((tfms >> 16) & 0xf) << 4;
5396 + }
5397 +
5398 +- asm("cpuid"
5399 ++ asm volatile("cpuid"
5400 + : "=a" (max_amd_level)
5401 + : "a" (0x80000000)
5402 + : "ebx", "ecx", "edx");
5403 +@@ -146,7 +146,7 @@ static void get_flags(void)
5404 + if (max_amd_level >= 0x80000001 &&
5405 + max_amd_level <= 0x8000ffff) {
5406 + u32 eax = 0x80000001;
5407 +- asm("cpuid"
5408 ++ asm volatile("cpuid"
5409 + : "+a" (eax),
5410 + "=c" (cpu.flags[6]),
5411 + "=d" (cpu.flags[1])
5412 +@@ -205,9 +205,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5413 + u32 ecx = MSR_K7_HWCR;
5414 + u32 eax, edx;
5415 +
5416 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5417 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5418 + eax &= ~(1 << 15);
5419 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5420 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5421 +
5422 + get_flags(); /* Make sure it really did something */
5423 + err = check_flags();
5424 +@@ -220,9 +220,9 @@ int check_cpu(int *cpu_level_ptr, int *r
5425 + u32 ecx = MSR_VIA_FCR;
5426 + u32 eax, edx;
5427 +
5428 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5429 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5430 + eax |= (1<<1)|(1<<7);
5431 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5432 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5433 +
5434 + set_bit(X86_FEATURE_CX8, cpu.flags);
5435 + err = check_flags();
5436 +@@ -233,12 +233,12 @@ int check_cpu(int *cpu_level_ptr, int *r
5437 + u32 eax, edx;
5438 + u32 level = 1;
5439 +
5440 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5441 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5442 +- asm("cpuid"
5443 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
5444 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
5445 ++ asm volatile("cpuid"
5446 + : "+a" (level), "=d" (cpu.flags[0])
5447 + : : "ecx", "ebx");
5448 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5449 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
5450 +
5451 + err = check_flags();
5452 + }
5453 +diff -urNp linux-2.6.26.6/arch/x86/boot/edd.c linux-2.6.26.6/arch/x86/boot/edd.c
5454 +--- linux-2.6.26.6/arch/x86/boot/edd.c 2008-10-08 23:24:05.000000000 -0400
5455 ++++ linux-2.6.26.6/arch/x86/boot/edd.c 2008-10-11 21:54:19.000000000 -0400
5456 +@@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
5457 + ax = 0x4100;
5458 + bx = EDDMAGIC1;
5459 + dx = devno;
5460 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
5461 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
5462 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
5463 + : : "esi", "edi");
5464 +
5465 +@@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
5466 + ei->params.length = sizeof(ei->params);
5467 + ax = 0x4800;
5468 + dx = devno;
5469 +- asm("pushfl; int $0x13; popfl"
5470 ++ asm volatile("pushfl; int $0x13; popfl"
5471 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
5472 + : "S" (&ei->params)
5473 + : "ebx", "ecx", "edi");
5474 +@@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
5475 + ax = 0x0800;
5476 + dx = devno;
5477 + di = 0;
5478 +- asm("pushw %%es; "
5479 ++ asm volatile("pushw %%es; "
5480 + "movw %%di,%%es; "
5481 + "pushfl; stc; int $0x13; setc %%al; popfl; "
5482 + "popw %%es"
5483 +diff -urNp linux-2.6.26.6/arch/x86/boot/main.c linux-2.6.26.6/arch/x86/boot/main.c
5484 +--- linux-2.6.26.6/arch/x86/boot/main.c 2008-10-08 23:24:05.000000000 -0400
5485 ++++ linux-2.6.26.6/arch/x86/boot/main.c 2008-10-11 21:54:19.000000000 -0400
5486 +@@ -77,7 +77,7 @@ static void query_ist(void)
5487 + if (cpu.level < 6)
5488 + return;
5489 +
5490 +- asm("int $0x15"
5491 ++ asm volatile("int $0x15"
5492 + : "=a" (boot_params.ist_info.signature),
5493 + "=b" (boot_params.ist_info.command),
5494 + "=c" (boot_params.ist_info.event),
5495 +diff -urNp linux-2.6.26.6/arch/x86/boot/mca.c linux-2.6.26.6/arch/x86/boot/mca.c
5496 +--- linux-2.6.26.6/arch/x86/boot/mca.c 2008-10-08 23:24:05.000000000 -0400
5497 ++++ linux-2.6.26.6/arch/x86/boot/mca.c 2008-10-11 21:54:19.000000000 -0400
5498 +@@ -19,7 +19,7 @@ int query_mca(void)
5499 + u8 err;
5500 + u16 es, bx, len;
5501 +
5502 +- asm("pushw %%es ; "
5503 ++ asm volatile("pushw %%es ; "
5504 + "int $0x15 ; "
5505 + "setc %0 ; "
5506 + "movw %%es, %1 ; "
5507 +diff -urNp linux-2.6.26.6/arch/x86/boot/memory.c linux-2.6.26.6/arch/x86/boot/memory.c
5508 +--- linux-2.6.26.6/arch/x86/boot/memory.c 2008-10-08 23:24:05.000000000 -0400
5509 ++++ linux-2.6.26.6/arch/x86/boot/memory.c 2008-10-11 21:54:19.000000000 -0400
5510 +@@ -30,7 +30,7 @@ static int detect_memory_e820(void)
5511 + /* Important: %edx is clobbered by some BIOSes,
5512 + so it must be either used for the error output
5513 + or explicitly marked clobbered. */
5514 +- asm("int $0x15; setc %0"
5515 ++ asm volatile("int $0x15; setc %0"
5516 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
5517 + "=m" (*desc)
5518 + : "D" (desc), "d" (SMAP), "a" (0xe820));
5519 +@@ -65,7 +65,7 @@ static int detect_memory_e801(void)
5520 +
5521 + bx = cx = dx = 0;
5522 + ax = 0xe801;
5523 +- asm("stc; int $0x15; setc %0"
5524 ++ asm volatile("stc; int $0x15; setc %0"
5525 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
5526 +
5527 + if (err)
5528 +@@ -95,7 +95,7 @@ static int detect_memory_88(void)
5529 + u8 err;
5530 +
5531 + ax = 0x8800;
5532 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
5533 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
5534 +
5535 + boot_params.screen_info.ext_mem_k = ax;
5536 +
5537 +diff -urNp linux-2.6.26.6/arch/x86/boot/video.c linux-2.6.26.6/arch/x86/boot/video.c
5538 +--- linux-2.6.26.6/arch/x86/boot/video.c 2008-10-08 23:24:05.000000000 -0400
5539 ++++ linux-2.6.26.6/arch/x86/boot/video.c 2008-10-11 21:54:19.000000000 -0400
5540 +@@ -23,7 +23,7 @@ static void store_cursor_position(void)
5541 +
5542 + ax = 0x0300;
5543 + bx = 0;
5544 +- asm(INT10
5545 ++ asm volatile(INT10
5546 + : "=d" (curpos), "+a" (ax), "+b" (bx)
5547 + : : "ecx", "esi", "edi");
5548 +
5549 +@@ -38,7 +38,7 @@ static void store_video_mode(void)
5550 + /* N.B.: the saving of the video page here is a bit silly,
5551 + since we pretty much assume page 0 everywhere. */
5552 + ax = 0x0f00;
5553 +- asm(INT10
5554 ++ asm volatile(INT10
5555 + : "+a" (ax), "=b" (page)
5556 + : : "ecx", "edx", "esi", "edi");
5557 +
5558 +diff -urNp linux-2.6.26.6/arch/x86/boot/video-vesa.c linux-2.6.26.6/arch/x86/boot/video-vesa.c
5559 +--- linux-2.6.26.6/arch/x86/boot/video-vesa.c 2008-10-08 23:24:05.000000000 -0400
5560 ++++ linux-2.6.26.6/arch/x86/boot/video-vesa.c 2008-10-11 21:54:19.000000000 -0400
5561 +@@ -41,7 +41,7 @@ static int vesa_probe(void)
5562 +
5563 + ax = 0x4f00;
5564 + di = (size_t)&vginfo;
5565 +- asm(INT10
5566 ++ asm volatile(INT10
5567 + : "+a" (ax), "+D" (di), "=m" (vginfo)
5568 + : : "ebx", "ecx", "edx", "esi");
5569 +
5570 +@@ -68,7 +68,7 @@ static int vesa_probe(void)
5571 + ax = 0x4f01;
5572 + cx = mode;
5573 + di = (size_t)&vminfo;
5574 +- asm(INT10
5575 ++ asm volatile(INT10
5576 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
5577 + : : "ebx", "edx", "esi");
5578 +
5579 +@@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
5580 + ax = 0x4f01;
5581 + cx = vesa_mode;
5582 + di = (size_t)&vminfo;
5583 +- asm(INT10
5584 ++ asm volatile(INT10
5585 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
5586 + : : "ebx", "edx", "esi");
5587 +
5588 +@@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
5589 + /* Save the VESA protected mode info */
5590 + static void vesa_store_pm_info(void)
5591 + {
5592 +- u16 ax, bx, di, es;
5593 ++ u16 ax, bx, cx, di, es;
5594 +
5595 + ax = 0x4f0a;
5596 +- bx = di = 0;
5597 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
5598 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
5599 +- : : "ecx", "esi");
5600 ++ bx = cx = di = 0;
5601 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
5602 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
5603 ++ : : "esi");
5604 +
5605 + if (ax != 0x004f)
5606 + return;
5607 +
5608 + boot_params.screen_info.vesapm_seg = es;
5609 + boot_params.screen_info.vesapm_off = di;
5610 ++ boot_params.screen_info.vesapm_size = cx;
5611 + }
5612 +
5613 + /*
5614 +@@ -269,7 +270,7 @@ void vesa_store_edid(void)
5615 + /* Note: The VBE DDC spec is different from the main VESA spec;
5616 + we genuinely have to assume all registers are destroyed here. */
5617 +
5618 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
5619 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
5620 + : "+a" (ax), "+b" (bx)
5621 + : "c" (cx), "D" (di)
5622 + : "esi");
5623 +@@ -285,7 +286,7 @@ void vesa_store_edid(void)
5624 + cx = 0; /* Controller 0 */
5625 + dx = 0; /* EDID block number */
5626 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
5627 +- asm(INT10
5628 ++ asm volatile(INT10
5629 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
5630 + : "c" (cx), "D" (di)
5631 + : "esi");
5632 +diff -urNp linux-2.6.26.6/arch/x86/boot/video-vga.c linux-2.6.26.6/arch/x86/boot/video-vga.c
5633 +--- linux-2.6.26.6/arch/x86/boot/video-vga.c 2008-10-08 23:24:05.000000000 -0400
5634 ++++ linux-2.6.26.6/arch/x86/boot/video-vga.c 2008-10-11 21:54:19.000000000 -0400
5635 +@@ -225,7 +225,7 @@ static int vga_probe(void)
5636 + };
5637 + u8 vga_flag;
5638 +
5639 +- asm(INT10
5640 ++ asm volatile(INT10
5641 + : "=b" (ega_bx)
5642 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
5643 + : "ecx", "edx", "esi", "edi");
5644 +@@ -237,7 +237,7 @@ static int vga_probe(void)
5645 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
5646 + if ((u8)ega_bx != 0x10) {
5647 + /* EGA/VGA */
5648 +- asm(INT10
5649 ++ asm volatile(INT10
5650 + : "=a" (vga_flag)
5651 + : "a" (0x1a00)
5652 + : "ebx", "ecx", "edx", "esi", "edi");
5653 +diff -urNp linux-2.6.26.6/arch/x86/boot/voyager.c linux-2.6.26.6/arch/x86/boot/voyager.c
5654 +--- linux-2.6.26.6/arch/x86/boot/voyager.c 2008-10-08 23:24:05.000000000 -0400
5655 ++++ linux-2.6.26.6/arch/x86/boot/voyager.c 2008-10-11 21:54:19.000000000 -0400
5656 +@@ -23,7 +23,7 @@ int query_voyager(void)
5657 +
5658 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
5659 +
5660 +- asm("pushw %%es ; "
5661 ++ asm volatile("pushw %%es ; "
5662 + "int $0x15 ; "
5663 + "setc %0 ; "
5664 + "movw %%es, %1 ; "
5665 +diff -urNp linux-2.6.26.6/arch/x86/ia32/ia32_signal.c linux-2.6.26.6/arch/x86/ia32/ia32_signal.c
5666 +--- linux-2.6.26.6/arch/x86/ia32/ia32_signal.c 2008-10-08 23:24:05.000000000 -0400
5667 ++++ linux-2.6.26.6/arch/x86/ia32/ia32_signal.c 2008-10-11 21:54:19.000000000 -0400
5668 +@@ -531,6 +531,7 @@ int ia32_setup_rt_frame(int sig, struct
5669 + __NR_ia32_rt_sigreturn,
5670 + 0x80cd,
5671 + 0,
5672 ++ 0
5673 + };
5674 +
5675 + frame = get_sigframe(ka, regs, sizeof(*frame));
5676 +diff -urNp linux-2.6.26.6/arch/x86/Kconfig linux-2.6.26.6/arch/x86/Kconfig
5677 +--- linux-2.6.26.6/arch/x86/Kconfig 2008-10-08 23:24:05.000000000 -0400
5678 ++++ linux-2.6.26.6/arch/x86/Kconfig 2008-10-11 21:54:19.000000000 -0400
5679 +@@ -887,7 +887,7 @@ config PAGE_OFFSET
5680 + hex
5681 + default 0xB0000000 if VMSPLIT_3G_OPT
5682 + default 0x80000000 if VMSPLIT_2G
5683 +- default 0x78000000 if VMSPLIT_2G_OPT
5684 ++ default 0x70000000 if VMSPLIT_2G_OPT
5685 + default 0x40000000 if VMSPLIT_1G
5686 + default 0xC0000000
5687 + depends on X86_32
5688 +@@ -1206,8 +1206,7 @@ config CRASH_DUMP
5689 + config PHYSICAL_START
5690 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
5691 + default "0x1000000" if X86_NUMAQ
5692 +- default "0x200000" if X86_64
5693 +- default "0x100000"
5694 ++ default "0x200000"
5695 + help
5696 + This gives the physical address where the kernel is loaded.
5697 +
5698 +@@ -1299,9 +1298,9 @@ config HOTPLUG_CPU
5699 + suspend.
5700 +
5701 + config COMPAT_VDSO
5702 +- def_bool y
5703 ++ def_bool n
5704 + prompt "Compat VDSO support"
5705 +- depends on X86_32 || IA32_EMULATION
5706 ++ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
5707 + help
5708 + Map the 32-bit VDSO to the predictable old-style address too.
5709 + ---help---
5710 +@@ -1488,7 +1487,7 @@ config PCI
5711 + choice
5712 + prompt "PCI access mode"
5713 + depends on X86_32 && PCI && !X86_VISWS
5714 +- default PCI_GOANY
5715 ++ default PCI_GODIRECT
5716 + ---help---
5717 + On PCI systems, the BIOS can be used to detect the PCI devices and
5718 + determine their configuration. However, some old PCI motherboards
5719 +diff -urNp linux-2.6.26.6/arch/x86/Kconfig.cpu linux-2.6.26.6/arch/x86/Kconfig.cpu
5720 +--- linux-2.6.26.6/arch/x86/Kconfig.cpu 2008-10-08 23:24:05.000000000 -0400
5721 ++++ linux-2.6.26.6/arch/x86/Kconfig.cpu 2008-10-11 21:54:19.000000000 -0400
5722 +@@ -340,7 +340,7 @@ config X86_PPRO_FENCE
5723 +
5724 + config X86_F00F_BUG
5725 + def_bool y
5726 +- depends on M586MMX || M586TSC || M586 || M486 || M386
5727 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
5728 +
5729 + config X86_WP_WORKS_OK
5730 + def_bool y
5731 +@@ -360,7 +360,7 @@ config X86_POPAD_OK
5732 +
5733 + config X86_ALIGNMENT_16
5734 + def_bool y
5735 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
5736 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
5737 +
5738 + config X86_GOOD_APIC
5739 + def_bool y
5740 +@@ -403,7 +403,7 @@ config X86_TSC
5741 + # generates cmov.
5742 + config X86_CMOV
5743 + def_bool y
5744 +- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
5745 ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
5746 +
5747 + config X86_MINIMUM_CPU_FAMILY
5748 + int
5749 +diff -urNp linux-2.6.26.6/arch/x86/Kconfig.debug linux-2.6.26.6/arch/x86/Kconfig.debug
5750 +--- linux-2.6.26.6/arch/x86/Kconfig.debug 2008-10-08 23:24:05.000000000 -0400
5751 ++++ linux-2.6.26.6/arch/x86/Kconfig.debug 2008-10-11 21:54:19.000000000 -0400
5752 +@@ -84,7 +84,7 @@ config X86_PTDUMP
5753 + config DEBUG_RODATA
5754 + bool "Write protect kernel read-only data structures"
5755 + default y
5756 +- depends on DEBUG_KERNEL
5757 ++ depends on DEBUG_KERNEL && BROKEN
5758 + help
5759 + Mark the kernel read-only data as write-protected in the pagetables,
5760 + in order to catch accidental (and incorrect) writes to such const
5761 +diff -urNp linux-2.6.26.6/arch/x86/kernel/acpi/boot.c linux-2.6.26.6/arch/x86/kernel/acpi/boot.c
5762 +--- linux-2.6.26.6/arch/x86/kernel/acpi/boot.c 2008-10-08 23:24:05.000000000 -0400
5763 ++++ linux-2.6.26.6/arch/x86/kernel/acpi/boot.c 2008-10-11 21:54:19.000000000 -0400
5764 +@@ -1227,7 +1227,7 @@ static struct dmi_system_id __initdata a
5765 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
5766 + },
5767 + },
5768 +- {}
5769 ++ { NULL, NULL, {{0, NULL}}, NULL}
5770 + };
5771 +
5772 + #endif /* __i386__ */
5773 +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
5774 +--- linux-2.6.26.6/arch/x86/kernel/acpi/realmode/wakeup.S 2008-10-08 23:24:05.000000000 -0400
5775 ++++ linux-2.6.26.6/arch/x86/kernel/acpi/realmode/wakeup.S 2008-10-11 21:54:19.000000000 -0400
5776 +@@ -104,7 +104,7 @@ _start:
5777 + movl %eax, %ecx
5778 + orl %edx, %ecx
5779 + jz 1f
5780 +- movl $0xc0000080, %ecx
5781 ++ mov $MSR_EFER, %ecx
5782 + wrmsr
5783 + 1:
5784 +
5785 +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
5786 +--- linux-2.6.26.6/arch/x86/kernel/acpi/wakeup_32.S 2008-10-08 23:24:05.000000000 -0400
5787 ++++ linux-2.6.26.6/arch/x86/kernel/acpi/wakeup_32.S 2008-10-11 21:54:19.000000000 -0400
5788 +@@ -30,13 +30,11 @@ wakeup_pmode_return:
5789 + # and restore the stack ... but you need gdt for this to work
5790 + movl saved_context_esp, %esp
5791 +
5792 +- movl %cs:saved_magic, %eax
5793 +- cmpl $0x12345678, %eax
5794 ++ cmpl $0x12345678, saved_magic
5795 + jne bogus_magic
5796 +
5797 + # jump to place where we left off
5798 +- movl saved_eip, %eax
5799 +- jmp *%eax
5800 ++ jmp *(saved_eip)
5801 +
5802 + bogus_magic:
5803 + jmp bogus_magic
5804 +diff -urNp linux-2.6.26.6/arch/x86/kernel/alternative.c linux-2.6.26.6/arch/x86/kernel/alternative.c
5805 +--- linux-2.6.26.6/arch/x86/kernel/alternative.c 2008-10-08 23:24:05.000000000 -0400
5806 ++++ linux-2.6.26.6/arch/x86/kernel/alternative.c 2008-10-11 22:15:25.000000000 -0400
5807 +@@ -403,7 +403,7 @@ void apply_paravirt(struct paravirt_patc
5808 +
5809 + BUG_ON(p->len > MAX_PATCH_LEN);
5810 + /* prep the buffer with the original instructions */
5811 +- memcpy(insnbuf, p->instr, p->len);
5812 ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
5813 + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
5814 + (unsigned long)p->instr, p->len);
5815 +
5816 +@@ -483,11 +483,26 @@ void __init alternative_instructions(voi
5817 + * instructions. And on the local CPU you need to be protected again NMI or MCE
5818 + * handlers seeing an inconsistent instruction while you patch.
5819 + */
5820 +-void *text_poke_early(void *addr, const void *opcode, size_t len)
5821 ++void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
5822 + {
5823 + unsigned long flags;
5824 ++
5825 ++#ifdef CONFIG_PAX_KERNEXEC
5826 ++ unsigned long cr0;
5827 ++#endif
5828 ++
5829 + local_irq_save(flags);
5830 +- memcpy(addr, opcode, len);
5831 ++
5832 ++#ifdef CONFIG_PAX_KERNEXEC
5833 ++ pax_open_kernel(cr0);
5834 ++#endif
5835 ++
5836 ++ memcpy(ktla_ktva(addr), opcode, len);
5837 ++
5838 ++#ifdef CONFIG_PAX_KERNEXEC
5839 ++ pax_close_kernel(cr0);
5840 ++#endif
5841 ++
5842 + local_irq_restore(flags);
5843 + sync_core();
5844 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
5845 +@@ -508,33 +523,27 @@ void *text_poke_early(void *addr, const
5846 + */
5847 + void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
5848 + {
5849 +- unsigned long flags;
5850 +- char *vaddr;
5851 +- int nr_pages = 2;
5852 ++ unsigned char *vaddr = ktla_ktva(addr);
5853 + struct page *pages[2];
5854 +- int i;
5855 ++ size_t i;
5856 ++
5857 ++ if (!core_kernel_text((unsigned long)addr)
5858 +
5859 +- if (!core_kernel_text((unsigned long)addr)) {
5860 +- pages[0] = vmalloc_to_page(addr);
5861 +- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
5862 ++#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
5863 ++ && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
5864 ++#endif
5865 ++
5866 ++ ) {
5867 ++ pages[0] = vmalloc_to_page(vaddr);
5868 ++ pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
5869 + } else {
5870 +- pages[0] = virt_to_page(addr);
5871 ++ pages[0] = virt_to_page(vaddr);
5872 + WARN_ON(!PageReserved(pages[0]));
5873 +- pages[1] = virt_to_page(addr + PAGE_SIZE);
5874 ++ pages[1] = virt_to_page(vaddr + PAGE_SIZE);
5875 + }
5876 + BUG_ON(!pages[0]);
5877 +- if (!pages[1])
5878 +- nr_pages = 1;
5879 +- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
5880 +- BUG_ON(!vaddr);
5881 +- local_irq_save(flags);
5882 +- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
5883 +- local_irq_restore(flags);
5884 +- vunmap(vaddr);
5885 +- sync_core();
5886 +- /* Could also do a CLFLUSH here to speed up CPU recovery; but
5887 +- that causes hangs on some VIA CPUs. */
5888 ++ text_poke_early(addr, opcode, len);
5889 + for (i = 0; i < len; i++)
5890 +- BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
5891 ++ BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
5892 + return addr;
5893 + }
5894 +diff -urNp linux-2.6.26.6/arch/x86/kernel/apm_32.c linux-2.6.26.6/arch/x86/kernel/apm_32.c
5895 +--- linux-2.6.26.6/arch/x86/kernel/apm_32.c 2008-10-08 23:24:05.000000000 -0400
5896 ++++ linux-2.6.26.6/arch/x86/kernel/apm_32.c 2008-10-11 21:54:19.000000000 -0400
5897 +@@ -406,7 +406,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
5898 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
5899 + static struct apm_user *user_list;
5900 + static DEFINE_SPINLOCK(user_list_lock);
5901 +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
5902 ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
5903 +
5904 + static const char driver_version[] = "1.16ac"; /* no spaces */
5905 +
5906 +@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
5907 + struct desc_struct save_desc_40;
5908 + struct desc_struct *gdt;
5909 +
5910 ++#ifdef CONFIG_PAX_KERNEXEC
5911 ++ unsigned long cr0;
5912 ++#endif
5913 ++
5914 + cpus = apm_save_cpus();
5915 +
5916 + cpu = get_cpu();
5917 + gdt = get_cpu_gdt_table(cpu);
5918 + save_desc_40 = gdt[0x40 / 8];
5919 ++
5920 ++#ifdef CONFIG_PAX_KERNEXEC
5921 ++ pax_open_kernel(cr0);
5922 ++#endif
5923 ++
5924 + gdt[0x40 / 8] = bad_bios_desc;
5925 +
5926 ++#ifdef CONFIG_PAX_KERNEXEC
5927 ++ pax_close_kernel(cr0);
5928 ++#endif
5929 ++
5930 + apm_irq_save(flags);
5931 + APM_DO_SAVE_SEGS;
5932 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
5933 + APM_DO_RESTORE_SEGS;
5934 + apm_irq_restore(flags);
5935 ++
5936 ++#ifdef CONFIG_PAX_KERNEXEC
5937 ++ pax_open_kernel(cr0);
5938 ++#endif
5939 ++
5940 + gdt[0x40 / 8] = save_desc_40;
5941 ++
5942 ++#ifdef CONFIG_PAX_KERNEXEC
5943 ++ pax_close_kernel(cr0);
5944 ++#endif
5945 ++
5946 + put_cpu();
5947 + apm_restore_cpus(cpus);
5948 +
5949 +@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
5950 + struct desc_struct save_desc_40;
5951 + struct desc_struct *gdt;
5952 +
5953 ++#ifdef CONFIG_PAX_KERNEXEC
5954 ++ unsigned long cr0;
5955 ++#endif
5956 ++
5957 + cpus = apm_save_cpus();
5958 +
5959 + cpu = get_cpu();
5960 + gdt = get_cpu_gdt_table(cpu);
5961 + save_desc_40 = gdt[0x40 / 8];
5962 ++
5963 ++#ifdef CONFIG_PAX_KERNEXEC
5964 ++ pax_open_kernel(cr0);
5965 ++#endif
5966 ++
5967 + gdt[0x40 / 8] = bad_bios_desc;
5968 +
5969 ++#ifdef CONFIG_PAX_KERNEXEC
5970 ++ pax_close_kernel(cr0);
5971 ++#endif
5972 ++
5973 + apm_irq_save(flags);
5974 + APM_DO_SAVE_SEGS;
5975 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
5976 + APM_DO_RESTORE_SEGS;
5977 + apm_irq_restore(flags);
5978 ++
5979 ++#ifdef CONFIG_PAX_KERNEXEC
5980 ++ pax_open_kernel(cr0);
5981 ++#endif
5982 ++
5983 + gdt[0x40 / 8] = save_desc_40;
5984 ++
5985 ++#ifdef CONFIG_PAX_KERNEXEC
5986 ++ pax_close_kernel(cr0);
5987 ++#endif
5988 ++
5989 + put_cpu();
5990 + apm_restore_cpus(cpus);
5991 + return error;
5992 +@@ -928,7 +974,7 @@ recalc:
5993 +
5994 + static void apm_power_off(void)
5995 + {
5996 +- unsigned char po_bios_call[] = {
5997 ++ const unsigned char po_bios_call[] = {
5998 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
5999 + 0x8e, 0xd0, /* movw ax,ss */
6000 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
6001 +@@ -1868,7 +1914,10 @@ static const struct file_operations apm_
6002 + static struct miscdevice apm_device = {
6003 + APM_MINOR_DEV,
6004 + "apm_bios",
6005 +- &apm_bios_fops
6006 ++ &apm_bios_fops,
6007 ++ {NULL, NULL},
6008 ++ NULL,
6009 ++ NULL
6010 + };
6011 +
6012 +
6013 +@@ -2189,7 +2238,7 @@ static struct dmi_system_id __initdata a
6014 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
6015 + },
6016 +
6017 +- { }
6018 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
6019 + };
6020 +
6021 + /*
6022 +@@ -2207,6 +2256,10 @@ static int __init apm_init(void)
6023 + struct desc_struct *gdt;
6024 + int err;
6025 +
6026 ++#ifdef CONFIG_PAX_KERNEXEC
6027 ++ unsigned long cr0;
6028 ++#endif
6029 ++
6030 + dmi_check_system(apm_dmi_table);
6031 +
6032 + if (apm_info.bios.version == 0 || paravirt_enabled()) {
6033 +@@ -2280,9 +2333,18 @@ static int __init apm_init(void)
6034 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
6035 + * even though they are called in protected mode.
6036 + */
6037 ++
6038 ++#ifdef CONFIG_PAX_KERNEXEC
6039 ++ pax_open_kernel(cr0);
6040 ++#endif
6041 ++
6042 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
6043 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
6044 +
6045 ++#ifdef CONFIG_PAX_KERNEXEC
6046 ++ pax_close_kernel(cr0);
6047 ++#endif
6048 ++
6049 + /*
6050 + * Set up the long jump entry point to the APM BIOS, which is called
6051 + * from inline assembly.
6052 +@@ -2301,6 +2363,11 @@ static int __init apm_init(void)
6053 + * code to that CPU.
6054 + */
6055 + gdt = get_cpu_gdt_table(0);
6056 ++
6057 ++#ifdef CONFIG_PAX_KERNEXEC
6058 ++ pax_open_kernel(cr0);
6059 ++#endif
6060 ++
6061 + set_base(gdt[APM_CS >> 3],
6062 + __va((unsigned long)apm_info.bios.cseg << 4));
6063 + set_base(gdt[APM_CS_16 >> 3],
6064 +@@ -2308,6 +2375,10 @@ static int __init apm_init(void)
6065 + set_base(gdt[APM_DS >> 3],
6066 + __va((unsigned long)apm_info.bios.dseg << 4));
6067 +
6068 ++#ifdef CONFIG_PAX_KERNEXEC
6069 ++ pax_close_kernel(cr0);
6070 ++#endif
6071 ++
6072 + proc_create("apm", 0, NULL, &apm_file_ops);
6073 +
6074 + kapmd_task = kthread_create(apm, NULL, "kapmd");
6075 +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
6076 +--- linux-2.6.26.6/arch/x86/kernel/asm-offsets_32.c 2008-10-08 23:24:05.000000000 -0400
6077 ++++ linux-2.6.26.6/arch/x86/kernel/asm-offsets_32.c 2008-10-11 21:54:19.000000000 -0400
6078 +@@ -100,6 +100,7 @@ void foo(void)
6079 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
6080 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
6081 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
6082 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
6083 +
6084 + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
6085 +
6086 +@@ -113,6 +114,7 @@ void foo(void)
6087 + OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
6088 + OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
6089 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
6090 ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
6091 + #endif
6092 +
6093 + #ifdef CONFIG_XEN
6094 +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
6095 +--- linux-2.6.26.6/arch/x86/kernel/asm-offsets_64.c 2008-10-08 23:24:05.000000000 -0400
6096 ++++ linux-2.6.26.6/arch/x86/kernel/asm-offsets_64.c 2008-10-11 21:54:19.000000000 -0400
6097 +@@ -117,6 +117,7 @@ int main(void)
6098 + ENTRY(cr8);
6099 + BLANK();
6100 + #undef ENTRY
6101 ++ DEFINE(TSS_size, sizeof(struct tss_struct));
6102 + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
6103 + BLANK();
6104 + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
6105 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/common.c linux-2.6.26.6/arch/x86/kernel/cpu/common.c
6106 +--- linux-2.6.26.6/arch/x86/kernel/cpu/common.c 2008-10-08 23:24:05.000000000 -0400
6107 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/common.c 2008-10-11 21:54:19.000000000 -0400
6108 +@@ -4,7 +4,6 @@
6109 + #include <linux/smp.h>
6110 + #include <linux/module.h>
6111 + #include <linux/percpu.h>
6112 +-#include <linux/bootmem.h>
6113 + #include <asm/processor.h>
6114 + #include <asm/i387.h>
6115 + #include <asm/msr.h>
6116 +@@ -21,42 +20,6 @@
6117 +
6118 + #include "cpu.h"
6119 +
6120 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
6121 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
6122 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
6123 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
6124 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
6125 +- /*
6126 +- * Segments used for calling PnP BIOS have byte granularity.
6127 +- * They code segments and data segments have fixed 64k limits,
6128 +- * the transfer segment sizes are set at run time.
6129 +- */
6130 +- /* 32-bit code */
6131 +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
6132 +- /* 16-bit code */
6133 +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
6134 +- /* 16-bit data */
6135 +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
6136 +- /* 16-bit data */
6137 +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
6138 +- /* 16-bit data */
6139 +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
6140 +- /*
6141 +- * The APM segments have byte granularity and their bases
6142 +- * are set at run time. All have 64k limits.
6143 +- */
6144 +- /* 32-bit code */
6145 +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
6146 +- /* 16-bit code */
6147 +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
6148 +- /* data */
6149 +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
6150 +-
6151 +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
6152 +- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
6153 +-} };
6154 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
6155 +-
6156 + __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
6157 +
6158 + static int cachesize_override __cpuinitdata = -1;
6159 +@@ -479,6 +442,10 @@ void __cpuinit identify_cpu(struct cpuin
6160 + * we do "generic changes."
6161 + */
6162 +
6163 ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
6164 ++ setup_clear_cpu_cap(X86_FEATURE_SEP);
6165 ++#endif
6166 ++
6167 + /* If the model name is still unset, do table lookup. */
6168 + if (!c->x86_model_id[0]) {
6169 + char *p;
6170 +@@ -615,7 +582,7 @@ static __init int setup_disablecpuid(cha
6171 + }
6172 + __setup("clearcpuid=", setup_disablecpuid);
6173 +
6174 +-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
6175 ++cpumask_t cpu_initialized = CPU_MASK_NONE;
6176 +
6177 + void __init early_cpu_init(void)
6178 + {
6179 +@@ -644,7 +611,7 @@ void switch_to_new_gdt(void)
6180 + {
6181 + struct desc_ptr gdt_descr;
6182 +
6183 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
6184 ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
6185 + gdt_descr.size = GDT_SIZE - 1;
6186 + load_gdt(&gdt_descr);
6187 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
6188 +@@ -660,7 +627,7 @@ void __cpuinit cpu_init(void)
6189 + {
6190 + int cpu = smp_processor_id();
6191 + struct task_struct *curr = current;
6192 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
6193 ++ struct tss_struct *t = init_tss + cpu;
6194 + struct thread_struct *thread = &curr->thread;
6195 +
6196 + if (cpu_test_and_set(cpu, cpu_initialized)) {
6197 +@@ -715,7 +682,7 @@ void __cpuinit cpu_init(void)
6198 + }
6199 +
6200 + #ifdef CONFIG_HOTPLUG_CPU
6201 +-void __cpuinit cpu_uninit(void)
6202 ++void cpu_uninit(void)
6203 + {
6204 + int cpu = raw_smp_processor_id();
6205 + cpu_clear(cpu, cpu_initialized);
6206 +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
6207 +--- linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-10-08 23:24:05.000000000 -0400
6208 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-10-11 21:54:19.000000000 -0400
6209 +@@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
6210 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
6211 + },
6212 + },
6213 +- { }
6214 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
6215 + };
6216 + #endif
6217 +
6218 +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
6219 +--- linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-10-08 23:24:05.000000000 -0400
6220 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-10-11 21:54:19.000000000 -0400
6221 +@@ -223,7 +223,7 @@ static struct cpu_model models[] =
6222 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
6223 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
6224 +
6225 +- { NULL, }
6226 ++ { NULL, NULL, 0, NULL}
6227 + };
6228 + #undef _BANIAS
6229 + #undef BANIAS
6230 +diff -urNp linux-2.6.26.6/arch/x86/kernel/cpu/intel.c linux-2.6.26.6/arch/x86/kernel/cpu/intel.c
6231 +--- linux-2.6.26.6/arch/x86/kernel/cpu/intel.c 2008-10-08 23:24:05.000000000 -0400
6232 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/intel.c 2008-10-11 21:54:19.000000000 -0400
6233 +@@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
6234 + * Update the IDT descriptor and reload the IDT so that
6235 + * it uses the read-only mapped virtual address.
6236 + */
6237 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
6238 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
6239 + load_idt(&idt_descr);
6240 + }
6241 + #endif
6242 +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
6243 +--- linux-2.6.26.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-10-08 23:24:05.000000000 -0400
6244 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-10-11 21:54:19.000000000 -0400
6245 +@@ -672,6 +672,7 @@ static struct miscdevice mce_log_device
6246 + MISC_MCELOG_MINOR,
6247 + "mcelog",
6248 + &mce_chrdev_ops,
6249 ++ {NULL, NULL}, NULL, NULL
6250 + };
6251 +
6252 + static unsigned long old_cr4 __initdata;
6253 +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
6254 +--- linux-2.6.26.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-08 23:24:05.000000000 -0400
6255 ++++ linux-2.6.26.6/arch/x86/kernel/cpu/mtrr/generic.c 2008-10-11 21:55:52.000000000 -0400
6256 +@@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
6257 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
6258 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
6259 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
6260 +- {}
6261 ++ { 0, 0 }
6262 + };
6263 +
6264 + static unsigned long smp_changes_mask;
6265 +-static struct mtrr_state mtrr_state = {};
6266 ++static struct mtrr_state mtrr_state;
6267 + static int mtrr_state_set;
6268 + static u64 tom2;
6269 +
6270 +@@ -213,7 +213,7 @@ void __init get_mtrr_state(void)
6271 + mtrr_state.enabled = (lo & 0xc00) >> 10;
6272 +
6273 + if (amd_special_default_mtrr()) {
6274 +- unsigned lo, hi;
6275 ++ unsigned hi;
6276 + /* TOP_MEM2 */
6277 + rdmsr(MSR_K8_TOP_MEM2, lo, hi);
6278 + tom2 = hi;
6279 +diff -urNp linux-2.6.26.6/arch/x86/kernel/crash.c linux-2.6.26.6/arch/x86/kernel/crash.c
6280 +--- linux-2.6.26.6/arch/x86/kernel/crash.c 2008-10-08 23:24:05.000000000 -0400
6281 ++++ linux-2.6.26.6/arch/x86/kernel/crash.c 2008-10-11 21:54:19.000000000 -0400
6282 +@@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
6283 + local_irq_disable();
6284 +
6285 + #ifdef CONFIG_X86_32
6286 +- if (!user_mode_vm(regs)) {
6287 ++ if (!user_mode(regs)) {
6288 + crash_fixup_ss_esp(&fixed_regs, regs);
6289 + regs = &fixed_regs;
6290 + }
6291 +diff -urNp linux-2.6.26.6/arch/x86/kernel/doublefault_32.c linux-2.6.26.6/arch/x86/kernel/doublefault_32.c
6292 +--- linux-2.6.26.6/arch/x86/kernel/doublefault_32.c 2008-10-08 23:24:05.000000000 -0400
6293 ++++ linux-2.6.26.6/arch/x86/kernel/doublefault_32.c 2008-10-11 21:54:19.000000000 -0400
6294 +@@ -11,7 +11,7 @@
6295 +
6296 + #define DOUBLEFAULT_STACKSIZE (1024)
6297 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
6298 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
6299 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
6300 +
6301 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
6302 +
6303 +@@ -21,7 +21,7 @@ static void doublefault_fn(void)
6304 + unsigned long gdt, tss;
6305 +
6306 + store_gdt(&gdt_desc);
6307 +- gdt = gdt_desc.address;
6308 ++ gdt = (unsigned long)gdt_desc.address;
6309 +
6310 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
6311 +
6312 +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
6313 + /* 0x2 bit is always set */
6314 + .flags = X86_EFLAGS_SF | 0x2,
6315 + .sp = STACK_START,
6316 +- .es = __USER_DS,
6317 ++ .es = __KERNEL_DS,
6318 + .cs = __KERNEL_CS,
6319 + .ss = __KERNEL_DS,
6320 +- .ds = __USER_DS,
6321 ++ .ds = __KERNEL_DS,
6322 + .fs = __KERNEL_PERCPU,
6323 +
6324 + .__cr3 = __pa(swapper_pg_dir)
6325 +diff -urNp linux-2.6.26.6/arch/x86/kernel/efi_32.c linux-2.6.26.6/arch/x86/kernel/efi_32.c
6326 +--- linux-2.6.26.6/arch/x86/kernel/efi_32.c 2008-10-08 23:24:05.000000000 -0400
6327 ++++ linux-2.6.26.6/arch/x86/kernel/efi_32.c 2008-10-11 21:54:19.000000000 -0400
6328 +@@ -38,70 +38,37 @@
6329 + */
6330 +
6331 + static unsigned long efi_rt_eflags;
6332 +-static pgd_t efi_bak_pg_dir_pointer[2];
6333 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
6334 +
6335 +-void efi_call_phys_prelog(void)
6336 ++void __init efi_call_phys_prelog(void)
6337 + {
6338 +- unsigned long cr4;
6339 +- unsigned long temp;
6340 + struct desc_ptr gdt_descr;
6341 +
6342 + local_irq_save(efi_rt_eflags);
6343 +
6344 +- /*
6345 +- * If I don't have PAE, I should just duplicate two entries in page
6346 +- * directory. If I have PAE, I just need to duplicate one entry in
6347 +- * page directory.
6348 +- */
6349 +- cr4 = read_cr4();
6350 +-
6351 +- if (cr4 & X86_CR4_PAE) {
6352 +- efi_bak_pg_dir_pointer[0].pgd =
6353 +- swapper_pg_dir[pgd_index(0)].pgd;
6354 +- swapper_pg_dir[0].pgd =
6355 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6356 +- } else {
6357 +- efi_bak_pg_dir_pointer[0].pgd =
6358 +- swapper_pg_dir[pgd_index(0)].pgd;
6359 +- efi_bak_pg_dir_pointer[1].pgd =
6360 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
6361 +- swapper_pg_dir[pgd_index(0)].pgd =
6362 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
6363 +- temp = PAGE_OFFSET + 0x400000;
6364 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
6365 +- swapper_pg_dir[pgd_index(temp)].pgd;
6366 +- }
6367 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
6368 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6369 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6370 +
6371 + /*
6372 + * After the lock is released, the original page table is restored.
6373 + */
6374 + __flush_tlb_all();
6375 +
6376 +- gdt_descr.address = __pa(get_cpu_gdt_table(0));
6377 ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
6378 + gdt_descr.size = GDT_SIZE - 1;
6379 + load_gdt(&gdt_descr);
6380 + }
6381 +
6382 +-void efi_call_phys_epilog(void)
6383 ++void __init efi_call_phys_epilog(void)
6384 + {
6385 +- unsigned long cr4;
6386 + struct desc_ptr gdt_descr;
6387 +
6388 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
6389 ++ gdt_descr.address = get_cpu_gdt_table(0);
6390 + gdt_descr.size = GDT_SIZE - 1;
6391 + load_gdt(&gdt_descr);
6392 +
6393 +- cr4 = read_cr4();
6394 +-
6395 +- if (cr4 & X86_CR4_PAE) {
6396 +- swapper_pg_dir[pgd_index(0)].pgd =
6397 +- efi_bak_pg_dir_pointer[0].pgd;
6398 +- } else {
6399 +- swapper_pg_dir[pgd_index(0)].pgd =
6400 +- efi_bak_pg_dir_pointer[0].pgd;
6401 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
6402 +- efi_bak_pg_dir_pointer[1].pgd;
6403 +- }
6404 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
6405 +
6406 + /*
6407 + * After the lock is released, the original page table is restored.
6408 +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
6409 +--- linux-2.6.26.6/arch/x86/kernel/efi_stub_32.S 2008-10-08 23:24:05.000000000 -0400
6410 ++++ linux-2.6.26.6/arch/x86/kernel/efi_stub_32.S 2008-10-11 21:54:19.000000000 -0400
6411 +@@ -6,6 +6,7 @@
6412 + */
6413 +
6414 + #include <linux/linkage.h>
6415 ++#include <linux/init.h>
6416 + #include <asm/page.h>
6417 +
6418 + /*
6419 +@@ -20,7 +21,7 @@
6420 + * service functions will comply with gcc calling convention, too.
6421 + */
6422 +
6423 +-.text
6424 ++__INIT
6425 + ENTRY(efi_call_phys)
6426 + /*
6427 + * 0. The function can only be called in Linux kernel. So CS has been
6428 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
6429 + * The mapping of lower virtual memory has been created in prelog and
6430 + * epilog.
6431 + */
6432 +- movl $1f, %edx
6433 +- subl $__PAGE_OFFSET, %edx
6434 +- jmp *%edx
6435 ++ jmp 1f-__PAGE_OFFSET
6436 + 1:
6437 +
6438 + /*
6439 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
6440 + * parameter 2, ..., param n. To make things easy, we save the return
6441 + * address of efi_call_phys in a global variable.
6442 + */
6443 +- popl %edx
6444 +- movl %edx, saved_return_addr
6445 +- /* get the function pointer into ECX*/
6446 +- popl %ecx
6447 +- movl %ecx, efi_rt_function_ptr
6448 +- movl $2f, %edx
6449 +- subl $__PAGE_OFFSET, %edx
6450 +- pushl %edx
6451 ++ popl (saved_return_addr)
6452 ++ popl (efi_rt_function_ptr)
6453 +
6454 + /*
6455 + * 3. Clear PG bit in %CR0.
6456 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
6457 + /*
6458 + * 5. Call the physical function.
6459 + */
6460 +- jmp *%ecx
6461 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
6462 +
6463 +-2:
6464 + /*
6465 + * 6. After EFI runtime service returns, control will return to
6466 + * following instruction. We'd better readjust stack pointer first.
6467 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
6468 + movl %cr0, %edx
6469 + orl $0x80000000, %edx
6470 + movl %edx, %cr0
6471 +- jmp 1f
6472 +-1:
6473 ++
6474 + /*
6475 + * 8. Now restore the virtual mode from flat mode by
6476 + * adding EIP with PAGE_OFFSET.
6477 + */
6478 +- movl $1f, %edx
6479 +- jmp *%edx
6480 ++ jmp 1f+__PAGE_OFFSET
6481 + 1:
6482 +
6483 + /*
6484 + * 9. Balance the stack. And because EAX contain the return value,
6485 + * we'd better not clobber it.
6486 + */
6487 +- leal efi_rt_function_ptr, %edx
6488 +- movl (%edx), %ecx
6489 +- pushl %ecx
6490 ++ pushl (efi_rt_function_ptr)
6491 +
6492 + /*
6493 +- * 10. Push the saved return address onto the stack and return.
6494 ++ * 10. Return to the saved return address.
6495 + */
6496 +- leal saved_return_addr, %edx
6497 +- movl (%edx), %ecx
6498 +- pushl %ecx
6499 +- ret
6500 ++ jmpl *(saved_return_addr)
6501 + .previous
6502 +
6503 +-.data
6504 ++__INITDATA
6505 + saved_return_addr:
6506 + .long 0
6507 + efi_rt_function_ptr:
6508 +diff -urNp linux-2.6.26.6/arch/x86/kernel/entry_32.S linux-2.6.26.6/arch/x86/kernel/entry_32.S
6509 +--- linux-2.6.26.6/arch/x86/kernel/entry_32.S 2008-10-08 23:24:05.000000000 -0400
6510 ++++ linux-2.6.26.6/arch/x86/kernel/entry_32.S 2008-10-11 21:54:19.000000000 -0400
6511 +@@ -90,7 +90,7 @@
6512 + #define resume_userspace_sig resume_userspace
6513 + #endif
6514 +
6515 +-#define SAVE_ALL \
6516 ++#define __SAVE_ALL(_DS) \
6517 + cld; \
6518 + pushl %fs; \
6519 + CFI_ADJUST_CFA_OFFSET 4;\
6520 +@@ -122,12 +122,26 @@
6521 + pushl %ebx; \
6522 + CFI_ADJUST_CFA_OFFSET 4;\
6523 + CFI_REL_OFFSET ebx, 0;\
6524 +- movl $(__USER_DS), %edx; \
6525 ++ movl $(_DS), %edx; \
6526 + movl %edx, %ds; \
6527 + movl %edx, %es; \
6528 + movl $(__KERNEL_PERCPU), %edx; \
6529 + movl %edx, %fs
6530 +
6531 ++#ifdef CONFIG_PAX_KERNEXEC
6532 ++#define SAVE_ALL \
6533 ++ __SAVE_ALL(__KERNEL_DS); \
6534 ++ GET_CR0_INTO_EDX; \
6535 ++ movl %edx, %esi; \
6536 ++ orl $X86_CR0_WP, %edx; \
6537 ++ xorl %edx, %esi; \
6538 ++ SET_CR0_FROM_EDX
6539 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
6540 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
6541 ++#else
6542 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
6543 ++#endif
6544 ++
6545 + #define RESTORE_INT_REGS \
6546 + popl %ebx; \
6547 + CFI_ADJUST_CFA_OFFSET -4;\
6548 +@@ -218,6 +232,11 @@ ENTRY(ret_from_fork)
6549 + CFI_ADJUST_CFA_OFFSET 4
6550 + popfl
6551 + CFI_ADJUST_CFA_OFFSET -4
6552 ++
6553 ++#ifdef CONFIG_PAX_KERNEXEC
6554 ++ xorl %esi, %esi
6555 ++#endif
6556 ++
6557 + jmp syscall_exit
6558 + CFI_ENDPROC
6559 + END(ret_from_fork)
6560 +@@ -241,7 +260,17 @@ check_userspace:
6561 + movb PT_CS(%esp), %al
6562 + andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
6563 + cmpl $USER_RPL, %eax
6564 ++
6565 ++#ifdef CONFIG_PAX_KERNEXEC
6566 ++ jae resume_userspace
6567 ++
6568 ++ GET_CR0_INTO_EDX
6569 ++ xorl %esi, %edx
6570 ++ SET_CR0_FROM_EDX
6571 ++ jmp resume_kernel
6572 ++#else
6573 + jb resume_kernel # not returning to v8086 or userspace
6574 ++#endif
6575 +
6576 + ENTRY(resume_userspace)
6577 + LOCKDEP_SYS_EXIT
6578 +@@ -303,10 +332,9 @@ sysenter_past_esp:
6579 + /*CFI_REL_OFFSET cs, 0*/
6580 + /*
6581 + * Push current_thread_info()->sysenter_return to the stack.
6582 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
6583 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
6584 + */
6585 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
6586 ++ GET_THREAD_INFO(%ebp)
6587 ++ pushl TI_sysenter_return(%ebp)
6588 + CFI_ADJUST_CFA_OFFSET 4
6589 + CFI_REL_OFFSET eip, 0
6590 +
6591 +@@ -319,9 +347,17 @@ sysenter_past_esp:
6592 + * Load the potential sixth argument from user stack.
6593 + * Careful about security.
6594 + */
6595 ++ movl PT_OLDESP(%esp),%ebp
6596 ++
6597 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6598 ++ mov PT_OLDSS(%esp),%ds
6599 ++1: movl %ds:(%ebp),%ebp
6600 ++#else
6601 + cmpl $__PAGE_OFFSET-3,%ebp
6602 + jae syscall_fault
6603 + 1: movl (%ebp),%ebp
6604 ++#endif
6605 ++
6606 + movl %ebp,PT_EBP(%esp)
6607 + .section __ex_table,"a"
6608 + .align 4
6609 +@@ -343,20 +379,37 @@ sysenter_past_esp:
6610 + movl TI_flags(%ebp), %ecx
6611 + testw $_TIF_ALLWORK_MASK, %cx
6612 + jne syscall_exit_work
6613 ++
6614 ++#ifdef CONFIG_PAX_RANDKSTACK
6615 ++ pushl %eax
6616 ++ CFI_ADJUST_CFA_OFFSET 4
6617 ++ call pax_randomize_kstack
6618 ++ popl %eax
6619 ++ CFI_ADJUST_CFA_OFFSET -4
6620 ++#endif
6621 ++
6622 + /* if something modifies registers it must also disable sysexit */
6623 + movl PT_EIP(%esp), %edx
6624 + movl PT_OLDESP(%esp), %ecx
6625 + xorl %ebp,%ebp
6626 + TRACE_IRQS_ON
6627 + 1: mov PT_FS(%esp), %fs
6628 ++2: mov PT_DS(%esp), %ds
6629 ++3: mov PT_ES(%esp), %es
6630 + ENABLE_INTERRUPTS_SYSCALL_RET
6631 + CFI_ENDPROC
6632 + .pushsection .fixup,"ax"
6633 +-2: movl $0,PT_FS(%esp)
6634 ++4: movl $0,PT_FS(%esp)
6635 ++ jmp 1b
6636 ++5: movl $0,PT_DS(%esp)
6637 ++ jmp 1b
6638 ++6: movl $0,PT_ES(%esp)
6639 + jmp 1b
6640 + .section __ex_table,"a"
6641 + .align 4
6642 +- .long 1b,2b
6643 ++ .long 1b,4b
6644 ++ .long 2b,5b
6645 ++ .long 3b,6b
6646 + .popsection
6647 + ENDPROC(ia32_sysenter_target)
6648 +
6649 +@@ -390,6 +443,10 @@ no_singlestep:
6650 + testw $_TIF_ALLWORK_MASK, %cx # current->work
6651 + jne syscall_exit_work
6652 +
6653 ++#ifdef CONFIG_PAX_RANDKSTACK
6654 ++ call pax_randomize_kstack
6655 ++#endif
6656 ++
6657 + restore_all:
6658 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
6659 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
6660 +@@ -483,25 +540,19 @@ work_resched:
6661 +
6662 + work_notifysig: # deal with pending signals and
6663 + # notify-resume requests
6664 ++ movl %esp, %eax
6665 + #ifdef CONFIG_VM86
6666 + testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
6667 +- movl %esp, %eax
6668 +- jne work_notifysig_v86 # returning to kernel-space or
6669 ++ jz 1f # returning to kernel-space or
6670 + # vm86-space
6671 +- xorl %edx, %edx
6672 +- call do_notify_resume
6673 +- jmp resume_userspace_sig
6674 +
6675 +- ALIGN
6676 +-work_notifysig_v86:
6677 + pushl %ecx # save ti_flags for do_notify_resume
6678 + CFI_ADJUST_CFA_OFFSET 4
6679 + call save_v86_state # %eax contains pt_regs pointer
6680 + popl %ecx
6681 + CFI_ADJUST_CFA_OFFSET -4
6682 + movl %eax, %esp
6683 +-#else
6684 +- movl %esp, %eax
6685 ++1:
6686 + #endif
6687 + xorl %edx, %edx
6688 + call do_notify_resume
6689 +@@ -552,17 +603,24 @@ syscall_badsys:
6690 + END(syscall_badsys)
6691 + CFI_ENDPROC
6692 +
6693 +-#define FIXUP_ESPFIX_STACK \
6694 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
6695 +- PER_CPU(gdt_page, %ebx); \
6696 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
6697 +- addl %esp, %eax; \
6698 +- pushl $__KERNEL_DS; \
6699 +- CFI_ADJUST_CFA_OFFSET 4; \
6700 +- pushl %eax; \
6701 +- CFI_ADJUST_CFA_OFFSET 4; \
6702 +- lss (%esp), %esp; \
6703 ++.macro FIXUP_ESPFIX_STACK
6704 ++ /* since we are on a wrong stack, we cant make it a C code :( */
6705 ++#ifdef CONFIG_SMP
6706 ++ movl PER_CPU_VAR(cpu_number), %ebx;
6707 ++ shll $PAGE_SHIFT_asm, %ebx;
6708 ++ addl $cpu_gdt_table, %ebx;
6709 ++#else
6710 ++ movl $cpu_gdt_table, %ebx;
6711 ++#endif
6712 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
6713 ++ addl %esp, %eax;
6714 ++ pushl $__KERNEL_DS;
6715 ++ CFI_ADJUST_CFA_OFFSET 4;
6716 ++ pushl %eax;
6717 ++ CFI_ADJUST_CFA_OFFSET 4;
6718 ++ lss (%esp), %esp;
6719 + CFI_ADJUST_CFA_OFFSET -8;
6720 ++.endm
6721 + #define UNWIND_ESPFIX_STACK \
6722 + movl %ss, %eax; \
6723 + /* see if on espfix stack */ \
6724 +@@ -579,7 +637,7 @@ END(syscall_badsys)
6725 + * Build the entry stubs and pointer table with
6726 + * some assembler magic.
6727 + */
6728 +-.section .rodata,"a"
6729 ++.section .rodata,"a",@progbits
6730 + ENTRY(interrupt)
6731 + .text
6732 +
6733 +@@ -679,12 +737,21 @@ error_code:
6734 + popl %ecx
6735 + CFI_ADJUST_CFA_OFFSET -4
6736 + /*CFI_REGISTER es, ecx*/
6737 ++
6738 ++#ifdef CONFIG_PAX_KERNEXEC
6739 ++ GET_CR0_INTO_EDX
6740 ++ movl %edx, %esi
6741 ++ orl $X86_CR0_WP, %edx
6742 ++ xorl %edx, %esi
6743 ++ SET_CR0_FROM_EDX
6744 ++#endif
6745 ++
6746 + movl PT_FS(%esp), %edi # get the function address
6747 + movl PT_ORIG_EAX(%esp), %edx # get the error code
6748 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
6749 + mov %ecx, PT_FS(%esp)
6750 + /*CFI_REL_OFFSET fs, ES*/
6751 +- movl $(__USER_DS), %ecx
6752 ++ movl $(__KERNEL_DS), %ecx
6753 + movl %ecx, %ds
6754 + movl %ecx, %es
6755 + movl %esp,%eax # pt_regs pointer
6756 +@@ -818,6 +885,13 @@ nmi_stack_correct:
6757 + xorl %edx,%edx # zero error code
6758 + movl %esp,%eax # pt_regs pointer
6759 + call do_nmi
6760 ++
6761 ++#ifdef CONFIG_PAX_KERNEXEC
6762 ++ GET_CR0_INTO_EDX
6763 ++ xorl %esi, %edx
6764 ++ SET_CR0_FROM_EDX
6765 ++#endif
6766 ++
6767 + jmp restore_nocheck_notrace
6768 + CFI_ENDPROC
6769 +
6770 +@@ -858,6 +932,13 @@ nmi_espfix_stack:
6771 + FIXUP_ESPFIX_STACK # %eax == %esp
6772 + xorl %edx,%edx # zero error code
6773 + call do_nmi
6774 ++
6775 ++#ifdef CONFIG_PAX_KERNEXEC
6776 ++ GET_CR0_INTO_EDX
6777 ++ xorl %esi, %edx
6778 ++ SET_CR0_FROM_EDX
6779 ++#endif
6780 ++
6781 + RESTORE_REGS
6782 + lss 12+4(%esp), %esp # back to espfix stack
6783 + CFI_ADJUST_CFA_OFFSET -24
6784 +@@ -1110,7 +1191,6 @@ ENDPROC(xen_failsafe_callback)
6785 +
6786 + #endif /* CONFIG_XEN */
6787 +
6788 +-.section .rodata,"a"
6789 + #include "syscall_table_32.S"
6790 +
6791 + syscall_table_size=(.-sys_call_table)
6792 +diff -urNp linux-2.6.26.6/arch/x86/kernel/entry_64.S linux-2.6.26.6/arch/x86/kernel/entry_64.S
6793 +--- linux-2.6.26.6/arch/x86/kernel/entry_64.S 2008-10-08 23:24:05.000000000 -0400
6794 ++++ linux-2.6.26.6/arch/x86/kernel/entry_64.S 2008-10-11 21:54:19.000000000 -0400
6795 +@@ -767,17 +767,18 @@ END(spurious_interrupt)
6796 + xorl %ebx,%ebx
6797 + 1:
6798 + .if \ist
6799 +- movq %gs:pda_data_offset, %rbp
6800 ++ imul $TSS_size, %gs:pda_cpunumber, %ebp
6801 ++ lea init_tss(%rbp), %rbp
6802 + .endif
6803 + movq %rsp,%rdi
6804 + movq ORIG_RAX(%rsp),%rsi
6805 + movq $-1,ORIG_RAX(%rsp)
6806 + .if \ist
6807 +- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
6808 ++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
6809 + .endif
6810 + call \sym
6811 + .if \ist
6812 +- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
6813 ++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
6814 + .endif
6815 + DISABLE_INTERRUPTS(CLBR_NONE)
6816 + .if \irqtrace
6817 +diff -urNp linux-2.6.26.6/arch/x86/kernel/head_32.S linux-2.6.26.6/arch/x86/kernel/head_32.S
6818 +--- linux-2.6.26.6/arch/x86/kernel/head_32.S 2008-10-08 23:24:05.000000000 -0400
6819 ++++ linux-2.6.26.6/arch/x86/kernel/head_32.S 2008-10-11 21:55:07.000000000 -0400
6820 +@@ -19,6 +19,7 @@
6821 + #include <asm/asm-offsets.h>
6822 + #include <asm/setup.h>
6823 + #include <asm/processor-flags.h>
6824 ++#include <asm/msr-index.h>
6825 +
6826 + /* Physical address */
6827 + #define pa(X) ((X) - __PAGE_OFFSET)
6828 +@@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
6829 + LOW_PAGES = LOW_PAGES + 0x1000000
6830 + #endif
6831 +
6832 +-#if PTRS_PER_PMD > 1
6833 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
6834 +-#else
6835 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
6836 +-#endif
6837 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
6838 + BOOTBITMAP_SIZE = LOW_PAGES / 8
6839 + ALLOCATOR_SLOP = 4
6840 +
6841 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
6842 +
6843 + /*
6844 ++ * Real beginning of normal "text" segment
6845 ++ */
6846 ++ENTRY(stext)
6847 ++ENTRY(_stext)
6848 ++
6849 ++.section .text.startup,"ax",@progbits
6850 ++ ljmp $(__BOOT_CS),$phys_startup_32
6851 ++
6852 ++/*
6853 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
6854 + * %esi points to the real-mode code as a 32-bit pointer.
6855 + * CS and DS must be 4 GB flat segments, but we don't depend on
6856 +@@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
6857 + * can.
6858 + */
6859 + .section .text.head,"ax",@progbits
6860 ++
6861 ++#ifdef CONFIG_PAX_KERNEXEC
6862 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
6863 ++.fill 4096,1,0xcc
6864 ++#endif
6865 ++
6866 + ENTRY(startup_32)
6867 + /* test KEEP_SEGMENTS flag to see if the bootloader is asking
6868 + us to not reload segments */
6869 +@@ -99,6 +111,56 @@ ENTRY(startup_32)
6870 + movl %eax,%gs
6871 + 2:
6872 +
6873 ++ movl $pa(cpu_gdt_table),%edi
6874 ++ movl $__per_cpu_start,%eax
6875 ++ movw %ax,__KERNEL_PERCPU + 2(%edi)
6876 ++ rorl $16,%eax
6877 ++ movb %al,__KERNEL_PERCPU + 4(%edi)
6878 ++ movb %ah,__KERNEL_PERCPU + 7(%edi)
6879 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
6880 ++ subl $__per_cpu_start,%eax
6881 ++ movw %ax,__KERNEL_PERCPU + 0(%edi)
6882 ++
6883 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
6884 ++ /* check for VMware */
6885 ++ movl $0x564d5868,%eax
6886 ++ xorl %ebx,%ebx
6887 ++ movl $0xa,%ecx
6888 ++ movl $0x5658,%edx
6889 ++ in (%dx),%eax
6890 ++ cmpl $0x564d5868,%ebx
6891 ++ jz 2f
6892 ++
6893 ++ movl $NR_CPUS,%ecx
6894 ++ movl $pa(cpu_gdt_table),%edi
6895 ++1:
6896 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
6897 ++ addl $PAGE_SIZE_asm,%edi
6898 ++ loop 1b
6899 ++2:
6900 ++#endif
6901 ++
6902 ++#ifdef CONFIG_PAX_KERNEXEC
6903 ++ movl $pa(boot_gdt),%edi
6904 ++ movl $KERNEL_TEXT_OFFSET,%eax
6905 ++ movw %ax,__BOOT_CS + 2(%edi)
6906 ++ rorl $16,%eax
6907 ++ movb %al,__BOOT_CS + 4(%edi)
6908 ++ movb %ah,__BOOT_CS + 7(%edi)
6909 ++ rorl $16,%eax
6910 ++
6911 ++ movl $NR_CPUS,%ecx
6912 ++ movl $pa(cpu_gdt_table),%edi
6913 ++1:
6914 ++ movw %ax,__KERNEL_CS + 2(%edi)
6915 ++ rorl $16,%eax
6916 ++ movb %al,__KERNEL_CS + 4(%edi)
6917 ++ movb %ah,__KERNEL_CS + 7(%edi)
6918 ++ rorl $16,%eax
6919 ++ addl $PAGE_SIZE_asm,%edi
6920 ++ loop 1b
6921 ++#endif
6922 ++
6923 + /*
6924 + * Clear BSS first so that there are no surprises...
6925 + */
6926 +@@ -142,9 +204,7 @@ ENTRY(startup_32)
6927 + cmpl $num_subarch_entries, %eax
6928 + jae bad_subarch
6929 +
6930 +- movl pa(subarch_entries)(,%eax,4), %eax
6931 +- subl $__PAGE_OFFSET, %eax
6932 +- jmp *%eax
6933 ++ jmp *pa(subarch_entries)(,%eax,4)
6934 +
6935 + bad_subarch:
6936 + WEAK(lguest_entry)
6937 +@@ -156,9 +216,9 @@ WEAK(xen_entry)
6938 + __INITDATA
6939 +
6940 + subarch_entries:
6941 +- .long default_entry /* normal x86/PC */
6942 +- .long lguest_entry /* lguest hypervisor */
6943 +- .long xen_entry /* Xen hypervisor */
6944 ++ .long pa(default_entry) /* normal x86/PC */
6945 ++ .long pa(lguest_entry) /* lguest hypervisor */
6946 ++ .long pa(xen_entry) /* Xen hypervisor */
6947 + num_subarch_entries = (. - subarch_entries) / 4
6948 + .previous
6949 + #endif /* CONFIG_PARAVIRT */
6950 +@@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
6951 + *
6952 + * Note that the stack is not yet set up!
6953 + */
6954 +-#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
6955 ++#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
6956 + #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
6957 + #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
6958 +
6959 +@@ -221,8 +281,7 @@ default_entry:
6960 + movl %edi,pa(init_pg_tables_end)
6961 +
6962 + /* Do early initialization of the fixmap area */
6963 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
6964 +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
6965 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
6966 + #else /* Not PAE */
6967 +
6968 + page_pde_offset = (__PAGE_OFFSET >> 20);
6969 +@@ -251,8 +310,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
6970 + movl %edi,pa(init_pg_tables_end)
6971 +
6972 + /* Do early initialization of the fixmap area */
6973 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
6974 +- movl %eax,pa(swapper_pg_dir+0xffc)
6975 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
6976 + #endif
6977 + jmp 3f
6978 + /*
6979 +@@ -316,13 +374,16 @@ ENTRY(startup_32_smp)
6980 + jnc 6f
6981 +
6982 + /* Setup EFER (Extended Feature Enable Register) */
6983 +- movl $0xc0000080, %ecx
6984 ++ movl $MSR_EFER, %ecx
6985 + rdmsr
6986 +
6987 + btsl $11, %eax
6988 + /* Make changes effective */
6989 + wrmsr
6990 +
6991 ++ btsl $63-32,pa(__supported_pte_mask+4)
6992 ++ movl $1,pa(nx_enabled)
6993 ++
6994 + 6:
6995 +
6996 + /*
6997 +@@ -348,9 +409,7 @@ ENTRY(startup_32_smp)
6998 +
6999 + #ifdef CONFIG_SMP
7000 + cmpb $0, ready
7001 +- jz 1f /* Initial CPU cleans BSS */
7002 +- jmp checkCPUtype
7003 +-1:
7004 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
7005 + #endif /* CONFIG_SMP */
7006 +
7007 + /*
7008 +@@ -427,12 +486,12 @@ is386: movl $2,%ecx # set MP
7009 + ljmp $(__KERNEL_CS),$1f
7010 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
7011 + movl %eax,%ss # after changing gdt.
7012 +- movl %eax,%fs # gets reset once there's real percpu
7013 +-
7014 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
7015 + movl %eax,%ds
7016 + movl %eax,%es
7017 +
7018 ++ movl $(__KERNEL_PERCPU), %eax
7019 ++ movl %eax,%fs # set this cpu's percpu
7020 ++
7021 + xorl %eax,%eax # Clear GS and LDT
7022 + movl %eax,%gs
7023 + lldt %ax
7024 +@@ -443,11 +502,7 @@ is386: movl $2,%ecx # set MP
7025 + movb ready, %cl
7026 + movb $1, ready
7027 + cmpb $0,%cl # the first CPU calls start_kernel
7028 +- je 1f
7029 +- movl $(__KERNEL_PERCPU), %eax
7030 +- movl %eax,%fs # set this cpu's percpu
7031 +- jmp initialize_secondary # all other CPUs call initialize_secondary
7032 +-1:
7033 ++ jne initialize_secondary # all other CPUs call initialize_secondary
7034 + #endif /* CONFIG_SMP */
7035 + jmp i386_start_kernel
7036 +
7037 +@@ -533,15 +588,15 @@ early_page_fault:
7038 + jmp early_fault
7039 +
7040 + early_fault:
7041 +- cld
7042 + #ifdef CONFIG_PRINTK
7043 ++ cmpl $2,%ss:early_recursion_flag
7044 ++ je hlt_loop
7045 ++ incl %ss:early_recursion_flag
7046 ++ cld
7047 + pusha
7048 + movl $(__KERNEL_DS),%eax
7049 + movl %eax,%ds
7050 + movl %eax,%es
7051 +- cmpl $2,early_recursion_flag
7052 +- je hlt_loop
7053 +- incl early_recursion_flag
7054 + movl %cr2,%eax
7055 + pushl %eax
7056 + pushl %edx /* trapno */
7057 +@@ -551,8 +606,8 @@ early_fault:
7058 + #else
7059 + call printk
7060 + #endif
7061 +-#endif
7062 + call dump_stack
7063 ++#endif
7064 + hlt_loop:
7065 + hlt
7066 + jmp hlt_loop
7067 +@@ -560,8 +615,11 @@ hlt_loop:
7068 + /* This is the default interrupt "handler" :-) */
7069 + ALIGN
7070 + ignore_int:
7071 +- cld
7072 + #ifdef CONFIG_PRINTK
7073 ++ cmpl $2,%ss:early_recursion_flag
7074 ++ je hlt_loop
7075 ++ incl %ss:early_recursion_flag
7076 ++ cld
7077 + pushl %eax
7078 + pushl %ecx
7079 + pushl %edx
7080 +@@ -570,9 +628,6 @@ ignore_int:
7081 + movl $(__KERNEL_DS),%eax
7082 + movl %eax,%ds
7083 + movl %eax,%es
7084 +- cmpl $2,early_recursion_flag
7085 +- je hlt_loop
7086 +- incl early_recursion_flag
7087 + pushl 16(%esp)
7088 + pushl 24(%esp)
7089 + pushl 32(%esp)
7090 +@@ -592,36 +647,41 @@ ignore_int:
7091 + #endif
7092 + iret
7093 +
7094 +-.section .text
7095 +-/*
7096 +- * Real beginning of normal "text" segment
7097 +- */
7098 +-ENTRY(stext)
7099 +-ENTRY(_stext)
7100 +-
7101 + /*
7102 + * BSS section
7103 + */
7104 +-.section ".bss.page_aligned","wa"
7105 +- .align PAGE_SIZE_asm
7106 + #ifdef CONFIG_X86_PAE
7107 ++.section .swapper_pg_pmd,"a",@progbits
7108 + swapper_pg_pmd:
7109 + .fill 1024*KPMDS,4,0
7110 + #else
7111 ++.section .swapper_pg_dir,"a",@progbits
7112 + ENTRY(swapper_pg_dir)
7113 + .fill 1024,4,0
7114 + #endif
7115 + swapper_pg_fixmap:
7116 + .fill 1024,4,0
7117 ++
7118 ++.section .empty_zero_page,"a",@progbits
7119 + ENTRY(empty_zero_page)
7120 + .fill 4096,1,0
7121 ++
7122 ++/*
7123 ++ * The IDT has to be page-aligned to simplify the Pentium
7124 ++ * F0 0F bug workaround.. We have a special link segment
7125 ++ * for this.
7126 ++ */
7127 ++.section .idt,"a",@progbits
7128 ++ENTRY(idt_table)
7129 ++ .fill 256,8,0
7130 ++
7131 + /*
7132 + * This starts the data section.
7133 + */
7134 ++.data
7135 ++
7136 + #ifdef CONFIG_X86_PAE
7137 +-.section ".data.page_aligned","wa"
7138 +- /* Page-aligned for the benefit of paravirt? */
7139 +- .align PAGE_SIZE_asm
7140 ++.section .swapper_pg_dir,"a",@progbits
7141 + ENTRY(swapper_pg_dir)
7142 + .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
7143 + # if KPMDS == 3
7144 +@@ -644,11 +704,12 @@ ENTRY(swapper_pg_dir)
7145 +
7146 + .data
7147 + ENTRY(stack_start)
7148 +- .long init_thread_union+THREAD_SIZE
7149 ++ .long init_thread_union+THREAD_SIZE-8
7150 + .long __BOOT_DS
7151 +
7152 + ready: .byte 0
7153 +
7154 ++.section .rodata,"a",@progbits
7155 + early_recursion_flag:
7156 + .long 0
7157 +
7158 +@@ -684,7 +745,7 @@ fault_msg:
7159 + .word 0 # 32 bit align gdt_desc.address
7160 + boot_gdt_descr:
7161 + .word __BOOT_DS+7
7162 +- .long boot_gdt - __PAGE_OFFSET
7163 ++ .long pa(boot_gdt)
7164 +
7165 + .word 0 # 32-bit align idt_desc.address
7166 + idt_descr:
7167 +@@ -695,7 +756,7 @@ idt_descr:
7168 + .word 0 # 32 bit align gdt_desc.address
7169 + ENTRY(early_gdt_descr)
7170 + .word GDT_ENTRIES*8-1
7171 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
7172 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
7173 +
7174 + /*
7175 + * The boot_gdt must mirror the equivalent in setup.S and is
7176 +@@ -704,5 +765,59 @@ ENTRY(early_gdt_descr)
7177 + .align L1_CACHE_BYTES
7178 + ENTRY(boot_gdt)
7179 + .fill GDT_ENTRY_BOOT_CS,8,0
7180 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
7181 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
7182 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
7183 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
7184 ++
7185 ++ .align PAGE_SIZE_asm
7186 ++ENTRY(cpu_gdt_table)
7187 ++ .rept NR_CPUS
7188 ++ .quad 0x0000000000000000 /* NULL descriptor */
7189 ++ .quad 0x0000000000000000 /* 0x0b reserved */
7190 ++ .quad 0x0000000000000000 /* 0x13 reserved */
7191 ++ .quad 0x0000000000000000 /* 0x1b reserved */
7192 ++ .quad 0x0000000000000000 /* 0x20 unused */
7193 ++ .quad 0x0000000000000000 /* 0x28 unused */
7194 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
7195 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
7196 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
7197 ++ .quad 0x0000000000000000 /* 0x4b reserved */
7198 ++ .quad 0x0000000000000000 /* 0x53 reserved */
7199 ++ .quad 0x0000000000000000 /* 0x5b reserved */
7200 ++
7201 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
7202 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
7203 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
7204 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
7205 ++
7206 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
7207 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
7208 ++
7209 ++ /*
7210 ++ * Segments used for calling PnP BIOS have byte granularity.
7211 ++ * The code segments and data segments have fixed 64k limits,
7212 ++ * the transfer segment sizes are set at run time.
7213 ++ */
7214 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
7215 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
7216 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
7217 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
7218 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
7219 ++
7220 ++ /*
7221 ++ * The APM segments have byte granularity and their bases
7222 ++ * are set at run time. All have 64k limits.
7223 ++ */
7224 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
7225 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
7226 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
7227 ++
7228 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
7229 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
7230 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
7231 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
7232 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
7233 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
7234 ++
7235 ++ /* Be sure this is zeroed to avoid false validations in Xen */
7236 ++ .fill PAGE_SIZE_asm - GDT_SIZE,1,0
7237 ++ .endr
7238 +diff -urNp linux-2.6.26.6/arch/x86/kernel/head64.c linux-2.6.26.6/arch/x86/kernel/head64.c
7239 +--- linux-2.6.26.6/arch/x86/kernel/head64.c 2008-10-08 23:24:05.000000000 -0400
7240 ++++ linux-2.6.26.6/arch/x86/kernel/head64.c 2008-10-11 21:54:19.000000000 -0400
7241 +@@ -143,6 +143,11 @@ void __init x86_64_start_kernel(char * r
7242 + /* Make NULL pointers segfault */
7243 + zap_identity_mappings();
7244 +
7245 ++ for (i = 0; i < NR_CPUS; i++)
7246 ++ cpu_pda(i) = &boot_cpu_pda[i];
7247 ++
7248 ++ pda_init(0);
7249 ++
7250 + /* Cleanup the over mapped high alias */
7251 + cleanup_highmap();
7252 +
7253 +@@ -157,10 +162,6 @@ void __init x86_64_start_kernel(char * r
7254 +
7255 + early_printk("Kernel alive\n");
7256 +
7257 +- for (i = 0; i < NR_CPUS; i++)
7258 +- cpu_pda(i) = &boot_cpu_pda[i];
7259 +-
7260 +- pda_init(0);
7261 + copy_bootdata(__va(real_mode_data));
7262 +
7263 + reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
7264 +diff -urNp linux-2.6.26.6/arch/x86/kernel/head_64.S linux-2.6.26.6/arch/x86/kernel/head_64.S
7265 +--- linux-2.6.26.6/arch/x86/kernel/head_64.S 2008-10-08 23:24:05.000000000 -0400
7266 ++++ linux-2.6.26.6/arch/x86/kernel/head_64.S 2008-10-11 22:15:25.000000000 -0400
7267 +@@ -77,6 +77,8 @@ startup_64:
7268 + */
7269 + addq %rbp, init_level4_pgt + 0(%rip)
7270 + addq %rbp, init_level4_pgt + (258*8)(%rip)
7271 ++ addq %rbp, init_level4_pgt + (388*8)(%rip)
7272 ++ addq %rbp, init_level4_pgt + (452*8)(%rip)
7273 + addq %rbp, init_level4_pgt + (511*8)(%rip)
7274 +
7275 + addq %rbp, level3_ident_pgt + 0(%rip)
7276 +@@ -181,6 +183,10 @@ ENTRY(secondary_startup_64)
7277 + btl $20,%edi /* No Execute supported? */
7278 + jnc 1f
7279 + btsl $_EFER_NX, %eax
7280 ++ leaq init_level4_pgt(%rip), %rdi
7281 ++ btsq $_PAGE_BIT_NX, 8*258(%rdi)
7282 ++ btsq $_PAGE_BIT_NX, 8*388(%rdi)
7283 ++ btsq $_PAGE_BIT_NX, 8*452(%rdi)
7284 + 1: wrmsr /* Make changes effective */
7285 +
7286 + /* Setup cr0 */
7287 +@@ -255,15 +261,15 @@ ENTRY(secondary_startup_64)
7288 + .align 8
7289 + ENTRY(initial_code)
7290 + .quad x86_64_start_kernel
7291 +- __FINITDATA
7292 +
7293 + ENTRY(init_rsp)
7294 + .quad init_thread_union+THREAD_SIZE-8
7295 ++ __FINITDATA
7296 +
7297 + bad_address:
7298 + jmp bad_address
7299 +
7300 +- .section ".init.text","ax"
7301 ++ __INIT
7302 + #ifdef CONFIG_EARLY_PRINTK
7303 + .globl early_idt_handlers
7304 + early_idt_handlers:
7305 +@@ -308,18 +314,23 @@ ENTRY(early_idt_handler)
7306 + #endif /* EARLY_PRINTK */
7307 + 1: hlt
7308 + jmp 1b
7309 ++ .previous
7310 +
7311 + #ifdef CONFIG_EARLY_PRINTK
7312 ++ __INITDATA
7313 + early_recursion_flag:
7314 + .long 0
7315 ++ .previous
7316 +
7317 ++ .section .rodata,"a",@progbits
7318 + early_idt_msg:
7319 + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
7320 + early_idt_ripmsg:
7321 + .asciz "RIP %s\n"
7322 +-#endif /* CONFIG_EARLY_PRINTK */
7323 + .previous
7324 ++#endif /* CONFIG_EARLY_PRINTK */
7325 +
7326 ++ .section .rodata,"a",@progbits
7327 + .balign PAGE_SIZE
7328 +
7329 + #define NEXT_PAGE(name) \
7330 +@@ -344,7 +355,11 @@ NEXT_PAGE(init_level4_pgt)
7331 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
7332 + .fill 257,8,0
7333 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
7334 +- .fill 252,8,0
7335 ++ .fill 129,8,0
7336 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
7337 ++ .fill 63,8,0
7338 ++ .quad level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
7339 ++ .fill 58,8,0
7340 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
7341 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
7342 +
7343 +@@ -352,6 +367,12 @@ NEXT_PAGE(level3_ident_pgt)
7344 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
7345 + .fill 511,8,0
7346 +
7347 ++NEXT_PAGE(level3_vmalloc_pgt)
7348 ++ .fill 512,8,0
7349 ++
7350 ++NEXT_PAGE(level3_vmemmap_pgt)
7351 ++ .fill 512,8,0
7352 ++
7353 + NEXT_PAGE(level3_kernel_pgt)
7354 + .fill 510,8,0
7355 + /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
7356 +@@ -393,36 +414,18 @@ NEXT_PAGE(level2_spare_pgt)
7357 + #undef PMDS
7358 + #undef NEXT_PAGE
7359 +
7360 +- .data
7361 +- .align 16
7362 +- .globl cpu_gdt_descr
7363 +-cpu_gdt_descr:
7364 +- .word gdt_end-cpu_gdt_table-1
7365 +-gdt:
7366 +- .quad cpu_gdt_table
7367 +-#ifdef CONFIG_SMP
7368 +- .rept NR_CPUS-1
7369 +- .word 0
7370 +- .quad 0
7371 +- .endr
7372 +-#endif
7373 +-
7374 +-ENTRY(phys_base)
7375 +- /* This must match the first entry in level2_kernel_pgt */
7376 +- .quad 0x0000000000000000
7377 +-
7378 + /* We need valid kernel segments for data and code in long mode too
7379 + * IRET will check the segment types kkeil 2000/10/28
7380 + * Also sysret mandates a special GDT layout
7381 + */
7382 +-
7383 +- .section .data.page_aligned, "aw"
7384 ++
7385 + .align PAGE_SIZE
7386 +
7387 + /* The TLS descriptors are currently at a different place compared to i386.
7388 + Hopefully nobody expects them at a fixed place (Wine?) */
7389 +
7390 + ENTRY(cpu_gdt_table)
7391 ++ .rept NR_CPUS
7392 + .quad 0x0000000000000000 /* NULL descriptor */
7393 + .quad 0x00cf9b000000ffff /* __KERNEL32_CS */
7394 + .quad 0x00af9b000000ffff /* __KERNEL_CS */
7395 +@@ -435,15 +438,24 @@ ENTRY(cpu_gdt_table)
7396 + .quad 0,0 /* LDT */
7397 + .quad 0,0,0 /* three TLS descriptors */
7398 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
7399 +-gdt_end:
7400 + /* asm/segment.h:GDT_ENTRIES must match this */
7401 + /* This should be a multiple of the cache line size */
7402 +- /* GDTs of other CPUs are now dynamically allocated */
7403 +
7404 + /* zero the remaining page */
7405 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
7406 ++ .endr
7407 ++
7408 ++ .align 16
7409 ++ .globl cpu_gdt_descr
7410 ++cpu_gdt_descr:
7411 ++ .word GDT_SIZE-1
7412 ++gdt:
7413 ++ .quad cpu_gdt_table
7414 ++
7415 ++ENTRY(phys_base)
7416 ++ /* This must match the first entry in level2_kernel_pgt */
7417 ++ .quad 0x0000000000000000
7418 +
7419 +- .section .bss, "aw", @nobits
7420 + .align L1_CACHE_BYTES
7421 + ENTRY(idt_table)
7422 + .skip 256 * 16
7423 +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
7424 +--- linux-2.6.26.6/arch/x86/kernel/i386_ksyms_32.c 2008-10-08 23:24:05.000000000 -0400
7425 ++++ linux-2.6.26.6/arch/x86/kernel/i386_ksyms_32.c 2008-10-11 21:54:19.000000000 -0400
7426 +@@ -3,8 +3,12 @@
7427 + #include <asm/desc.h>
7428 + #include <asm/pgtable.h>
7429 +
7430 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
7431 ++
7432 + /* Networking helper routines. */
7433 + EXPORT_SYMBOL(csum_partial_copy_generic);
7434 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
7435 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
7436 +
7437 + EXPORT_SYMBOL(__get_user_1);
7438 + EXPORT_SYMBOL(__get_user_2);
7439 +@@ -19,3 +23,7 @@ EXPORT_SYMBOL(strstr);
7440 +
7441 + EXPORT_SYMBOL(csum_partial);
7442 + EXPORT_SYMBOL(empty_zero_page);
7443 ++
7444 ++#ifdef CONFIG_PAX_KERNEXEC
7445 ++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
7446 ++#endif
7447 +diff -urNp linux-2.6.26.6/arch/x86/kernel/init_task.c linux-2.6.26.6/arch/x86/kernel/init_task.c
7448 +--- linux-2.6.26.6/arch/x86/kernel/init_task.c 2008-10-08 23:24:05.000000000 -0400
7449 ++++ linux-2.6.26.6/arch/x86/kernel/init_task.c 2008-10-11 21:54:19.000000000 -0400
7450 +@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
7451 + * section. Since TSS's are completely CPU-local, we want them
7452 + * on exact cacheline boundaries, to eliminate cacheline ping-pong.
7453 + */
7454 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
7455 +-
7456 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
7457 ++EXPORT_SYMBOL(init_tss);
7458 +diff -urNp linux-2.6.26.6/arch/x86/kernel/ioport.c linux-2.6.26.6/arch/x86/kernel/ioport.c
7459 +--- linux-2.6.26.6/arch/x86/kernel/ioport.c 2008-10-08 23:24:05.000000000 -0400
7460 ++++ linux-2.6.26.6/arch/x86/kernel/ioport.c 2008-10-11 21:54:19.000000000 -0400
7461 +@@ -14,6 +14,7 @@
7462 + #include <linux/slab.h>
7463 + #include <linux/thread_info.h>
7464 + #include <linux/syscalls.h>
7465 ++#include <linux/grsecurity.h>
7466 +
7467 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
7468 + static void set_bitmap(unsigned long *bitmap, unsigned int base,
7469 +@@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
7470 +
7471 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
7472 + return -EINVAL;
7473 ++#ifdef CONFIG_GRKERNSEC_IO
7474 ++ if (turn_on) {
7475 ++ gr_handle_ioperm();
7476 ++ return -EPERM;
7477 ++ }
7478 ++#endif
7479 + if (turn_on && !capable(CAP_SYS_RAWIO))
7480 + return -EPERM;
7481 +
7482 +@@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
7483 + * because the ->io_bitmap_max value must match the bitmap
7484 + * contents:
7485 + */
7486 +- tss = &per_cpu(init_tss, get_cpu());
7487 ++ tss = init_tss + get_cpu();
7488 +
7489 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
7490 +
7491 +@@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
7492 + return -EINVAL;
7493 + /* Trying to gain more privileges? */
7494 + if (level > old) {
7495 ++#ifdef CONFIG_GRKERNSEC_IO
7496 ++ gr_handle_iopl();
7497 ++ return -EPERM;
7498 ++#else
7499 + if (!capable(CAP_SYS_RAWIO))
7500 + return -EPERM;
7501 ++#endif
7502 + }
7503 + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
7504 +
7505 +diff -urNp linux-2.6.26.6/arch/x86/kernel/irq_32.c linux-2.6.26.6/arch/x86/kernel/irq_32.c
7506 +--- linux-2.6.26.6/arch/x86/kernel/irq_32.c 2008-10-08 23:24:05.000000000 -0400
7507 ++++ linux-2.6.26.6/arch/x86/kernel/irq_32.c 2008-10-11 21:54:19.000000000 -0400
7508 +@@ -115,7 +115,7 @@ unsigned int do_IRQ(struct pt_regs *regs
7509 + int arg1, arg2, bx;
7510 +
7511 + /* build the stack frame on the IRQ stack */
7512 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
7513 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
7514 + irqctx->tinfo.task = curctx->tinfo.task;
7515 + irqctx->tinfo.previous_esp = current_stack_pointer;
7516 +
7517 +@@ -209,7 +209,7 @@ asmlinkage void do_softirq(void)
7518 + irqctx->tinfo.previous_esp = current_stack_pointer;
7519 +
7520 + /* build the stack frame on the softirq stack */
7521 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
7522 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
7523 +
7524 + asm volatile(
7525 + " xchgl %%ebx,%%esp \n"
7526 +diff -urNp linux-2.6.26.6/arch/x86/kernel/kprobes.c linux-2.6.26.6/arch/x86/kernel/kprobes.c
7527 +--- linux-2.6.26.6/arch/x86/kernel/kprobes.c 2008-10-08 23:24:05.000000000 -0400
7528 ++++ linux-2.6.26.6/arch/x86/kernel/kprobes.c 2008-10-11 21:54:19.000000000 -0400
7529 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
7530 + char op;
7531 + s32 raddr;
7532 + } __attribute__((packed)) * jop;
7533 +- jop = (struct __arch_jmp_op *)from;
7534 ++
7535 ++#ifdef CONFIG_PAX_KERNEXEC
7536 ++ unsigned long cr0;
7537 ++#endif
7538 ++
7539 ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
7540 ++
7541 ++#ifdef CONFIG_PAX_KERNEXEC
7542 ++ pax_open_kernel(cr0);
7543 ++#endif
7544 ++
7545 + jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
7546 + jop->op = RELATIVEJUMP_INSTRUCTION;
7547 ++
7548 ++#ifdef CONFIG_PAX_KERNEXEC
7549 ++ pax_close_kernel(cr0);
7550 ++#endif
7551 ++
7552 + }
7553 +
7554 + /*
7555 +@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
7556 +
7557 + static void __kprobes arch_copy_kprobe(struct kprobe *p)
7558 + {
7559 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
7560 ++
7561 ++#ifdef CONFIG_PAX_KERNEXEC
7562 ++ unsigned long cr0;
7563 ++#endif
7564 ++
7565 ++#ifdef CONFIG_PAX_KERNEXEC
7566 ++ pax_open_kernel(cr0);
7567 ++#endif
7568 ++
7569 ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
7570 ++
7571 ++#ifdef CONFIG_PAX_KERNEXEC
7572 ++ pax_close_kernel(cr0);
7573 ++#endif
7574 +
7575 + fix_riprel(p);
7576 +
7577 +- if (can_boost(p->addr))
7578 ++ if (can_boost(ktla_ktva(p->addr)))
7579 + p->ainsn.boostable = 0;
7580 + else
7581 + p->ainsn.boostable = -1;
7582 +
7583 +- p->opcode = *p->addr;
7584 ++ p->opcode = *(ktla_ktva(p->addr));
7585 + }
7586 +
7587 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
7588 +@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
7589 + if (p->opcode == BREAKPOINT_INSTRUCTION)
7590 + regs->ip = (unsigned long)p->addr;
7591 + else
7592 +- regs->ip = (unsigned long)p->ainsn.insn;
7593 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
7594 + }
7595 +
7596 + /* Called with kretprobe_lock held */
7597 +@@ -450,7 +478,7 @@ static void __kprobes setup_singlestep(s
7598 + if (p->ainsn.boostable == 1 && !p->post_handler) {
7599 + /* Boost up -- we can execute copied instructions directly */
7600 + reset_current_kprobe();
7601 +- regs->ip = (unsigned long)p->ainsn.insn;
7602 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
7603 + preempt_enable_no_resched();
7604 + return;
7605 + }
7606 +@@ -772,7 +800,7 @@ static void __kprobes resume_execution(s
7607 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
7608 + {
7609 + unsigned long *tos = stack_addr(regs);
7610 +- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
7611 ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
7612 + unsigned long orig_ip = (unsigned long)p->addr;
7613 + kprobe_opcode_t *insn = p->ainsn.insn;
7614 +
7615 +@@ -955,7 +983,7 @@ int __kprobes kprobe_exceptions_notify(s
7616 + struct die_args *args = data;
7617 + int ret = NOTIFY_DONE;
7618 +
7619 +- if (args->regs && user_mode_vm(args->regs))
7620 ++ if (args->regs && user_mode(args->regs))
7621 + return ret;
7622 +
7623 + switch (val) {
7624 +diff -urNp linux-2.6.26.6/arch/x86/kernel/ldt.c linux-2.6.26.6/arch/x86/kernel/ldt.c
7625 +--- linux-2.6.26.6/arch/x86/kernel/ldt.c 2008-10-08 23:24:05.000000000 -0400
7626 ++++ linux-2.6.26.6/arch/x86/kernel/ldt.c 2008-10-11 21:54:19.000000000 -0400
7627 +@@ -65,7 +65,7 @@ static int alloc_ldt(mm_context_t *pc, i
7628 + cpumask_t mask;
7629 +
7630 + preempt_disable();
7631 +- load_LDT(pc);
7632 ++ load_LDT_nolock(pc);
7633 + mask = cpumask_of_cpu(smp_processor_id());
7634 + if (!cpus_equal(current->mm->cpu_vm_mask, mask))
7635 + smp_call_function(flush_ldt, NULL, 1, 1);
7636 +@@ -110,6 +110,24 @@ int init_new_context(struct task_struct
7637 + retval = copy_ldt(&mm->context, &old_mm->context);
7638 + mutex_unlock(&old_mm->context.lock);
7639 + }
7640 ++
7641 ++ if (tsk == current) {
7642 ++ mm->context.vdso = ~0UL;
7643 ++
7644 ++#ifdef CONFIG_X86_32
7645 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7646 ++ mm->context.user_cs_base = 0UL;
7647 ++ mm->context.user_cs_limit = ~0UL;
7648 ++
7649 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
7650 ++ cpus_clear(mm->context.cpu_user_cs_mask);
7651 ++#endif
7652 ++
7653 ++#endif
7654 ++#endif
7655 ++
7656 ++ }
7657 ++
7658 + return retval;
7659 + }
7660 +
7661 +@@ -223,6 +241,13 @@ static int write_ldt(void __user *ptr, u
7662 + }
7663 + }
7664 +
7665 ++#ifdef CONFIG_PAX_SEGMEXEC
7666 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
7667 ++ error = -EINVAL;
7668 ++ goto out_unlock;
7669 ++ }
7670 ++#endif
7671 ++
7672 + fill_ldt(&ldt, &ldt_info);
7673 + if (oldmode)
7674 + ldt.avl = 0;
7675 +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
7676 +--- linux-2.6.26.6/arch/x86/kernel/machine_kexec_32.c 2008-10-08 23:24:05.000000000 -0400
7677 ++++ linux-2.6.26.6/arch/x86/kernel/machine_kexec_32.c 2008-10-11 21:55:52.000000000 -0400
7678 +@@ -30,7 +30,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
7679 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
7680 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
7681 +
7682 +-static void set_idt(void *newidt, __u16 limit)
7683 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
7684 + {
7685 + struct desc_ptr curidt;
7686 +
7687 +@@ -42,7 +42,7 @@ static void set_idt(void *newidt, __u16
7688 + };
7689 +
7690 +
7691 +-static void set_gdt(void *newgdt, __u16 limit)
7692 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
7693 + {
7694 + struct desc_ptr curgdt;
7695 +
7696 +@@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
7697 + local_irq_disable();
7698 +
7699 + control_page = page_address(image->control_code_page);
7700 +- memcpy(control_page, relocate_kernel, PAGE_SIZE);
7701 ++ memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), PAGE_SIZE);
7702 +
7703 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
7704 +- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
7705 ++ page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
7706 + page_list[PA_PGD] = __pa(kexec_pgd);
7707 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
7708 + #ifdef CONFIG_X86_PAE
7709 +diff -urNp linux-2.6.26.6/arch/x86/kernel/module_32.c linux-2.6.26.6/arch/x86/kernel/module_32.c
7710 +--- linux-2.6.26.6/arch/x86/kernel/module_32.c 2008-10-08 23:24:05.000000000 -0400
7711 ++++ linux-2.6.26.6/arch/x86/kernel/module_32.c 2008-10-11 21:54:19.000000000 -0400
7712 +@@ -23,6 +23,9 @@
7713 + #include <linux/kernel.h>
7714 + #include <linux/bug.h>
7715 +
7716 ++#include <asm/desc.h>
7717 ++#include <asm/pgtable.h>
7718 ++
7719 + #if 0
7720 + #define DEBUGP printk
7721 + #else
7722 +@@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
7723 + {
7724 + if (size == 0)
7725 + return NULL;
7726 ++
7727 ++#ifdef CONFIG_PAX_KERNEXEC
7728 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
7729 ++#else
7730 + return vmalloc_exec(size);
7731 ++#endif
7732 ++
7733 + }
7734 +
7735 ++#ifdef CONFIG_PAX_KERNEXEC
7736 ++void *module_alloc_exec(unsigned long size)
7737 ++{
7738 ++ struct vm_struct *area;
7739 ++
7740 ++ if (size == 0)
7741 ++ return NULL;
7742 ++
7743 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
7744 ++ if (area)
7745 ++ return area->addr;
7746 ++
7747 ++ return NULL;
7748 ++}
7749 ++EXPORT_SYMBOL(module_alloc_exec);
7750 ++#endif
7751 +
7752 + /* Free memory returned from module_alloc */
7753 + void module_free(struct module *mod, void *module_region)
7754 +@@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
7755 + table entries. */
7756 + }
7757 +
7758 ++#ifdef CONFIG_PAX_KERNEXEC
7759 ++void module_free_exec(struct module *mod, void *module_region)
7760 ++{
7761 ++ struct vm_struct **p, *tmp;
7762 ++
7763 ++ if (!module_region)
7764 ++ return;
7765 ++
7766 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
7767 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
7768 ++ WARN_ON(1);
7769 ++ return;
7770 ++ }
7771 ++
7772 ++ write_lock(&vmlist_lock);
7773 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
7774 ++ if (tmp->addr == module_region)
7775 ++ break;
7776 ++
7777 ++ if (tmp) {
7778 ++ unsigned long cr0;
7779 ++
7780 ++ pax_open_kernel(cr0);
7781 ++ memset(tmp->addr, 0xCC, tmp->size);
7782 ++ pax_close_kernel(cr0);
7783 ++
7784 ++ *p = tmp->next;
7785 ++ kfree(tmp);
7786 ++ }
7787 ++ write_unlock(&vmlist_lock);
7788 ++
7789 ++ if (!tmp) {
7790 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
7791 ++ module_region);
7792 ++ WARN_ON(1);
7793 ++ }
7794 ++}
7795 ++#endif
7796 ++
7797 + /* We don't need anything special. */
7798 + int module_frob_arch_sections(Elf_Ehdr *hdr,
7799 + Elf_Shdr *sechdrs,
7800 +@@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
7801 + unsigned int i;
7802 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
7803 + Elf32_Sym *sym;
7804 +- uint32_t *location;
7805 ++ uint32_t *plocation, location;
7806 ++
7807 ++#ifdef CONFIG_PAX_KERNEXEC
7808 ++ unsigned long cr0;
7809 ++#endif
7810 +
7811 + DEBUGP("Applying relocate section %u to %u\n", relsec,
7812 + sechdrs[relsec].sh_info);
7813 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
7814 + /* This is where to make the change */
7815 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
7816 +- + rel[i].r_offset;
7817 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
7818 ++ location = (uint32_t)plocation;
7819 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
7820 ++ plocation = ktla_ktva((void *)plocation);
7821 + /* This is the symbol it is referring to. Note that all
7822 + undefined symbols have been resolved. */
7823 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
7824 +@@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
7825 +
7826 + switch (ELF32_R_TYPE(rel[i].r_info)) {
7827 + case R_386_32:
7828 ++
7829 ++#ifdef CONFIG_PAX_KERNEXEC
7830 ++ pax_open_kernel(cr0);
7831 ++#endif
7832 ++
7833 + /* We add the value into the location given */
7834 +- *location += sym->st_value;
7835 ++ *plocation += sym->st_value;
7836 ++
7837 ++#ifdef CONFIG_PAX_KERNEXEC
7838 ++ pax_close_kernel(cr0);
7839 ++#endif
7840 ++
7841 + break;
7842 + case R_386_PC32:
7843 ++
7844 ++#ifdef CONFIG_PAX_KERNEXEC
7845 ++ pax_open_kernel(cr0);
7846 ++#endif
7847 ++
7848 + /* Add the value, subtract its postition */
7849 +- *location += sym->st_value - (uint32_t)location;
7850 ++ *plocation += sym->st_value - location;
7851 ++
7852 ++#ifdef CONFIG_PAX_KERNEXEC
7853 ++ pax_close_kernel(cr0);
7854 ++#endif
7855 ++
7856 + break;
7857 + default:
7858 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
7859 +diff -urNp linux-2.6.26.6/arch/x86/kernel/module_64.c linux-2.6.26.6/arch/x86/kernel/module_64.c
7860 +--- linux-2.6.26.6/arch/x86/kernel/module_64.c 2008-10-08 23:24:05.000000000 -0400
7861 ++++ linux-2.6.26.6/arch/x86/kernel/module_64.c 2008-10-11 21:54:19.000000000 -0400
7862 +@@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
7863 + table entries. */
7864 + }
7865 +
7866 +-void *module_alloc(unsigned long size)
7867 ++static void *__module_alloc(unsigned long size, pgprot_t prot)
7868 + {
7869 + struct vm_struct *area;
7870 +
7871 +@@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
7872 + if (!area)
7873 + return NULL;
7874 +
7875 +- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
7876 ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
7877 ++}
7878 ++
7879 ++#ifdef CONFIG_PAX_KERNEXEC
7880 ++void *module_alloc(unsigned long size)
7881 ++{
7882 ++ return __module_alloc(size, PAGE_KERNEL);
7883 ++}
7884 ++
7885 ++void module_free_exec(struct module *mod, void *module_region)
7886 ++{
7887 ++ module_free(mod, module_region);
7888 ++}
7889 ++
7890 ++void *module_alloc_exec(unsigned long size)
7891 ++{
7892 ++ return __module_alloc(size, PAGE_KERNEL_RX);
7893 + }
7894 ++#else
7895 ++void *module_alloc(unsigned long size)
7896 ++{
7897 ++ return __module_alloc(size, PAGE_KERNEL_EXEC);
7898 ++}
7899 ++#endif
7900 ++
7901 + #endif
7902 +
7903 + /* We don't need anything special. */
7904 +@@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
7905 + Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
7906 + Elf64_Sym *sym;
7907 + void *loc;
7908 +- u64 val;
7909 ++ u64 val;
7910 ++
7911 ++#ifdef CONFIG_PAX_KERNEXEC
7912 ++ unsigned long cr0;
7913 ++#endif
7914 +
7915 + DEBUGP("Applying relocate section %u to %u\n", relsec,
7916 + sechdrs[relsec].sh_info);
7917 +@@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
7918 + case R_X86_64_NONE:
7919 + break;
7920 + case R_X86_64_64:
7921 ++
7922 ++#ifdef CONFIG_PAX_KERNEXEC
7923 ++ pax_open_kernel(cr0);
7924 ++#endif
7925 ++
7926 + *(u64 *)loc = val;
7927 ++
7928 ++#ifdef CONFIG_PAX_KERNEXEC
7929 ++ pax_close_kernel(cr0);
7930 ++#endif
7931 ++
7932 + break;
7933 + case R_X86_64_32:
7934 ++
7935 ++#ifdef CONFIG_PAX_KERNEXEC
7936 ++ pax_open_kernel(cr0);
7937 ++#endif
7938 ++
7939 + *(u32 *)loc = val;
7940 ++
7941 ++#ifdef CONFIG_PAX_KERNEXEC
7942 ++ pax_close_kernel(cr0);
7943 ++#endif
7944 ++
7945 + if (val != *(u32 *)loc)
7946 + goto overflow;
7947 + break;
7948 + case R_X86_64_32S:
7949 ++
7950 ++#ifdef CONFIG_PAX_KERNEXEC
7951 ++ pax_open_kernel(cr0);
7952 ++#endif
7953 ++
7954 + *(s32 *)loc = val;
7955 ++
7956 ++#ifdef CONFIG_PAX_KERNEXEC
7957 ++ pax_close_kernel(cr0);
7958 ++#endif
7959 ++
7960 + if ((s64)val != *(s32 *)loc)
7961 + goto overflow;
7962 + break;
7963 + case R_X86_64_PC32:
7964 + val -= (u64)loc;
7965 ++
7966 ++#ifdef CONFIG_PAX_KERNEXEC
7967 ++ pax_open_kernel(cr0);
7968 ++#endif
7969 ++
7970 + *(u32 *)loc = val;
7971 ++
7972 ++#ifdef CONFIG_PAX_KERNEXEC
7973 ++ pax_close_kernel(cr0);
7974 ++#endif
7975 ++
7976 + #if 0
7977 + if ((s64)val != *(s32 *)loc)
7978 + goto overflow;
7979 +diff -urNp linux-2.6.26.6/arch/x86/kernel/mpparse.c linux-2.6.26.6/arch/x86/kernel/mpparse.c
7980 +--- linux-2.6.26.6/arch/x86/kernel/mpparse.c 2008-10-08 23:24:05.000000000 -0400
7981 ++++ linux-2.6.26.6/arch/x86/kernel/mpparse.c 2008-10-11 21:54:19.000000000 -0400
7982 +@@ -313,14 +313,14 @@ static int __init smp_read_mpc(struct mp
7983 +
7984 + memcpy(str, mpc->mpc_productid, 12);
7985 + str[12] = 0;
7986 +- printk("Product ID: %s ", str);
7987 ++ printk(KERN_CONT "Product ID: %s ", str);
7988 +
7989 + #ifdef CONFIG_X86_32
7990 + mps_oem_check(mpc, oem, str);
7991 + #endif
7992 +- printk(KERN_INFO "MPTABLE: Product ID: %s ", str);
7993 ++ printk(KERN_CONT "MPTABLE: Product ID: %s ", str);
7994 +
7995 +- printk(KERN_INFO "MPTABLE: APIC at: 0x%X\n", mpc->mpc_lapic);
7996 ++ printk(KERN_CONT "MPTABLE: APIC at: 0x%X\n", mpc->mpc_lapic);
7997 +
7998 + /* save the local APIC address, it might be non-default */
7999 + if (!acpi_lapic)
8000 +diff -urNp linux-2.6.26.6/arch/x86/kernel/paravirt.c linux-2.6.26.6/arch/x86/kernel/paravirt.c
8001 +--- linux-2.6.26.6/arch/x86/kernel/paravirt.c 2008-10-08 23:24:05.000000000 -0400
8002 ++++ linux-2.6.26.6/arch/x86/kernel/paravirt.c 2008-10-11 21:54:19.000000000 -0400
8003 +@@ -42,7 +42,7 @@ void _paravirt_nop(void)
8004 + {
8005 + }
8006 +
8007 +-static void __init default_banner(void)
8008 ++static void default_banner(void)
8009 + {
8010 + printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
8011 + pv_info.name);
8012 +@@ -159,7 +159,7 @@ unsigned paravirt_patch_insns(void *insn
8013 + if (insn_len > len || start == NULL)
8014 + insn_len = len;
8015 + else
8016 +- memcpy(insnbuf, start, insn_len);
8017 ++ memcpy(insnbuf, ktla_ktva(start), insn_len);
8018 +
8019 + return insn_len;
8020 + }
8021 +@@ -261,21 +261,21 @@ enum paravirt_lazy_mode paravirt_get_laz
8022 + return __get_cpu_var(paravirt_lazy_mode);
8023 + }
8024 +
8025 +-struct pv_info pv_info = {
8026 ++struct pv_info pv_info __read_only = {
8027 + .name = "bare hardware",
8028 + .paravirt_enabled = 0,
8029 + .kernel_rpl = 0,
8030 + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
8031 + };
8032 +
8033 +-struct pv_init_ops pv_init_ops = {
8034 ++struct pv_init_ops pv_init_ops __read_only = {
8035 + .patch = native_patch,
8036 + .banner = default_banner,
8037 + .arch_setup = paravirt_nop,
8038 + .memory_setup = machine_specific_memory_setup,
8039 + };
8040 +
8041 +-struct pv_time_ops pv_time_ops = {
8042 ++struct pv_time_ops pv_time_ops __read_only = {
8043 + .time_init = hpet_time_init,
8044 + .get_wallclock = native_get_wallclock,
8045 + .set_wallclock = native_set_wallclock,
8046 +@@ -283,7 +283,7 @@ struct pv_time_ops pv_time_ops = {
8047 + .get_cpu_khz = native_calculate_cpu_khz,
8048 + };
8049 +
8050 +-struct pv_irq_ops pv_irq_ops = {
8051 ++struct pv_irq_ops pv_irq_ops __read_only = {
8052 + .init_IRQ = native_init_IRQ,
8053 + .save_fl = native_save_fl,
8054 + .restore_fl = native_restore_fl,
8055 +@@ -293,7 +293,7 @@ struct pv_irq_ops pv_irq_ops = {
8056 + .halt = native_halt,
8057 + };
8058 +
8059 +-struct pv_cpu_ops pv_cpu_ops = {
8060 ++struct pv_cpu_ops pv_cpu_ops __read_only = {
8061 + .cpuid = native_cpuid,
8062 + .get_debugreg = native_get_debugreg,
8063 + .set_debugreg = native_set_debugreg,
8064 +@@ -339,7 +339,7 @@ struct pv_cpu_ops pv_cpu_ops = {
8065 + },
8066 + };
8067 +
8068 +-struct pv_apic_ops pv_apic_ops = {
8069 ++struct pv_apic_ops pv_apic_ops __read_only = {
8070 + #ifdef CONFIG_X86_LOCAL_APIC
8071 + .apic_write = native_apic_write,
8072 + .apic_write_atomic = native_apic_write_atomic,
8073 +@@ -350,7 +350,7 @@ struct pv_apic_ops pv_apic_ops = {
8074 + #endif
8075 + };
8076 +
8077 +-struct pv_mmu_ops pv_mmu_ops = {
8078 ++struct pv_mmu_ops pv_mmu_ops __read_only = {
8079 + #ifndef CONFIG_X86_64
8080 + .pagetable_setup_start = native_pagetable_setup_start,
8081 + .pagetable_setup_done = native_pagetable_setup_done,
8082 +diff -urNp linux-2.6.26.6/arch/x86/kernel/process_32.c linux-2.6.26.6/arch/x86/kernel/process_32.c
8083 +--- linux-2.6.26.6/arch/x86/kernel/process_32.c 2008-10-08 23:24:05.000000000 -0400
8084 ++++ linux-2.6.26.6/arch/x86/kernel/process_32.c 2008-10-11 21:55:07.000000000 -0400
8085 +@@ -66,8 +66,10 @@ EXPORT_SYMBOL(boot_option_idle_override)
8086 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
8087 + EXPORT_PER_CPU_SYMBOL(current_task);
8088 +
8089 ++#ifdef CONFIG_SMP
8090 + DEFINE_PER_CPU(int, cpu_number);
8091 + EXPORT_PER_CPU_SYMBOL(cpu_number);
8092 ++#endif
8093 +
8094 + /*
8095 + * Return saved PC of a blocked thread.
8096 +@@ -75,6 +77,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
8097 + unsigned long thread_saved_pc(struct task_struct *tsk)
8098 + {
8099 + return ((unsigned long *)tsk->thread.sp)[3];
8100 ++//XXX return tsk->thread.eip;
8101 + }
8102 +
8103 + /*
8104 +@@ -201,7 +204,7 @@ void __show_registers(struct pt_regs *re
8105 + unsigned long sp;
8106 + unsigned short ss, gs;
8107 +
8108 +- if (user_mode_vm(regs)) {
8109 ++ if (user_mode(regs)) {
8110 + sp = regs->sp;
8111 + ss = regs->ss & 0xffff;
8112 + savesegment(gs, gs);
8113 +@@ -278,8 +281,8 @@ int kernel_thread(int (*fn)(void *), voi
8114 + regs.bx = (unsigned long) fn;
8115 + regs.dx = (unsigned long) arg;
8116 +
8117 +- regs.ds = __USER_DS;
8118 +- regs.es = __USER_DS;
8119 ++ regs.ds = __KERNEL_DS;
8120 ++ regs.es = __KERNEL_DS;
8121 + regs.fs = __KERNEL_PERCPU;
8122 + regs.orig_ax = -1;
8123 + regs.ip = (unsigned long) kernel_thread_helper;
8124 +@@ -301,7 +304,7 @@ void exit_thread(void)
8125 + struct task_struct *tsk = current;
8126 + struct thread_struct *t = &tsk->thread;
8127 + int cpu = get_cpu();
8128 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8129 ++ struct tss_struct *tss = init_tss + cpu;
8130 +
8131 + kfree(t->io_bitmap_ptr);
8132 + t->io_bitmap_ptr = NULL;
8133 +@@ -322,6 +325,7 @@ void flush_thread(void)
8134 + {
8135 + struct task_struct *tsk = current;
8136 +
8137 ++ loadsegment(gs, 0);
8138 + tsk->thread.debugreg0 = 0;
8139 + tsk->thread.debugreg1 = 0;
8140 + tsk->thread.debugreg2 = 0;
8141 +@@ -361,7 +365,7 @@ int copy_thread(int nr, unsigned long cl
8142 + struct task_struct *tsk;
8143 + int err;
8144 +
8145 +- childregs = task_pt_regs(p);
8146 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
8147 + *childregs = *regs;
8148 + childregs->ax = 0;
8149 + childregs->sp = sp;
8150 +@@ -390,6 +394,7 @@ int copy_thread(int nr, unsigned long cl
8151 + * Set a new TLS for the child thread?
8152 + */
8153 + if (clone_flags & CLONE_SETTLS)
8154 ++//XXX needs set_fs()?
8155 + err = do_set_thread_area(p, -1,
8156 + (struct user_desc __user *)childregs->si, 0);
8157 +
8158 +@@ -589,7 +594,7 @@ struct task_struct * __switch_to(struct
8159 + struct thread_struct *prev = &prev_p->thread,
8160 + *next = &next_p->thread;
8161 + int cpu = smp_processor_id();
8162 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8163 ++ struct tss_struct *tss = init_tss + cpu;
8164 +
8165 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
8166 +
8167 +@@ -617,6 +622,11 @@ struct task_struct * __switch_to(struct
8168 + */
8169 + savesegment(gs, prev->gs);
8170 +
8171 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
8172 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
8173 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
8174 ++#endif
8175 ++
8176 + /*
8177 + * Load the per-thread Thread-Local Storage descriptor.
8178 + */
8179 +@@ -755,15 +765,27 @@ unsigned long get_wchan(struct task_stru
8180 + return 0;
8181 + }
8182 +
8183 +-unsigned long arch_align_stack(unsigned long sp)
8184 ++#ifdef CONFIG_PAX_RANDKSTACK
8185 ++asmlinkage void pax_randomize_kstack(void)
8186 + {
8187 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8188 +- sp -= get_random_int() % 8192;
8189 +- return sp & ~0xf;
8190 +-}
8191 ++ struct thread_struct *thread = &current->thread;
8192 ++ unsigned long time;
8193 +
8194 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
8195 +-{
8196 +- unsigned long range_end = mm->brk + 0x02000000;
8197 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8198 ++ if (!randomize_va_space)
8199 ++ return;
8200 ++
8201 ++ rdtscl(time);
8202 ++
8203 ++ /* P4 seems to return a 0 LSB, ignore it */
8204 ++#ifdef CONFIG_MPENTIUM4
8205 ++ time &= 0x1EUL;
8206 ++ time <<= 2;
8207 ++#else
8208 ++ time &= 0xFUL;
8209 ++ time <<= 3;
8210 ++#endif
8211 ++
8212 ++ thread->sp0 ^= time;
8213 ++ load_sp0(init_tss + smp_processor_id(), thread);
8214 + }
8215 ++#endif
8216 +diff -urNp linux-2.6.26.6/arch/x86/kernel/process_64.c linux-2.6.26.6/arch/x86/kernel/process_64.c
8217 +--- linux-2.6.26.6/arch/x86/kernel/process_64.c 2008-10-08 23:24:05.000000000 -0400
8218 ++++ linux-2.6.26.6/arch/x86/kernel/process_64.c 2008-10-11 21:54:19.000000000 -0400
8219 +@@ -146,6 +146,8 @@ static inline void play_dead(void)
8220 + void cpu_idle(void)
8221 + {
8222 + current_thread_info()->status |= TS_POLLING;
8223 ++ current->stack_canary = pax_get_random_long();
8224 ++ write_pda(stack_canary, current->stack_canary);
8225 + /* endless idle loop with no priority at all */
8226 + while (1) {
8227 + tick_nohz_stop_sched_tick();
8228 +@@ -255,7 +257,7 @@ void exit_thread(void)
8229 + struct thread_struct *t = &me->thread;
8230 +
8231 + if (me->thread.io_bitmap_ptr) {
8232 +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
8233 ++ struct tss_struct *tss = init_tss + get_cpu();
8234 +
8235 + kfree(t->io_bitmap_ptr);
8236 + t->io_bitmap_ptr = NULL;
8237 +@@ -566,7 +568,7 @@ __switch_to(struct task_struct *prev_p,
8238 + struct thread_struct *prev = &prev_p->thread,
8239 + *next = &next_p->thread;
8240 + int cpu = smp_processor_id();
8241 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8242 ++ struct tss_struct *tss = init_tss + cpu;
8243 +
8244 + /* we're going to use this soon, after a few expensive things */
8245 + if (next_p->fpu_counter>5)
8246 +@@ -641,7 +643,6 @@ __switch_to(struct task_struct *prev_p,
8247 + write_pda(kernelstack,
8248 + (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
8249 + #ifdef CONFIG_CC_STACKPROTECTOR
8250 +- write_pda(stack_canary, next_p->stack_canary);
8251 + /*
8252 + * Build time only check to make sure the stack_canary is at
8253 + * offset 40 in the pda; this is a gcc ABI requirement
8254 +@@ -855,16 +856,3 @@ long sys_arch_prctl(int code, unsigned l
8255 + {
8256 + return do_arch_prctl(current, code, addr);
8257 + }
8258 +-
8259 +-unsigned long arch_align_stack(unsigned long sp)
8260 +-{
8261 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8262 +- sp -= get_random_int() % 8192;
8263 +- return sp & ~0xf;
8264 +-}
8265 +-
8266 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
8267 +-{
8268 +- unsigned long range_end = mm->brk + 0x02000000;
8269 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
8270 +-}
8271 +diff -urNp linux-2.6.26.6/arch/x86/kernel/ptrace.c linux-2.6.26.6/arch/x86/kernel/ptrace.c
8272 +--- linux-2.6.26.6/arch/x86/kernel/ptrace.c 2008-10-08 23:24:05.000000000 -0400
8273 ++++ linux-2.6.26.6/arch/x86/kernel/ptrace.c 2008-10-11 21:54:19.000000000 -0400
8274 +@@ -1371,7 +1371,7 @@ void send_sigtrap(struct task_struct *ts
8275 + info.si_code = TRAP_BRKPT;
8276 +
8277 + /* User-mode ip? */
8278 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
8279 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
8280 +
8281 + /* Send us the fake SIGTRAP */
8282 + force_sig_info(SIGTRAP, &info, tsk);
8283 +diff -urNp linux-2.6.26.6/arch/x86/kernel/reboot.c linux-2.6.26.6/arch/x86/kernel/reboot.c
8284 +--- linux-2.6.26.6/arch/x86/kernel/reboot.c 2008-10-08 23:24:05.000000000 -0400
8285 ++++ linux-2.6.26.6/arch/x86/kernel/reboot.c 2008-10-11 21:54:19.000000000 -0400
8286 +@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
8287 + EXPORT_SYMBOL(pm_power_off);
8288 +
8289 + static long no_idt[3];
8290 +-static int reboot_mode;
8291 ++static unsigned short reboot_mode;
8292 + enum reboot_type reboot_type = BOOT_KBD;
8293 + int reboot_force;
8294 +
8295 +@@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
8296 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
8297 + },
8298 + },
8299 +- { }
8300 ++ { NULL, NULL, {{0, NULL}}, NULL}
8301 + };
8302 +
8303 + static int __init reboot_init(void)
8304 +@@ -209,15 +209,15 @@ core_initcall(reboot_init);
8305 + controller to pulse the CPU reset line, which is more thorough, but
8306 + doesn't work with at least one type of 486 motherboard. It is easy
8307 + to stop this code working; hence the copious comments. */
8308 +-static unsigned long long
8309 +-real_mode_gdt_entries [3] =
8310 ++static struct desc_struct
8311 ++real_mode_gdt_entries [3] __read_only =
8312 + {
8313 +- 0x0000000000000000ULL, /* Null descriptor */
8314 +- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
8315 +- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
8316 ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
8317 ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
8318 ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
8319 + };
8320 +
8321 +-static struct desc_ptr
8322 ++static const struct desc_ptr
8323 + real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
8324 + real_mode_idt = { 0x3ff, 0 };
8325 +
8326 +@@ -239,7 +239,7 @@ real_mode_idt = { 0x3ff, 0 };
8327 +
8328 + More could be done here to set up the registers as if a CPU reset had
8329 + occurred; hopefully real BIOSs don't assume much. */
8330 +-static unsigned char real_mode_switch [] =
8331 ++static const unsigned char real_mode_switch [] =
8332 + {
8333 + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
8334 + 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
8335 +@@ -253,7 +253,7 @@ static unsigned char real_mode_switch []
8336 + 0x24, 0x10, /* f: andb $0x10,al */
8337 + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
8338 + };
8339 +-static unsigned char jump_to_bios [] =
8340 ++static const unsigned char jump_to_bios [] =
8341 + {
8342 + 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
8343 + };
8344 +@@ -263,7 +263,7 @@ static unsigned char jump_to_bios [] =
8345 + * specified by the code and length parameters.
8346 + * We assume that length will aways be less that 100!
8347 + */
8348 +-void machine_real_restart(unsigned char *code, int length)
8349 ++void machine_real_restart(const unsigned char *code, unsigned int length)
8350 + {
8351 + local_irq_disable();
8352 +
8353 +@@ -283,8 +283,8 @@ void machine_real_restart(unsigned char
8354 + /* Remap the kernel at virtual address zero, as well as offset zero
8355 + from the kernel segment. This assumes the kernel segment starts at
8356 + virtual address PAGE_OFFSET. */
8357 +- memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
8358 +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
8359 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
8360 ++ min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
8361 +
8362 + /*
8363 + * Use `swapper_pg_dir' as our page directory.
8364 +@@ -296,16 +296,15 @@ void machine_real_restart(unsigned char
8365 + boot)". This seems like a fairly standard thing that gets set by
8366 + REBOOT.COM programs, and the previous reset routine did this
8367 + too. */
8368 +- *((unsigned short *)0x472) = reboot_mode;
8369 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
8370 +
8371 + /* For the switch to real mode, copy some code to low memory. It has
8372 + to be in the first 64k because it is running in 16-bit mode, and it
8373 + has to have the same physical and virtual address, because it turns
8374 + off paging. Copy it near the end of the first page, out of the way
8375 + of BIOS variables. */
8376 +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
8377 +- real_mode_switch, sizeof (real_mode_switch));
8378 +- memcpy((void *)(0x1000 - 100), code, length);
8379 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
8380 ++ memcpy(__va(0x1000 - 100), code, length);
8381 +
8382 + /* Set up the IDT for real mode. */
8383 + load_idt(&real_mode_idt);
8384 +diff -urNp linux-2.6.26.6/arch/x86/kernel/setup_32.c linux-2.6.26.6/arch/x86/kernel/setup_32.c
8385 +--- linux-2.6.26.6/arch/x86/kernel/setup_32.c 2008-10-08 23:24:05.000000000 -0400
8386 ++++ linux-2.6.26.6/arch/x86/kernel/setup_32.c 2008-10-11 21:55:52.000000000 -0400
8387 +@@ -67,6 +67,7 @@
8388 + #include <asm/bios_ebda.h>
8389 + #include <asm/cacheflush.h>
8390 + #include <asm/processor.h>
8391 ++#include <asm/boot.h>
8392 +
8393 + /* This value is set up by the early boot code to point to the value
8394 + immediately after the boot time page tables. It contains a *physical*
8395 +@@ -341,10 +342,10 @@ early_param("reservetop", parse_reservet
8396 + */
8397 + unsigned long __init find_max_low_pfn(void)
8398 + {
8399 +- unsigned long max_low_pfn;
8400 ++ unsigned long __max_low_pfn;
8401 +
8402 +- max_low_pfn = max_pfn;
8403 +- if (max_low_pfn > MAXMEM_PFN) {
8404 ++ __max_low_pfn = max_pfn;
8405 ++ if (__max_low_pfn > MAXMEM_PFN) {
8406 + if (highmem_pages == -1)
8407 + highmem_pages = max_pfn - MAXMEM_PFN;
8408 + if (highmem_pages + MAXMEM_PFN < max_pfn)
8409 +@@ -353,7 +354,7 @@ unsigned long __init find_max_low_pfn(vo
8410 + printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
8411 + highmem_pages = 0;
8412 + }
8413 +- max_low_pfn = MAXMEM_PFN;
8414 ++ __max_low_pfn = MAXMEM_PFN;
8415 + #ifndef CONFIG_HIGHMEM
8416 + /* Maximum memory usable is what is directly addressable */
8417 + printk(KERN_WARNING "Warning only %ldMB will be used.\n",
8418 +@@ -381,18 +382,18 @@ unsigned long __init find_max_low_pfn(vo
8419 + highmem_pages = 0;
8420 + }
8421 + if (highmem_pages) {
8422 +- if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
8423 ++ if (__max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
8424 + printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
8425 + highmem_pages = 0;
8426 + }
8427 +- max_low_pfn -= highmem_pages;
8428 ++ __max_low_pfn -= highmem_pages;
8429 + }
8430 + #else
8431 + if (highmem_pages)
8432 + printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
8433 + #endif
8434 + }
8435 +- return max_low_pfn;
8436 ++ return __max_low_pfn;
8437 + }
8438 +
8439 + #define BIOS_LOWMEM_KILOBYTES 0x413
8440 +@@ -447,7 +448,7 @@ static void __init reserve_ebda_region(v
8441 +
8442 + #ifndef CONFIG_NEED_MULTIPLE_NODES
8443 + static void __init setup_bootmem_allocator(void);
8444 +-static unsigned long __init setup_memory(void)
8445 ++static void __init setup_memory(void)
8446 + {
8447 + /*
8448 + * partially used pages are not usable - thus
8449 +@@ -477,8 +478,6 @@ static unsigned long __init setup_memory
8450 + pages_to_mb(max_low_pfn));
8451 +
8452 + setup_bootmem_allocator();
8453 +-
8454 +- return max_low_pfn;
8455 + }
8456 +
8457 + static void __init zone_sizes_init(void)
8458 +@@ -498,7 +497,7 @@ static void __init zone_sizes_init(void)
8459 + free_area_init_nodes(max_zone_pfns);
8460 + }
8461 + #else
8462 +-extern unsigned long __init setup_memory(void);
8463 ++extern void __init setup_memory(void);
8464 + extern void zone_sizes_init(void);
8465 + #endif /* !CONFIG_NEED_MULTIPLE_NODES */
8466 +
8467 +@@ -662,8 +661,8 @@ void __init setup_bootmem_allocator(void
8468 + * the (very unlikely) case of us accidentally initializing the
8469 + * bootmem allocator with an invalid RAM area.
8470 + */
8471 +- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
8472 +- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
8473 ++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
8474 ++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR,
8475 + BOOTMEM_DEFAULT);
8476 +
8477 + /*
8478 +@@ -758,8 +757,6 @@ DEFINE_PER_CPU(int, x86_cpu_to_node_map)
8479 + */
8480 + void __init setup_arch(char **cmdline_p)
8481 + {
8482 +- unsigned long max_low_pfn;
8483 +-
8484 + memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
8485 + pre_setup_arch_hook();
8486 + early_cpu_init();
8487 +@@ -799,14 +796,14 @@ void __init setup_arch(char **cmdline_p)
8488 +
8489 + if (!boot_params.hdr.root_flags)
8490 + root_mountflags &= ~MS_RDONLY;
8491 +- init_mm.start_code = (unsigned long) _text;
8492 +- init_mm.end_code = (unsigned long) _etext;
8493 ++ init_mm.start_code = ktla_ktva((unsigned long) _text);
8494 ++ init_mm.end_code = ktla_ktva((unsigned long) _etext);
8495 + init_mm.end_data = (unsigned long) _edata;
8496 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
8497 +
8498 +- code_resource.start = virt_to_phys(_text);
8499 +- code_resource.end = virt_to_phys(_etext)-1;
8500 +- data_resource.start = virt_to_phys(_etext);
8501 ++ code_resource.start = virt_to_phys(ktla_ktva(_text));
8502 ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
8503 ++ data_resource.start = virt_to_phys(_data);
8504 + data_resource.end = virt_to_phys(_edata)-1;
8505 + bss_resource.start = virt_to_phys(&__bss_start);
8506 + bss_resource.end = virt_to_phys(&__bss_stop)-1;
8507 +@@ -830,7 +827,7 @@ void __init setup_arch(char **cmdline_p)
8508 + if (mtrr_trim_uncached_memory(max_pfn))
8509 + propagate_e820_map();
8510 +
8511 +- max_low_pfn = setup_memory();
8512 ++ setup_memory();
8513 +
8514 + #ifdef CONFIG_KVM_CLOCK
8515 + kvmclock_init();
8516 +diff -urNp linux-2.6.26.6/arch/x86/kernel/setup64.c linux-2.6.26.6/arch/x86/kernel/setup64.c
8517 +--- linux-2.6.26.6/arch/x86/kernel/setup64.c 2008-10-08 23:24:05.000000000 -0400
8518 ++++ linux-2.6.26.6/arch/x86/kernel/setup64.c 2008-10-11 21:55:07.000000000 -0400
8519 +@@ -38,15 +38,13 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
8520 + EXPORT_SYMBOL(_cpu_pda);
8521 + struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
8522 +
8523 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
8524 ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
8525 +
8526 + char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
8527 +
8528 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
8529 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
8530 +
8531 +-static int do_not_nx __cpuinitdata = 0;
8532 +-
8533 + /* noexec=on|off
8534 + Control non executable mappings for 64bit processes.
8535 +
8536 +@@ -59,16 +57,14 @@ static int __init nonx_setup(char *str)
8537 + return -EINVAL;
8538 + if (!strncmp(str, "on", 2)) {
8539 + __supported_pte_mask |= _PAGE_NX;
8540 +- do_not_nx = 0;
8541 + } else if (!strncmp(str, "off", 3)) {
8542 +- do_not_nx = 1;
8543 + __supported_pte_mask &= ~_PAGE_NX;
8544 + }
8545 + return 0;
8546 + }
8547 + early_param("noexec", nonx_setup);
8548 +
8549 +-int force_personality32 = 0;
8550 ++int force_personality32;
8551 +
8552 + /* noexec32=on|off
8553 + Control non executable heap for 32bit processes.
8554 +@@ -151,7 +147,7 @@ void __cpuinit check_efer(void)
8555 + unsigned long efer;
8556 +
8557 + rdmsrl(MSR_EFER, efer);
8558 +- if (!(efer & EFER_NX) || do_not_nx) {
8559 ++ if (!(efer & EFER_NX)) {
8560 + __supported_pte_mask &= ~_PAGE_NX;
8561 + }
8562 + }
8563 +@@ -174,12 +170,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
8564 + void __cpuinit cpu_init (void)
8565 + {
8566 + int cpu = stack_smp_processor_id();
8567 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
8568 ++ struct tss_struct *t = init_tss + cpu;
8569 + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
8570 + unsigned long v;
8571 + char *estacks = NULL;
8572 + struct task_struct *me;
8573 + int i;
8574 ++ struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)get_cpu_gdt_table(cpu)};
8575 +
8576 + /* CPU 0 is initialised in head64.c */
8577 + if (cpu != 0) {
8578 +@@ -197,14 +194,9 @@ void __cpuinit cpu_init (void)
8579 + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
8580 +
8581 + /*
8582 +- * Initialize the per-CPU GDT with the boot GDT,
8583 +- * and set up the GDT descriptor:
8584 ++ * Initialize the per-CPU GDT with the boot GDT:
8585 + */
8586 +- if (cpu)
8587 +- memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
8588 +-
8589 +- cpu_gdt_descr[cpu].size = GDT_SIZE;
8590 +- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
8591 ++ load_gdt(&cpu_gdt_descr);
8592 + load_idt((const struct desc_ptr *)&idt_descr);
8593 +
8594 + memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
8595 +diff -urNp linux-2.6.26.6/arch/x86/kernel/signal_32.c linux-2.6.26.6/arch/x86/kernel/signal_32.c
8596 +--- linux-2.6.26.6/arch/x86/kernel/signal_32.c 2008-10-08 23:24:05.000000000 -0400
8597 ++++ linux-2.6.26.6/arch/x86/kernel/signal_32.c 2008-10-11 21:54:19.000000000 -0400
8598 +@@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction
8599 + }
8600 +
8601 + if (current->mm->context.vdso)
8602 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
8603 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
8604 + else
8605 +- restorer = &frame->retcode;
8606 ++ restorer = (void __user *)&frame->retcode;
8607 + if (ka->sa.sa_flags & SA_RESTORER)
8608 + restorer = ka->sa.sa_restorer;
8609 +
8610 +@@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
8611 + goto give_sigsegv;
8612 +
8613 + /* Set up to return from userspace. */
8614 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
8615 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
8616 + if (ka->sa.sa_flags & SA_RESTORER)
8617 + restorer = ka->sa.sa_restorer;
8618 + err |= __put_user(restorer, &frame->pretcode);
8619 +@@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
8620 + * X86_32: vm86 regs switched out by assembly code before reaching
8621 + * here, so testing against kernel CS suffices.
8622 + */
8623 +- if (!user_mode(regs))
8624 ++ if (!user_mode_novm(regs))
8625 + return;
8626 +
8627 + if (current_thread_info()->status & TS_RESTORE_SIGMASK)
8628 +diff -urNp linux-2.6.26.6/arch/x86/kernel/signal_64.c linux-2.6.26.6/arch/x86/kernel/signal_64.c
8629 +--- linux-2.6.26.6/arch/x86/kernel/signal_64.c 2008-10-08 23:24:05.000000000 -0400
8630 ++++ linux-2.6.26.6/arch/x86/kernel/signal_64.c 2008-10-11 21:54:19.000000000 -0400
8631 +@@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
8632 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
8633 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
8634 + if (sizeof(*set) == 16) {
8635 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
8636 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
8637 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
8638 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
8639 + } else
8640 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
8641 +
8642 +diff -urNp linux-2.6.26.6/arch/x86/kernel/smpboot.c linux-2.6.26.6/arch/x86/kernel/smpboot.c
8643 +--- linux-2.6.26.6/arch/x86/kernel/smpboot.c 2008-10-08 23:24:05.000000000 -0400
8644 ++++ linux-2.6.26.6/arch/x86/kernel/smpboot.c 2008-10-11 21:55:07.000000000 -0400
8645 +@@ -847,15 +847,13 @@ static int __cpuinit do_boot_cpu(int api
8646 + .cpu = cpu,
8647 + .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
8648 + };
8649 ++
8650 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
8651 ++ unsigned long cr0;
8652 ++#endif
8653 ++
8654 + INIT_WORK(&c_idle.work, do_fork_idle);
8655 + #ifdef CONFIG_X86_64
8656 +- /* allocate memory for gdts of secondary cpus. Hotplug is considered */
8657 +- if (!cpu_gdt_descr[cpu].address &&
8658 +- !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
8659 +- printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
8660 +- return -1;
8661 +- }
8662 +-
8663 + /* Allocate node local memory for AP pdas */
8664 + if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
8665 + struct x8664_pda *newpda, *pda;
8666 +@@ -905,7 +903,17 @@ do_rest:
8667 + #ifdef CONFIG_X86_32
8668 + per_cpu(current_task, cpu) = c_idle.idle;
8669 + init_gdt(cpu);
8670 ++
8671 ++#ifdef CONFIG_PAX_KERNEXEC
8672 ++ pax_open_kernel(cr0);
8673 ++#endif
8674 ++
8675 + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
8676 ++
8677 ++#ifdef CONFIG_PAX_KERNEXEC
8678 ++ pax_close_kernel(cr0);
8679 ++#endif
8680 ++
8681 + c_idle.idle->thread.ip = (unsigned long) start_secondary;
8682 + /* Stack for startup_32 can be just as for start_secondary onwards */
8683 + stack_start.sp = (void *) c_idle.idle->thread.sp;
8684 +@@ -913,7 +921,7 @@ do_rest:
8685 + #else
8686 + cpu_pda(cpu)->pcurrent = c_idle.idle;
8687 + init_rsp = c_idle.idle->thread.sp;
8688 +- load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
8689 ++ load_sp0(init_tss + cpu, &c_idle.idle->thread);
8690 + initial_code = (unsigned long)start_secondary;
8691 + clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
8692 + #endif
8693 +diff -urNp linux-2.6.26.6/arch/x86/kernel/smpcommon.c linux-2.6.26.6/arch/x86/kernel/smpcommon.c
8694 +--- linux-2.6.26.6/arch/x86/kernel/smpcommon.c 2008-10-08 23:24:05.000000000 -0400
8695 ++++ linux-2.6.26.6/arch/x86/kernel/smpcommon.c 2008-10-11 21:55:07.000000000 -0400
8696 +@@ -3,9 +3,10 @@
8697 + */
8698 + #include <linux/module.h>
8699 + #include <asm/smp.h>
8700 ++#include <asm/sections.h>
8701 +
8702 + #ifdef CONFIG_X86_32
8703 +-DEFINE_PER_CPU(unsigned long, this_cpu_off);
8704 ++DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
8705 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
8706 +
8707 + /* Initialize the CPU's GDT. This is either the boot CPU doing itself
8708 +@@ -13,15 +14,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
8709 + secondary which will soon come up. */
8710 + __cpuinit void init_gdt(int cpu)
8711 + {
8712 +- struct desc_struct *gdt = get_cpu_gdt_table(cpu);
8713 ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
8714 ++ unsigned long base, limit;
8715 ++
8716 ++ base = per_cpu_offset(cpu);
8717 ++ limit = PERCPU_ENOUGH_ROOM - 1;
8718 ++ if (limit < 64*1024)
8719 ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
8720 ++ else
8721 ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
8722 +
8723 +- pack_descriptor(&gdt[GDT_ENTRY_PERCPU],
8724 +- __per_cpu_offset[cpu], 0xFFFFF,
8725 +- 0x2 | DESCTYPE_S, 0x8);
8726 ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
8727 +
8728 +- gdt[GDT_ENTRY_PERCPU].s = 1;
8729 +-
8730 +- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
8731 ++ per_cpu(this_cpu_off, cpu) = base;
8732 + per_cpu(cpu_number, cpu) = cpu;
8733 + }
8734 + #endif
8735 +diff -urNp linux-2.6.26.6/arch/x86/kernel/step.c linux-2.6.26.6/arch/x86/kernel/step.c
8736 +--- linux-2.6.26.6/arch/x86/kernel/step.c 2008-10-08 23:24:05.000000000 -0400
8737 ++++ linux-2.6.26.6/arch/x86/kernel/step.c 2008-10-11 21:55:07.000000000 -0400
8738 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
8739 + * and APM bios ones we just ignore here.
8740 + */
8741 + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
8742 +- u32 *desc;
8743 ++ struct desc_struct *desc;
8744 + unsigned long base;
8745 +
8746 +- seg &= ~7UL;
8747 ++ seg >>= 3;
8748 +
8749 + mutex_lock(&child->mm->context.lock);
8750 +- if (unlikely((seg >> 3) >= child->mm->context.size))
8751 +- addr = -1L; /* bogus selector, access would fault */
8752 ++ if (unlikely(seg >= child->mm->context.size))
8753 ++ addr = -EINVAL;
8754 + else {
8755 +- desc = child->mm->context.ldt + seg;
8756 +- base = ((desc[0] >> 16) |
8757 +- ((desc[1] & 0xff) << 16) |
8758 +- (desc[1] & 0xff000000));
8759 ++ desc = &child->mm->context.ldt[seg];
8760 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
8761 +
8762 + /* 16-bit code segment? */
8763 +- if (!((desc[1] >> 22) & 1))
8764 ++ if (!((desc->b >> 22) & 1))
8765 + addr &= 0xffff;
8766 + addr += base;
8767 + }
8768 +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
8769 + unsigned char opcode[15];
8770 + unsigned long addr = convert_ip_to_linear(child, regs);
8771 +
8772 ++ if (addr == -EINVAL)
8773 ++ return 0;
8774 ++
8775 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
8776 + for (i = 0; i < copied; i++) {
8777 + switch (opcode[i]) {
8778 +@@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
8779 +
8780 + #ifdef CONFIG_X86_64
8781 + case 0x40 ... 0x4f:
8782 +- if (regs->cs != __USER_CS)
8783 ++ if ((regs->cs & 0xffff) != __USER_CS)
8784 + /* 32-bit mode: register increment */
8785 + return 0;
8786 + /* 64-bit mode: REX prefix */
8787 +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
8788 +--- linux-2.6.26.6/arch/x86/kernel/syscall_table_32.S 2008-10-08 23:24:05.000000000 -0400
8789 ++++ linux-2.6.26.6/arch/x86/kernel/syscall_table_32.S 2008-10-11 21:54:19.000000000 -0400
8790 +@@ -1,3 +1,4 @@
8791 ++.section .rodata,"a",@progbits
8792 + ENTRY(sys_call_table)
8793 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
8794 + .long sys_exit
8795 +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
8796 +--- linux-2.6.26.6/arch/x86/kernel/sys_i386_32.c 2008-10-08 23:24:05.000000000 -0400
8797 ++++ linux-2.6.26.6/arch/x86/kernel/sys_i386_32.c 2008-10-11 21:54:19.000000000 -0400
8798 +@@ -22,6 +22,21 @@
8799 + #include <asm/uaccess.h>
8800 + #include <asm/unistd.h>
8801 +
8802 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
8803 ++{
8804 ++ unsigned long pax_task_size = TASK_SIZE;
8805 ++
8806 ++#ifdef CONFIG_PAX_SEGMEXEC
8807 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
8808 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
8809 ++#endif
8810 ++
8811 ++ if (len > pax_task_size || addr > pax_task_size - len)
8812 ++ return -EINVAL;
8813 ++
8814 ++ return 0;
8815 ++}
8816 ++
8817 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
8818 + unsigned long prot, unsigned long flags,
8819 + unsigned long fd, unsigned long pgoff)
8820 +@@ -81,6 +96,205 @@ out:
8821 + return err;
8822 + }
8823 +
8824 ++unsigned long
8825 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
8826 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
8827 ++{
8828 ++ struct mm_struct *mm = current->mm;
8829 ++ struct vm_area_struct *vma;
8830 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
8831 ++
8832 ++#ifdef CONFIG_PAX_SEGMEXEC
8833 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
8834 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
8835 ++#endif
8836 ++
8837 ++ if (len > pax_task_size)
8838 ++ return -ENOMEM;
8839 ++
8840 ++ if (flags & MAP_FIXED)
8841 ++ return addr;
8842 ++
8843 ++#ifdef CONFIG_PAX_RANDMMAP
8844 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8845 ++#endif
8846 ++
8847 ++ if (addr) {
8848 ++ addr = PAGE_ALIGN(addr);
8849 ++ vma = find_vma(mm, addr);
8850 ++ if (pax_task_size - len >= addr &&
8851 ++ (!vma || addr + len <= vma->vm_start))
8852 ++ return addr;
8853 ++ }
8854 ++ if (len > mm->cached_hole_size) {
8855 ++ start_addr = addr = mm->free_area_cache;
8856 ++ } else {
8857 ++ start_addr = addr = mm->mmap_base;
8858 ++ mm->cached_hole_size = 0;
8859 ++ }
8860 ++
8861 ++#ifdef CONFIG_PAX_PAGEEXEC
8862 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
8863 ++ start_addr = 0x00110000UL;
8864 ++
8865 ++#ifdef CONFIG_PAX_RANDMMAP
8866 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
8867 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
8868 ++#endif
8869 ++
8870 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
8871 ++ start_addr = addr = mm->mmap_base;
8872 ++ else
8873 ++ addr = start_addr;
8874 ++ }
8875 ++#endif
8876 ++
8877 ++full_search:
8878 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
8879 ++ /* At this point: (!vma || addr < vma->vm_end). */
8880 ++ if (pax_task_size - len < addr) {
8881 ++ /*
8882 ++ * Start a new search - just in case we missed
8883 ++ * some holes.
8884 ++ */
8885 ++ if (start_addr != mm->mmap_base) {
8886 ++ start_addr = addr = mm->mmap_base;
8887 ++ mm->cached_hole_size = 0;
8888 ++ goto full_search;
8889 ++ }
8890 ++ return -ENOMEM;
8891 ++ }
8892 ++ if (!vma || addr + len <= vma->vm_start) {
8893 ++ /*
8894 ++ * Remember the place where we stopped the search:
8895 ++ */
8896 ++ mm->free_area_cache = addr + len;
8897 ++ return addr;
8898 ++ }
8899 ++ if (addr + mm->cached_hole_size < vma->vm_start)
8900 ++ mm->cached_hole_size = vma->vm_start - addr;
8901 ++ addr = vma->vm_end;
8902 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
8903 ++ start_addr = addr = mm->mmap_base;
8904 ++ mm->cached_hole_size = 0;
8905 ++ goto full_search;
8906 ++ }
8907 ++ }
8908 ++}
8909 ++
8910 ++unsigned long
8911 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
8912 ++ const unsigned long len, const unsigned long pgoff,
8913 ++ const unsigned long flags)
8914 ++{
8915 ++ struct vm_area_struct *vma;
8916 ++ struct mm_struct *mm = current->mm;
8917 ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
8918 ++
8919 ++#ifdef CONFIG_PAX_SEGMEXEC
8920 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
8921 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
8922 ++#endif
8923 ++
8924 ++ /* requested length too big for entire address space */
8925 ++ if (len > pax_task_size)
8926 ++ return -ENOMEM;
8927 ++
8928 ++ if (flags & MAP_FIXED)
8929 ++ return addr;
8930 ++
8931 ++#ifdef CONFIG_PAX_PAGEEXEC
8932 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
8933 ++ goto bottomup;
8934 ++#endif
8935 ++
8936 ++#ifdef CONFIG_PAX_RANDMMAP
8937 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8938 ++#endif
8939 ++
8940 ++ /* requesting a specific address */
8941 ++ if (addr) {
8942 ++ addr = PAGE_ALIGN(addr);
8943 ++ vma = find_vma(mm, addr);
8944 ++ if (pax_task_size - len >= addr &&
8945 ++ (!vma || addr + len <= vma->vm_start))
8946 ++ return addr;
8947 ++ }
8948 ++
8949 ++ /* check if free_area_cache is useful for us */
8950 ++ if (len <= mm->cached_hole_size) {
8951 ++ mm->cached_hole_size = 0;
8952 ++ mm->free_area_cache = mm->mmap_base;
8953 ++ }
8954 ++
8955 ++ /* either no address requested or can't fit in requested address hole */
8956 ++ addr = mm->free_area_cache;
8957 ++
8958 ++ /* make sure it can fit in the remaining address space */
8959 ++ if (addr > len) {
8960 ++ vma = find_vma(mm, addr-len);
8961 ++ if (!vma || addr <= vma->vm_start)
8962 ++ /* remember the address as a hint for next time */
8963 ++ return (mm->free_area_cache = addr-len);
8964 ++ }
8965 ++
8966 ++ if (mm->mmap_base < len)
8967 ++ goto bottomup;
8968 ++
8969 ++ addr = mm->mmap_base-len;
8970 ++
8971 ++ do {
8972 ++ /*
8973 ++ * Lookup failure means no vma is above this address,
8974 ++ * else if new region fits below vma->vm_start,
8975 ++ * return with success:
8976 ++ */
8977 ++ vma = find_vma(mm, addr);
8978 ++ if (!vma || addr+len <= vma->vm_start)
8979 ++ /* remember the address as a hint for next time */
8980 ++ return (mm->free_area_cache = addr);
8981 ++
8982 ++ /* remember the largest hole we saw so far */
8983 ++ if (addr + mm->cached_hole_size < vma->vm_start)
8984 ++ mm->cached_hole_size = vma->vm_start - addr;
8985 ++
8986 ++ /* try just below the current vma->vm_start */
8987 ++ addr = vma->vm_start-len;
8988 ++ } while (len < vma->vm_start);
8989 ++
8990 ++bottomup:
8991 ++ /*
8992 ++ * A failed mmap() very likely causes application failure,
8993 ++ * so fall back to the bottom-up function here. This scenario
8994 ++ * can happen with large stack limits and large mmap()
8995 ++ * allocations.
8996 ++ */
8997 ++
8998 ++#ifdef CONFIG_PAX_SEGMEXEC
8999 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9000 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
9001 ++ else
9002 ++#endif
9003 ++
9004 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9005 ++
9006 ++#ifdef CONFIG_PAX_RANDMMAP
9007 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9008 ++ mm->mmap_base += mm->delta_mmap;
9009 ++#endif
9010 ++
9011 ++ mm->free_area_cache = mm->mmap_base;
9012 ++ mm->cached_hole_size = ~0UL;
9013 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9014 ++ /*
9015 ++ * Restore the topdown base:
9016 ++ */
9017 ++ mm->mmap_base = base;
9018 ++ mm->free_area_cache = base;
9019 ++ mm->cached_hole_size = ~0UL;
9020 ++
9021 ++ return addr;
9022 ++}
9023 +
9024 + struct sel_arg_struct {
9025 + unsigned long n;
9026 +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
9027 +--- linux-2.6.26.6/arch/x86/kernel/sys_x86_64.c 2008-10-08 23:24:05.000000000 -0400
9028 ++++ linux-2.6.26.6/arch/x86/kernel/sys_x86_64.c 2008-10-11 21:54:19.000000000 -0400
9029 +@@ -45,8 +45,8 @@ out:
9030 + return error;
9031 + }
9032 +
9033 +-static void find_start_end(unsigned long flags, unsigned long *begin,
9034 +- unsigned long *end)
9035 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
9036 ++ unsigned long *begin, unsigned long *end)
9037 + {
9038 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
9039 + unsigned long new_begin;
9040 +@@ -65,7 +65,7 @@ static void find_start_end(unsigned long
9041 + *begin = new_begin;
9042 + }
9043 + } else {
9044 +- *begin = TASK_UNMAPPED_BASE;
9045 ++ *begin = mm->mmap_base;
9046 + *end = TASK_SIZE;
9047 + }
9048 + }
9049 +@@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
9050 + if (flags & MAP_FIXED)
9051 + return addr;
9052 +
9053 +- find_start_end(flags, &begin, &end);
9054 ++ find_start_end(mm, flags, &begin, &end);
9055 +
9056 + if (len > end)
9057 + return -ENOMEM;
9058 +
9059 ++#ifdef CONFIG_PAX_RANDMMAP
9060 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9061 ++#endif
9062 ++
9063 + if (addr) {
9064 + addr = PAGE_ALIGN(addr);
9065 + vma = find_vma(mm, addr);
9066 +@@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
9067 + {
9068 + struct vm_area_struct *vma;
9069 + struct mm_struct *mm = current->mm;
9070 +- unsigned long addr = addr0;
9071 ++ unsigned long base = mm->mmap_base, addr = addr0;
9072 +
9073 + /* requested length too big for entire address space */
9074 + if (len > TASK_SIZE)
9075 +@@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
9076 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
9077 + goto bottomup;
9078 +
9079 ++#ifdef CONFIG_PAX_RANDMMAP
9080 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
9081 ++#endif
9082 ++
9083 + /* requesting a specific address */
9084 + if (addr) {
9085 + addr = PAGE_ALIGN(addr);
9086 +@@ -211,13 +219,21 @@ bottomup:
9087 + * can happen with large stack limits and large mmap()
9088 + * allocations.
9089 + */
9090 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9091 ++
9092 ++#ifdef CONFIG_PAX_RANDMMAP
9093 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9094 ++ mm->mmap_base += mm->delta_mmap;
9095 ++#endif
9096 ++
9097 ++ mm->free_area_cache = mm->mmap_base;
9098 + mm->cached_hole_size = ~0UL;
9099 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
9100 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9101 + /*
9102 + * Restore the topdown base:
9103 + */
9104 +- mm->free_area_cache = mm->mmap_base;
9105 ++ mm->mmap_base = base;
9106 ++ mm->free_area_cache = base;
9107 + mm->cached_hole_size = ~0UL;
9108 +
9109 + return addr;
9110 +diff -urNp linux-2.6.26.6/arch/x86/kernel/time_32.c linux-2.6.26.6/arch/x86/kernel/time_32.c
9111 +--- linux-2.6.26.6/arch/x86/kernel/time_32.c 2008-10-08 23:24:05.000000000 -0400
9112 ++++ linux-2.6.26.6/arch/x86/kernel/time_32.c 2008-10-11 21:54:19.000000000 -0400
9113 +@@ -52,20 +52,30 @@ unsigned long profile_pc(struct pt_regs
9114 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
9115 + in_lock_functions(pc)) {
9116 + #ifdef CONFIG_FRAME_POINTER
9117 +- return *(unsigned long *)(regs->bp + 4);
9118 ++ return ktla_ktva(*(unsigned long *)(regs->bp + 4));
9119 + #else
9120 + unsigned long *sp = (unsigned long *)&regs->sp;
9121 +
9122 + /* Return address is either directly at stack pointer
9123 + or above a saved flags. Eflags has bits 22-31 zero,
9124 + kernel addresses don't. */
9125 ++
9126 ++#ifdef CONFIG_PAX_KERNEXEC
9127 ++ return ktla_ktva(sp[0]);
9128 ++#else
9129 + if (sp[0] >> 22)
9130 + return sp[0];
9131 + if (sp[1] >> 22)
9132 + return sp[1];
9133 + #endif
9134 ++
9135 ++#endif
9136 + }
9137 + #endif
9138 ++
9139 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
9140 ++ pc = ktla_ktva(pc);
9141 ++
9142 + return pc;
9143 + }
9144 + EXPORT_SYMBOL(profile_pc);
9145 +diff -urNp linux-2.6.26.6/arch/x86/kernel/tlb_32.c linux-2.6.26.6/arch/x86/kernel/tlb_32.c
9146 +--- linux-2.6.26.6/arch/x86/kernel/tlb_32.c 2008-10-08 23:24:05.000000000 -0400
9147 ++++ linux-2.6.26.6/arch/x86/kernel/tlb_32.c 2008-10-11 21:54:19.000000000 -0400
9148 +@@ -5,7 +5,7 @@
9149 + #include <asm/tlbflush.h>
9150 +
9151 + DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
9152 +- ____cacheline_aligned = { &init_mm, 0, };
9153 ++ ____cacheline_aligned = { &init_mm, 0, {0} };
9154 +
9155 + /* must come after the send_IPI functions above for inlining */
9156 + #include <mach_ipi.h>
9157 +diff -urNp linux-2.6.26.6/arch/x86/kernel/tls.c linux-2.6.26.6/arch/x86/kernel/tls.c
9158 +--- linux-2.6.26.6/arch/x86/kernel/tls.c 2008-10-08 23:24:05.000000000 -0400
9159 ++++ linux-2.6.26.6/arch/x86/kernel/tls.c 2008-10-11 21:54:19.000000000 -0400
9160 +@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
9161 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
9162 + return -EINVAL;
9163 +
9164 ++#ifdef CONFIG_PAX_SEGMEXEC
9165 ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
9166 ++ return -EINVAL;
9167 ++#endif
9168 ++
9169 + set_tls_desc(p, idx, &info, 1);
9170 +
9171 + return 0;
9172 +diff -urNp linux-2.6.26.6/arch/x86/kernel/traps_32.c linux-2.6.26.6/arch/x86/kernel/traps_32.c
9173 +--- linux-2.6.26.6/arch/x86/kernel/traps_32.c 2008-10-08 23:24:05.000000000 -0400
9174 ++++ linux-2.6.26.6/arch/x86/kernel/traps_32.c 2008-10-11 21:55:07.000000000 -0400
9175 +@@ -70,14 +70,6 @@ asmlinkage int system_call(void);
9176 + /* Do we ignore FPU interrupts ? */
9177 + char ignore_fpu_irq;
9178 +
9179 +-/*
9180 +- * The IDT has to be page-aligned to simplify the Pentium
9181 +- * F0 0F bug workaround.. We have a special link segment
9182 +- * for this.
9183 +- */
9184 +-gate_desc idt_table[256]
9185 +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
9186 +-
9187 + asmlinkage void divide_error(void);
9188 + asmlinkage void debug(void);
9189 + asmlinkage void nmi(void);
9190 +@@ -339,22 +331,23 @@ void show_registers(struct pt_regs *regs
9191 + * When in-kernel, we also print out the stack and code at the
9192 + * time of the fault..
9193 + */
9194 +- if (!user_mode_vm(regs)) {
9195 ++ if (!user_mode(regs)) {
9196 + unsigned int code_prologue = code_bytes * 43 / 64;
9197 + unsigned int code_len = code_bytes;
9198 + unsigned char c;
9199 + u8 *ip;
9200 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
9201 +
9202 + printk("\n" KERN_EMERG "Stack: ");
9203 + show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
9204 +
9205 + printk(KERN_EMERG "Code: ");
9206 +
9207 +- ip = (u8 *)regs->ip - code_prologue;
9208 ++ ip = (u8 *)regs->ip - code_prologue + cs_base;
9209 + if (ip < (u8 *)PAGE_OFFSET ||
9210 + probe_kernel_address(ip, c)) {
9211 + /* try starting at EIP */
9212 +- ip = (u8 *)regs->ip;
9213 ++ ip = (u8 *)regs->ip + cs_base;
9214 + code_len = code_len - code_prologue + 1;
9215 + }
9216 + for (i = 0; i < code_len; i++, ip++) {
9217 +@@ -363,7 +356,7 @@ void show_registers(struct pt_regs *regs
9218 + printk(" Bad EIP value.");
9219 + break;
9220 + }
9221 +- if (ip == (u8 *)regs->ip)
9222 ++ if (ip == (u8 *)regs->ip + cs_base)
9223 + printk("<%02x> ", c);
9224 + else
9225 + printk("%02x ", c);
9226 +@@ -376,6 +369,7 @@ int is_valid_bugaddr(unsigned long ip)
9227 + {
9228 + unsigned short ud2;
9229 +
9230 ++ ip = ktla_ktva(ip);
9231 + if (ip < PAGE_OFFSET)
9232 + return 0;
9233 + if (probe_kernel_address((unsigned short *)ip, ud2))
9234 +@@ -488,7 +482,7 @@ void die(const char *str, struct pt_regs
9235 + static inline void
9236 + die_if_kernel(const char *str, struct pt_regs *regs, long err)
9237 + {
9238 +- if (!user_mode_vm(regs))
9239 ++ if (!user_mode(regs))
9240 + die(str, regs, err);
9241 + }
9242 +
9243 +@@ -498,7 +492,7 @@ do_trap(int trapnr, int signr, char *str
9244 + {
9245 + struct task_struct *tsk = current;
9246 +
9247 +- if (regs->flags & X86_VM_MASK) {
9248 ++ if (v8086_mode(regs)) {
9249 + if (vm86)
9250 + goto vm86_trap;
9251 + goto trap_signal;
9252 +@@ -532,6 +526,12 @@ kernel_trap:
9253 + tsk->thread.trap_no = trapnr;
9254 + die(str, regs, error_code);
9255 + }
9256 ++
9257 ++#ifdef CONFIG_PAX_REFCOUNT
9258 ++ if (trapnr == 4)
9259 ++ pax_report_refcount_overflow(regs);
9260 ++#endif
9261 ++
9262 + return;
9263 +
9264 + vm86_trap:
9265 +@@ -612,7 +612,7 @@ void __kprobes do_general_protection(str
9266 + int cpu;
9267 +
9268 + cpu = get_cpu();
9269 +- tss = &per_cpu(init_tss, cpu);
9270 ++ tss = init_tss + cpu;
9271 + thread = &current->thread;
9272 +
9273 + /*
9274 +@@ -644,12 +644,28 @@ void __kprobes do_general_protection(str
9275 + }
9276 + put_cpu();
9277 +
9278 +- if (regs->flags & X86_VM_MASK)
9279 ++ if (v8086_mode(regs))
9280 + goto gp_in_vm86;
9281 +
9282 +- if (!user_mode(regs))
9283 ++ if (!user_mode_novm(regs))
9284 + goto gp_in_kernel;
9285 +
9286 ++#ifdef CONFIG_PAX_PAGEEXEC
9287 ++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
9288 ++ struct mm_struct *mm = current->mm;
9289 ++ unsigned long limit;
9290 ++
9291 ++ down_write(&mm->mmap_sem);
9292 ++ limit = mm->context.user_cs_limit;
9293 ++ if (limit < TASK_SIZE) {
9294 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
9295 ++ up_write(&mm->mmap_sem);
9296 ++ return;
9297 ++ }
9298 ++ up_write(&mm->mmap_sem);
9299 ++ }
9300 ++#endif
9301 ++
9302 + current->thread.error_code = error_code;
9303 + current->thread.trap_no = 13;
9304 +
9305 +@@ -678,6 +694,13 @@ gp_in_kernel:
9306 + if (notify_die(DIE_GPF, "general protection fault", regs,
9307 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
9308 + return;
9309 ++
9310 ++#ifdef CONFIG_PAX_KERNEXEC
9311 ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
9312 ++ die("PAX: suspicious general protection fault", regs, error_code);
9313 ++ else
9314 ++#endif
9315 ++
9316 + die("general protection fault", regs, error_code);
9317 + }
9318 + }
9319 +@@ -779,7 +802,7 @@ void notrace __kprobes die_nmi(struct pt
9320 + * If we are in kernel we are probably nested up pretty bad
9321 + * and might aswell get out now while we still can:
9322 + */
9323 +- if (!user_mode_vm(regs)) {
9324 ++ if (!user_mode(regs)) {
9325 + current->thread.trap_no = 2;
9326 + crash_kexec(regs);
9327 + }
9328 +@@ -925,7 +948,7 @@ void __kprobes do_debug(struct pt_regs *
9329 + goto clear_dr7;
9330 + }
9331 +
9332 +- if (regs->flags & X86_VM_MASK)
9333 ++ if (v8086_mode(regs))
9334 + goto debug_vm86;
9335 +
9336 + /* Save debug status register where ptrace can see it */
9337 +@@ -941,7 +964,7 @@ void __kprobes do_debug(struct pt_regs *
9338 + * check for kernel mode by just checking the CPL
9339 + * of CS.
9340 + */
9341 +- if (!user_mode(regs))
9342 ++ if (!user_mode_novm(regs))
9343 + goto clear_TF_reenable;
9344 + }
9345 +
9346 +@@ -1097,7 +1120,7 @@ void do_simd_coprocessor_error(struct pt
9347 + * Handle strange cache flush from user space exception
9348 + * in all other cases. This is undocumented behaviour.
9349 + */
9350 +- if (regs->flags & X86_VM_MASK) {
9351 ++ if (v8086_mode(regs)) {
9352 + handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
9353 + return;
9354 + }
9355 +@@ -1117,19 +1140,14 @@ void do_spurious_interrupt_bug(struct pt
9356 +
9357 + unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
9358 + {
9359 +- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
9360 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
9361 + unsigned long new_kesp = kesp - base;
9362 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
9363 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
9364 ++ struct desc_struct ss;
9365 +
9366 + /* Set up base for espfix segment */
9367 +- desc &= 0x00f0ff0000000000ULL;
9368 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
9369 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
9370 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
9371 +- (lim_pages & 0xffff);
9372 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
9373 ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
9374 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
9375 +
9376 + return new_kesp;
9377 + }
9378 +diff -urNp linux-2.6.26.6/arch/x86/kernel/traps_64.c linux-2.6.26.6/arch/x86/kernel/traps_64.c
9379 +--- linux-2.6.26.6/arch/x86/kernel/traps_64.c 2008-10-08 23:24:05.000000000 -0400
9380 ++++ linux-2.6.26.6/arch/x86/kernel/traps_64.c 2008-10-11 21:54:19.000000000 -0400
9381 +@@ -669,6 +669,12 @@ static void __kprobes do_trap(int trapnr
9382 + tsk->thread.trap_no = trapnr;
9383 + die(str, regs, error_code);
9384 + }
9385 ++
9386 ++#ifdef CONFIG_PAX_REFCOUNT
9387 ++ if (trapnr == 4)
9388 ++ pax_report_refcount_overflow(regs);
9389 ++#endif
9390 ++
9391 + return;
9392 + }
9393 +
9394 +diff -urNp linux-2.6.26.6/arch/x86/kernel/tsc_32.c linux-2.6.26.6/arch/x86/kernel/tsc_32.c
9395 +--- linux-2.6.26.6/arch/x86/kernel/tsc_32.c 2008-10-08 23:24:05.000000000 -0400
9396 ++++ linux-2.6.26.6/arch/x86/kernel/tsc_32.c 2008-10-11 21:54:19.000000000 -0400
9397 +@@ -353,7 +353,7 @@ static struct dmi_system_id __initdata b
9398 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
9399 + },
9400 + },
9401 +- {}
9402 ++ { NULL, NULL, {{0, NULL}}, NULL}
9403 + };
9404 +
9405 + /*
9406 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vm86_32.c linux-2.6.26.6/arch/x86/kernel/vm86_32.c
9407 +--- linux-2.6.26.6/arch/x86/kernel/vm86_32.c 2008-10-08 23:24:05.000000000 -0400
9408 ++++ linux-2.6.26.6/arch/x86/kernel/vm86_32.c 2008-10-11 21:54:19.000000000 -0400
9409 +@@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
9410 + do_exit(SIGSEGV);
9411 + }
9412 +
9413 +- tss = &per_cpu(init_tss, get_cpu());
9414 ++ tss = init_tss + get_cpu();
9415 + current->thread.sp0 = current->thread.saved_sp0;
9416 + current->thread.sysenter_cs = __KERNEL_CS;
9417 + load_sp0(tss, &current->thread);
9418 +@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
9419 + tsk->thread.saved_fs = info->regs32->fs;
9420 + savesegment(gs, tsk->thread.saved_gs);
9421 +
9422 +- tss = &per_cpu(init_tss, get_cpu());
9423 ++ tss = init_tss + get_cpu();
9424 + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
9425 + if (cpu_has_sep)
9426 + tsk->thread.sysenter_cs = 0;
9427 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vmi_32.c linux-2.6.26.6/arch/x86/kernel/vmi_32.c
9428 +--- linux-2.6.26.6/arch/x86/kernel/vmi_32.c 2008-10-08 23:24:05.000000000 -0400
9429 ++++ linux-2.6.26.6/arch/x86/kernel/vmi_32.c 2008-10-11 21:54:19.000000000 -0400
9430 +@@ -101,18 +101,43 @@ static unsigned patch_internal(int call,
9431 + {
9432 + u64 reloc;
9433 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
9434 ++
9435 ++#ifdef CONFIG_PAX_KERNEXEC
9436 ++ unsigned long cr0;
9437 ++#endif
9438 ++
9439 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
9440 + switch(rel->type) {
9441 + case VMI_RELOCATION_CALL_REL:
9442 + BUG_ON(len < 5);
9443 ++
9444 ++#ifdef CONFIG_PAX_KERNEXEC
9445 ++ pax_open_kernel(cr0);
9446 ++#endif
9447 ++
9448 + *(char *)insnbuf = MNEM_CALL;
9449 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9450 ++
9451 ++#ifdef CONFIG_PAX_KERNEXEC
9452 ++ pax_close_kernel(cr0);
9453 ++#endif
9454 ++
9455 + return 5;
9456 +
9457 + case VMI_RELOCATION_JUMP_REL:
9458 + BUG_ON(len < 5);
9459 ++
9460 ++#ifdef CONFIG_PAX_KERNEXEC
9461 ++ pax_open_kernel(cr0);
9462 ++#endif
9463 ++
9464 + *(char *)insnbuf = MNEM_JMP;
9465 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
9466 ++
9467 ++#ifdef CONFIG_PAX_KERNEXEC
9468 ++ pax_close_kernel(cr0);
9469 ++#endif
9470 ++
9471 + return 5;
9472 +
9473 + case VMI_RELOCATION_NOP:
9474 +@@ -515,14 +540,14 @@ static void vmi_set_pud(pud_t *pudp, pud
9475 +
9476 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
9477 + {
9478 +- const pte_t pte = { .pte = 0 };
9479 ++ const pte_t pte = __pte(0ULL);
9480 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
9481 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
9482 + }
9483 +
9484 + static void vmi_pmd_clear(pmd_t *pmd)
9485 + {
9486 +- const pte_t pte = { .pte = 0 };
9487 ++ const pte_t pte = __pte(0ULL);
9488 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
9489 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
9490 + }
9491 +@@ -551,8 +576,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
9492 + ap.ss = __KERNEL_DS;
9493 + ap.esp = (unsigned long) start_esp;
9494 +
9495 +- ap.ds = __USER_DS;
9496 +- ap.es = __USER_DS;
9497 ++ ap.ds = __KERNEL_DS;
9498 ++ ap.es = __KERNEL_DS;
9499 + ap.fs = __KERNEL_PERCPU;
9500 + ap.gs = 0;
9501 +
9502 +@@ -747,12 +772,20 @@ static inline int __init activate_vmi(vo
9503 + u64 reloc;
9504 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
9505 +
9506 ++#ifdef CONFIG_PAX_KERNEXEC
9507 ++ unsigned long cr0;
9508 ++#endif
9509 ++
9510 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
9511 + printk(KERN_ERR "VMI ROM failed to initialize!");
9512 + return 0;
9513 + }
9514 + savesegment(cs, kernel_cs);
9515 +
9516 ++#ifdef CONFIG_PAX_KERNEXEC
9517 ++ pax_open_kernel(cr0);
9518 ++#endif
9519 ++
9520 + pv_info.paravirt_enabled = 1;
9521 + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
9522 + pv_info.name = "vmi";
9523 +@@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
9524 +
9525 + para_fill(pv_irq_ops.safe_halt, Halt);
9526 +
9527 ++#ifdef CONFIG_PAX_KERNEXEC
9528 ++ pax_close_kernel(cr0);
9529 ++#endif
9530 ++
9531 + /*
9532 + * Alternative instruction rewriting doesn't happen soon enough
9533 + * to convert VMI_IRET to a call instead of a jump; so we have
9534 +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
9535 +--- linux-2.6.26.6/arch/x86/kernel/vmlinux_32.lds.S 2008-10-08 23:24:05.000000000 -0400
9536 ++++ linux-2.6.26.6/arch/x86/kernel/vmlinux_32.lds.S 2008-10-11 21:54:19.000000000 -0400
9537 +@@ -15,6 +15,20 @@
9538 + #include <asm/page.h>
9539 + #include <asm/cache.h>
9540 + #include <asm/boot.h>
9541 ++#include <asm/segment.h>
9542 ++
9543 ++#ifdef CONFIG_X86_PAE
9544 ++#define PMD_SHIFT 21
9545 ++#else
9546 ++#define PMD_SHIFT 22
9547 ++#endif
9548 ++#define PMD_SIZE (1 << PMD_SHIFT)
9549 ++
9550 ++#ifdef CONFIG_PAX_KERNEXEC
9551 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
9552 ++#else
9553 ++#define __KERNEL_TEXT_OFFSET 0
9554 ++#endif
9555 +
9556 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
9557 + OUTPUT_ARCH(i386)
9558 +@@ -22,90 +36,23 @@ ENTRY(phys_startup_32)
9559 + jiffies = jiffies_64;
9560 +
9561 + PHDRS {
9562 +- text PT_LOAD FLAGS(5); /* R_E */
9563 +- data PT_LOAD FLAGS(7); /* RWE */
9564 +- note PT_NOTE FLAGS(0); /* ___ */
9565 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
9566 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
9567 ++ inittext PT_LOAD FLAGS(5); /* R_E */
9568 ++ text PT_LOAD FLAGS(5); /* R_E */
9569 ++ rodata PT_LOAD FLAGS(4); /* R__ */
9570 ++ data PT_LOAD FLAGS(6); /* RW_ */
9571 ++ note PT_NOTE FLAGS(0); /* ___ */
9572 + }
9573 + SECTIONS
9574 + {
9575 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
9576 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
9577 +-
9578 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
9579 +- _text = .; /* Text and read-only data */
9580 +- *(.text.head)
9581 +- } :text = 0x9090
9582 +-
9583 +- /* read-only */
9584 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
9585 +- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
9586 +- *(.text.page_aligned)
9587 +- TEXT_TEXT
9588 +- SCHED_TEXT
9589 +- LOCK_TEXT
9590 +- KPROBES_TEXT
9591 +- *(.fixup)
9592 +- *(.gnu.warning)
9593 +- _etext = .; /* End of text section */
9594 +- } :text = 0x9090
9595 +-
9596 +- . = ALIGN(16); /* Exception table */
9597 +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
9598 +- __start___ex_table = .;
9599 +- *(__ex_table)
9600 +- __stop___ex_table = .;
9601 +- }
9602 +-
9603 +- NOTES :text :note
9604 +-
9605 +- BUG_TABLE :text
9606 +-
9607 +- . = ALIGN(4);
9608 +- .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
9609 +- __tracedata_start = .;
9610 +- *(.tracedata)
9611 +- __tracedata_end = .;
9612 +- }
9613 ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
9614 +
9615 +- RODATA
9616 +-
9617 +- /* writeable */
9618 +- . = ALIGN(PAGE_SIZE);
9619 +- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
9620 +- DATA_DATA
9621 +- CONSTRUCTORS
9622 +- } :data
9623 +-
9624 +- . = ALIGN(PAGE_SIZE);
9625 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
9626 +- __nosave_begin = .;
9627 +- *(.data.nosave)
9628 +- . = ALIGN(PAGE_SIZE);
9629 +- __nosave_end = .;
9630 +- }
9631 +-
9632 +- . = ALIGN(PAGE_SIZE);
9633 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9634 +- *(.data.page_aligned)
9635 +- *(.data.idt)
9636 +- }
9637 +-
9638 +- . = ALIGN(32);
9639 +- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
9640 +- *(.data.cacheline_aligned)
9641 +- }
9642 +-
9643 +- /* rarely changed data like cpu maps */
9644 +- . = ALIGN(32);
9645 +- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
9646 +- *(.data.read_mostly)
9647 +- _edata = .; /* End of data section */
9648 +- }
9649 +-
9650 +- . = ALIGN(THREAD_SIZE); /* init_task */
9651 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9652 +- *(.data.init_task)
9653 +- }
9654 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
9655 ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
9656 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
9657 ++ *(.text.startup)
9658 ++ } :initdata
9659 +
9660 + /* might get freed after init */
9661 + . = ALIGN(PAGE_SIZE);
9662 +@@ -123,14 +70,8 @@ SECTIONS
9663 + . = ALIGN(PAGE_SIZE);
9664 +
9665 + /* will be freed after init */
9666 +- . = ALIGN(PAGE_SIZE); /* Init code and data */
9667 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
9668 +- __init_begin = .;
9669 +- _sinittext = .;
9670 +- INIT_TEXT
9671 +- _einittext = .;
9672 +- }
9673 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
9674 ++ __init_begin = .;
9675 + INIT_DATA
9676 + }
9677 + . = ALIGN(16);
9678 +@@ -170,11 +111,6 @@ SECTIONS
9679 + *(.parainstructions)
9680 + __parainstructions_end = .;
9681 + }
9682 +- /* .exit.text is discard at runtime, not link time, to deal with references
9683 +- from .altinstructions and .eh_frame */
9684 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
9685 +- EXIT_TEXT
9686 +- }
9687 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
9688 + EXIT_DATA
9689 + }
9690 +@@ -187,17 +123,144 @@ SECTIONS
9691 + }
9692 + #endif
9693 + . = ALIGN(PAGE_SIZE);
9694 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
9695 +- __per_cpu_start = .;
9696 ++ per_cpu_start = .;
9697 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
9698 ++ __per_cpu_start = . + per_cpu_start;
9699 ++ LONG(0)
9700 + *(.data.percpu)
9701 + *(.data.percpu.shared_aligned)
9702 +- __per_cpu_end = .;
9703 +- }
9704 ++ __per_cpu_end = . + per_cpu_start;
9705 ++ } :percpu
9706 ++ . += per_cpu_start;
9707 + . = ALIGN(PAGE_SIZE);
9708 + /* freed after init ends here */
9709 +
9710 ++ . = ALIGN(PAGE_SIZE); /* Init code and data */
9711 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9712 ++ _sinittext = .;
9713 ++ INIT_TEXT
9714 ++ _einittext = .;
9715 ++ } :inittext
9716 ++
9717 ++ /* .exit.text is discard at runtime, not link time, to deal with references
9718 ++ from .altinstructions and .eh_frame */
9719 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9720 ++ EXIT_TEXT
9721 ++ }
9722 ++
9723 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9724 ++ BYTE(0)
9725 ++ . = ALIGN(2*PMD_SIZE) - 1;
9726 ++ }
9727 ++
9728 ++ /* freed after init ends here */
9729 ++
9730 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9731 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
9732 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
9733 ++ _text = .; /* Text and read-only data */
9734 ++ *(.text.head)
9735 ++ } :text = 0x9090
9736 ++
9737 ++ /* read-only */
9738 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
9739 ++ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
9740 ++ *(.text.page_aligned)
9741 ++ TEXT_TEXT
9742 ++ SCHED_TEXT
9743 ++ LOCK_TEXT
9744 ++ KPROBES_TEXT
9745 ++ *(.fixup)
9746 ++ *(.gnu.warning)
9747 ++ _etext = .; /* End of text section */
9748 ++ } :text = 0x9090
9749 ++
9750 ++ . += __KERNEL_TEXT_OFFSET;
9751 ++ . = ALIGN(4096); /* Exception table */
9752 ++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
9753 ++ __start___ex_table = .;
9754 ++ *(__ex_table)
9755 ++ __stop___ex_table = .;
9756 ++ } :rodata
9757 ++
9758 ++ NOTES :rodata :note
9759 ++
9760 ++ BUG_TABLE :rodata
9761 ++
9762 ++ . = ALIGN(4);
9763 ++ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
9764 ++ __tracedata_start = .;
9765 ++ *(.tracedata)
9766 ++ __tracedata_end = .;
9767 ++ }
9768 ++
9769 ++ RO_DATA(PAGE_SIZE)
9770 ++
9771 ++ . = ALIGN(PAGE_SIZE);
9772 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
9773 ++ *(.idt)
9774 ++ . = ALIGN(PAGE_SIZE);
9775 ++ *(.empty_zero_page)
9776 ++ *(.swapper_pg_pmd)
9777 ++ *(.swapper_pg_dir)
9778 ++ }
9779 ++
9780 ++#ifdef CONFIG_PAX_KERNEXEC
9781 ++
9782 ++#ifdef CONFIG_MODULES
9783 ++ . = ALIGN(PAGE_SIZE);
9784 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
9785 ++ MODULES_VADDR = .;
9786 ++ BYTE(0)
9787 ++ . += (6 * 1024 * 1024);
9788 ++ . = ALIGN( PMD_SIZE) - 1;
9789 ++ MODULES_END = .;
9790 ++ }
9791 ++#else
9792 ++ . = ALIGN(PMD_SIZE) - 1;
9793 ++#endif
9794 ++
9795 ++#endif
9796 ++
9797 ++ /* writeable */
9798 ++ . = ALIGN(PAGE_SIZE);
9799 ++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
9800 ++ _data = .;
9801 ++ DATA_DATA
9802 ++ CONSTRUCTORS
9803 ++ } :data
9804 ++
9805 ++ . = ALIGN(PAGE_SIZE);
9806 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
9807 ++ __nosave_begin = .;
9808 ++ *(.data.nosave)
9809 ++ . = ALIGN(PAGE_SIZE);
9810 ++ __nosave_end = .;
9811 ++ }
9812 ++
9813 ++ . = ALIGN(PAGE_SIZE);
9814 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9815 ++ *(.data.page_aligned)
9816 ++ }
9817 ++
9818 ++ . = ALIGN(32);
9819 ++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
9820 ++ *(.data.cacheline_aligned)
9821 ++ }
9822 ++
9823 ++ /* rarely changed data like cpu maps */
9824 ++ . = ALIGN(32);
9825 ++ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
9826 ++ *(.data.read_mostly)
9827 ++ _edata = .; /* End of data section */
9828 ++ }
9829 ++
9830 ++ . = ALIGN(THREAD_SIZE); /* init_task */
9831 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9832 ++ *(.data.init_task)
9833 ++ }
9834 ++
9835 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
9836 +- __init_end = .;
9837 + __bss_start = .; /* BSS */
9838 + *(.bss.page_aligned)
9839 + *(.bss)
9840 +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
9841 +--- linux-2.6.26.6/arch/x86/kernel/vmlinux_64.lds.S 2008-10-08 23:24:05.000000000 -0400
9842 ++++ linux-2.6.26.6/arch/x86/kernel/vmlinux_64.lds.S 2008-10-11 21:54:19.000000000 -0400
9843 +@@ -16,8 +16,8 @@ jiffies_64 = jiffies;
9844 + _proxy_pda = 1;
9845 + PHDRS {
9846 + text PT_LOAD FLAGS(5); /* R_E */
9847 +- data PT_LOAD FLAGS(7); /* RWE */
9848 +- user PT_LOAD FLAGS(7); /* RWE */
9849 ++ data PT_LOAD FLAGS(6); /* RW_ */
9850 ++ user PT_LOAD FLAGS(7); /* RWX */
9851 + data.init PT_LOAD FLAGS(7); /* RWE */
9852 + note PT_NOTE FLAGS(4); /* R__ */
9853 + }
9854 +@@ -51,7 +51,7 @@ SECTIONS
9855 +
9856 + BUG_TABLE :text
9857 +
9858 +- RODATA
9859 ++ RO_DATA(PAGE_SIZE)
9860 +
9861 + . = ALIGN(4);
9862 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
9863 +@@ -60,15 +60,18 @@ SECTIONS
9864 + __tracedata_end = .;
9865 + }
9866 +
9867 ++#ifdef CONFIG_PAX_KERNEXEC
9868 ++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
9869 ++#else
9870 + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
9871 ++#endif
9872 + /* Data */
9873 ++ _data = .;
9874 + .data : AT(ADDR(.data) - LOAD_OFFSET) {
9875 + DATA_DATA
9876 + CONSTRUCTORS
9877 + } :data
9878 +
9879 +- _edata = .; /* End of data section */
9880 +-
9881 + . = ALIGN(PAGE_SIZE);
9882 + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
9883 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
9884 +@@ -79,9 +82,27 @@ SECTIONS
9885 + *(.data.read_mostly)
9886 + }
9887 +
9888 ++ . = ALIGN(THREAD_SIZE); /* init_task */
9889 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9890 ++ *(.data.init_task)
9891 ++ }
9892 ++
9893 ++ . = ALIGN(PAGE_SIZE);
9894 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9895 ++ *(.data.page_aligned)
9896 ++ }
9897 ++
9898 ++ . = ALIGN(PAGE_SIZE);
9899 ++ __nosave_begin = .;
9900 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
9901 ++ . = ALIGN(PAGE_SIZE);
9902 ++ __nosave_end = .;
9903 ++
9904 ++ _edata = .; /* End of data section */
9905 ++
9906 + #define VSYSCALL_ADDR (-10*1024*1024)
9907 +-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
9908 +-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
9909 ++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
9910 ++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
9911 +
9912 + #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
9913 + #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
9914 +@@ -129,23 +150,13 @@ SECTIONS
9915 + #undef VVIRT_OFFSET
9916 + #undef VVIRT
9917 +
9918 +- . = ALIGN(THREAD_SIZE); /* init_task */
9919 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
9920 +- *(.data.init_task)
9921 +- }:data.init
9922 +-
9923 +- . = ALIGN(PAGE_SIZE);
9924 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
9925 +- *(.data.page_aligned)
9926 +- }
9927 +-
9928 + /* might get freed after init */
9929 + . = ALIGN(PAGE_SIZE);
9930 + __smp_alt_begin = .;
9931 + __smp_locks = .;
9932 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
9933 + *(.smp_locks)
9934 +- }
9935 ++ } :data.init
9936 + __smp_locks_end = .;
9937 + . = ALIGN(PAGE_SIZE);
9938 + __smp_alt_end = .;
9939 +@@ -221,12 +232,6 @@ SECTIONS
9940 + . = ALIGN(PAGE_SIZE);
9941 + __init_end = .;
9942 +
9943 +- . = ALIGN(PAGE_SIZE);
9944 +- __nosave_begin = .;
9945 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
9946 +- . = ALIGN(PAGE_SIZE);
9947 +- __nosave_end = .;
9948 +-
9949 + __bss_start = .; /* BSS */
9950 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
9951 + *(.bss.page_aligned)
9952 +@@ -234,6 +239,7 @@ SECTIONS
9953 + }
9954 + __bss_stop = .;
9955 +
9956 ++ . = ALIGN(2*1024*1024);
9957 + _end = . ;
9958 +
9959 + /* Sections to be discarded */
9960 +diff -urNp linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c
9961 +--- linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c 2008-10-08 23:24:05.000000000 -0400
9962 ++++ linux-2.6.26.6/arch/x86/kernel/vsyscall_64.c 2008-10-11 21:54:19.000000000 -0400
9963 +@@ -235,13 +235,13 @@ static ctl_table kernel_table2[] = {
9964 + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
9965 + .mode = 0644,
9966 + .proc_handler = vsyscall_sysctl_change },
9967 +- {}
9968 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
9969 + };
9970 +
9971 + static ctl_table kernel_root_table2[] = {
9972 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
9973 + .child = kernel_table2 },
9974 +- {}
9975 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
9976 + };
9977 + #endif
9978 +
9979 +@@ -251,6 +251,11 @@ static void __cpuinit vsyscall_set_cpu(i
9980 + {
9981 + unsigned long *d;
9982 + unsigned long node = 0;
9983 ++
9984 ++#ifdef CONFIG_PAX_KERNEXEC
9985 ++ unsigned long cr0;
9986 ++#endif
9987 ++
9988 + #ifdef CONFIG_NUMA
9989 + node = cpu_to_node(cpu);
9990 + #endif
9991 +@@ -261,10 +266,20 @@ static void __cpuinit vsyscall_set_cpu(i
9992 + in user space in vgetcpu.
9993 + 12 bits for the CPU and 8 bits for the node. */
9994 + d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU);
9995 ++
9996 ++#ifdef CONFIG_PAX_KERNEXEC
9997 ++ pax_open_kernel(cr0);
9998 ++#endif
9999 ++
10000 + *d = 0x0f40000000000ULL;
10001 + *d |= cpu;
10002 + *d |= (node & 0xf) << 12;
10003 + *d |= (node >> 4) << 48;
10004 ++
10005 ++#ifdef CONFIG_PAX_KERNEXEC
10006 ++ pax_close_kernel(cr0);
10007 ++#endif
10008 ++
10009 + }
10010 +
10011 + static void __cpuinit cpu_vsyscall_init(void *arg)
10012 +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
10013 +--- linux-2.6.26.6/arch/x86/kernel/x8664_ksyms_64.c 2008-10-08 23:24:05.000000000 -0400
10014 ++++ linux-2.6.26.6/arch/x86/kernel/x8664_ksyms_64.c 2008-10-11 21:54:19.000000000 -0400
10015 +@@ -53,8 +53,3 @@ EXPORT_SYMBOL(init_level4_pgt);
10016 + EXPORT_SYMBOL(load_gs_index);
10017 +
10018 + EXPORT_SYMBOL(_proxy_pda);
10019 +-
10020 +-#ifdef CONFIG_PARAVIRT
10021 +-/* Virtualized guests may want to use it */
10022 +-EXPORT_SYMBOL_GPL(cpu_gdt_descr);
10023 +-#endif
10024 +diff -urNp linux-2.6.26.6/arch/x86/kvm/i8254.c linux-2.6.26.6/arch/x86/kvm/i8254.c
10025 +--- linux-2.6.26.6/arch/x86/kvm/i8254.c 2008-10-08 23:24:05.000000000 -0400
10026 ++++ linux-2.6.26.6/arch/x86/kvm/i8254.c 2008-10-11 21:55:52.000000000 -0400
10027 +@@ -91,7 +91,7 @@ static void pit_set_gate(struct kvm *kvm
10028 + c->gate = val;
10029 + }
10030 +
10031 +-int pit_get_gate(struct kvm *kvm, int channel)
10032 ++static int pit_get_gate(struct kvm *kvm, int channel)
10033 + {
10034 + WARN_ON(!mutex_is_locked(&kvm->arch.vpit->pit_state.lock));
10035 +
10036 +@@ -193,7 +193,7 @@ static void pit_latch_status(struct kvm
10037 + }
10038 + }
10039 +
10040 +-int __pit_timer_fn(struct kvm_kpit_state *ps)
10041 ++static int __pit_timer_fn(struct kvm_kpit_state *ps)
10042 + {
10043 + struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0];
10044 + struct kvm_kpit_timer *pt = &ps->pit_timer;
10045 +@@ -575,7 +575,7 @@ void kvm_free_pit(struct kvm *kvm)
10046 + }
10047 + }
10048 +
10049 +-void __inject_pit_timer_intr(struct kvm *kvm)
10050 ++static void __inject_pit_timer_intr(struct kvm *kvm)
10051 + {
10052 + mutex_lock(&kvm->lock);
10053 + kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 1);
10054 +diff -urNp linux-2.6.26.6/arch/x86/kvm/mmu.c linux-2.6.26.6/arch/x86/kvm/mmu.c
10055 +--- linux-2.6.26.6/arch/x86/kvm/mmu.c 2008-10-08 23:24:05.000000000 -0400
10056 ++++ linux-2.6.26.6/arch/x86/kvm/mmu.c 2008-10-11 21:55:52.000000000 -0400
10057 +@@ -1950,7 +1950,7 @@ void kvm_mmu_zap_all(struct kvm *kvm)
10058 + kvm_flush_remote_tlbs(kvm);
10059 + }
10060 +
10061 +-void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm)
10062 ++static void kvm_mmu_remove_one_alloc_mmu_page(struct kvm *kvm)
10063 + {
10064 + struct kvm_mmu_page *page;
10065 +
10066 +diff -urNp linux-2.6.26.6/arch/x86/kvm/svm.c linux-2.6.26.6/arch/x86/kvm/svm.c
10067 +--- linux-2.6.26.6/arch/x86/kvm/svm.c 2008-10-08 23:24:05.000000000 -0400
10068 ++++ linux-2.6.26.6/arch/x86/kvm/svm.c 2008-10-11 21:54:19.000000000 -0400
10069 +@@ -1478,7 +1478,19 @@ static void reload_tss(struct kvm_vcpu *
10070 + int cpu = raw_smp_processor_id();
10071 +
10072 + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
10073 ++
10074 ++#ifdef CONFIG_PAX_KERNEXEC
10075 ++ unsigned long cr0;
10076 ++
10077 ++ pax_open_kernel(cr0);
10078 ++#endif
10079 ++
10080 + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
10081 ++
10082 ++#ifdef CONFIG_PAX_KERNEXEC
10083 ++ pax_close_kernel(cr0);
10084 ++#endif
10085 ++
10086 + load_TR_desc();
10087 + }
10088 +
10089 +diff -urNp linux-2.6.26.6/arch/x86/kvm/vmx.c linux-2.6.26.6/arch/x86/kvm/vmx.c
10090 +--- linux-2.6.26.6/arch/x86/kvm/vmx.c 2008-10-08 23:24:05.000000000 -0400
10091 ++++ linux-2.6.26.6/arch/x86/kvm/vmx.c 2008-10-11 21:55:52.000000000 -0400
10092 +@@ -111,7 +111,7 @@ static struct vmcs_config {
10093 + u32 vmentry_ctrl;
10094 + } vmcs_config;
10095 +
10096 +-struct vmx_capability {
10097 ++static struct vmx_capability {
10098 + u32 ept;
10099 + u32 vpid;
10100 + } vmx_capability;
10101 +@@ -475,9 +475,23 @@ static void reload_tss(void)
10102 + struct descriptor_table gdt;
10103 + struct desc_struct *descs;
10104 +
10105 ++#ifdef CONFIG_PAX_KERNEXEC
10106 ++ unsigned long cr0;
10107 ++#endif
10108 ++
10109 + get_gdt(&gdt);
10110 + descs = (void *)gdt.base;
10111 ++
10112 ++#ifdef CONFIG_PAX_KERNEXEC
10113 ++ pax_open_kernel(cr0);
10114 ++#endif
10115 ++
10116 + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
10117 ++
10118 ++#ifdef CONFIG_PAX_KERNEXEC
10119 ++ pax_close_kernel(cr0);
10120 ++#endif
10121 ++
10122 + load_TR_desc();
10123 + }
10124 +
10125 +@@ -1824,7 +1838,7 @@ static void allocate_vpid(struct vcpu_vm
10126 + spin_unlock(&vmx_vpid_lock);
10127 + }
10128 +
10129 +-void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
10130 ++static void vmx_disable_intercept_for_msr(struct page *msr_bitmap, u32 msr)
10131 + {
10132 + void *va;
10133 +
10134 +@@ -2956,7 +2970,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
10135 + vcpu->arch.interrupt_window_open =
10136 + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
10137 +
10138 +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
10139 ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
10140 + vmx->launched = 1;
10141 +
10142 + intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
10143 +diff -urNp linux-2.6.26.6/arch/x86/kvm/x86.c linux-2.6.26.6/arch/x86/kvm/x86.c
10144 +--- linux-2.6.26.6/arch/x86/kvm/x86.c 2008-10-08 23:24:05.000000000 -0400
10145 ++++ linux-2.6.26.6/arch/x86/kvm/x86.c 2008-10-11 21:55:52.000000000 -0400
10146 +@@ -63,34 +63,34 @@ static int kvm_dev_ioctl_get_supported_c
10147 + struct kvm_x86_ops *kvm_x86_ops;
10148 +
10149 + struct kvm_stats_debugfs_item debugfs_entries[] = {
10150 +- { "pf_fixed", VCPU_STAT(pf_fixed) },
10151 +- { "pf_guest", VCPU_STAT(pf_guest) },
10152 +- { "tlb_flush", VCPU_STAT(tlb_flush) },
10153 +- { "invlpg", VCPU_STAT(invlpg) },
10154 +- { "exits", VCPU_STAT(exits) },
10155 +- { "io_exits", VCPU_STAT(io_exits) },
10156 +- { "mmio_exits", VCPU_STAT(mmio_exits) },
10157 +- { "signal_exits", VCPU_STAT(signal_exits) },
10158 +- { "irq_window", VCPU_STAT(irq_window_exits) },
10159 +- { "halt_exits", VCPU_STAT(halt_exits) },
10160 +- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
10161 +- { "hypercalls", VCPU_STAT(hypercalls) },
10162 +- { "request_irq", VCPU_STAT(request_irq_exits) },
10163 +- { "irq_exits", VCPU_STAT(irq_exits) },
10164 +- { "host_state_reload", VCPU_STAT(host_state_reload) },
10165 +- { "efer_reload", VCPU_STAT(efer_reload) },
10166 +- { "fpu_reload", VCPU_STAT(fpu_reload) },
10167 +- { "insn_emulation", VCPU_STAT(insn_emulation) },
10168 +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
10169 +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
10170 +- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
10171 +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
10172 +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
10173 +- { "mmu_flooded", VM_STAT(mmu_flooded) },
10174 +- { "mmu_recycled", VM_STAT(mmu_recycled) },
10175 +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
10176 +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
10177 +- { "largepages", VM_STAT(lpages) },
10178 ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
10179 ++ { "pf_guest", VCPU_STAT(pf_guest), NULL },
10180 ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
10181 ++ { "invlpg", VCPU_STAT(invlpg), NULL },
10182 ++ { "exits", VCPU_STAT(exits), NULL },
10183 ++ { "io_exits", VCPU_STAT(io_exits), NULL },
10184 ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
10185 ++ { "signal_exits", VCPU_STAT(signal_exits), NULL },
10186 ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
10187 ++ { "halt_exits", VCPU_STAT(halt_exits), NULL },
10188 ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
10189 ++ { "hypercalls", VCPU_STAT(hypercalls), NULL },
10190 ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
10191 ++ { "irq_exits", VCPU_STAT(irq_exits), NULL },
10192 ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
10193 ++ { "efer_reload", VCPU_STAT(efer_reload), NULL },
10194 ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
10195 ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
10196 ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
10197 ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
10198 ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
10199 ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
10200 ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
10201 ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
10202 ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
10203 ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
10204 ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
10205 ++ { "largepages", VM_STAT(lpages), NULL },
10206 + { NULL }
10207 + };
10208 +
10209 +@@ -1254,7 +1254,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
10210 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
10211 + struct kvm_interrupt *irq)
10212 + {
10213 +- if (irq->irq < 0 || irq->irq >= 256)
10214 ++ if (irq->irq >= 256)
10215 + return -EINVAL;
10216 + if (irqchip_in_kernel(vcpu->kvm))
10217 + return -ENXIO;
10218 +@@ -3411,7 +3411,7 @@ static int load_state_from_tss16(struct
10219 + return 0;
10220 + }
10221 +
10222 +-int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
10223 ++static int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
10224 + u32 old_tss_base,
10225 + struct desc_struct *nseg_desc)
10226 + {
10227 +@@ -3440,7 +3440,7 @@ out:
10228 + return ret;
10229 + }
10230 +
10231 +-int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
10232 ++static int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
10233 + u32 old_tss_base,
10234 + struct desc_struct *nseg_desc)
10235 + {
10236 +diff -urNp linux-2.6.26.6/arch/x86/lib/checksum_32.S linux-2.6.26.6/arch/x86/lib/checksum_32.S
10237 +--- linux-2.6.26.6/arch/x86/lib/checksum_32.S 2008-10-08 23:24:05.000000000 -0400
10238 ++++ linux-2.6.26.6/arch/x86/lib/checksum_32.S 2008-10-11 21:54:19.000000000 -0400
10239 +@@ -28,7 +28,8 @@
10240 + #include <linux/linkage.h>
10241 + #include <asm/dwarf2.h>
10242 + #include <asm/errno.h>
10243 +-
10244 ++#include <asm/segment.h>
10245 ++
10246 + /*
10247 + * computes a partial checksum, e.g. for TCP/UDP fragments
10248 + */
10249 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
10250 +
10251 + #define ARGBASE 16
10252 + #define FP 12
10253 +-
10254 +-ENTRY(csum_partial_copy_generic)
10255 ++
10256 ++ENTRY(csum_partial_copy_generic_to_user)
10257 + CFI_STARTPROC
10258 ++ pushl $(__USER_DS)
10259 ++ CFI_ADJUST_CFA_OFFSET 4
10260 ++ popl %es
10261 ++ CFI_ADJUST_CFA_OFFSET -4
10262 ++ jmp csum_partial_copy_generic
10263 ++
10264 ++ENTRY(csum_partial_copy_generic_from_user)
10265 ++ pushl $(__USER_DS)
10266 ++ CFI_ADJUST_CFA_OFFSET 4
10267 ++ popl %ds
10268 ++ CFI_ADJUST_CFA_OFFSET -4
10269 ++
10270 ++ENTRY(csum_partial_copy_generic)
10271 + subl $4,%esp
10272 + CFI_ADJUST_CFA_OFFSET 4
10273 + pushl %edi
10274 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
10275 + jmp 4f
10276 + SRC(1: movw (%esi), %bx )
10277 + addl $2, %esi
10278 +-DST( movw %bx, (%edi) )
10279 ++DST( movw %bx, %es:(%edi) )
10280 + addl $2, %edi
10281 + addw %bx, %ax
10282 + adcl $0, %eax
10283 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
10284 + SRC(1: movl (%esi), %ebx )
10285 + SRC( movl 4(%esi), %edx )
10286 + adcl %ebx, %eax
10287 +-DST( movl %ebx, (%edi) )
10288 ++DST( movl %ebx, %es:(%edi) )
10289 + adcl %edx, %eax
10290 +-DST( movl %edx, 4(%edi) )
10291 ++DST( movl %edx, %es:4(%edi) )
10292 +
10293 + SRC( movl 8(%esi), %ebx )
10294 + SRC( movl 12(%esi), %edx )
10295 + adcl %ebx, %eax
10296 +-DST( movl %ebx, 8(%edi) )
10297 ++DST( movl %ebx, %es:8(%edi) )
10298 + adcl %edx, %eax
10299 +-DST( movl %edx, 12(%edi) )
10300 ++DST( movl %edx, %es:12(%edi) )
10301 +
10302 + SRC( movl 16(%esi), %ebx )
10303 + SRC( movl 20(%esi), %edx )
10304 + adcl %ebx, %eax
10305 +-DST( movl %ebx, 16(%edi) )
10306 ++DST( movl %ebx, %es:16(%edi) )
10307 + adcl %edx, %eax
10308 +-DST( movl %edx, 20(%edi) )
10309 ++DST( movl %edx, %es:20(%edi) )
10310 +
10311 + SRC( movl 24(%esi), %ebx )
10312 + SRC( movl 28(%esi), %edx )
10313 + adcl %ebx, %eax
10314 +-DST( movl %ebx, 24(%edi) )
10315 ++DST( movl %ebx, %es:24(%edi) )
10316 + adcl %edx, %eax
10317 +-DST( movl %edx, 28(%edi) )
10318 ++DST( movl %edx, %es:28(%edi) )
10319 +
10320 + lea 32(%esi), %esi
10321 + lea 32(%edi), %edi
10322 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
10323 + shrl $2, %edx # This clears CF
10324 + SRC(3: movl (%esi), %ebx )
10325 + adcl %ebx, %eax
10326 +-DST( movl %ebx, (%edi) )
10327 ++DST( movl %ebx, %es:(%edi) )
10328 + lea 4(%esi), %esi
10329 + lea 4(%edi), %edi
10330 + dec %edx
10331 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
10332 + jb 5f
10333 + SRC( movw (%esi), %cx )
10334 + leal 2(%esi), %esi
10335 +-DST( movw %cx, (%edi) )
10336 ++DST( movw %cx, %es:(%edi) )
10337 + leal 2(%edi), %edi
10338 + je 6f
10339 + shll $16,%ecx
10340 + SRC(5: movb (%esi), %cl )
10341 +-DST( movb %cl, (%edi) )
10342 ++DST( movb %cl, %es:(%edi) )
10343 + 6: addl %ecx, %eax
10344 + adcl $0, %eax
10345 + 7:
10346 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
10347 +
10348 + 6001:
10349 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
10350 +- movl $-EFAULT, (%ebx)
10351 ++ movl $-EFAULT, %ss:(%ebx)
10352 +
10353 + # zero the complete destination - computing the rest
10354 + # is too much work
10355 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
10356 +
10357 + 6002:
10358 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10359 +- movl $-EFAULT,(%ebx)
10360 ++ movl $-EFAULT,%ss:(%ebx)
10361 + jmp 5000b
10362 +
10363 + .previous
10364 +
10365 ++ pushl %ss
10366 ++ CFI_ADJUST_CFA_OFFSET 4
10367 ++ popl %ds
10368 ++ CFI_ADJUST_CFA_OFFSET -4
10369 ++ pushl %ss
10370 ++ CFI_ADJUST_CFA_OFFSET 4
10371 ++ popl %es
10372 ++ CFI_ADJUST_CFA_OFFSET -4
10373 + popl %ebx
10374 + CFI_ADJUST_CFA_OFFSET -4
10375 + CFI_RESTORE ebx
10376 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
10377 + CFI_ADJUST_CFA_OFFSET -4
10378 + ret
10379 + CFI_ENDPROC
10380 +-ENDPROC(csum_partial_copy_generic)
10381 ++ENDPROC(csum_partial_copy_generic_to_user)
10382 +
10383 + #else
10384 +
10385 + /* Version for PentiumII/PPro */
10386 +
10387 + #define ROUND1(x) \
10388 ++ nop; nop; nop; \
10389 + SRC(movl x(%esi), %ebx ) ; \
10390 + addl %ebx, %eax ; \
10391 +- DST(movl %ebx, x(%edi) ) ;
10392 ++ DST(movl %ebx, %es:x(%edi)) ;
10393 +
10394 + #define ROUND(x) \
10395 ++ nop; nop; nop; \
10396 + SRC(movl x(%esi), %ebx ) ; \
10397 + adcl %ebx, %eax ; \
10398 +- DST(movl %ebx, x(%edi) ) ;
10399 ++ DST(movl %ebx, %es:x(%edi)) ;
10400 +
10401 + #define ARGBASE 12
10402 +-
10403 +-ENTRY(csum_partial_copy_generic)
10404 ++
10405 ++ENTRY(csum_partial_copy_generic_to_user)
10406 + CFI_STARTPROC
10407 ++ pushl $(__USER_DS)
10408 ++ CFI_ADJUST_CFA_OFFSET 4
10409 ++ popl %es
10410 ++ CFI_ADJUST_CFA_OFFSET -4
10411 ++ jmp csum_partial_copy_generic
10412 ++
10413 ++ENTRY(csum_partial_copy_generic_from_user)
10414 ++ pushl $(__USER_DS)
10415 ++ CFI_ADJUST_CFA_OFFSET 4
10416 ++ popl %ds
10417 ++ CFI_ADJUST_CFA_OFFSET -4
10418 ++
10419 ++ENTRY(csum_partial_copy_generic)
10420 + pushl %ebx
10421 + CFI_ADJUST_CFA_OFFSET 4
10422 + CFI_REL_OFFSET ebx, 0
10423 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
10424 + subl %ebx, %edi
10425 + lea -1(%esi),%edx
10426 + andl $-32,%edx
10427 +- lea 3f(%ebx,%ebx), %ebx
10428 ++ lea 3f(%ebx,%ebx,2), %ebx
10429 + testl %esi, %esi
10430 + jmp *%ebx
10431 + 1: addl $64,%esi
10432 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
10433 + jb 5f
10434 + SRC( movw (%esi), %dx )
10435 + leal 2(%esi), %esi
10436 +-DST( movw %dx, (%edi) )
10437 ++DST( movw %dx, %es:(%edi) )
10438 + leal 2(%edi), %edi
10439 + je 6f
10440 + shll $16,%edx
10441 + 5:
10442 + SRC( movb (%esi), %dl )
10443 +-DST( movb %dl, (%edi) )
10444 ++DST( movb %dl, %es:(%edi) )
10445 + 6: addl %edx, %eax
10446 + adcl $0, %eax
10447 + 7:
10448 + .section .fixup, "ax"
10449 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
10450 +- movl $-EFAULT, (%ebx)
10451 ++ movl $-EFAULT, %ss:(%ebx)
10452 + # zero the complete destination (computing the rest is too much work)
10453 + movl ARGBASE+8(%esp),%edi # dst
10454 + movl ARGBASE+12(%esp),%ecx # len
10455 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
10456 + rep; stosb
10457 + jmp 7b
10458 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10459 +- movl $-EFAULT, (%ebx)
10460 ++ movl $-EFAULT, %ss:(%ebx)
10461 + jmp 7b
10462 + .previous
10463 +
10464 ++ pushl %ss
10465 ++ CFI_ADJUST_CFA_OFFSET 4
10466 ++ popl %ds
10467 ++ CFI_ADJUST_CFA_OFFSET -4
10468 ++ pushl %ss
10469 ++ CFI_ADJUST_CFA_OFFSET 4
10470 ++ popl %es
10471 ++ CFI_ADJUST_CFA_OFFSET -4
10472 + popl %esi
10473 + CFI_ADJUST_CFA_OFFSET -4
10474 + CFI_RESTORE esi
10475 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
10476 + CFI_RESTORE ebx
10477 + ret
10478 + CFI_ENDPROC
10479 +-ENDPROC(csum_partial_copy_generic)
10480 ++ENDPROC(csum_partial_copy_generic_to_user)
10481 +
10482 + #undef ROUND
10483 + #undef ROUND1
10484 +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
10485 +--- linux-2.6.26.6/arch/x86/lib/clear_page_64.S 2008-10-08 23:24:05.000000000 -0400
10486 ++++ linux-2.6.26.6/arch/x86/lib/clear_page_64.S 2008-10-11 21:54:19.000000000 -0400
10487 +@@ -44,7 +44,7 @@ ENDPROC(clear_page)
10488 +
10489 + #include <asm/cpufeature.h>
10490 +
10491 +- .section .altinstr_replacement,"ax"
10492 ++ .section .altinstr_replacement,"a"
10493 + 1: .byte 0xeb /* jmp <disp8> */
10494 + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
10495 + 2:
10496 +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
10497 +--- linux-2.6.26.6/arch/x86/lib/copy_page_64.S 2008-10-08 23:24:05.000000000 -0400
10498 ++++ linux-2.6.26.6/arch/x86/lib/copy_page_64.S 2008-10-11 21:54:19.000000000 -0400
10499 +@@ -104,7 +104,7 @@ ENDPROC(copy_page)
10500 +
10501 + #include <asm/cpufeature.h>
10502 +
10503 +- .section .altinstr_replacement,"ax"
10504 ++ .section .altinstr_replacement,"a"
10505 + 1: .byte 0xeb /* jmp <disp8> */
10506 + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
10507 + 2:
10508 +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
10509 +--- linux-2.6.26.6/arch/x86/lib/copy_user_64.S 2008-10-08 23:24:05.000000000 -0400
10510 ++++ linux-2.6.26.6/arch/x86/lib/copy_user_64.S 2008-10-11 21:54:19.000000000 -0400
10511 +@@ -19,7 +19,7 @@
10512 + .byte 0xe9 /* 32bit jump */
10513 + .long \orig-1f /* by default jump to orig */
10514 + 1:
10515 +- .section .altinstr_replacement,"ax"
10516 ++ .section .altinstr_replacement,"a"
10517 + 2: .byte 0xe9 /* near jump with 32bit immediate */
10518 + .long \alt-1b /* offset */ /* or alternatively to alt */
10519 + .previous
10520 +@@ -76,6 +76,8 @@ ENDPROC(copy_from_user)
10521 + /* must zero dest */
10522 + bad_from_user:
10523 + CFI_STARTPROC
10524 ++ testl %edx,%edx
10525 ++ js bad_to_user
10526 + movl %edx,%ecx
10527 + xorl %eax,%eax
10528 + rep
10529 +diff -urNp linux-2.6.26.6/arch/x86/lib/getuser_32.S linux-2.6.26.6/arch/x86/lib/getuser_32.S
10530 +--- linux-2.6.26.6/arch/x86/lib/getuser_32.S 2008-10-08 23:24:05.000000000 -0400
10531 ++++ linux-2.6.26.6/arch/x86/lib/getuser_32.S 2008-10-11 21:54:19.000000000 -0400
10532 +@@ -11,7 +11,7 @@
10533 + #include <linux/linkage.h>
10534 + #include <asm/dwarf2.h>
10535 + #include <asm/thread_info.h>
10536 +-
10537 ++#include <asm/segment.h>
10538 +
10539 + /*
10540 + * __get_user_X
10541 +@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
10542 + GET_THREAD_INFO(%edx)
10543 + cmpl TI_addr_limit(%edx),%eax
10544 + jae bad_get_user
10545 ++ pushl $(__USER_DS)
10546 ++ popl %ds
10547 + 1: movzbl (%eax),%edx
10548 ++ pushl %ss
10549 ++ pop %ds
10550 + xorl %eax,%eax
10551 + ret
10552 + CFI_ENDPROC
10553 +@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
10554 + GET_THREAD_INFO(%edx)
10555 + cmpl TI_addr_limit(%edx),%eax
10556 + jae bad_get_user
10557 ++ pushl $(__USER_DS)
10558 ++ popl %ds
10559 + 2: movzwl -1(%eax),%edx
10560 ++ pushl %ss
10561 ++ pop %ds
10562 + xorl %eax,%eax
10563 + ret
10564 + CFI_ENDPROC
10565 +@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
10566 + GET_THREAD_INFO(%edx)
10567 + cmpl TI_addr_limit(%edx),%eax
10568 + jae bad_get_user
10569 ++ pushl $(__USER_DS)
10570 ++ popl %ds
10571 + 3: movl -3(%eax),%edx
10572 ++ pushl %ss
10573 ++ pop %ds
10574 + xorl %eax,%eax
10575 + ret
10576 + CFI_ENDPROC
10577 +@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
10578 +
10579 + bad_get_user:
10580 + CFI_STARTPROC
10581 ++ pushl %ss
10582 ++ pop %ds
10583 + xorl %edx,%edx
10584 + movl $-14,%eax
10585 + ret
10586 +diff -urNp linux-2.6.26.6/arch/x86/lib/memcpy_64.S linux-2.6.26.6/arch/x86/lib/memcpy_64.S
10587 +--- linux-2.6.26.6/arch/x86/lib/memcpy_64.S 2008-10-08 23:24:05.000000000 -0400
10588 ++++ linux-2.6.26.6/arch/x86/lib/memcpy_64.S 2008-10-11 21:54:19.000000000 -0400
10589 +@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
10590 + /* Some CPUs run faster using the string copy instructions.
10591 + It is also a lot simpler. Use this when possible */
10592 +
10593 +- .section .altinstr_replacement,"ax"
10594 ++ .section .altinstr_replacement,"a"
10595 + 1: .byte 0xeb /* jmp <disp8> */
10596 + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
10597 + 2:
10598 +diff -urNp linux-2.6.26.6/arch/x86/lib/memset_64.S linux-2.6.26.6/arch/x86/lib/memset_64.S
10599 +--- linux-2.6.26.6/arch/x86/lib/memset_64.S 2008-10-08 23:24:05.000000000 -0400
10600 ++++ linux-2.6.26.6/arch/x86/lib/memset_64.S 2008-10-11 21:54:19.000000000 -0400
10601 +@@ -118,7 +118,7 @@ ENDPROC(__memset)
10602 +
10603 + #include <asm/cpufeature.h>
10604 +
10605 +- .section .altinstr_replacement,"ax"
10606 ++ .section .altinstr_replacement,"a"
10607 + 1: .byte 0xeb /* jmp <disp8> */
10608 + .byte (memset_c - memset) - (2f - 1b) /* offset */
10609 + 2:
10610 +diff -urNp linux-2.6.26.6/arch/x86/lib/mmx_32.c linux-2.6.26.6/arch/x86/lib/mmx_32.c
10611 +--- linux-2.6.26.6/arch/x86/lib/mmx_32.c 2008-10-08 23:24:05.000000000 -0400
10612 ++++ linux-2.6.26.6/arch/x86/lib/mmx_32.c 2008-10-11 21:54:19.000000000 -0400
10613 +@@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
10614 + {
10615 + void *p;
10616 + int i;
10617 ++ unsigned long cr0;
10618 +
10619 + if (unlikely(in_interrupt()))
10620 + return __memcpy(to, from, len);
10621 +@@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
10622 + kernel_fpu_begin();
10623 +
10624 + __asm__ __volatile__ (
10625 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
10626 +- " prefetch 64(%0)\n"
10627 +- " prefetch 128(%0)\n"
10628 +- " prefetch 192(%0)\n"
10629 +- " prefetch 256(%0)\n"
10630 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
10631 ++ " prefetch 64(%1)\n"
10632 ++ " prefetch 128(%1)\n"
10633 ++ " prefetch 192(%1)\n"
10634 ++ " prefetch 256(%1)\n"
10635 + "2: \n"
10636 + ".section .fixup, \"ax\"\n"
10637 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10638 ++ "3: \n"
10639 ++
10640 ++#ifdef CONFIG_PAX_KERNEXEC
10641 ++ " movl %%cr0, %0\n"
10642 ++ " movl %0, %%eax\n"
10643 ++ " andl $0xFFFEFFFF, %%eax\n"
10644 ++ " movl %%eax, %%cr0\n"
10645 ++#endif
10646 ++
10647 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10648 ++
10649 ++#ifdef CONFIG_PAX_KERNEXEC
10650 ++ " movl %0, %%cr0\n"
10651 ++#endif
10652 ++
10653 + " jmp 2b\n"
10654 + ".previous\n"
10655 + _ASM_EXTABLE(1b, 3b)
10656 +- : : "r" (from));
10657 ++ : "=&r" (cr0) : "r" (from) : "ax");
10658 +
10659 + for ( ; i > 5; i--) {
10660 + __asm__ __volatile__ (
10661 +- "1: prefetch 320(%0)\n"
10662 +- "2: movq (%0), %%mm0\n"
10663 +- " movq 8(%0), %%mm1\n"
10664 +- " movq 16(%0), %%mm2\n"
10665 +- " movq 24(%0), %%mm3\n"
10666 +- " movq %%mm0, (%1)\n"
10667 +- " movq %%mm1, 8(%1)\n"
10668 +- " movq %%mm2, 16(%1)\n"
10669 +- " movq %%mm3, 24(%1)\n"
10670 +- " movq 32(%0), %%mm0\n"
10671 +- " movq 40(%0), %%mm1\n"
10672 +- " movq 48(%0), %%mm2\n"
10673 +- " movq 56(%0), %%mm3\n"
10674 +- " movq %%mm0, 32(%1)\n"
10675 +- " movq %%mm1, 40(%1)\n"
10676 +- " movq %%mm2, 48(%1)\n"
10677 +- " movq %%mm3, 56(%1)\n"
10678 ++ "1: prefetch 320(%1)\n"
10679 ++ "2: movq (%1), %%mm0\n"
10680 ++ " movq 8(%1), %%mm1\n"
10681 ++ " movq 16(%1), %%mm2\n"
10682 ++ " movq 24(%1), %%mm3\n"
10683 ++ " movq %%mm0, (%2)\n"
10684 ++ " movq %%mm1, 8(%2)\n"
10685 ++ " movq %%mm2, 16(%2)\n"
10686 ++ " movq %%mm3, 24(%2)\n"
10687 ++ " movq 32(%1), %%mm0\n"
10688 ++ " movq 40(%1), %%mm1\n"
10689 ++ " movq 48(%1), %%mm2\n"
10690 ++ " movq 56(%1), %%mm3\n"
10691 ++ " movq %%mm0, 32(%2)\n"
10692 ++ " movq %%mm1, 40(%2)\n"
10693 ++ " movq %%mm2, 48(%2)\n"
10694 ++ " movq %%mm3, 56(%2)\n"
10695 + ".section .fixup, \"ax\"\n"
10696 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10697 ++ "3:\n"
10698 ++
10699 ++#ifdef CONFIG_PAX_KERNEXEC
10700 ++ " movl %%cr0, %0\n"
10701 ++ " movl %0, %%eax\n"
10702 ++ " andl $0xFFFEFFFF, %%eax\n"
10703 ++ " movl %%eax, %%cr0\n"
10704 ++#endif
10705 ++
10706 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10707 ++
10708 ++#ifdef CONFIG_PAX_KERNEXEC
10709 ++ " movl %0, %%cr0\n"
10710 ++#endif
10711 ++
10712 + " jmp 2b\n"
10713 + ".previous\n"
10714 + _ASM_EXTABLE(1b, 3b)
10715 +- : : "r" (from), "r" (to) : "memory");
10716 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10717 +
10718 + from += 64;
10719 + to += 64;
10720 +@@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
10721 + static void fast_copy_page(void *to, void *from)
10722 + {
10723 + int i;
10724 ++ unsigned long cr0;
10725 +
10726 + kernel_fpu_begin();
10727 +
10728 +@@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
10729 + * but that is for later. -AV
10730 + */
10731 + __asm__ __volatile__(
10732 +- "1: prefetch (%0)\n"
10733 +- " prefetch 64(%0)\n"
10734 +- " prefetch 128(%0)\n"
10735 +- " prefetch 192(%0)\n"
10736 +- " prefetch 256(%0)\n"
10737 ++ "1: prefetch (%1)\n"
10738 ++ " prefetch 64(%1)\n"
10739 ++ " prefetch 128(%1)\n"
10740 ++ " prefetch 192(%1)\n"
10741 ++ " prefetch 256(%1)\n"
10742 + "2: \n"
10743 + ".section .fixup, \"ax\"\n"
10744 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10745 ++ "3: \n"
10746 ++
10747 ++#ifdef CONFIG_PAX_KERNEXEC
10748 ++ " movl %%cr0, %0\n"
10749 ++ " movl %0, %%eax\n"
10750 ++ " andl $0xFFFEFFFF, %%eax\n"
10751 ++ " movl %%eax, %%cr0\n"
10752 ++#endif
10753 ++
10754 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10755 ++
10756 ++#ifdef CONFIG_PAX_KERNEXEC
10757 ++ " movl %0, %%cr0\n"
10758 ++#endif
10759 ++
10760 + " jmp 2b\n"
10761 + ".previous\n"
10762 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
10763 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
10764 +
10765 + for (i = 0; i < (4096-320)/64; i++) {
10766 + __asm__ __volatile__ (
10767 +- "1: prefetch 320(%0)\n"
10768 +- "2: movq (%0), %%mm0\n"
10769 +- " movntq %%mm0, (%1)\n"
10770 +- " movq 8(%0), %%mm1\n"
10771 +- " movntq %%mm1, 8(%1)\n"
10772 +- " movq 16(%0), %%mm2\n"
10773 +- " movntq %%mm2, 16(%1)\n"
10774 +- " movq 24(%0), %%mm3\n"
10775 +- " movntq %%mm3, 24(%1)\n"
10776 +- " movq 32(%0), %%mm4\n"
10777 +- " movntq %%mm4, 32(%1)\n"
10778 +- " movq 40(%0), %%mm5\n"
10779 +- " movntq %%mm5, 40(%1)\n"
10780 +- " movq 48(%0), %%mm6\n"
10781 +- " movntq %%mm6, 48(%1)\n"
10782 +- " movq 56(%0), %%mm7\n"
10783 +- " movntq %%mm7, 56(%1)\n"
10784 ++ "1: prefetch 320(%1)\n"
10785 ++ "2: movq (%1), %%mm0\n"
10786 ++ " movntq %%mm0, (%2)\n"
10787 ++ " movq 8(%1), %%mm1\n"
10788 ++ " movntq %%mm1, 8(%2)\n"
10789 ++ " movq 16(%1), %%mm2\n"
10790 ++ " movntq %%mm2, 16(%2)\n"
10791 ++ " movq 24(%1), %%mm3\n"
10792 ++ " movntq %%mm3, 24(%2)\n"
10793 ++ " movq 32(%1), %%mm4\n"
10794 ++ " movntq %%mm4, 32(%2)\n"
10795 ++ " movq 40(%1), %%mm5\n"
10796 ++ " movntq %%mm5, 40(%2)\n"
10797 ++ " movq 48(%1), %%mm6\n"
10798 ++ " movntq %%mm6, 48(%2)\n"
10799 ++ " movq 56(%1), %%mm7\n"
10800 ++ " movntq %%mm7, 56(%2)\n"
10801 + ".section .fixup, \"ax\"\n"
10802 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10803 ++ "3:\n"
10804 ++
10805 ++#ifdef CONFIG_PAX_KERNEXEC
10806 ++ " movl %%cr0, %0\n"
10807 ++ " movl %0, %%eax\n"
10808 ++ " andl $0xFFFEFFFF, %%eax\n"
10809 ++ " movl %%eax, %%cr0\n"
10810 ++#endif
10811 ++
10812 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10813 ++
10814 ++#ifdef CONFIG_PAX_KERNEXEC
10815 ++ " movl %0, %%cr0\n"
10816 ++#endif
10817 ++
10818 + " jmp 2b\n"
10819 + ".previous\n"
10820 +- _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
10821 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10822 +
10823 + from += 64;
10824 + to += 64;
10825 +@@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
10826 + static void fast_copy_page(void *to, void *from)
10827 + {
10828 + int i;
10829 ++ unsigned long cr0;
10830 +
10831 + kernel_fpu_begin();
10832 +
10833 + __asm__ __volatile__ (
10834 +- "1: prefetch (%0)\n"
10835 +- " prefetch 64(%0)\n"
10836 +- " prefetch 128(%0)\n"
10837 +- " prefetch 192(%0)\n"
10838 +- " prefetch 256(%0)\n"
10839 ++ "1: prefetch (%1)\n"
10840 ++ " prefetch 64(%1)\n"
10841 ++ " prefetch 128(%1)\n"
10842 ++ " prefetch 192(%1)\n"
10843 ++ " prefetch 256(%1)\n"
10844 + "2: \n"
10845 + ".section .fixup, \"ax\"\n"
10846 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10847 ++ "3: \n"
10848 ++
10849 ++#ifdef CONFIG_PAX_KERNEXEC
10850 ++ " movl %%cr0, %0\n"
10851 ++ " movl %0, %%eax\n"
10852 ++ " andl $0xFFFEFFFF, %%eax\n"
10853 ++ " movl %%eax, %%cr0\n"
10854 ++#endif
10855 ++
10856 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10857 ++
10858 ++#ifdef CONFIG_PAX_KERNEXEC
10859 ++ " movl %0, %%cr0\n"
10860 ++#endif
10861 ++
10862 + " jmp 2b\n"
10863 + ".previous\n"
10864 +- _ASM_EXTABLE(1b, 3b) : : "r" (from));
10865 ++ _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
10866 +
10867 + for (i = 0; i < 4096/64; i++) {
10868 + __asm__ __volatile__ (
10869 +- "1: prefetch 320(%0)\n"
10870 +- "2: movq (%0), %%mm0\n"
10871 +- " movq 8(%0), %%mm1\n"
10872 +- " movq 16(%0), %%mm2\n"
10873 +- " movq 24(%0), %%mm3\n"
10874 +- " movq %%mm0, (%1)\n"
10875 +- " movq %%mm1, 8(%1)\n"
10876 +- " movq %%mm2, 16(%1)\n"
10877 +- " movq %%mm3, 24(%1)\n"
10878 +- " movq 32(%0), %%mm0\n"
10879 +- " movq 40(%0), %%mm1\n"
10880 +- " movq 48(%0), %%mm2\n"
10881 +- " movq 56(%0), %%mm3\n"
10882 +- " movq %%mm0, 32(%1)\n"
10883 +- " movq %%mm1, 40(%1)\n"
10884 +- " movq %%mm2, 48(%1)\n"
10885 +- " movq %%mm3, 56(%1)\n"
10886 ++ "1: prefetch 320(%1)\n"
10887 ++ "2: movq (%1), %%mm0\n"
10888 ++ " movq 8(%1), %%mm1\n"
10889 ++ " movq 16(%1), %%mm2\n"
10890 ++ " movq 24(%1), %%mm3\n"
10891 ++ " movq %%mm0, (%2)\n"
10892 ++ " movq %%mm1, 8(%2)\n"
10893 ++ " movq %%mm2, 16(%2)\n"
10894 ++ " movq %%mm3, 24(%2)\n"
10895 ++ " movq 32(%1), %%mm0\n"
10896 ++ " movq 40(%1), %%mm1\n"
10897 ++ " movq 48(%1), %%mm2\n"
10898 ++ " movq 56(%1), %%mm3\n"
10899 ++ " movq %%mm0, 32(%2)\n"
10900 ++ " movq %%mm1, 40(%2)\n"
10901 ++ " movq %%mm2, 48(%2)\n"
10902 ++ " movq %%mm3, 56(%2)\n"
10903 + ".section .fixup, \"ax\"\n"
10904 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10905 ++ "3:\n"
10906 ++
10907 ++#ifdef CONFIG_PAX_KERNEXEC
10908 ++ " movl %%cr0, %0\n"
10909 ++ " movl %0, %%eax\n"
10910 ++ " andl $0xFFFEFFFF, %%eax\n"
10911 ++ " movl %%eax, %%cr0\n"
10912 ++#endif
10913 ++
10914 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10915 ++
10916 ++#ifdef CONFIG_PAX_KERNEXEC
10917 ++ " movl %0, %%cr0\n"
10918 ++#endif
10919 ++
10920 + " jmp 2b\n"
10921 + ".previous\n"
10922 + _ASM_EXTABLE(1b, 3b)
10923 +- : : "r" (from), "r" (to) : "memory");
10924 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10925 +
10926 + from += 64;
10927 + to += 64;
10928 +diff -urNp linux-2.6.26.6/arch/x86/lib/putuser_32.S linux-2.6.26.6/arch/x86/lib/putuser_32.S
10929 +--- linux-2.6.26.6/arch/x86/lib/putuser_32.S 2008-10-08 23:24:05.000000000 -0400
10930 ++++ linux-2.6.26.6/arch/x86/lib/putuser_32.S 2008-10-11 21:54:19.000000000 -0400
10931 +@@ -11,7 +11,7 @@
10932 + #include <linux/linkage.h>
10933 + #include <asm/dwarf2.h>
10934 + #include <asm/thread_info.h>
10935 +-
10936 ++#include <asm/segment.h>
10937 +
10938 + /*
10939 + * __put_user_X
10940 +@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
10941 + ENTER
10942 + cmpl TI_addr_limit(%ebx),%ecx
10943 + jae bad_put_user
10944 ++ pushl $(__USER_DS)
10945 ++ popl %ds
10946 + 1: movb %al,(%ecx)
10947 ++ pushl %ss
10948 ++ popl %ds
10949 + xorl %eax,%eax
10950 + EXIT
10951 + ENDPROC(__put_user_1)
10952 +@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
10953 + subl $1,%ebx
10954 + cmpl %ebx,%ecx
10955 + jae bad_put_user
10956 ++ pushl $(__USER_DS)
10957 ++ popl %ds
10958 + 2: movw %ax,(%ecx)
10959 ++ pushl %ss
10960 ++ popl %ds
10961 + xorl %eax,%eax
10962 + EXIT
10963 + ENDPROC(__put_user_2)
10964 +@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
10965 + subl $3,%ebx
10966 + cmpl %ebx,%ecx
10967 + jae bad_put_user
10968 ++ pushl $(__USER_DS)
10969 ++ popl %ds
10970 + 3: movl %eax,(%ecx)
10971 ++ pushl %ss
10972 ++ popl %ds
10973 + xorl %eax,%eax
10974 + EXIT
10975 + ENDPROC(__put_user_4)
10976 +@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
10977 + subl $7,%ebx
10978 + cmpl %ebx,%ecx
10979 + jae bad_put_user
10980 ++ pushl $(__USER_DS)
10981 ++ popl %ds
10982 + 4: movl %eax,(%ecx)
10983 + 5: movl %edx,4(%ecx)
10984 ++ pushl %ss
10985 ++ popl %ds
10986 + xorl %eax,%eax
10987 + EXIT
10988 + ENDPROC(__put_user_8)
10989 +@@ -85,6 +101,10 @@ bad_put_user:
10990 + CFI_DEF_CFA esp, 2*4
10991 + CFI_OFFSET eip, -1*4
10992 + CFI_OFFSET ebx, -2*4
10993 ++ pushl %ss
10994 ++ CFI_ADJUST_CFA_OFFSET 4
10995 ++ popl %ds
10996 ++ CFI_ADJUST_CFA_OFFSET -4
10997 + movl $-14,%eax
10998 + EXIT
10999 + END(bad_put_user)
11000 +diff -urNp linux-2.6.26.6/arch/x86/lib/usercopy_32.c linux-2.6.26.6/arch/x86/lib/usercopy_32.c
11001 +--- linux-2.6.26.6/arch/x86/lib/usercopy_32.c 2008-10-08 23:24:05.000000000 -0400
11002 ++++ linux-2.6.26.6/arch/x86/lib/usercopy_32.c 2008-10-11 21:55:52.000000000 -0400
11003 +@@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
11004 + * Copy a null terminated string from userspace.
11005 + */
11006 +
11007 +-#define __do_strncpy_from_user(dst, src, count, res) \
11008 +-do { \
11009 +- int __d0, __d1, __d2; \
11010 +- might_sleep(); \
11011 +- __asm__ __volatile__( \
11012 +- " testl %1,%1\n" \
11013 +- " jz 2f\n" \
11014 +- "0: lodsb\n" \
11015 +- " stosb\n" \
11016 +- " testb %%al,%%al\n" \
11017 +- " jz 1f\n" \
11018 +- " decl %1\n" \
11019 +- " jnz 0b\n" \
11020 +- "1: subl %1,%0\n" \
11021 +- "2:\n" \
11022 +- ".section .fixup,\"ax\"\n" \
11023 +- "3: movl %5,%0\n" \
11024 +- " jmp 2b\n" \
11025 +- ".previous\n" \
11026 +- _ASM_EXTABLE(0b,3b) \
11027 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
11028 +- "=&D" (__d2) \
11029 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
11030 +- : "memory"); \
11031 +-} while (0)
11032 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
11033 ++{
11034 ++ int __d0, __d1, __d2;
11035 ++ long res = -EFAULT;
11036 ++
11037 ++ might_sleep();
11038 ++ __asm__ __volatile__(
11039 ++ " movw %w10,%%ds\n"
11040 ++ " testl %1,%1\n"
11041 ++ " jz 2f\n"
11042 ++ "0: lodsb\n"
11043 ++ " stosb\n"
11044 ++ " testb %%al,%%al\n"
11045 ++ " jz 1f\n"
11046 ++ " decl %1\n"
11047 ++ " jnz 0b\n"
11048 ++ "1: subl %1,%0\n"
11049 ++ "2:\n"
11050 ++ " pushl %%ss\n"
11051 ++ " popl %%ds\n"
11052 ++ ".section .fixup,\"ax\"\n"
11053 ++ "3: movl %5,%0\n"
11054 ++ " jmp 2b\n"
11055 ++ ".previous\n"
11056 ++ _ASM_EXTABLE(0b,3b)
11057 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
11058 ++ "=&D" (__d2)
11059 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
11060 ++ "r"(__USER_DS)
11061 ++ : "memory");
11062 ++ return res;
11063 ++}
11064 +
11065 + /**
11066 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
11067 +@@ -78,9 +85,7 @@ do { \
11068 + long
11069 + __strncpy_from_user(char *dst, const char __user *src, long count)
11070 + {
11071 +- long res;
11072 +- __do_strncpy_from_user(dst, src, count, res);
11073 +- return res;
11074 ++ return __do_strncpy_from_user(dst, src, count);
11075 + }
11076 + EXPORT_SYMBOL(__strncpy_from_user);
11077 +
11078 +@@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
11079 + {
11080 + long res = -EFAULT;
11081 + if (access_ok(VERIFY_READ, src, 1))
11082 +- __do_strncpy_from_user(dst, src, count, res);
11083 ++ res = __do_strncpy_from_user(dst, src, count);
11084 + return res;
11085 + }
11086 + EXPORT_SYMBOL(strncpy_from_user);
11087 +@@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
11088 + * Zero Userspace
11089 + */
11090 +
11091 +-#define __do_clear_user(addr,size) \
11092 +-do { \
11093 +- int __d0; \
11094 +- might_sleep(); \
11095 +- __asm__ __volatile__( \
11096 +- "0: rep; stosl\n" \
11097 +- " movl %2,%0\n" \
11098 +- "1: rep; stosb\n" \
11099 +- "2:\n" \
11100 +- ".section .fixup,\"ax\"\n" \
11101 +- "3: lea 0(%2,%0,4),%0\n" \
11102 +- " jmp 2b\n" \
11103 +- ".previous\n" \
11104 +- _ASM_EXTABLE(0b,3b) \
11105 +- _ASM_EXTABLE(1b,2b) \
11106 +- : "=&c"(size), "=&D" (__d0) \
11107 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
11108 +-} while (0)
11109 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
11110 ++{
11111 ++ int __d0;
11112 ++
11113 ++ might_sleep();
11114 ++ __asm__ __volatile__(
11115 ++ " movw %w6,%%es\n"
11116 ++ "0: rep; stosl\n"
11117 ++ " movl %2,%0\n"
11118 ++ "1: rep; stosb\n"
11119 ++ "2:\n"
11120 ++ " pushl %%ss\n"
11121 ++ " popl %%es\n"
11122 ++ ".section .fixup,\"ax\"\n"
11123 ++ "3: lea 0(%2,%0,4),%0\n"
11124 ++ " jmp 2b\n"
11125 ++ ".previous\n"
11126 ++ _ASM_EXTABLE(0b,3b)
11127 ++ _ASM_EXTABLE(1b,2b)
11128 ++ : "=&c"(size), "=&D" (__d0)
11129 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
11130 ++ "r"(__USER_DS));
11131 ++ return size;
11132 ++}
11133 +
11134 + /**
11135 + * clear_user: - Zero a block of memory in user space.
11136 +@@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
11137 + {
11138 + might_sleep();
11139 + if (access_ok(VERIFY_WRITE, to, n))
11140 +- __do_clear_user(to, n);
11141 ++ n = __do_clear_user(to, n);
11142 + return n;
11143 + }
11144 + EXPORT_SYMBOL(clear_user);
11145 +@@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
11146 + unsigned long
11147 + __clear_user(void __user *to, unsigned long n)
11148 + {
11149 +- __do_clear_user(to, n);
11150 +- return n;
11151 ++ return __do_clear_user(to, n);
11152 + }
11153 + EXPORT_SYMBOL(__clear_user);
11154 +
11155 +@@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
11156 + might_sleep();
11157 +
11158 + __asm__ __volatile__(
11159 ++ " movw %w8,%%es\n"
11160 + " testl %0, %0\n"
11161 + " jz 3f\n"
11162 +- " andl %0,%%ecx\n"
11163 ++ " movl %0,%%ecx\n"
11164 + "0: repne; scasb\n"
11165 + " setne %%al\n"
11166 + " subl %%ecx,%0\n"
11167 + " addl %0,%%eax\n"
11168 + "1:\n"
11169 ++ " pushl %%ss\n"
11170 ++ " popl %%es\n"
11171 + ".section .fixup,\"ax\"\n"
11172 + "2: xorl %%eax,%%eax\n"
11173 + " jmp 1b\n"
11174 +@@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
11175 + " .long 0b,2b\n"
11176 + ".previous"
11177 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
11178 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
11179 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
11180 + :"cc");
11181 + return res & mask;
11182 + }
11183 +@@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
11184 +
11185 + #ifdef CONFIG_X86_INTEL_USERCOPY
11186 + static unsigned long
11187 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
11188 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
11189 + {
11190 + int d0, d1;
11191 + __asm__ __volatile__(
11192 ++ " movw %w6, %%es\n"
11193 + " .align 2,0x90\n"
11194 + "1: movl 32(%4), %%eax\n"
11195 + " cmpl $67, %0\n"
11196 +@@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
11197 + " .align 2,0x90\n"
11198 + "3: movl 0(%4), %%eax\n"
11199 + "4: movl 4(%4), %%edx\n"
11200 +- "5: movl %%eax, 0(%3)\n"
11201 +- "6: movl %%edx, 4(%3)\n"
11202 ++ "5: movl %%eax, %%es:0(%3)\n"
11203 ++ "6: movl %%edx, %%es:4(%3)\n"
11204 + "7: movl 8(%4), %%eax\n"
11205 + "8: movl 12(%4),%%edx\n"
11206 +- "9: movl %%eax, 8(%3)\n"
11207 +- "10: movl %%edx, 12(%3)\n"
11208 ++ "9: movl %%eax, %%es:8(%3)\n"
11209 ++ "10: movl %%edx, %%es:12(%3)\n"
11210 + "11: movl 16(%4), %%eax\n"
11211 + "12: movl 20(%4), %%edx\n"
11212 +- "13: movl %%eax, 16(%3)\n"
11213 +- "14: movl %%edx, 20(%3)\n"
11214 ++ "13: movl %%eax, %%es:16(%3)\n"
11215 ++ "14: movl %%edx, %%es:20(%3)\n"
11216 + "15: movl 24(%4), %%eax\n"
11217 + "16: movl 28(%4), %%edx\n"
11218 +- "17: movl %%eax, 24(%3)\n"
11219 +- "18: movl %%edx, 28(%3)\n"
11220 ++ "17: movl %%eax, %%es:24(%3)\n"
11221 ++ "18: movl %%edx, %%es:28(%3)\n"
11222 + "19: movl 32(%4), %%eax\n"
11223 + "20: movl 36(%4), %%edx\n"
11224 +- "21: movl %%eax, 32(%3)\n"
11225 +- "22: movl %%edx, 36(%3)\n"
11226 ++ "21: movl %%eax, %%es:32(%3)\n"
11227 ++ "22: movl %%edx, %%es:36(%3)\n"
11228 + "23: movl 40(%4), %%eax\n"
11229 + "24: movl 44(%4), %%edx\n"
11230 +- "25: movl %%eax, 40(%3)\n"
11231 +- "26: movl %%edx, 44(%3)\n"
11232 ++ "25: movl %%eax, %%es:40(%3)\n"
11233 ++ "26: movl %%edx, %%es:44(%3)\n"
11234 + "27: movl 48(%4), %%eax\n"
11235 + "28: movl 52(%4), %%edx\n"
11236 +- "29: movl %%eax, 48(%3)\n"
11237 +- "30: movl %%edx, 52(%3)\n"
11238 ++ "29: movl %%eax, %%es:48(%3)\n"
11239 ++ "30: movl %%edx, %%es:52(%3)\n"
11240 + "31: movl 56(%4), %%eax\n"
11241 + "32: movl 60(%4), %%edx\n"
11242 +- "33: movl %%eax, 56(%3)\n"
11243 +- "34: movl %%edx, 60(%3)\n"
11244 ++ "33: movl %%eax, %%es:56(%3)\n"
11245 ++ "34: movl %%edx, %%es:60(%3)\n"
11246 + " addl $-64, %0\n"
11247 + " addl $64, %4\n"
11248 + " addl $64, %3\n"
11249 +@@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
11250 + "36: movl %%eax, %0\n"
11251 + "37: rep; movsb\n"
11252 + "100:\n"
11253 ++ " pushl %%ss\n"
11254 ++ " popl %%es\n"
11255 + ".section .fixup,\"ax\"\n"
11256 + "101: lea 0(%%eax,%0,4),%0\n"
11257 + " jmp 100b\n"
11258 +@@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
11259 + " .long 99b,101b\n"
11260 + ".previous"
11261 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11262 +- : "1"(to), "2"(from), "0"(size)
11263 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11264 ++ : "eax", "edx", "memory");
11265 ++ return size;
11266 ++}
11267 ++
11268 ++static unsigned long
11269 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
11270 ++{
11271 ++ int d0, d1;
11272 ++ __asm__ __volatile__(
11273 ++ " movw %w6, %%ds\n"
11274 ++ " .align 2,0x90\n"
11275 ++ "1: movl 32(%4), %%eax\n"
11276 ++ " cmpl $67, %0\n"
11277 ++ " jbe 3f\n"
11278 ++ "2: movl 64(%4), %%eax\n"
11279 ++ " .align 2,0x90\n"
11280 ++ "3: movl 0(%4), %%eax\n"
11281 ++ "4: movl 4(%4), %%edx\n"
11282 ++ "5: movl %%eax, %%es:0(%3)\n"
11283 ++ "6: movl %%edx, %%es:4(%3)\n"
11284 ++ "7: movl 8(%4), %%eax\n"
11285 ++ "8: movl 12(%4),%%edx\n"
11286 ++ "9: movl %%eax, %%es:8(%3)\n"
11287 ++ "10: movl %%edx, %%es:12(%3)\n"
11288 ++ "11: movl 16(%4), %%eax\n"
11289 ++ "12: movl 20(%4), %%edx\n"
11290 ++ "13: movl %%eax, %%es:16(%3)\n"
11291 ++ "14: movl %%edx, %%es:20(%3)\n"
11292 ++ "15: movl 24(%4), %%eax\n"
11293 ++ "16: movl 28(%4), %%edx\n"
11294 ++ "17: movl %%eax, %%es:24(%3)\n"
11295 ++ "18: movl %%edx, %%es:28(%3)\n"
11296 ++ "19: movl 32(%4), %%eax\n"
11297 ++ "20: movl 36(%4), %%edx\n"
11298 ++ "21: movl %%eax, %%es:32(%3)\n"
11299 ++ "22: movl %%edx, %%es:36(%3)\n"
11300 ++ "23: movl 40(%4), %%eax\n"
11301 ++ "24: movl 44(%4), %%edx\n"
11302 ++ "25: movl %%eax, %%es:40(%3)\n"
11303 ++ "26: movl %%edx, %%es:44(%3)\n"
11304 ++ "27: movl 48(%4), %%eax\n"
11305 ++ "28: movl 52(%4), %%edx\n"
11306 ++ "29: movl %%eax, %%es:48(%3)\n"
11307 ++ "30: movl %%edx, %%es:52(%3)\n"
11308 ++ "31: movl 56(%4), %%eax\n"
11309 ++ "32: movl 60(%4), %%edx\n"
11310 ++ "33: movl %%eax, %%es:56(%3)\n"
11311 ++ "34: movl %%edx, %%es:60(%3)\n"
11312 ++ " addl $-64, %0\n"
11313 ++ " addl $64, %4\n"
11314 ++ " addl $64, %3\n"
11315 ++ " cmpl $63, %0\n"
11316 ++ " ja 1b\n"
11317 ++ "35: movl %0, %%eax\n"
11318 ++ " shrl $2, %0\n"
11319 ++ " andl $3, %%eax\n"
11320 ++ " cld\n"
11321 ++ "99: rep; movsl\n"
11322 ++ "36: movl %%eax, %0\n"
11323 ++ "37: rep; movsb\n"
11324 ++ "100:\n"
11325 ++ " pushl %%ss\n"
11326 ++ " popl %%ds\n"
11327 ++ ".section .fixup,\"ax\"\n"
11328 ++ "101: lea 0(%%eax,%0,4),%0\n"
11329 ++ " jmp 100b\n"
11330 ++ ".previous\n"
11331 ++ ".section __ex_table,\"a\"\n"
11332 ++ " .align 4\n"
11333 ++ " .long 1b,100b\n"
11334 ++ " .long 2b,100b\n"
11335 ++ " .long 3b,100b\n"
11336 ++ " .long 4b,100b\n"
11337 ++ " .long 5b,100b\n"
11338 ++ " .long 6b,100b\n"
11339 ++ " .long 7b,100b\n"
11340 ++ " .long 8b,100b\n"
11341 ++ " .long 9b,100b\n"
11342 ++ " .long 10b,100b\n"
11343 ++ " .long 11b,100b\n"
11344 ++ " .long 12b,100b\n"
11345 ++ " .long 13b,100b\n"
11346 ++ " .long 14b,100b\n"
11347 ++ " .long 15b,100b\n"
11348 ++ " .long 16b,100b\n"
11349 ++ " .long 17b,100b\n"
11350 ++ " .long 18b,100b\n"
11351 ++ " .long 19b,100b\n"
11352 ++ " .long 20b,100b\n"
11353 ++ " .long 21b,100b\n"
11354 ++ " .long 22b,100b\n"
11355 ++ " .long 23b,100b\n"
11356 ++ " .long 24b,100b\n"
11357 ++ " .long 25b,100b\n"
11358 ++ " .long 26b,100b\n"
11359 ++ " .long 27b,100b\n"
11360 ++ " .long 28b,100b\n"
11361 ++ " .long 29b,100b\n"
11362 ++ " .long 30b,100b\n"
11363 ++ " .long 31b,100b\n"
11364 ++ " .long 32b,100b\n"
11365 ++ " .long 33b,100b\n"
11366 ++ " .long 34b,100b\n"
11367 ++ " .long 35b,100b\n"
11368 ++ " .long 36b,100b\n"
11369 ++ " .long 37b,100b\n"
11370 ++ " .long 99b,101b\n"
11371 ++ ".previous"
11372 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
11373 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11374 + : "eax", "edx", "memory");
11375 + return size;
11376 + }
11377 +@@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
11378 + {
11379 + int d0, d1;
11380 + __asm__ __volatile__(
11381 ++ " movw %w6, %%ds\n"
11382 + " .align 2,0x90\n"
11383 + "0: movl 32(%4), %%eax\n"
11384 + " cmpl $67, %0\n"
11385 +@@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
11386 + " .align 2,0x90\n"
11387 + "2: movl 0(%4), %%eax\n"
11388 + "21: movl 4(%4), %%edx\n"
11389 +- " movl %%eax, 0(%3)\n"
11390 +- " movl %%edx, 4(%3)\n"
11391 ++ " movl %%eax, %%es:0(%3)\n"
11392 ++ " movl %%edx, %%es:4(%3)\n"
11393 + "3: movl 8(%4), %%eax\n"
11394 + "31: movl 12(%4),%%edx\n"
11395 +- " movl %%eax, 8(%3)\n"
11396 +- " movl %%edx, 12(%3)\n"
11397 ++ " movl %%eax, %%es:8(%3)\n"
11398 ++ " movl %%edx, %%es:12(%3)\n"
11399 + "4: movl 16(%4), %%eax\n"
11400 + "41: movl 20(%4), %%edx\n"
11401 +- " movl %%eax, 16(%3)\n"
11402 +- " movl %%edx, 20(%3)\n"
11403 ++ " movl %%eax, %%es:16(%3)\n"
11404 ++ " movl %%edx, %%es:20(%3)\n"
11405 + "10: movl 24(%4), %%eax\n"
11406 + "51: movl 28(%4), %%edx\n"
11407 +- " movl %%eax, 24(%3)\n"
11408 +- " movl %%edx, 28(%3)\n"
11409 ++ " movl %%eax, %%es:24(%3)\n"
11410 ++ " movl %%edx, %%es:28(%3)\n"
11411 + "11: movl 32(%4), %%eax\n"
11412 + "61: movl 36(%4), %%edx\n"
11413 +- " movl %%eax, 32(%3)\n"
11414 +- " movl %%edx, 36(%3)\n"
11415 ++ " movl %%eax, %%es:32(%3)\n"
11416 ++ " movl %%edx, %%es:36(%3)\n"
11417 + "12: movl 40(%4), %%eax\n"
11418 + "71: movl 44(%4), %%edx\n"
11419 +- " movl %%eax, 40(%3)\n"
11420 +- " movl %%edx, 44(%3)\n"
11421 ++ " movl %%eax, %%es:40(%3)\n"
11422 ++ " movl %%edx, %%es:44(%3)\n"
11423 + "13: movl 48(%4), %%eax\n"
11424 + "81: movl 52(%4), %%edx\n"
11425 +- " movl %%eax, 48(%3)\n"
11426 +- " movl %%edx, 52(%3)\n"
11427 ++ " movl %%eax, %%es:48(%3)\n"
11428 ++ " movl %%edx, %%es:52(%3)\n"
11429 + "14: movl 56(%4), %%eax\n"
11430 + "91: movl 60(%4), %%edx\n"
11431 +- " movl %%eax, 56(%3)\n"
11432 +- " movl %%edx, 60(%3)\n"
11433 ++ " movl %%eax, %%es:56(%3)\n"
11434 ++ " movl %%edx, %%es:60(%3)\n"
11435 + " addl $-64, %0\n"
11436 + " addl $64, %4\n"
11437 + " addl $64, %3\n"
11438 +@@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
11439 + " movl %%eax,%0\n"
11440 + "7: rep; movsb\n"
11441 + "8:\n"
11442 ++ " pushl %%ss\n"
11443 ++ " popl %%ds\n"
11444 + ".section .fixup,\"ax\"\n"
11445 + "9: lea 0(%%eax,%0,4),%0\n"
11446 + "16: pushl %0\n"
11447 +@@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
11448 + " .long 7b,16b\n"
11449 + ".previous"
11450 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11451 +- : "1"(to), "2"(from), "0"(size)
11452 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11453 + : "eax", "edx", "memory");
11454 + return size;
11455 + }
11456 +@@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
11457 + int d0, d1;
11458 +
11459 + __asm__ __volatile__(
11460 ++ " movw %w6, %%ds\n"
11461 + " .align 2,0x90\n"
11462 + "0: movl 32(%4), %%eax\n"
11463 + " cmpl $67, %0\n"
11464 +@@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
11465 + " .align 2,0x90\n"
11466 + "2: movl 0(%4), %%eax\n"
11467 + "21: movl 4(%4), %%edx\n"
11468 +- " movnti %%eax, 0(%3)\n"
11469 +- " movnti %%edx, 4(%3)\n"
11470 ++ " movnti %%eax, %%es:0(%3)\n"
11471 ++ " movnti %%edx, %%es:4(%3)\n"
11472 + "3: movl 8(%4), %%eax\n"
11473 + "31: movl 12(%4),%%edx\n"
11474 +- " movnti %%eax, 8(%3)\n"
11475 +- " movnti %%edx, 12(%3)\n"
11476 ++ " movnti %%eax, %%es:8(%3)\n"
11477 ++ " movnti %%edx, %%es:12(%3)\n"
11478 + "4: movl 16(%4), %%eax\n"
11479 + "41: movl 20(%4), %%edx\n"
11480 +- " movnti %%eax, 16(%3)\n"
11481 +- " movnti %%edx, 20(%3)\n"
11482 ++ " movnti %%eax, %%es:16(%3)\n"
11483 ++ " movnti %%edx, %%es:20(%3)\n"
11484 + "10: movl 24(%4), %%eax\n"
11485 + "51: movl 28(%4), %%edx\n"
11486 +- " movnti %%eax, 24(%3)\n"
11487 +- " movnti %%edx, 28(%3)\n"
11488 ++ " movnti %%eax, %%es:24(%3)\n"
11489 ++ " movnti %%edx, %%es:28(%3)\n"
11490 + "11: movl 32(%4), %%eax\n"
11491 + "61: movl 36(%4), %%edx\n"
11492 +- " movnti %%eax, 32(%3)\n"
11493 +- " movnti %%edx, 36(%3)\n"
11494 ++ " movnti %%eax, %%es:32(%3)\n"
11495 ++ " movnti %%edx, %%es:36(%3)\n"
11496 + "12: movl 40(%4), %%eax\n"
11497 + "71: movl 44(%4), %%edx\n"
11498 +- " movnti %%eax, 40(%3)\n"
11499 +- " movnti %%edx, 44(%3)\n"
11500 ++ " movnti %%eax, %%es:40(%3)\n"
11501 ++ " movnti %%edx, %%es:44(%3)\n"
11502 + "13: movl 48(%4), %%eax\n"
11503 + "81: movl 52(%4), %%edx\n"
11504 +- " movnti %%eax, 48(%3)\n"
11505 +- " movnti %%edx, 52(%3)\n"
11506 ++ " movnti %%eax, %%es:48(%3)\n"
11507 ++ " movnti %%edx, %%es:52(%3)\n"
11508 + "14: movl 56(%4), %%eax\n"
11509 + "91: movl 60(%4), %%edx\n"
11510 +- " movnti %%eax, 56(%3)\n"
11511 +- " movnti %%edx, 60(%3)\n"
11512 ++ " movnti %%eax, %%es:56(%3)\n"
11513 ++ " movnti %%edx, %%es:60(%3)\n"
11514 + " addl $-64, %0\n"
11515 + " addl $64, %4\n"
11516 + " addl $64, %3\n"
11517 +@@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
11518 + " movl %%eax,%0\n"
11519 + "7: rep; movsb\n"
11520 + "8:\n"
11521 ++ " pushl %%ss\n"
11522 ++ " popl %%ds\n"
11523 + ".section .fixup,\"ax\"\n"
11524 + "9: lea 0(%%eax,%0,4),%0\n"
11525 + "16: pushl %0\n"
11526 +@@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
11527 + " .long 7b,16b\n"
11528 + ".previous"
11529 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11530 +- : "1"(to), "2"(from), "0"(size)
11531 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11532 + : "eax", "edx", "memory");
11533 + return size;
11534 + }
11535 +@@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
11536 + int d0, d1;
11537 +
11538 + __asm__ __volatile__(
11539 ++ " movw %w6, %%ds\n"
11540 + " .align 2,0x90\n"
11541 + "0: movl 32(%4), %%eax\n"
11542 + " cmpl $67, %0\n"
11543 +@@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
11544 + " .align 2,0x90\n"
11545 + "2: movl 0(%4), %%eax\n"
11546 + "21: movl 4(%4), %%edx\n"
11547 +- " movnti %%eax, 0(%3)\n"
11548 +- " movnti %%edx, 4(%3)\n"
11549 ++ " movnti %%eax, %%es:0(%3)\n"
11550 ++ " movnti %%edx, %%es:4(%3)\n"
11551 + "3: movl 8(%4), %%eax\n"
11552 + "31: movl 12(%4),%%edx\n"
11553 +- " movnti %%eax, 8(%3)\n"
11554 +- " movnti %%edx, 12(%3)\n"
11555 ++ " movnti %%eax, %%es:8(%3)\n"
11556 ++ " movnti %%edx, %%es:12(%3)\n"
11557 + "4: movl 16(%4), %%eax\n"
11558 + "41: movl 20(%4), %%edx\n"
11559 +- " movnti %%eax, 16(%3)\n"
11560 +- " movnti %%edx, 20(%3)\n"
11561 ++ " movnti %%eax, %%es:16(%3)\n"
11562 ++ " movnti %%edx, %%es:20(%3)\n"
11563 + "10: movl 24(%4), %%eax\n"
11564 + "51: movl 28(%4), %%edx\n"
11565 +- " movnti %%eax, 24(%3)\n"
11566 +- " movnti %%edx, 28(%3)\n"
11567 ++ " movnti %%eax, %%es:24(%3)\n"
11568 ++ " movnti %%edx, %%es:28(%3)\n"
11569 + "11: movl 32(%4), %%eax\n"
11570 + "61: movl 36(%4), %%edx\n"
11571 +- " movnti %%eax, 32(%3)\n"
11572 +- " movnti %%edx, 36(%3)\n"
11573 ++ " movnti %%eax, %%es:32(%3)\n"
11574 ++ " movnti %%edx, %%es:36(%3)\n"
11575 + "12: movl 40(%4), %%eax\n"
11576 + "71: movl 44(%4), %%edx\n"
11577 +- " movnti %%eax, 40(%3)\n"
11578 +- " movnti %%edx, 44(%3)\n"
11579 ++ " movnti %%eax, %%es:40(%3)\n"
11580 ++ " movnti %%edx, %%es:44(%3)\n"
11581 + "13: movl 48(%4), %%eax\n"
11582 + "81: movl 52(%4), %%edx\n"
11583 +- " movnti %%eax, 48(%3)\n"
11584 +- " movnti %%edx, 52(%3)\n"
11585 ++ " movnti %%eax, %%es:48(%3)\n"
11586 ++ " movnti %%edx, %%es:52(%3)\n"
11587 + "14: movl 56(%4), %%eax\n"
11588 + "91: movl 60(%4), %%edx\n"
11589 +- " movnti %%eax, 56(%3)\n"
11590 +- " movnti %%edx, 60(%3)\n"
11591 ++ " movnti %%eax, %%es:56(%3)\n"
11592 ++ " movnti %%edx, %%es:60(%3)\n"
11593 + " addl $-64, %0\n"
11594 + " addl $64, %4\n"
11595 + " addl $64, %3\n"
11596 +@@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
11597 + " movl %%eax,%0\n"
11598 + "7: rep; movsb\n"
11599 + "8:\n"
11600 ++ " pushl %%ss\n"
11601 ++ " popl %%ds\n"
11602 + ".section .fixup,\"ax\"\n"
11603 + "9: lea 0(%%eax,%0,4),%0\n"
11604 + "16: jmp 8b\n"
11605 +@@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
11606 + " .long 7b,16b\n"
11607 + ".previous"
11608 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11609 +- : "1"(to), "2"(from), "0"(size)
11610 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11611 + : "eax", "edx", "memory");
11612 + return size;
11613 + }
11614 +@@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
11615 + */
11616 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
11617 + unsigned long size);
11618 +-unsigned long __copy_user_intel(void __user *to, const void *from,
11619 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
11620 ++ unsigned long size);
11621 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
11622 + unsigned long size);
11623 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
11624 + const void __user *from, unsigned long size);
11625 + #endif /* CONFIG_X86_INTEL_USERCOPY */
11626 +
11627 + /* Generic arbitrary sized copy. */
11628 +-#define __copy_user(to, from, size) \
11629 +-do { \
11630 +- int __d0, __d1, __d2; \
11631 +- __asm__ __volatile__( \
11632 +- " cmp $7,%0\n" \
11633 +- " jbe 1f\n" \
11634 +- " movl %1,%0\n" \
11635 +- " negl %0\n" \
11636 +- " andl $7,%0\n" \
11637 +- " subl %0,%3\n" \
11638 +- "4: rep; movsb\n" \
11639 +- " movl %3,%0\n" \
11640 +- " shrl $2,%0\n" \
11641 +- " andl $3,%3\n" \
11642 +- " .align 2,0x90\n" \
11643 +- "0: rep; movsl\n" \
11644 +- " movl %3,%0\n" \
11645 +- "1: rep; movsb\n" \
11646 +- "2:\n" \
11647 +- ".section .fixup,\"ax\"\n" \
11648 +- "5: addl %3,%0\n" \
11649 +- " jmp 2b\n" \
11650 +- "3: lea 0(%3,%0,4),%0\n" \
11651 +- " jmp 2b\n" \
11652 +- ".previous\n" \
11653 +- ".section __ex_table,\"a\"\n" \
11654 +- " .align 4\n" \
11655 +- " .long 4b,5b\n" \
11656 +- " .long 0b,3b\n" \
11657 +- " .long 1b,2b\n" \
11658 +- ".previous" \
11659 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
11660 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
11661 +- : "memory"); \
11662 +-} while (0)
11663 +-
11664 +-#define __copy_user_zeroing(to, from, size) \
11665 +-do { \
11666 +- int __d0, __d1, __d2; \
11667 +- __asm__ __volatile__( \
11668 +- " cmp $7,%0\n" \
11669 +- " jbe 1f\n" \
11670 +- " movl %1,%0\n" \
11671 +- " negl %0\n" \
11672 +- " andl $7,%0\n" \
11673 +- " subl %0,%3\n" \
11674 +- "4: rep; movsb\n" \
11675 +- " movl %3,%0\n" \
11676 +- " shrl $2,%0\n" \
11677 +- " andl $3,%3\n" \
11678 +- " .align 2,0x90\n" \
11679 +- "0: rep; movsl\n" \
11680 +- " movl %3,%0\n" \
11681 +- "1: rep; movsb\n" \
11682 +- "2:\n" \
11683 +- ".section .fixup,\"ax\"\n" \
11684 +- "5: addl %3,%0\n" \
11685 +- " jmp 6f\n" \
11686 +- "3: lea 0(%3,%0,4),%0\n" \
11687 +- "6: pushl %0\n" \
11688 +- " pushl %%eax\n" \
11689 +- " xorl %%eax,%%eax\n" \
11690 +- " rep; stosb\n" \
11691 +- " popl %%eax\n" \
11692 +- " popl %0\n" \
11693 +- " jmp 2b\n" \
11694 +- ".previous\n" \
11695 +- ".section __ex_table,\"a\"\n" \
11696 +- " .align 4\n" \
11697 +- " .long 4b,5b\n" \
11698 +- " .long 0b,3b\n" \
11699 +- " .long 1b,6b\n" \
11700 +- ".previous" \
11701 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
11702 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
11703 +- : "memory"); \
11704 +-} while (0)
11705 ++static unsigned long
11706 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
11707 ++{
11708 ++ int __d0, __d1, __d2;
11709 ++
11710 ++ __asm__ __volatile__(
11711 ++ " movw %w8,%%es\n"
11712 ++ " cmp $7,%0\n"
11713 ++ " jbe 1f\n"
11714 ++ " movl %1,%0\n"
11715 ++ " negl %0\n"
11716 ++ " andl $7,%0\n"
11717 ++ " subl %0,%3\n"
11718 ++ "4: rep; movsb\n"
11719 ++ " movl %3,%0\n"
11720 ++ " shrl $2,%0\n"
11721 ++ " andl $3,%3\n"
11722 ++ " .align 2,0x90\n"
11723 ++ "0: rep; movsl\n"
11724 ++ " movl %3,%0\n"
11725 ++ "1: rep; movsb\n"
11726 ++ "2:\n"
11727 ++ " pushl %%ss\n"
11728 ++ " popl %%es\n"
11729 ++ ".section .fixup,\"ax\"\n"
11730 ++ "5: addl %3,%0\n"
11731 ++ " jmp 2b\n"
11732 ++ "3: lea 0(%3,%0,4),%0\n"
11733 ++ " jmp 2b\n"
11734 ++ ".previous\n"
11735 ++ ".section __ex_table,\"a\"\n"
11736 ++ " .align 4\n"
11737 ++ " .long 4b,5b\n"
11738 ++ " .long 0b,3b\n"
11739 ++ " .long 1b,2b\n"
11740 ++ ".previous"
11741 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11742 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11743 ++ : "memory");
11744 ++ return size;
11745 ++}
11746 ++
11747 ++static unsigned long
11748 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
11749 ++{
11750 ++ int __d0, __d1, __d2;
11751 ++
11752 ++ __asm__ __volatile__(
11753 ++ " movw %w8,%%ds\n"
11754 ++ " cmp $7,%0\n"
11755 ++ " jbe 1f\n"
11756 ++ " movl %1,%0\n"
11757 ++ " negl %0\n"
11758 ++ " andl $7,%0\n"
11759 ++ " subl %0,%3\n"
11760 ++ "4: rep; movsb\n"
11761 ++ " movl %3,%0\n"
11762 ++ " shrl $2,%0\n"
11763 ++ " andl $3,%3\n"
11764 ++ " .align 2,0x90\n"
11765 ++ "0: rep; movsl\n"
11766 ++ " movl %3,%0\n"
11767 ++ "1: rep; movsb\n"
11768 ++ "2:\n"
11769 ++ " pushl %%ss\n"
11770 ++ " popl %%ds\n"
11771 ++ ".section .fixup,\"ax\"\n"
11772 ++ "5: addl %3,%0\n"
11773 ++ " jmp 2b\n"
11774 ++ "3: lea 0(%3,%0,4),%0\n"
11775 ++ " jmp 2b\n"
11776 ++ ".previous\n"
11777 ++ ".section __ex_table,\"a\"\n"
11778 ++ " .align 4\n"
11779 ++ " .long 4b,5b\n"
11780 ++ " .long 0b,3b\n"
11781 ++ " .long 1b,2b\n"
11782 ++ ".previous"
11783 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11784 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11785 ++ : "memory");
11786 ++ return size;
11787 ++}
11788 ++
11789 ++static unsigned long
11790 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
11791 ++{
11792 ++ int __d0, __d1, __d2;
11793 ++
11794 ++ __asm__ __volatile__(
11795 ++ " movw %w8,%%ds\n"
11796 ++ " cmp $7,%0\n"
11797 ++ " jbe 1f\n"
11798 ++ " movl %1,%0\n"
11799 ++ " negl %0\n"
11800 ++ " andl $7,%0\n"
11801 ++ " subl %0,%3\n"
11802 ++ "4: rep; movsb\n"
11803 ++ " movl %3,%0\n"
11804 ++ " shrl $2,%0\n"
11805 ++ " andl $3,%3\n"
11806 ++ " .align 2,0x90\n"
11807 ++ "0: rep; movsl\n"
11808 ++ " movl %3,%0\n"
11809 ++ "1: rep; movsb\n"
11810 ++ "2:\n"
11811 ++ " pushl %%ss\n"
11812 ++ " popl %%ds\n"
11813 ++ ".section .fixup,\"ax\"\n"
11814 ++ "5: addl %3,%0\n"
11815 ++ " jmp 6f\n"
11816 ++ "3: lea 0(%3,%0,4),%0\n"
11817 ++ "6: pushl %0\n"
11818 ++ " pushl %%eax\n"
11819 ++ " xorl %%eax,%%eax\n"
11820 ++ " rep; stosb\n"
11821 ++ " popl %%eax\n"
11822 ++ " popl %0\n"
11823 ++ " jmp 2b\n"
11824 ++ ".previous\n"
11825 ++ ".section __ex_table,\"a\"\n"
11826 ++ " .align 4\n"
11827 ++ " .long 4b,5b\n"
11828 ++ " .long 0b,3b\n"
11829 ++ " .long 1b,6b\n"
11830 ++ ".previous"
11831 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11832 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11833 ++ : "memory");
11834 ++ return size;
11835 ++}
11836 +
11837 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
11838 + unsigned long n)
11839 +@@ -768,9 +959,9 @@ survive:
11840 + }
11841 + #endif
11842 + if (movsl_is_ok(to, from, n))
11843 +- __copy_user(to, from, n);
11844 ++ n = __generic_copy_to_user(to, from, n);
11845 + else
11846 +- n = __copy_user_intel(to, from, n);
11847 ++ n = __generic_copy_to_user_intel(to, from, n);
11848 + return n;
11849 + }
11850 + EXPORT_SYMBOL(__copy_to_user_ll);
11851 +@@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
11852 + unsigned long n)
11853 + {
11854 + if (movsl_is_ok(to, from, n))
11855 +- __copy_user_zeroing(to, from, n);
11856 ++ n = __copy_user_zeroing(to, from, n);
11857 + else
11858 + n = __copy_user_zeroing_intel(to, from, n);
11859 + return n;
11860 +@@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
11861 + unsigned long n)
11862 + {
11863 + if (movsl_is_ok(to, from, n))
11864 +- __copy_user(to, from, n);
11865 ++ n = __generic_copy_from_user(to, from, n);
11866 + else
11867 +- n = __copy_user_intel((void __user *)to,
11868 +- (const void *)from, n);
11869 ++ n = __generic_copy_from_user_intel(to, from, n);
11870 + return n;
11871 + }
11872 + EXPORT_SYMBOL(__copy_from_user_ll_nozero);
11873 +@@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
11874 + unsigned long n)
11875 + {
11876 + #ifdef CONFIG_X86_INTEL_USERCOPY
11877 +- if (n > 64 && cpu_has_xmm2)
11878 ++ if ( n > 64 && cpu_has_xmm2)
11879 + n = __copy_user_zeroing_intel_nocache(to, from, n);
11880 + else
11881 +- __copy_user_zeroing(to, from, n);
11882 ++ n = __copy_user_zeroing(to, from, n);
11883 + #else
11884 +- __copy_user_zeroing(to, from, n);
11885 ++ n = __copy_user_zeroing(to, from, n);
11886 + #endif
11887 + return n;
11888 + }
11889 +@@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
11890 + unsigned long n)
11891 + {
11892 + #ifdef CONFIG_X86_INTEL_USERCOPY
11893 +- if (n > 64 && cpu_has_xmm2)
11894 ++ if ( n > 64 && cpu_has_xmm2)
11895 + n = __copy_user_intel_nocache(to, from, n);
11896 + else
11897 +- __copy_user(to, from, n);
11898 ++ n = __generic_copy_from_user(to, from, n);
11899 + #else
11900 +- __copy_user(to, from, n);
11901 ++ n = __generic_copy_from_user(to, from, n);
11902 + #endif
11903 + return n;
11904 + }
11905 +@@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
11906 + {
11907 + if (access_ok(VERIFY_READ, from, n))
11908 + n = __copy_from_user(to, from, n);
11909 +- else
11910 ++ else if ((long)n > 0)
11911 + memset(to, 0, n);
11912 + return n;
11913 + }
11914 + EXPORT_SYMBOL(copy_from_user);
11915 ++
11916 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
11917 ++void __set_fs(mm_segment_t x, int cpu)
11918 ++{
11919 ++ unsigned long limit = x.seg;
11920 ++ struct desc_struct d;
11921 ++
11922 ++ current_thread_info()->addr_limit = x;
11923 ++ if (likely(limit))
11924 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
11925 ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
11926 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
11927 ++}
11928 ++
11929 ++void set_fs(mm_segment_t x)
11930 ++{
11931 ++ __set_fs(x, get_cpu());
11932 ++ put_cpu_no_resched();
11933 ++}
11934 ++#else
11935 ++void set_fs(mm_segment_t x)
11936 ++{
11937 ++ current_thread_info()->addr_limit = x;
11938 ++}
11939 ++#endif
11940 ++
11941 ++EXPORT_SYMBOL(set_fs);
11942 +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
11943 +--- linux-2.6.26.6/arch/x86/mach-voyager/voyager_basic.c 2008-10-08 23:24:05.000000000 -0400
11944 ++++ linux-2.6.26.6/arch/x86/mach-voyager/voyager_basic.c 2008-10-11 21:54:19.000000000 -0400
11945 +@@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
11946 + __u8 cmos[4];
11947 + ClickMap_t *map;
11948 + unsigned long map_addr;
11949 +- unsigned long old;
11950 ++ pte_t old;
11951 +
11952 + if (region >= CLICK_ENTRIES) {
11953 + printk("Voyager: Illegal ClickMap region %d\n", region);
11954 +@@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
11955 +
11956 + /* steal page 0 for this */
11957 + old = pg0[0];
11958 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
11959 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
11960 + local_flush_tlb();
11961 + /* now clear everything out but page 0 */
11962 + map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
11963 +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
11964 +--- linux-2.6.26.6/arch/x86/mach-voyager/voyager_smp.c 2008-10-08 23:24:05.000000000 -0400
11965 ++++ linux-2.6.26.6/arch/x86/mach-voyager/voyager_smp.c 2008-10-11 21:54:19.000000000 -0400
11966 +@@ -515,6 +515,10 @@ static void __init do_boot_cpu(__u8 cpu)
11967 + __u32 *hijack_vector;
11968 + __u32 start_phys_address = setup_trampoline();
11969 +
11970 ++#ifdef CONFIG_PAX_KERNEXEC
11971 ++ unsigned long cr0;
11972 ++#endif
11973 ++
11974 + /* There's a clever trick to this: The linux trampoline is
11975 + * compiled to begin at absolute location zero, so make the
11976 + * address zero but have the data segment selector compensate
11977 +@@ -534,7 +538,17 @@ static void __init do_boot_cpu(__u8 cpu)
11978 +
11979 + init_gdt(cpu);
11980 + per_cpu(current_task, cpu) = idle;
11981 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
11982 ++
11983 ++#ifdef CONFIG_PAX_KERNEXEC
11984 ++ pax_open_kernel(cr0);
11985 ++#endif
11986 ++
11987 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
11988 ++
11989 ++#ifdef CONFIG_PAX_KERNEXEC
11990 ++ pax_close_kernel(cr0);
11991 ++#endif
11992 ++
11993 + irq_ctx_init(cpu);
11994 +
11995 + /* Note: Don't modify initial ss override */
11996 +@@ -1217,7 +1231,7 @@ void smp_local_timer_interrupt(void)
11997 + per_cpu(prof_counter, cpu);
11998 + }
11999 +
12000 +- update_process_times(user_mode_vm(get_irq_regs()));
12001 ++ update_process_times(user_mode(get_irq_regs()));
12002 + }
12003 +
12004 + if (((1 << cpu) & voyager_extended_vic_processors) == 0)
12005 +diff -urNp linux-2.6.26.6/arch/x86/Makefile linux-2.6.26.6/arch/x86/Makefile
12006 +--- linux-2.6.26.6/arch/x86/Makefile 2008-10-08 23:24:05.000000000 -0400
12007 ++++ linux-2.6.26.6/arch/x86/Makefile 2008-10-11 21:54:19.000000000 -0400
12008 +@@ -258,3 +258,12 @@ endef
12009 + CLEAN_FILES += arch/x86/boot/fdimage \
12010 + arch/x86/boot/image.iso \
12011 + arch/x86/boot/mtools.conf
12012 ++
12013 ++define OLD_LD
12014 ++
12015 ++*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
12016 ++*** Please upgrade your binutils to 2.18 or newer
12017 ++endef
12018 ++
12019 ++archprepare:
12020 ++ $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
12021 +diff -urNp linux-2.6.26.6/arch/x86/mm/discontig_32.c linux-2.6.26.6/arch/x86/mm/discontig_32.c
12022 +--- linux-2.6.26.6/arch/x86/mm/discontig_32.c 2008-10-08 23:24:05.000000000 -0400
12023 ++++ linux-2.6.26.6/arch/x86/mm/discontig_32.c 2008-10-11 21:55:52.000000000 -0400
12024 +@@ -311,7 +311,7 @@ void __init remap_numa_kva(void)
12025 + #endif /* CONFIG_DISCONTIGMEM */
12026 +
12027 + extern void setup_bootmem_allocator(void);
12028 +-unsigned long __init setup_memory(void)
12029 ++unsigned void __init setup_memory(void)
12030 + {
12031 + int nid;
12032 + unsigned long system_start_pfn, system_max_low_pfn;
12033 +@@ -384,7 +384,6 @@ unsigned long __init setup_memory(void)
12034 + memset(NODE_DATA(0), 0, sizeof(struct pglist_data));
12035 + NODE_DATA(0)->bdata = &node0_bdata;
12036 + setup_bootmem_allocator();
12037 +- return max_low_pfn;
12038 + }
12039 +
12040 + void __init numa_kva_reserve(void)
12041 +diff -urNp linux-2.6.26.6/arch/x86/mm/extable.c linux-2.6.26.6/arch/x86/mm/extable.c
12042 +--- linux-2.6.26.6/arch/x86/mm/extable.c 2008-10-08 23:24:05.000000000 -0400
12043 ++++ linux-2.6.26.6/arch/x86/mm/extable.c 2008-10-11 21:55:07.000000000 -0400
12044 +@@ -1,14 +1,62 @@
12045 + #include <linux/module.h>
12046 + #include <linux/spinlock.h>
12047 ++#include <linux/sort.h>
12048 + #include <asm/uaccess.h>
12049 +
12050 ++/*
12051 ++ * The exception table needs to be sorted so that the binary
12052 ++ * search that we use to find entries in it works properly.
12053 ++ * This is used both for the kernel exception table and for
12054 ++ * the exception tables of modules that get loaded.
12055 ++ */
12056 ++static int cmp_ex(const void *a, const void *b)
12057 ++{
12058 ++ const struct exception_table_entry *x = a, *y = b;
12059 ++
12060 ++ /* avoid overflow */
12061 ++ if (x->insn > y->insn)
12062 ++ return 1;
12063 ++ if (x->insn < y->insn)
12064 ++ return -1;
12065 ++ return 0;
12066 ++}
12067 ++
12068 ++static void swap_ex(void *a, void *b, int size)
12069 ++{
12070 ++ struct exception_table_entry t, *x = a, *y = b;
12071 ++
12072 ++#ifdef CONFIG_PAX_KERNEXEC
12073 ++ unsigned long cr0;
12074 ++#endif
12075 ++
12076 ++ t = *x;
12077 ++
12078 ++#ifdef CONFIG_PAX_KERNEXEC
12079 ++ pax_open_kernel(cr0);
12080 ++#endif
12081 ++
12082 ++ *x = *y;
12083 ++ *y = t;
12084 ++
12085 ++#ifdef CONFIG_PAX_KERNEXEC
12086 ++ pax_close_kernel(cr0);
12087 ++#endif
12088 ++
12089 ++}
12090 ++
12091 ++void sort_extable(struct exception_table_entry *start,
12092 ++ struct exception_table_entry *finish)
12093 ++{
12094 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
12095 ++ cmp_ex, swap_ex);
12096 ++}
12097 +
12098 + int fixup_exception(struct pt_regs *regs)
12099 + {
12100 + const struct exception_table_entry *fixup;
12101 +
12102 + #ifdef CONFIG_PNPBIOS
12103 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
12104 ++ if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
12105 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
12106 + extern u32 pnp_bios_is_utter_crap;
12107 + pnp_bios_is_utter_crap = 1;
12108 +diff -urNp linux-2.6.26.6/arch/x86/mm/fault.c linux-2.6.26.6/arch/x86/mm/fault.c
12109 +--- linux-2.6.26.6/arch/x86/mm/fault.c 2008-10-08 23:24:05.000000000 -0400
12110 ++++ linux-2.6.26.6/arch/x86/mm/fault.c 2008-10-11 21:55:07.000000000 -0400
12111 +@@ -25,6 +25,8 @@
12112 + #include <linux/kprobes.h>
12113 + #include <linux/uaccess.h>
12114 + #include <linux/kdebug.h>
12115 ++#include <linux/unistd.h>
12116 ++#include <linux/compiler.h>
12117 +
12118 + #include <asm/system.h>
12119 + #include <asm/desc.h>
12120 +@@ -34,6 +36,7 @@
12121 + #include <asm/tlbflush.h>
12122 + #include <asm/proto.h>
12123 + #include <asm-generic/sections.h>
12124 ++#include <asm/tlbflush.h>
12125 +
12126 + /*
12127 + * Page fault error code bits
12128 +@@ -55,11 +58,7 @@ static inline int notify_page_fault(stru
12129 + int ret = 0;
12130 +
12131 + /* kprobe_running() needs smp_processor_id() */
12132 +-#ifdef CONFIG_X86_32
12133 +- if (!user_mode_vm(regs)) {
12134 +-#else
12135 + if (!user_mode(regs)) {
12136 +-#endif
12137 + preempt_disable();
12138 + if (kprobe_running() && kprobe_fault_handler(regs, 14))
12139 + ret = 1;
12140 +@@ -257,6 +256,30 @@ bad:
12141 + #endif
12142 + }
12143 +
12144 ++#ifdef CONFIG_PAX_EMUTRAMP
12145 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
12146 ++#endif
12147 ++
12148 ++#ifdef CONFIG_PAX_PAGEEXEC
12149 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
12150 ++{
12151 ++ pgd_t *pgd;
12152 ++ pud_t *pud;
12153 ++ pmd_t *pmd;
12154 ++
12155 ++ pgd = pgd_offset(mm, address);
12156 ++ if (!pgd_present(*pgd))
12157 ++ return NULL;
12158 ++ pud = pud_offset(pgd, address);
12159 ++ if (!pud_present(*pud))
12160 ++ return NULL;
12161 ++ pmd = pmd_offset(pud, address);
12162 ++ if (!pmd_present(*pmd))
12163 ++ return NULL;
12164 ++ return pmd;
12165 ++}
12166 ++#endif
12167 ++
12168 + #ifdef CONFIG_X86_32
12169 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
12170 + {
12171 +@@ -343,7 +366,7 @@ static int is_errata93(struct pt_regs *r
12172 + static int is_errata100(struct pt_regs *regs, unsigned long address)
12173 + {
12174 + #ifdef CONFIG_X86_64
12175 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
12176 ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
12177 + (address >> 32))
12178 + return 1;
12179 + #endif
12180 +@@ -380,17 +403,32 @@ static void show_fault_oops(struct pt_re
12181 + #endif
12182 +
12183 + #ifdef CONFIG_X86_PAE
12184 +- if (error_code & PF_INSTR) {
12185 ++ if (nx_enabled && (error_code & PF_INSTR)) {
12186 + unsigned int level;
12187 + pte_t *pte = lookup_address(address, &level);
12188 +
12189 + if (pte && pte_present(*pte) && !pte_exec(*pte))
12190 + printk(KERN_CRIT "kernel tried to execute "
12191 + "NX-protected page - exploit attempt? "
12192 +- "(uid: %d)\n", current->uid);
12193 ++ "(uid: %d, task: %s, pid: %d)\n",
12194 ++ current->uid, current->comm, task_pid_nr(current));
12195 + }
12196 + #endif
12197 +
12198 ++#ifdef CONFIG_PAX_KERNEXEC
12199 ++#ifdef CONFIG_MODULES
12200 ++ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
12201 ++#else
12202 ++ if (init_mm.start_code <= address && address < init_mm.end_code)
12203 ++#endif
12204 ++ if (current->signal->curr_ip)
12205 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12206 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
12207 ++ else
12208 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
12209 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
12210 ++#endif
12211 ++
12212 + printk(KERN_ALERT "BUG: unable to handle kernel ");
12213 + if (address < PAGE_SIZE)
12214 + printk(KERN_CONT "NULL pointer dereference");
12215 +@@ -583,13 +621,22 @@ void __kprobes do_page_fault(struct pt_r
12216 + struct task_struct *tsk;
12217 + struct mm_struct *mm;
12218 + struct vm_area_struct *vma;
12219 +- unsigned long address;
12220 + int write, si_code;
12221 + int fault;
12222 + #ifdef CONFIG_X86_64
12223 + unsigned long flags;
12224 + #endif
12225 +
12226 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12227 ++ pte_t *pte;
12228 ++ pmd_t *pmd;
12229 ++ spinlock_t *ptl;
12230 ++ unsigned char pte_mask;
12231 ++#endif
12232 ++
12233 ++ /* get the address */
12234 ++ const unsigned long address = read_cr2();
12235 ++
12236 + /*
12237 + * We can fault from pretty much anywhere, with unknown IRQ state.
12238 + */
12239 +@@ -599,9 +646,6 @@ void __kprobes do_page_fault(struct pt_r
12240 + mm = tsk->mm;
12241 + prefetchw(&mm->mmap_sem);
12242 +
12243 +- /* get the address */
12244 +- address = read_cr2();
12245 +-
12246 + si_code = SEGV_MAPERR;
12247 +
12248 + if (notify_page_fault(regs))
12249 +@@ -652,7 +696,7 @@ void __kprobes do_page_fault(struct pt_r
12250 + * atomic region then we must not take the fault.
12251 + */
12252 + if (in_atomic() || !mm)
12253 +- goto bad_area_nosemaphore;
12254 ++ goto bad_area_nopax;
12255 + #else /* CONFIG_X86_64 */
12256 + if (likely(regs->flags & X86_EFLAGS_IF))
12257 + local_irq_enable();
12258 +@@ -665,13 +709,13 @@ void __kprobes do_page_fault(struct pt_r
12259 + * atomic region then we must not take the fault.
12260 + */
12261 + if (unlikely(in_atomic() || !mm))
12262 +- goto bad_area_nosemaphore;
12263 ++ goto bad_area_nopax;
12264 +
12265 + /*
12266 + * User-mode registers count as a user access even for any
12267 + * potential system fault or CPU buglet.
12268 + */
12269 +- if (user_mode_vm(regs))
12270 ++ if (user_mode(regs))
12271 + error_code |= PF_USER;
12272 + again:
12273 + #endif
12274 +@@ -693,10 +737,104 @@ again:
12275 + if (!down_read_trylock(&mm->mmap_sem)) {
12276 + if ((error_code & PF_USER) == 0 &&
12277 + !search_exception_tables(regs->ip))
12278 +- goto bad_area_nosemaphore;
12279 ++ goto bad_area_nopax;
12280 + down_read(&mm->mmap_sem);
12281 + }
12282 +
12283 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
12284 ++ if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
12285 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
12286 ++ goto not_pax_fault;
12287 ++
12288 ++ /* PaX: it's our fault, let's handle it if we can */
12289 ++
12290 ++ /* PaX: take a look at read faults before acquiring any locks */
12291 ++ if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
12292 ++ /* instruction fetch attempt from a protected page in user mode */
12293 ++ up_read(&mm->mmap_sem);
12294 ++
12295 ++#ifdef CONFIG_PAX_EMUTRAMP
12296 ++ switch (pax_handle_fetch_fault(regs)) {
12297 ++ case 2:
12298 ++ return;
12299 ++ }
12300 ++#endif
12301 ++
12302 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12303 ++ do_group_exit(SIGKILL);
12304 ++ }
12305 ++
12306 ++ pmd = pax_get_pmd(mm, address);
12307 ++ if (unlikely(!pmd))
12308 ++ goto not_pax_fault;
12309 ++
12310 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
12311 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
12312 ++ pte_unmap_unlock(pte, ptl);
12313 ++ goto not_pax_fault;
12314 ++ }
12315 ++
12316 ++ if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
12317 ++ /* write attempt to a protected page in user mode */
12318 ++ pte_unmap_unlock(pte, ptl);
12319 ++ goto not_pax_fault;
12320 ++ }
12321 ++
12322 ++#ifdef CONFIG_SMP
12323 ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
12324 ++#else
12325 ++ if (likely(address > get_limit(regs->cs)))
12326 ++#endif
12327 ++ {
12328 ++ set_pte(pte, pte_mkread(*pte));
12329 ++ __flush_tlb_one(address);
12330 ++ pte_unmap_unlock(pte, ptl);
12331 ++ up_read(&mm->mmap_sem);
12332 ++ return;
12333 ++ }
12334 ++
12335 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
12336 ++
12337 ++ /*
12338 ++ * PaX: fill DTLB with user rights and retry
12339 ++ */
12340 ++ __asm__ __volatile__ (
12341 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12342 ++ "movw %w4,%%es\n"
12343 ++#endif
12344 ++ "orb %2,(%1)\n"
12345 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
12346 ++/*
12347 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
12348 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
12349 ++ * page fault when examined during a TLB load attempt. this is true not only
12350 ++ * for PTEs holding a non-present entry but also present entries that will
12351 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
12352 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
12353 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
12354 ++
12355 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
12356 ++ * fast path of the page fault handler and can get rid of tracing since we
12357 ++ * can no longer flush unintended entries.
12358 ++ */
12359 ++ "invlpg (%0)\n"
12360 ++#endif
12361 ++ "testb $0,%%es:(%0)\n"
12362 ++ "xorb %3,(%1)\n"
12363 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12364 ++ "pushl %%ss\n"
12365 ++ "popl %%es\n"
12366 ++#endif
12367 ++ :
12368 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
12369 ++ : "memory", "cc");
12370 ++ pte_unmap_unlock(pte, ptl);
12371 ++ up_read(&mm->mmap_sem);
12372 ++ return;
12373 ++
12374 ++not_pax_fault:
12375 ++#endif
12376 ++
12377 + vma = find_vma(mm, address);
12378 + if (!vma)
12379 + goto bad_area;
12380 +@@ -714,6 +852,12 @@ again:
12381 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
12382 + goto bad_area;
12383 + }
12384 ++
12385 ++#ifdef CONFIG_PAX_SEGMEXEC
12386 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
12387 ++ goto bad_area;
12388 ++#endif
12389 ++
12390 + if (expand_stack(vma, address))
12391 + goto bad_area;
12392 + /*
12393 +@@ -723,6 +867,8 @@ again:
12394 + good_area:
12395 + si_code = SEGV_ACCERR;
12396 + write = 0;
12397 ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
12398 ++ goto bad_area;
12399 + switch (error_code & (PF_PROT|PF_WRITE)) {
12400 + default: /* 3: write, present */
12401 + /* fall through */
12402 +@@ -780,6 +926,54 @@ bad_area:
12403 + up_read(&mm->mmap_sem);
12404 +
12405 + bad_area_nosemaphore:
12406 ++
12407 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12408 ++ if (mm && (error_code & PF_USER)) {
12409 ++ unsigned long ip = regs->ip;
12410 ++
12411 ++ if (v8086_mode(regs))
12412 ++ ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
12413 ++
12414 ++ /*
12415 ++ * It's possible to have interrupts off here.
12416 ++ */
12417 ++ local_irq_enable();
12418 ++
12419 ++#ifdef CONFIG_PAX_PAGEEXEC
12420 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
12421 ++ (nx_enabled && ((error_code & PF_INSTR) || !(error_code & (PF_PROT | PF_WRITE))) && (regs->ip == address))) {
12422 ++
12423 ++#ifdef CONFIG_PAX_EMUTRAMP
12424 ++ switch (pax_handle_fetch_fault(regs)) {
12425 ++ case 2:
12426 ++ return;
12427 ++ }
12428 ++#endif
12429 ++
12430 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12431 ++ do_group_exit(SIGKILL);
12432 ++ }
12433 ++#endif
12434 ++
12435 ++#ifdef CONFIG_PAX_SEGMEXEC
12436 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
12437 ++
12438 ++#ifdef CONFIG_PAX_EMUTRAMP
12439 ++ switch (pax_handle_fetch_fault(regs)) {
12440 ++ case 2:
12441 ++ return;
12442 ++ }
12443 ++#endif
12444 ++
12445 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
12446 ++ do_group_exit(SIGKILL);
12447 ++ }
12448 ++#endif
12449 ++
12450 ++ }
12451 ++#endif
12452 ++
12453 ++bad_area_nopax:
12454 + /* User mode accesses just cause a SIGSEGV */
12455 + if (error_code & PF_USER) {
12456 + /*
12457 +@@ -862,7 +1056,7 @@ no_context:
12458 + #ifdef CONFIG_X86_32
12459 + die("Oops", regs, error_code);
12460 + bust_spinlocks(0);
12461 +- do_exit(SIGKILL);
12462 ++ do_group_exit(SIGKILL);
12463 + #else
12464 + if (__die("Oops", regs, error_code))
12465 + regs = NULL;
12466 +@@ -876,17 +1070,17 @@ no_context:
12467 + * us unable to handle the page fault gracefully.
12468 + */
12469 + out_of_memory:
12470 +- up_read(&mm->mmap_sem);
12471 + if (is_global_init(tsk)) {
12472 + yield();
12473 + #ifdef CONFIG_X86_32
12474 +- down_read(&mm->mmap_sem);
12475 + goto survive;
12476 + #else
12477 ++ up_read(&mm->mmap_sem);
12478 + goto again;
12479 + #endif
12480 + }
12481 +
12482 ++ up_read(&mm->mmap_sem);
12483 + printk("VM: killing process %s\n", tsk->comm);
12484 + if (error_code & PF_USER)
12485 + do_group_exit(SIGKILL);
12486 +@@ -983,3 +1177,174 @@ void vmalloc_sync_all(void)
12487 + }
12488 + #endif
12489 + }
12490 ++
12491 ++#ifdef CONFIG_PAX_EMUTRAMP
12492 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
12493 ++{
12494 ++ int err;
12495 ++
12496 ++ do { /* PaX: gcc trampoline emulation #1 */
12497 ++ unsigned char mov1, mov2;
12498 ++ unsigned short jmp;
12499 ++ unsigned int addr1, addr2;
12500 ++
12501 ++#ifdef CONFIG_X86_64
12502 ++ if ((regs->ip + 11) >> 32)
12503 ++ break;
12504 ++#endif
12505 ++
12506 ++ err = get_user(mov1, (unsigned char __user *)regs->ip);
12507 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12508 ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
12509 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12510 ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
12511 ++
12512 ++ if (err)
12513 ++ break;
12514 ++
12515 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
12516 ++ regs->cx = addr1;
12517 ++ regs->ax = addr2;
12518 ++ regs->ip = addr2;
12519 ++ return 2;
12520 ++ }
12521 ++ } while (0);
12522 ++
12523 ++ do { /* PaX: gcc trampoline emulation #2 */
12524 ++ unsigned char mov, jmp;
12525 ++ unsigned int addr1, addr2;
12526 ++
12527 ++#ifdef CONFIG_X86_64
12528 ++ if ((regs->ip + 9) >> 32)
12529 ++ break;
12530 ++#endif
12531 ++
12532 ++ err = get_user(mov, (unsigned char __user *)regs->ip);
12533 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
12534 ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
12535 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
12536 ++
12537 ++ if (err)
12538 ++ break;
12539 ++
12540 ++ if (mov == 0xB9 && jmp == 0xE9) {
12541 ++ regs->cx = addr1;
12542 ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
12543 ++ return 2;
12544 ++ }
12545 ++ } while (0);
12546 ++
12547 ++ return 1; /* PaX in action */
12548 ++}
12549 ++
12550 ++#ifdef CONFIG_X86_64
12551 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
12552 ++{
12553 ++ int err;
12554 ++
12555 ++ do { /* PaX: gcc trampoline emulation #1 */
12556 ++ unsigned short mov1, mov2, jmp1;
12557 ++ unsigned char jmp2;
12558 ++ unsigned int addr1;
12559 ++ unsigned long addr2;
12560 ++
12561 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
12562 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
12563 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
12564 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
12565 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
12566 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
12567 ++
12568 ++ if (err)
12569 ++ break;
12570 ++
12571 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
12572 ++ regs->r11 = addr1;
12573 ++ regs->r10 = addr2;
12574 ++ regs->ip = addr1;
12575 ++ return 2;
12576 ++ }
12577 ++ } while (0);
12578 ++
12579 ++ do { /* PaX: gcc trampoline emulation #2 */
12580 ++ unsigned short mov1, mov2, jmp1;
12581 ++ unsigned char jmp2;
12582 ++ unsigned long addr1, addr2;
12583 ++
12584 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
12585 ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
12586 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
12587 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
12588 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
12589 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
12590 ++
12591 ++ if (err)
12592 ++ break;
12593 ++
12594 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
12595 ++ regs->r11 = addr1;
12596 ++ regs->r10 = addr2;
12597 ++ regs->ip = addr1;
12598 ++ return 2;
12599 ++ }
12600 ++ } while (0);
12601 ++
12602 ++ return 1; /* PaX in action */
12603 ++}
12604 ++#endif
12605 ++
12606 ++/*
12607 ++ * PaX: decide what to do with offenders (regs->ip = fault address)
12608 ++ *
12609 ++ * returns 1 when task should be killed
12610 ++ * 2 when gcc trampoline was detected
12611 ++ */
12612 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
12613 ++{
12614 ++ if (v8086_mode(regs))
12615 ++ return 1;
12616 ++
12617 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
12618 ++ return 1;
12619 ++
12620 ++#ifdef CONFIG_X86_32
12621 ++ return pax_handle_fetch_fault_32(regs);
12622 ++#else
12623 ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
12624 ++ return pax_handle_fetch_fault_32(regs);
12625 ++ else
12626 ++ return pax_handle_fetch_fault_64(regs);
12627 ++#endif
12628 ++}
12629 ++#endif
12630 ++
12631 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12632 ++void pax_report_insns(void *pc, void *sp)
12633 ++{
12634 ++ long i;
12635 ++
12636 ++ printk(KERN_ERR "PAX: bytes at PC: ");
12637 ++ for (i = 0; i < 20; i++) {
12638 ++ unsigned char c;
12639 ++ if (get_user(c, (unsigned char __user *)pc+i))
12640 ++ printk(KERN_CONT "?? ");
12641 ++ else
12642 ++ printk(KERN_CONT "%02x ", c);
12643 ++ }
12644 ++ printk("\n");
12645 ++
12646 ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
12647 ++ for (i = -1; i < 80 / sizeof(long); i++) {
12648 ++ unsigned long c;
12649 ++ if (get_user(c, (unsigned long __user *)sp+i))
12650 ++#ifdef CONFIG_X86_32
12651 ++ printk(KERN_CONT "???????? ");
12652 ++#else
12653 ++ printk(KERN_CONT "???????????????? ");
12654 ++#endif
12655 ++ else
12656 ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
12657 ++ }
12658 ++ printk("\n");
12659 ++}
12660 ++#endif
12661 +diff -urNp linux-2.6.26.6/arch/x86/mm/highmem_32.c linux-2.6.26.6/arch/x86/mm/highmem_32.c
12662 +--- linux-2.6.26.6/arch/x86/mm/highmem_32.c 2008-10-08 23:24:05.000000000 -0400
12663 ++++ linux-2.6.26.6/arch/x86/mm/highmem_32.c 2008-10-11 21:54:19.000000000 -0400
12664 +@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
12665 + enum fixed_addresses idx;
12666 + unsigned long vaddr;
12667 +
12668 ++#ifdef CONFIG_PAX_KERNEXEC
12669 ++ unsigned long cr0;
12670 ++#endif
12671 ++
12672 + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
12673 + pagefault_disable();
12674 +
12675 +@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
12676 + idx = type + KM_TYPE_NR*smp_processor_id();
12677 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
12678 + BUG_ON(!pte_none(*(kmap_pte-idx)));
12679 ++
12680 ++#ifdef CONFIG_PAX_KERNEXEC
12681 ++ pax_open_kernel(cr0);
12682 ++#endif
12683 ++
12684 + set_pte(kmap_pte-idx, mk_pte(page, prot));
12685 ++
12686 ++#ifdef CONFIG_PAX_KERNEXEC
12687 ++ pax_close_kernel(cr0);
12688 ++#endif
12689 ++
12690 + arch_flush_lazy_mmu_mode();
12691 +
12692 + return (void *)vaddr;
12693 +@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
12694 + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
12695 + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
12696 +
12697 ++#ifdef CONFIG_PAX_KERNEXEC
12698 ++ unsigned long cr0;
12699 ++#endif
12700 ++
12701 + /*
12702 + * Force other mappings to Oops if they'll try to access this pte
12703 + * without first remap it. Keeping stale mappings around is a bad idea
12704 + * also, in case the page changes cacheability attributes or becomes
12705 + * a protected page in a hypervisor.
12706 + */
12707 +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
12708 ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
12709 ++
12710 ++#ifdef CONFIG_PAX_KERNEXEC
12711 ++ pax_open_kernel(cr0);
12712 ++#endif
12713 ++
12714 + kpte_clear_flush(kmap_pte-idx, vaddr);
12715 +- else {
12716 ++
12717 ++#ifdef CONFIG_PAX_KERNEXEC
12718 ++ pax_close_kernel(cr0);
12719 ++#endif
12720 ++
12721 ++ } else {
12722 + #ifdef CONFIG_DEBUG_HIGHMEM
12723 + BUG_ON(vaddr < PAGE_OFFSET);
12724 + BUG_ON(vaddr >= (unsigned long)high_memory);
12725 +@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
12726 + enum fixed_addresses idx;
12727 + unsigned long vaddr;
12728 +
12729 ++#ifdef CONFIG_PAX_KERNEXEC
12730 ++ unsigned long cr0;
12731 ++#endif
12732 ++
12733 + pagefault_disable();
12734 +
12735 + idx = type + KM_TYPE_NR*smp_processor_id();
12736 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
12737 ++
12738 ++#ifdef CONFIG_PAX_KERNEXEC
12739 ++ pax_open_kernel(cr0);
12740 ++#endif
12741 ++
12742 + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
12743 ++
12744 ++#ifdef CONFIG_PAX_KERNEXEC
12745 ++ pax_close_kernel(cr0);
12746 ++#endif
12747 ++
12748 + arch_flush_lazy_mmu_mode();
12749 +
12750 + return (void*) vaddr;
12751 +diff -urNp linux-2.6.26.6/arch/x86/mm/hugetlbpage.c linux-2.6.26.6/arch/x86/mm/hugetlbpage.c
12752 +--- linux-2.6.26.6/arch/x86/mm/hugetlbpage.c 2008-10-08 23:24:05.000000000 -0400
12753 ++++ linux-2.6.26.6/arch/x86/mm/hugetlbpage.c 2008-10-11 21:54:19.000000000 -0400
12754 +@@ -230,13 +230,18 @@ static unsigned long hugetlb_get_unmappe
12755 + {
12756 + struct mm_struct *mm = current->mm;
12757 + struct vm_area_struct *vma;
12758 +- unsigned long start_addr;
12759 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
12760 ++
12761 ++#ifdef CONFIG_PAX_SEGMEXEC
12762 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12763 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12764 ++#endif
12765 +
12766 + if (len > mm->cached_hole_size) {
12767 +- start_addr = mm->free_area_cache;
12768 ++ start_addr = mm->free_area_cache;
12769 + } else {
12770 +- start_addr = TASK_UNMAPPED_BASE;
12771 +- mm->cached_hole_size = 0;
12772 ++ start_addr = mm->mmap_base;
12773 ++ mm->cached_hole_size = 0;
12774 + }
12775 +
12776 + full_search:
12777 +@@ -244,13 +249,13 @@ full_search:
12778 +
12779 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
12780 + /* At this point: (!vma || addr < vma->vm_end). */
12781 +- if (TASK_SIZE - len < addr) {
12782 ++ if (pax_task_size - len < addr) {
12783 + /*
12784 + * Start a new search - just in case we missed
12785 + * some holes.
12786 + */
12787 +- if (start_addr != TASK_UNMAPPED_BASE) {
12788 +- start_addr = TASK_UNMAPPED_BASE;
12789 ++ if (start_addr != mm->mmap_base) {
12790 ++ start_addr = mm->mmap_base;
12791 + mm->cached_hole_size = 0;
12792 + goto full_search;
12793 + }
12794 +@@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
12795 + {
12796 + struct mm_struct *mm = current->mm;
12797 + struct vm_area_struct *vma, *prev_vma;
12798 +- unsigned long base = mm->mmap_base, addr = addr0;
12799 ++ unsigned long base = mm->mmap_base, addr;
12800 + unsigned long largest_hole = mm->cached_hole_size;
12801 +- int first_time = 1;
12802 +
12803 + /* don't allow allocations above current base */
12804 + if (mm->free_area_cache > base)
12805 +@@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
12806 + largest_hole = 0;
12807 + mm->free_area_cache = base;
12808 + }
12809 +-try_again:
12810 ++
12811 + /* make sure it can fit in the remaining address space */
12812 + if (mm->free_area_cache < len)
12813 + goto fail;
12814 +@@ -326,22 +330,26 @@ try_again:
12815 +
12816 + fail:
12817 + /*
12818 +- * if hint left us with no space for the requested
12819 +- * mapping then try again:
12820 +- */
12821 +- if (first_time) {
12822 +- mm->free_area_cache = base;
12823 +- largest_hole = 0;
12824 +- first_time = 0;
12825 +- goto try_again;
12826 +- }
12827 +- /*
12828 + * A failed mmap() very likely causes application failure,
12829 + * so fall back to the bottom-up function here. This scenario
12830 + * can happen with large stack limits and large mmap()
12831 + * allocations.
12832 + */
12833 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
12834 ++
12835 ++#ifdef CONFIG_PAX_SEGMEXEC
12836 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12837 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
12838 ++ else
12839 ++#endif
12840 ++
12841 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12842 ++
12843 ++#ifdef CONFIG_PAX_RANDMMAP
12844 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12845 ++ mm->mmap_base += mm->delta_mmap;
12846 ++#endif
12847 ++
12848 ++ mm->free_area_cache = mm->mmap_base;
12849 + mm->cached_hole_size = ~0UL;
12850 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
12851 + len, pgoff, flags);
12852 +@@ -349,6 +357,7 @@ fail:
12853 + /*
12854 + * Restore the topdown base:
12855 + */
12856 ++ mm->mmap_base = base;
12857 + mm->free_area_cache = base;
12858 + mm->cached_hole_size = ~0UL;
12859 +
12860 +@@ -361,10 +370,17 @@ hugetlb_get_unmapped_area(struct file *f
12861 + {
12862 + struct mm_struct *mm = current->mm;
12863 + struct vm_area_struct *vma;
12864 ++ unsigned long pax_task_size = TASK_SIZE;
12865 +
12866 + if (len & ~HPAGE_MASK)
12867 + return -EINVAL;
12868 +- if (len > TASK_SIZE)
12869 ++
12870 ++#ifdef CONFIG_PAX_SEGMEXEC
12871 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12872 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12873 ++#endif
12874 ++
12875 ++ if (len > pax_task_size)
12876 + return -ENOMEM;
12877 +
12878 + if (flags & MAP_FIXED) {
12879 +@@ -376,7 +392,7 @@ hugetlb_get_unmapped_area(struct file *f
12880 + if (addr) {
12881 + addr = ALIGN(addr, HPAGE_SIZE);
12882 + vma = find_vma(mm, addr);
12883 +- if (TASK_SIZE - len >= addr &&
12884 ++ if (pax_task_size - len >= addr &&
12885 + (!vma || addr + len <= vma->vm_start))
12886 + return addr;
12887 + }
12888 +diff -urNp linux-2.6.26.6/arch/x86/mm/init_32.c linux-2.6.26.6/arch/x86/mm/init_32.c
12889 +--- linux-2.6.26.6/arch/x86/mm/init_32.c 2008-10-08 23:24:05.000000000 -0400
12890 ++++ linux-2.6.26.6/arch/x86/mm/init_32.c 2008-10-11 21:54:19.000000000 -0400
12891 +@@ -47,6 +47,7 @@
12892 + #include <asm/paravirt.h>
12893 + #include <asm/setup.h>
12894 + #include <asm/cacheflush.h>
12895 ++#include <asm/desc.h>
12896 +
12897 + unsigned int __VMALLOC_RESERVE = 128 << 20;
12898 +
12899 +@@ -58,32 +59,6 @@ unsigned long highstart_pfn, highend_pfn
12900 + static noinline int do_test_wp_bit(void);
12901 +
12902 + /*
12903 +- * Creates a middle page table and puts a pointer to it in the
12904 +- * given global directory entry. This only returns the gd entry
12905 +- * in non-PAE compilation mode, since the middle layer is folded.
12906 +- */
12907 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
12908 +-{
12909 +- pud_t *pud;
12910 +- pmd_t *pmd_table;
12911 +-
12912 +-#ifdef CONFIG_X86_PAE
12913 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
12914 +- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
12915 +-
12916 +- paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
12917 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
12918 +- pud = pud_offset(pgd, 0);
12919 +- BUG_ON(pmd_table != pmd_offset(pud, 0));
12920 +- }
12921 +-#endif
12922 +- pud = pud_offset(pgd, 0);
12923 +- pmd_table = pmd_offset(pud, 0);
12924 +-
12925 +- return pmd_table;
12926 +-}
12927 +-
12928 +-/*
12929 + * Create a page table and place a pointer to it in a middle page
12930 + * directory entry:
12931 + */
12932 +@@ -101,7 +76,11 @@ static pte_t * __init one_page_table_ini
12933 + }
12934 +
12935 + paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
12936 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12937 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
12938 ++#else
12939 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
12940 ++#endif
12941 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
12942 + }
12943 +
12944 +@@ -123,6 +102,7 @@ page_table_range_init(unsigned long star
12945 + int pgd_idx, pmd_idx;
12946 + unsigned long vaddr;
12947 + pgd_t *pgd;
12948 ++ pud_t *pud;
12949 + pmd_t *pmd;
12950 +
12951 + vaddr = start;
12952 +@@ -131,8 +111,13 @@ page_table_range_init(unsigned long star
12953 + pgd = pgd_base + pgd_idx;
12954 +
12955 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
12956 +- pmd = one_md_table_init(pgd);
12957 +- pmd = pmd + pmd_index(vaddr);
12958 ++ pud = pud_offset(pgd, vaddr);
12959 ++ pmd = pmd_offset(pud, vaddr);
12960 ++
12961 ++#ifdef CONFIG_X86_PAE
12962 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
12963 ++#endif
12964 ++
12965 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
12966 + pmd++, pmd_idx++) {
12967 + one_page_table_init(pmd);
12968 +@@ -143,11 +128,23 @@ page_table_range_init(unsigned long star
12969 + }
12970 + }
12971 +
12972 +-static inline int is_kernel_text(unsigned long addr)
12973 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
12974 + {
12975 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
12976 +- return 1;
12977 +- return 0;
12978 ++ unsigned long etext;
12979 ++
12980 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
12981 ++ etext = ktva_ktla((unsigned long)&MODULES_END);
12982 ++#else
12983 ++ etext = (unsigned long)&_etext;
12984 ++#endif
12985 ++
12986 ++ if ((start > ktla_ktva(etext) ||
12987 ++ end <= ktla_ktva((unsigned long)_stext)) &&
12988 ++ (start > ktla_ktva((unsigned long)_einittext) ||
12989 ++ end <= ktla_ktva((unsigned long)_sinittext)) &&
12990 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
12991 ++ return 0;
12992 ++ return 1;
12993 + }
12994 +
12995 + /*
12996 +@@ -157,9 +154,10 @@ static inline int is_kernel_text(unsigne
12997 + */
12998 + static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
12999 + {
13000 +- int pgd_idx, pmd_idx, pte_ofs;
13001 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
13002 + unsigned long pfn;
13003 + pgd_t *pgd;
13004 ++ pud_t *pud;
13005 + pmd_t *pmd;
13006 + pte_t *pte;
13007 +
13008 +@@ -167,15 +165,18 @@ static void __init kernel_physical_mappi
13009 + pgd = pgd_base + pgd_idx;
13010 + pfn = 0;
13011 +
13012 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
13013 +- pmd = one_md_table_init(pgd);
13014 +- if (pfn >= max_low_pfn)
13015 +- continue;
13016 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
13017 ++ pud = pud_offset(pgd, 0);
13018 ++ pmd = pmd_offset(pud, 0);
13019 ++
13020 ++#ifdef CONFIG_X86_PAE
13021 ++ paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
13022 ++#endif
13023 +
13024 + for (pmd_idx = 0;
13025 + pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
13026 + pmd++, pmd_idx++) {
13027 +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
13028 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
13029 +
13030 + /*
13031 + * Map with big pages if possible, otherwise
13032 +@@ -187,14 +188,9 @@ static void __init kernel_physical_mappi
13033 + * slowdowns.
13034 + */
13035 + if (cpu_has_pse && !(pgd_idx == 0 && pmd_idx == 0)) {
13036 +- unsigned int addr2;
13037 + pgprot_t prot = PAGE_KERNEL_LARGE;
13038 +
13039 +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
13040 +- PAGE_OFFSET + PAGE_SIZE-1;
13041 +-
13042 +- if (is_kernel_text(addr) ||
13043 +- is_kernel_text(addr2))
13044 ++ if (is_kernel_text(address, address + PMD_SIZE))
13045 + prot = PAGE_KERNEL_LARGE_EXEC;
13046 +
13047 + set_pmd(pmd, pfn_pmd(pfn, prot));
13048 +@@ -207,10 +203,10 @@ static void __init kernel_physical_mappi
13049 +
13050 + for (pte_ofs = 0;
13051 + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
13052 +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
13053 ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
13054 + pgprot_t prot = PAGE_KERNEL;
13055 +
13056 +- if (is_kernel_text(addr))
13057 ++ if (is_kernel_text(address, address + PAGE_SIZE))
13058 + prot = PAGE_KERNEL_EXEC;
13059 +
13060 + set_pte(pte, pfn_pte(pfn, prot));
13061 +@@ -239,7 +235,9 @@ static inline int page_kills_ppro(unsign
13062 + */
13063 + int devmem_is_allowed(unsigned long pagenr)
13064 + {
13065 +- if (pagenr <= 256)
13066 ++ if (!pagenr)
13067 ++ return 1;
13068 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13069 + return 1;
13070 + if (!page_is_ram(pagenr))
13071 + return 1;
13072 +@@ -320,10 +318,10 @@ static void __init set_highmem_pages_ini
13073 + # define set_highmem_pages_init(bad_ppro) do { } while (0)
13074 + #endif /* CONFIG_HIGHMEM */
13075 +
13076 +-pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
13077 ++pteval_t __PAGE_KERNEL __read_only = _PAGE_KERNEL;
13078 + EXPORT_SYMBOL(__PAGE_KERNEL);
13079 +
13080 +-pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
13081 ++pteval_t __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
13082 +
13083 + void __init native_pagetable_setup_start(pgd_t *base)
13084 + {
13085 +@@ -345,7 +343,7 @@ void __init native_pagetable_setup_start
13086 +
13087 + pud = pud_offset(pgd, va);
13088 + pmd = pmd_offset(pud, va);
13089 +- if (!pmd_present(*pmd))
13090 ++ if (!pmd_present(*pmd) || pmd_huge(*pmd))
13091 + break;
13092 +
13093 + pte = pte_offset_kernel(pmd, va);
13094 +@@ -421,12 +419,12 @@ static void __init pagetable_init(void)
13095 + * ACPI suspend needs this for resume, because things like the intel-agp
13096 + * driver might have split up a kernel 4MB mapping.
13097 + */
13098 +-char swsusp_pg_dir[PAGE_SIZE]
13099 ++pgd_t swsusp_pg_dir[PTRS_PER_PGD]
13100 + __attribute__ ((aligned(PAGE_SIZE)));
13101 +
13102 + static inline void save_pg_dir(void)
13103 + {
13104 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
13105 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
13106 + }
13107 + #else /* !CONFIG_ACPI_SLEEP */
13108 + static inline void save_pg_dir(void)
13109 +@@ -456,13 +454,11 @@ void zap_low_mappings(void)
13110 +
13111 + int nx_enabled;
13112 +
13113 +-pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
13114 ++pteval_t __supported_pte_mask __read_only = ~_PAGE_NX;
13115 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
13116 +
13117 + #ifdef CONFIG_X86_PAE
13118 +
13119 +-static int disable_nx __initdata;
13120 +-
13121 + /*
13122 + * noexec = on|off
13123 + *
13124 +@@ -471,40 +467,33 @@ static int disable_nx __initdata;
13125 + * on Enable
13126 + * off Disable
13127 + */
13128 ++#if !defined(CONFIG_PAX_PAGEEXEC)
13129 + static int __init noexec_setup(char *str)
13130 + {
13131 + if (!str || !strcmp(str, "on")) {
13132 +- if (cpu_has_nx) {
13133 +- __supported_pte_mask |= _PAGE_NX;
13134 +- disable_nx = 0;
13135 +- }
13136 ++ if (cpu_has_nx)
13137 ++ nx_enabled = 1;
13138 + } else {
13139 +- if (!strcmp(str, "off")) {
13140 +- disable_nx = 1;
13141 +- __supported_pte_mask &= ~_PAGE_NX;
13142 +- } else {
13143 ++ if (!strcmp(str, "off"))
13144 ++ nx_enabled = 0;
13145 ++ else
13146 + return -EINVAL;
13147 +- }
13148 + }
13149 +
13150 + return 0;
13151 + }
13152 + early_param("noexec", noexec_setup);
13153 ++#endif
13154 +
13155 + static void __init set_nx(void)
13156 + {
13157 +- unsigned int v[4], l, h;
13158 +-
13159 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
13160 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
13161 ++ if (!nx_enabled && cpu_has_nx) {
13162 ++ unsigned l, h;
13163 +
13164 +- if ((v[3] & (1 << 20)) && !disable_nx) {
13165 +- rdmsr(MSR_EFER, l, h);
13166 +- l |= EFER_NX;
13167 +- wrmsr(MSR_EFER, l, h);
13168 +- nx_enabled = 1;
13169 +- __supported_pte_mask |= _PAGE_NX;
13170 +- }
13171 ++ __supported_pte_mask &= ~_PAGE_NX;
13172 ++ rdmsr(MSR_EFER, l, h);
13173 ++ l &= ~EFER_NX;
13174 ++ wrmsr(MSR_EFER, l, h);
13175 + }
13176 + }
13177 + #endif
13178 +@@ -596,7 +585,7 @@ void __init mem_init(void)
13179 + set_highmem_pages_init(bad_ppro);
13180 +
13181 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
13182 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
13183 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
13184 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
13185 +
13186 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
13187 +@@ -643,10 +632,10 @@ void __init mem_init(void)
13188 + ((unsigned long)&__init_end -
13189 + (unsigned long)&__init_begin) >> 10,
13190 +
13191 +- (unsigned long)&_etext, (unsigned long)&_edata,
13192 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
13193 ++ (unsigned long)&_data, (unsigned long)&_edata,
13194 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
13195 +
13196 +- (unsigned long)&_text, (unsigned long)&_etext,
13197 ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
13198 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
13199 +
13200 + #ifdef CONFIG_HIGHMEM
13201 +@@ -773,6 +762,46 @@ void free_init_pages(char *what, unsigne
13202 +
13203 + void free_initmem(void)
13204 + {
13205 ++
13206 ++#ifdef CONFIG_PAX_KERNEXEC
13207 ++ /* PaX: limit KERNEL_CS to actual size */
13208 ++ unsigned long addr, limit;
13209 ++ struct desc_struct d;
13210 ++ int cpu;
13211 ++ pgd_t *pgd;
13212 ++ pud_t *pud;
13213 ++ pmd_t *pmd;
13214 ++
13215 ++#ifdef CONFIG_MODULES
13216 ++ limit = ktva_ktla((unsigned long)&MODULES_END);
13217 ++#else
13218 ++ limit = (unsigned long)&_etext;
13219 ++#endif
13220 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
13221 ++
13222 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13223 ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
13224 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
13225 ++ }
13226 ++
13227 ++ /* PaX: make KERNEL_CS read-only */
13228 ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
13229 ++ pgd = pgd_offset_k(addr);
13230 ++ pud = pud_offset(pgd, addr);
13231 ++ pmd = pmd_offset(pud, addr);
13232 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13233 ++ }
13234 ++#ifdef CONFIG_X86_PAE
13235 ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
13236 ++ pgd = pgd_offset_k(addr);
13237 ++ pud = pud_offset(pgd, addr);
13238 ++ pmd = pmd_offset(pud, addr);
13239 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13240 ++ }
13241 ++#endif
13242 ++ flush_tlb_all();
13243 ++#endif
13244 ++
13245 + free_init_pages("unused kernel memory",
13246 + (unsigned long)(&__init_begin),
13247 + (unsigned long)(&__init_end));
13248 +diff -urNp linux-2.6.26.6/arch/x86/mm/init_64.c linux-2.6.26.6/arch/x86/mm/init_64.c
13249 +--- linux-2.6.26.6/arch/x86/mm/init_64.c 2008-10-08 23:24:05.000000000 -0400
13250 ++++ linux-2.6.26.6/arch/x86/mm/init_64.c 2008-10-11 21:54:19.000000000 -0400
13251 +@@ -143,6 +143,10 @@ set_pte_phys(unsigned long vaddr, unsign
13252 + pmd_t *pmd;
13253 + pte_t *pte, new_pte;
13254 +
13255 ++#ifdef CONFIG_PAX_KERNEXEC
13256 ++ unsigned long cr0;
13257 ++#endif
13258 ++
13259 + pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
13260 +
13261 + pgd = pgd_offset_k(vaddr);
13262 +@@ -154,7 +158,7 @@ set_pte_phys(unsigned long vaddr, unsign
13263 + pud = pud_offset(pgd, vaddr);
13264 + if (pud_none(*pud)) {
13265 + pmd = (pmd_t *) spp_getpage();
13266 +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
13267 ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
13268 + if (pmd != pmd_offset(pud, 0)) {
13269 + printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
13270 + pmd, pmd_offset(pud, 0));
13271 +@@ -164,7 +168,7 @@ set_pte_phys(unsigned long vaddr, unsign
13272 + pmd = pmd_offset(pud, vaddr);
13273 + if (pmd_none(*pmd)) {
13274 + pte = (pte_t *) spp_getpage();
13275 +- set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
13276 ++ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
13277 + if (pte != pte_offset_kernel(pmd, 0)) {
13278 + printk(KERN_ERR "PAGETABLE BUG #02!\n");
13279 + return;
13280 +@@ -176,8 +180,17 @@ set_pte_phys(unsigned long vaddr, unsign
13281 + if (!pte_none(*pte) && pte_val(new_pte) &&
13282 + pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
13283 + pte_ERROR(*pte);
13284 ++
13285 ++#ifdef CONFIG_PAX_KERNEXEC
13286 ++ pax_open_kernel(cr0);
13287 ++#endif
13288 ++
13289 + set_pte(pte, new_pte);
13290 +
13291 ++#ifdef CONFIG_PAX_KERNEXEC
13292 ++ pax_close_kernel(cr0);
13293 ++#endif
13294 ++
13295 + /*
13296 + * It's enough to flush this one mapping.
13297 + * (PGE mappings get flushed as well)
13298 +@@ -667,7 +680,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
13299 + */
13300 + int devmem_is_allowed(unsigned long pagenr)
13301 + {
13302 +- if (pagenr <= 256)
13303 ++ if (!pagenr)
13304 ++ return 1;
13305 ++ if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13306 + return 1;
13307 + if (!page_is_ram(pagenr))
13308 + return 1;
13309 +@@ -755,6 +770,39 @@ void free_init_pages(char *what, unsigne
13310 +
13311 + void free_initmem(void)
13312 + {
13313 ++
13314 ++#ifdef CONFIG_PAX_KERNEXEC
13315 ++ unsigned long addr, end;
13316 ++ pgd_t *pgd;
13317 ++ pud_t *pud;
13318 ++ pmd_t *pmd;
13319 ++
13320 ++ /* PaX: make kernel code/rodata read-only, rest non-executable */
13321 ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
13322 ++ pgd = pgd_offset_k(addr);
13323 ++ pud = pud_offset(pgd, addr);
13324 ++ pmd = pmd_offset(pud, addr);
13325 ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
13326 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13327 ++ else
13328 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13329 ++ }
13330 ++
13331 ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
13332 ++ end = addr + KERNEL_IMAGE_SIZE;
13333 ++ for (; addr < end; addr += PMD_SIZE) {
13334 ++ pgd = pgd_offset_k(addr);
13335 ++ pud = pud_offset(pgd, addr);
13336 ++ pmd = pmd_offset(pud, addr);
13337 ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
13338 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13339 ++ else
13340 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
13341 ++ }
13342 ++
13343 ++ flush_tlb_all();
13344 ++#endif
13345 ++
13346 + free_init_pages("unused kernel memory",
13347 + (unsigned long)(&__init_begin),
13348 + (unsigned long)(&__init_end));
13349 +@@ -913,7 +961,7 @@ int in_gate_area_no_task(unsigned long a
13350 +
13351 + const char *arch_vma_name(struct vm_area_struct *vma)
13352 + {
13353 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
13354 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
13355 + return "[vdso]";
13356 + if (vma == &gate_vma)
13357 + return "[vsyscall]";
13358 +diff -urNp linux-2.6.26.6/arch/x86/mm/ioremap.c linux-2.6.26.6/arch/x86/mm/ioremap.c
13359 +--- linux-2.6.26.6/arch/x86/mm/ioremap.c 2008-10-08 23:24:05.000000000 -0400
13360 ++++ linux-2.6.26.6/arch/x86/mm/ioremap.c 2008-10-11 21:54:19.000000000 -0400
13361 +@@ -62,8 +62,8 @@ int page_is_ram(unsigned long pagenr)
13362 + * Second special case: Some BIOSen report the PC BIOS
13363 + * area (640->1Mb) as ram even though it is not.
13364 + */
13365 +- if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
13366 +- pagenr < (BIOS_END >> PAGE_SHIFT))
13367 ++ if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
13368 ++ pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
13369 + return 0;
13370 +
13371 + for (i = 0; i < e820.nr_map; i++) {
13372 +@@ -213,6 +213,8 @@ static void __iomem *__ioremap_caller(re
13373 + break;
13374 + }
13375 +
13376 ++ prot = canon_pgprot(prot);
13377 ++
13378 + /*
13379 + * Ok, go for it..
13380 + */
13381 +diff -urNp linux-2.6.26.6/arch/x86/mm/mmap.c linux-2.6.26.6/arch/x86/mm/mmap.c
13382 +--- linux-2.6.26.6/arch/x86/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
13383 ++++ linux-2.6.26.6/arch/x86/mm/mmap.c 2008-10-11 21:54:19.000000000 -0400
13384 +@@ -36,7 +36,7 @@
13385 + * Leave an at least ~128 MB hole.
13386 + */
13387 + #define MIN_GAP (128*1024*1024)
13388 +-#define MAX_GAP (TASK_SIZE/6*5)
13389 ++#define MAX_GAP (pax_task_size/6*5)
13390 +
13391 + /*
13392 + * True on X86_32 or when emulating IA32 on X86_64
13393 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
13394 + return rnd << PAGE_SHIFT;
13395 + }
13396 +
13397 +-static unsigned long mmap_base(void)
13398 ++static unsigned long mmap_base(struct mm_struct *mm)
13399 + {
13400 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
13401 ++ unsigned long pax_task_size = TASK_SIZE;
13402 ++
13403 ++#ifdef CONFIG_PAX_SEGMEXEC
13404 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13405 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
13406 ++#endif
13407 +
13408 + if (gap < MIN_GAP)
13409 + gap = MIN_GAP;
13410 + else if (gap > MAX_GAP)
13411 + gap = MAX_GAP;
13412 +
13413 +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
13414 ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
13415 + }
13416 +
13417 + /*
13418 + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
13419 + * does, but not when emulating X86_32
13420 + */
13421 +-static unsigned long mmap_legacy_base(void)
13422 ++static unsigned long mmap_legacy_base(struct mm_struct *mm)
13423 + {
13424 +- if (mmap_is_ia32())
13425 ++ if (mmap_is_ia32()) {
13426 ++
13427 ++#ifdef CONFIG_PAX_SEGMEXEC
13428 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13429 ++ return SEGMEXEC_TASK_UNMAPPED_BASE;
13430 ++ else
13431 ++#endif
13432 ++
13433 + return TASK_UNMAPPED_BASE;
13434 +- else
13435 ++ } else
13436 + return TASK_UNMAPPED_BASE + mmap_rnd();
13437 + }
13438 +
13439 +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
13440 + void arch_pick_mmap_layout(struct mm_struct *mm)
13441 + {
13442 + if (mmap_is_legacy()) {
13443 +- mm->mmap_base = mmap_legacy_base();
13444 ++ mm->mmap_base = mmap_legacy_base(mm);
13445 ++
13446 ++#ifdef CONFIG_PAX_RANDMMAP
13447 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13448 ++ mm->mmap_base += mm->delta_mmap;
13449 ++#endif
13450 ++
13451 + mm->get_unmapped_area = arch_get_unmapped_area;
13452 + mm->unmap_area = arch_unmap_area;
13453 + } else {
13454 +- mm->mmap_base = mmap_base();
13455 ++ mm->mmap_base = mmap_base(mm);
13456 ++
13457 ++#ifdef CONFIG_PAX_RANDMMAP
13458 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13459 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
13460 ++#endif
13461 ++
13462 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
13463 + mm->unmap_area = arch_unmap_area_topdown;
13464 + }
13465 +diff -urNp linux-2.6.26.6/arch/x86/mm/numa_64.c linux-2.6.26.6/arch/x86/mm/numa_64.c
13466 +--- linux-2.6.26.6/arch/x86/mm/numa_64.c 2008-10-08 23:24:05.000000000 -0400
13467 ++++ linux-2.6.26.6/arch/x86/mm/numa_64.c 2008-10-11 21:54:19.000000000 -0400
13468 +@@ -21,7 +21,7 @@
13469 + #include <asm/k8.h>
13470 +
13471 + #ifndef Dprintk
13472 +-#define Dprintk(x...)
13473 ++#define Dprintk(x...) do {} while (0)
13474 + #endif
13475 +
13476 + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
13477 +diff -urNp linux-2.6.26.6/arch/x86/mm/pageattr.c linux-2.6.26.6/arch/x86/mm/pageattr.c
13478 +--- linux-2.6.26.6/arch/x86/mm/pageattr.c 2008-10-08 23:24:05.000000000 -0400
13479 ++++ linux-2.6.26.6/arch/x86/mm/pageattr.c 2008-10-11 21:54:19.000000000 -0400
13480 +@@ -20,6 +20,7 @@
13481 + #include <asm/pgalloc.h>
13482 + #include <asm/proto.h>
13483 + #include <asm/pat.h>
13484 ++#include <asm/desc.h>
13485 +
13486 + /*
13487 + * The current flushing context - we pass it instead of 5 arguments:
13488 +@@ -172,7 +173,7 @@ static inline pgprot_t static_protection
13489 + * Does not cover __inittext since that is gone later on. On
13490 + * 64bit we do not enforce !NX on the low mapping
13491 + */
13492 +- if (within(address, (unsigned long)_text, (unsigned long)_etext))
13493 ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
13494 + pgprot_val(forbidden) |= _PAGE_NX;
13495 +
13496 + /*
13497 +@@ -233,8 +234,20 @@ pte_t *lookup_address(unsigned long addr
13498 + */
13499 + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
13500 + {
13501 ++
13502 ++#ifdef CONFIG_PAX_KERNEXEC
13503 ++ unsigned long cr0;
13504 ++
13505 ++ pax_open_kernel(cr0);
13506 ++#endif
13507 ++
13508 + /* change init_mm */
13509 + set_pte_atomic(kpte, pte);
13510 ++
13511 ++#ifdef CONFIG_PAX_KERNEXEC
13512 ++ pax_close_kernel(cr0);
13513 ++#endif
13514 ++
13515 + #ifdef CONFIG_X86_32
13516 + if (!SHARED_KERNEL_PMD) {
13517 + struct page *page;
13518 +diff -urNp linux-2.6.26.6/arch/x86/mm/pat.c linux-2.6.26.6/arch/x86/mm/pat.c
13519 +--- linux-2.6.26.6/arch/x86/mm/pat.c 2008-10-08 23:24:05.000000000 -0400
13520 ++++ linux-2.6.26.6/arch/x86/mm/pat.c 2008-10-11 21:54:19.000000000 -0400
13521 +@@ -471,7 +471,7 @@ pgprot_t phys_mem_access_prot(struct fil
13522 + return vma_prot;
13523 + }
13524 +
13525 +-#ifdef CONFIG_NONPROMISC_DEVMEM
13526 ++#ifndef CONFIG_NONPROMISC_DEVMEM
13527 + /* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
13528 + static inline int range_is_allowed(unsigned long pfn, unsigned long size)
13529 + {
13530 +diff -urNp linux-2.6.26.6/arch/x86/mm/pgtable_32.c linux-2.6.26.6/arch/x86/mm/pgtable_32.c
13531 +--- linux-2.6.26.6/arch/x86/mm/pgtable_32.c 2008-10-08 23:24:05.000000000 -0400
13532 ++++ linux-2.6.26.6/arch/x86/mm/pgtable_32.c 2008-10-11 21:54:19.000000000 -0400
13533 +@@ -78,6 +78,10 @@ static void set_pte_pfn(unsigned long va
13534 + pmd_t *pmd;
13535 + pte_t *pte;
13536 +
13537 ++#ifdef CONFIG_PAX_KERNEXEC
13538 ++ unsigned long cr0;
13539 ++#endif
13540 ++
13541 + pgd = swapper_pg_dir + pgd_index(vaddr);
13542 + if (pgd_none(*pgd)) {
13543 + BUG();
13544 +@@ -94,11 +98,20 @@ static void set_pte_pfn(unsigned long va
13545 + return;
13546 + }
13547 + pte = pte_offset_kernel(pmd, vaddr);
13548 ++
13549 ++#ifdef CONFIG_PAX_KERNEXEC
13550 ++ pax_open_kernel(cr0);
13551 ++#endif
13552 ++
13553 + if (pgprot_val(flags))
13554 + set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
13555 + else
13556 + pte_clear(&init_mm, vaddr, pte);
13557 +
13558 ++#ifdef CONFIG_PAX_KERNEXEC
13559 ++ pax_close_kernel(cr0);
13560 ++#endif
13561 ++
13562 + /*
13563 + * It's enough to flush this one mapping.
13564 + * (PGE mappings get flushed as well)
13565 +diff -urNp linux-2.6.26.6/arch/x86/oprofile/backtrace.c linux-2.6.26.6/arch/x86/oprofile/backtrace.c
13566 +--- linux-2.6.26.6/arch/x86/oprofile/backtrace.c 2008-10-08 23:24:05.000000000 -0400
13567 ++++ linux-2.6.26.6/arch/x86/oprofile/backtrace.c 2008-10-11 21:54:19.000000000 -0400
13568 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data
13569 + unsigned int *depth = data;
13570 +
13571 + if ((*depth)--)
13572 +- oprofile_add_trace(addr);
13573 ++ oprofile_add_trace(ktla_ktva(addr));
13574 + }
13575 +
13576 + static struct stacktrace_ops backtrace_ops = {
13577 +@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
13578 + struct frame_head *head = (struct frame_head *)frame_pointer(regs);
13579 + unsigned long stack = kernel_trap_sp(regs);
13580 +
13581 +- if (!user_mode_vm(regs)) {
13582 ++ if (!user_mode(regs)) {
13583 + if (depth)
13584 + dump_trace(NULL, regs, (unsigned long *)stack, 0,
13585 + &backtrace_ops, &depth);
13586 +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
13587 +--- linux-2.6.26.6/arch/x86/oprofile/op_model_p4.c 2008-10-08 23:24:05.000000000 -0400
13588 ++++ linux-2.6.26.6/arch/x86/oprofile/op_model_p4.c 2008-10-11 21:54:19.000000000 -0400
13589 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
13590 + #endif
13591 + }
13592 +
13593 +-static int inline addr_increment(void)
13594 ++static inline int addr_increment(void)
13595 + {
13596 + #ifdef CONFIG_SMP
13597 + return smp_num_siblings == 2 ? 2 : 1;
13598 +diff -urNp linux-2.6.26.6/arch/x86/pci/common.c linux-2.6.26.6/arch/x86/pci/common.c
13599 +--- linux-2.6.26.6/arch/x86/pci/common.c 2008-10-08 23:24:05.000000000 -0400
13600 ++++ linux-2.6.26.6/arch/x86/pci/common.c 2008-10-11 21:54:19.000000000 -0400
13601 +@@ -342,7 +342,7 @@ static struct dmi_system_id __devinitdat
13602 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
13603 + },
13604 + },
13605 +- {}
13606 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13607 + };
13608 +
13609 + void __init dmi_check_pciprobe(void)
13610 +diff -urNp linux-2.6.26.6/arch/x86/pci/early.c linux-2.6.26.6/arch/x86/pci/early.c
13611 +--- linux-2.6.26.6/arch/x86/pci/early.c 2008-10-08 23:24:05.000000000 -0400
13612 ++++ linux-2.6.26.6/arch/x86/pci/early.c 2008-10-11 21:54:19.000000000 -0400
13613 +@@ -7,7 +7,7 @@
13614 + /* Direct PCI access. This is used for PCI accesses in early boot before
13615 + the PCI subsystem works. */
13616 +
13617 +-#define PDprintk(x...)
13618 ++#define PDprintk(x...) do {} while (0)
13619 +
13620 + u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
13621 + {
13622 +diff -urNp linux-2.6.26.6/arch/x86/pci/fixup.c linux-2.6.26.6/arch/x86/pci/fixup.c
13623 +--- linux-2.6.26.6/arch/x86/pci/fixup.c 2008-10-08 23:24:05.000000000 -0400
13624 ++++ linux-2.6.26.6/arch/x86/pci/fixup.c 2008-10-11 21:54:19.000000000 -0400
13625 +@@ -364,7 +364,7 @@ static struct dmi_system_id __devinitdat
13626 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
13627 + },
13628 + },
13629 +- {}
13630 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13631 + };
13632 +
13633 + /*
13634 +@@ -435,7 +435,7 @@ static struct dmi_system_id __devinitdat
13635 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
13636 + },
13637 + },
13638 +- { }
13639 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13640 + };
13641 +
13642 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
13643 +diff -urNp linux-2.6.26.6/arch/x86/pci/irq.c linux-2.6.26.6/arch/x86/pci/irq.c
13644 +--- linux-2.6.26.6/arch/x86/pci/irq.c 2008-10-08 23:24:05.000000000 -0400
13645 ++++ linux-2.6.26.6/arch/x86/pci/irq.c 2008-10-11 21:54:19.000000000 -0400
13646 +@@ -542,7 +542,7 @@ static __init int intel_router_probe(str
13647 + static struct pci_device_id __initdata pirq_440gx[] = {
13648 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
13649 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
13650 +- { },
13651 ++ { PCI_DEVICE(0, 0) }
13652 + };
13653 +
13654 + /* 440GX has a proprietary PIRQ router -- don't use it */
13655 +@@ -1115,7 +1115,7 @@ static struct dmi_system_id __initdata p
13656 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
13657 + },
13658 + },
13659 +- { }
13660 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13661 + };
13662 +
13663 + static int __init pcibios_irq_init(void)
13664 +diff -urNp linux-2.6.26.6/arch/x86/pci/pcbios.c linux-2.6.26.6/arch/x86/pci/pcbios.c
13665 +--- linux-2.6.26.6/arch/x86/pci/pcbios.c 2008-10-08 23:24:05.000000000 -0400
13666 ++++ linux-2.6.26.6/arch/x86/pci/pcbios.c 2008-10-11 21:54:19.000000000 -0400
13667 +@@ -57,50 +57,120 @@ union bios32 {
13668 + static struct {
13669 + unsigned long address;
13670 + unsigned short segment;
13671 +-} bios32_indirect = { 0, __KERNEL_CS };
13672 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
13673 +
13674 + /*
13675 + * Returns the entry point for the given service, NULL on error
13676 + */
13677 +
13678 +-static unsigned long bios32_service(unsigned long service)
13679 ++static unsigned long __devinit bios32_service(unsigned long service)
13680 + {
13681 + unsigned char return_code; /* %al */
13682 + unsigned long address; /* %ebx */
13683 + unsigned long length; /* %ecx */
13684 + unsigned long entry; /* %edx */
13685 + unsigned long flags;
13686 ++ struct desc_struct d, *gdt;
13687 ++
13688 ++#ifdef CONFIG_PAX_KERNEXEC
13689 ++ unsigned long cr0;
13690 ++#endif
13691 +
13692 + local_irq_save(flags);
13693 +- __asm__("lcall *(%%edi); cld"
13694 ++
13695 ++ gdt = get_cpu_gdt_table(smp_processor_id());
13696 ++
13697 ++#ifdef CONFIG_PAX_KERNEXEC
13698 ++ pax_open_kernel(cr0);
13699 ++#endif
13700 ++
13701 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
13702 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
13703 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
13704 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
13705 ++
13706 ++#ifdef CONFIG_PAX_KERNEXEC
13707 ++ pax_close_kernel(cr0);
13708 ++#endif
13709 ++
13710 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
13711 + : "=a" (return_code),
13712 + "=b" (address),
13713 + "=c" (length),
13714 + "=d" (entry)
13715 + : "0" (service),
13716 + "1" (0),
13717 +- "D" (&bios32_indirect));
13718 ++ "D" (&bios32_indirect),
13719 ++ "r"(__PCIBIOS_DS)
13720 ++ : "memory");
13721 ++
13722 ++#ifdef CONFIG_PAX_KERNEXEC
13723 ++ pax_open_kernel(cr0);
13724 ++#endif
13725 ++
13726 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
13727 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
13728 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
13729 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
13730 ++
13731 ++#ifdef CONFIG_PAX_KERNEXEC
13732 ++ pax_close_kernel(cr0);
13733 ++#endif
13734 ++
13735 + local_irq_restore(flags);
13736 +
13737 + switch (return_code) {
13738 +- case 0:
13739 +- return address + entry;
13740 +- case 0x80: /* Not present */
13741 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
13742 +- return 0;
13743 +- default: /* Shouldn't happen */
13744 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
13745 +- service, return_code);
13746 ++ case 0: {
13747 ++ int cpu;
13748 ++ unsigned char flags;
13749 ++
13750 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
13751 ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
13752 ++ printk(KERN_WARNING "bios32_service: not valid\n");
13753 + return 0;
13754 ++ }
13755 ++ address = address + PAGE_OFFSET;
13756 ++ length += 16UL; /* some BIOSs underreport this... */
13757 ++ flags = 4;
13758 ++ if (length >= 64*1024*1024) {
13759 ++ length >>= PAGE_SHIFT;
13760 ++ flags |= 8;
13761 ++ }
13762 ++
13763 ++#ifdef CONFIG_PAX_KERNEXEC
13764 ++ pax_open_kernel(cr0);
13765 ++#endif
13766 ++
13767 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13768 ++ gdt = get_cpu_gdt_table(cpu);
13769 ++ pack_descriptor(&d, address, length, 0x9b, flags);
13770 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
13771 ++ pack_descriptor(&d, address, length, 0x93, flags);
13772 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
13773 ++ }
13774 ++
13775 ++#ifdef CONFIG_PAX_KERNEXEC
13776 ++ pax_close_kernel(cr0);
13777 ++#endif
13778 ++
13779 ++ return entry;
13780 ++ }
13781 ++ case 0x80: /* Not present */
13782 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
13783 ++ return 0;
13784 ++ default: /* Shouldn't happen */
13785 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
13786 ++ service, return_code);
13787 ++ return 0;
13788 + }
13789 + }
13790 +
13791 + static struct {
13792 + unsigned long address;
13793 + unsigned short segment;
13794 +-} pci_indirect = { 0, __KERNEL_CS };
13795 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
13796 +
13797 +-static int pci_bios_present;
13798 ++static int pci_bios_present __read_only;
13799 +
13800 + static int __devinit check_pcibios(void)
13801 + {
13802 +@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
13803 + unsigned long flags, pcibios_entry;
13804 +
13805 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
13806 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
13807 ++ pci_indirect.address = pcibios_entry;
13808 +
13809 + local_irq_save(flags);
13810 +- __asm__(
13811 +- "lcall *(%%edi); cld\n\t"
13812 ++ __asm__("movw %w6, %%ds\n\t"
13813 ++ "lcall *%%ss:(%%edi); cld\n\t"
13814 ++ "push %%ss\n\t"
13815 ++ "pop %%ds\n\t"
13816 + "jc 1f\n\t"
13817 + "xor %%ah, %%ah\n"
13818 + "1:"
13819 +@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
13820 + "=b" (ebx),
13821 + "=c" (ecx)
13822 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
13823 +- "D" (&pci_indirect)
13824 ++ "D" (&pci_indirect),
13825 ++ "r" (__PCIBIOS_DS)
13826 + : "memory");
13827 + local_irq_restore(flags);
13828 +
13829 +@@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
13830 +
13831 + switch (len) {
13832 + case 1:
13833 +- __asm__("lcall *(%%esi); cld\n\t"
13834 ++ __asm__("movw %w6, %%ds\n\t"
13835 ++ "lcall *%%ss:(%%esi); cld\n\t"
13836 ++ "push %%ss\n\t"
13837 ++ "pop %%ds\n\t"
13838 + "jc 1f\n\t"
13839 + "xor %%ah, %%ah\n"
13840 + "1:"
13841 +@@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
13842 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
13843 + "b" (bx),
13844 + "D" ((long)reg),
13845 +- "S" (&pci_indirect));
13846 ++ "S" (&pci_indirect),
13847 ++ "r" (__PCIBIOS_DS));
13848 + /*
13849 + * Zero-extend the result beyond 8 bits, do not trust the
13850 + * BIOS having done it:
13851 +@@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
13852 + *value &= 0xff;
13853 + break;
13854 + case 2:
13855 +- __asm__("lcall *(%%esi); cld\n\t"
13856 ++ __asm__("movw %w6, %%ds\n\t"
13857 ++ "lcall *%%ss:(%%esi); cld\n\t"
13858 ++ "push %%ss\n\t"
13859 ++ "pop %%ds\n\t"
13860 + "jc 1f\n\t"
13861 + "xor %%ah, %%ah\n"
13862 + "1:"
13863 +@@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
13864 + : "1" (PCIBIOS_READ_CONFIG_WORD),
13865 + "b" (bx),
13866 + "D" ((long)reg),
13867 +- "S" (&pci_indirect));
13868 ++ "S" (&pci_indirect),
13869 ++ "r" (__PCIBIOS_DS));
13870 + /*
13871 + * Zero-extend the result beyond 16 bits, do not trust the
13872 + * BIOS having done it:
13873 +@@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
13874 + *value &= 0xffff;
13875 + break;
13876 + case 4:
13877 +- __asm__("lcall *(%%esi); cld\n\t"
13878 ++ __asm__("movw %w6, %%ds\n\t"
13879 ++ "lcall *%%ss:(%%esi); cld\n\t"
13880 ++ "push %%ss\n\t"
13881 ++ "pop %%ds\n\t"
13882 + "jc 1f\n\t"
13883 + "xor %%ah, %%ah\n"
13884 + "1:"
13885 +@@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
13886 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
13887 + "b" (bx),
13888 + "D" ((long)reg),
13889 +- "S" (&pci_indirect));
13890 ++ "S" (&pci_indirect),
13891 ++ "r" (__PCIBIOS_DS));
13892 + break;
13893 + }
13894 +
13895 +@@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
13896 +
13897 + switch (len) {
13898 + case 1:
13899 +- __asm__("lcall *(%%esi); cld\n\t"
13900 ++ __asm__("movw %w6, %%ds\n\t"
13901 ++ "lcall *%%ss:(%%esi); cld\n\t"
13902 ++ "push %%ss\n\t"
13903 ++ "pop %%ds\n\t"
13904 + "jc 1f\n\t"
13905 + "xor %%ah, %%ah\n"
13906 + "1:"
13907 +@@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
13908 + "c" (value),
13909 + "b" (bx),
13910 + "D" ((long)reg),
13911 +- "S" (&pci_indirect));
13912 ++ "S" (&pci_indirect),
13913 ++ "r" (__PCIBIOS_DS));
13914 + break;
13915 + case 2:
13916 +- __asm__("lcall *(%%esi); cld\n\t"
13917 ++ __asm__("movw %w6, %%ds\n\t"
13918 ++ "lcall *%%ss:(%%esi); cld\n\t"
13919 ++ "push %%ss\n\t"
13920 ++ "pop %%ds\n\t"
13921 + "jc 1f\n\t"
13922 + "xor %%ah, %%ah\n"
13923 + "1:"
13924 +@@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
13925 + "c" (value),
13926 + "b" (bx),
13927 + "D" ((long)reg),
13928 +- "S" (&pci_indirect));
13929 ++ "S" (&pci_indirect),
13930 ++ "r" (__PCIBIOS_DS));
13931 + break;
13932 + case 4:
13933 +- __asm__("lcall *(%%esi); cld\n\t"
13934 ++ __asm__("movw %w6, %%ds\n\t"
13935 ++ "lcall *%%ss:(%%esi); cld\n\t"
13936 ++ "push %%ss\n\t"
13937 ++ "pop %%ds\n\t"
13938 + "jc 1f\n\t"
13939 + "xor %%ah, %%ah\n"
13940 + "1:"
13941 +@@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
13942 + "c" (value),
13943 + "b" (bx),
13944 + "D" ((long)reg),
13945 +- "S" (&pci_indirect));
13946 ++ "S" (&pci_indirect),
13947 ++ "r" (__PCIBIOS_DS));
13948 + break;
13949 + }
13950 +
13951 +@@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
13952 +
13953 + DBG("PCI: Fetching IRQ routing table... ");
13954 + __asm__("push %%es\n\t"
13955 ++ "movw %w8, %%ds\n\t"
13956 + "push %%ds\n\t"
13957 + "pop %%es\n\t"
13958 +- "lcall *(%%esi); cld\n\t"
13959 ++ "lcall *%%ss:(%%esi); cld\n\t"
13960 + "pop %%es\n\t"
13961 ++ "push %%ss\n\t"
13962 ++ "pop %%ds\n"
13963 + "jc 1f\n\t"
13964 + "xor %%ah, %%ah\n"
13965 + "1:"
13966 +@@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
13967 + "1" (0),
13968 + "D" ((long) &opt),
13969 + "S" (&pci_indirect),
13970 +- "m" (opt)
13971 ++ "m" (opt),
13972 ++ "r" (__PCIBIOS_DS)
13973 + : "memory");
13974 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
13975 + if (ret & 0xff00)
13976 +@@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
13977 + {
13978 + int ret;
13979 +
13980 +- __asm__("lcall *(%%esi); cld\n\t"
13981 ++ __asm__("movw %w5, %%ds\n\t"
13982 ++ "lcall *%%ss:(%%esi); cld\n\t"
13983 ++ "push %%ss\n\t"
13984 ++ "pop %%ds\n"
13985 + "jc 1f\n\t"
13986 + "xor %%ah, %%ah\n"
13987 + "1:"
13988 +@@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
13989 + : "0" (PCIBIOS_SET_PCI_HW_INT),
13990 + "b" ((dev->bus->number << 8) | dev->devfn),
13991 + "c" ((irq << 8) | (pin + 10)),
13992 +- "S" (&pci_indirect));
13993 ++ "S" (&pci_indirect),
13994 ++ "r" (__PCIBIOS_DS));
13995 + return !(ret & 0xff00);
13996 + }
13997 + EXPORT_SYMBOL(pcibios_set_irq_routing);
13998 +diff -urNp linux-2.6.26.6/arch/x86/power/cpu_32.c linux-2.6.26.6/arch/x86/power/cpu_32.c
13999 +--- linux-2.6.26.6/arch/x86/power/cpu_32.c 2008-10-08 23:24:05.000000000 -0400
14000 ++++ linux-2.6.26.6/arch/x86/power/cpu_32.c 2008-10-11 21:54:19.000000000 -0400
14001 +@@ -66,7 +66,7 @@ static void do_fpu_end(void)
14002 + static void fix_processor_context(void)
14003 + {
14004 + int cpu = smp_processor_id();
14005 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
14006 ++ struct tss_struct *t = init_tss + cpu;
14007 +
14008 + set_tss_desc(cpu, t); /*
14009 + * This just modifies memory; should not be
14010 +diff -urNp linux-2.6.26.6/arch/x86/power/cpu_64.c linux-2.6.26.6/arch/x86/power/cpu_64.c
14011 +--- linux-2.6.26.6/arch/x86/power/cpu_64.c 2008-10-08 23:24:05.000000000 -0400
14012 ++++ linux-2.6.26.6/arch/x86/power/cpu_64.c 2008-10-11 21:54:19.000000000 -0400
14013 +@@ -136,7 +136,11 @@ void restore_processor_state(void)
14014 + static void fix_processor_context(void)
14015 + {
14016 + int cpu = smp_processor_id();
14017 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
14018 ++ struct tss_struct *t = init_tss + cpu;
14019 ++
14020 ++#ifdef CONFIG_PAX_KERNEXEC
14021 ++ unsigned long cr0;
14022 ++#endif
14023 +
14024 + /*
14025 + * This just modifies memory; should not be necessary. But... This
14026 +@@ -145,8 +149,16 @@ static void fix_processor_context(void)
14027 + */
14028 + set_tss_desc(cpu, t);
14029 +
14030 ++#ifdef CONFIG_PAX_KERNEXEC
14031 ++ pax_open_kernel(cr0);
14032 ++#endif
14033 ++
14034 + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
14035 +
14036 ++#ifdef CONFIG_PAX_KERNEXEC
14037 ++ pax_close_kernel(cr0);
14038 ++#endif
14039 ++
14040 + syscall_init(); /* This sets MSR_*STAR and related */
14041 + load_TR_desc(); /* This does ltr */
14042 + load_LDT(&current->active_mm->context); /* This does lldt */
14043 +diff -urNp linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c
14044 +--- linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c 2008-10-08 23:24:05.000000000 -0400
14045 ++++ linux-2.6.26.6/arch/x86/vdso/vdso32-setup.c 2008-10-11 21:54:19.000000000 -0400
14046 +@@ -239,7 +239,7 @@ static inline void map_compat_vdso(int m
14047 + void enable_sep_cpu(void)
14048 + {
14049 + int cpu = get_cpu();
14050 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
14051 ++ struct tss_struct *tss = init_tss + cpu;
14052 +
14053 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
14054 + put_cpu();
14055 +@@ -262,7 +262,7 @@ static int __init gate_vma_init(void)
14056 + gate_vma.vm_start = FIXADDR_USER_START;
14057 + gate_vma.vm_end = FIXADDR_USER_END;
14058 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
14059 +- gate_vma.vm_page_prot = __P101;
14060 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
14061 + /*
14062 + * Make sure the vDSO gets into every core dump.
14063 + * Dumping its contents makes post-mortem fully interpretable later
14064 +@@ -341,7 +341,7 @@ int arch_setup_additional_pages(struct l
14065 + if (compat)
14066 + addr = VDSO_HIGH_BASE;
14067 + else {
14068 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
14069 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
14070 + if (IS_ERR_VALUE(addr)) {
14071 + ret = addr;
14072 + goto up_fail;
14073 +@@ -368,7 +368,7 @@ int arch_setup_additional_pages(struct l
14074 + goto up_fail;
14075 + }
14076 +
14077 +- current->mm->context.vdso = (void *)addr;
14078 ++ current->mm->context.vdso = addr;
14079 + current_thread_info()->sysenter_return =
14080 + VDSO32_SYMBOL(addr, SYSENTER_RETURN);
14081 +
14082 +@@ -394,7 +394,7 @@ static ctl_table abi_table2[] = {
14083 + .mode = 0644,
14084 + .proc_handler = proc_dointvec
14085 + },
14086 +- {}
14087 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14088 + };
14089 +
14090 + static ctl_table abi_root_table2[] = {
14091 +@@ -404,7 +404,7 @@ static ctl_table abi_root_table2[] = {
14092 + .mode = 0555,
14093 + .child = abi_table2
14094 + },
14095 +- {}
14096 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
14097 + };
14098 +
14099 + static __init int ia32_binfmt_init(void)
14100 +@@ -419,8 +419,14 @@ __initcall(ia32_binfmt_init);
14101 +
14102 + const char *arch_vma_name(struct vm_area_struct *vma)
14103 + {
14104 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
14105 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
14106 + return "[vdso]";
14107 ++
14108 ++#ifdef CONFIG_PAX_SEGMEXEC
14109 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
14110 ++ return "[vdso]";
14111 ++#endif
14112 ++
14113 + return NULL;
14114 + }
14115 +
14116 +@@ -429,7 +435,7 @@ struct vm_area_struct *get_gate_vma(stru
14117 + struct mm_struct *mm = tsk->mm;
14118 +
14119 + /* Check to see if this task was created in compat vdso mode */
14120 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
14121 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
14122 + return &gate_vma;
14123 + return NULL;
14124 + }
14125 +diff -urNp linux-2.6.26.6/arch/x86/vdso/vma.c linux-2.6.26.6/arch/x86/vdso/vma.c
14126 +--- linux-2.6.26.6/arch/x86/vdso/vma.c 2008-10-08 23:24:05.000000000 -0400
14127 ++++ linux-2.6.26.6/arch/x86/vdso/vma.c 2008-10-11 21:54:19.000000000 -0400
14128 +@@ -122,7 +122,7 @@ int arch_setup_additional_pages(struct l
14129 + if (ret)
14130 + goto up_fail;
14131 +
14132 +- current->mm->context.vdso = (void *)addr;
14133 ++ current->mm->context.vdso = addr;
14134 + up_fail:
14135 + up_write(&mm->mmap_sem);
14136 + return ret;
14137 +diff -urNp linux-2.6.26.6/arch/x86/xen/enlighten.c linux-2.6.26.6/arch/x86/xen/enlighten.c
14138 +--- linux-2.6.26.6/arch/x86/xen/enlighten.c 2008-10-08 23:24:05.000000000 -0400
14139 ++++ linux-2.6.26.6/arch/x86/xen/enlighten.c 2008-10-11 21:54:19.000000000 -0400
14140 +@@ -295,7 +295,7 @@ static void xen_set_ldt(const void *addr
14141 + static void xen_load_gdt(const struct desc_ptr *dtr)
14142 + {
14143 + unsigned long *frames;
14144 +- unsigned long va = dtr->address;
14145 ++ unsigned long va = (unsigned long)dtr->address;
14146 + unsigned int size = dtr->size + 1;
14147 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
14148 + int f;
14149 +@@ -310,7 +310,7 @@ static void xen_load_gdt(const struct de
14150 + mcs = xen_mc_entry(sizeof(*frames) * pages);
14151 + frames = mcs.args;
14152 +
14153 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
14154 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
14155 + frames[f] = virt_to_mfn(va);
14156 + make_lowmem_page_readonly((void *)va);
14157 + }
14158 +@@ -403,7 +403,7 @@ static void xen_write_idt_entry(gate_des
14159 +
14160 + preempt_disable();
14161 +
14162 +- start = __get_cpu_var(idt_desc).address;
14163 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
14164 + end = start + __get_cpu_var(idt_desc).size + 1;
14165 +
14166 + xen_mc_flush();
14167 +diff -urNp linux-2.6.26.6/arch/x86/xen/smp.c linux-2.6.26.6/arch/x86/xen/smp.c
14168 +--- linux-2.6.26.6/arch/x86/xen/smp.c 2008-10-08 23:24:05.000000000 -0400
14169 ++++ linux-2.6.26.6/arch/x86/xen/smp.c 2008-10-11 21:54:19.000000000 -0400
14170 +@@ -154,7 +154,7 @@ void __init xen_smp_prepare_boot_cpu(voi
14171 +
14172 + /* We've switched to the "real" per-cpu gdt, so make sure the
14173 + old memory can be recycled */
14174 +- make_lowmem_page_readwrite(&per_cpu__gdt_page);
14175 ++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
14176 +
14177 + for_each_possible_cpu(cpu) {
14178 + cpus_clear(per_cpu(cpu_sibling_map, cpu));
14179 +@@ -218,7 +218,7 @@ static __cpuinit int
14180 + cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
14181 + {
14182 + struct vcpu_guest_context *ctxt;
14183 +- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
14184 ++ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
14185 +
14186 + if (cpu_test_and_set(cpu, xen_cpu_initialized_map))
14187 + return 0;
14188 +@@ -228,8 +228,8 @@ cpu_initialize_context(unsigned int cpu,
14189 + return -ENOMEM;
14190 +
14191 + ctxt->flags = VGCF_IN_KERNEL;
14192 +- ctxt->user_regs.ds = __USER_DS;
14193 +- ctxt->user_regs.es = __USER_DS;
14194 ++ ctxt->user_regs.ds = __KERNEL_DS;
14195 ++ ctxt->user_regs.es = __KERNEL_DS;
14196 + ctxt->user_regs.fs = __KERNEL_PERCPU;
14197 + ctxt->user_regs.gs = 0;
14198 + ctxt->user_regs.ss = __KERNEL_DS;
14199 +@@ -242,11 +242,11 @@ cpu_initialize_context(unsigned int cpu,
14200 +
14201 + ctxt->ldt_ents = 0;
14202 +
14203 +- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
14204 +- make_lowmem_page_readonly(gdt->gdt);
14205 ++ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
14206 ++ make_lowmem_page_readonly(gdt);
14207 +
14208 +- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
14209 +- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
14210 ++ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
14211 ++ ctxt->gdt_ents = GDT_ENTRIES;
14212 +
14213 + ctxt->user_regs.cs = __KERNEL_CS;
14214 + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
14215 +diff -urNp linux-2.6.26.6/crypto/async_tx/async_tx.c linux-2.6.26.6/crypto/async_tx/async_tx.c
14216 +--- linux-2.6.26.6/crypto/async_tx/async_tx.c 2008-10-08 23:24:05.000000000 -0400
14217 ++++ linux-2.6.26.6/crypto/async_tx/async_tx.c 2008-10-11 21:54:19.000000000 -0400
14218 +@@ -357,8 +357,8 @@ async_tx_init(void)
14219 + err:
14220 + printk(KERN_ERR "async_tx: initialization failure\n");
14221 +
14222 +- while (--cap >= 0)
14223 +- free_percpu(channel_table[cap]);
14224 ++ while (cap)
14225 ++ free_percpu(channel_table[--cap]);
14226 +
14227 + return 1;
14228 + }
14229 +diff -urNp linux-2.6.26.6/crypto/lrw.c linux-2.6.26.6/crypto/lrw.c
14230 +--- linux-2.6.26.6/crypto/lrw.c 2008-10-08 23:24:05.000000000 -0400
14231 ++++ linux-2.6.26.6/crypto/lrw.c 2008-10-11 21:54:19.000000000 -0400
14232 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
14233 + struct priv *ctx = crypto_tfm_ctx(parent);
14234 + struct crypto_cipher *child = ctx->child;
14235 + int err, i;
14236 +- be128 tmp = { 0 };
14237 ++ be128 tmp = { 0, 0 };
14238 + int bsize = crypto_cipher_blocksize(child);
14239 +
14240 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
14241 +diff -urNp linux-2.6.26.6/Documentation/dontdiff linux-2.6.26.6/Documentation/dontdiff
14242 +--- linux-2.6.26.6/Documentation/dontdiff 2008-10-08 23:24:05.000000000 -0400
14243 ++++ linux-2.6.26.6/Documentation/dontdiff 2008-10-11 21:54:19.000000000 -0400
14244 +@@ -3,6 +3,7 @@
14245 + *.bin
14246 + *.cpio
14247 + *.css
14248 ++*.dbg
14249 + *.dvi
14250 + *.eps
14251 + *.gif
14252 +@@ -51,9 +52,14 @@ COPYING
14253 + CREDITS
14254 + CVS
14255 + ChangeSet
14256 ++GPATH
14257 ++GRTAGS
14258 ++GSYMS
14259 ++GTAGS
14260 + Image
14261 + Kerntypes
14262 + MODS.txt
14263 ++Module.markers
14264 + Module.symvers
14265 + PENDING
14266 + SCCS
14267 +@@ -72,6 +78,7 @@ bbootsect
14268 + bin2c
14269 + binkernel.spec
14270 + bootsect
14271 ++bounds.h
14272 + bsetup
14273 + btfixupprep
14274 + build
14275 +@@ -88,6 +95,7 @@ config_data.gz*
14276 + conmakehash
14277 + consolemap_deftbl.c*
14278 + crc32table.h*
14279 ++cpustr.h
14280 + cscope.*
14281 + defkeymap.c*
14282 + devlist.h*
14283 +@@ -136,6 +144,7 @@ miboot*
14284 + mk_elfconfig
14285 + mkboot
14286 + mkbugboot
14287 ++mkcpustr
14288 + mkdep
14289 + mkprep
14290 + mktables
14291 +@@ -177,16 +186,20 @@ times.h*
14292 + tkparse
14293 + trix_boot.h
14294 + utsrelease.h*
14295 +-vdso.lds
14296 ++vdso*.lds
14297 + version.h*
14298 + vmlinux
14299 + vmlinux-*
14300 + vmlinux.aout
14301 +-vmlinux*.lds*
14302 ++vmlinux.bin.all
14303 ++vmlinux*.lds
14304 ++vmlinux.relocs
14305 + vmlinux*.scr
14306 +-vsyscall.lds
14307 ++vsyscall*.lds
14308 ++wakeup.lds
14309 + wanxlfw.inc
14310 + uImage
14311 + unifdef
14312 ++utsrelease.h
14313 + zImage*
14314 + zconf.hash.c
14315 +diff -urNp linux-2.6.26.6/drivers/acpi/blacklist.c linux-2.6.26.6/drivers/acpi/blacklist.c
14316 +--- linux-2.6.26.6/drivers/acpi/blacklist.c 2008-10-08 23:24:05.000000000 -0400
14317 ++++ linux-2.6.26.6/drivers/acpi/blacklist.c 2008-10-11 21:54:19.000000000 -0400
14318 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
14319 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
14320 + "Incorrect _ADR", 1},
14321 +
14322 +- {""}
14323 ++ {"", "", 0, 0, 0, all_versions, 0}
14324 + };
14325 +
14326 + #if CONFIG_ACPI_BLACKLIST_YEAR
14327 +diff -urNp linux-2.6.26.6/drivers/acpi/osl.c linux-2.6.26.6/drivers/acpi/osl.c
14328 +--- linux-2.6.26.6/drivers/acpi/osl.c 2008-10-08 23:24:05.000000000 -0400
14329 ++++ linux-2.6.26.6/drivers/acpi/osl.c 2008-10-11 21:54:19.000000000 -0400
14330 +@@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
14331 + void __iomem *virt_addr;
14332 +
14333 + virt_addr = ioremap(phys_addr, width);
14334 ++ if (!virt_addr)
14335 ++ return AE_NO_MEMORY;
14336 + if (!value)
14337 + value = &dummy;
14338 +
14339 +@@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
14340 + void __iomem *virt_addr;
14341 +
14342 + virt_addr = ioremap(phys_addr, width);
14343 ++ if (!virt_addr)
14344 ++ return AE_NO_MEMORY;
14345 +
14346 + switch (width) {
14347 + case 8:
14348 +diff -urNp linux-2.6.26.6/drivers/acpi/processor_core.c linux-2.6.26.6/drivers/acpi/processor_core.c
14349 +--- linux-2.6.26.6/drivers/acpi/processor_core.c 2008-10-08 23:24:05.000000000 -0400
14350 ++++ linux-2.6.26.6/drivers/acpi/processor_core.c 2008-10-11 21:54:19.000000000 -0400
14351 +@@ -631,7 +631,7 @@ static int __cpuinit acpi_processor_star
14352 + return 0;
14353 + }
14354 +
14355 +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
14356 ++ BUG_ON(pr->id >= nr_cpu_ids);
14357 +
14358 + /*
14359 + * Buggy BIOS check
14360 +diff -urNp linux-2.6.26.6/drivers/acpi/processor_idle.c linux-2.6.26.6/drivers/acpi/processor_idle.c
14361 +--- linux-2.6.26.6/drivers/acpi/processor_idle.c 2008-10-08 23:24:05.000000000 -0400
14362 ++++ linux-2.6.26.6/drivers/acpi/processor_idle.c 2008-10-11 21:54:19.000000000 -0400
14363 +@@ -181,7 +181,7 @@ static struct dmi_system_id __cpuinitdat
14364 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
14365 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
14366 + (void *)2},
14367 +- {},
14368 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
14369 + };
14370 +
14371 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
14372 +diff -urNp linux-2.6.26.6/drivers/acpi/sleep/main.c linux-2.6.26.6/drivers/acpi/sleep/main.c
14373 +--- linux-2.6.26.6/drivers/acpi/sleep/main.c 2008-10-08 23:24:05.000000000 -0400
14374 ++++ linux-2.6.26.6/drivers/acpi/sleep/main.c 2008-10-11 21:54:19.000000000 -0400
14375 +@@ -249,7 +249,7 @@ static struct dmi_system_id __initdata a
14376 + .ident = "Toshiba Satellite 4030cdt",
14377 + .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
14378 + },
14379 +- {},
14380 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
14381 + };
14382 + #endif /* CONFIG_SUSPEND */
14383 +
14384 +diff -urNp linux-2.6.26.6/drivers/acpi/tables/tbfadt.c linux-2.6.26.6/drivers/acpi/tables/tbfadt.c
14385 +--- linux-2.6.26.6/drivers/acpi/tables/tbfadt.c 2008-10-08 23:24:05.000000000 -0400
14386 ++++ linux-2.6.26.6/drivers/acpi/tables/tbfadt.c 2008-10-11 21:54:19.000000000 -0400
14387 +@@ -48,7 +48,7 @@
14388 + ACPI_MODULE_NAME("tbfadt")
14389 +
14390 + /* Local prototypes */
14391 +-static void inline
14392 ++static inline void
14393 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
14394 + u8 bit_width, u64 address);
14395 +
14396 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
14397 + *
14398 + ******************************************************************************/
14399 +
14400 +-static void inline
14401 ++static inline void
14402 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
14403 + u8 bit_width, u64 address)
14404 + {
14405 +diff -urNp linux-2.6.26.6/drivers/ata/ahci.c linux-2.6.26.6/drivers/ata/ahci.c
14406 +--- linux-2.6.26.6/drivers/ata/ahci.c 2008-10-08 23:24:05.000000000 -0400
14407 ++++ linux-2.6.26.6/drivers/ata/ahci.c 2008-10-11 21:54:19.000000000 -0400
14408 +@@ -546,7 +546,7 @@ static const struct pci_device_id ahci_p
14409 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
14410 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
14411 +
14412 +- { } /* terminate list */
14413 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14414 + };
14415 +
14416 +
14417 +diff -urNp linux-2.6.26.6/drivers/ata/ata_piix.c linux-2.6.26.6/drivers/ata/ata_piix.c
14418 +--- linux-2.6.26.6/drivers/ata/ata_piix.c 2008-10-08 23:24:05.000000000 -0400
14419 ++++ linux-2.6.26.6/drivers/ata/ata_piix.c 2008-10-11 21:54:19.000000000 -0400
14420 +@@ -275,7 +275,7 @@ static const struct pci_device_id piix_p
14421 + /* SATA Controller IDE (ICH10) */
14422 + { 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
14423 +
14424 +- { } /* terminate list */
14425 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
14426 + };
14427 +
14428 + static struct pci_driver piix_pci_driver = {
14429 +@@ -578,7 +578,7 @@ static const struct ich_laptop ich_lapto
14430 + { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
14431 + { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
14432 + /* end marker */
14433 +- { 0, }
14434 ++ { 0, 0, 0 }
14435 + };
14436 +
14437 + /**
14438 +@@ -1134,7 +1134,7 @@ static int piix_broken_suspend(void)
14439 + },
14440 + },
14441 +
14442 +- { } /* terminate list */
14443 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
14444 + };
14445 + static const char *oemstrs[] = {
14446 + "Tecra M3,",
14447 +diff -urNp linux-2.6.26.6/drivers/ata/libata-core.c linux-2.6.26.6/drivers/ata/libata-core.c
14448 +--- linux-2.6.26.6/drivers/ata/libata-core.c 2008-10-08 23:24:05.000000000 -0400
14449 ++++ linux-2.6.26.6/drivers/ata/libata-core.c 2008-10-11 21:54:19.000000000 -0400
14450 +@@ -736,7 +736,7 @@ static const struct ata_xfer_ent {
14451 + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
14452 + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
14453 + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
14454 +- { -1, },
14455 ++ { -1, 0, 0 }
14456 + };
14457 +
14458 + /**
14459 +@@ -2860,7 +2860,7 @@ static const struct ata_timing ata_timin
14460 + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
14461 + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
14462 +
14463 +- { 0xFF }
14464 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
14465 + };
14466 +
14467 + #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
14468 +@@ -3947,7 +3947,7 @@ static const struct ata_blacklist_entry
14469 + { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
14470 +
14471 + /* End Marker */
14472 +- { }
14473 ++ { NULL, NULL, 0 }
14474 + };
14475 +
14476 + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
14477 +diff -urNp linux-2.6.26.6/drivers/char/agp/frontend.c linux-2.6.26.6/drivers/char/agp/frontend.c
14478 +--- linux-2.6.26.6/drivers/char/agp/frontend.c 2008-10-08 23:24:05.000000000 -0400
14479 ++++ linux-2.6.26.6/drivers/char/agp/frontend.c 2008-10-11 21:54:19.000000000 -0400
14480 +@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
14481 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
14482 + return -EFAULT;
14483 +
14484 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
14485 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
14486 + return -EFAULT;
14487 +
14488 + client = agp_find_client_by_pid(reserve.pid);
14489 +diff -urNp linux-2.6.26.6/drivers/char/agp/intel-agp.c linux-2.6.26.6/drivers/char/agp/intel-agp.c
14490 +--- linux-2.6.26.6/drivers/char/agp/intel-agp.c 2008-10-08 23:24:05.000000000 -0400
14491 ++++ linux-2.6.26.6/drivers/char/agp/intel-agp.c 2008-10-11 21:54:20.000000000 -0400
14492 +@@ -2319,7 +2319,7 @@ static struct pci_device_id agp_intel_pc
14493 + ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
14494 + ID(PCI_DEVICE_ID_INTEL_Q45_HB),
14495 + ID(PCI_DEVICE_ID_INTEL_G45_HB),
14496 +- { }
14497 ++ { 0, 0, 0, 0, 0, 0, 0 }
14498 + };
14499 +
14500 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
14501 +diff -urNp linux-2.6.26.6/drivers/char/drm/drm_pciids.h linux-2.6.26.6/drivers/char/drm/drm_pciids.h
14502 +--- linux-2.6.26.6/drivers/char/drm/drm_pciids.h 2008-10-08 23:24:05.000000000 -0400
14503 ++++ linux-2.6.26.6/drivers/char/drm/drm_pciids.h 2008-10-11 21:54:20.000000000 -0400
14504 +@@ -346,7 +346,7 @@
14505 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14506 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14507 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14508 +- {0, 0, 0}
14509 ++ {0, 0, 0, 0, 0, 0, 0 }
14510 +
14511 + #define i830_PCI_IDS \
14512 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
14513 +diff -urNp linux-2.6.26.6/drivers/char/hpet.c linux-2.6.26.6/drivers/char/hpet.c
14514 +--- linux-2.6.26.6/drivers/char/hpet.c 2008-10-08 23:24:05.000000000 -0400
14515 ++++ linux-2.6.26.6/drivers/char/hpet.c 2008-10-11 21:54:20.000000000 -0400
14516 +@@ -953,7 +953,7 @@ static struct acpi_driver hpet_acpi_driv
14517 + },
14518 + };
14519 +
14520 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
14521 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
14522 +
14523 + static int __init hpet_init(void)
14524 + {
14525 +diff -urNp linux-2.6.26.6/drivers/char/keyboard.c linux-2.6.26.6/drivers/char/keyboard.c
14526 +--- linux-2.6.26.6/drivers/char/keyboard.c 2008-10-08 23:24:05.000000000 -0400
14527 ++++ linux-2.6.26.6/drivers/char/keyboard.c 2008-10-11 21:54:20.000000000 -0400
14528 +@@ -633,6 +633,16 @@ static void k_spec(struct vc_data *vc, u
14529 + kbd->kbdmode == VC_MEDIUMRAW) &&
14530 + value != KVAL(K_SAK))
14531 + return; /* SAK is allowed even in raw mode */
14532 ++
14533 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
14534 ++ {
14535 ++ void *func = fn_handler[value];
14536 ++ if (func == fn_show_state || func == fn_show_ptregs ||
14537 ++ func == fn_show_mem)
14538 ++ return;
14539 ++ }
14540 ++#endif
14541 ++
14542 + fn_handler[value](vc);
14543 + }
14544 +
14545 +@@ -1386,7 +1396,7 @@ static const struct input_device_id kbd_
14546 + .evbit = { BIT_MASK(EV_SND) },
14547 + },
14548 +
14549 +- { }, /* Terminating entry */
14550 ++ { 0 }, /* Terminating entry */
14551 + };
14552 +
14553 + MODULE_DEVICE_TABLE(input, kbd_ids);
14554 +diff -urNp linux-2.6.26.6/drivers/char/mem.c linux-2.6.26.6/drivers/char/mem.c
14555 +--- linux-2.6.26.6/drivers/char/mem.c 2008-10-08 23:24:05.000000000 -0400
14556 ++++ linux-2.6.26.6/drivers/char/mem.c 2008-10-11 21:54:20.000000000 -0400
14557 +@@ -26,6 +26,7 @@
14558 + #include <linux/bootmem.h>
14559 + #include <linux/splice.h>
14560 + #include <linux/pfn.h>
14561 ++#include <linux/grsecurity.h>
14562 +
14563 + #include <asm/uaccess.h>
14564 + #include <asm/io.h>
14565 +@@ -34,6 +35,10 @@
14566 + # include <linux/efi.h>
14567 + #endif
14568 +
14569 ++#ifdef CONFIG_GRKERNSEC
14570 ++extern struct file_operations grsec_fops;
14571 ++#endif
14572 ++
14573 + /*
14574 + * Architectures vary in how they handle caching for addresses
14575 + * outside of main memory.
14576 +@@ -191,6 +196,11 @@ static ssize_t write_mem(struct file * f
14577 + if (!valid_phys_addr_range(p, count))
14578 + return -EFAULT;
14579 +
14580 ++#ifdef CONFIG_GRKERNSEC_KMEM
14581 ++ gr_handle_mem_write();
14582 ++ return -EPERM;
14583 ++#endif
14584 ++
14585 + written = 0;
14586 +
14587 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
14588 +@@ -346,6 +356,11 @@ static int mmap_mem(struct file * file,
14589 + &vma->vm_page_prot))
14590 + return -EINVAL;
14591 +
14592 ++#ifdef CONFIG_GRKERNSEC_KMEM
14593 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
14594 ++ return -EPERM;
14595 ++#endif
14596 ++
14597 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
14598 + size,
14599 + vma->vm_page_prot);
14600 +@@ -584,6 +599,11 @@ static ssize_t write_kmem(struct file *
14601 + ssize_t written;
14602 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
14603 +
14604 ++#ifdef CONFIG_GRKERNSEC_KMEM
14605 ++ gr_handle_kmem_write();
14606 ++ return -EPERM;
14607 ++#endif
14608 ++
14609 + if (p < (unsigned long) high_memory) {
14610 +
14611 + wrote = count;
14612 +@@ -787,6 +807,16 @@ static loff_t memory_lseek(struct file *
14613 +
14614 + static int open_port(struct inode * inode, struct file * filp)
14615 + {
14616 ++#ifdef CONFIG_GRKERNSEC_KMEM
14617 ++ gr_handle_open_port();
14618 ++ return -EPERM;
14619 ++#endif
14620 ++
14621 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
14622 ++}
14623 ++
14624 ++static int open_mem(struct inode * inode, struct file * filp)
14625 ++{
14626 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
14627 + }
14628 +
14629 +@@ -794,7 +824,6 @@ static int open_port(struct inode * inod
14630 + #define full_lseek null_lseek
14631 + #define write_zero write_null
14632 + #define read_full read_zero
14633 +-#define open_mem open_port
14634 + #define open_kmem open_mem
14635 + #define open_oldmem open_mem
14636 +
14637 +@@ -931,6 +960,11 @@ static int memory_open(struct inode * in
14638 + filp->f_op = &oldmem_fops;
14639 + break;
14640 + #endif
14641 ++#ifdef CONFIG_GRKERNSEC
14642 ++ case 13:
14643 ++ filp->f_op = &grsec_fops;
14644 ++ break;
14645 ++#endif
14646 + default:
14647 + return -ENXIO;
14648 + }
14649 +@@ -965,6 +999,9 @@ static const struct {
14650 + #ifdef CONFIG_CRASH_DUMP
14651 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
14652 + #endif
14653 ++#ifdef CONFIG_GRKERNSEC
14654 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
14655 ++#endif
14656 + };
14657 +
14658 + static struct class *mem_class;
14659 +diff -urNp linux-2.6.26.6/drivers/char/nvram.c linux-2.6.26.6/drivers/char/nvram.c
14660 +--- linux-2.6.26.6/drivers/char/nvram.c 2008-10-08 23:24:05.000000000 -0400
14661 ++++ linux-2.6.26.6/drivers/char/nvram.c 2008-10-11 21:54:20.000000000 -0400
14662 +@@ -430,7 +430,10 @@ static const struct file_operations nvra
14663 + static struct miscdevice nvram_dev = {
14664 + NVRAM_MINOR,
14665 + "nvram",
14666 +- &nvram_fops
14667 ++ &nvram_fops,
14668 ++ {NULL, NULL},
14669 ++ NULL,
14670 ++ NULL
14671 + };
14672 +
14673 + static int __init
14674 +diff -urNp linux-2.6.26.6/drivers/char/random.c linux-2.6.26.6/drivers/char/random.c
14675 +--- linux-2.6.26.6/drivers/char/random.c 2008-10-08 23:24:05.000000000 -0400
14676 ++++ linux-2.6.26.6/drivers/char/random.c 2008-10-11 21:54:20.000000000 -0400
14677 +@@ -248,8 +248,13 @@
14678 + /*
14679 + * Configuration information
14680 + */
14681 ++#ifdef CONFIG_GRKERNSEC_RANDNET
14682 ++#define INPUT_POOL_WORDS 512
14683 ++#define OUTPUT_POOL_WORDS 128
14684 ++#else
14685 + #define INPUT_POOL_WORDS 128
14686 + #define OUTPUT_POOL_WORDS 32
14687 ++#endif
14688 + #define SEC_XFER_SIZE 512
14689 +
14690 + /*
14691 +@@ -286,10 +291,17 @@ static struct poolinfo {
14692 + int poolwords;
14693 + int tap1, tap2, tap3, tap4, tap5;
14694 + } poolinfo_table[] = {
14695 ++#ifdef CONFIG_GRKERNSEC_RANDNET
14696 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
14697 ++ { 512, 411, 308, 208, 104, 1 },
14698 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
14699 ++ { 128, 103, 76, 51, 25, 1 },
14700 ++#else
14701 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
14702 + { 128, 103, 76, 51, 25, 1 },
14703 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
14704 + { 32, 26, 20, 14, 7, 1 },
14705 ++#endif
14706 + #if 0
14707 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
14708 + { 2048, 1638, 1231, 819, 411, 1 },
14709 +@@ -1165,7 +1177,7 @@ EXPORT_SYMBOL(generate_random_uuid);
14710 + #include <linux/sysctl.h>
14711 +
14712 + static int min_read_thresh = 8, min_write_thresh;
14713 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
14714 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
14715 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
14716 + static char sysctl_bootid[16];
14717 +
14718 +diff -urNp linux-2.6.26.6/drivers/char/tpm/tpm.c linux-2.6.26.6/drivers/char/tpm/tpm.c
14719 +--- linux-2.6.26.6/drivers/char/tpm/tpm.c 2008-10-08 23:24:05.000000000 -0400
14720 ++++ linux-2.6.26.6/drivers/char/tpm/tpm.c 2008-10-11 21:54:20.000000000 -0400
14721 +@@ -970,7 +970,7 @@ ssize_t tpm_write(struct file *file, con
14722 +
14723 + mutex_lock(&chip->buffer_mutex);
14724 +
14725 +- if (in_size > TPM_BUFSIZE)
14726 ++ if (in_size > (unsigned int)TPM_BUFSIZE)
14727 + in_size = TPM_BUFSIZE;
14728 +
14729 + if (copy_from_user
14730 +diff -urNp linux-2.6.26.6/drivers/char/vt_ioctl.c linux-2.6.26.6/drivers/char/vt_ioctl.c
14731 +--- linux-2.6.26.6/drivers/char/vt_ioctl.c 2008-10-08 23:24:05.000000000 -0400
14732 ++++ linux-2.6.26.6/drivers/char/vt_ioctl.c 2008-10-11 21:54:20.000000000 -0400
14733 +@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
14734 + case KDSKBENT:
14735 + if (!perm)
14736 + return -EPERM;
14737 ++
14738 ++#ifdef CONFIG_GRKERNSEC
14739 ++ if (!capable(CAP_SYS_TTY_CONFIG))
14740 ++ return -EPERM;
14741 ++#endif
14742 ++
14743 + if (!i && v == K_NOSUCHMAP) {
14744 + /* deallocate map */
14745 + key_map = key_maps[s];
14746 +@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
14747 + goto reterr;
14748 + }
14749 +
14750 ++#ifdef CONFIG_GRKERNSEC
14751 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
14752 ++ ret = -EPERM;
14753 ++ goto reterr;
14754 ++ }
14755 ++#endif
14756 ++
14757 + q = func_table[i];
14758 + first_free = funcbufptr + (funcbufsize - funcbufleft);
14759 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
14760 +diff -urNp linux-2.6.26.6/drivers/edac/edac_core.h linux-2.6.26.6/drivers/edac/edac_core.h
14761 +--- linux-2.6.26.6/drivers/edac/edac_core.h 2008-10-08 23:24:05.000000000 -0400
14762 ++++ linux-2.6.26.6/drivers/edac/edac_core.h 2008-10-11 21:54:20.000000000 -0400
14763 +@@ -86,11 +86,11 @@ extern int edac_debug_level;
14764 +
14765 + #else /* !CONFIG_EDAC_DEBUG */
14766 +
14767 +-#define debugf0( ... )
14768 +-#define debugf1( ... )
14769 +-#define debugf2( ... )
14770 +-#define debugf3( ... )
14771 +-#define debugf4( ... )
14772 ++#define debugf0( ... ) do {} while (0)
14773 ++#define debugf1( ... ) do {} while (0)
14774 ++#define debugf2( ... ) do {} while (0)
14775 ++#define debugf3( ... ) do {} while (0)
14776 ++#define debugf4( ... ) do {} while (0)
14777 +
14778 + #endif /* !CONFIG_EDAC_DEBUG */
14779 +
14780 +diff -urNp linux-2.6.26.6/drivers/firmware/dmi_scan.c linux-2.6.26.6/drivers/firmware/dmi_scan.c
14781 +--- linux-2.6.26.6/drivers/firmware/dmi_scan.c 2008-10-08 23:24:05.000000000 -0400
14782 ++++ linux-2.6.26.6/drivers/firmware/dmi_scan.c 2008-10-11 21:54:20.000000000 -0400
14783 +@@ -379,11 +379,6 @@ void __init dmi_scan_machine(void)
14784 + }
14785 + }
14786 + else {
14787 +- /*
14788 +- * no iounmap() for that ioremap(); it would be a no-op, but
14789 +- * it's so early in setup that sucker gets confused into doing
14790 +- * what it shouldn't if we actually call it.
14791 +- */
14792 + p = dmi_ioremap(0xF0000, 0x10000);
14793 + if (p == NULL)
14794 + goto out;
14795 +diff -urNp linux-2.6.26.6/drivers/hwmon/fscpos.c linux-2.6.26.6/drivers/hwmon/fscpos.c
14796 +--- linux-2.6.26.6/drivers/hwmon/fscpos.c 2008-10-08 23:24:05.000000000 -0400
14797 ++++ linux-2.6.26.6/drivers/hwmon/fscpos.c 2008-10-11 21:54:20.000000000 -0400
14798 +@@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
14799 + unsigned long v = simple_strtoul(buf, NULL, 10);
14800 +
14801 + /* Range: 0..255 */
14802 +- if (v < 0) v = 0;
14803 + if (v > 255) v = 255;
14804 +
14805 + mutex_lock(&data->update_lock);
14806 +diff -urNp linux-2.6.26.6/drivers/hwmon/k8temp.c linux-2.6.26.6/drivers/hwmon/k8temp.c
14807 +--- linux-2.6.26.6/drivers/hwmon/k8temp.c 2008-10-08 23:24:05.000000000 -0400
14808 ++++ linux-2.6.26.6/drivers/hwmon/k8temp.c 2008-10-11 21:54:20.000000000 -0400
14809 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
14810 +
14811 + static struct pci_device_id k8temp_ids[] = {
14812 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
14813 +- { 0 },
14814 ++ { 0, 0, 0, 0, 0, 0, 0 },
14815 + };
14816 +
14817 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
14818 +diff -urNp linux-2.6.26.6/drivers/hwmon/sis5595.c linux-2.6.26.6/drivers/hwmon/sis5595.c
14819 +--- linux-2.6.26.6/drivers/hwmon/sis5595.c 2008-10-08 23:24:05.000000000 -0400
14820 ++++ linux-2.6.26.6/drivers/hwmon/sis5595.c 2008-10-11 21:54:20.000000000 -0400
14821 +@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
14822 +
14823 + static struct pci_device_id sis5595_pci_ids[] = {
14824 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
14825 +- { 0, }
14826 ++ { 0, 0, 0, 0, 0, 0, 0 }
14827 + };
14828 +
14829 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
14830 +diff -urNp linux-2.6.26.6/drivers/hwmon/via686a.c linux-2.6.26.6/drivers/hwmon/via686a.c
14831 +--- linux-2.6.26.6/drivers/hwmon/via686a.c 2008-10-08 23:24:05.000000000 -0400
14832 ++++ linux-2.6.26.6/drivers/hwmon/via686a.c 2008-10-11 21:54:20.000000000 -0400
14833 +@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
14834 +
14835 + static struct pci_device_id via686a_pci_ids[] = {
14836 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
14837 +- { 0, }
14838 ++ { 0, 0, 0, 0, 0, 0, 0 }
14839 + };
14840 +
14841 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
14842 +diff -urNp linux-2.6.26.6/drivers/hwmon/vt8231.c linux-2.6.26.6/drivers/hwmon/vt8231.c
14843 +--- linux-2.6.26.6/drivers/hwmon/vt8231.c 2008-10-08 23:24:05.000000000 -0400
14844 ++++ linux-2.6.26.6/drivers/hwmon/vt8231.c 2008-10-11 21:54:20.000000000 -0400
14845 +@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
14846 +
14847 + static struct pci_device_id vt8231_pci_ids[] = {
14848 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
14849 +- { 0, }
14850 ++ { 0, 0, 0, 0, 0, 0, 0 }
14851 + };
14852 +
14853 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
14854 +diff -urNp linux-2.6.26.6/drivers/hwmon/w83791d.c linux-2.6.26.6/drivers/hwmon/w83791d.c
14855 +--- linux-2.6.26.6/drivers/hwmon/w83791d.c 2008-10-08 23:24:05.000000000 -0400
14856 ++++ linux-2.6.26.6/drivers/hwmon/w83791d.c 2008-10-11 21:54:20.000000000 -0400
14857 +@@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
14858 + static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
14859 + static int w83791d_detach_client(struct i2c_client *client);
14860 +
14861 +-static int w83791d_read(struct i2c_client *client, u8 register);
14862 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
14863 ++static int w83791d_read(struct i2c_client *client, u8 reg);
14864 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
14865 + static struct w83791d_data *w83791d_update_device(struct device *dev);
14866 +
14867 + #ifdef DEBUG
14868 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c
14869 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c 2008-10-08 23:24:05.000000000 -0400
14870 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-i801.c 2008-10-11 21:54:20.000000000 -0400
14871 +@@ -592,7 +592,7 @@ static struct pci_device_id i801_ids[] =
14872 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
14873 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
14874 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
14875 +- { 0, }
14876 ++ { 0, 0, 0, 0, 0, 0, 0 }
14877 + };
14878 +
14879 + MODULE_DEVICE_TABLE (pci, i801_ids);
14880 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c
14881 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c 2008-10-08 23:24:05.000000000 -0400
14882 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-i810.c 2008-10-11 21:54:20.000000000 -0400
14883 +@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
14884 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
14885 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
14886 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
14887 +- { 0, },
14888 ++ { 0, 0, 0, 0, 0, 0, 0 },
14889 + };
14890 +
14891 + MODULE_DEVICE_TABLE (pci, i810_ids);
14892 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c
14893 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c 2008-10-08 23:24:05.000000000 -0400
14894 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-piix4.c 2008-10-11 21:54:20.000000000 -0400
14895 +@@ -133,7 +133,7 @@ static struct dmi_system_id __devinitdat
14896 + .ident = "IBM",
14897 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
14898 + },
14899 +- { },
14900 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
14901 + };
14902 +
14903 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
14904 +@@ -431,7 +431,7 @@ static struct pci_device_id piix4_ids[]
14905 + PCI_DEVICE_ID_SERVERWORKS_CSB6) },
14906 + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
14907 + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
14908 +- { 0, }
14909 ++ { 0, 0, 0, 0, 0, 0, 0 }
14910 + };
14911 +
14912 + MODULE_DEVICE_TABLE (pci, piix4_ids);
14913 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c
14914 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c 2008-10-08 23:24:05.000000000 -0400
14915 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-sis630.c 2008-10-11 21:54:20.000000000 -0400
14916 +@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
14917 + static struct pci_device_id sis630_ids[] __devinitdata = {
14918 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
14919 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
14920 +- { 0, }
14921 ++ { 0, 0, 0, 0, 0, 0, 0 }
14922 + };
14923 +
14924 + MODULE_DEVICE_TABLE (pci, sis630_ids);
14925 +diff -urNp linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c
14926 +--- linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c 2008-10-08 23:24:05.000000000 -0400
14927 ++++ linux-2.6.26.6/drivers/i2c/busses/i2c-sis96x.c 2008-10-11 21:54:20.000000000 -0400
14928 +@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
14929 +
14930 + static struct pci_device_id sis96x_ids[] = {
14931 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
14932 +- { 0, }
14933 ++ { 0, 0, 0, 0, 0, 0, 0 }
14934 + };
14935 +
14936 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
14937 +diff -urNp linux-2.6.26.6/drivers/ieee1394/dv1394.c linux-2.6.26.6/drivers/ieee1394/dv1394.c
14938 +--- linux-2.6.26.6/drivers/ieee1394/dv1394.c 2008-10-08 23:24:05.000000000 -0400
14939 ++++ linux-2.6.26.6/drivers/ieee1394/dv1394.c 2008-10-11 21:54:20.000000000 -0400
14940 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
14941 + based upon DIF section and sequence
14942 + */
14943 +
14944 +-static void inline
14945 ++static inline void
14946 + frame_put_packet (struct frame *f, struct packet *p)
14947 + {
14948 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
14949 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
14950 + /* default SYT offset is 3 cycles */
14951 + init->syt_offset = 3;
14952 +
14953 +- if ( (init->channel > 63) || (init->channel < 0) )
14954 ++ if (init->channel > 63)
14955 + init->channel = 63;
14956 +
14957 + chan_mask = (u64)1 << init->channel;
14958 +@@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
14959 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
14960 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
14961 + },
14962 +- { }
14963 ++ { 0, 0, 0, 0, 0, 0 }
14964 + };
14965 +
14966 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
14967 +diff -urNp linux-2.6.26.6/drivers/ieee1394/eth1394.c linux-2.6.26.6/drivers/ieee1394/eth1394.c
14968 +--- linux-2.6.26.6/drivers/ieee1394/eth1394.c 2008-10-08 23:24:05.000000000 -0400
14969 ++++ linux-2.6.26.6/drivers/ieee1394/eth1394.c 2008-10-11 21:54:20.000000000 -0400
14970 +@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
14971 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
14972 + .version = ETHER1394_GASP_VERSION,
14973 + },
14974 +- {}
14975 ++ { 0, 0, 0, 0, 0, 0 }
14976 + };
14977 +
14978 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
14979 +diff -urNp linux-2.6.26.6/drivers/ieee1394/hosts.c linux-2.6.26.6/drivers/ieee1394/hosts.c
14980 +--- linux-2.6.26.6/drivers/ieee1394/hosts.c 2008-10-08 23:24:05.000000000 -0400
14981 ++++ linux-2.6.26.6/drivers/ieee1394/hosts.c 2008-10-11 21:54:20.000000000 -0400
14982 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
14983 + }
14984 +
14985 + static struct hpsb_host_driver dummy_driver = {
14986 ++ .name = "dummy",
14987 + .transmit_packet = dummy_transmit_packet,
14988 + .devctl = dummy_devctl,
14989 + .isoctl = dummy_isoctl
14990 +diff -urNp linux-2.6.26.6/drivers/ieee1394/ohci1394.c linux-2.6.26.6/drivers/ieee1394/ohci1394.c
14991 +--- linux-2.6.26.6/drivers/ieee1394/ohci1394.c 2008-10-08 23:24:05.000000000 -0400
14992 ++++ linux-2.6.26.6/drivers/ieee1394/ohci1394.c 2008-10-11 21:54:20.000000000 -0400
14993 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
14994 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
14995 +
14996 + /* Module Parameters */
14997 +-static int phys_dma = 1;
14998 ++static int phys_dma;
14999 + module_param(phys_dma, int, 0444);
15000 +-MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
15001 ++MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
15002 +
15003 + static void dma_trm_tasklet(unsigned long data);
15004 + static void dma_trm_reset(struct dma_trm_ctx *d);
15005 +@@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
15006 + .subvendor = PCI_ANY_ID,
15007 + .subdevice = PCI_ANY_ID,
15008 + },
15009 +- { 0, },
15010 ++ { 0, 0, 0, 0, 0, 0, 0 },
15011 + };
15012 +
15013 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
15014 +diff -urNp linux-2.6.26.6/drivers/ieee1394/raw1394.c linux-2.6.26.6/drivers/ieee1394/raw1394.c
15015 +--- linux-2.6.26.6/drivers/ieee1394/raw1394.c 2008-10-08 23:24:05.000000000 -0400
15016 ++++ linux-2.6.26.6/drivers/ieee1394/raw1394.c 2008-10-11 21:54:20.000000000 -0400
15017 +@@ -2958,7 +2958,7 @@ static struct ieee1394_device_id raw1394
15018 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15019 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15020 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
15021 +- {}
15022 ++ { 0, 0, 0, 0, 0, 0 }
15023 + };
15024 +
15025 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
15026 +diff -urNp linux-2.6.26.6/drivers/ieee1394/sbp2.c linux-2.6.26.6/drivers/ieee1394/sbp2.c
15027 +--- linux-2.6.26.6/drivers/ieee1394/sbp2.c 2008-10-08 23:24:05.000000000 -0400
15028 ++++ linux-2.6.26.6/drivers/ieee1394/sbp2.c 2008-10-11 21:54:20.000000000 -0400
15029 +@@ -283,7 +283,7 @@ static struct ieee1394_device_id sbp2_id
15030 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
15031 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
15032 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
15033 +- {}
15034 ++ { 0, 0, 0, 0, 0, 0 }
15035 + };
15036 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
15037 +
15038 +@@ -2101,7 +2101,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
15039 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
15040 + MODULE_LICENSE("GPL");
15041 +
15042 +-static int sbp2_module_init(void)
15043 ++static int __init sbp2_module_init(void)
15044 + {
15045 + int ret;
15046 +
15047 +diff -urNp linux-2.6.26.6/drivers/ieee1394/video1394.c linux-2.6.26.6/drivers/ieee1394/video1394.c
15048 +--- linux-2.6.26.6/drivers/ieee1394/video1394.c 2008-10-08 23:24:05.000000000 -0400
15049 ++++ linux-2.6.26.6/drivers/ieee1394/video1394.c 2008-10-11 21:54:20.000000000 -0400
15050 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
15051 + if (unlikely(d == NULL))
15052 + return -EFAULT;
15053 +
15054 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
15055 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
15056 + PRINT(KERN_ERR, ohci->host->id,
15057 + "Buffer %d out of range",v.buffer);
15058 + return -EINVAL;
15059 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
15060 + if (unlikely(d == NULL))
15061 + return -EFAULT;
15062 +
15063 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
15064 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
15065 + PRINT(KERN_ERR, ohci->host->id,
15066 + "Buffer %d out of range",v.buffer);
15067 + return -EINVAL;
15068 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
15069 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
15070 + if (d == NULL) return -EFAULT;
15071 +
15072 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
15073 ++ if (v.buffer>=d->num_desc - 1) {
15074 + PRINT(KERN_ERR, ohci->host->id,
15075 + "Buffer %d out of range",v.buffer);
15076 + return -EINVAL;
15077 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
15078 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
15079 + if (d == NULL) return -EFAULT;
15080 +
15081 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
15082 ++ if (v.buffer>=d->num_desc-1) {
15083 + PRINT(KERN_ERR, ohci->host->id,
15084 + "Buffer %d out of range",v.buffer);
15085 + return -EINVAL;
15086 +@@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
15087 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
15088 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
15089 + },
15090 +- { }
15091 ++ { 0, 0, 0, 0, 0, 0 }
15092 + };
15093 +
15094 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
15095 +diff -urNp linux-2.6.26.6/drivers/input/keyboard/atkbd.c linux-2.6.26.6/drivers/input/keyboard/atkbd.c
15096 +--- linux-2.6.26.6/drivers/input/keyboard/atkbd.c 2008-10-08 23:24:05.000000000 -0400
15097 ++++ linux-2.6.26.6/drivers/input/keyboard/atkbd.c 2008-10-11 21:54:20.000000000 -0400
15098 +@@ -1115,7 +1115,7 @@ static struct serio_device_id atkbd_seri
15099 + .id = SERIO_ANY,
15100 + .extra = SERIO_ANY,
15101 + },
15102 +- { 0 }
15103 ++ { 0, 0, 0, 0 }
15104 + };
15105 +
15106 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
15107 +diff -urNp linux-2.6.26.6/drivers/input/mouse/lifebook.c linux-2.6.26.6/drivers/input/mouse/lifebook.c
15108 +--- linux-2.6.26.6/drivers/input/mouse/lifebook.c 2008-10-08 23:24:05.000000000 -0400
15109 ++++ linux-2.6.26.6/drivers/input/mouse/lifebook.c 2008-10-11 21:54:20.000000000 -0400
15110 +@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
15111 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
15112 + },
15113 + },
15114 +- { }
15115 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
15116 + };
15117 +
15118 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
15119 +diff -urNp linux-2.6.26.6/drivers/input/mouse/psmouse-base.c linux-2.6.26.6/drivers/input/mouse/psmouse-base.c
15120 +--- linux-2.6.26.6/drivers/input/mouse/psmouse-base.c 2008-10-08 23:24:05.000000000 -0400
15121 ++++ linux-2.6.26.6/drivers/input/mouse/psmouse-base.c 2008-10-11 21:54:20.000000000 -0400
15122 +@@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
15123 + .id = SERIO_ANY,
15124 + .extra = SERIO_ANY,
15125 + },
15126 +- { 0 }
15127 ++ { 0, 0, 0, 0 }
15128 + };
15129 +
15130 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
15131 +diff -urNp linux-2.6.26.6/drivers/input/mouse/synaptics.c linux-2.6.26.6/drivers/input/mouse/synaptics.c
15132 +--- linux-2.6.26.6/drivers/input/mouse/synaptics.c 2008-10-08 23:24:05.000000000 -0400
15133 ++++ linux-2.6.26.6/drivers/input/mouse/synaptics.c 2008-10-11 21:54:20.000000000 -0400
15134 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
15135 + break;
15136 + case 2:
15137 + if (SYN_MODEL_PEN(priv->model_id))
15138 +- ; /* Nothing, treat a pen as a single finger */
15139 ++ break; /* Nothing, treat a pen as a single finger */
15140 + break;
15141 + case 4 ... 15:
15142 + if (SYN_CAP_PALMDETECT(priv->capabilities))
15143 +@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
15144 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
15145 + },
15146 + },
15147 +- { }
15148 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15149 + };
15150 + #endif
15151 +
15152 +diff -urNp linux-2.6.26.6/drivers/input/mousedev.c linux-2.6.26.6/drivers/input/mousedev.c
15153 +--- linux-2.6.26.6/drivers/input/mousedev.c 2008-10-08 23:24:05.000000000 -0400
15154 ++++ linux-2.6.26.6/drivers/input/mousedev.c 2008-10-11 21:54:20.000000000 -0400
15155 +@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
15156 +
15157 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
15158 + static struct miscdevice psaux_mouse = {
15159 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
15160 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
15161 + };
15162 + static int psaux_registered;
15163 + #endif
15164 +diff -urNp linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h
15165 +--- linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h 2008-10-08 23:24:05.000000000 -0400
15166 ++++ linux-2.6.26.6/drivers/input/serio/i8042-x86ia64io.h 2008-10-11 21:54:20.000000000 -0400
15167 +@@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
15168 + DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
15169 + },
15170 + },
15171 +- { }
15172 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15173 + };
15174 +
15175 + /*
15176 +@@ -298,7 +298,7 @@ static struct dmi_system_id __initdata i
15177 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
15178 + },
15179 + },
15180 +- { }
15181 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15182 + };
15183 +
15184 + #ifdef CONFIG_PNP
15185 +@@ -317,7 +317,7 @@ static struct dmi_system_id __initdata i
15186 + DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
15187 + },
15188 + },
15189 +- { }
15190 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
15191 + };
15192 + #endif
15193 +
15194 +diff -urNp linux-2.6.26.6/drivers/input/serio/serio_raw.c linux-2.6.26.6/drivers/input/serio/serio_raw.c
15195 +--- linux-2.6.26.6/drivers/input/serio/serio_raw.c 2008-10-08 23:24:05.000000000 -0400
15196 ++++ linux-2.6.26.6/drivers/input/serio/serio_raw.c 2008-10-11 21:54:20.000000000 -0400
15197 +@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
15198 + .id = SERIO_ANY,
15199 + .extra = SERIO_ANY,
15200 + },
15201 +- { 0 }
15202 ++ { 0, 0, 0, 0 }
15203 + };
15204 +
15205 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
15206 +diff -urNp linux-2.6.26.6/drivers/md/bitmap.c linux-2.6.26.6/drivers/md/bitmap.c
15207 +--- linux-2.6.26.6/drivers/md/bitmap.c 2008-10-08 23:24:05.000000000 -0400
15208 ++++ linux-2.6.26.6/drivers/md/bitmap.c 2008-10-11 21:54:20.000000000 -0400
15209 +@@ -57,7 +57,7 @@
15210 + # if DEBUG > 0
15211 + # define PRINTK(x...) printk(KERN_DEBUG x)
15212 + # else
15213 +-# define PRINTK(x...)
15214 ++# define PRINTK(x...) do {} while (0)
15215 + # endif
15216 + #endif
15217 +
15218 +diff -urNp linux-2.6.26.6/drivers/mtd/devices/doc2000.c linux-2.6.26.6/drivers/mtd/devices/doc2000.c
15219 +--- linux-2.6.26.6/drivers/mtd/devices/doc2000.c 2008-10-08 23:24:05.000000000 -0400
15220 ++++ linux-2.6.26.6/drivers/mtd/devices/doc2000.c 2008-10-11 21:54:20.000000000 -0400
15221 +@@ -779,7 +779,7 @@ static int doc_write(struct mtd_info *mt
15222 +
15223 + /* The ECC will not be calculated correctly if less than 512 is written */
15224 + /* DBB-
15225 +- if (len != 0x200 && eccbuf)
15226 ++ if (len != 0x200)
15227 + printk(KERN_WARNING
15228 + "ECC needs a full sector write (adr: %lx size %lx)\n",
15229 + (long) to, (long) len);
15230 +diff -urNp linux-2.6.26.6/drivers/mtd/devices/doc2001.c linux-2.6.26.6/drivers/mtd/devices/doc2001.c
15231 +--- linux-2.6.26.6/drivers/mtd/devices/doc2001.c 2008-10-08 23:24:05.000000000 -0400
15232 ++++ linux-2.6.26.6/drivers/mtd/devices/doc2001.c 2008-10-11 21:54:20.000000000 -0400
15233 +@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
15234 + /* Don't allow read past end of device */
15235 + if (from >= this->totlen)
15236 + return -EINVAL;
15237 ++ if (!len)
15238 ++ return -EINVAL;
15239 +
15240 + /* Don't allow a single read to cross a 512-byte block boundary */
15241 + if (from + len > ((from | 0x1ff) + 1))
15242 +diff -urNp linux-2.6.26.6/drivers/mtd/devices/slram.c linux-2.6.26.6/drivers/mtd/devices/slram.c
15243 +--- linux-2.6.26.6/drivers/mtd/devices/slram.c 2008-10-08 23:24:05.000000000 -0400
15244 ++++ linux-2.6.26.6/drivers/mtd/devices/slram.c 2008-10-11 21:54:20.000000000 -0400
15245 +@@ -275,7 +275,7 @@ static int parse_cmdline(char *devname,
15246 + }
15247 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
15248 + devname, devstart, devlength);
15249 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
15250 ++ if (devlength % SLRAM_BLK_SZ != 0) {
15251 + E("slram: Illegal start / length parameter.\n");
15252 + return(-EINVAL);
15253 + }
15254 +diff -urNp linux-2.6.26.6/drivers/mtd/ubi/build.c linux-2.6.26.6/drivers/mtd/ubi/build.c
15255 +--- linux-2.6.26.6/drivers/mtd/ubi/build.c 2008-10-08 23:24:05.000000000 -0400
15256 ++++ linux-2.6.26.6/drivers/mtd/ubi/build.c 2008-10-11 21:54:20.000000000 -0400
15257 +@@ -1057,7 +1057,7 @@ static int __init bytes_str_to_int(const
15258 + unsigned long result;
15259 +
15260 + result = simple_strtoul(str, &endp, 0);
15261 +- if (str == endp || result < 0) {
15262 ++ if (str == endp) {
15263 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
15264 + str);
15265 + return -EINVAL;
15266 +diff -urNp linux-2.6.26.6/drivers/net/eepro100.c linux-2.6.26.6/drivers/net/eepro100.c
15267 +--- linux-2.6.26.6/drivers/net/eepro100.c 2008-10-08 23:24:05.000000000 -0400
15268 ++++ linux-2.6.26.6/drivers/net/eepro100.c 2008-10-11 21:54:20.000000000 -0400
15269 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
15270 + # define rx_align(skb) skb_reserve((skb), 2)
15271 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
15272 + #else
15273 +-# define rx_align(skb)
15274 ++# define rx_align(skb) do {} while (0)
15275 + # define RxFD_ALIGNMENT
15276 + #endif
15277 +
15278 +@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
15279 + }
15280 +
15281 + static struct pci_device_id eepro100_pci_tbl[] = {
15282 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
15283 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
15284 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
15285 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
15286 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
15287 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
15288 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
15289 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
15290 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
15291 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
15292 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
15293 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
15294 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
15295 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
15296 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
15297 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
15298 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
15299 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
15300 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
15301 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
15302 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
15303 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
15304 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
15305 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
15306 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
15307 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
15308 +- { 0,}
15309 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15310 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15311 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15312 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15313 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15314 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15315 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15316 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15317 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15318 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15319 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15320 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15321 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15322 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15323 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15324 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15325 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15326 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15327 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15328 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15329 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15330 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15331 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15332 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15333 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15334 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
15335 ++ { 0, 0, 0, 0, 0, 0, 0 }
15336 + };
15337 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
15338 +
15339 +diff -urNp linux-2.6.26.6/drivers/net/irda/vlsi_ir.c linux-2.6.26.6/drivers/net/irda/vlsi_ir.c
15340 +--- linux-2.6.26.6/drivers/net/irda/vlsi_ir.c 2008-10-08 23:24:05.000000000 -0400
15341 ++++ linux-2.6.26.6/drivers/net/irda/vlsi_ir.c 2008-10-11 21:54:20.000000000 -0400
15342 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
15343 + /* no race - tx-ring already empty */
15344 + vlsi_set_baud(idev, iobase);
15345 + netif_wake_queue(ndev);
15346 +- }
15347 +- else
15348 +- ;
15349 ++ } else {
15350 + /* keep the speed change pending like it would
15351 + * for any len>0 packet. tx completion interrupt
15352 + * will apply it when the tx ring becomes empty.
15353 + */
15354 ++ }
15355 + spin_unlock_irqrestore(&idev->lock, flags);
15356 + dev_kfree_skb_any(skb);
15357 + return 0;
15358 +diff -urNp linux-2.6.26.6/drivers/net/pcnet32.c linux-2.6.26.6/drivers/net/pcnet32.c
15359 +--- linux-2.6.26.6/drivers/net/pcnet32.c 2008-10-08 23:24:05.000000000 -0400
15360 ++++ linux-2.6.26.6/drivers/net/pcnet32.c 2008-10-11 21:54:20.000000000 -0400
15361 +@@ -78,7 +78,7 @@ static int cards_found;
15362 + /*
15363 + * VLB I/O addresses
15364 + */
15365 +-static unsigned int pcnet32_portlist[] __initdata =
15366 ++static unsigned int pcnet32_portlist[] __devinitdata =
15367 + { 0x300, 0x320, 0x340, 0x360, 0 };
15368 +
15369 + static int pcnet32_debug = 0;
15370 +diff -urNp linux-2.6.26.6/drivers/net/tg3.h linux-2.6.26.6/drivers/net/tg3.h
15371 +--- linux-2.6.26.6/drivers/net/tg3.h 2008-10-08 23:24:05.000000000 -0400
15372 ++++ linux-2.6.26.6/drivers/net/tg3.h 2008-10-11 21:54:20.000000000 -0400
15373 +@@ -102,6 +102,7 @@
15374 + #define CHIPREV_ID_5750_A0 0x4000
15375 + #define CHIPREV_ID_5750_A1 0x4001
15376 + #define CHIPREV_ID_5750_A3 0x4003
15377 ++#define CHIPREV_ID_5750_C1 0x4201
15378 + #define CHIPREV_ID_5750_C2 0x4202
15379 + #define CHIPREV_ID_5752_A0_HW 0x5000
15380 + #define CHIPREV_ID_5752_A0 0x6000
15381 +diff -urNp linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c
15382 +--- linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-10-08 23:24:05.000000000 -0400
15383 ++++ linux-2.6.26.6/drivers/pci/hotplug/cpqphp_nvram.c 2008-10-11 21:54:20.000000000 -0400
15384 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
15385 +
15386 + void compaq_nvram_init (void __iomem *rom_start)
15387 + {
15388 ++
15389 ++#ifndef CONFIG_PAX_KERNEXEC
15390 + if (rom_start) {
15391 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
15392 + }
15393 ++#endif
15394 ++
15395 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
15396 +
15397 + /* initialize our int15 lock */
15398 +diff -urNp linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c
15399 +--- linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c 2008-10-08 23:24:05.000000000 -0400
15400 ++++ linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv.c 2008-10-11 21:54:20.000000000 -0400
15401 +@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
15402 + .port_type = PCIE_RC_PORT,
15403 + .service_type = PCIE_PORT_SERVICE_AER,
15404 + },
15405 +- { /* end: all zeroes */ }
15406 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15407 + };
15408 +
15409 + static struct pci_error_handlers aer_error_handlers = {
15410 +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
15411 +--- linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-10-08 23:24:05.000000000 -0400
15412 ++++ linux-2.6.26.6/drivers/pci/pcie/aer/aerdrv_core.c 2008-10-11 21:54:20.000000000 -0400
15413 +@@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
15414 + struct aer_err_source *e_src)
15415 + {
15416 + struct device *s_device;
15417 +- struct aer_err_info e_info = {0, 0, 0,};
15418 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
15419 + int i;
15420 + u16 id;
15421 +
15422 +diff -urNp linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c
15423 +--- linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c 2008-10-08 23:24:05.000000000 -0400
15424 ++++ linux-2.6.26.6/drivers/pci/pcie/portdrv_pci.c 2008-10-11 21:54:20.000000000 -0400
15425 +@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
15426 + static const struct pci_device_id port_pci_ids[] = { {
15427 + /* handle any PCI-Express port */
15428 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
15429 +- }, { /* end: all zeroes */ }
15430 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
15431 + };
15432 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
15433 +
15434 +diff -urNp linux-2.6.26.6/drivers/pci/proc.c linux-2.6.26.6/drivers/pci/proc.c
15435 +--- linux-2.6.26.6/drivers/pci/proc.c 2008-10-08 23:24:05.000000000 -0400
15436 ++++ linux-2.6.26.6/drivers/pci/proc.c 2008-10-11 21:54:20.000000000 -0400
15437 +@@ -472,7 +472,16 @@ static const struct file_operations proc
15438 + static int __init pci_proc_init(void)
15439 + {
15440 + struct pci_dev *dev = NULL;
15441 ++
15442 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
15443 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
15444 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
15445 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15446 ++ proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
15447 ++#endif
15448 ++#else
15449 + proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
15450 ++#endif
15451 + proc_create("devices", 0, proc_bus_pci_dir,
15452 + &proc_bus_pci_dev_operations);
15453 + proc_initialized = 1;
15454 +diff -urNp linux-2.6.26.6/drivers/pcmcia/ti113x.h linux-2.6.26.6/drivers/pcmcia/ti113x.h
15455 +--- linux-2.6.26.6/drivers/pcmcia/ti113x.h 2008-10-08 23:24:05.000000000 -0400
15456 ++++ linux-2.6.26.6/drivers/pcmcia/ti113x.h 2008-10-11 21:54:20.000000000 -0400
15457 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
15458 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
15459 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
15460 +
15461 +- {}
15462 ++ { 0, 0, 0, 0, 0, 0, 0 }
15463 + };
15464 +
15465 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
15466 +diff -urNp linux-2.6.26.6/drivers/pcmcia/yenta_socket.c linux-2.6.26.6/drivers/pcmcia/yenta_socket.c
15467 +--- linux-2.6.26.6/drivers/pcmcia/yenta_socket.c 2008-10-08 23:24:05.000000000 -0400
15468 ++++ linux-2.6.26.6/drivers/pcmcia/yenta_socket.c 2008-10-11 21:54:20.000000000 -0400
15469 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
15470 +
15471 + /* match any cardbus bridge */
15472 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
15473 +- { /* all zeroes */ }
15474 ++ { 0, 0, 0, 0, 0, 0, 0 }
15475 + };
15476 + MODULE_DEVICE_TABLE(pci, yenta_table);
15477 +
15478 +diff -urNp linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c
15479 +--- linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c 2008-10-08 23:24:05.000000000 -0400
15480 ++++ linux-2.6.26.6/drivers/pnp/pnpbios/bioscalls.c 2008-10-11 21:54:20.000000000 -0400
15481 +@@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
15482 + set_limit(gdt[(selname) >> 3], size); \
15483 + } while(0)
15484 +
15485 +-static struct desc_struct bad_bios_desc;
15486 ++static struct desc_struct bad_bios_desc __read_only;
15487 +
15488 + /*
15489 + * At some point we want to use this stack frame pointer to unwind
15490 +@@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
15491 + struct desc_struct save_desc_40;
15492 + int cpu;
15493 +
15494 ++#ifdef CONFIG_PAX_KERNEXEC
15495 ++ unsigned long cr0;
15496 ++#endif
15497 ++
15498 + /*
15499 + * PnP BIOSes are generally not terribly re-entrant.
15500 + * Also, don't rely on them to save everything correctly.
15501 +@@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
15502 +
15503 + cpu = get_cpu();
15504 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
15505 ++
15506 ++#ifdef CONFIG_PAX_KERNEXEC
15507 ++ pax_open_kernel(cr0);
15508 ++#endif
15509 ++
15510 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
15511 +
15512 ++#ifdef CONFIG_PAX_KERNEXEC
15513 ++ pax_close_kernel(cr0);
15514 ++#endif
15515 ++
15516 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
15517 + spin_lock_irqsave(&pnp_bios_lock, flags);
15518 +
15519 +@@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
15520 + :"memory");
15521 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
15522 +
15523 ++#ifdef CONFIG_PAX_KERNEXEC
15524 ++ pax_open_kernel(cr0);
15525 ++#endif
15526 ++
15527 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
15528 ++
15529 ++#ifdef CONFIG_PAX_KERNEXEC
15530 ++ pax_close_kernel(cr0);
15531 ++#endif
15532 ++
15533 + put_cpu();
15534 +
15535 + /* If we get here and this is set then the PnP BIOS faulted on us. */
15536 +@@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
15537 + return status;
15538 + }
15539 +
15540 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
15541 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
15542 + {
15543 + int i;
15544 +
15545 ++#ifdef CONFIG_PAX_KERNEXEC
15546 ++ unsigned long cr0;
15547 ++#endif
15548 ++
15549 + spin_lock_init(&pnp_bios_lock);
15550 + pnp_bios_callpoint.offset = header->fields.pm16offset;
15551 + pnp_bios_callpoint.segment = PNP_CS16;
15552 +
15553 ++#ifdef CONFIG_PAX_KERNEXEC
15554 ++ pax_open_kernel(cr0);
15555 ++#endif
15556 ++
15557 + bad_bios_desc.a = 0;
15558 +- bad_bios_desc.b = 0x00409200;
15559 ++ bad_bios_desc.b = 0x00409300;
15560 +
15561 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
15562 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
15563 +@@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
15564 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
15565 + __va(header->fields.pm16dseg));
15566 + }
15567 ++
15568 ++#ifdef CONFIG_PAX_KERNEXEC
15569 ++ pax_close_kernel(cr0);
15570 ++#endif
15571 ++
15572 + }
15573 +diff -urNp linux-2.6.26.6/drivers/pnp/quirks.c linux-2.6.26.6/drivers/pnp/quirks.c
15574 +--- linux-2.6.26.6/drivers/pnp/quirks.c 2008-10-08 23:24:05.000000000 -0400
15575 ++++ linux-2.6.26.6/drivers/pnp/quirks.c 2008-10-11 21:54:20.000000000 -0400
15576 +@@ -319,7 +319,7 @@ static struct pnp_fixup pnp_fixups[] = {
15577 + /* PnP resources that might overlap PCI BARs */
15578 + {"PNP0c01", quirk_system_pci_resources},
15579 + {"PNP0c02", quirk_system_pci_resources},
15580 +- {""}
15581 ++ {"", NULL}
15582 + };
15583 +
15584 + void pnp_fixup_device(struct pnp_dev *dev)
15585 +diff -urNp linux-2.6.26.6/drivers/pnp/resource.c linux-2.6.26.6/drivers/pnp/resource.c
15586 +--- linux-2.6.26.6/drivers/pnp/resource.c 2008-10-08 23:24:05.000000000 -0400
15587 ++++ linux-2.6.26.6/drivers/pnp/resource.c 2008-10-11 21:54:20.000000000 -0400
15588 +@@ -378,7 +378,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
15589 + return 1;
15590 +
15591 + /* check if the resource is valid */
15592 +- if (*irq < 0 || *irq > 15)
15593 ++ if (*irq > 15)
15594 + return 0;
15595 +
15596 + /* check if the resource is reserved */
15597 +@@ -451,7 +451,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
15598 + return 1;
15599 +
15600 + /* check if the resource is valid */
15601 +- if (*dma < 0 || *dma == 4 || *dma > 7)
15602 ++ if (*dma == 4 || *dma > 7)
15603 + return 0;
15604 +
15605 + /* check if the resource is reserved */
15606 +diff -urNp linux-2.6.26.6/drivers/scsi/scsi_logging.h linux-2.6.26.6/drivers/scsi/scsi_logging.h
15607 +--- linux-2.6.26.6/drivers/scsi/scsi_logging.h 2008-10-08 23:24:05.000000000 -0400
15608 ++++ linux-2.6.26.6/drivers/scsi/scsi_logging.h 2008-10-11 21:54:20.000000000 -0400
15609 +@@ -51,7 +51,7 @@ do { \
15610 + } while (0); \
15611 + } while (0)
15612 + #else
15613 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
15614 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
15615 + #endif /* CONFIG_SCSI_LOGGING */
15616 +
15617 + /*
15618 +diff -urNp linux-2.6.26.6/drivers/serial/8250_pci.c linux-2.6.26.6/drivers/serial/8250_pci.c
15619 +--- linux-2.6.26.6/drivers/serial/8250_pci.c 2008-10-08 23:24:05.000000000 -0400
15620 ++++ linux-2.6.26.6/drivers/serial/8250_pci.c 2008-10-11 21:54:20.000000000 -0400
15621 +@@ -2844,7 +2844,7 @@ static struct pci_device_id serial_pci_t
15622 + PCI_ANY_ID, PCI_ANY_ID,
15623 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
15624 + 0xffff00, pbn_default },
15625 +- { 0, }
15626 ++ { 0, 0, 0, 0, 0, 0, 0 }
15627 + };
15628 +
15629 + static struct pci_driver serial_pci_driver = {
15630 +diff -urNp linux-2.6.26.6/drivers/usb/class/cdc-acm.c linux-2.6.26.6/drivers/usb/class/cdc-acm.c
15631 +--- linux-2.6.26.6/drivers/usb/class/cdc-acm.c 2008-10-08 23:24:05.000000000 -0400
15632 ++++ linux-2.6.26.6/drivers/usb/class/cdc-acm.c 2008-10-11 21:54:20.000000000 -0400
15633 +@@ -1264,7 +1264,7 @@ static struct usb_device_id acm_ids[] =
15634 + USB_CDC_ACM_PROTO_AT_CDMA) },
15635 +
15636 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
15637 +- { }
15638 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15639 + };
15640 +
15641 + MODULE_DEVICE_TABLE (usb, acm_ids);
15642 +diff -urNp linux-2.6.26.6/drivers/usb/class/usblp.c linux-2.6.26.6/drivers/usb/class/usblp.c
15643 +--- linux-2.6.26.6/drivers/usb/class/usblp.c 2008-10-08 23:24:05.000000000 -0400
15644 ++++ linux-2.6.26.6/drivers/usb/class/usblp.c 2008-10-11 21:54:20.000000000 -0400
15645 +@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
15646 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
15647 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
15648 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
15649 +- { 0, 0 }
15650 ++ { 0, 0, 0 }
15651 + };
15652 +
15653 + static int usblp_wwait(struct usblp *usblp, int nonblock);
15654 +@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
15655 + { USB_INTERFACE_INFO(7, 1, 2) },
15656 + { USB_INTERFACE_INFO(7, 1, 3) },
15657 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
15658 +- { } /* Terminating entry */
15659 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
15660 + };
15661 +
15662 + MODULE_DEVICE_TABLE (usb, usblp_ids);
15663 +diff -urNp linux-2.6.26.6/drivers/usb/core/hub.c linux-2.6.26.6/drivers/usb/core/hub.c
15664 +--- linux-2.6.26.6/drivers/usb/core/hub.c 2008-10-08 23:24:05.000000000 -0400
15665 ++++ linux-2.6.26.6/drivers/usb/core/hub.c 2008-10-11 21:54:20.000000000 -0400
15666 +@@ -3045,7 +3045,7 @@ static struct usb_device_id hub_id_table
15667 + .bDeviceClass = USB_CLASS_HUB},
15668 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
15669 + .bInterfaceClass = USB_CLASS_HUB},
15670 +- { } /* Terminating entry */
15671 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
15672 + };
15673 +
15674 + MODULE_DEVICE_TABLE (usb, hub_id_table);
15675 +diff -urNp linux-2.6.26.6/drivers/usb/host/ehci-pci.c linux-2.6.26.6/drivers/usb/host/ehci-pci.c
15676 +--- linux-2.6.26.6/drivers/usb/host/ehci-pci.c 2008-10-08 23:24:05.000000000 -0400
15677 ++++ linux-2.6.26.6/drivers/usb/host/ehci-pci.c 2008-10-11 21:54:20.000000000 -0400
15678 +@@ -390,7 +390,7 @@ static const struct pci_device_id pci_id
15679 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
15680 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
15681 + },
15682 +- { /* end: all zeroes */ }
15683 ++ { 0, 0, 0, 0, 0, 0, 0 }
15684 + };
15685 + MODULE_DEVICE_TABLE(pci, pci_ids);
15686 +
15687 +diff -urNp linux-2.6.26.6/drivers/usb/host/uhci-hcd.c linux-2.6.26.6/drivers/usb/host/uhci-hcd.c
15688 +--- linux-2.6.26.6/drivers/usb/host/uhci-hcd.c 2008-10-08 23:24:05.000000000 -0400
15689 ++++ linux-2.6.26.6/drivers/usb/host/uhci-hcd.c 2008-10-11 21:54:20.000000000 -0400
15690 +@@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
15691 + /* handle any USB UHCI controller */
15692 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
15693 + .driver_data = (unsigned long) &uhci_driver,
15694 +- }, { /* end: all zeroes */ }
15695 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
15696 + };
15697 +
15698 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
15699 +diff -urNp linux-2.6.26.6/drivers/usb/storage/debug.h linux-2.6.26.6/drivers/usb/storage/debug.h
15700 +--- linux-2.6.26.6/drivers/usb/storage/debug.h 2008-10-08 23:24:05.000000000 -0400
15701 ++++ linux-2.6.26.6/drivers/usb/storage/debug.h 2008-10-11 21:54:20.000000000 -0400
15702 +@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
15703 + #define US_DEBUGPX(x...) printk( x )
15704 + #define US_DEBUG(x) x
15705 + #else
15706 +-#define US_DEBUGP(x...)
15707 +-#define US_DEBUGPX(x...)
15708 +-#define US_DEBUG(x)
15709 ++#define US_DEBUGP(x...) do {} while (0)
15710 ++#define US_DEBUGPX(x...) do {} while (0)
15711 ++#define US_DEBUG(x) do {} while (0)
15712 + #endif
15713 +
15714 + #endif
15715 +diff -urNp linux-2.6.26.6/drivers/usb/storage/usb.c linux-2.6.26.6/drivers/usb/storage/usb.c
15716 +--- linux-2.6.26.6/drivers/usb/storage/usb.c 2008-10-08 23:24:05.000000000 -0400
15717 ++++ linux-2.6.26.6/drivers/usb/storage/usb.c 2008-10-11 21:54:20.000000000 -0400
15718 +@@ -137,7 +137,7 @@ static struct usb_device_id storage_usb_
15719 + #undef UNUSUAL_DEV
15720 + #undef USUAL_DEV
15721 + /* Terminating entry */
15722 +- { }
15723 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
15724 + };
15725 +
15726 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
15727 +@@ -177,7 +177,7 @@ static struct us_unusual_dev us_unusual_
15728 + # undef USUAL_DEV
15729 +
15730 + /* Terminating entry */
15731 +- { NULL }
15732 ++ { NULL, NULL, 0, 0, NULL }
15733 + };
15734 +
15735 +
15736 +diff -urNp linux-2.6.26.6/drivers/video/fbcmap.c linux-2.6.26.6/drivers/video/fbcmap.c
15737 +--- linux-2.6.26.6/drivers/video/fbcmap.c 2008-10-08 23:24:05.000000000 -0400
15738 ++++ linux-2.6.26.6/drivers/video/fbcmap.c 2008-10-11 21:54:20.000000000 -0400
15739 +@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
15740 + int rc, size = cmap->len * sizeof(u16);
15741 + struct fb_cmap umap;
15742 +
15743 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
15744 +- !info->fbops->fb_setcmap))
15745 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
15746 + return -EINVAL;
15747 +
15748 + memset(&umap, 0, sizeof(struct fb_cmap));
15749 +diff -urNp linux-2.6.26.6/drivers/video/fbmem.c linux-2.6.26.6/drivers/video/fbmem.c
15750 +--- linux-2.6.26.6/drivers/video/fbmem.c 2008-10-08 23:24:05.000000000 -0400
15751 ++++ linux-2.6.26.6/drivers/video/fbmem.c 2008-10-11 21:54:20.000000000 -0400
15752 +@@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
15753 + image->dx += image->width + 8;
15754 + }
15755 + } else if (rotate == FB_ROTATE_UD) {
15756 +- for (x = 0; x < num && image->dx >= 0; x++) {
15757 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
15758 + info->fbops->fb_imageblit(info, image);
15759 + image->dx -= image->width + 8;
15760 + }
15761 +@@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
15762 + image->dy += image->height + 8;
15763 + }
15764 + } else if (rotate == FB_ROTATE_CCW) {
15765 +- for (x = 0; x < num && image->dy >= 0; x++) {
15766 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
15767 + info->fbops->fb_imageblit(info, image);
15768 + image->dy -= image->height + 8;
15769 + }
15770 +@@ -1084,7 +1084,7 @@ fb_ioctl(struct inode *inode, struct fil
15771 + return - EFAULT;
15772 + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
15773 + return -EINVAL;
15774 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
15775 ++ if (con2fb.framebuffer >= FB_MAX)
15776 + return -EINVAL;
15777 + #ifdef CONFIG_KMOD
15778 + if (!registered_fb[con2fb.framebuffer])
15779 +diff -urNp linux-2.6.26.6/drivers/video/fbmon.c linux-2.6.26.6/drivers/video/fbmon.c
15780 +--- linux-2.6.26.6/drivers/video/fbmon.c 2008-10-08 23:24:05.000000000 -0400
15781 ++++ linux-2.6.26.6/drivers/video/fbmon.c 2008-10-11 21:54:20.000000000 -0400
15782 +@@ -45,7 +45,7 @@
15783 + #ifdef DEBUG
15784 + #define DPRINTK(fmt, args...) printk(fmt,## args)
15785 + #else
15786 +-#define DPRINTK(fmt, args...)
15787 ++#define DPRINTK(fmt, args...) do {} while (0)
15788 + #endif
15789 +
15790 + #define FBMON_FIX_HEADER 1
15791 +diff -urNp linux-2.6.26.6/drivers/video/i810/i810_accel.c linux-2.6.26.6/drivers/video/i810/i810_accel.c
15792 +--- linux-2.6.26.6/drivers/video/i810/i810_accel.c 2008-10-08 23:24:05.000000000 -0400
15793 ++++ linux-2.6.26.6/drivers/video/i810/i810_accel.c 2008-10-11 21:54:20.000000000 -0400
15794 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
15795 + }
15796 + }
15797 + printk("ringbuffer lockup!!!\n");
15798 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
15799 + i810_report_error(mmio);
15800 + par->dev_flags |= LOCKUP;
15801 + info->pixmap.scan_align = 1;
15802 +diff -urNp linux-2.6.26.6/drivers/video/i810/i810_main.c linux-2.6.26.6/drivers/video/i810/i810_main.c
15803 +--- linux-2.6.26.6/drivers/video/i810/i810_main.c 2008-10-08 23:24:05.000000000 -0400
15804 ++++ linux-2.6.26.6/drivers/video/i810/i810_main.c 2008-10-11 21:54:20.000000000 -0400
15805 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
15806 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
15807 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
15808 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
15809 +- { 0 },
15810 ++ { 0, 0, 0, 0, 0, 0, 0 },
15811 + };
15812 +
15813 + static struct pci_driver i810fb_driver = {
15814 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
15815 + int size = ((cursor->image.width + 7) >> 3) *
15816 + cursor->image.height;
15817 + int i;
15818 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
15819 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
15820 +
15821 + if (data == NULL)
15822 + return -ENOMEM;
15823 +diff -urNp linux-2.6.26.6/drivers/video/modedb.c linux-2.6.26.6/drivers/video/modedb.c
15824 +--- linux-2.6.26.6/drivers/video/modedb.c 2008-10-08 23:24:05.000000000 -0400
15825 ++++ linux-2.6.26.6/drivers/video/modedb.c 2008-10-11 21:54:20.000000000 -0400
15826 +@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
15827 + {
15828 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
15829 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
15830 +- 0, FB_VMODE_NONINTERLACED
15831 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15832 + }, {
15833 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
15834 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
15835 +- 0, FB_VMODE_NONINTERLACED
15836 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15837 + }, {
15838 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
15839 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
15840 +- 0, FB_VMODE_NONINTERLACED
15841 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15842 + }, {
15843 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
15844 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
15845 +- 0, FB_VMODE_INTERLACED
15846 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
15847 + }, {
15848 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
15849 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
15850 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15851 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15852 + }, {
15853 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
15854 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
15855 +- 0, FB_VMODE_NONINTERLACED
15856 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15857 + }, {
15858 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
15859 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
15860 +- 0, FB_VMODE_NONINTERLACED
15861 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15862 + }, {
15863 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
15864 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
15865 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15866 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15867 + }, {
15868 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
15869 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
15870 +- 0, FB_VMODE_NONINTERLACED
15871 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15872 + }, {
15873 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
15874 + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
15875 +- 0, FB_VMODE_INTERLACED
15876 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
15877 + }, {
15878 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
15879 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
15880 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15881 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15882 + }, {
15883 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
15884 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
15885 +- 0, FB_VMODE_NONINTERLACED
15886 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15887 + }, {
15888 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
15889 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
15890 +- 0, FB_VMODE_NONINTERLACED
15891 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15892 + }, {
15893 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
15894 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
15895 +- 0, FB_VMODE_NONINTERLACED
15896 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15897 + }, {
15898 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
15899 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
15900 +- 0, FB_VMODE_NONINTERLACED
15901 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15902 + }, {
15903 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
15904 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
15905 +- 0, FB_VMODE_NONINTERLACED
15906 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15907 + }, {
15908 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
15909 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
15910 +- 0, FB_VMODE_INTERLACED
15911 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
15912 + }, {
15913 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
15914 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
15915 +- 0, FB_VMODE_NONINTERLACED
15916 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15917 + }, {
15918 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
15919 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
15920 +- 0, FB_VMODE_NONINTERLACED
15921 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15922 + }, {
15923 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
15924 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
15925 +- 0, FB_VMODE_NONINTERLACED
15926 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15927 + }, {
15928 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
15929 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
15930 +- 0, FB_VMODE_NONINTERLACED
15931 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15932 + }, {
15933 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
15934 + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
15935 +- 0, FB_VMODE_NONINTERLACED
15936 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15937 + }, {
15938 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
15939 + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
15940 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15941 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15942 + }, {
15943 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
15944 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
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 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
15949 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
15950 +- 0, FB_VMODE_NONINTERLACED
15951 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15952 + }, {
15953 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
15954 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
15955 +- 0, FB_VMODE_NONINTERLACED
15956 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15957 + }, {
15958 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
15959 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
15960 +- 0, FB_VMODE_NONINTERLACED
15961 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15962 + }, {
15963 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
15964 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
15965 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
15966 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15967 + }, {
15968 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
15969 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
15970 +- 0, FB_VMODE_NONINTERLACED
15971 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15972 + }, {
15973 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
15974 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
15975 +- 0, FB_VMODE_NONINTERLACED
15976 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15977 + }, {
15978 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
15979 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
15980 +- 0, FB_VMODE_NONINTERLACED
15981 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15982 + }, {
15983 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
15984 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
15985 +- 0, FB_VMODE_NONINTERLACED
15986 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15987 + }, {
15988 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
15989 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
15990 +- 0, FB_VMODE_NONINTERLACED
15991 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15992 + }, {
15993 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
15994 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
15995 +- 0, FB_VMODE_NONINTERLACED
15996 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
15997 + }, {
15998 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
15999 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
16000 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16001 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16002 + }, {
16003 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
16004 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 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 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
16009 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
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 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
16014 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
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 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
16019 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
16020 +- 0, FB_VMODE_NONINTERLACED
16021 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16022 + }, {
16023 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
16024 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
16025 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16026 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16027 + }, {
16028 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
16029 + NULL, 70, 1800, 1440, 4000, 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 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
16034 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
16035 +- 0, FB_VMODE_NONINTERLACED
16036 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16037 + }, {
16038 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
16039 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
16040 +- 0, FB_VMODE_NONINTERLACED
16041 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16042 + }, {
16043 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
16044 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
16045 +- 0, FB_VMODE_DOUBLE
16046 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16047 + }, {
16048 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
16049 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
16050 +- 0, FB_VMODE_DOUBLE
16051 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16052 + }, {
16053 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
16054 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
16055 +- 0, FB_VMODE_DOUBLE
16056 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16057 + }, {
16058 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
16059 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
16060 +- 0, FB_VMODE_DOUBLE
16061 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16062 + }, {
16063 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
16064 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
16065 +- 0, FB_VMODE_DOUBLE
16066 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16067 + }, {
16068 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
16069 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
16070 +- 0, FB_VMODE_DOUBLE
16071 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16072 + }, {
16073 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
16074 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
16075 +- 0, FB_VMODE_DOUBLE
16076 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16077 + }, {
16078 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
16079 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
16080 +- 0, FB_VMODE_DOUBLE
16081 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16082 + }, {
16083 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
16084 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
16085 +- 0, FB_VMODE_DOUBLE
16086 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16087 + }, {
16088 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
16089 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
16090 +- 0, FB_VMODE_DOUBLE
16091 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
16092 + }, {
16093 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
16094 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
16095 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
16096 +- FB_VMODE_NONINTERLACED
16097 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16098 + }, {
16099 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
16100 + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
16101 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
16102 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16103 + }, {
16104 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
16105 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
16106 +- 0, FB_VMODE_NONINTERLACED
16107 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16108 + }, {
16109 + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
16110 + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
16111 +- 0, FB_VMODE_NONINTERLACED
16112 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
16113 + },
16114 + };
16115 +
16116 +diff -urNp linux-2.6.26.6/drivers/video/uvesafb.c linux-2.6.26.6/drivers/video/uvesafb.c
16117 +--- linux-2.6.26.6/drivers/video/uvesafb.c 2008-10-08 23:24:05.000000000 -0400
16118 ++++ linux-2.6.26.6/drivers/video/uvesafb.c 2008-10-11 21:54:20.000000000 -0400
16119 +@@ -18,6 +18,7 @@
16120 + #include <linux/fb.h>
16121 + #include <linux/io.h>
16122 + #include <linux/mutex.h>
16123 ++#include <linux/moduleloader.h>
16124 + #include <video/edid.h>
16125 + #include <video/uvesafb.h>
16126 + #ifdef CONFIG_X86
16127 +@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
16128 + NULL,
16129 + };
16130 +
16131 +- return call_usermodehelper(v86d_path, argv, envp, 1);
16132 ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
16133 + }
16134 +
16135 + /*
16136 +@@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
16137 + if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
16138 + par->pmi_setpal = par->ypan = 0;
16139 + } else {
16140 ++
16141 ++#ifdef CONFIG_PAX_KERNEXEC
16142 ++#ifdef CONFIG_MODULES
16143 ++ unsigned long cr0;
16144 ++
16145 ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
16146 ++#endif
16147 ++ if (!par->pmi_code) {
16148 ++ par->pmi_setpal = par->ypan = 0;
16149 ++ return 0;
16150 ++ }
16151 ++#endif
16152 ++
16153 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
16154 + + task->t.regs.edi);
16155 ++
16156 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16157 ++ pax_open_kernel(cr0);
16158 ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
16159 ++ pax_close_kernel(cr0);
16160 ++
16161 ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
16162 ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
16163 ++#else
16164 + par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
16165 + par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
16166 ++#endif
16167 ++
16168 + printk(KERN_INFO "uvesafb: protected mode interface info at "
16169 + "%04x:%04x\n",
16170 + (u16)task->t.regs.es, (u16)task->t.regs.edi);
16171 +@@ -1827,6 +1852,11 @@ out:
16172 + if (par->vbe_modes)
16173 + kfree(par->vbe_modes);
16174 +
16175 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16176 ++ if (par->pmi_code)
16177 ++ module_free_exec(NULL, par->pmi_code);
16178 ++#endif
16179 ++
16180 + framebuffer_release(info);
16181 + return err;
16182 + }
16183 +@@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
16184 + kfree(par->vbe_state_orig);
16185 + if (par->vbe_state_saved)
16186 + kfree(par->vbe_state_saved);
16187 ++
16188 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16189 ++ if (par->pmi_code)
16190 ++ module_free_exec(NULL, par->pmi_code);
16191 ++#endif
16192 ++
16193 + }
16194 +
16195 + framebuffer_release(info);
16196 +diff -urNp linux-2.6.26.6/drivers/video/vesafb.c linux-2.6.26.6/drivers/video/vesafb.c
16197 +--- linux-2.6.26.6/drivers/video/vesafb.c 2008-10-08 23:24:05.000000000 -0400
16198 ++++ linux-2.6.26.6/drivers/video/vesafb.c 2008-10-11 21:54:20.000000000 -0400
16199 +@@ -9,6 +9,7 @@
16200 + */
16201 +
16202 + #include <linux/module.h>
16203 ++#include <linux/moduleloader.h>
16204 + #include <linux/kernel.h>
16205 + #include <linux/errno.h>
16206 + #include <linux/string.h>
16207 +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
16208 + static int vram_total __initdata; /* Set total amount of memory */
16209 + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
16210 + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
16211 +-static void (*pmi_start)(void) __read_mostly;
16212 +-static void (*pmi_pal) (void) __read_mostly;
16213 ++static void (*pmi_start)(void) __read_only;
16214 ++static void (*pmi_pal) (void) __read_only;
16215 + static int depth __read_mostly;
16216 + static int vga_compat __read_mostly;
16217 + /* --------------------------------------------------------------------- */
16218 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
16219 + unsigned int size_vmode;
16220 + unsigned int size_remap;
16221 + unsigned int size_total;
16222 ++ void *pmi_code = NULL;
16223 +
16224 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
16225 + return -ENODEV;
16226 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
16227 + size_remap = size_total;
16228 + vesafb_fix.smem_len = size_remap;
16229 +
16230 +-#ifndef __i386__
16231 +- screen_info.vesapm_seg = 0;
16232 +-#endif
16233 +-
16234 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
16235 + printk(KERN_WARNING
16236 + "vesafb: cannot reserve video memory at 0x%lx\n",
16237 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
16238 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
16239 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
16240 +
16241 ++#ifdef __i386__
16242 ++
16243 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16244 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
16245 ++ if (!pmi_code)
16246 ++#elif !defined(CONFIG_PAX_KERNEXEC)
16247 ++ if (0)
16248 ++#endif
16249 ++
16250 ++#endif
16251 ++ screen_info.vesapm_seg = 0;
16252 ++
16253 + if (screen_info.vesapm_seg) {
16254 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
16255 +- screen_info.vesapm_seg,screen_info.vesapm_off);
16256 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
16257 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
16258 + }
16259 +
16260 + if (screen_info.vesapm_seg < 0xc000)
16261 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
16262 +
16263 + if (ypan || pmi_setpal) {
16264 + unsigned short *pmi_base;
16265 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16266 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
16267 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
16268 ++
16269 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16270 ++ unsigned long cr0;
16271 ++#endif
16272 ++
16273 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
16274 ++
16275 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16276 ++ pax_open_kernel(cr0);
16277 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
16278 ++#else
16279 ++ pmi_code = pmi_base;
16280 ++#endif
16281 ++
16282 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
16283 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
16284 ++
16285 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16286 ++ pmi_start = ktva_ktla(pmi_start);
16287 ++ pmi_pal = ktva_ktla(pmi_pal);
16288 ++ pax_close_kernel(cr0);
16289 ++#endif
16290 ++
16291 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
16292 + if (pmi_base[3]) {
16293 + printk(KERN_INFO "vesafb: pmi: ports = ");
16294 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
16295 + info->node, info->fix.id);
16296 + return 0;
16297 + err:
16298 ++
16299 ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16300 ++ module_free_exec(NULL, pmi_code);
16301 ++#endif
16302 ++
16303 + if (info->screen_base)
16304 + iounmap(info->screen_base);
16305 + framebuffer_release(info);
16306 +diff -urNp linux-2.6.26.6/fs/9p/vfs_inode.c linux-2.6.26.6/fs/9p/vfs_inode.c
16307 +--- linux-2.6.26.6/fs/9p/vfs_inode.c 2008-10-08 23:24:05.000000000 -0400
16308 ++++ linux-2.6.26.6/fs/9p/vfs_inode.c 2008-10-11 21:54:20.000000000 -0400
16309 +@@ -1022,7 +1022,7 @@ static void *v9fs_vfs_follow_link(struct
16310 + static void
16311 + v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
16312 + {
16313 +- char *s = nd_get_link(nd);
16314 ++ const char *s = nd_get_link(nd);
16315 +
16316 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
16317 + if (!IS_ERR(s))
16318 +diff -urNp linux-2.6.26.6/fs/aio.c linux-2.6.26.6/fs/aio.c
16319 +--- linux-2.6.26.6/fs/aio.c 2008-10-08 23:24:05.000000000 -0400
16320 ++++ linux-2.6.26.6/fs/aio.c 2008-10-11 21:54:20.000000000 -0400
16321 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
16322 + size += sizeof(struct io_event) * nr_events;
16323 + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
16324 +
16325 +- if (nr_pages < 0)
16326 ++ if (nr_pages <= 0)
16327 + return -EINVAL;
16328 +
16329 + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
16330 +diff -urNp linux-2.6.26.6/fs/autofs4/symlink.c linux-2.6.26.6/fs/autofs4/symlink.c
16331 +--- linux-2.6.26.6/fs/autofs4/symlink.c 2008-10-08 23:24:05.000000000 -0400
16332 ++++ linux-2.6.26.6/fs/autofs4/symlink.c 2008-10-11 21:54:20.000000000 -0400
16333 +@@ -15,7 +15,7 @@
16334 + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
16335 + {
16336 + struct autofs_info *ino = autofs4_dentry_ino(dentry);
16337 +- nd_set_link(nd, (char *)ino->u.symlink);
16338 ++ nd_set_link(nd, ino->u.symlink);
16339 + return NULL;
16340 + }
16341 +
16342 +diff -urNp linux-2.6.26.6/fs/befs/linuxvfs.c linux-2.6.26.6/fs/befs/linuxvfs.c
16343 +--- linux-2.6.26.6/fs/befs/linuxvfs.c 2008-10-08 23:24:05.000000000 -0400
16344 ++++ linux-2.6.26.6/fs/befs/linuxvfs.c 2008-10-11 21:54:20.000000000 -0400
16345 +@@ -489,7 +489,7 @@ static void befs_put_link(struct dentry
16346 + {
16347 + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
16348 + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
16349 +- char *link = nd_get_link(nd);
16350 ++ const char *link = nd_get_link(nd);
16351 + if (!IS_ERR(link))
16352 + kfree(link);
16353 + }
16354 +diff -urNp linux-2.6.26.6/fs/binfmt_aout.c linux-2.6.26.6/fs/binfmt_aout.c
16355 +--- linux-2.6.26.6/fs/binfmt_aout.c 2008-10-08 23:24:05.000000000 -0400
16356 ++++ linux-2.6.26.6/fs/binfmt_aout.c 2008-10-11 21:54:20.000000000 -0400
16357 +@@ -24,6 +24,7 @@
16358 + #include <linux/binfmts.h>
16359 + #include <linux/personality.h>
16360 + #include <linux/init.h>
16361 ++#include <linux/grsecurity.h>
16362 +
16363 + #include <asm/system.h>
16364 + #include <asm/uaccess.h>
16365 +@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
16366 + /* If the size of the dump file exceeds the rlimit, then see what would happen
16367 + if we wrote the stack, but not the data area. */
16368 + #ifdef __sparc__
16369 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
16370 + if ((dump.u_dsize + dump.u_ssize) > limit)
16371 + dump.u_dsize = 0;
16372 + #else
16373 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
16374 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
16375 + dump.u_dsize = 0;
16376 + #endif
16377 +
16378 + /* Make sure we have enough room to write the stack and data areas. */
16379 + #ifdef __sparc__
16380 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
16381 + if (dump.u_ssize > limit)
16382 + dump.u_ssize = 0;
16383 + #else
16384 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
16385 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
16386 + dump.u_ssize = 0;
16387 + #endif
16388 +@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
16389 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
16390 + if (rlim >= RLIM_INFINITY)
16391 + rlim = ~0;
16392 ++
16393 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
16394 + if (ex.a_data + ex.a_bss > rlim)
16395 + return -ENOMEM;
16396 +
16397 +@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
16398 +
16399 + compute_creds(bprm);
16400 + current->flags &= ~PF_FORKNOEXEC;
16401 ++
16402 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16403 ++ current->mm->pax_flags = 0UL;
16404 ++#endif
16405 ++
16406 ++#ifdef CONFIG_PAX_PAGEEXEC
16407 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
16408 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
16409 ++
16410 ++#ifdef CONFIG_PAX_EMUTRAMP
16411 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
16412 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
16413 ++#endif
16414 ++
16415 ++#ifdef CONFIG_PAX_MPROTECT
16416 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
16417 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
16418 ++#endif
16419 ++
16420 ++ }
16421 ++#endif
16422 ++
16423 + #ifdef __sparc__
16424 + if (N_MAGIC(ex) == NMAGIC) {
16425 + loff_t pos = fd_offset;
16426 +@@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
16427 +
16428 + down_write(&current->mm->mmap_sem);
16429 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
16430 +- PROT_READ | PROT_WRITE | PROT_EXEC,
16431 ++ PROT_READ | PROT_WRITE,
16432 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
16433 + fd_offset + ex.a_text);
16434 + up_write(&current->mm->mmap_sem);
16435 +diff -urNp linux-2.6.26.6/fs/binfmt_elf.c linux-2.6.26.6/fs/binfmt_elf.c
16436 +--- linux-2.6.26.6/fs/binfmt_elf.c 2008-10-08 23:24:05.000000000 -0400
16437 ++++ linux-2.6.26.6/fs/binfmt_elf.c 2008-10-11 21:54:20.000000000 -0400
16438 +@@ -38,10 +38,16 @@
16439 + #include <linux/random.h>
16440 + #include <linux/elf.h>
16441 + #include <linux/utsname.h>
16442 ++#include <linux/grsecurity.h>
16443 ++
16444 + #include <asm/uaccess.h>
16445 + #include <asm/param.h>
16446 + #include <asm/page.h>
16447 +
16448 ++#ifdef CONFIG_PAX_SEGMEXEC
16449 ++#include <asm/desc.h>
16450 ++#endif
16451 ++
16452 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
16453 + static int load_elf_library(struct file *);
16454 + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
16455 +@@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
16456 +
16457 + static int set_brk(unsigned long start, unsigned long end)
16458 + {
16459 ++ unsigned long e = end;
16460 ++
16461 + start = ELF_PAGEALIGN(start);
16462 + end = ELF_PAGEALIGN(end);
16463 + if (end > start) {
16464 +@@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
16465 + if (BAD_ADDR(addr))
16466 + return addr;
16467 + }
16468 +- current->mm->start_brk = current->mm->brk = end;
16469 ++ current->mm->start_brk = current->mm->brk = e;
16470 + return 0;
16471 + }
16472 +
16473 +@@ -351,10 +359,10 @@ static unsigned long load_elf_interp(str
16474 + {
16475 + struct elf_phdr *elf_phdata;
16476 + struct elf_phdr *eppnt;
16477 +- unsigned long load_addr = 0;
16478 ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
16479 + int load_addr_set = 0;
16480 + unsigned long last_bss = 0, elf_bss = 0;
16481 +- unsigned long error = ~0UL;
16482 ++ unsigned long error = -EINVAL;
16483 + unsigned long total_size;
16484 + int retval, i, size;
16485 +
16486 +@@ -400,6 +408,11 @@ static unsigned long load_elf_interp(str
16487 + goto out_close;
16488 + }
16489 +
16490 ++#ifdef CONFIG_PAX_SEGMEXEC
16491 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
16492 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16493 ++#endif
16494 ++
16495 + eppnt = elf_phdata;
16496 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
16497 + if (eppnt->p_type == PT_LOAD) {
16498 +@@ -443,8 +456,8 @@ static unsigned long load_elf_interp(str
16499 + k = load_addr + eppnt->p_vaddr;
16500 + if (BAD_ADDR(k) ||
16501 + eppnt->p_filesz > eppnt->p_memsz ||
16502 +- eppnt->p_memsz > TASK_SIZE ||
16503 +- TASK_SIZE - eppnt->p_memsz < k) {
16504 ++ eppnt->p_memsz > pax_task_size ||
16505 ++ pax_task_size - eppnt->p_memsz < k) {
16506 + error = -ENOMEM;
16507 + goto out_close;
16508 + }
16509 +@@ -498,6 +511,177 @@ out:
16510 + return error;
16511 + }
16512 +
16513 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
16514 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
16515 ++{
16516 ++ unsigned long pax_flags = 0UL;
16517 ++
16518 ++#ifdef CONFIG_PAX_PAGEEXEC
16519 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
16520 ++ pax_flags |= MF_PAX_PAGEEXEC;
16521 ++#endif
16522 ++
16523 ++#ifdef CONFIG_PAX_SEGMEXEC
16524 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
16525 ++ pax_flags |= MF_PAX_SEGMEXEC;
16526 ++#endif
16527 ++
16528 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16529 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16530 ++ if (nx_enabled)
16531 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
16532 ++ else
16533 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
16534 ++ }
16535 ++#endif
16536 ++
16537 ++#ifdef CONFIG_PAX_EMUTRAMP
16538 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
16539 ++ pax_flags |= MF_PAX_EMUTRAMP;
16540 ++#endif
16541 ++
16542 ++#ifdef CONFIG_PAX_MPROTECT
16543 ++ if (elf_phdata->p_flags & PF_MPROTECT)
16544 ++ pax_flags |= MF_PAX_MPROTECT;
16545 ++#endif
16546 ++
16547 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
16548 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
16549 ++ pax_flags |= MF_PAX_RANDMMAP;
16550 ++#endif
16551 ++
16552 ++ return pax_flags;
16553 ++}
16554 ++#endif
16555 ++
16556 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
16557 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
16558 ++{
16559 ++ unsigned long pax_flags = 0UL;
16560 ++
16561 ++#ifdef CONFIG_PAX_PAGEEXEC
16562 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
16563 ++ pax_flags |= MF_PAX_PAGEEXEC;
16564 ++#endif
16565 ++
16566 ++#ifdef CONFIG_PAX_SEGMEXEC
16567 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
16568 ++ pax_flags |= MF_PAX_SEGMEXEC;
16569 ++#endif
16570 ++
16571 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16572 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16573 ++ if (nx_enabled)
16574 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
16575 ++ else
16576 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
16577 ++ }
16578 ++#endif
16579 ++
16580 ++#ifdef CONFIG_PAX_EMUTRAMP
16581 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
16582 ++ pax_flags |= MF_PAX_EMUTRAMP;
16583 ++#endif
16584 ++
16585 ++#ifdef CONFIG_PAX_MPROTECT
16586 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
16587 ++ pax_flags |= MF_PAX_MPROTECT;
16588 ++#endif
16589 ++
16590 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
16591 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
16592 ++ pax_flags |= MF_PAX_RANDMMAP;
16593 ++#endif
16594 ++
16595 ++ return pax_flags;
16596 ++}
16597 ++#endif
16598 ++
16599 ++#ifdef CONFIG_PAX_EI_PAX
16600 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
16601 ++{
16602 ++ unsigned long pax_flags = 0UL;
16603 ++
16604 ++#ifdef CONFIG_PAX_PAGEEXEC
16605 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
16606 ++ pax_flags |= MF_PAX_PAGEEXEC;
16607 ++#endif
16608 ++
16609 ++#ifdef CONFIG_PAX_SEGMEXEC
16610 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
16611 ++ pax_flags |= MF_PAX_SEGMEXEC;
16612 ++#endif
16613 ++
16614 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
16615 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16616 ++ if (nx_enabled)
16617 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
16618 ++ else
16619 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
16620 ++ }
16621 ++#endif
16622 ++
16623 ++#ifdef CONFIG_PAX_EMUTRAMP
16624 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
16625 ++ pax_flags |= MF_PAX_EMUTRAMP;
16626 ++#endif
16627 ++
16628 ++#ifdef CONFIG_PAX_MPROTECT
16629 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
16630 ++ pax_flags |= MF_PAX_MPROTECT;
16631 ++#endif
16632 ++
16633 ++#ifdef CONFIG_PAX_ASLR
16634 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
16635 ++ pax_flags |= MF_PAX_RANDMMAP;
16636 ++#endif
16637 ++
16638 ++ return pax_flags;
16639 ++}
16640 ++#endif
16641 ++
16642 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
16643 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
16644 ++{
16645 ++ unsigned long pax_flags = 0UL;
16646 ++
16647 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
16648 ++ unsigned long i;
16649 ++#endif
16650 ++
16651 ++#ifdef CONFIG_PAX_EI_PAX
16652 ++ pax_flags = pax_parse_ei_pax(elf_ex);
16653 ++#endif
16654 ++
16655 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
16656 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
16657 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
16658 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
16659 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
16660 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
16661 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
16662 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
16663 ++ return -EINVAL;
16664 ++
16665 ++#ifdef CONFIG_PAX_SOFTMODE
16666 ++ if (pax_softmode)
16667 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
16668 ++ else
16669 ++#endif
16670 ++
16671 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
16672 ++ break;
16673 ++ }
16674 ++#endif
16675 ++
16676 ++ if (0 > pax_check_flags(&pax_flags))
16677 ++ return -EINVAL;
16678 ++
16679 ++ current->mm->pax_flags = pax_flags;
16680 ++ return 0;
16681 ++}
16682 ++#endif
16683 ++
16684 + /*
16685 + * These are the functions used to load ELF style executables and shared
16686 + * libraries. There is no binary dependent code anywhere else.
16687 +@@ -514,6 +698,11 @@ static unsigned long randomize_stack_top
16688 + {
16689 + unsigned int random_variable = 0;
16690 +
16691 ++#ifdef CONFIG_PAX_RANDUSTACK
16692 ++ if (randomize_va_space)
16693 ++ return stack_top - current->mm->delta_stack;
16694 ++#endif
16695 ++
16696 + if ((current->flags & PF_RANDOMIZE) &&
16697 + !(current->personality & ADDR_NO_RANDOMIZE)) {
16698 + random_variable = get_random_int() & STACK_RND_MASK;
16699 +@@ -532,7 +721,7 @@ static int load_elf_binary(struct linux_
16700 + unsigned long load_addr = 0, load_bias = 0;
16701 + int load_addr_set = 0;
16702 + char * elf_interpreter = NULL;
16703 +- unsigned long error;
16704 ++ unsigned long error = 0;
16705 + struct elf_phdr *elf_ppnt, *elf_phdata;
16706 + unsigned long elf_bss, elf_brk;
16707 + int elf_exec_fileno;
16708 +@@ -543,11 +732,11 @@ static int load_elf_binary(struct linux_
16709 + unsigned long start_code, end_code, start_data, end_data;
16710 + unsigned long reloc_func_desc = 0;
16711 + int executable_stack = EXSTACK_DEFAULT;
16712 +- unsigned long def_flags = 0;
16713 + struct {
16714 + struct elfhdr elf_ex;
16715 + struct elfhdr interp_elf_ex;
16716 + } *loc;
16717 ++ unsigned long pax_task_size = TASK_SIZE;
16718 +
16719 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
16720 + if (!loc) {
16721 +@@ -715,11 +904,80 @@ static int load_elf_binary(struct linux_
16722 +
16723 + /* OK, This is the point of no return */
16724 + current->flags &= ~PF_FORKNOEXEC;
16725 +- current->mm->def_flags = def_flags;
16726 ++
16727 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16728 ++ current->mm->pax_flags = 0UL;
16729 ++#endif
16730 ++
16731 ++#ifdef CONFIG_PAX_DLRESOLVE
16732 ++ current->mm->call_dl_resolve = 0UL;
16733 ++#endif
16734 ++
16735 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
16736 ++ current->mm->call_syscall = 0UL;
16737 ++#endif
16738 ++
16739 ++#ifdef CONFIG_PAX_ASLR
16740 ++ current->mm->delta_mmap = 0UL;
16741 ++ current->mm->delta_stack = 0UL;
16742 ++#endif
16743 ++
16744 ++ current->mm->def_flags = 0;
16745 ++
16746 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
16747 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
16748 ++ send_sig(SIGKILL, current, 0);
16749 ++ goto out_free_dentry;
16750 ++ }
16751 ++#endif
16752 ++
16753 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
16754 ++ pax_set_initial_flags(bprm);
16755 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
16756 ++ if (pax_set_initial_flags_func)
16757 ++ (pax_set_initial_flags_func)(bprm);
16758 ++#endif
16759 ++
16760 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
16761 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
16762 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
16763 ++ current->mm->def_flags |= VM_PAGEEXEC;
16764 ++ }
16765 ++#endif
16766 ++
16767 ++#ifdef CONFIG_PAX_SEGMEXEC
16768 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
16769 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
16770 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
16771 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16772 ++ }
16773 ++#endif
16774 ++
16775 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
16776 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16777 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
16778 ++ put_cpu_no_resched();
16779 ++ }
16780 ++#endif
16781 ++
16782 ++#ifdef CONFIG_PAX_ASLR
16783 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
16784 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
16785 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
16786 ++ }
16787 ++#endif
16788 +
16789 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
16790 + may depend on the personality. */
16791 + SET_PERSONALITY(loc->elf_ex, 0);
16792 ++
16793 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
16794 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
16795 ++ executable_stack = EXSTACK_DISABLE_X;
16796 ++ current->personality &= ~READ_IMPLIES_EXEC;
16797 ++ } else
16798 ++#endif
16799 ++
16800 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
16801 + current->personality |= READ_IMPLIES_EXEC;
16802 +
16803 +@@ -800,6 +1058,20 @@ static int load_elf_binary(struct linux_
16804 + #else
16805 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
16806 + #endif
16807 ++
16808 ++#ifdef CONFIG_PAX_RANDMMAP
16809 ++ /* PaX: randomize base address at the default exe base if requested */
16810 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
16811 ++#ifdef CONFIG_SPARC64
16812 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
16813 ++#else
16814 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
16815 ++#endif
16816 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
16817 ++ elf_flags |= MAP_FIXED;
16818 ++ }
16819 ++#endif
16820 ++
16821 + }
16822 +
16823 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
16824 +@@ -832,9 +1104,9 @@ static int load_elf_binary(struct linux_
16825 + * allowed task size. Note that p_filesz must always be
16826 + * <= p_memsz so it is only necessary to check p_memsz.
16827 + */
16828 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
16829 +- elf_ppnt->p_memsz > TASK_SIZE ||
16830 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
16831 ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
16832 ++ elf_ppnt->p_memsz > pax_task_size ||
16833 ++ pax_task_size - elf_ppnt->p_memsz < k) {
16834 + /* set_brk can never work. Avoid overflows. */
16835 + send_sig(SIGKILL, current, 0);
16836 + retval = -EINVAL;
16837 +@@ -862,6 +1134,11 @@ static int load_elf_binary(struct linux_
16838 + start_data += load_bias;
16839 + end_data += load_bias;
16840 +
16841 ++#ifdef CONFIG_PAX_RANDMMAP
16842 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
16843 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
16844 ++#endif
16845 ++
16846 + /* Calling set_brk effectively mmaps the pages that we need
16847 + * for the bss and break sections. We must do this before
16848 + * mapping in the interpreter, to make sure it doesn't wind
16849 +@@ -873,9 +1150,11 @@ static int load_elf_binary(struct linux_
16850 + goto out_free_dentry;
16851 + }
16852 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
16853 +- send_sig(SIGSEGV, current, 0);
16854 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
16855 +- goto out_free_dentry;
16856 ++ /*
16857 ++ * This bss-zeroing can fail if the ELF
16858 ++ * file specifies odd protections. So
16859 ++ * we don't check the return value
16860 ++ */
16861 + }
16862 +
16863 + if (elf_interpreter) {
16864 +@@ -1118,8 +1397,10 @@ static int dump_seek(struct file *file,
16865 + unsigned long n = off;
16866 + if (n > PAGE_SIZE)
16867 + n = PAGE_SIZE;
16868 +- if (!dump_write(file, buf, n))
16869 ++ if (!dump_write(file, buf, n)) {
16870 ++ free_page((unsigned long)buf);
16871 + return 0;
16872 ++ }
16873 + off -= n;
16874 + }
16875 + free_page((unsigned long)buf);
16876 +@@ -1131,7 +1412,7 @@ static int dump_seek(struct file *file,
16877 + * Decide what to dump of a segment, part, all or none.
16878 + */
16879 + static unsigned long vma_dump_size(struct vm_area_struct *vma,
16880 +- unsigned long mm_flags)
16881 ++ unsigned long mm_flags, long signr)
16882 + {
16883 + /* The vma can be set up to tell us the answer directly. */
16884 + if (vma->vm_flags & VM_ALWAYSDUMP)
16885 +@@ -1157,7 +1438,7 @@ static unsigned long vma_dump_size(struc
16886 + if (vma->vm_file == NULL)
16887 + return 0;
16888 +
16889 +- if (FILTER(MAPPED_PRIVATE))
16890 ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
16891 + goto whole;
16892 +
16893 + /*
16894 +@@ -1243,8 +1524,11 @@ static int writenote(struct memelfnote *
16895 + #undef DUMP_WRITE
16896 +
16897 + #define DUMP_WRITE(addr, nr) \
16898 ++ do { \
16899 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
16900 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
16901 +- goto end_coredump;
16902 ++ goto end_coredump; \
16903 ++ } while (0);
16904 + #define DUMP_SEEK(off) \
16905 + if (!dump_seek(file, (off))) \
16906 + goto end_coredump;
16907 +@@ -1957,7 +2241,7 @@ static int elf_core_dump(long signr, str
16908 + phdr.p_offset = offset;
16909 + phdr.p_vaddr = vma->vm_start;
16910 + phdr.p_paddr = 0;
16911 +- phdr.p_filesz = vma_dump_size(vma, mm_flags);
16912 ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
16913 + phdr.p_memsz = vma->vm_end - vma->vm_start;
16914 + offset += phdr.p_filesz;
16915 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
16916 +@@ -1989,7 +2273,7 @@ static int elf_core_dump(long signr, str
16917 + unsigned long addr;
16918 + unsigned long end;
16919 +
16920 +- end = vma->vm_start + vma_dump_size(vma, mm_flags);
16921 ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
16922 +
16923 + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
16924 + struct page *page;
16925 +@@ -2009,6 +2293,7 @@ static int elf_core_dump(long signr, str
16926 + flush_cache_page(tmp_vma, addr,
16927 + page_to_pfn(page));
16928 + kaddr = kmap(page);
16929 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
16930 + if ((size += PAGE_SIZE) > limit ||
16931 + !dump_write(file, kaddr,
16932 + PAGE_SIZE)) {
16933 +diff -urNp linux-2.6.26.6/fs/binfmt_flat.c linux-2.6.26.6/fs/binfmt_flat.c
16934 +--- linux-2.6.26.6/fs/binfmt_flat.c 2008-10-08 23:24:05.000000000 -0400
16935 ++++ linux-2.6.26.6/fs/binfmt_flat.c 2008-10-11 21:54:20.000000000 -0400
16936 +@@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
16937 + realdatastart = (unsigned long) -ENOMEM;
16938 + printk("Unable to allocate RAM for process data, errno %d\n",
16939 + (int)-realdatastart);
16940 ++ down_write(&current->mm->mmap_sem);
16941 + do_munmap(current->mm, textpos, text_len);
16942 ++ up_write(&current->mm->mmap_sem);
16943 + ret = realdatastart;
16944 + goto err;
16945 + }
16946 +@@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
16947 + }
16948 + if (result >= (unsigned long)-4096) {
16949 + printk("Unable to read data+bss, errno %d\n", (int)-result);
16950 ++ down_write(&current->mm->mmap_sem);
16951 + do_munmap(current->mm, textpos, text_len);
16952 + do_munmap(current->mm, realdatastart, data_len + extra);
16953 ++ up_write(&current->mm->mmap_sem);
16954 + ret = result;
16955 + goto err;
16956 + }
16957 +@@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
16958 + }
16959 + if (result >= (unsigned long)-4096) {
16960 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
16961 ++ down_write(&current->mm->mmap_sem);
16962 + do_munmap(current->mm, textpos, text_len + data_len + extra +
16963 + MAX_SHARED_LIBS * sizeof(unsigned long));
16964 ++ up_write(&current->mm->mmap_sem);
16965 + ret = result;
16966 + goto err;
16967 + }
16968 +diff -urNp linux-2.6.26.6/fs/binfmt_misc.c linux-2.6.26.6/fs/binfmt_misc.c
16969 +--- linux-2.6.26.6/fs/binfmt_misc.c 2008-10-08 23:24:05.000000000 -0400
16970 ++++ linux-2.6.26.6/fs/binfmt_misc.c 2008-10-11 21:54:20.000000000 -0400
16971 +@@ -710,7 +710,7 @@ static int bm_fill_super(struct super_bl
16972 + static struct tree_descr bm_files[] = {
16973 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
16974 + [3] = {"register", &bm_register_operations, S_IWUSR},
16975 +- /* last one */ {""}
16976 ++ /* last one */ {"", NULL, 0}
16977 + };
16978 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
16979 + if (!err)
16980 +diff -urNp linux-2.6.26.6/fs/bio.c linux-2.6.26.6/fs/bio.c
16981 +--- linux-2.6.26.6/fs/bio.c 2008-10-08 23:24:05.000000000 -0400
16982 ++++ linux-2.6.26.6/fs/bio.c 2008-10-11 21:55:52.000000000 -0400
16983 +@@ -502,7 +502,7 @@ static int __bio_copy_iov(struct bio *bi
16984 +
16985 + while (bv_len && iov_idx < iov_count) {
16986 + unsigned int bytes;
16987 +- char *iov_addr;
16988 ++ char __user *iov_addr;
16989 +
16990 + bytes = min_t(unsigned int,
16991 + iov[iov_idx].iov_len - iov_off, bv_len);
16992 +diff -urNp linux-2.6.26.6/fs/buffer.c linux-2.6.26.6/fs/buffer.c
16993 +--- linux-2.6.26.6/fs/buffer.c 2008-10-08 23:24:05.000000000 -0400
16994 ++++ linux-2.6.26.6/fs/buffer.c 2008-10-11 21:54:20.000000000 -0400
16995 +@@ -41,6 +41,7 @@
16996 + #include <linux/bitops.h>
16997 + #include <linux/mpage.h>
16998 + #include <linux/bit_spinlock.h>
16999 ++#include <linux/grsecurity.h>
17000 +
17001 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
17002 +
17003 +@@ -2191,6 +2192,7 @@ int generic_cont_expand_simple(struct in
17004 +
17005 + err = -EFBIG;
17006 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
17007 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
17008 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
17009 + send_sig(SIGXFSZ, current, 0);
17010 + goto out;
17011 +diff -urNp linux-2.6.26.6/fs/cifs/cifs_uniupr.h linux-2.6.26.6/fs/cifs/cifs_uniupr.h
17012 +--- linux-2.6.26.6/fs/cifs/cifs_uniupr.h 2008-10-08 23:24:05.000000000 -0400
17013 ++++ linux-2.6.26.6/fs/cifs/cifs_uniupr.h 2008-10-11 21:54:20.000000000 -0400
17014 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
17015 + {0x0490, 0x04cc, UniCaseRangeU0490},
17016 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
17017 + {0xff40, 0xff5a, UniCaseRangeUff40},
17018 +- {0}
17019 ++ {0, 0, NULL}
17020 + };
17021 + #endif
17022 +
17023 +diff -urNp linux-2.6.26.6/fs/cifs/link.c linux-2.6.26.6/fs/cifs/link.c
17024 +--- linux-2.6.26.6/fs/cifs/link.c 2008-10-08 23:24:05.000000000 -0400
17025 ++++ linux-2.6.26.6/fs/cifs/link.c 2008-10-11 21:54:20.000000000 -0400
17026 +@@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
17027 +
17028 + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
17029 + {
17030 +- char *p = nd_get_link(nd);
17031 ++ const char *p = nd_get_link(nd);
17032 + if (!IS_ERR(p))
17033 + kfree(p);
17034 + }
17035 +diff -urNp linux-2.6.26.6/fs/compat.c linux-2.6.26.6/fs/compat.c
17036 +--- linux-2.6.26.6/fs/compat.c 2008-10-08 23:24:05.000000000 -0400
17037 ++++ linux-2.6.26.6/fs/compat.c 2008-10-11 21:54:20.000000000 -0400
17038 +@@ -51,6 +51,7 @@
17039 + #include <linux/poll.h>
17040 + #include <linux/mm.h>
17041 + #include <linux/eventpoll.h>
17042 ++#include <linux/grsecurity.h>
17043 +
17044 + #include <asm/uaccess.h>
17045 + #include <asm/mmu_context.h>
17046 +@@ -1294,14 +1295,12 @@ static int compat_copy_strings(int argc,
17047 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
17048 + struct page *page;
17049 +
17050 +-#ifdef CONFIG_STACK_GROWSUP
17051 + ret = expand_stack_downwards(bprm->vma, pos);
17052 + if (ret < 0) {
17053 + /* We've exceed the stack rlimit. */
17054 + ret = -E2BIG;
17055 + goto out;
17056 + }
17057 +-#endif
17058 + ret = get_user_pages(current, bprm->mm, pos,
17059 + 1, 1, 1, &page, NULL);
17060 + if (ret <= 0) {
17061 +@@ -1347,6 +1346,11 @@ int compat_do_execve(char * filename,
17062 + compat_uptr_t __user *envp,
17063 + struct pt_regs * regs)
17064 + {
17065 ++#ifdef CONFIG_GRKERNSEC
17066 ++ struct file *old_exec_file;
17067 ++ struct acl_subject_label *old_acl;
17068 ++ struct rlimit old_rlim[RLIM_NLIMITS];
17069 ++#endif
17070 + struct linux_binprm *bprm;
17071 + struct file *file;
17072 + int retval;
17073 +@@ -1367,6 +1371,14 @@ int compat_do_execve(char * filename,
17074 + bprm->filename = filename;
17075 + bprm->interp = filename;
17076 +
17077 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
17078 ++ retval = -EAGAIN;
17079 ++ if (gr_handle_nproc())
17080 ++ goto out_file;
17081 ++ retval = -EACCES;
17082 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
17083 ++ goto out_file;
17084 ++
17085 + retval = bprm_mm_init(bprm);
17086 + if (retval)
17087 + goto out_file;
17088 +@@ -1400,8 +1412,36 @@ int compat_do_execve(char * filename,
17089 + if (retval < 0)
17090 + goto out;
17091 +
17092 ++ if (!gr_tpe_allow(file)) {
17093 ++ retval = -EACCES;
17094 ++ goto out;
17095 ++ }
17096 ++
17097 ++ if (gr_check_crash_exec(file)) {
17098 ++ retval = -EACCES;
17099 ++ goto out;
17100 ++ }
17101 ++
17102 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17103 ++
17104 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
17105 ++
17106 ++#ifdef CONFIG_GRKERNSEC
17107 ++ old_acl = current->acl;
17108 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17109 ++ old_exec_file = current->exec_file;
17110 ++ get_file(file);
17111 ++ current->exec_file = file;
17112 ++#endif
17113 ++
17114 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17115 ++
17116 + retval = search_binary_handler(bprm, regs);
17117 + if (retval >= 0) {
17118 ++#ifdef CONFIG_GRKERNSEC
17119 ++ if (old_exec_file)
17120 ++ fput(old_exec_file);
17121 ++#endif
17122 + /* execve success */
17123 + security_bprm_free(bprm);
17124 + acct_update_integrals(current);
17125 +@@ -1409,6 +1449,13 @@ int compat_do_execve(char * filename,
17126 + return retval;
17127 + }
17128 +
17129 ++#ifdef CONFIG_GRKERNSEC
17130 ++ current->acl = old_acl;
17131 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17132 ++ fput(current->exec_file);
17133 ++ current->exec_file = old_exec_file;
17134 ++#endif
17135 ++
17136 + out:
17137 + if (bprm->security)
17138 + security_bprm_free(bprm);
17139 +diff -urNp linux-2.6.26.6/fs/compat_ioctl.c linux-2.6.26.6/fs/compat_ioctl.c
17140 +--- linux-2.6.26.6/fs/compat_ioctl.c 2008-10-08 23:24:05.000000000 -0400
17141 ++++ linux-2.6.26.6/fs/compat_ioctl.c 2008-10-11 21:54:20.000000000 -0400
17142 +@@ -1889,15 +1889,15 @@ struct ioctl_trans {
17143 + };
17144 +
17145 + #define HANDLE_IOCTL(cmd,handler) \
17146 +- { (cmd), (ioctl_trans_handler_t)(handler) },
17147 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
17148 +
17149 + /* pointer to compatible structure or no argument */
17150 + #define COMPATIBLE_IOCTL(cmd) \
17151 +- { (cmd), do_ioctl32_pointer },
17152 ++ { (cmd), do_ioctl32_pointer, NULL },
17153 +
17154 + /* argument is an unsigned long integer, not a pointer */
17155 + #define ULONG_IOCTL(cmd) \
17156 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
17157 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
17158 +
17159 + /* ioctl should not be warned about even if it's not implemented.
17160 + Valid reasons to use this:
17161 +diff -urNp linux-2.6.26.6/fs/debugfs/inode.c linux-2.6.26.6/fs/debugfs/inode.c
17162 +--- linux-2.6.26.6/fs/debugfs/inode.c 2008-10-08 23:24:05.000000000 -0400
17163 ++++ linux-2.6.26.6/fs/debugfs/inode.c 2008-10-11 21:54:20.000000000 -0400
17164 +@@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
17165 +
17166 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
17167 + {
17168 +- static struct tree_descr debug_files[] = {{""}};
17169 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
17170 +
17171 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
17172 + }
17173 +diff -urNp linux-2.6.26.6/fs/exec.c linux-2.6.26.6/fs/exec.c
17174 +--- linux-2.6.26.6/fs/exec.c 2008-10-08 23:24:05.000000000 -0400
17175 ++++ linux-2.6.26.6/fs/exec.c 2008-10-11 21:55:07.000000000 -0400
17176 +@@ -51,6 +51,13 @@
17177 + #include <linux/tsacct_kern.h>
17178 + #include <linux/cn_proc.h>
17179 + #include <linux/audit.h>
17180 ++#include <linux/random.h>
17181 ++#include <linux/grsecurity.h>
17182 ++
17183 ++#ifdef CONFIG_PAX_REFCOUNT
17184 ++#include <linux/kallsyms.h>
17185 ++#include <linux/kdebug.h>
17186 ++#endif
17187 +
17188 + #include <asm/uaccess.h>
17189 + #include <asm/mmu_context.h>
17190 +@@ -65,6 +72,11 @@
17191 + #include <linux/a.out.h>
17192 + #endif
17193 +
17194 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
17195 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
17196 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
17197 ++#endif
17198 ++
17199 + int core_uses_pid;
17200 + char core_pattern[CORENAME_MAX_SIZE] = "core";
17201 + int suid_dumpable = 0;
17202 +@@ -163,18 +175,10 @@ static struct page *get_arg_page(struct
17203 + int write)
17204 + {
17205 + struct page *page;
17206 +- int ret;
17207 +
17208 +-#ifdef CONFIG_STACK_GROWSUP
17209 +- if (write) {
17210 +- ret = expand_stack_downwards(bprm->vma, pos);
17211 +- if (ret < 0)
17212 +- return NULL;
17213 +- }
17214 +-#endif
17215 +- ret = get_user_pages(current, bprm->mm, pos,
17216 +- 1, write, 1, &page, NULL);
17217 +- if (ret <= 0)
17218 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
17219 ++ return NULL;
17220 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
17221 + return NULL;
17222 +
17223 + if (write) {
17224 +@@ -247,6 +251,11 @@ static int __bprm_mm_init(struct linux_b
17225 + vma->vm_start = vma->vm_end - PAGE_SIZE;
17226 +
17227 + vma->vm_flags = VM_STACK_FLAGS;
17228 ++
17229 ++#ifdef CONFIG_PAX_SEGMEXEC
17230 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
17231 ++#endif
17232 ++
17233 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
17234 + err = insert_vm_struct(mm, vma);
17235 + if (err) {
17236 +@@ -259,6 +268,11 @@ static int __bprm_mm_init(struct linux_b
17237 +
17238 + bprm->p = vma->vm_end - sizeof(void *);
17239 +
17240 ++#ifdef CONFIG_PAX_RANDUSTACK
17241 ++ if (randomize_va_space)
17242 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
17243 ++#endif
17244 ++
17245 + return 0;
17246 +
17247 + err:
17248 +@@ -382,7 +396,7 @@ static int count(char __user * __user *
17249 + if (!p)
17250 + break;
17251 + argv++;
17252 +- if(++i > max)
17253 ++ if (++i > max)
17254 + return -E2BIG;
17255 + cond_resched();
17256 + }
17257 +@@ -522,6 +536,10 @@ static int shift_arg_pages(struct vm_are
17258 + if (vma != find_vma(mm, new_start))
17259 + return -EFAULT;
17260 +
17261 ++#ifdef CONFIG_PAX_SEGMEXEC
17262 ++ BUG_ON(pax_find_mirror_vma(vma));
17263 ++#endif
17264 ++
17265 + /*
17266 + * cover the whole range: [new_start, old_end)
17267 + */
17268 +@@ -610,6 +628,14 @@ int setup_arg_pages(struct linux_binprm
17269 + bprm->exec -= stack_shift;
17270 +
17271 + down_write(&mm->mmap_sem);
17272 ++
17273 ++ /* Move stack pages down in memory. */
17274 ++ if (stack_shift) {
17275 ++ ret = shift_arg_pages(vma, stack_shift);
17276 ++ if (ret)
17277 ++ goto out_unlock;
17278 ++ }
17279 ++
17280 + vm_flags = VM_STACK_FLAGS;
17281 +
17282 + /*
17283 +@@ -623,21 +649,24 @@ int setup_arg_pages(struct linux_binprm
17284 + vm_flags &= ~VM_EXEC;
17285 + vm_flags |= mm->def_flags;
17286 +
17287 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17288 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
17289 ++ vm_flags &= ~VM_EXEC;
17290 ++
17291 ++#ifdef CONFIG_PAX_MPROTECT
17292 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
17293 ++ vm_flags &= ~VM_MAYEXEC;
17294 ++#endif
17295 ++
17296 ++ }
17297 ++#endif
17298 ++
17299 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
17300 + vm_flags);
17301 + if (ret)
17302 + goto out_unlock;
17303 + BUG_ON(prev != vma);
17304 +
17305 +- /* Move stack pages down in memory. */
17306 +- if (stack_shift) {
17307 +- ret = shift_arg_pages(vma, stack_shift);
17308 +- if (ret) {
17309 +- up_write(&mm->mmap_sem);
17310 +- return ret;
17311 +- }
17312 +- }
17313 +-
17314 + #ifdef CONFIG_STACK_GROWSUP
17315 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
17316 + #else
17317 +@@ -649,7 +678,7 @@ int setup_arg_pages(struct linux_binprm
17318 +
17319 + out_unlock:
17320 + up_write(&mm->mmap_sem);
17321 +- return 0;
17322 ++ return ret;
17323 + }
17324 + EXPORT_SYMBOL(setup_arg_pages);
17325 +
17326 +@@ -668,7 +697,7 @@ struct file *open_exec(const char *name)
17327 + struct inode *inode = nd.path.dentry->d_inode;
17328 + file = ERR_PTR(-EACCES);
17329 + if (S_ISREG(inode->i_mode)) {
17330 +- int err = vfs_permission(&nd, MAY_EXEC);
17331 ++ err = vfs_permission(&nd, MAY_EXEC);
17332 + file = ERR_PTR(err);
17333 + if (!err) {
17334 + file = nameidata_to_filp(&nd,
17335 +@@ -1270,6 +1299,11 @@ int do_execve(char * filename,
17336 + char __user *__user *envp,
17337 + struct pt_regs * regs)
17338 + {
17339 ++#ifdef CONFIG_GRKERNSEC
17340 ++ struct file *old_exec_file;
17341 ++ struct acl_subject_label *old_acl;
17342 ++ struct rlimit old_rlim[RLIM_NLIMITS];
17343 ++#endif
17344 + struct linux_binprm *bprm;
17345 + struct file *file;
17346 + struct files_struct *displaced;
17347 +@@ -1289,6 +1323,20 @@ int do_execve(char * filename,
17348 + if (IS_ERR(file))
17349 + goto out_kfree;
17350 +
17351 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
17352 ++
17353 ++ if (gr_handle_nproc()) {
17354 ++ allow_write_access(file);
17355 ++ fput(file);
17356 ++ return -EAGAIN;
17357 ++ }
17358 ++
17359 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
17360 ++ allow_write_access(file);
17361 ++ fput(file);
17362 ++ return -EACCES;
17363 ++ }
17364 ++
17365 + sched_exec();
17366 +
17367 + bprm->file = file;
17368 +@@ -1328,8 +1376,38 @@ int do_execve(char * filename,
17369 + if (retval < 0)
17370 + goto out;
17371 +
17372 ++ if (!gr_tpe_allow(file)) {
17373 ++ retval = -EACCES;
17374 ++ goto out;
17375 ++ }
17376 ++
17377 ++ if (gr_check_crash_exec(file)) {
17378 ++ retval = -EACCES;
17379 ++ goto out;
17380 ++ }
17381 ++
17382 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
17383 ++
17384 ++ gr_handle_exec_args(bprm, argv);
17385 ++
17386 ++#ifdef CONFIG_GRKERNSEC
17387 ++ old_acl = current->acl;
17388 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
17389 ++ old_exec_file = current->exec_file;
17390 ++ get_file(file);
17391 ++ current->exec_file = file;
17392 ++#endif
17393 ++
17394 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
17395 ++ if (retval < 0)
17396 ++ goto out_fail;
17397 ++
17398 + retval = search_binary_handler(bprm,regs);
17399 + if (retval >= 0) {
17400 ++#ifdef CONFIG_GRKERNSEC
17401 ++ if (old_exec_file)
17402 ++ fput(old_exec_file);
17403 ++#endif
17404 + /* execve success */
17405 + security_bprm_free(bprm);
17406 + acct_update_integrals(current);
17407 +@@ -1339,6 +1417,14 @@ int do_execve(char * filename,
17408 + return retval;
17409 + }
17410 +
17411 ++out_fail:
17412 ++#ifdef CONFIG_GRKERNSEC
17413 ++ current->acl = old_acl;
17414 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
17415 ++ fput(current->exec_file);
17416 ++ current->exec_file = old_exec_file;
17417 ++#endif
17418 ++
17419 + out:
17420 + if (bprm->security)
17421 + security_bprm_free(bprm);
17422 +@@ -1505,6 +1591,125 @@ out:
17423 + return ispipe;
17424 + }
17425 +
17426 ++int pax_check_flags(unsigned long *flags)
17427 ++{
17428 ++ int retval = 0;
17429 ++
17430 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
17431 ++ if (*flags & MF_PAX_SEGMEXEC)
17432 ++ {
17433 ++ *flags &= ~MF_PAX_SEGMEXEC;
17434 ++ retval = -EINVAL;
17435 ++ }
17436 ++#endif
17437 ++
17438 ++ if ((*flags & MF_PAX_PAGEEXEC)
17439 ++
17440 ++#ifdef CONFIG_PAX_PAGEEXEC
17441 ++ && (*flags & MF_PAX_SEGMEXEC)
17442 ++#endif
17443 ++
17444 ++ )
17445 ++ {
17446 ++ *flags &= ~MF_PAX_PAGEEXEC;
17447 ++ retval = -EINVAL;
17448 ++ }
17449 ++
17450 ++ if ((*flags & MF_PAX_MPROTECT)
17451 ++
17452 ++#ifdef CONFIG_PAX_MPROTECT
17453 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17454 ++#endif
17455 ++
17456 ++ )
17457 ++ {
17458 ++ *flags &= ~MF_PAX_MPROTECT;
17459 ++ retval = -EINVAL;
17460 ++ }
17461 ++
17462 ++ if ((*flags & MF_PAX_EMUTRAMP)
17463 ++
17464 ++#ifdef CONFIG_PAX_EMUTRAMP
17465 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
17466 ++#endif
17467 ++
17468 ++ )
17469 ++ {
17470 ++ *flags &= ~MF_PAX_EMUTRAMP;
17471 ++ retval = -EINVAL;
17472 ++ }
17473 ++
17474 ++ return retval;
17475 ++}
17476 ++
17477 ++EXPORT_SYMBOL(pax_check_flags);
17478 ++
17479 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
17480 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
17481 ++{
17482 ++ struct task_struct *tsk = current;
17483 ++ struct mm_struct *mm = current->mm;
17484 ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
17485 ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
17486 ++ char *path_exec = NULL;
17487 ++ char *path_fault = NULL;
17488 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
17489 ++
17490 ++ if (buffer_exec && buffer_fault) {
17491 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
17492 ++
17493 ++ down_read(&mm->mmap_sem);
17494 ++ vma = mm->mmap;
17495 ++ while (vma && (!vma_exec || !vma_fault)) {
17496 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
17497 ++ vma_exec = vma;
17498 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
17499 ++ vma_fault = vma;
17500 ++ vma = vma->vm_next;
17501 ++ }
17502 ++ if (vma_exec) {
17503 ++ path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
17504 ++ if (IS_ERR(path_exec))
17505 ++ path_exec = "<path too long>";
17506 ++ }
17507 ++ if (vma_fault) {
17508 ++ start = vma_fault->vm_start;
17509 ++ end = vma_fault->vm_end;
17510 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
17511 ++ if (vma_fault->vm_file) {
17512 ++ path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
17513 ++ if (IS_ERR(path_fault))
17514 ++ path_fault = "<path too long>";
17515 ++ } else
17516 ++ path_fault = "<anonymous mapping>";
17517 ++ }
17518 ++ up_read(&mm->mmap_sem);
17519 ++ }
17520 ++ if (tsk->signal->curr_ip)
17521 ++ 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);
17522 ++ else
17523 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
17524 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
17525 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
17526 ++ tsk->uid, tsk->euid, pc, sp);
17527 ++ free_page((unsigned long)buffer_exec);
17528 ++ free_page((unsigned long)buffer_fault);
17529 ++ pax_report_insns(pc, sp);
17530 ++ do_coredump(SIGKILL, SIGKILL, regs);
17531 ++}
17532 ++#endif
17533 ++
17534 ++#ifdef CONFIG_PAX_REFCOUNT
17535 ++void pax_report_refcount_overflow(struct pt_regs *regs)
17536 ++{
17537 ++ printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
17538 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
17539 ++ print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
17540 ++ show_registers(regs);
17541 ++ force_sig_specific(SIGKILL, current);
17542 ++}
17543 ++#endif
17544 ++
17545 + static void zap_process(struct task_struct *start)
17546 + {
17547 + struct task_struct *t;
17548 +@@ -1702,6 +1907,10 @@ int do_coredump(long signr, int exit_cod
17549 + */
17550 + clear_thread_flag(TIF_SIGPENDING);
17551 +
17552 ++ if (signr == SIGKILL || signr == SIGILL)
17553 ++ gr_handle_brute_attach(current);
17554 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
17555 ++
17556 + /*
17557 + * lock_kernel() because format_corename() is controlled by sysctl, which
17558 + * uses lock_kernel()
17559 +@@ -1722,6 +1931,8 @@ int do_coredump(long signr, int exit_cod
17560 +
17561 + if (ispipe) {
17562 + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
17563 ++ if (!helper_argv)
17564 ++ goto fail_unlock;
17565 + /* Terminate the string before the first option */
17566 + delimit = strchr(corename, ' ');
17567 + if (delimit)
17568 +diff -urNp linux-2.6.26.6/fs/ext2/balloc.c linux-2.6.26.6/fs/ext2/balloc.c
17569 +--- linux-2.6.26.6/fs/ext2/balloc.c 2008-10-08 23:24:05.000000000 -0400
17570 ++++ linux-2.6.26.6/fs/ext2/balloc.c 2008-10-11 21:54:20.000000000 -0400
17571 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
17572 +
17573 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
17574 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
17575 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
17576 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
17577 + sbi->s_resuid != current->fsuid &&
17578 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
17579 + return 0;
17580 +diff -urNp linux-2.6.26.6/fs/ext3/balloc.c linux-2.6.26.6/fs/ext3/balloc.c
17581 +--- linux-2.6.26.6/fs/ext3/balloc.c 2008-10-08 23:24:05.000000000 -0400
17582 ++++ linux-2.6.26.6/fs/ext3/balloc.c 2008-10-11 21:54:20.000000000 -0400
17583 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
17584 +
17585 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
17586 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
17587 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
17588 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
17589 + sbi->s_resuid != current->fsuid &&
17590 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
17591 + return 0;
17592 +diff -urNp linux-2.6.26.6/fs/ext3/namei.c linux-2.6.26.6/fs/ext3/namei.c
17593 +--- linux-2.6.26.6/fs/ext3/namei.c 2008-10-08 23:24:05.000000000 -0400
17594 ++++ linux-2.6.26.6/fs/ext3/namei.c 2008-10-11 21:54:20.000000000 -0400
17595 +@@ -1171,9 +1171,9 @@ static struct ext3_dir_entry_2 *do_split
17596 + u32 hash2;
17597 + struct dx_map_entry *map;
17598 + char *data1 = (*bh)->b_data, *data2;
17599 +- unsigned split, move, size, i;
17600 ++ unsigned split, move, size;
17601 + struct ext3_dir_entry_2 *de = NULL, *de2;
17602 +- int err = 0;
17603 ++ int i, err = 0;
17604 +
17605 + bh2 = ext3_append (handle, dir, &newblock, &err);
17606 + if (!(bh2)) {
17607 +diff -urNp linux-2.6.26.6/fs/ext3/xattr.c linux-2.6.26.6/fs/ext3/xattr.c
17608 +--- linux-2.6.26.6/fs/ext3/xattr.c 2008-10-08 23:24:05.000000000 -0400
17609 ++++ linux-2.6.26.6/fs/ext3/xattr.c 2008-10-11 21:54:20.000000000 -0400
17610 +@@ -89,8 +89,8 @@
17611 + printk("\n"); \
17612 + } while (0)
17613 + #else
17614 +-# define ea_idebug(f...)
17615 +-# define ea_bdebug(f...)
17616 ++# define ea_idebug(f...) do {} while (0)
17617 ++# define ea_bdebug(f...) do {} while (0)
17618 + #endif
17619 +
17620 + static void ext3_xattr_cache_insert(struct buffer_head *);
17621 +diff -urNp linux-2.6.26.6/fs/ext4/balloc.c linux-2.6.26.6/fs/ext4/balloc.c
17622 +--- linux-2.6.26.6/fs/ext4/balloc.c 2008-10-08 23:24:05.000000000 -0400
17623 ++++ linux-2.6.26.6/fs/ext4/balloc.c 2008-10-11 21:54:20.000000000 -0400
17624 +@@ -1608,7 +1608,7 @@ static int ext4_has_free_blocks(struct e
17625 +
17626 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
17627 + root_blocks = ext4_r_blocks_count(sbi->s_es);
17628 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
17629 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
17630 + sbi->s_resuid != current->fsuid &&
17631 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
17632 + return 0;
17633 +diff -urNp linux-2.6.26.6/fs/ext4/namei.c linux-2.6.26.6/fs/ext4/namei.c
17634 +--- linux-2.6.26.6/fs/ext4/namei.c 2008-10-08 23:24:05.000000000 -0400
17635 ++++ linux-2.6.26.6/fs/ext4/namei.c 2008-10-11 21:54:20.000000000 -0400
17636 +@@ -1173,9 +1173,9 @@ static struct ext4_dir_entry_2 *do_split
17637 + u32 hash2;
17638 + struct dx_map_entry *map;
17639 + char *data1 = (*bh)->b_data, *data2;
17640 +- unsigned split, move, size, i;
17641 ++ unsigned split, move, size;
17642 + struct ext4_dir_entry_2 *de = NULL, *de2;
17643 +- int err = 0;
17644 ++ int i, err = 0;
17645 +
17646 + bh2 = ext4_append (handle, dir, &newblock, &err);
17647 + if (!(bh2)) {
17648 +diff -urNp linux-2.6.26.6/fs/fcntl.c linux-2.6.26.6/fs/fcntl.c
17649 +--- linux-2.6.26.6/fs/fcntl.c 2008-10-08 23:24:05.000000000 -0400
17650 ++++ linux-2.6.26.6/fs/fcntl.c 2008-10-11 21:54:20.000000000 -0400
17651 +@@ -20,6 +20,7 @@
17652 + #include <linux/signal.h>
17653 + #include <linux/rcupdate.h>
17654 + #include <linux/pid_namespace.h>
17655 ++#include <linux/grsecurity.h>
17656 +
17657 + #include <asm/poll.h>
17658 + #include <asm/siginfo.h>
17659 +@@ -67,6 +68,7 @@ static int locate_fd(unsigned int orig_s
17660 + spin_lock(&files->file_lock);
17661 +
17662 + error = -EINVAL;
17663 ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
17664 + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17665 + goto out;
17666 +
17667 +@@ -86,6 +88,7 @@ repeat:
17668 + fdt->max_fds, start);
17669 +
17670 + error = -EMFILE;
17671 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
17672 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17673 + goto out;
17674 +
17675 +@@ -133,6 +136,8 @@ asmlinkage long sys_dup2(unsigned int ol
17676 + struct files_struct * files = current->files;
17677 + struct fdtable *fdt;
17678 +
17679 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
17680 ++
17681 + spin_lock(&files->file_lock);
17682 + if (!(file = fcheck(oldfd)))
17683 + goto out_unlock;
17684 +@@ -452,7 +457,8 @@ static inline int sigio_perm(struct task
17685 + return (((fown->euid == 0) ||
17686 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
17687 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
17688 +- !security_file_send_sigiotask(p, fown, sig));
17689 ++ !security_file_send_sigiotask(p, fown, sig) &&
17690 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
17691 + }
17692 +
17693 + static void send_sigio_to_task(struct task_struct *p,
17694 +diff -urNp linux-2.6.26.6/fs/fuse/control.c linux-2.6.26.6/fs/fuse/control.c
17695 +--- linux-2.6.26.6/fs/fuse/control.c 2008-10-08 23:24:05.000000000 -0400
17696 ++++ linux-2.6.26.6/fs/fuse/control.c 2008-10-11 21:54:20.000000000 -0400
17697 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
17698 +
17699 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
17700 + {
17701 +- struct tree_descr empty_descr = {""};
17702 ++ struct tree_descr empty_descr = {"", NULL, 0};
17703 + struct fuse_conn *fc;
17704 + int err;
17705 +
17706 +diff -urNp linux-2.6.26.6/fs/fuse/dir.c linux-2.6.26.6/fs/fuse/dir.c
17707 +--- linux-2.6.26.6/fs/fuse/dir.c 2008-10-08 23:24:05.000000000 -0400
17708 ++++ linux-2.6.26.6/fs/fuse/dir.c 2008-10-11 21:54:20.000000000 -0400
17709 +@@ -1031,7 +1031,7 @@ static char *read_link(struct dentry *de
17710 + return link;
17711 + }
17712 +
17713 +-static void free_link(char *link)
17714 ++static void free_link(const char *link)
17715 + {
17716 + if (!IS_ERR(link))
17717 + free_page((unsigned long) link);
17718 +diff -urNp linux-2.6.26.6/fs/hfs/inode.c linux-2.6.26.6/fs/hfs/inode.c
17719 +--- linux-2.6.26.6/fs/hfs/inode.c 2008-10-08 23:24:05.000000000 -0400
17720 ++++ linux-2.6.26.6/fs/hfs/inode.c 2008-10-11 21:54:20.000000000 -0400
17721 +@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
17722 +
17723 + if (S_ISDIR(main_inode->i_mode)) {
17724 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
17725 +- /* panic? */;
17726 ++ {/* panic? */}
17727 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
17728 + sizeof(struct hfs_cat_dir));
17729 + if (rec.type != HFS_CDR_DIR ||
17730 +@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
17731 + sizeof(struct hfs_cat_file));
17732 + } else {
17733 + if (fd.entrylength < sizeof(struct hfs_cat_file))
17734 +- /* panic? */;
17735 ++ {/* panic? */}
17736 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
17737 + sizeof(struct hfs_cat_file));
17738 + if (rec.type != HFS_CDR_FIL ||
17739 +diff -urNp linux-2.6.26.6/fs/hfsplus/inode.c linux-2.6.26.6/fs/hfsplus/inode.c
17740 +--- linux-2.6.26.6/fs/hfsplus/inode.c 2008-10-08 23:24:05.000000000 -0400
17741 ++++ linux-2.6.26.6/fs/hfsplus/inode.c 2008-10-11 21:54:20.000000000 -0400
17742 +@@ -421,7 +421,7 @@ int hfsplus_cat_read_inode(struct inode
17743 + struct hfsplus_cat_folder *folder = &entry.folder;
17744 +
17745 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
17746 +- /* panic? */;
17747 ++ {/* panic? */}
17748 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
17749 + sizeof(struct hfsplus_cat_folder));
17750 + hfsplus_get_perms(inode, &folder->permissions, 1);
17751 +@@ -438,7 +438,7 @@ int hfsplus_cat_read_inode(struct inode
17752 + struct hfsplus_cat_file *file = &entry.file;
17753 +
17754 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
17755 +- /* panic? */;
17756 ++ {/* panic? */}
17757 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
17758 + sizeof(struct hfsplus_cat_file));
17759 +
17760 +@@ -494,7 +494,7 @@ int hfsplus_cat_write_inode(struct inode
17761 + struct hfsplus_cat_folder *folder = &entry.folder;
17762 +
17763 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
17764 +- /* panic? */;
17765 ++ {/* panic? */}
17766 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
17767 + sizeof(struct hfsplus_cat_folder));
17768 + /* simple node checks? */
17769 +@@ -516,7 +516,7 @@ int hfsplus_cat_write_inode(struct inode
17770 + struct hfsplus_cat_file *file = &entry.file;
17771 +
17772 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
17773 +- /* panic? */;
17774 ++ {/* panic? */}
17775 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
17776 + sizeof(struct hfsplus_cat_file));
17777 + hfsplus_inode_write_fork(inode, &file->data_fork);
17778 +diff -urNp linux-2.6.26.6/fs/jffs2/debug.h linux-2.6.26.6/fs/jffs2/debug.h
17779 +--- linux-2.6.26.6/fs/jffs2/debug.h 2008-10-08 23:24:05.000000000 -0400
17780 ++++ linux-2.6.26.6/fs/jffs2/debug.h 2008-10-11 21:54:20.000000000 -0400
17781 +@@ -52,13 +52,13 @@
17782 + #if CONFIG_JFFS2_FS_DEBUG > 0
17783 + #define D1(x) x
17784 + #else
17785 +-#define D1(x)
17786 ++#define D1(x) do {} while (0);
17787 + #endif
17788 +
17789 + #if CONFIG_JFFS2_FS_DEBUG > 1
17790 + #define D2(x) x
17791 + #else
17792 +-#define D2(x)
17793 ++#define D2(x) do {} while (0);
17794 + #endif
17795 +
17796 + /* The prefixes of JFFS2 messages */
17797 +@@ -114,73 +114,73 @@
17798 + #ifdef JFFS2_DBG_READINODE_MESSAGES
17799 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17800 + #else
17801 +-#define dbg_readinode(fmt, ...)
17802 ++#define dbg_readinode(fmt, ...) do {} while (0)
17803 + #endif
17804 + #ifdef JFFS2_DBG_READINODE2_MESSAGES
17805 + #define dbg_readinode2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17806 + #else
17807 +-#define dbg_readinode2(fmt, ...)
17808 ++#define dbg_readinode2(fmt, ...) do {} while (0)
17809 + #endif
17810 +
17811 + /* Fragtree build debugging messages */
17812 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
17813 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17814 + #else
17815 +-#define dbg_fragtree(fmt, ...)
17816 ++#define dbg_fragtree(fmt, ...) do {} while (0)
17817 + #endif
17818 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
17819 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17820 + #else
17821 +-#define dbg_fragtree2(fmt, ...)
17822 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
17823 + #endif
17824 +
17825 + /* Directory entry list manilulation debugging messages */
17826 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
17827 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17828 + #else
17829 +-#define dbg_dentlist(fmt, ...)
17830 ++#define dbg_dentlist(fmt, ...) do {} while (0)
17831 + #endif
17832 +
17833 + /* Print the messages about manipulating node_refs */
17834 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
17835 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17836 + #else
17837 +-#define dbg_noderef(fmt, ...)
17838 ++#define dbg_noderef(fmt, ...) do {} while (0)
17839 + #endif
17840 +
17841 + /* Manipulations with the list of inodes (JFFS2 inocache) */
17842 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
17843 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17844 + #else
17845 +-#define dbg_inocache(fmt, ...)
17846 ++#define dbg_inocache(fmt, ...) do {} while (0)
17847 + #endif
17848 +
17849 + /* Summary debugging messages */
17850 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
17851 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17852 + #else
17853 +-#define dbg_summary(fmt, ...)
17854 ++#define dbg_summary(fmt, ...) do {} while (0)
17855 + #endif
17856 +
17857 + /* File system build messages */
17858 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
17859 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17860 + #else
17861 +-#define dbg_fsbuild(fmt, ...)
17862 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
17863 + #endif
17864 +
17865 + /* Watch the object allocations */
17866 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
17867 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17868 + #else
17869 +-#define dbg_memalloc(fmt, ...)
17870 ++#define dbg_memalloc(fmt, ...) do {} while (0)
17871 + #endif
17872 +
17873 + /* Watch the XATTR subsystem */
17874 + #ifdef JFFS2_DBG_XATTR_MESSAGES
17875 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
17876 + #else
17877 +-#define dbg_xattr(fmt, ...)
17878 ++#define dbg_xattr(fmt, ...) do {} while (0)
17879 + #endif
17880 +
17881 + /* "Sanity" checks */
17882 +diff -urNp linux-2.6.26.6/fs/jffs2/erase.c linux-2.6.26.6/fs/jffs2/erase.c
17883 +--- linux-2.6.26.6/fs/jffs2/erase.c 2008-10-08 23:24:05.000000000 -0400
17884 ++++ linux-2.6.26.6/fs/jffs2/erase.c 2008-10-11 21:54:20.000000000 -0400
17885 +@@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
17886 + struct jffs2_unknown_node marker = {
17887 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
17888 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
17889 +- .totlen = cpu_to_je32(c->cleanmarker_size)
17890 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
17891 ++ .hdr_crc = cpu_to_je32(0)
17892 + };
17893 +
17894 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
17895 +diff -urNp linux-2.6.26.6/fs/jffs2/summary.h linux-2.6.26.6/fs/jffs2/summary.h
17896 +--- linux-2.6.26.6/fs/jffs2/summary.h 2008-10-08 23:24:05.000000000 -0400
17897 ++++ linux-2.6.26.6/fs/jffs2/summary.h 2008-10-11 21:54:20.000000000 -0400
17898 +@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
17899 +
17900 + #define jffs2_sum_active() (0)
17901 + #define jffs2_sum_init(a) (0)
17902 +-#define jffs2_sum_exit(a)
17903 +-#define jffs2_sum_disable_collecting(a)
17904 ++#define jffs2_sum_exit(a) do {} while (0)
17905 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
17906 + #define jffs2_sum_is_disabled(a) (0)
17907 +-#define jffs2_sum_reset_collected(a)
17908 ++#define jffs2_sum_reset_collected(a) do {} while (0)
17909 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
17910 +-#define jffs2_sum_move_collected(a,b)
17911 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
17912 + #define jffs2_sum_write_sumnode(a) (0)
17913 +-#define jffs2_sum_add_padding_mem(a,b)
17914 +-#define jffs2_sum_add_inode_mem(a,b,c)
17915 +-#define jffs2_sum_add_dirent_mem(a,b,c)
17916 +-#define jffs2_sum_add_xattr_mem(a,b,c)
17917 +-#define jffs2_sum_add_xref_mem(a,b,c)
17918 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
17919 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
17920 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
17921 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
17922 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
17923 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
17924 +
17925 + #endif /* CONFIG_JFFS2_SUMMARY */
17926 +diff -urNp linux-2.6.26.6/fs/jffs2/wbuf.c linux-2.6.26.6/fs/jffs2/wbuf.c
17927 +--- linux-2.6.26.6/fs/jffs2/wbuf.c 2008-10-08 23:24:05.000000000 -0400
17928 ++++ linux-2.6.26.6/fs/jffs2/wbuf.c 2008-10-11 21:54:20.000000000 -0400
17929 +@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
17930 + {
17931 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
17932 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
17933 +- .totlen = constant_cpu_to_je32(8)
17934 ++ .totlen = constant_cpu_to_je32(8),
17935 ++ .hdr_crc = constant_cpu_to_je32(0)
17936 + };
17937 +
17938 + /*
17939 +diff -urNp linux-2.6.26.6/fs/Kconfig linux-2.6.26.6/fs/Kconfig
17940 +--- linux-2.6.26.6/fs/Kconfig 2008-10-08 23:24:05.000000000 -0400
17941 ++++ linux-2.6.26.6/fs/Kconfig 2008-10-11 21:54:20.000000000 -0400
17942 +@@ -926,12 +926,12 @@ config PROC_FS
17943 +
17944 + config PROC_KCORE
17945 + bool "/proc/kcore support" if !ARM
17946 +- depends on PROC_FS && MMU
17947 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
17948 +
17949 + config PROC_VMCORE
17950 + bool "/proc/vmcore support (EXPERIMENTAL)"
17951 +- depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP
17952 +- default y
17953 ++ depends on PROC_FS && EXPERIMENTAL && CRASH_DUMP && !GRKERNSEC
17954 ++ default n
17955 + help
17956 + Exports the dump image of crashed kernel in ELF format.
17957 +
17958 +diff -urNp linux-2.6.26.6/fs/locks.c linux-2.6.26.6/fs/locks.c
17959 +--- linux-2.6.26.6/fs/locks.c 2008-10-08 23:24:05.000000000 -0400
17960 ++++ linux-2.6.26.6/fs/locks.c 2008-10-11 21:55:52.000000000 -0400
17961 +@@ -2019,16 +2019,16 @@ void locks_remove_flock(struct file *fil
17962 + return;
17963 +
17964 + if (filp->f_op && filp->f_op->flock) {
17965 +- struct file_lock fl = {
17966 ++ struct file_lock flock = {
17967 + .fl_pid = current->tgid,
17968 + .fl_file = filp,
17969 + .fl_flags = FL_FLOCK,
17970 + .fl_type = F_UNLCK,
17971 + .fl_end = OFFSET_MAX,
17972 + };
17973 +- filp->f_op->flock(filp, F_SETLKW, &fl);
17974 +- if (fl.fl_ops && fl.fl_ops->fl_release_private)
17975 +- fl.fl_ops->fl_release_private(&fl);
17976 ++ filp->f_op->flock(filp, F_SETLKW, &flock);
17977 ++ if (flock.fl_ops && flock.fl_ops->fl_release_private)
17978 ++ flock.fl_ops->fl_release_private(&flock);
17979 + }
17980 +
17981 + lock_kernel();
17982 +diff -urNp linux-2.6.26.6/fs/namei.c linux-2.6.26.6/fs/namei.c
17983 +--- linux-2.6.26.6/fs/namei.c 2008-10-08 23:24:05.000000000 -0400
17984 ++++ linux-2.6.26.6/fs/namei.c 2008-10-11 21:54:20.000000000 -0400
17985 +@@ -31,6 +31,7 @@
17986 + #include <linux/file.h>
17987 + #include <linux/fcntl.h>
17988 + #include <linux/device_cgroup.h>
17989 ++#include <linux/grsecurity.h>
17990 + #include <asm/namei.h>
17991 + #include <asm/uaccess.h>
17992 +
17993 +@@ -673,7 +674,7 @@ static __always_inline int __do_follow_l
17994 + cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
17995 + error = PTR_ERR(cookie);
17996 + if (!IS_ERR(cookie)) {
17997 +- char *s = nd_get_link(nd);
17998 ++ const char *s = nd_get_link(nd);
17999 + error = 0;
18000 + if (s)
18001 + error = __vfs_follow_link(nd, s);
18002 +@@ -704,6 +705,13 @@ static inline int do_follow_link(struct
18003 + err = security_inode_follow_link(path->dentry, nd);
18004 + if (err)
18005 + goto loop;
18006 ++
18007 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
18008 ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
18009 ++ err = -EACCES;
18010 ++ goto loop;
18011 ++ }
18012 ++
18013 + current->link_count++;
18014 + current->total_link_count++;
18015 + nd->depth++;
18016 +@@ -1052,11 +1060,18 @@ return_reval:
18017 + break;
18018 + }
18019 + return_base:
18020 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
18021 ++ path_put(&nd->path);
18022 ++ return -ENOENT;
18023 ++ }
18024 + return 0;
18025 + out_dput:
18026 + path_put_conditional(&next, nd);
18027 + break;
18028 + }
18029 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
18030 ++ err = -ENOENT;
18031 ++
18032 + path_put(&nd->path);
18033 + return_err:
18034 + return err;
18035 +@@ -1706,9 +1721,17 @@ static int __open_namei_create(struct na
18036 + int error;
18037 + struct dentry *dir = nd->path.dentry;
18038 +
18039 ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
18040 ++ error = -EACCES;
18041 ++ goto out_unlock_dput;
18042 ++ }
18043 ++
18044 + if (!IS_POSIXACL(dir->d_inode))
18045 + mode &= ~current->fs->umask;
18046 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
18047 ++ if (!error)
18048 ++ gr_handle_create(path->dentry, nd->path.mnt);
18049 ++out_unlock_dput:
18050 + mutex_unlock(&dir->d_inode->i_mutex);
18051 + dput(nd->path.dentry);
18052 + nd->path.dentry = path->dentry;
18053 +@@ -1789,6 +1812,17 @@ struct file *do_filp_open(int dfd, const
18054 + &nd, flag);
18055 + if (error)
18056 + return ERR_PTR(error);
18057 ++
18058 ++ if (gr_handle_rawio(nd.path.dentry->d_inode)) {
18059 ++ error = -EPERM;
18060 ++ goto exit;
18061 ++ }
18062 ++
18063 ++ if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
18064 ++ error = -EACCES;
18065 ++ goto exit;
18066 ++ }
18067 ++
18068 + goto ok;
18069 + }
18070 +
18071 +@@ -1852,6 +1886,20 @@ do_last:
18072 + /*
18073 + * It already exists.
18074 + */
18075 ++
18076 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
18077 ++ error = -EPERM;
18078 ++ goto exit_mutex_unlock;
18079 ++ }
18080 ++ if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
18081 ++ error = -EACCES;
18082 ++ goto exit_mutex_unlock;
18083 ++ }
18084 ++ if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
18085 ++ error = -EACCES;
18086 ++ goto exit_mutex_unlock;
18087 ++ }
18088 ++
18089 + mutex_unlock(&dir->d_inode->i_mutex);
18090 + audit_inode(pathname, path.dentry);
18091 +
18092 +@@ -1936,6 +1984,13 @@ do_link:
18093 + error = security_inode_follow_link(path.dentry, &nd);
18094 + if (error)
18095 + goto exit_dput;
18096 ++
18097 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
18098 ++ path.dentry, nd.path.mnt)) {
18099 ++ error = -EACCES;
18100 ++ goto exit_dput;
18101 ++ }
18102 ++
18103 + error = __do_follow_link(&path, &nd);
18104 + if (error) {
18105 + /* Does someone understand code flow here? Or it is only
18106 +@@ -2110,9 +2165,21 @@ asmlinkage long sys_mknodat(int dfd, con
18107 + error = may_mknod(mode);
18108 + if (error)
18109 + goto out_dput;
18110 ++
18111 ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
18112 ++ error = -EPERM;
18113 ++ goto out_dput;
18114 ++ }
18115 ++
18116 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
18117 ++ error = -EACCES;
18118 ++ goto out_dput;
18119 ++ }
18120 ++
18121 + error = mnt_want_write(nd.path.mnt);
18122 + if (error)
18123 + goto out_dput;
18124 ++
18125 + switch (mode & S_IFMT) {
18126 + case 0: case S_IFREG:
18127 + error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
18128 +@@ -2126,6 +2193,9 @@ asmlinkage long sys_mknodat(int dfd, con
18129 + break;
18130 + }
18131 + mnt_drop_write(nd.path.mnt);
18132 ++
18133 ++ if (!error)
18134 ++ gr_handle_create(dentry, nd.path.mnt);
18135 + out_dput:
18136 + dput(dentry);
18137 + out_unlock:
18138 +@@ -2184,6 +2254,11 @@ asmlinkage long sys_mkdirat(int dfd, con
18139 + if (IS_ERR(dentry))
18140 + goto out_unlock;
18141 +
18142 ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
18143 ++ error = -EACCES;
18144 ++ goto out_dput;
18145 ++ }
18146 ++
18147 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
18148 + mode &= ~current->fs->umask;
18149 + error = mnt_want_write(nd.path.mnt);
18150 +@@ -2191,6 +2266,10 @@ asmlinkage long sys_mkdirat(int dfd, con
18151 + goto out_dput;
18152 + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
18153 + mnt_drop_write(nd.path.mnt);
18154 ++
18155 ++ if (!error)
18156 ++ gr_handle_create(dentry, nd.path.mnt);
18157 ++
18158 + out_dput:
18159 + dput(dentry);
18160 + out_unlock:
18161 +@@ -2273,6 +2352,8 @@ static long do_rmdir(int dfd, const char
18162 + char * name;
18163 + struct dentry *dentry;
18164 + struct nameidata nd;
18165 ++ ino_t saved_ino = 0;
18166 ++ dev_t saved_dev = 0;
18167 +
18168 + name = getname(pathname);
18169 + if(IS_ERR(name))
18170 +@@ -2298,11 +2379,26 @@ static long do_rmdir(int dfd, const char
18171 + error = PTR_ERR(dentry);
18172 + if (IS_ERR(dentry))
18173 + goto exit2;
18174 ++
18175 ++ if (dentry->d_inode != NULL) {
18176 ++ if (dentry->d_inode->i_nlink <= 1) {
18177 ++ saved_ino = dentry->d_inode->i_ino;
18178 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
18179 ++ }
18180 ++
18181 ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
18182 ++ error = -EACCES;
18183 ++ goto exit3;
18184 ++ }
18185 ++ }
18186 ++
18187 + error = mnt_want_write(nd.path.mnt);
18188 + if (error)
18189 + goto exit3;
18190 + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
18191 + mnt_drop_write(nd.path.mnt);
18192 ++ if (!error && (saved_dev || saved_ino))
18193 ++ gr_handle_delete(saved_ino, saved_dev);
18194 + exit3:
18195 + dput(dentry);
18196 + exit2:
18197 +@@ -2363,6 +2459,8 @@ static long do_unlinkat(int dfd, const c
18198 + struct dentry *dentry;
18199 + struct nameidata nd;
18200 + struct inode *inode = NULL;
18201 ++ ino_t saved_ino = 0;
18202 ++ dev_t saved_dev = 0;
18203 +
18204 + name = getname(pathname);
18205 + if(IS_ERR(name))
18206 +@@ -2382,12 +2480,25 @@ static long do_unlinkat(int dfd, const c
18207 + if (nd.last.name[nd.last.len])
18208 + goto slashes;
18209 + inode = dentry->d_inode;
18210 +- if (inode)
18211 ++ if (inode) {
18212 ++ if (inode->i_nlink <= 1) {
18213 ++ saved_ino = inode->i_ino;
18214 ++ saved_dev = inode->i_sb->s_dev;
18215 ++ }
18216 ++
18217 + atomic_inc(&inode->i_count);
18218 ++
18219 ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
18220 ++ error = -EACCES;
18221 ++ goto exit2;
18222 ++ }
18223 ++ }
18224 + error = mnt_want_write(nd.path.mnt);
18225 + if (error)
18226 + goto exit2;
18227 + error = vfs_unlink(nd.path.dentry->d_inode, dentry);
18228 ++ if (!error && (saved_ino || saved_dev))
18229 ++ gr_handle_delete(saved_ino, saved_dev);
18230 + mnt_drop_write(nd.path.mnt);
18231 + exit2:
18232 + dput(dentry);
18233 +@@ -2469,10 +2580,18 @@ asmlinkage long sys_symlinkat(const char
18234 + if (IS_ERR(dentry))
18235 + goto out_unlock;
18236 +
18237 ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
18238 ++ error = -EACCES;
18239 ++ goto out_dput;
18240 ++ }
18241 ++
18242 + error = mnt_want_write(nd.path.mnt);
18243 + if (error)
18244 + goto out_dput;
18245 ++
18246 + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
18247 ++ if (!error)
18248 ++ gr_handle_create(dentry, nd.path.mnt);
18249 + mnt_drop_write(nd.path.mnt);
18250 + out_dput:
18251 + dput(dentry);
18252 +@@ -2569,10 +2688,26 @@ asmlinkage long sys_linkat(int olddfd, c
18253 + error = PTR_ERR(new_dentry);
18254 + if (IS_ERR(new_dentry))
18255 + goto out_unlock;
18256 ++
18257 ++ if (gr_handle_hardlink(old_nd.path.dentry, old_nd.path.mnt,
18258 ++ old_nd.path.dentry->d_inode,
18259 ++ old_nd.path.dentry->d_inode->i_mode, to)) {
18260 ++ error = -EACCES;
18261 ++ goto out_dput;
18262 ++ }
18263 ++
18264 ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
18265 ++ old_nd.path.dentry, old_nd.path.mnt, to)) {
18266 ++ error = -EACCES;
18267 ++ goto out_dput;
18268 ++ }
18269 ++
18270 + error = mnt_want_write(nd.path.mnt);
18271 + if (error)
18272 + goto out_dput;
18273 + error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
18274 ++ if (!error)
18275 ++ gr_handle_create(new_dentry, nd.path.mnt);
18276 + mnt_drop_write(nd.path.mnt);
18277 + out_dput:
18278 + dput(new_dentry);
18279 +@@ -2729,8 +2864,10 @@ int vfs_rename(struct inode *old_dir, st
18280 + error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
18281 + else
18282 + error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
18283 ++
18284 + if (!error) {
18285 + const char *new_name = old_dentry->d_name.name;
18286 ++
18287 + fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
18288 + new_dentry->d_inode, old_dentry);
18289 + }
18290 +@@ -2800,11 +2937,21 @@ static int do_rename(int olddfd, const c
18291 + if (new_dentry == trap)
18292 + goto exit5;
18293 +
18294 ++ error = gr_acl_handle_rename(new_dentry, newnd.path.dentry, newnd.path.mnt,
18295 ++ old_dentry, old_dir->d_inode, oldnd.path.mnt,
18296 ++ newname);
18297 ++ if (error)
18298 ++ goto exit5;
18299 ++
18300 + error = mnt_want_write(oldnd.path.mnt);
18301 + if (error)
18302 + goto exit5;
18303 + error = vfs_rename(old_dir->d_inode, old_dentry,
18304 + new_dir->d_inode, new_dentry);
18305 ++ if (!error)
18306 ++ gr_handle_rename(old_dir->d_inode, newnd.path.dentry->d_inode, old_dentry,
18307 ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
18308 ++
18309 + mnt_drop_write(oldnd.path.mnt);
18310 + exit5:
18311 + dput(new_dentry);
18312 +diff -urNp linux-2.6.26.6/fs/namespace.c linux-2.6.26.6/fs/namespace.c
18313 +--- linux-2.6.26.6/fs/namespace.c 2008-10-08 23:24:05.000000000 -0400
18314 ++++ linux-2.6.26.6/fs/namespace.c 2008-10-11 21:54:20.000000000 -0400
18315 +@@ -27,6 +27,7 @@
18316 + #include <linux/ramfs.h>
18317 + #include <linux/log2.h>
18318 + #include <linux/idr.h>
18319 ++#include <linux/grsecurity.h>
18320 + #include <asm/uaccess.h>
18321 + #include <asm/unistd.h>
18322 + #include "pnode.h"
18323 +@@ -1085,6 +1086,8 @@ static int do_umount(struct vfsmount *mn
18324 + lock_kernel();
18325 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
18326 + unlock_kernel();
18327 ++
18328 ++ gr_log_remount(mnt->mnt_devname, retval);
18329 + }
18330 + up_write(&sb->s_umount);
18331 + return retval;
18332 +@@ -1108,6 +1111,9 @@ static int do_umount(struct vfsmount *mn
18333 + security_sb_umount_busy(mnt);
18334 + up_write(&namespace_sem);
18335 + release_mounts(&umount_list);
18336 ++
18337 ++ gr_log_unmount(mnt->mnt_devname, retval);
18338 ++
18339 + return retval;
18340 + }
18341 +
18342 +@@ -1940,6 +1946,11 @@ long do_mount(char *dev_name, char *dir_
18343 + if (retval)
18344 + goto dput_out;
18345 +
18346 ++ if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
18347 ++ retval = -EPERM;
18348 ++ goto dput_out;
18349 ++ }
18350 ++
18351 + if (flags & MS_REMOUNT)
18352 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
18353 + data_page);
18354 +@@ -1954,6 +1965,9 @@ long do_mount(char *dev_name, char *dir_
18355 + dev_name, data_page);
18356 + dput_out:
18357 + path_put(&nd.path);
18358 ++
18359 ++ gr_log_mount(dev_name, dir_name, retval);
18360 ++
18361 + return retval;
18362 + }
18363 +
18364 +@@ -2072,6 +2086,9 @@ asmlinkage long sys_mount(char __user *
18365 + if (retval < 0)
18366 + goto out3;
18367 +
18368 ++ if (gr_handle_chroot_pivot())
18369 ++ return -EPERM;
18370 ++
18371 + lock_kernel();
18372 + retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
18373 + flags, (void *)data_page);
18374 +diff -urNp linux-2.6.26.6/fs/nfs/nfs4proc.c linux-2.6.26.6/fs/nfs/nfs4proc.c
18375 +--- linux-2.6.26.6/fs/nfs/nfs4proc.c 2008-10-08 23:24:05.000000000 -0400
18376 ++++ linux-2.6.26.6/fs/nfs/nfs4proc.c 2008-10-11 21:54:20.000000000 -0400
18377 +@@ -655,7 +655,7 @@ static int _nfs4_do_open_reclaim(struct
18378 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
18379 + {
18380 + struct nfs_server *server = NFS_SERVER(state->inode);
18381 +- struct nfs4_exception exception = { };
18382 ++ struct nfs4_exception exception = {0, 0};
18383 + int err;
18384 + do {
18385 + err = _nfs4_do_open_reclaim(ctx, state);
18386 +@@ -697,7 +697,7 @@ static int _nfs4_open_delegation_recall(
18387 +
18388 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
18389 + {
18390 +- struct nfs4_exception exception = { };
18391 ++ struct nfs4_exception exception = {0, 0};
18392 + struct nfs_server *server = NFS_SERVER(state->inode);
18393 + int err;
18394 + do {
18395 +@@ -990,7 +990,7 @@ static int _nfs4_open_expired(struct nfs
18396 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
18397 + {
18398 + struct nfs_server *server = NFS_SERVER(state->inode);
18399 +- struct nfs4_exception exception = { };
18400 ++ struct nfs4_exception exception = {0, 0};
18401 + int err;
18402 +
18403 + do {
18404 +@@ -1092,7 +1092,7 @@ out_err:
18405 +
18406 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
18407 + {
18408 +- struct nfs4_exception exception = { };
18409 ++ struct nfs4_exception exception = {0, 0};
18410 + struct nfs4_state *res;
18411 + int status;
18412 +
18413 +@@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode
18414 + struct iattr *sattr, struct nfs4_state *state)
18415 + {
18416 + struct nfs_server *server = NFS_SERVER(inode);
18417 +- struct nfs4_exception exception = { };
18418 ++ struct nfs4_exception exception = {0, 0};
18419 + int err;
18420 + do {
18421 + err = nfs4_handle_exception(server,
18422 +@@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
18423 +
18424 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
18425 + {
18426 +- struct nfs4_exception exception = { };
18427 ++ struct nfs4_exception exception = {0, 0};
18428 + int err;
18429 + do {
18430 + err = nfs4_handle_exception(server,
18431 +@@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
18432 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
18433 + struct nfs_fsinfo *info)
18434 + {
18435 +- struct nfs4_exception exception = { };
18436 ++ struct nfs4_exception exception = {0, 0};
18437 + int err;
18438 + do {
18439 + err = nfs4_handle_exception(server,
18440 +@@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
18441 +
18442 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18443 + {
18444 +- struct nfs4_exception exception = { };
18445 ++ struct nfs4_exception exception = {0, 0};
18446 + int err;
18447 + do {
18448 + err = nfs4_handle_exception(server,
18449 +@@ -1706,7 +1706,7 @@ static int nfs4_proc_lookupfh(struct nfs
18450 + struct qstr *name, struct nfs_fh *fhandle,
18451 + struct nfs_fattr *fattr)
18452 + {
18453 +- struct nfs4_exception exception = { };
18454 ++ struct nfs4_exception exception = {0, 0};
18455 + int err;
18456 + do {
18457 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
18458 +@@ -1735,7 +1735,7 @@ static int _nfs4_proc_lookup(struct inod
18459 +
18460 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
18461 + {
18462 +- struct nfs4_exception exception = { };
18463 ++ struct nfs4_exception exception = {0, 0};
18464 + int err;
18465 + do {
18466 + err = nfs4_handle_exception(NFS_SERVER(dir),
18467 +@@ -1799,7 +1799,7 @@ static int _nfs4_proc_access(struct inod
18468 +
18469 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
18470 + {
18471 +- struct nfs4_exception exception = { };
18472 ++ struct nfs4_exception exception = {0, 0};
18473 + int err;
18474 + do {
18475 + err = nfs4_handle_exception(NFS_SERVER(inode),
18476 +@@ -1854,7 +1854,7 @@ static int _nfs4_proc_readlink(struct in
18477 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
18478 + unsigned int pgbase, unsigned int pglen)
18479 + {
18480 +- struct nfs4_exception exception = { };
18481 ++ struct nfs4_exception exception = {0, 0};
18482 + int err;
18483 + do {
18484 + err = nfs4_handle_exception(NFS_SERVER(inode),
18485 +@@ -1950,7 +1950,7 @@ static int _nfs4_proc_remove(struct inod
18486 +
18487 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
18488 + {
18489 +- struct nfs4_exception exception = { };
18490 ++ struct nfs4_exception exception = {0, 0};
18491 + int err;
18492 + do {
18493 + err = nfs4_handle_exception(NFS_SERVER(dir),
18494 +@@ -2022,7 +2022,7 @@ static int _nfs4_proc_rename(struct inod
18495 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
18496 + struct inode *new_dir, struct qstr *new_name)
18497 + {
18498 +- struct nfs4_exception exception = { };
18499 ++ struct nfs4_exception exception = {0, 0};
18500 + int err;
18501 + do {
18502 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
18503 +@@ -2069,7 +2069,7 @@ static int _nfs4_proc_link(struct inode
18504 +
18505 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
18506 + {
18507 +- struct nfs4_exception exception = { };
18508 ++ struct nfs4_exception exception = {0, 0};
18509 + int err;
18510 + do {
18511 + err = nfs4_handle_exception(NFS_SERVER(inode),
18512 +@@ -2126,7 +2126,7 @@ static int _nfs4_proc_symlink(struct ino
18513 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
18514 + struct page *page, unsigned int len, struct iattr *sattr)
18515 + {
18516 +- struct nfs4_exception exception = { };
18517 ++ struct nfs4_exception exception = {0, 0};
18518 + int err;
18519 + do {
18520 + err = nfs4_handle_exception(NFS_SERVER(dir),
18521 +@@ -2179,7 +2179,7 @@ static int _nfs4_proc_mkdir(struct inode
18522 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
18523 + struct iattr *sattr)
18524 + {
18525 +- struct nfs4_exception exception = { };
18526 ++ struct nfs4_exception exception = {0, 0};
18527 + int err;
18528 + do {
18529 + err = nfs4_handle_exception(NFS_SERVER(dir),
18530 +@@ -2228,7 +2228,7 @@ static int _nfs4_proc_readdir(struct den
18531 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
18532 + u64 cookie, struct page *page, unsigned int count, int plus)
18533 + {
18534 +- struct nfs4_exception exception = { };
18535 ++ struct nfs4_exception exception = {0, 0};
18536 + int err;
18537 + do {
18538 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
18539 +@@ -2298,7 +2298,7 @@ static int _nfs4_proc_mknod(struct inode
18540 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
18541 + struct iattr *sattr, dev_t rdev)
18542 + {
18543 +- struct nfs4_exception exception = { };
18544 ++ struct nfs4_exception exception = {0, 0};
18545 + int err;
18546 + do {
18547 + err = nfs4_handle_exception(NFS_SERVER(dir),
18548 +@@ -2327,7 +2327,7 @@ static int _nfs4_proc_statfs(struct nfs_
18549 +
18550 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
18551 + {
18552 +- struct nfs4_exception exception = { };
18553 ++ struct nfs4_exception exception = {0, 0};
18554 + int err;
18555 + do {
18556 + err = nfs4_handle_exception(server,
18557 +@@ -2355,7 +2355,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
18558 +
18559 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
18560 + {
18561 +- struct nfs4_exception exception = { };
18562 ++ struct nfs4_exception exception = {0, 0};
18563 + int err;
18564 +
18565 + do {
18566 +@@ -2398,7 +2398,7 @@ static int _nfs4_proc_pathconf(struct nf
18567 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
18568 + struct nfs_pathconf *pathconf)
18569 + {
18570 +- struct nfs4_exception exception = { };
18571 ++ struct nfs4_exception exception = {0, 0};
18572 + int err;
18573 +
18574 + do {
18575 +@@ -2685,7 +2685,7 @@ out_free:
18576 +
18577 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
18578 + {
18579 +- struct nfs4_exception exception = { };
18580 ++ struct nfs4_exception exception = {0, 0};
18581 + ssize_t ret;
18582 + do {
18583 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
18584 +@@ -2742,7 +2742,7 @@ static int __nfs4_proc_set_acl(struct in
18585 +
18586 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
18587 + {
18588 +- struct nfs4_exception exception = { };
18589 ++ struct nfs4_exception exception = {0, 0};
18590 + int err;
18591 + do {
18592 + err = nfs4_handle_exception(NFS_SERVER(inode),
18593 +@@ -3034,7 +3034,7 @@ out:
18594 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
18595 + {
18596 + struct nfs_server *server = NFS_SERVER(inode);
18597 +- struct nfs4_exception exception = { };
18598 ++ struct nfs4_exception exception = {0, 0};
18599 + int err;
18600 + do {
18601 + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
18602 +@@ -3109,7 +3109,7 @@ out:
18603 +
18604 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
18605 + {
18606 +- struct nfs4_exception exception = { };
18607 ++ struct nfs4_exception exception = {0, 0};
18608 + int err;
18609 +
18610 + do {
18611 +@@ -3459,7 +3459,7 @@ static int _nfs4_do_setlk(struct nfs4_st
18612 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
18613 + {
18614 + struct nfs_server *server = NFS_SERVER(state->inode);
18615 +- struct nfs4_exception exception = { };
18616 ++ struct nfs4_exception exception = {0, 0};
18617 + int err;
18618 +
18619 + do {
18620 +@@ -3477,7 +3477,7 @@ static int nfs4_lock_reclaim(struct nfs4
18621 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
18622 + {
18623 + struct nfs_server *server = NFS_SERVER(state->inode);
18624 +- struct nfs4_exception exception = { };
18625 ++ struct nfs4_exception exception = {0, 0};
18626 + int err;
18627 +
18628 + err = nfs4_set_lock_state(state, request);
18629 +@@ -3538,7 +3538,7 @@ out:
18630 +
18631 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
18632 + {
18633 +- struct nfs4_exception exception = { };
18634 ++ struct nfs4_exception exception = {0, 0};
18635 + int err;
18636 +
18637 + do {
18638 +@@ -3588,7 +3588,7 @@ nfs4_proc_lock(struct file *filp, int cm
18639 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
18640 + {
18641 + struct nfs_server *server = NFS_SERVER(state->inode);
18642 +- struct nfs4_exception exception = { };
18643 ++ struct nfs4_exception exception = {0, 0};
18644 + int err;
18645 +
18646 + err = nfs4_set_lock_state(state, fl);
18647 +diff -urNp linux-2.6.26.6/fs/nfsd/export.c linux-2.6.26.6/fs/nfsd/export.c
18648 +--- linux-2.6.26.6/fs/nfsd/export.c 2008-10-08 23:24:05.000000000 -0400
18649 ++++ linux-2.6.26.6/fs/nfsd/export.c 2008-10-11 21:54:20.000000000 -0400
18650 +@@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
18651 + * probably discover the problem when someone fails to
18652 + * authenticate.
18653 + */
18654 +- if (f->pseudoflavor < 0)
18655 ++ if ((s32)f->pseudoflavor < 0)
18656 + return -EINVAL;
18657 + err = get_int(mesg, &f->flags);
18658 + if (err)
18659 +diff -urNp linux-2.6.26.6/fs/nls/nls_base.c linux-2.6.26.6/fs/nls/nls_base.c
18660 +--- linux-2.6.26.6/fs/nls/nls_base.c 2008-10-08 23:24:05.000000000 -0400
18661 ++++ linux-2.6.26.6/fs/nls/nls_base.c 2008-10-11 21:54:20.000000000 -0400
18662 +@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
18663 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
18664 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
18665 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
18666 +- {0, /* end of table */}
18667 ++ {0, 0, 0, 0, 0, /* end of table */}
18668 + };
18669 +
18670 + int
18671 +diff -urNp linux-2.6.26.6/fs/ntfs/file.c linux-2.6.26.6/fs/ntfs/file.c
18672 +--- linux-2.6.26.6/fs/ntfs/file.c 2008-10-08 23:24:05.000000000 -0400
18673 ++++ linux-2.6.26.6/fs/ntfs/file.c 2008-10-11 21:54:20.000000000 -0400
18674 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
18675 + #endif /* NTFS_RW */
18676 + };
18677 +
18678 +-const struct file_operations ntfs_empty_file_ops = {};
18679 ++const struct file_operations ntfs_empty_file_ops;
18680 +
18681 +-const struct inode_operations ntfs_empty_inode_ops = {};
18682 ++const struct inode_operations ntfs_empty_inode_ops;
18683 +diff -urNp linux-2.6.26.6/fs/open.c linux-2.6.26.6/fs/open.c
18684 +--- linux-2.6.26.6/fs/open.c 2008-10-08 23:24:05.000000000 -0400
18685 ++++ linux-2.6.26.6/fs/open.c 2008-10-11 21:54:20.000000000 -0400
18686 +@@ -29,6 +29,7 @@
18687 + #include <linux/rcupdate.h>
18688 + #include <linux/audit.h>
18689 + #include <linux/falloc.h>
18690 ++#include <linux/grsecurity.h>
18691 +
18692 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
18693 + {
18694 +@@ -206,6 +207,9 @@ int do_truncate(struct dentry *dentry, l
18695 + if (length < 0)
18696 + return -EINVAL;
18697 +
18698 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
18699 ++ return -EACCES;
18700 ++
18701 + newattrs.ia_size = length;
18702 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
18703 + if (filp) {
18704 +@@ -478,6 +482,9 @@ asmlinkage long sys_faccessat(int dfd, c
18705 + if (__mnt_is_readonly(nd.path.mnt))
18706 + res = -EROFS;
18707 +
18708 ++ if (!res && !gr_acl_handle_access(nd.path.dentry, nd.path.mnt, mode))
18709 ++ res = -EACCES;
18710 ++
18711 + out_path_release:
18712 + path_put(&nd.path);
18713 + out:
18714 +@@ -509,6 +516,8 @@ asmlinkage long sys_chdir(const char __u
18715 + if (error)
18716 + goto dput_and_out;
18717 +
18718 ++ gr_log_chdir(nd.path.dentry, nd.path.mnt);
18719 ++
18720 + set_fs_pwd(current->fs, &nd.path);
18721 +
18722 + dput_and_out:
18723 +@@ -535,6 +544,13 @@ asmlinkage long sys_fchdir(unsigned int
18724 + goto out_putf;
18725 +
18726 + error = file_permission(file, MAY_EXEC);
18727 ++
18728 ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
18729 ++ error = -EPERM;
18730 ++
18731 ++ if (!error)
18732 ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
18733 ++
18734 + if (!error)
18735 + set_fs_pwd(current->fs, &file->f_path);
18736 + out_putf:
18737 +@@ -560,8 +576,16 @@ asmlinkage long sys_chroot(const char __
18738 + if (!capable(CAP_SYS_CHROOT))
18739 + goto dput_and_out;
18740 +
18741 ++ if (gr_handle_chroot_chroot(nd.path.dentry, nd.path.mnt))
18742 ++ goto dput_and_out;
18743 ++
18744 + set_fs_root(current->fs, &nd.path);
18745 + set_fs_altroot();
18746 ++
18747 ++ gr_handle_chroot_caps(current);
18748 ++
18749 ++ gr_handle_chroot_chdir(&nd.path);
18750 ++
18751 + error = 0;
18752 + dput_and_out:
18753 + path_put(&nd.path);
18754 +@@ -592,9 +616,22 @@ asmlinkage long sys_fchmod(unsigned int
18755 + err = -EPERM;
18756 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
18757 + goto out_drop_write;
18758 ++
18759 ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
18760 ++ err = -EACCES;
18761 ++ goto out_drop_write;
18762 ++ }
18763 ++
18764 + mutex_lock(&inode->i_mutex);
18765 + if (mode == (mode_t) -1)
18766 + mode = inode->i_mode;
18767 ++
18768 ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
18769 ++ err = -EPERM;
18770 ++ mutex_unlock(&inode->i_mutex);
18771 ++ goto out_drop_write;
18772 ++ }
18773 ++
18774 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
18775 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
18776 + err = notify_change(dentry, &newattrs);
18777 +@@ -629,9 +666,21 @@ asmlinkage long sys_fchmodat(int dfd, co
18778 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
18779 + goto out_drop_write;
18780 +
18781 ++ if (!gr_acl_handle_chmod(nd.path.dentry, nd.path.mnt, mode)) {
18782 ++ error = -EACCES;
18783 ++ goto out_drop_write;
18784 ++ }
18785 ++
18786 + mutex_lock(&inode->i_mutex);
18787 + if (mode == (mode_t) -1)
18788 + mode = inode->i_mode;
18789 ++
18790 ++ if (gr_handle_chroot_chmod(nd.path.dentry, nd.path.mnt, mode)) {
18791 ++ error = -EACCES;
18792 ++ mutex_unlock(&inode->i_mutex);
18793 ++ goto dput_and_out;
18794 ++ }
18795 ++
18796 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
18797 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
18798 + error = notify_change(nd.path.dentry, &newattrs);
18799 +@@ -650,7 +699,7 @@ asmlinkage long sys_chmod(const char __u
18800 + return sys_fchmodat(AT_FDCWD, filename, mode);
18801 + }
18802 +
18803 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
18804 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
18805 + {
18806 + struct inode * inode;
18807 + int error;
18808 +@@ -664,6 +713,12 @@ static int chown_common(struct dentry *
18809 + error = -EPERM;
18810 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
18811 + goto out;
18812 ++
18813 ++ if (!gr_acl_handle_chown(dentry, mnt)) {
18814 ++ error = -EACCES;
18815 ++ goto out;
18816 ++ }
18817 ++
18818 + newattrs.ia_valid = ATTR_CTIME;
18819 + if (user != (uid_t) -1) {
18820 + newattrs.ia_valid |= ATTR_UID;
18821 +@@ -694,7 +749,7 @@ asmlinkage long sys_chown(const char __u
18822 + error = mnt_want_write(nd.path.mnt);
18823 + if (error)
18824 + goto out_release;
18825 +- error = chown_common(nd.path.dentry, user, group);
18826 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
18827 + mnt_drop_write(nd.path.mnt);
18828 + out_release:
18829 + path_put(&nd.path);
18830 +@@ -719,7 +774,7 @@ asmlinkage long sys_fchownat(int dfd, co
18831 + error = mnt_want_write(nd.path.mnt);
18832 + if (error)
18833 + goto out_release;
18834 +- error = chown_common(nd.path.dentry, user, group);
18835 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
18836 + mnt_drop_write(nd.path.mnt);
18837 + out_release:
18838 + path_put(&nd.path);
18839 +@@ -738,7 +793,7 @@ asmlinkage long sys_lchown(const char __
18840 + error = mnt_want_write(nd.path.mnt);
18841 + if (error)
18842 + goto out_release;
18843 +- error = chown_common(nd.path.dentry, user, group);
18844 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
18845 + mnt_drop_write(nd.path.mnt);
18846 + out_release:
18847 + path_put(&nd.path);
18848 +@@ -762,7 +817,7 @@ asmlinkage long sys_fchown(unsigned int
18849 + goto out_fput;
18850 + dentry = file->f_path.dentry;
18851 + audit_inode(NULL, dentry);
18852 +- error = chown_common(dentry, user, group);
18853 ++ error = chown_common(dentry, user, group, file->f_path.mnt);
18854 + mnt_drop_write(file->f_path.mnt);
18855 + out_fput:
18856 + fput(file);
18857 +@@ -993,6 +1048,7 @@ repeat:
18858 + * N.B. For clone tasks sharing a files structure, this test
18859 + * will limit the total number of files that can be opened.
18860 + */
18861 ++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
18862 + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
18863 + goto out;
18864 +
18865 +diff -urNp linux-2.6.26.6/fs/partitions/efi.c linux-2.6.26.6/fs/partitions/efi.c
18866 +--- linux-2.6.26.6/fs/partitions/efi.c 2008-10-08 23:24:05.000000000 -0400
18867 ++++ linux-2.6.26.6/fs/partitions/efi.c 2008-10-11 21:54:20.000000000 -0400
18868 +@@ -99,7 +99,7 @@
18869 + #ifdef EFI_DEBUG
18870 + #define Dprintk(x...) printk(KERN_DEBUG x)
18871 + #else
18872 +-#define Dprintk(x...)
18873 ++#define Dprintk(x...) do {} while (0)
18874 + #endif
18875 +
18876 + /* This allows a kernel command line option 'gpt' to override
18877 +diff -urNp linux-2.6.26.6/fs/pipe.c linux-2.6.26.6/fs/pipe.c
18878 +--- linux-2.6.26.6/fs/pipe.c 2008-10-08 23:24:05.000000000 -0400
18879 ++++ linux-2.6.26.6/fs/pipe.c 2008-10-11 21:54:20.000000000 -0400
18880 +@@ -886,7 +886,7 @@ void free_pipe_info(struct inode *inode)
18881 + inode->i_pipe = NULL;
18882 + }
18883 +
18884 +-static struct vfsmount *pipe_mnt __read_mostly;
18885 ++struct vfsmount *pipe_mnt __read_mostly;
18886 + static int pipefs_delete_dentry(struct dentry *dentry)
18887 + {
18888 + /*
18889 +diff -urNp linux-2.6.26.6/fs/proc/array.c linux-2.6.26.6/fs/proc/array.c
18890 +--- linux-2.6.26.6/fs/proc/array.c 2008-10-08 23:24:05.000000000 -0400
18891 ++++ linux-2.6.26.6/fs/proc/array.c 2008-10-11 21:54:20.000000000 -0400
18892 +@@ -310,6 +310,21 @@ static inline void task_context_switch_c
18893 + p->nivcsw);
18894 + }
18895 +
18896 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
18897 ++static inline void task_pax(struct seq_file *m, struct task_struct *p)
18898 ++{
18899 ++ if (p->mm)
18900 ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
18901 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
18902 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
18903 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
18904 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
18905 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
18906 ++ else
18907 ++ seq_printf(m, "PaX:\t-----\n");
18908 ++}
18909 ++#endif
18910 ++
18911 + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
18912 + struct pid *pid, struct task_struct *task)
18913 + {
18914 +@@ -329,9 +344,20 @@ int proc_pid_status(struct seq_file *m,
18915 + task_show_regs(m, task);
18916 + #endif
18917 + task_context_switch_counts(m, task);
18918 ++
18919 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
18920 ++ task_pax(m, task);
18921 ++#endif
18922 ++
18923 + return 0;
18924 + }
18925 +
18926 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18927 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
18928 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
18929 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
18930 ++#endif
18931 ++
18932 + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
18933 + struct pid *pid, struct task_struct *task, int whole)
18934 + {
18935 +@@ -424,6 +450,19 @@ static int do_task_stat(struct seq_file
18936 + gtime = task_gtime(task);
18937 + }
18938 +
18939 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18940 ++ if (PAX_RAND_FLAGS(mm)) {
18941 ++ eip = 0;
18942 ++ esp = 0;
18943 ++ wchan = 0;
18944 ++ }
18945 ++#endif
18946 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
18947 ++ wchan = 0;
18948 ++ eip =0;
18949 ++ esp =0;
18950 ++#endif
18951 ++
18952 + /* scale priority and nice values from timeslices to -20..20 */
18953 + /* to make it look like a "normal" Unix priority/nice value */
18954 + priority = task_prio(task);
18955 +@@ -464,9 +503,15 @@ static int do_task_stat(struct seq_file
18956 + vsize,
18957 + mm ? get_mm_rss(mm) : 0,
18958 + rsslim,
18959 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
18960 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
18961 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
18962 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
18963 ++#else
18964 + mm ? mm->start_code : 0,
18965 + mm ? mm->end_code : 0,
18966 + mm ? mm->start_stack : 0,
18967 ++#endif
18968 + esp,
18969 + eip,
18970 + /* The signal information here is obsolete.
18971 +@@ -519,3 +564,10 @@ int proc_pid_statm(struct seq_file *m, s
18972 +
18973 + return 0;
18974 + }
18975 ++
18976 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
18977 ++int proc_pid_ipaddr(struct task_struct *task, char *buffer)
18978 ++{
18979 ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
18980 ++}
18981 ++#endif
18982 +diff -urNp linux-2.6.26.6/fs/proc/base.c linux-2.6.26.6/fs/proc/base.c
18983 +--- linux-2.6.26.6/fs/proc/base.c 2008-10-08 23:24:05.000000000 -0400
18984 ++++ linux-2.6.26.6/fs/proc/base.c 2008-10-11 21:54:20.000000000 -0400
18985 +@@ -77,6 +77,8 @@
18986 + #include <linux/oom.h>
18987 + #include <linux/elf.h>
18988 + #include <linux/pid_namespace.h>
18989 ++#include <linux/grsecurity.h>
18990 ++
18991 + #include "internal.h"
18992 +
18993 + /* NOTE:
18994 +@@ -146,7 +148,7 @@ static unsigned int pid_entry_count_dirs
18995 + return count;
18996 + }
18997 +
18998 +-int maps_protect;
18999 ++int maps_protect = 1;
19000 + EXPORT_SYMBOL(maps_protect);
19001 +
19002 + static struct fs_struct *get_fs_struct(struct task_struct *task)
19003 +@@ -227,6 +229,9 @@ static int check_mem_permission(struct t
19004 + if (task == current)
19005 + return 0;
19006 +
19007 ++ if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
19008 ++ return -EPERM;
19009 ++
19010 + /*
19011 + * If current is actively ptrace'ing, and would also be
19012 + * permitted to freshly attach with ptrace now, permit it.
19013 +@@ -305,9 +310,9 @@ static int proc_pid_auxv(struct task_str
19014 + struct mm_struct *mm = get_task_mm(task);
19015 + if (mm) {
19016 + unsigned int nwords = 0;
19017 +- do
19018 ++ do {
19019 + nwords += 2;
19020 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19021 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
19022 + res = nwords * sizeof(mm->saved_auxv[0]);
19023 + if (res > PAGE_SIZE)
19024 + res = PAGE_SIZE;
19025 +@@ -1410,7 +1415,11 @@ static struct inode *proc_pid_make_inode
19026 + inode->i_gid = 0;
19027 + if (task_dumpable(task)) {
19028 + inode->i_uid = task->euid;
19029 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19030 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19031 ++#else
19032 + inode->i_gid = task->egid;
19033 ++#endif
19034 + }
19035 + security_task_to_inode(task, inode);
19036 +
19037 +@@ -1426,17 +1435,45 @@ static int pid_getattr(struct vfsmount *
19038 + {
19039 + struct inode *inode = dentry->d_inode;
19040 + struct task_struct *task;
19041 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19042 ++ struct task_struct *tmp = current;
19043 ++#endif
19044 ++
19045 + generic_fillattr(inode, stat);
19046 +
19047 + rcu_read_lock();
19048 + stat->uid = 0;
19049 + stat->gid = 0;
19050 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
19051 +- if (task) {
19052 ++
19053 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
19054 ++ rcu_read_unlock();
19055 ++ return -ENOENT;
19056 ++ }
19057 ++
19058 ++
19059 ++ if (task
19060 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19061 ++ && (!tmp->uid || (tmp->uid == task->uid)
19062 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19063 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19064 ++#endif
19065 ++ )
19066 ++#endif
19067 ++ ) {
19068 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19069 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19070 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19071 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19072 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19073 ++#endif
19074 + task_dumpable(task)) {
19075 + stat->uid = task->euid;
19076 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19077 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
19078 ++#else
19079 + stat->gid = task->egid;
19080 ++#endif
19081 + }
19082 + }
19083 + rcu_read_unlock();
19084 +@@ -1464,11 +1501,21 @@ static int pid_revalidate(struct dentry
19085 + {
19086 + struct inode *inode = dentry->d_inode;
19087 + struct task_struct *task = get_proc_task(inode);
19088 ++
19089 + if (task) {
19090 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
19091 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19092 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
19093 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19094 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
19095 ++#endif
19096 + task_dumpable(task)) {
19097 + inode->i_uid = task->euid;
19098 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19099 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19100 ++#else
19101 + inode->i_gid = task->egid;
19102 ++#endif
19103 + } else {
19104 + inode->i_uid = 0;
19105 + inode->i_gid = 0;
19106 +@@ -1837,12 +1884,22 @@ static int proc_fd_permission(struct ino
19107 + struct nameidata *nd)
19108 + {
19109 + int rv;
19110 ++ struct task_struct *task;
19111 +
19112 + rv = generic_permission(inode, mask, NULL);
19113 +- if (rv == 0)
19114 +- return 0;
19115 ++
19116 + if (task_pid(current) == proc_pid(inode))
19117 + rv = 0;
19118 ++
19119 ++ task = get_proc_task(inode);
19120 ++ if (task == NULL)
19121 ++ return rv;
19122 ++
19123 ++ if (gr_acl_handle_procpidmem(task))
19124 ++ rv = -EACCES;
19125 ++
19126 ++ put_task_struct(task);
19127 ++
19128 + return rv;
19129 + }
19130 +
19131 +@@ -1953,6 +2010,9 @@ static struct dentry *proc_pident_lookup
19132 + if (!task)
19133 + goto out_no_task;
19134 +
19135 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19136 ++ goto out;
19137 ++
19138 + /*
19139 + * Yes, it does not scale. And it should not. Don't add
19140 + * new entries into /proc/<tgid>/ without very good reasons.
19141 +@@ -1997,6 +2057,9 @@ static int proc_pident_readdir(struct fi
19142 + if (!task)
19143 + goto out_no_task;
19144 +
19145 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19146 ++ goto out;
19147 ++
19148 + ret = 0;
19149 + i = filp->f_pos;
19150 + switch (i) {
19151 +@@ -2359,6 +2422,9 @@ static struct dentry *proc_base_lookup(s
19152 + if (p > last)
19153 + goto out;
19154 +
19155 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
19156 ++ goto out;
19157 ++
19158 + error = proc_base_instantiate(dir, dentry, task, p);
19159 +
19160 + out:
19161 +@@ -2471,6 +2537,9 @@ static const struct pid_entry tgid_base_
19162 + #ifdef CONFIG_TASK_IO_ACCOUNTING
19163 + INF("io", S_IRUGO, pid_io_accounting),
19164 + #endif
19165 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19166 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
19167 ++#endif
19168 + };
19169 +
19170 + static int proc_tgid_base_readdir(struct file * filp,
19171 +@@ -2600,7 +2669,14 @@ static struct dentry *proc_pid_instantia
19172 + if (!inode)
19173 + goto out;
19174 +
19175 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19176 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
19177 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19178 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19179 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
19180 ++#else
19181 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
19182 ++#endif
19183 + inode->i_op = &proc_tgid_base_inode_operations;
19184 + inode->i_fop = &proc_tgid_base_operations;
19185 + inode->i_flags|=S_IMMUTABLE;
19186 +@@ -2642,7 +2718,11 @@ struct dentry *proc_pid_lookup(struct in
19187 + if (!task)
19188 + goto out;
19189 +
19190 ++ if (gr_check_hidden_task(task))
19191 ++ goto out_put_task;
19192 ++
19193 + result = proc_pid_instantiate(dir, dentry, task, NULL);
19194 ++out_put_task:
19195 + put_task_struct(task);
19196 + out:
19197 + return result;
19198 +@@ -2707,6 +2787,9 @@ int proc_pid_readdir(struct file * filp,
19199 + {
19200 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
19201 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
19202 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19203 ++ struct task_struct *tmp = current;
19204 ++#endif
19205 + struct tgid_iter iter;
19206 + struct pid_namespace *ns;
19207 +
19208 +@@ -2725,6 +2808,17 @@ int proc_pid_readdir(struct file * filp,
19209 + for (iter = next_tgid(ns, iter);
19210 + iter.task;
19211 + iter.tgid += 1, iter = next_tgid(ns, iter)) {
19212 ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
19213 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19214 ++ || (tmp->uid && (iter.task->uid != tmp->uid)
19215 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19216 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
19217 ++#endif
19218 ++ )
19219 ++#endif
19220 ++ )
19221 ++ continue;
19222 ++
19223 + filp->f_pos = iter.tgid + TGID_OFFSET;
19224 + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
19225 + put_task_struct(iter.task);
19226 +diff -urNp linux-2.6.26.6/fs/proc/inode.c linux-2.6.26.6/fs/proc/inode.c
19227 +--- linux-2.6.26.6/fs/proc/inode.c 2008-10-08 23:24:05.000000000 -0400
19228 ++++ linux-2.6.26.6/fs/proc/inode.c 2008-10-11 21:54:20.000000000 -0400
19229 +@@ -403,7 +403,11 @@ struct inode *proc_get_inode(struct supe
19230 + if (de->mode) {
19231 + inode->i_mode = de->mode;
19232 + inode->i_uid = de->uid;
19233 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
19234 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
19235 ++#else
19236 + inode->i_gid = de->gid;
19237 ++#endif
19238 + }
19239 + if (de->size)
19240 + inode->i_size = de->size;
19241 +diff -urNp linux-2.6.26.6/fs/proc/internal.h linux-2.6.26.6/fs/proc/internal.h
19242 +--- linux-2.6.26.6/fs/proc/internal.h 2008-10-08 23:24:05.000000000 -0400
19243 ++++ linux-2.6.26.6/fs/proc/internal.h 2008-10-11 21:54:20.000000000 -0400
19244 +@@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
19245 + struct pid *pid, struct task_struct *task);
19246 + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
19247 + struct pid *pid, struct task_struct *task);
19248 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
19249 ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
19250 ++#endif
19251 + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
19252 +
19253 + extern const struct file_operations proc_maps_operations;
19254 +diff -urNp linux-2.6.26.6/fs/proc/proc_misc.c linux-2.6.26.6/fs/proc/proc_misc.c
19255 +--- linux-2.6.26.6/fs/proc/proc_misc.c 2008-10-08 23:24:05.000000000 -0400
19256 ++++ linux-2.6.26.6/fs/proc/proc_misc.c 2008-10-11 21:54:20.000000000 -0400
19257 +@@ -830,6 +830,8 @@ struct proc_dir_entry *proc_root_kcore;
19258 +
19259 + void __init proc_misc_init(void)
19260 + {
19261 ++ int gr_mode = 0;
19262 ++
19263 + static struct {
19264 + char *name;
19265 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
19266 +@@ -845,13 +847,24 @@ void __init proc_misc_init(void)
19267 + {"stram", stram_read_proc},
19268 + #endif
19269 + {"filesystems", filesystems_read_proc},
19270 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
19271 + {"cmdline", cmdline_read_proc},
19272 ++#endif
19273 + {"execdomains", execdomains_read_proc},
19274 + {NULL,}
19275 + };
19276 + for (p = simple_ones; p->name; p++)
19277 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
19278 +
19279 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19280 ++ gr_mode = S_IRUSR;
19281 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19282 ++ gr_mode = S_IRUSR | S_IRGRP;
19283 ++#endif
19284 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19285 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
19286 ++#endif
19287 ++
19288 + proc_symlink("mounts", NULL, "self/mounts");
19289 +
19290 + /* And now for trickier ones */
19291 +@@ -859,14 +872,18 @@ void __init proc_misc_init(void)
19292 + proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
19293 + #endif
19294 + proc_create("locks", 0, NULL, &proc_locks_operations);
19295 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19296 ++ proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
19297 ++#else
19298 + proc_create("devices", 0, NULL, &proc_devinfo_operations);
19299 ++#endif
19300 + proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
19301 + #ifdef CONFIG_BLOCK
19302 + proc_create("partitions", 0, NULL, &proc_partitions_operations);
19303 + #endif
19304 + proc_create("stat", 0, NULL, &proc_stat_operations);
19305 + proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
19306 +-#ifdef CONFIG_SLABINFO
19307 ++#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
19308 + proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
19309 + #ifdef CONFIG_DEBUG_SLAB_LEAK
19310 + proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
19311 +@@ -888,7 +905,7 @@ void __init proc_misc_init(void)
19312 + #ifdef CONFIG_SCHEDSTATS
19313 + proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
19314 + #endif
19315 +-#ifdef CONFIG_PROC_KCORE
19316 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
19317 + proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
19318 + if (proc_root_kcore)
19319 + proc_root_kcore->size =
19320 +diff -urNp linux-2.6.26.6/fs/proc/proc_net.c linux-2.6.26.6/fs/proc/proc_net.c
19321 +--- linux-2.6.26.6/fs/proc/proc_net.c 2008-10-08 23:24:05.000000000 -0400
19322 ++++ linux-2.6.26.6/fs/proc/proc_net.c 2008-10-11 21:54:20.000000000 -0400
19323 +@@ -69,6 +69,14 @@ static struct net *get_proc_task_net(str
19324 + struct nsproxy *ns;
19325 + struct net *net = NULL;
19326 +
19327 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19328 ++ if (current->fsuid)
19329 ++ return net;
19330 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19331 ++ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
19332 ++ return net;
19333 ++#endif
19334 ++
19335 + rcu_read_lock();
19336 + task = pid_task(proc_pid(dir), PIDTYPE_PID);
19337 + if (task != NULL) {
19338 +diff -urNp linux-2.6.26.6/fs/proc/proc_sysctl.c linux-2.6.26.6/fs/proc/proc_sysctl.c
19339 +--- linux-2.6.26.6/fs/proc/proc_sysctl.c 2008-10-08 23:24:05.000000000 -0400
19340 ++++ linux-2.6.26.6/fs/proc/proc_sysctl.c 2008-10-11 21:54:20.000000000 -0400
19341 +@@ -7,6 +7,8 @@
19342 + #include <linux/security.h>
19343 + #include "internal.h"
19344 +
19345 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
19346 ++
19347 + static struct dentry_operations proc_sys_dentry_operations;
19348 + static const struct file_operations proc_sys_file_operations;
19349 + static const struct inode_operations proc_sys_inode_operations;
19350 +@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
19351 + if (!table)
19352 + goto out;
19353 +
19354 ++ if (gr_handle_sysctl(table, 001))
19355 ++ goto out;
19356 ++
19357 + err = ERR_PTR(-ENOMEM);
19358 + inode = proc_sys_make_inode(dir, table);
19359 + if (!inode)
19360 +@@ -332,6 +337,9 @@ static int proc_sys_readdir(struct file
19361 + if (pos < filp->f_pos)
19362 + continue;
19363 +
19364 ++ if (gr_handle_sysctl(table, 0))
19365 ++ continue;
19366 ++
19367 + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
19368 + goto out;
19369 + filp->f_pos = pos + 1;
19370 +@@ -394,6 +402,30 @@ out:
19371 + return error;
19372 + }
19373 +
19374 ++/* Eric Biederman is to blame */
19375 ++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
19376 ++{
19377 ++ int error = 0;
19378 ++ struct ctl_table_header *head;
19379 ++ struct ctl_table *table;
19380 ++
19381 ++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
19382 ++ /* Has the sysctl entry disappeared on us? */
19383 ++ if (!table)
19384 ++ goto out;
19385 ++
19386 ++ if (gr_handle_sysctl(table, 001)) {
19387 ++ error = -ENOENT;
19388 ++ goto out;
19389 ++ }
19390 ++
19391 ++out:
19392 ++ sysctl_head_finish(head);
19393 ++
19394 ++ generic_fillattr(dentry->d_inode, stat);
19395 ++
19396 ++ return error;
19397 ++}
19398 + static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
19399 + {
19400 + struct inode *inode = dentry->d_inode;
19401 +@@ -422,6 +454,7 @@ static const struct inode_operations pro
19402 + .lookup = proc_sys_lookup,
19403 + .permission = proc_sys_permission,
19404 + .setattr = proc_sys_setattr,
19405 ++ .getattr = proc_sys_getattr,
19406 + };
19407 +
19408 + static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
19409 +diff -urNp linux-2.6.26.6/fs/proc/root.c linux-2.6.26.6/fs/proc/root.c
19410 +--- linux-2.6.26.6/fs/proc/root.c 2008-10-08 23:24:05.000000000 -0400
19411 ++++ linux-2.6.26.6/fs/proc/root.c 2008-10-11 21:54:20.000000000 -0400
19412 +@@ -135,7 +135,15 @@ void __init proc_root_init(void)
19413 + #ifdef CONFIG_PROC_DEVICETREE
19414 + proc_device_tree_init();
19415 + #endif
19416 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
19417 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
19418 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
19419 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
19420 ++ proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
19421 ++#endif
19422 ++#else
19423 + proc_mkdir("bus", NULL);
19424 ++#endif
19425 + proc_sys_init();
19426 + }
19427 +
19428 +diff -urNp linux-2.6.26.6/fs/proc/task_mmu.c linux-2.6.26.6/fs/proc/task_mmu.c
19429 +--- linux-2.6.26.6/fs/proc/task_mmu.c 2008-10-08 23:24:05.000000000 -0400
19430 ++++ linux-2.6.26.6/fs/proc/task_mmu.c 2008-10-11 21:54:20.000000000 -0400
19431 +@@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
19432 + "VmStk:\t%8lu kB\n"
19433 + "VmExe:\t%8lu kB\n"
19434 + "VmLib:\t%8lu kB\n"
19435 +- "VmPTE:\t%8lu kB\n",
19436 +- hiwater_vm << (PAGE_SHIFT-10),
19437 ++ "VmPTE:\t%8lu kB\n"
19438 ++
19439 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19440 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
19441 ++#endif
19442 ++
19443 ++ ,hiwater_vm << (PAGE_SHIFT-10),
19444 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
19445 + mm->locked_vm << (PAGE_SHIFT-10),
19446 + hiwater_rss << (PAGE_SHIFT-10),
19447 + total_rss << (PAGE_SHIFT-10),
19448 + data << (PAGE_SHIFT-10),
19449 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
19450 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
19451 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
19452 ++
19453 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19454 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
19455 ++#endif
19456 ++
19457 ++ );
19458 + }
19459 +
19460 + unsigned long task_vsize(struct mm_struct *mm)
19461 +@@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
19462 + return ret;
19463 + }
19464 +
19465 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19466 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
19467 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
19468 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
19469 ++#endif
19470 ++
19471 + static int show_map(struct seq_file *m, void *v)
19472 + {
19473 + struct proc_maps_private *priv = m->private;
19474 +@@ -220,13 +237,22 @@ static int show_map(struct seq_file *m,
19475 + }
19476 +
19477 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
19478 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19479 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
19480 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
19481 ++#else
19482 + vma->vm_start,
19483 + vma->vm_end,
19484 ++#endif
19485 + flags & VM_READ ? 'r' : '-',
19486 + flags & VM_WRITE ? 'w' : '-',
19487 + flags & VM_EXEC ? 'x' : '-',
19488 + flags & VM_MAYSHARE ? 's' : 'p',
19489 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19490 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
19491 ++#else
19492 + vma->vm_pgoff << PAGE_SHIFT,
19493 ++#endif
19494 + MAJOR(dev), MINOR(dev), ino, &len);
19495 +
19496 + /*
19497 +@@ -240,11 +266,11 @@ static int show_map(struct seq_file *m,
19498 + const char *name = arch_vma_name(vma);
19499 + if (!name) {
19500 + if (mm) {
19501 +- if (vma->vm_start <= mm->start_brk &&
19502 +- vma->vm_end >= mm->brk) {
19503 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
19504 + name = "[heap]";
19505 +- } else if (vma->vm_start <= mm->start_stack &&
19506 +- vma->vm_end >= mm->start_stack) {
19507 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
19508 ++ (vma->vm_start <= mm->start_stack &&
19509 ++ vma->vm_end >= mm->start_stack)) {
19510 + name = "[stack]";
19511 + }
19512 + } else {
19513 +@@ -377,9 +403,16 @@ static int show_smap(struct seq_file *m,
19514 + };
19515 +
19516 + memset(&mss, 0, sizeof mss);
19517 +- mss.vma = vma;
19518 +- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
19519 +- walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
19520 ++
19521 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19522 ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
19523 ++#endif
19524 ++ mss.vma = vma;
19525 ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
19526 ++ walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
19527 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19528 ++ }
19529 ++#endif
19530 +
19531 + ret = show_map(m, v);
19532 + if (ret)
19533 +@@ -395,7 +428,11 @@ static int show_smap(struct seq_file *m,
19534 + "Private_Dirty: %8lu kB\n"
19535 + "Referenced: %8lu kB\n"
19536 + "Swap: %8lu kB\n",
19537 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19538 ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
19539 ++#else
19540 + (vma->vm_end - vma->vm_start) >> 10,
19541 ++#endif
19542 + mss.resident >> 10,
19543 + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
19544 + mss.shared_clean >> 10,
19545 +@@ -747,6 +784,11 @@ static int show_numa_map_checked(struct
19546 + struct proc_maps_private *priv = m->private;
19547 + struct task_struct *task = priv->task;
19548 +
19549 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
19550 ++ if (!ptrace_may_attach(task))
19551 ++ return -EACCES;
19552 ++#endif
19553 ++
19554 + if (maps_protect && !ptrace_may_attach(task))
19555 + return -EACCES;
19556 +
19557 +diff -urNp linux-2.6.26.6/fs/readdir.c linux-2.6.26.6/fs/readdir.c
19558 +--- linux-2.6.26.6/fs/readdir.c 2008-10-08 23:24:05.000000000 -0400
19559 ++++ linux-2.6.26.6/fs/readdir.c 2008-10-11 21:54:20.000000000 -0400
19560 +@@ -16,6 +16,8 @@
19561 + #include <linux/security.h>
19562 + #include <linux/syscalls.h>
19563 + #include <linux/unistd.h>
19564 ++#include <linux/namei.h>
19565 ++#include <linux/grsecurity.h>
19566 +
19567 + #include <asm/uaccess.h>
19568 +
19569 +@@ -67,6 +69,7 @@ struct old_linux_dirent {
19570 +
19571 + struct readdir_callback {
19572 + struct old_linux_dirent __user * dirent;
19573 ++ struct file * file;
19574 + int result;
19575 + };
19576 +
19577 +@@ -82,6 +85,10 @@ static int fillonedir(void * __buf, cons
19578 + d_ino = ino;
19579 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
19580 + return -EOVERFLOW;
19581 ++
19582 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
19583 ++ return 0;
19584 ++
19585 + buf->result++;
19586 + dirent = buf->dirent;
19587 + if (!access_ok(VERIFY_WRITE, dirent,
19588 +@@ -113,6 +120,7 @@ asmlinkage long old_readdir(unsigned int
19589 +
19590 + buf.result = 0;
19591 + buf.dirent = dirent;
19592 ++ buf.file = file;
19593 +
19594 + error = vfs_readdir(file, fillonedir, &buf);
19595 + if (error >= 0)
19596 +@@ -139,6 +147,7 @@ struct linux_dirent {
19597 + struct getdents_callback {
19598 + struct linux_dirent __user * current_dir;
19599 + struct linux_dirent __user * previous;
19600 ++ struct file * file;
19601 + int count;
19602 + int error;
19603 + };
19604 +@@ -157,6 +166,10 @@ static int filldir(void * __buf, const c
19605 + d_ino = ino;
19606 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
19607 + return -EOVERFLOW;
19608 ++
19609 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
19610 ++ return 0;
19611 ++
19612 + dirent = buf->previous;
19613 + if (dirent) {
19614 + if (__put_user(offset, &dirent->d_off))
19615 +@@ -203,6 +216,7 @@ asmlinkage long sys_getdents(unsigned in
19616 + buf.previous = NULL;
19617 + buf.count = count;
19618 + buf.error = 0;
19619 ++ buf.file = file;
19620 +
19621 + error = vfs_readdir(file, filldir, &buf);
19622 + if (error < 0)
19623 +@@ -225,6 +239,7 @@ out:
19624 + struct getdents_callback64 {
19625 + struct linux_dirent64 __user * current_dir;
19626 + struct linux_dirent64 __user * previous;
19627 ++ struct file *file;
19628 + int count;
19629 + int error;
19630 + };
19631 +@@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
19632 + buf->error = -EINVAL; /* only used if we fail.. */
19633 + if (reclen > buf->count)
19634 + return -EINVAL;
19635 ++
19636 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
19637 ++ return 0;
19638 ++
19639 + dirent = buf->previous;
19640 + if (dirent) {
19641 + if (__put_user(offset, &dirent->d_off))
19642 +@@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
19643 +
19644 + buf.current_dir = dirent;
19645 + buf.previous = NULL;
19646 ++ buf.file = file;
19647 + buf.count = count;
19648 + buf.error = 0;
19649 +
19650 +diff -urNp linux-2.6.26.6/fs/smbfs/symlink.c linux-2.6.26.6/fs/smbfs/symlink.c
19651 +--- linux-2.6.26.6/fs/smbfs/symlink.c 2008-10-08 23:24:05.000000000 -0400
19652 ++++ linux-2.6.26.6/fs/smbfs/symlink.c 2008-10-11 21:54:20.000000000 -0400
19653 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
19654 +
19655 + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
19656 + {
19657 +- char *s = nd_get_link(nd);
19658 ++ const char *s = nd_get_link(nd);
19659 + if (!IS_ERR(s))
19660 + __putname(s);
19661 + }
19662 +diff -urNp linux-2.6.26.6/fs/sysfs/symlink.c linux-2.6.26.6/fs/sysfs/symlink.c
19663 +--- linux-2.6.26.6/fs/sysfs/symlink.c 2008-10-08 23:24:05.000000000 -0400
19664 ++++ linux-2.6.26.6/fs/sysfs/symlink.c 2008-10-11 21:54:20.000000000 -0400
19665 +@@ -175,7 +175,7 @@ static void *sysfs_follow_link(struct de
19666 +
19667 + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
19668 + {
19669 +- char *page = nd_get_link(nd);
19670 ++ const char *page = nd_get_link(nd);
19671 + if (!IS_ERR(page))
19672 + free_page((unsigned long)page);
19673 + }
19674 +diff -urNp linux-2.6.26.6/fs/udf/balloc.c linux-2.6.26.6/fs/udf/balloc.c
19675 +--- linux-2.6.26.6/fs/udf/balloc.c 2008-10-08 23:24:05.000000000 -0400
19676 ++++ linux-2.6.26.6/fs/udf/balloc.c 2008-10-11 21:54:20.000000000 -0400
19677 +@@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
19678 + unsigned long overflow;
19679 +
19680 + mutex_lock(&sbi->s_alloc_mutex);
19681 +- if (bloc.logicalBlockNum < 0 ||
19682 +- (bloc.logicalBlockNum + count) >
19683 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19684 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19685 + udf_debug("%d < %d || %d + %d > %d\n",
19686 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
19687 + sbi->s_partmaps[bloc.partitionReferenceNum].
19688 +@@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
19689 +
19690 + mutex_lock(&sbi->s_alloc_mutex);
19691 + part_len = sbi->s_partmaps[partition].s_partition_len;
19692 +- if (first_block < 0 || first_block >= part_len)
19693 ++ if (first_block >= part_len)
19694 + goto out;
19695 +
19696 + if (first_block + block_count > part_len)
19697 +@@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
19698 + mutex_lock(&sbi->s_alloc_mutex);
19699 +
19700 + repeat:
19701 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
19702 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
19703 + goal = 0;
19704 +
19705 + nr_groups = bitmap->s_nr_groups;
19706 +@@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
19707 + struct udf_inode_info *iinfo;
19708 +
19709 + mutex_lock(&sbi->s_alloc_mutex);
19710 +- if (bloc.logicalBlockNum < 0 ||
19711 +- (bloc.logicalBlockNum + count) >
19712 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19713 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
19714 + udf_debug("%d < %d || %d + %d > %d\n",
19715 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
19716 + sbi->s_partmaps[bloc.partitionReferenceNum].
19717 +@@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
19718 + int8_t etype = -1;
19719 + struct udf_inode_info *iinfo;
19720 +
19721 +- if (first_block < 0 ||
19722 +- first_block >= sbi->s_partmaps[partition].s_partition_len)
19723 ++ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
19724 + return 0;
19725 +
19726 + iinfo = UDF_I(table);
19727 +@@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
19728 + return newblock;
19729 +
19730 + mutex_lock(&sbi->s_alloc_mutex);
19731 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
19732 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
19733 + goal = 0;
19734 +
19735 + /* We search for the closest matching block to goal. If we find
19736 +diff -urNp linux-2.6.26.6/fs/ufs/inode.c linux-2.6.26.6/fs/ufs/inode.c
19737 +--- linux-2.6.26.6/fs/ufs/inode.c 2008-10-08 23:24:05.000000000 -0400
19738 ++++ linux-2.6.26.6/fs/ufs/inode.c 2008-10-11 21:54:20.000000000 -0400
19739 +@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
19740 +
19741 +
19742 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
19743 +- if (i_block < 0) {
19744 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
19745 +- } else if (i_block < direct_blocks) {
19746 ++ if (i_block < direct_blocks) {
19747 + offsets[n++] = i_block;
19748 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
19749 + offsets[n++] = UFS_IND_BLOCK;
19750 +@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
19751 + lock_kernel();
19752 +
19753 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
19754 +- if (fragment < 0)
19755 +- goto abort_negative;
19756 + if (fragment >
19757 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
19758 + << uspi->s_fpbshift))
19759 +@@ -504,10 +500,6 @@ abort:
19760 + unlock_kernel();
19761 + return err;
19762 +
19763 +-abort_negative:
19764 +- ufs_warning(sb, "ufs_get_block", "block < 0");
19765 +- goto abort;
19766 +-
19767 + abort_too_big:
19768 + ufs_warning(sb, "ufs_get_block", "block > big");
19769 + goto abort;
19770 +diff -urNp linux-2.6.26.6/fs/utimes.c linux-2.6.26.6/fs/utimes.c
19771 +--- linux-2.6.26.6/fs/utimes.c 2008-10-08 23:24:05.000000000 -0400
19772 ++++ linux-2.6.26.6/fs/utimes.c 2008-10-11 21:54:20.000000000 -0400
19773 +@@ -8,6 +8,7 @@
19774 + #include <linux/stat.h>
19775 + #include <linux/utime.h>
19776 + #include <linux/syscalls.h>
19777 ++#include <linux/grsecurity.h>
19778 + #include <asm/uaccess.h>
19779 + #include <asm/unistd.h>
19780 +
19781 +@@ -57,10 +58,10 @@ long do_utimes(int dfd, char __user *fil
19782 + int error;
19783 + struct nameidata nd;
19784 + struct dentry *dentry;
19785 ++ struct vfsmount *mnt;
19786 + struct inode *inode;
19787 + struct iattr newattrs;
19788 + struct file *f = NULL;
19789 +- struct vfsmount *mnt;
19790 +
19791 + error = -EINVAL;
19792 + if (times && (!nsec_valid(times[0].tv_nsec) ||
19793 +@@ -153,6 +154,12 @@ long do_utimes(int dfd, char __user *fil
19794 + goto mnt_drop_write_and_out;
19795 + }
19796 + }
19797 ++
19798 ++ if (!gr_acl_handle_utime(dentry, mnt)) {
19799 ++ error = -EACCES;
19800 ++ goto mnt_drop_write_and_out;
19801 ++ }
19802 ++
19803 + mutex_lock(&inode->i_mutex);
19804 + error = notify_change(dentry, &newattrs);
19805 + mutex_unlock(&inode->i_mutex);
19806 +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
19807 +--- linux-2.6.26.6/fs/xfs/linux-2.6/xfs_iops.c 2008-10-08 23:24:05.000000000 -0400
19808 ++++ linux-2.6.26.6/fs/xfs/linux-2.6/xfs_iops.c 2008-10-11 21:54:20.000000000 -0400
19809 +@@ -560,7 +560,7 @@ xfs_vn_put_link(
19810 + struct nameidata *nd,
19811 + void *p)
19812 + {
19813 +- char *s = nd_get_link(nd);
19814 ++ const char *s = nd_get_link(nd);
19815 +
19816 + if (!IS_ERR(s))
19817 + kfree(s);
19818 +diff -urNp linux-2.6.26.6/fs/xfs/xfs_bmap.c linux-2.6.26.6/fs/xfs/xfs_bmap.c
19819 +--- linux-2.6.26.6/fs/xfs/xfs_bmap.c 2008-10-08 23:24:05.000000000 -0400
19820 ++++ linux-2.6.26.6/fs/xfs/xfs_bmap.c 2008-10-11 21:54:20.000000000 -0400
19821 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
19822 + int nmap,
19823 + int ret_nmap);
19824 + #else
19825 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
19826 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
19827 + #endif /* DEBUG */
19828 +
19829 + #if defined(XFS_RW_TRACE)
19830 +diff -urNp linux-2.6.26.6/grsecurity/gracl_alloc.c linux-2.6.26.6/grsecurity/gracl_alloc.c
19831 +--- linux-2.6.26.6/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
19832 ++++ linux-2.6.26.6/grsecurity/gracl_alloc.c 2008-10-11 21:54:20.000000000 -0400
19833 +@@ -0,0 +1,91 @@
19834 ++#include <linux/kernel.h>
19835 ++#include <linux/mm.h>
19836 ++#include <linux/slab.h>
19837 ++#include <linux/vmalloc.h>
19838 ++#include <linux/gracl.h>
19839 ++#include <linux/grsecurity.h>
19840 ++
19841 ++static unsigned long alloc_stack_next = 1;
19842 ++static unsigned long alloc_stack_size = 1;
19843 ++static void **alloc_stack;
19844 ++
19845 ++static __inline__ int
19846 ++alloc_pop(void)
19847 ++{
19848 ++ if (alloc_stack_next == 1)
19849 ++ return 0;
19850 ++
19851 ++ kfree(alloc_stack[alloc_stack_next - 2]);
19852 ++
19853 ++ alloc_stack_next--;
19854 ++
19855 ++ return 1;
19856 ++}
19857 ++
19858 ++static __inline__ void
19859 ++alloc_push(void *buf)
19860 ++{
19861 ++ if (alloc_stack_next >= alloc_stack_size)
19862 ++ BUG();
19863 ++
19864 ++ alloc_stack[alloc_stack_next - 1] = buf;
19865 ++
19866 ++ alloc_stack_next++;
19867 ++
19868 ++ return;
19869 ++}
19870 ++
19871 ++void *
19872 ++acl_alloc(unsigned long len)
19873 ++{
19874 ++ void *ret;
19875 ++
19876 ++ if (len > PAGE_SIZE)
19877 ++ BUG();
19878 ++
19879 ++ ret = kmalloc(len, GFP_KERNEL);
19880 ++
19881 ++ if (ret)
19882 ++ alloc_push(ret);
19883 ++
19884 ++ return ret;
19885 ++}
19886 ++
19887 ++void
19888 ++acl_free_all(void)
19889 ++{
19890 ++ if (gr_acl_is_enabled() || !alloc_stack)
19891 ++ return;
19892 ++
19893 ++ while (alloc_pop()) ;
19894 ++
19895 ++ if (alloc_stack) {
19896 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
19897 ++ kfree(alloc_stack);
19898 ++ else
19899 ++ vfree(alloc_stack);
19900 ++ }
19901 ++
19902 ++ alloc_stack = NULL;
19903 ++ alloc_stack_size = 1;
19904 ++ alloc_stack_next = 1;
19905 ++
19906 ++ return;
19907 ++}
19908 ++
19909 ++int
19910 ++acl_alloc_stack_init(unsigned long size)
19911 ++{
19912 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
19913 ++ alloc_stack =
19914 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
19915 ++ else
19916 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
19917 ++
19918 ++ alloc_stack_size = size;
19919 ++
19920 ++ if (!alloc_stack)
19921 ++ return 0;
19922 ++ else
19923 ++ return 1;
19924 ++}
19925 +diff -urNp linux-2.6.26.6/grsecurity/gracl.c linux-2.6.26.6/grsecurity/gracl.c
19926 +--- linux-2.6.26.6/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
19927 ++++ linux-2.6.26.6/grsecurity/gracl.c 2008-10-11 21:54:20.000000000 -0400
19928 +@@ -0,0 +1,3722 @@
19929 ++#include <linux/kernel.h>
19930 ++#include <linux/module.h>
19931 ++#include <linux/sched.h>
19932 ++#include <linux/mm.h>
19933 ++#include <linux/file.h>
19934 ++#include <linux/fs.h>
19935 ++#include <linux/namei.h>
19936 ++#include <linux/mount.h>
19937 ++#include <linux/tty.h>
19938 ++#include <linux/proc_fs.h>
19939 ++#include <linux/smp_lock.h>
19940 ++#include <linux/slab.h>
19941 ++#include <linux/vmalloc.h>
19942 ++#include <linux/types.h>
19943 ++#include <linux/sysctl.h>
19944 ++#include <linux/netdevice.h>
19945 ++#include <linux/ptrace.h>
19946 ++#include <linux/gracl.h>
19947 ++#include <linux/gralloc.h>
19948 ++#include <linux/grsecurity.h>
19949 ++#include <linux/grinternal.h>
19950 ++#include <linux/pid_namespace.h>
19951 ++#include <linux/fdtable.h>
19952 ++#include <linux/percpu.h>
19953 ++
19954 ++#include <asm/uaccess.h>
19955 ++#include <asm/errno.h>
19956 ++#include <asm/mman.h>
19957 ++
19958 ++static struct acl_role_db acl_role_set;
19959 ++static struct name_db name_set;
19960 ++static struct inodev_db inodev_set;
19961 ++
19962 ++/* for keeping track of userspace pointers used for subjects, so we
19963 ++ can share references in the kernel as well
19964 ++*/
19965 ++
19966 ++static struct dentry *real_root;
19967 ++static struct vfsmount *real_root_mnt;
19968 ++
19969 ++static struct acl_subj_map_db subj_map_set;
19970 ++
19971 ++static struct acl_role_label *default_role;
19972 ++
19973 ++static u16 acl_sp_role_value;
19974 ++
19975 ++extern char *gr_shared_page[4];
19976 ++static DECLARE_MUTEX(gr_dev_sem);
19977 ++DEFINE_RWLOCK(gr_inode_lock);
19978 ++
19979 ++struct gr_arg *gr_usermode;
19980 ++
19981 ++static unsigned int gr_status = GR_STATUS_INIT;
19982 ++
19983 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
19984 ++extern void gr_clear_learn_entries(void);
19985 ++
19986 ++#ifdef CONFIG_GRKERNSEC_RESLOG
19987 ++extern void gr_log_resource(const struct task_struct *task,
19988 ++ const int res, const unsigned long wanted, const int gt);
19989 ++#endif
19990 ++
19991 ++unsigned char *gr_system_salt;
19992 ++unsigned char *gr_system_sum;
19993 ++
19994 ++static struct sprole_pw **acl_special_roles = NULL;
19995 ++static __u16 num_sprole_pws = 0;
19996 ++
19997 ++static struct acl_role_label *kernel_role = NULL;
19998 ++
19999 ++static unsigned int gr_auth_attempts = 0;
20000 ++static unsigned long gr_auth_expires = 0UL;
20001 ++
20002 ++extern struct vfsmount *sock_mnt;
20003 ++extern struct vfsmount *pipe_mnt;
20004 ++extern struct vfsmount *shm_mnt;
20005 ++static struct acl_object_label *fakefs_obj;
20006 ++
20007 ++extern int gr_init_uidset(void);
20008 ++extern void gr_free_uidset(void);
20009 ++extern void gr_remove_uid(uid_t uid);
20010 ++extern int gr_find_uid(uid_t uid);
20011 ++
20012 ++__inline__ int
20013 ++gr_acl_is_enabled(void)
20014 ++{
20015 ++ return (gr_status & GR_READY);
20016 ++}
20017 ++
20018 ++char gr_roletype_to_char(void)
20019 ++{
20020 ++ switch (current->role->roletype &
20021 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
20022 ++ GR_ROLE_SPECIAL)) {
20023 ++ case GR_ROLE_DEFAULT:
20024 ++ return 'D';
20025 ++ case GR_ROLE_USER:
20026 ++ return 'U';
20027 ++ case GR_ROLE_GROUP:
20028 ++ return 'G';
20029 ++ case GR_ROLE_SPECIAL:
20030 ++ return 'S';
20031 ++ }
20032 ++
20033 ++ return 'X';
20034 ++}
20035 ++
20036 ++__inline__ int
20037 ++gr_acl_tpe_check(void)
20038 ++{
20039 ++ if (unlikely(!(gr_status & GR_READY)))
20040 ++ return 0;
20041 ++ if (current->role->roletype & GR_ROLE_TPE)
20042 ++ return 1;
20043 ++ else
20044 ++ return 0;
20045 ++}
20046 ++
20047 ++int
20048 ++gr_handle_rawio(const struct inode *inode)
20049 ++{
20050 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
20051 ++ if (inode && S_ISBLK(inode->i_mode) &&
20052 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
20053 ++ !capable(CAP_SYS_RAWIO))
20054 ++ return 1;
20055 ++#endif
20056 ++ return 0;
20057 ++}
20058 ++
20059 ++static int
20060 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
20061 ++{
20062 ++ int i;
20063 ++ unsigned long *l1;
20064 ++ unsigned long *l2;
20065 ++ unsigned char *c1;
20066 ++ unsigned char *c2;
20067 ++ int num_longs;
20068 ++
20069 ++ if (likely(lena != lenb))
20070 ++ return 0;
20071 ++
20072 ++ l1 = (unsigned long *)a;
20073 ++ l2 = (unsigned long *)b;
20074 ++
20075 ++ num_longs = lena / sizeof(unsigned long);
20076 ++
20077 ++ for (i = num_longs; i--; l1++, l2++) {
20078 ++ if (unlikely(*l1 != *l2))
20079 ++ return 0;
20080 ++ }
20081 ++
20082 ++ c1 = (unsigned char *) l1;
20083 ++ c2 = (unsigned char *) l2;
20084 ++
20085 ++ i = lena - (num_longs * sizeof(unsigned long));
20086 ++
20087 ++ for (; i--; c1++, c2++) {
20088 ++ if (unlikely(*c1 != *c2))
20089 ++ return 0;
20090 ++ }
20091 ++
20092 ++ return 1;
20093 ++}
20094 ++
20095 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20096 ++ struct dentry *root, struct vfsmount *rootmnt,
20097 ++ char *buffer, int buflen)
20098 ++{
20099 ++ char * end = buffer+buflen;
20100 ++ char * retval;
20101 ++ int namelen;
20102 ++
20103 ++ *--end = '\0';
20104 ++ buflen--;
20105 ++
20106 ++ if (buflen < 1)
20107 ++ goto Elong;
20108 ++ /* Get '/' right */
20109 ++ retval = end-1;
20110 ++ *retval = '/';
20111 ++
20112 ++ for (;;) {
20113 ++ struct dentry * parent;
20114 ++
20115 ++ if (dentry == root && vfsmnt == rootmnt)
20116 ++ break;
20117 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
20118 ++ /* Global root? */
20119 ++ spin_lock(&vfsmount_lock);
20120 ++ if (vfsmnt->mnt_parent == vfsmnt) {
20121 ++ spin_unlock(&vfsmount_lock);
20122 ++ goto global_root;
20123 ++ }
20124 ++ dentry = vfsmnt->mnt_mountpoint;
20125 ++ vfsmnt = vfsmnt->mnt_parent;
20126 ++ spin_unlock(&vfsmount_lock);
20127 ++ continue;
20128 ++ }
20129 ++ parent = dentry->d_parent;
20130 ++ prefetch(parent);
20131 ++ namelen = dentry->d_name.len;
20132 ++ buflen -= namelen + 1;
20133 ++ if (buflen < 0)
20134 ++ goto Elong;
20135 ++ end -= namelen;
20136 ++ memcpy(end, dentry->d_name.name, namelen);
20137 ++ *--end = '/';
20138 ++ retval = end;
20139 ++ dentry = parent;
20140 ++ }
20141 ++
20142 ++ return retval;
20143 ++
20144 ++global_root:
20145 ++ namelen = dentry->d_name.len;
20146 ++ buflen -= namelen;
20147 ++ if (buflen < 0)
20148 ++ goto Elong;
20149 ++ retval -= namelen-1; /* hit the slash */
20150 ++ memcpy(retval, dentry->d_name.name, namelen);
20151 ++ return retval;
20152 ++Elong:
20153 ++ return ERR_PTR(-ENAMETOOLONG);
20154 ++}
20155 ++
20156 ++static char *
20157 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
20158 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
20159 ++{
20160 ++ char *retval;
20161 ++
20162 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
20163 ++ if (unlikely(IS_ERR(retval)))
20164 ++ retval = strcpy(buf, "<path too long>");
20165 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
20166 ++ retval[1] = '\0';
20167 ++
20168 ++ return retval;
20169 ++}
20170 ++
20171 ++static char *
20172 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20173 ++ char *buf, int buflen)
20174 ++{
20175 ++ char *res;
20176 ++
20177 ++ /* we can use real_root, real_root_mnt, because this is only called
20178 ++ by the RBAC system */
20179 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
20180 ++
20181 ++ return res;
20182 ++}
20183 ++
20184 ++static char *
20185 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
20186 ++ char *buf, int buflen)
20187 ++{
20188 ++ char *res;
20189 ++ struct dentry *root;
20190 ++ struct vfsmount *rootmnt;
20191 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
20192 ++
20193 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
20194 ++ read_lock(&reaper->fs->lock);
20195 ++ root = dget(reaper->fs->root.dentry);
20196 ++ rootmnt = mntget(reaper->fs->root.mnt);
20197 ++ read_unlock(&reaper->fs->lock);
20198 ++
20199 ++ spin_lock(&dcache_lock);
20200 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
20201 ++ spin_unlock(&dcache_lock);
20202 ++
20203 ++ dput(root);
20204 ++ mntput(rootmnt);
20205 ++ return res;
20206 ++}
20207 ++
20208 ++static char *
20209 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
20210 ++{
20211 ++ char *ret;
20212 ++ spin_lock(&dcache_lock);
20213 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20214 ++ PAGE_SIZE);
20215 ++ spin_unlock(&dcache_lock);
20216 ++ return ret;
20217 ++}
20218 ++
20219 ++char *
20220 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
20221 ++{
20222 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
20223 ++ PAGE_SIZE);
20224 ++}
20225 ++
20226 ++char *
20227 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
20228 ++{
20229 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
20230 ++ PAGE_SIZE);
20231 ++}
20232 ++
20233 ++char *
20234 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
20235 ++{
20236 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
20237 ++ PAGE_SIZE);
20238 ++}
20239 ++
20240 ++char *
20241 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
20242 ++{
20243 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
20244 ++ PAGE_SIZE);
20245 ++}
20246 ++
20247 ++char *
20248 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
20249 ++{
20250 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
20251 ++ PAGE_SIZE);
20252 ++}
20253 ++
20254 ++__inline__ __u32
20255 ++to_gr_audit(const __u32 reqmode)
20256 ++{
20257 ++ /* masks off auditable permission flags, then shifts them to create
20258 ++ auditing flags, and adds the special case of append auditing if
20259 ++ we're requesting write */
20260 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
20261 ++}
20262 ++
20263 ++struct acl_subject_label *
20264 ++lookup_subject_map(const struct acl_subject_label *userp)
20265 ++{
20266 ++ unsigned int index = shash(userp, subj_map_set.s_size);
20267 ++ struct subject_map *match;
20268 ++
20269 ++ match = subj_map_set.s_hash[index];
20270 ++
20271 ++ while (match && match->user != userp)
20272 ++ match = match->next;
20273 ++
20274 ++ if (match != NULL)
20275 ++ return match->kernel;
20276 ++ else
20277 ++ return NULL;
20278 ++}
20279 ++
20280 ++static void
20281 ++insert_subj_map_entry(struct subject_map *subjmap)
20282 ++{
20283 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
20284 ++ struct subject_map **curr;
20285 ++
20286 ++ subjmap->prev = NULL;
20287 ++
20288 ++ curr = &subj_map_set.s_hash[index];
20289 ++ if (*curr != NULL)
20290 ++ (*curr)->prev = subjmap;
20291 ++
20292 ++ subjmap->next = *curr;
20293 ++ *curr = subjmap;
20294 ++
20295 ++ return;
20296 ++}
20297 ++
20298 ++static struct acl_role_label *
20299 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
20300 ++ const gid_t gid)
20301 ++{
20302 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
20303 ++ struct acl_role_label *match;
20304 ++ struct role_allowed_ip *ipp;
20305 ++ unsigned int x;
20306 ++
20307 ++ match = acl_role_set.r_hash[index];
20308 ++
20309 ++ while (match) {
20310 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
20311 ++ for (x = 0; x < match->domain_child_num; x++) {
20312 ++ if (match->domain_children[x] == uid)
20313 ++ goto found;
20314 ++ }
20315 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
20316 ++ break;
20317 ++ match = match->next;
20318 ++ }
20319 ++found:
20320 ++ if (match == NULL) {
20321 ++ try_group:
20322 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
20323 ++ match = acl_role_set.r_hash[index];
20324 ++
20325 ++ while (match) {
20326 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
20327 ++ for (x = 0; x < match->domain_child_num; x++) {
20328 ++ if (match->domain_children[x] == gid)
20329 ++ goto found2;
20330 ++ }
20331 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
20332 ++ break;
20333 ++ match = match->next;
20334 ++ }
20335 ++found2:
20336 ++ if (match == NULL)
20337 ++ match = default_role;
20338 ++ if (match->allowed_ips == NULL)
20339 ++ return match;
20340 ++ else {
20341 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20342 ++ if (likely
20343 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20344 ++ (ntohl(ipp->addr) & ipp->netmask)))
20345 ++ return match;
20346 ++ }
20347 ++ match = default_role;
20348 ++ }
20349 ++ } else if (match->allowed_ips == NULL) {
20350 ++ return match;
20351 ++ } else {
20352 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
20353 ++ if (likely
20354 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
20355 ++ (ntohl(ipp->addr) & ipp->netmask)))
20356 ++ return match;
20357 ++ }
20358 ++ goto try_group;
20359 ++ }
20360 ++
20361 ++ return match;
20362 ++}
20363 ++
20364 ++struct acl_subject_label *
20365 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
20366 ++ const struct acl_role_label *role)
20367 ++{
20368 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
20369 ++ struct acl_subject_label *match;
20370 ++
20371 ++ match = role->subj_hash[index];
20372 ++
20373 ++ while (match && (match->inode != ino || match->device != dev ||
20374 ++ (match->mode & GR_DELETED))) {
20375 ++ match = match->next;
20376 ++ }
20377 ++
20378 ++ if (match && !(match->mode & GR_DELETED))
20379 ++ return match;
20380 ++ else
20381 ++ return NULL;
20382 ++}
20383 ++
20384 ++static struct acl_object_label *
20385 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
20386 ++ const struct acl_subject_label *subj)
20387 ++{
20388 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20389 ++ struct acl_object_label *match;
20390 ++
20391 ++ match = subj->obj_hash[index];
20392 ++
20393 ++ while (match && (match->inode != ino || match->device != dev ||
20394 ++ (match->mode & GR_DELETED))) {
20395 ++ match = match->next;
20396 ++ }
20397 ++
20398 ++ if (match && !(match->mode & GR_DELETED))
20399 ++ return match;
20400 ++ else
20401 ++ return NULL;
20402 ++}
20403 ++
20404 ++static struct acl_object_label *
20405 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
20406 ++ const struct acl_subject_label *subj)
20407 ++{
20408 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
20409 ++ struct acl_object_label *match;
20410 ++
20411 ++ match = subj->obj_hash[index];
20412 ++
20413 ++ while (match && (match->inode != ino || match->device != dev ||
20414 ++ !(match->mode & GR_DELETED))) {
20415 ++ match = match->next;
20416 ++ }
20417 ++
20418 ++ if (match && (match->mode & GR_DELETED))
20419 ++ return match;
20420 ++
20421 ++ match = subj->obj_hash[index];
20422 ++
20423 ++ while (match && (match->inode != ino || match->device != dev ||
20424 ++ (match->mode & GR_DELETED))) {
20425 ++ match = match->next;
20426 ++ }
20427 ++
20428 ++ if (match && !(match->mode & GR_DELETED))
20429 ++ return match;
20430 ++ else
20431 ++ return NULL;
20432 ++}
20433 ++
20434 ++static struct name_entry *
20435 ++lookup_name_entry(const char *name)
20436 ++{
20437 ++ unsigned int len = strlen(name);
20438 ++ unsigned int key = full_name_hash(name, len);
20439 ++ unsigned int index = key % name_set.n_size;
20440 ++ struct name_entry *match;
20441 ++
20442 ++ match = name_set.n_hash[index];
20443 ++
20444 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
20445 ++ match = match->next;
20446 ++
20447 ++ return match;
20448 ++}
20449 ++
20450 ++static struct name_entry *
20451 ++lookup_name_entry_create(const char *name)
20452 ++{
20453 ++ unsigned int len = strlen(name);
20454 ++ unsigned int key = full_name_hash(name, len);
20455 ++ unsigned int index = key % name_set.n_size;
20456 ++ struct name_entry *match;
20457 ++
20458 ++ match = name_set.n_hash[index];
20459 ++
20460 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20461 ++ !match->deleted))
20462 ++ match = match->next;
20463 ++
20464 ++ if (match && match->deleted)
20465 ++ return match;
20466 ++
20467 ++ match = name_set.n_hash[index];
20468 ++
20469 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
20470 ++ match->deleted))
20471 ++ match = match->next;
20472 ++
20473 ++ if (match && !match->deleted)
20474 ++ return match;
20475 ++ else
20476 ++ return NULL;
20477 ++}
20478 ++
20479 ++static struct inodev_entry *
20480 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
20481 ++{
20482 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
20483 ++ struct inodev_entry *match;
20484 ++
20485 ++ match = inodev_set.i_hash[index];
20486 ++
20487 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
20488 ++ match = match->next;
20489 ++
20490 ++ return match;
20491 ++}
20492 ++
20493 ++static void
20494 ++insert_inodev_entry(struct inodev_entry *entry)
20495 ++{
20496 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
20497 ++ inodev_set.i_size);
20498 ++ struct inodev_entry **curr;
20499 ++
20500 ++ entry->prev = NULL;
20501 ++
20502 ++ curr = &inodev_set.i_hash[index];
20503 ++ if (*curr != NULL)
20504 ++ (*curr)->prev = entry;
20505 ++
20506 ++ entry->next = *curr;
20507 ++ *curr = entry;
20508 ++
20509 ++ return;
20510 ++}
20511 ++
20512 ++static void
20513 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
20514 ++{
20515 ++ unsigned int index =
20516 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
20517 ++ struct acl_role_label **curr;
20518 ++
20519 ++ role->prev = NULL;
20520 ++
20521 ++ curr = &acl_role_set.r_hash[index];
20522 ++ if (*curr != NULL)
20523 ++ (*curr)->prev = role;
20524 ++
20525 ++ role->next = *curr;
20526 ++ *curr = role;
20527 ++
20528 ++ return;
20529 ++}
20530 ++
20531 ++static void
20532 ++insert_acl_role_label(struct acl_role_label *role)
20533 ++{
20534 ++ int i;
20535 ++
20536 ++ if (role->roletype & GR_ROLE_DOMAIN) {
20537 ++ for (i = 0; i < role->domain_child_num; i++)
20538 ++ __insert_acl_role_label(role, role->domain_children[i]);
20539 ++ } else
20540 ++ __insert_acl_role_label(role, role->uidgid);
20541 ++}
20542 ++
20543 ++static int
20544 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
20545 ++{
20546 ++ struct name_entry **curr, *nentry;
20547 ++ struct inodev_entry *ientry;
20548 ++ unsigned int len = strlen(name);
20549 ++ unsigned int key = full_name_hash(name, len);
20550 ++ unsigned int index = key % name_set.n_size;
20551 ++
20552 ++ curr = &name_set.n_hash[index];
20553 ++
20554 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
20555 ++ curr = &((*curr)->next);
20556 ++
20557 ++ if (*curr != NULL)
20558 ++ return 1;
20559 ++
20560 ++ nentry = acl_alloc(sizeof (struct name_entry));
20561 ++ if (nentry == NULL)
20562 ++ return 0;
20563 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
20564 ++ if (ientry == NULL)
20565 ++ return 0;
20566 ++ ientry->nentry = nentry;
20567 ++
20568 ++ nentry->key = key;
20569 ++ nentry->name = name;
20570 ++ nentry->inode = inode;
20571 ++ nentry->device = device;
20572 ++ nentry->len = len;
20573 ++ nentry->deleted = deleted;
20574 ++
20575 ++ nentry->prev = NULL;
20576 ++ curr = &name_set.n_hash[index];
20577 ++ if (*curr != NULL)
20578 ++ (*curr)->prev = nentry;
20579 ++ nentry->next = *curr;
20580 ++ *curr = nentry;
20581 ++
20582 ++ /* insert us into the table searchable by inode/dev */
20583 ++ insert_inodev_entry(ientry);
20584 ++
20585 ++ return 1;
20586 ++}
20587 ++
20588 ++static void
20589 ++insert_acl_obj_label(struct acl_object_label *obj,
20590 ++ struct acl_subject_label *subj)
20591 ++{
20592 ++ unsigned int index =
20593 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
20594 ++ struct acl_object_label **curr;
20595 ++
20596 ++
20597 ++ obj->prev = NULL;
20598 ++
20599 ++ curr = &subj->obj_hash[index];
20600 ++ if (*curr != NULL)
20601 ++ (*curr)->prev = obj;
20602 ++
20603 ++ obj->next = *curr;
20604 ++ *curr = obj;
20605 ++
20606 ++ return;
20607 ++}
20608 ++
20609 ++static void
20610 ++insert_acl_subj_label(struct acl_subject_label *obj,
20611 ++ struct acl_role_label *role)
20612 ++{
20613 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
20614 ++ struct acl_subject_label **curr;
20615 ++
20616 ++ obj->prev = NULL;
20617 ++
20618 ++ curr = &role->subj_hash[index];
20619 ++ if (*curr != NULL)
20620 ++ (*curr)->prev = obj;
20621 ++
20622 ++ obj->next = *curr;
20623 ++ *curr = obj;
20624 ++
20625 ++ return;
20626 ++}
20627 ++
20628 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
20629 ++
20630 ++static void *
20631 ++create_table(__u32 * len, int elementsize)
20632 ++{
20633 ++ unsigned int table_sizes[] = {
20634 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
20635 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
20636 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
20637 ++ 268435399, 536870909, 1073741789, 2147483647
20638 ++ };
20639 ++ void *newtable = NULL;
20640 ++ unsigned int pwr = 0;
20641 ++
20642 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
20643 ++ table_sizes[pwr] <= *len)
20644 ++ pwr++;
20645 ++
20646 ++ if (table_sizes[pwr] <= *len)
20647 ++ return newtable;
20648 ++
20649 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
20650 ++ newtable =
20651 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
20652 ++ else
20653 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
20654 ++
20655 ++ *len = table_sizes[pwr];
20656 ++
20657 ++ return newtable;
20658 ++}
20659 ++
20660 ++static int
20661 ++init_variables(const struct gr_arg *arg)
20662 ++{
20663 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
20664 ++ unsigned int stacksize;
20665 ++
20666 ++ subj_map_set.s_size = arg->role_db.num_subjects;
20667 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
20668 ++ name_set.n_size = arg->role_db.num_objects;
20669 ++ inodev_set.i_size = arg->role_db.num_objects;
20670 ++
20671 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
20672 ++ !name_set.n_size || !inodev_set.i_size)
20673 ++ return 1;
20674 ++
20675 ++ if (!gr_init_uidset())
20676 ++ return 1;
20677 ++
20678 ++ /* set up the stack that holds allocation info */
20679 ++
20680 ++ stacksize = arg->role_db.num_pointers + 5;
20681 ++
20682 ++ if (!acl_alloc_stack_init(stacksize))
20683 ++ return 1;
20684 ++
20685 ++ /* grab reference for the real root dentry and vfsmount */
20686 ++ read_lock(&reaper->fs->lock);
20687 ++ real_root_mnt = mntget(reaper->fs->root.mnt);
20688 ++ real_root = dget(reaper->fs->root.dentry);
20689 ++ read_unlock(&reaper->fs->lock);
20690 ++
20691 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
20692 ++ if (fakefs_obj == NULL)
20693 ++ return 1;
20694 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
20695 ++
20696 ++ subj_map_set.s_hash =
20697 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
20698 ++ acl_role_set.r_hash =
20699 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
20700 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
20701 ++ inodev_set.i_hash =
20702 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
20703 ++
20704 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
20705 ++ !name_set.n_hash || !inodev_set.i_hash)
20706 ++ return 1;
20707 ++
20708 ++ memset(subj_map_set.s_hash, 0,
20709 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
20710 ++ memset(acl_role_set.r_hash, 0,
20711 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
20712 ++ memset(name_set.n_hash, 0,
20713 ++ sizeof (struct name_entry *) * name_set.n_size);
20714 ++ memset(inodev_set.i_hash, 0,
20715 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
20716 ++
20717 ++ return 0;
20718 ++}
20719 ++
20720 ++/* free information not needed after startup
20721 ++ currently contains user->kernel pointer mappings for subjects
20722 ++*/
20723 ++
20724 ++static void
20725 ++free_init_variables(void)
20726 ++{
20727 ++ __u32 i;
20728 ++
20729 ++ if (subj_map_set.s_hash) {
20730 ++ for (i = 0; i < subj_map_set.s_size; i++) {
20731 ++ if (subj_map_set.s_hash[i]) {
20732 ++ kfree(subj_map_set.s_hash[i]);
20733 ++ subj_map_set.s_hash[i] = NULL;
20734 ++ }
20735 ++ }
20736 ++
20737 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
20738 ++ PAGE_SIZE)
20739 ++ kfree(subj_map_set.s_hash);
20740 ++ else
20741 ++ vfree(subj_map_set.s_hash);
20742 ++ }
20743 ++
20744 ++ return;
20745 ++}
20746 ++
20747 ++static void
20748 ++free_variables(void)
20749 ++{
20750 ++ struct acl_subject_label *s;
20751 ++ struct acl_role_label *r;
20752 ++ struct task_struct *task, *task2;
20753 ++ unsigned int i, x;
20754 ++
20755 ++ gr_clear_learn_entries();
20756 ++
20757 ++ read_lock(&tasklist_lock);
20758 ++ do_each_thread(task2, task) {
20759 ++ task->acl_sp_role = 0;
20760 ++ task->acl_role_id = 0;
20761 ++ task->acl = NULL;
20762 ++ task->role = NULL;
20763 ++ } while_each_thread(task2, task);
20764 ++ read_unlock(&tasklist_lock);
20765 ++
20766 ++ /* release the reference to the real root dentry and vfsmount */
20767 ++ if (real_root)
20768 ++ dput(real_root);
20769 ++ real_root = NULL;
20770 ++ if (real_root_mnt)
20771 ++ mntput(real_root_mnt);
20772 ++ real_root_mnt = NULL;
20773 ++
20774 ++ /* free all object hash tables */
20775 ++
20776 ++ FOR_EACH_ROLE_START(r, i)
20777 ++ if (r->subj_hash == NULL)
20778 ++ break;
20779 ++ FOR_EACH_SUBJECT_START(r, s, x)
20780 ++ if (s->obj_hash == NULL)
20781 ++ break;
20782 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
20783 ++ kfree(s->obj_hash);
20784 ++ else
20785 ++ vfree(s->obj_hash);
20786 ++ FOR_EACH_SUBJECT_END(s, x)
20787 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
20788 ++ if (s->obj_hash == NULL)
20789 ++ break;
20790 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
20791 ++ kfree(s->obj_hash);
20792 ++ else
20793 ++ vfree(s->obj_hash);
20794 ++ FOR_EACH_NESTED_SUBJECT_END(s)
20795 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
20796 ++ kfree(r->subj_hash);
20797 ++ else
20798 ++ vfree(r->subj_hash);
20799 ++ r->subj_hash = NULL;
20800 ++ FOR_EACH_ROLE_END(r,i)
20801 ++
20802 ++ acl_free_all();
20803 ++
20804 ++ if (acl_role_set.r_hash) {
20805 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
20806 ++ PAGE_SIZE)
20807 ++ kfree(acl_role_set.r_hash);
20808 ++ else
20809 ++ vfree(acl_role_set.r_hash);
20810 ++ }
20811 ++ if (name_set.n_hash) {
20812 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
20813 ++ PAGE_SIZE)
20814 ++ kfree(name_set.n_hash);
20815 ++ else
20816 ++ vfree(name_set.n_hash);
20817 ++ }
20818 ++
20819 ++ if (inodev_set.i_hash) {
20820 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
20821 ++ PAGE_SIZE)
20822 ++ kfree(inodev_set.i_hash);
20823 ++ else
20824 ++ vfree(inodev_set.i_hash);
20825 ++ }
20826 ++
20827 ++ gr_free_uidset();
20828 ++
20829 ++ memset(&name_set, 0, sizeof (struct name_db));
20830 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
20831 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
20832 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
20833 ++
20834 ++ default_role = NULL;
20835 ++
20836 ++ return;
20837 ++}
20838 ++
20839 ++static __u32
20840 ++count_user_objs(struct acl_object_label *userp)
20841 ++{
20842 ++ struct acl_object_label o_tmp;
20843 ++ __u32 num = 0;
20844 ++
20845 ++ while (userp) {
20846 ++ if (copy_from_user(&o_tmp, userp,
20847 ++ sizeof (struct acl_object_label)))
20848 ++ break;
20849 ++
20850 ++ userp = o_tmp.prev;
20851 ++ num++;
20852 ++ }
20853 ++
20854 ++ return num;
20855 ++}
20856 ++
20857 ++static struct acl_subject_label *
20858 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
20859 ++
20860 ++static int
20861 ++copy_user_glob(struct acl_object_label *obj)
20862 ++{
20863 ++ struct acl_object_label *g_tmp, **guser;
20864 ++ unsigned int len;
20865 ++ char *tmp;
20866 ++
20867 ++ if (obj->globbed == NULL)
20868 ++ return 0;
20869 ++
20870 ++ guser = &obj->globbed;
20871 ++ while (*guser) {
20872 ++ g_tmp = (struct acl_object_label *)
20873 ++ acl_alloc(sizeof (struct acl_object_label));
20874 ++ if (g_tmp == NULL)
20875 ++ return -ENOMEM;
20876 ++
20877 ++ if (copy_from_user(g_tmp, *guser,
20878 ++ sizeof (struct acl_object_label)))
20879 ++ return -EFAULT;
20880 ++
20881 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
20882 ++
20883 ++ if (!len || len >= PATH_MAX)
20884 ++ return -EINVAL;
20885 ++
20886 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
20887 ++ return -ENOMEM;
20888 ++
20889 ++ if (copy_from_user(tmp, g_tmp->filename, len))
20890 ++ return -EFAULT;
20891 ++
20892 ++ g_tmp->filename = tmp;
20893 ++
20894 ++ *guser = g_tmp;
20895 ++ guser = &(g_tmp->next);
20896 ++ }
20897 ++
20898 ++ return 0;
20899 ++}
20900 ++
20901 ++static int
20902 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
20903 ++ struct acl_role_label *role)
20904 ++{
20905 ++ struct acl_object_label *o_tmp;
20906 ++ unsigned int len;
20907 ++ int ret;
20908 ++ char *tmp;
20909 ++
20910 ++ while (userp) {
20911 ++ if ((o_tmp = (struct acl_object_label *)
20912 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
20913 ++ return -ENOMEM;
20914 ++
20915 ++ if (copy_from_user(o_tmp, userp,
20916 ++ sizeof (struct acl_object_label)))
20917 ++ return -EFAULT;
20918 ++
20919 ++ userp = o_tmp->prev;
20920 ++
20921 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
20922 ++
20923 ++ if (!len || len >= PATH_MAX)
20924 ++ return -EINVAL;
20925 ++
20926 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
20927 ++ return -ENOMEM;
20928 ++
20929 ++ if (copy_from_user(tmp, o_tmp->filename, len))
20930 ++ return -EFAULT;
20931 ++
20932 ++ o_tmp->filename = tmp;
20933 ++
20934 ++ insert_acl_obj_label(o_tmp, subj);
20935 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
20936 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
20937 ++ return -ENOMEM;
20938 ++
20939 ++ ret = copy_user_glob(o_tmp);
20940 ++ if (ret)
20941 ++ return ret;
20942 ++
20943 ++ if (o_tmp->nested) {
20944 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
20945 ++ if (IS_ERR(o_tmp->nested))
20946 ++ return PTR_ERR(o_tmp->nested);
20947 ++
20948 ++ /* insert into nested subject list */
20949 ++ o_tmp->nested->next = role->hash->first;
20950 ++ role->hash->first = o_tmp->nested;
20951 ++ }
20952 ++ }
20953 ++
20954 ++ return 0;
20955 ++}
20956 ++
20957 ++static __u32
20958 ++count_user_subjs(struct acl_subject_label *userp)
20959 ++{
20960 ++ struct acl_subject_label s_tmp;
20961 ++ __u32 num = 0;
20962 ++
20963 ++ while (userp) {
20964 ++ if (copy_from_user(&s_tmp, userp,
20965 ++ sizeof (struct acl_subject_label)))
20966 ++ break;
20967 ++
20968 ++ userp = s_tmp.prev;
20969 ++ /* do not count nested subjects against this count, since
20970 ++ they are not included in the hash table, but are
20971 ++ attached to objects. We have already counted
20972 ++ the subjects in userspace for the allocation
20973 ++ stack
20974 ++ */
20975 ++ if (!(s_tmp.mode & GR_NESTED))
20976 ++ num++;
20977 ++ }
20978 ++
20979 ++ return num;
20980 ++}
20981 ++
20982 ++static int
20983 ++copy_user_allowedips(struct acl_role_label *rolep)
20984 ++{
20985 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
20986 ++
20987 ++ ruserip = rolep->allowed_ips;
20988 ++
20989 ++ while (ruserip) {
20990 ++ rlast = rtmp;
20991 ++
20992 ++ if ((rtmp = (struct role_allowed_ip *)
20993 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
20994 ++ return -ENOMEM;
20995 ++
20996 ++ if (copy_from_user(rtmp, ruserip,
20997 ++ sizeof (struct role_allowed_ip)))
20998 ++ return -EFAULT;
20999 ++
21000 ++ ruserip = rtmp->prev;
21001 ++
21002 ++ if (!rlast) {
21003 ++ rtmp->prev = NULL;
21004 ++ rolep->allowed_ips = rtmp;
21005 ++ } else {
21006 ++ rlast->next = rtmp;
21007 ++ rtmp->prev = rlast;
21008 ++ }
21009 ++
21010 ++ if (!ruserip)
21011 ++ rtmp->next = NULL;
21012 ++ }
21013 ++
21014 ++ return 0;
21015 ++}
21016 ++
21017 ++static int
21018 ++copy_user_transitions(struct acl_role_label *rolep)
21019 ++{
21020 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
21021 ++
21022 ++ unsigned int len;
21023 ++ char *tmp;
21024 ++
21025 ++ rusertp = rolep->transitions;
21026 ++
21027 ++ while (rusertp) {
21028 ++ rlast = rtmp;
21029 ++
21030 ++ if ((rtmp = (struct role_transition *)
21031 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
21032 ++ return -ENOMEM;
21033 ++
21034 ++ if (copy_from_user(rtmp, rusertp,
21035 ++ sizeof (struct role_transition)))
21036 ++ return -EFAULT;
21037 ++
21038 ++ rusertp = rtmp->prev;
21039 ++
21040 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
21041 ++
21042 ++ if (!len || len >= GR_SPROLE_LEN)
21043 ++ return -EINVAL;
21044 ++
21045 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21046 ++ return -ENOMEM;
21047 ++
21048 ++ if (copy_from_user(tmp, rtmp->rolename, len))
21049 ++ return -EFAULT;
21050 ++
21051 ++ rtmp->rolename = tmp;
21052 ++
21053 ++ if (!rlast) {
21054 ++ rtmp->prev = NULL;
21055 ++ rolep->transitions = rtmp;
21056 ++ } else {
21057 ++ rlast->next = rtmp;
21058 ++ rtmp->prev = rlast;
21059 ++ }
21060 ++
21061 ++ if (!rusertp)
21062 ++ rtmp->next = NULL;
21063 ++ }
21064 ++
21065 ++ return 0;
21066 ++}
21067 ++
21068 ++static struct acl_subject_label *
21069 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
21070 ++{
21071 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
21072 ++ unsigned int len;
21073 ++ char *tmp;
21074 ++ __u32 num_objs;
21075 ++ struct acl_ip_label **i_tmp, *i_utmp2;
21076 ++ struct gr_hash_struct ghash;
21077 ++ struct subject_map *subjmap;
21078 ++ unsigned int i_num;
21079 ++ int err;
21080 ++
21081 ++ s_tmp = lookup_subject_map(userp);
21082 ++
21083 ++ /* we've already copied this subject into the kernel, just return
21084 ++ the reference to it, and don't copy it over again
21085 ++ */
21086 ++ if (s_tmp)
21087 ++ return(s_tmp);
21088 ++
21089 ++ if ((s_tmp = (struct acl_subject_label *)
21090 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
21091 ++ return ERR_PTR(-ENOMEM);
21092 ++
21093 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
21094 ++ if (subjmap == NULL)
21095 ++ return ERR_PTR(-ENOMEM);
21096 ++
21097 ++ subjmap->user = userp;
21098 ++ subjmap->kernel = s_tmp;
21099 ++ insert_subj_map_entry(subjmap);
21100 ++
21101 ++ if (copy_from_user(s_tmp, userp,
21102 ++ sizeof (struct acl_subject_label)))
21103 ++ return ERR_PTR(-EFAULT);
21104 ++
21105 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
21106 ++
21107 ++ if (!len || len >= PATH_MAX)
21108 ++ return ERR_PTR(-EINVAL);
21109 ++
21110 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
21111 ++ return ERR_PTR(-ENOMEM);
21112 ++
21113 ++ if (copy_from_user(tmp, s_tmp->filename, len))
21114 ++ return ERR_PTR(-EFAULT);
21115 ++
21116 ++ s_tmp->filename = tmp;
21117 ++
21118 ++ if (!strcmp(s_tmp->filename, "/"))
21119 ++ role->root_label = s_tmp;
21120 ++
21121 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
21122 ++ return ERR_PTR(-EFAULT);
21123 ++
21124 ++ /* copy user and group transition tables */
21125 ++
21126 ++ if (s_tmp->user_trans_num) {
21127 ++ uid_t *uidlist;
21128 ++
21129 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
21130 ++ if (uidlist == NULL)
21131 ++ return ERR_PTR(-ENOMEM);
21132 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
21133 ++ return ERR_PTR(-EFAULT);
21134 ++
21135 ++ s_tmp->user_transitions = uidlist;
21136 ++ }
21137 ++
21138 ++ if (s_tmp->group_trans_num) {
21139 ++ gid_t *gidlist;
21140 ++
21141 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
21142 ++ if (gidlist == NULL)
21143 ++ return ERR_PTR(-ENOMEM);
21144 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
21145 ++ return ERR_PTR(-EFAULT);
21146 ++
21147 ++ s_tmp->group_transitions = gidlist;
21148 ++ }
21149 ++
21150 ++ /* set up object hash table */
21151 ++ num_objs = count_user_objs(ghash.first);
21152 ++
21153 ++ s_tmp->obj_hash_size = num_objs;
21154 ++ s_tmp->obj_hash =
21155 ++ (struct acl_object_label **)
21156 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
21157 ++
21158 ++ if (!s_tmp->obj_hash)
21159 ++ return ERR_PTR(-ENOMEM);
21160 ++
21161 ++ memset(s_tmp->obj_hash, 0,
21162 ++ s_tmp->obj_hash_size *
21163 ++ sizeof (struct acl_object_label *));
21164 ++
21165 ++ /* add in objects */
21166 ++ err = copy_user_objs(ghash.first, s_tmp, role);
21167 ++
21168 ++ if (err)
21169 ++ return ERR_PTR(err);
21170 ++
21171 ++ /* set pointer for parent subject */
21172 ++ if (s_tmp->parent_subject) {
21173 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
21174 ++
21175 ++ if (IS_ERR(s_tmp2))
21176 ++ return s_tmp2;
21177 ++
21178 ++ s_tmp->parent_subject = s_tmp2;
21179 ++ }
21180 ++
21181 ++ /* add in ip acls */
21182 ++
21183 ++ if (!s_tmp->ip_num) {
21184 ++ s_tmp->ips = NULL;
21185 ++ goto insert;
21186 ++ }
21187 ++
21188 ++ i_tmp =
21189 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
21190 ++ sizeof (struct
21191 ++ acl_ip_label *));
21192 ++
21193 ++ if (!i_tmp)
21194 ++ return ERR_PTR(-ENOMEM);
21195 ++
21196 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
21197 ++ *(i_tmp + i_num) =
21198 ++ (struct acl_ip_label *)
21199 ++ acl_alloc(sizeof (struct acl_ip_label));
21200 ++ if (!*(i_tmp + i_num))
21201 ++ return ERR_PTR(-ENOMEM);
21202 ++
21203 ++ if (copy_from_user
21204 ++ (&i_utmp2, s_tmp->ips + i_num,
21205 ++ sizeof (struct acl_ip_label *)))
21206 ++ return ERR_PTR(-EFAULT);
21207 ++
21208 ++ if (copy_from_user
21209 ++ (*(i_tmp + i_num), i_utmp2,
21210 ++ sizeof (struct acl_ip_label)))
21211 ++ return ERR_PTR(-EFAULT);
21212 ++
21213 ++ if ((*(i_tmp + i_num))->iface == NULL)
21214 ++ continue;
21215 ++
21216 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
21217 ++ if (!len || len >= IFNAMSIZ)
21218 ++ return ERR_PTR(-EINVAL);
21219 ++ tmp = acl_alloc(len);
21220 ++ if (tmp == NULL)
21221 ++ return ERR_PTR(-ENOMEM);
21222 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
21223 ++ return ERR_PTR(-EFAULT);
21224 ++ (*(i_tmp + i_num))->iface = tmp;
21225 ++ }
21226 ++
21227 ++ s_tmp->ips = i_tmp;
21228 ++
21229 ++insert:
21230 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
21231 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
21232 ++ return ERR_PTR(-ENOMEM);
21233 ++
21234 ++ return s_tmp;
21235 ++}
21236 ++
21237 ++static int
21238 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
21239 ++{
21240 ++ struct acl_subject_label s_pre;
21241 ++ struct acl_subject_label * ret;
21242 ++ int err;
21243 ++
21244 ++ while (userp) {
21245 ++ if (copy_from_user(&s_pre, userp,
21246 ++ sizeof (struct acl_subject_label)))
21247 ++ return -EFAULT;
21248 ++
21249 ++ /* do not add nested subjects here, add
21250 ++ while parsing objects
21251 ++ */
21252 ++
21253 ++ if (s_pre.mode & GR_NESTED) {
21254 ++ userp = s_pre.prev;
21255 ++ continue;
21256 ++ }
21257 ++
21258 ++ ret = do_copy_user_subj(userp, role);
21259 ++
21260 ++ err = PTR_ERR(ret);
21261 ++ if (IS_ERR(ret))
21262 ++ return err;
21263 ++
21264 ++ insert_acl_subj_label(ret, role);
21265 ++
21266 ++ userp = s_pre.prev;
21267 ++ }
21268 ++
21269 ++ return 0;
21270 ++}
21271 ++
21272 ++static int
21273 ++copy_user_acl(struct gr_arg *arg)
21274 ++{
21275 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
21276 ++ struct sprole_pw *sptmp;
21277 ++ struct gr_hash_struct *ghash;
21278 ++ uid_t *domainlist;
21279 ++ unsigned int r_num;
21280 ++ unsigned int len;
21281 ++ char *tmp;
21282 ++ int err = 0;
21283 ++ __u16 i;
21284 ++ __u32 num_subjs;
21285 ++
21286 ++ /* we need a default and kernel role */
21287 ++ if (arg->role_db.num_roles < 2)
21288 ++ return -EINVAL;
21289 ++
21290 ++ /* copy special role authentication info from userspace */
21291 ++
21292 ++ num_sprole_pws = arg->num_sprole_pws;
21293 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
21294 ++
21295 ++ if (!acl_special_roles) {
21296 ++ err = -ENOMEM;
21297 ++ goto cleanup;
21298 ++ }
21299 ++
21300 ++ for (i = 0; i < num_sprole_pws; i++) {
21301 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
21302 ++ if (!sptmp) {
21303 ++ err = -ENOMEM;
21304 ++ goto cleanup;
21305 ++ }
21306 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
21307 ++ sizeof (struct sprole_pw))) {
21308 ++ err = -EFAULT;
21309 ++ goto cleanup;
21310 ++ }
21311 ++
21312 ++ len =
21313 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
21314 ++
21315 ++ if (!len || len >= GR_SPROLE_LEN) {
21316 ++ err = -EINVAL;
21317 ++ goto cleanup;
21318 ++ }
21319 ++
21320 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
21321 ++ err = -ENOMEM;
21322 ++ goto cleanup;
21323 ++ }
21324 ++
21325 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
21326 ++ err = -EFAULT;
21327 ++ goto cleanup;
21328 ++ }
21329 ++
21330 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
21331 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
21332 ++#endif
21333 ++ sptmp->rolename = tmp;
21334 ++ acl_special_roles[i] = sptmp;
21335 ++ }
21336 ++
21337 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
21338 ++
21339 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
21340 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
21341 ++
21342 ++ if (!r_tmp) {
21343 ++ err = -ENOMEM;
21344 ++ goto cleanup;
21345 ++ }
21346 ++
21347 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
21348 ++ sizeof (struct acl_role_label *))) {
21349 ++ err = -EFAULT;
21350 ++ goto cleanup;
21351 ++ }
21352 ++
21353 ++ if (copy_from_user(r_tmp, r_utmp2,
21354 ++ sizeof (struct acl_role_label))) {
21355 ++ err = -EFAULT;
21356 ++ goto cleanup;
21357 ++ }
21358 ++
21359 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
21360 ++
21361 ++ if (!len || len >= PATH_MAX) {
21362 ++ err = -EINVAL;
21363 ++ goto cleanup;
21364 ++ }
21365 ++
21366 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
21367 ++ err = -ENOMEM;
21368 ++ goto cleanup;
21369 ++ }
21370 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
21371 ++ err = -EFAULT;
21372 ++ goto cleanup;
21373 ++ }
21374 ++ r_tmp->rolename = tmp;
21375 ++
21376 ++ if (!strcmp(r_tmp->rolename, "default")
21377 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
21378 ++ default_role = r_tmp;
21379 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
21380 ++ kernel_role = r_tmp;
21381 ++ }
21382 ++
21383 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
21384 ++ err = -ENOMEM;
21385 ++ goto cleanup;
21386 ++ }
21387 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
21388 ++ err = -EFAULT;
21389 ++ goto cleanup;
21390 ++ }
21391 ++
21392 ++ r_tmp->hash = ghash;
21393 ++
21394 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
21395 ++
21396 ++ r_tmp->subj_hash_size = num_subjs;
21397 ++ r_tmp->subj_hash =
21398 ++ (struct acl_subject_label **)
21399 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
21400 ++
21401 ++ if (!r_tmp->subj_hash) {
21402 ++ err = -ENOMEM;
21403 ++ goto cleanup;
21404 ++ }
21405 ++
21406 ++ err = copy_user_allowedips(r_tmp);
21407 ++ if (err)
21408 ++ goto cleanup;
21409 ++
21410 ++ /* copy domain info */
21411 ++ if (r_tmp->domain_children != NULL) {
21412 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
21413 ++ if (domainlist == NULL) {
21414 ++ err = -ENOMEM;
21415 ++ goto cleanup;
21416 ++ }
21417 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
21418 ++ err = -EFAULT;
21419 ++ goto cleanup;
21420 ++ }
21421 ++ r_tmp->domain_children = domainlist;
21422 ++ }
21423 ++
21424 ++ err = copy_user_transitions(r_tmp);
21425 ++ if (err)
21426 ++ goto cleanup;
21427 ++
21428 ++ memset(r_tmp->subj_hash, 0,
21429 ++ r_tmp->subj_hash_size *
21430 ++ sizeof (struct acl_subject_label *));
21431 ++
21432 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
21433 ++
21434 ++ if (err)
21435 ++ goto cleanup;
21436 ++
21437 ++ /* set nested subject list to null */
21438 ++ r_tmp->hash->first = NULL;
21439 ++
21440 ++ insert_acl_role_label(r_tmp);
21441 ++ }
21442 ++
21443 ++ goto return_err;
21444 ++ cleanup:
21445 ++ free_variables();
21446 ++ return_err:
21447 ++ return err;
21448 ++
21449 ++}
21450 ++
21451 ++static int
21452 ++gracl_init(struct gr_arg *args)
21453 ++{
21454 ++ int error = 0;
21455 ++
21456 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
21457 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
21458 ++
21459 ++ if (init_variables(args)) {
21460 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
21461 ++ error = -ENOMEM;
21462 ++ free_variables();
21463 ++ goto out;
21464 ++ }
21465 ++
21466 ++ error = copy_user_acl(args);
21467 ++ free_init_variables();
21468 ++ if (error) {
21469 ++ free_variables();
21470 ++ goto out;
21471 ++ }
21472 ++
21473 ++ if ((error = gr_set_acls(0))) {
21474 ++ free_variables();
21475 ++ goto out;
21476 ++ }
21477 ++
21478 ++ gr_status |= GR_READY;
21479 ++ out:
21480 ++ return error;
21481 ++}
21482 ++
21483 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
21484 ++
21485 ++static int
21486 ++glob_match(const char *p, const char *n)
21487 ++{
21488 ++ char c;
21489 ++
21490 ++ while ((c = *p++) != '\0') {
21491 ++ switch (c) {
21492 ++ case '?':
21493 ++ if (*n == '\0')
21494 ++ return 1;
21495 ++ else if (*n == '/')
21496 ++ return 1;
21497 ++ break;
21498 ++ case '\\':
21499 ++ if (*n != c)
21500 ++ return 1;
21501 ++ break;
21502 ++ case '*':
21503 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
21504 ++ if (*n == '/')
21505 ++ return 1;
21506 ++ else if (c == '?') {
21507 ++ if (*n == '\0')
21508 ++ return 1;
21509 ++ else
21510 ++ ++n;
21511 ++ }
21512 ++ }
21513 ++ if (c == '\0') {
21514 ++ return 0;
21515 ++ } else {
21516 ++ const char *endp;
21517 ++
21518 ++ if ((endp = strchr(n, '/')) == NULL)
21519 ++ endp = n + strlen(n);
21520 ++
21521 ++ if (c == '[') {
21522 ++ for (--p; n < endp; ++n)
21523 ++ if (!glob_match(p, n))
21524 ++ return 0;
21525 ++ } else if (c == '/') {
21526 ++ while (*n != '\0' && *n != '/')
21527 ++ ++n;
21528 ++ if (*n == '/' && !glob_match(p, n + 1))
21529 ++ return 0;
21530 ++ } else {
21531 ++ for (--p; n < endp; ++n)
21532 ++ if (*n == c && !glob_match(p, n))
21533 ++ return 0;
21534 ++ }
21535 ++
21536 ++ return 1;
21537 ++ }
21538 ++ case '[':
21539 ++ {
21540 ++ int not;
21541 ++ char cold;
21542 ++
21543 ++ if (*n == '\0' || *n == '/')
21544 ++ return 1;
21545 ++
21546 ++ not = (*p == '!' || *p == '^');
21547 ++ if (not)
21548 ++ ++p;
21549 ++
21550 ++ c = *p++;
21551 ++ for (;;) {
21552 ++ unsigned char fn = (unsigned char)*n;
21553 ++
21554 ++ if (c == '\0')
21555 ++ return 1;
21556 ++ else {
21557 ++ if (c == fn)
21558 ++ goto matched;
21559 ++ cold = c;
21560 ++ c = *p++;
21561 ++
21562 ++ if (c == '-' && *p != ']') {
21563 ++ unsigned char cend = *p++;
21564 ++
21565 ++ if (cend == '\0')
21566 ++ return 1;
21567 ++
21568 ++ if (cold <= fn && fn <= cend)
21569 ++ goto matched;
21570 ++
21571 ++ c = *p++;
21572 ++ }
21573 ++ }
21574 ++
21575 ++ if (c == ']')
21576 ++ break;
21577 ++ }
21578 ++ if (!not)
21579 ++ return 1;
21580 ++ break;
21581 ++ matched:
21582 ++ while (c != ']') {
21583 ++ if (c == '\0')
21584 ++ return 1;
21585 ++
21586 ++ c = *p++;
21587 ++ }
21588 ++ if (not)
21589 ++ return 1;
21590 ++ }
21591 ++ break;
21592 ++ default:
21593 ++ if (c != *n)
21594 ++ return 1;
21595 ++ }
21596 ++
21597 ++ ++n;
21598 ++ }
21599 ++
21600 ++ if (*n == '\0')
21601 ++ return 0;
21602 ++
21603 ++ if (*n == '/')
21604 ++ return 0;
21605 ++
21606 ++ return 1;
21607 ++}
21608 ++
21609 ++static struct acl_object_label *
21610 ++chk_glob_label(struct acl_object_label *globbed,
21611 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
21612 ++{
21613 ++ struct acl_object_label *tmp;
21614 ++
21615 ++ if (*path == NULL)
21616 ++ *path = gr_to_filename_nolock(dentry, mnt);
21617 ++
21618 ++ tmp = globbed;
21619 ++
21620 ++ while (tmp) {
21621 ++ if (!glob_match(tmp->filename, *path))
21622 ++ return tmp;
21623 ++ tmp = tmp->next;
21624 ++ }
21625 ++
21626 ++ return NULL;
21627 ++}
21628 ++
21629 ++static struct acl_object_label *
21630 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
21631 ++ const ino_t curr_ino, const dev_t curr_dev,
21632 ++ const struct acl_subject_label *subj, char **path)
21633 ++{
21634 ++ struct acl_subject_label *tmpsubj;
21635 ++ struct acl_object_label *retval;
21636 ++ struct acl_object_label *retval2;
21637 ++
21638 ++ tmpsubj = (struct acl_subject_label *) subj;
21639 ++ read_lock(&gr_inode_lock);
21640 ++ do {
21641 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
21642 ++ if (retval) {
21643 ++ if (retval->globbed) {
21644 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
21645 ++ (struct vfsmount *)orig_mnt, path);
21646 ++ if (retval2)
21647 ++ retval = retval2;
21648 ++ }
21649 ++ break;
21650 ++ }
21651 ++ } while ((tmpsubj = tmpsubj->parent_subject));
21652 ++ read_unlock(&gr_inode_lock);
21653 ++
21654 ++ return retval;
21655 ++}
21656 ++
21657 ++static __inline__ struct acl_object_label *
21658 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
21659 ++ const struct dentry *curr_dentry,
21660 ++ const struct acl_subject_label *subj, char **path)
21661 ++{
21662 ++ return __full_lookup(orig_dentry, orig_mnt,
21663 ++ curr_dentry->d_inode->i_ino,
21664 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
21665 ++}
21666 ++
21667 ++static struct acl_object_label *
21668 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21669 ++ const struct acl_subject_label *subj, char *path)
21670 ++{
21671 ++ struct dentry *dentry = (struct dentry *) l_dentry;
21672 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
21673 ++ struct acl_object_label *retval;
21674 ++
21675 ++ spin_lock(&dcache_lock);
21676 ++
21677 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
21678 ++ /* ignore Eric Biederman */
21679 ++ IS_PRIVATE(l_dentry->d_inode))) {
21680 ++ retval = fakefs_obj;
21681 ++ goto out;
21682 ++ }
21683 ++
21684 ++ for (;;) {
21685 ++ if (dentry == real_root && mnt == real_root_mnt)
21686 ++ break;
21687 ++
21688 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
21689 ++ if (mnt->mnt_parent == mnt)
21690 ++ break;
21691 ++
21692 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
21693 ++ if (retval != NULL)
21694 ++ goto out;
21695 ++
21696 ++ dentry = mnt->mnt_mountpoint;
21697 ++ mnt = mnt->mnt_parent;
21698 ++ continue;
21699 ++ }
21700 ++
21701 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
21702 ++ if (retval != NULL)
21703 ++ goto out;
21704 ++
21705 ++ dentry = dentry->d_parent;
21706 ++ }
21707 ++
21708 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
21709 ++
21710 ++ if (retval == NULL)
21711 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
21712 ++out:
21713 ++ spin_unlock(&dcache_lock);
21714 ++ return retval;
21715 ++}
21716 ++
21717 ++static __inline__ struct acl_object_label *
21718 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21719 ++ const struct acl_subject_label *subj)
21720 ++{
21721 ++ char *path = NULL;
21722 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
21723 ++}
21724 ++
21725 ++static __inline__ struct acl_object_label *
21726 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21727 ++ const struct acl_subject_label *subj, char *path)
21728 ++{
21729 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
21730 ++}
21731 ++
21732 ++static struct acl_subject_label *
21733 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
21734 ++ const struct acl_role_label *role)
21735 ++{
21736 ++ struct dentry *dentry = (struct dentry *) l_dentry;
21737 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
21738 ++ struct acl_subject_label *retval;
21739 ++
21740 ++ spin_lock(&dcache_lock);
21741 ++
21742 ++ for (;;) {
21743 ++ if (dentry == real_root && mnt == real_root_mnt)
21744 ++ break;
21745 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
21746 ++ if (mnt->mnt_parent == mnt)
21747 ++ break;
21748 ++
21749 ++ read_lock(&gr_inode_lock);
21750 ++ retval =
21751 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
21752 ++ dentry->d_inode->i_sb->s_dev, role);
21753 ++ read_unlock(&gr_inode_lock);
21754 ++ if (retval != NULL)
21755 ++ goto out;
21756 ++
21757 ++ dentry = mnt->mnt_mountpoint;
21758 ++ mnt = mnt->mnt_parent;
21759 ++ continue;
21760 ++ }
21761 ++
21762 ++ read_lock(&gr_inode_lock);
21763 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
21764 ++ dentry->d_inode->i_sb->s_dev, role);
21765 ++ read_unlock(&gr_inode_lock);
21766 ++ if (retval != NULL)
21767 ++ goto out;
21768 ++
21769 ++ dentry = dentry->d_parent;
21770 ++ }
21771 ++
21772 ++ read_lock(&gr_inode_lock);
21773 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
21774 ++ dentry->d_inode->i_sb->s_dev, role);
21775 ++ read_unlock(&gr_inode_lock);
21776 ++
21777 ++ if (unlikely(retval == NULL)) {
21778 ++ read_lock(&gr_inode_lock);
21779 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
21780 ++ real_root->d_inode->i_sb->s_dev, role);
21781 ++ read_unlock(&gr_inode_lock);
21782 ++ }
21783 ++out:
21784 ++ spin_unlock(&dcache_lock);
21785 ++
21786 ++ return retval;
21787 ++}
21788 ++
21789 ++static void
21790 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
21791 ++{
21792 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
21793 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
21794 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
21795 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
21796 ++
21797 ++ return;
21798 ++}
21799 ++
21800 ++static void
21801 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
21802 ++{
21803 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
21804 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
21805 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
21806 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
21807 ++
21808 ++ return;
21809 ++}
21810 ++
21811 ++static void
21812 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
21813 ++ const unsigned int effective, const unsigned int fs)
21814 ++{
21815 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
21816 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
21817 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
21818 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
21819 ++
21820 ++ return;
21821 ++}
21822 ++
21823 ++__u32
21824 ++gr_check_link(const struct dentry * new_dentry,
21825 ++ const struct dentry * parent_dentry,
21826 ++ const struct vfsmount * parent_mnt,
21827 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
21828 ++{
21829 ++ struct acl_object_label *obj;
21830 ++ __u32 oldmode, newmode;
21831 ++ __u32 needmode;
21832 ++
21833 ++ if (unlikely(!(gr_status & GR_READY)))
21834 ++ return (GR_CREATE | GR_LINK);
21835 ++
21836 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
21837 ++ oldmode = obj->mode;
21838 ++
21839 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
21840 ++ oldmode |= (GR_CREATE | GR_LINK);
21841 ++
21842 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
21843 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
21844 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
21845 ++
21846 ++ newmode =
21847 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
21848 ++ oldmode | needmode);
21849 ++
21850 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
21851 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
21852 ++ GR_INHERIT | GR_AUDIT_INHERIT);
21853 ++
21854 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
21855 ++ goto bad;
21856 ++
21857 ++ if ((oldmode & needmode) != needmode)
21858 ++ goto bad;
21859 ++
21860 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
21861 ++ if ((newmode & needmode) != needmode)
21862 ++ goto bad;
21863 ++
21864 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
21865 ++ return newmode;
21866 ++bad:
21867 ++ needmode = oldmode;
21868 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
21869 ++ needmode |= GR_SETID;
21870 ++
21871 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
21872 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
21873 ++ return (GR_CREATE | GR_LINK);
21874 ++ } else if (newmode & GR_SUPPRESS)
21875 ++ return GR_SUPPRESS;
21876 ++ else
21877 ++ return 0;
21878 ++}
21879 ++
21880 ++__u32
21881 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
21882 ++ const struct vfsmount * mnt)
21883 ++{
21884 ++ __u32 retval = mode;
21885 ++ struct acl_subject_label *curracl;
21886 ++ struct acl_object_label *currobj;
21887 ++
21888 ++ if (unlikely(!(gr_status & GR_READY)))
21889 ++ return (mode & ~GR_AUDITS);
21890 ++
21891 ++ curracl = current->acl;
21892 ++
21893 ++ currobj = chk_obj_label(dentry, mnt, curracl);
21894 ++ retval = currobj->mode & mode;
21895 ++
21896 ++ if (unlikely
21897 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
21898 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
21899 ++ __u32 new_mode = mode;
21900 ++
21901 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21902 ++
21903 ++ retval = new_mode;
21904 ++
21905 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
21906 ++ new_mode |= GR_INHERIT;
21907 ++
21908 ++ if (!(mode & GR_NOLEARN))
21909 ++ gr_log_learn(current, dentry, mnt, new_mode);
21910 ++ }
21911 ++
21912 ++ return retval;
21913 ++}
21914 ++
21915 ++__u32
21916 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
21917 ++ const struct vfsmount * mnt, const __u32 mode)
21918 ++{
21919 ++ struct name_entry *match;
21920 ++ struct acl_object_label *matchpo;
21921 ++ struct acl_subject_label *curracl;
21922 ++ char *path;
21923 ++ __u32 retval;
21924 ++
21925 ++ if (unlikely(!(gr_status & GR_READY)))
21926 ++ return (mode & ~GR_AUDITS);
21927 ++
21928 ++ preempt_disable();
21929 ++ path = gr_to_filename_rbac(new_dentry, mnt);
21930 ++ match = lookup_name_entry_create(path);
21931 ++
21932 ++ if (!match)
21933 ++ goto check_parent;
21934 ++
21935 ++ curracl = current->acl;
21936 ++
21937 ++ read_lock(&gr_inode_lock);
21938 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
21939 ++ read_unlock(&gr_inode_lock);
21940 ++
21941 ++ if (matchpo) {
21942 ++ if ((matchpo->mode & mode) !=
21943 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
21944 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
21945 ++ __u32 new_mode = mode;
21946 ++
21947 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21948 ++
21949 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
21950 ++
21951 ++ preempt_enable();
21952 ++ return new_mode;
21953 ++ }
21954 ++ preempt_enable();
21955 ++ return (matchpo->mode & mode);
21956 ++ }
21957 ++
21958 ++ check_parent:
21959 ++ curracl = current->acl;
21960 ++
21961 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
21962 ++ retval = matchpo->mode & mode;
21963 ++
21964 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
21965 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
21966 ++ __u32 new_mode = mode;
21967 ++
21968 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21969 ++
21970 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
21971 ++ preempt_enable();
21972 ++ return new_mode;
21973 ++ }
21974 ++
21975 ++ preempt_enable();
21976 ++ return retval;
21977 ++}
21978 ++
21979 ++int
21980 ++gr_check_hidden_task(const struct task_struct *task)
21981 ++{
21982 ++ if (unlikely(!(gr_status & GR_READY)))
21983 ++ return 0;
21984 ++
21985 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
21986 ++ return 1;
21987 ++
21988 ++ return 0;
21989 ++}
21990 ++
21991 ++int
21992 ++gr_check_protected_task(const struct task_struct *task)
21993 ++{
21994 ++ if (unlikely(!(gr_status & GR_READY) || !task))
21995 ++ return 0;
21996 ++
21997 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
21998 ++ task->acl != current->acl)
21999 ++ return 1;
22000 ++
22001 ++ return 0;
22002 ++}
22003 ++
22004 ++void
22005 ++gr_copy_label(struct task_struct *tsk)
22006 ++{
22007 ++ tsk->signal->used_accept = 0;
22008 ++ tsk->acl_sp_role = 0;
22009 ++ tsk->acl_role_id = current->acl_role_id;
22010 ++ tsk->acl = current->acl;
22011 ++ tsk->role = current->role;
22012 ++ tsk->signal->curr_ip = current->signal->curr_ip;
22013 ++ if (current->exec_file)
22014 ++ get_file(current->exec_file);
22015 ++ tsk->exec_file = current->exec_file;
22016 ++ tsk->is_writable = current->is_writable;
22017 ++ if (unlikely(current->signal->used_accept))
22018 ++ current->signal->curr_ip = 0;
22019 ++
22020 ++ return;
22021 ++}
22022 ++
22023 ++static void
22024 ++gr_set_proc_res(struct task_struct *task)
22025 ++{
22026 ++ struct acl_subject_label *proc;
22027 ++ unsigned short i;
22028 ++
22029 ++ proc = task->acl;
22030 ++
22031 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
22032 ++ return;
22033 ++
22034 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
22035 ++ if (!(proc->resmask & (1 << i)))
22036 ++ continue;
22037 ++
22038 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
22039 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
22040 ++ }
22041 ++
22042 ++ return;
22043 ++}
22044 ++
22045 ++int
22046 ++gr_check_user_change(int real, int effective, int fs)
22047 ++{
22048 ++ unsigned int i;
22049 ++ __u16 num;
22050 ++ uid_t *uidlist;
22051 ++ int curuid;
22052 ++ int realok = 0;
22053 ++ int effectiveok = 0;
22054 ++ int fsok = 0;
22055 ++
22056 ++ if (unlikely(!(gr_status & GR_READY)))
22057 ++ return 0;
22058 ++
22059 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22060 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
22061 ++
22062 ++ num = current->acl->user_trans_num;
22063 ++ uidlist = current->acl->user_transitions;
22064 ++
22065 ++ if (uidlist == NULL)
22066 ++ return 0;
22067 ++
22068 ++ if (real == -1)
22069 ++ realok = 1;
22070 ++ if (effective == -1)
22071 ++ effectiveok = 1;
22072 ++ if (fs == -1)
22073 ++ fsok = 1;
22074 ++
22075 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
22076 ++ for (i = 0; i < num; i++) {
22077 ++ curuid = (int)uidlist[i];
22078 ++ if (real == curuid)
22079 ++ realok = 1;
22080 ++ if (effective == curuid)
22081 ++ effectiveok = 1;
22082 ++ if (fs == curuid)
22083 ++ fsok = 1;
22084 ++ }
22085 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
22086 ++ for (i = 0; i < num; i++) {
22087 ++ curuid = (int)uidlist[i];
22088 ++ if (real == curuid)
22089 ++ break;
22090 ++ if (effective == curuid)
22091 ++ break;
22092 ++ if (fs == curuid)
22093 ++ break;
22094 ++ }
22095 ++ /* not in deny list */
22096 ++ if (i == num) {
22097 ++ realok = 1;
22098 ++ effectiveok = 1;
22099 ++ fsok = 1;
22100 ++ }
22101 ++ }
22102 ++
22103 ++ if (realok && effectiveok && fsok)
22104 ++ return 0;
22105 ++ else {
22106 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22107 ++ return 1;
22108 ++ }
22109 ++}
22110 ++
22111 ++int
22112 ++gr_check_group_change(int real, int effective, int fs)
22113 ++{
22114 ++ unsigned int i;
22115 ++ __u16 num;
22116 ++ gid_t *gidlist;
22117 ++ int curgid;
22118 ++ int realok = 0;
22119 ++ int effectiveok = 0;
22120 ++ int fsok = 0;
22121 ++
22122 ++ if (unlikely(!(gr_status & GR_READY)))
22123 ++ return 0;
22124 ++
22125 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
22126 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
22127 ++
22128 ++ num = current->acl->group_trans_num;
22129 ++ gidlist = current->acl->group_transitions;
22130 ++
22131 ++ if (gidlist == NULL)
22132 ++ return 0;
22133 ++
22134 ++ if (real == -1)
22135 ++ realok = 1;
22136 ++ if (effective == -1)
22137 ++ effectiveok = 1;
22138 ++ if (fs == -1)
22139 ++ fsok = 1;
22140 ++
22141 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
22142 ++ for (i = 0; i < num; i++) {
22143 ++ curgid = (int)gidlist[i];
22144 ++ if (real == curgid)
22145 ++ realok = 1;
22146 ++ if (effective == curgid)
22147 ++ effectiveok = 1;
22148 ++ if (fs == curgid)
22149 ++ fsok = 1;
22150 ++ }
22151 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
22152 ++ for (i = 0; i < num; i++) {
22153 ++ curgid = (int)gidlist[i];
22154 ++ if (real == curgid)
22155 ++ break;
22156 ++ if (effective == curgid)
22157 ++ break;
22158 ++ if (fs == curgid)
22159 ++ break;
22160 ++ }
22161 ++ /* not in deny list */
22162 ++ if (i == num) {
22163 ++ realok = 1;
22164 ++ effectiveok = 1;
22165 ++ fsok = 1;
22166 ++ }
22167 ++ }
22168 ++
22169 ++ if (realok && effectiveok && fsok)
22170 ++ return 0;
22171 ++ else {
22172 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
22173 ++ return 1;
22174 ++ }
22175 ++}
22176 ++
22177 ++void
22178 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
22179 ++{
22180 ++ struct acl_role_label *role = task->role;
22181 ++ struct acl_subject_label *subj = NULL;
22182 ++ struct acl_object_label *obj;
22183 ++ struct file *filp;
22184 ++
22185 ++ if (unlikely(!(gr_status & GR_READY)))
22186 ++ return;
22187 ++
22188 ++ filp = task->exec_file;
22189 ++
22190 ++ /* kernel process, we'll give them the kernel role */
22191 ++ if (unlikely(!filp)) {
22192 ++ task->role = kernel_role;
22193 ++ task->acl = kernel_role->root_label;
22194 ++ return;
22195 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
22196 ++ role = lookup_acl_role_label(task, uid, gid);
22197 ++
22198 ++ /* perform subject lookup in possibly new role
22199 ++ we can use this result below in the case where role == task->role
22200 ++ */
22201 ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
22202 ++
22203 ++ /* if we changed uid/gid, but result in the same role
22204 ++ and are using inheritance, don't lose the inherited subject
22205 ++ if current subject is other than what normal lookup
22206 ++ would result in, we arrived via inheritance, don't
22207 ++ lose subject
22208 ++ */
22209 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
22210 ++ (subj == task->acl)))
22211 ++ task->acl = subj;
22212 ++
22213 ++ task->role = role;
22214 ++
22215 ++ task->is_writable = 0;
22216 ++
22217 ++ /* ignore additional mmap checks for processes that are writable
22218 ++ by the default ACL */
22219 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
22220 ++ if (unlikely(obj->mode & GR_WRITE))
22221 ++ task->is_writable = 1;
22222 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
22223 ++ if (unlikely(obj->mode & GR_WRITE))
22224 ++ task->is_writable = 1;
22225 ++
22226 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22227 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22228 ++#endif
22229 ++
22230 ++ gr_set_proc_res(task);
22231 ++
22232 ++ return;
22233 ++}
22234 ++
22235 ++int
22236 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
22237 ++{
22238 ++ struct task_struct *task = current;
22239 ++ struct acl_subject_label *newacl;
22240 ++ struct acl_object_label *obj;
22241 ++ __u32 retmode;
22242 ++
22243 ++ if (unlikely(!(gr_status & GR_READY)))
22244 ++ return 0;
22245 ++
22246 ++ newacl = chk_subj_label(dentry, mnt, task->role);
22247 ++
22248 ++ task_lock(task);
22249 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
22250 ++ GR_POVERRIDE) && (task->acl != newacl) &&
22251 ++ !(task->role->roletype & GR_ROLE_GOD) &&
22252 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
22253 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
22254 ++ (atomic_read(&task->fs->count) > 1 ||
22255 ++ atomic_read(&task->files->count) > 1 ||
22256 ++ atomic_read(&task->sighand->count) > 1)) {
22257 ++ task_unlock(task);
22258 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
22259 ++ return -EACCES;
22260 ++ }
22261 ++ task_unlock(task);
22262 ++
22263 ++ obj = chk_obj_label(dentry, mnt, task->acl);
22264 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
22265 ++
22266 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
22267 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
22268 ++ if (obj->nested)
22269 ++ task->acl = obj->nested;
22270 ++ else
22271 ++ task->acl = newacl;
22272 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
22273 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
22274 ++
22275 ++ task->is_writable = 0;
22276 ++
22277 ++ /* ignore additional mmap checks for processes that are writable
22278 ++ by the default ACL */
22279 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
22280 ++ if (unlikely(obj->mode & GR_WRITE))
22281 ++ task->is_writable = 1;
22282 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
22283 ++ if (unlikely(obj->mode & GR_WRITE))
22284 ++ task->is_writable = 1;
22285 ++
22286 ++ gr_set_proc_res(task);
22287 ++
22288 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22289 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
22290 ++#endif
22291 ++ return 0;
22292 ++}
22293 ++
22294 ++/* always called with valid inodev ptr */
22295 ++static void
22296 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
22297 ++{
22298 ++ struct acl_object_label *matchpo;
22299 ++ struct acl_subject_label *matchps;
22300 ++ struct acl_subject_label *subj;
22301 ++ struct acl_role_label *role;
22302 ++ unsigned int i, x;
22303 ++
22304 ++ FOR_EACH_ROLE_START(role, i)
22305 ++ FOR_EACH_SUBJECT_START(role, subj, x)
22306 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
22307 ++ matchpo->mode |= GR_DELETED;
22308 ++ FOR_EACH_SUBJECT_END(subj,x)
22309 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
22310 ++ if (subj->inode == ino && subj->device == dev)
22311 ++ subj->mode |= GR_DELETED;
22312 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
22313 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
22314 ++ matchps->mode |= GR_DELETED;
22315 ++ FOR_EACH_ROLE_END(role,i)
22316 ++
22317 ++ inodev->nentry->deleted = 1;
22318 ++
22319 ++ return;
22320 ++}
22321 ++
22322 ++void
22323 ++gr_handle_delete(const ino_t ino, const dev_t dev)
22324 ++{
22325 ++ struct inodev_entry *inodev;
22326 ++
22327 ++ if (unlikely(!(gr_status & GR_READY)))
22328 ++ return;
22329 ++
22330 ++ write_lock(&gr_inode_lock);
22331 ++ inodev = lookup_inodev_entry(ino, dev);
22332 ++ if (inodev != NULL)
22333 ++ do_handle_delete(inodev, ino, dev);
22334 ++ write_unlock(&gr_inode_lock);
22335 ++
22336 ++ return;
22337 ++}
22338 ++
22339 ++static void
22340 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
22341 ++ const ino_t newinode, const dev_t newdevice,
22342 ++ struct acl_subject_label *subj)
22343 ++{
22344 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
22345 ++ struct acl_object_label *match;
22346 ++
22347 ++ match = subj->obj_hash[index];
22348 ++
22349 ++ while (match && (match->inode != oldinode ||
22350 ++ match->device != olddevice ||
22351 ++ !(match->mode & GR_DELETED)))
22352 ++ match = match->next;
22353 ++
22354 ++ if (match && (match->inode == oldinode)
22355 ++ && (match->device == olddevice)
22356 ++ && (match->mode & GR_DELETED)) {
22357 ++ if (match->prev == NULL) {
22358 ++ subj->obj_hash[index] = match->next;
22359 ++ if (match->next != NULL)
22360 ++ match->next->prev = NULL;
22361 ++ } else {
22362 ++ match->prev->next = match->next;
22363 ++ if (match->next != NULL)
22364 ++ match->next->prev = match->prev;
22365 ++ }
22366 ++ match->prev = NULL;
22367 ++ match->next = NULL;
22368 ++ match->inode = newinode;
22369 ++ match->device = newdevice;
22370 ++ match->mode &= ~GR_DELETED;
22371 ++
22372 ++ insert_acl_obj_label(match, subj);
22373 ++ }
22374 ++
22375 ++ return;
22376 ++}
22377 ++
22378 ++static void
22379 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
22380 ++ const ino_t newinode, const dev_t newdevice,
22381 ++ struct acl_role_label *role)
22382 ++{
22383 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
22384 ++ struct acl_subject_label *match;
22385 ++
22386 ++ match = role->subj_hash[index];
22387 ++
22388 ++ while (match && (match->inode != oldinode ||
22389 ++ match->device != olddevice ||
22390 ++ !(match->mode & GR_DELETED)))
22391 ++ match = match->next;
22392 ++
22393 ++ if (match && (match->inode == oldinode)
22394 ++ && (match->device == olddevice)
22395 ++ && (match->mode & GR_DELETED)) {
22396 ++ if (match->prev == NULL) {
22397 ++ role->subj_hash[index] = match->next;
22398 ++ if (match->next != NULL)
22399 ++ match->next->prev = NULL;
22400 ++ } else {
22401 ++ match->prev->next = match->next;
22402 ++ if (match->next != NULL)
22403 ++ match->next->prev = match->prev;
22404 ++ }
22405 ++ match->prev = NULL;
22406 ++ match->next = NULL;
22407 ++ match->inode = newinode;
22408 ++ match->device = newdevice;
22409 ++ match->mode &= ~GR_DELETED;
22410 ++
22411 ++ insert_acl_subj_label(match, role);
22412 ++ }
22413 ++
22414 ++ return;
22415 ++}
22416 ++
22417 ++static void
22418 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
22419 ++ const ino_t newinode, const dev_t newdevice)
22420 ++{
22421 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
22422 ++ struct inodev_entry *match;
22423 ++
22424 ++ match = inodev_set.i_hash[index];
22425 ++
22426 ++ while (match && (match->nentry->inode != oldinode ||
22427 ++ match->nentry->device != olddevice || !match->nentry->deleted))
22428 ++ match = match->next;
22429 ++
22430 ++ if (match && (match->nentry->inode == oldinode)
22431 ++ && (match->nentry->device == olddevice) &&
22432 ++ match->nentry->deleted) {
22433 ++ if (match->prev == NULL) {
22434 ++ inodev_set.i_hash[index] = match->next;
22435 ++ if (match->next != NULL)
22436 ++ match->next->prev = NULL;
22437 ++ } else {
22438 ++ match->prev->next = match->next;
22439 ++ if (match->next != NULL)
22440 ++ match->next->prev = match->prev;
22441 ++ }
22442 ++ match->prev = NULL;
22443 ++ match->next = NULL;
22444 ++ match->nentry->inode = newinode;
22445 ++ match->nentry->device = newdevice;
22446 ++ match->nentry->deleted = 0;
22447 ++
22448 ++ insert_inodev_entry(match);
22449 ++ }
22450 ++
22451 ++ return;
22452 ++}
22453 ++
22454 ++static void
22455 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
22456 ++ const struct vfsmount *mnt)
22457 ++{
22458 ++ struct acl_subject_label *subj;
22459 ++ struct acl_role_label *role;
22460 ++ unsigned int i, x;
22461 ++
22462 ++ FOR_EACH_ROLE_START(role, i)
22463 ++ update_acl_subj_label(matchn->inode, matchn->device,
22464 ++ dentry->d_inode->i_ino,
22465 ++ dentry->d_inode->i_sb->s_dev, role);
22466 ++
22467 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
22468 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
22469 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
22470 ++ subj->inode = dentry->d_inode->i_ino;
22471 ++ subj->device = dentry->d_inode->i_sb->s_dev;
22472 ++ }
22473 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
22474 ++ FOR_EACH_SUBJECT_START(role, subj, x)
22475 ++ update_acl_obj_label(matchn->inode, matchn->device,
22476 ++ dentry->d_inode->i_ino,
22477 ++ dentry->d_inode->i_sb->s_dev, subj);
22478 ++ FOR_EACH_SUBJECT_END(subj,x)
22479 ++ FOR_EACH_ROLE_END(role,i)
22480 ++
22481 ++ update_inodev_entry(matchn->inode, matchn->device,
22482 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
22483 ++
22484 ++ return;
22485 ++}
22486 ++
22487 ++void
22488 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
22489 ++{
22490 ++ struct name_entry *matchn;
22491 ++
22492 ++ if (unlikely(!(gr_status & GR_READY)))
22493 ++ return;
22494 ++
22495 ++ preempt_disable();
22496 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
22497 ++
22498 ++ if (unlikely((unsigned long)matchn)) {
22499 ++ write_lock(&gr_inode_lock);
22500 ++ do_handle_create(matchn, dentry, mnt);
22501 ++ write_unlock(&gr_inode_lock);
22502 ++ }
22503 ++ preempt_enable();
22504 ++
22505 ++ return;
22506 ++}
22507 ++
22508 ++void
22509 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
22510 ++ struct dentry *old_dentry,
22511 ++ struct dentry *new_dentry,
22512 ++ struct vfsmount *mnt, const __u8 replace)
22513 ++{
22514 ++ struct name_entry *matchn;
22515 ++ struct inodev_entry *inodev;
22516 ++
22517 ++ /* vfs_rename swaps the name and parent link for old_dentry and
22518 ++ new_dentry
22519 ++ at this point, old_dentry has the new name, parent link, and inode
22520 ++ for the renamed file
22521 ++ if a file is being replaced by a rename, new_dentry has the inode
22522 ++ and name for the replaced file
22523 ++ */
22524 ++
22525 ++ if (unlikely(!(gr_status & GR_READY)))
22526 ++ return;
22527 ++
22528 ++ preempt_disable();
22529 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
22530 ++
22531 ++ /* we wouldn't have to check d_inode if it weren't for
22532 ++ NFS silly-renaming
22533 ++ */
22534 ++
22535 ++ write_lock(&gr_inode_lock);
22536 ++ if (unlikely(replace && new_dentry->d_inode)) {
22537 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
22538 ++ new_dentry->d_inode->i_sb->s_dev);
22539 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
22540 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
22541 ++ new_dentry->d_inode->i_sb->s_dev);
22542 ++ }
22543 ++
22544 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
22545 ++ old_dentry->d_inode->i_sb->s_dev);
22546 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
22547 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
22548 ++ old_dentry->d_inode->i_sb->s_dev);
22549 ++
22550 ++ if (unlikely((unsigned long)matchn))
22551 ++ do_handle_create(matchn, old_dentry, mnt);
22552 ++
22553 ++ write_unlock(&gr_inode_lock);
22554 ++ preempt_enable();
22555 ++
22556 ++ return;
22557 ++}
22558 ++
22559 ++static int
22560 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
22561 ++ unsigned char **sum)
22562 ++{
22563 ++ struct acl_role_label *r;
22564 ++ struct role_allowed_ip *ipp;
22565 ++ struct role_transition *trans;
22566 ++ unsigned int i;
22567 ++ int found = 0;
22568 ++
22569 ++ /* check transition table */
22570 ++
22571 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
22572 ++ if (!strcmp(rolename, trans->rolename)) {
22573 ++ found = 1;
22574 ++ break;
22575 ++ }
22576 ++ }
22577 ++
22578 ++ if (!found)
22579 ++ return 0;
22580 ++
22581 ++ /* handle special roles that do not require authentication
22582 ++ and check ip */
22583 ++
22584 ++ FOR_EACH_ROLE_START(r, i)
22585 ++ if (!strcmp(rolename, r->rolename) &&
22586 ++ (r->roletype & GR_ROLE_SPECIAL)) {
22587 ++ found = 0;
22588 ++ if (r->allowed_ips != NULL) {
22589 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
22590 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
22591 ++ (ntohl(ipp->addr) & ipp->netmask))
22592 ++ found = 1;
22593 ++ }
22594 ++ } else
22595 ++ found = 2;
22596 ++ if (!found)
22597 ++ return 0;
22598 ++
22599 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
22600 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
22601 ++ *salt = NULL;
22602 ++ *sum = NULL;
22603 ++ return 1;
22604 ++ }
22605 ++ }
22606 ++ FOR_EACH_ROLE_END(r,i)
22607 ++
22608 ++ for (i = 0; i < num_sprole_pws; i++) {
22609 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
22610 ++ *salt = acl_special_roles[i]->salt;
22611 ++ *sum = acl_special_roles[i]->sum;
22612 ++ return 1;
22613 ++ }
22614 ++ }
22615 ++
22616 ++ return 0;
22617 ++}
22618 ++
22619 ++static void
22620 ++assign_special_role(char *rolename)
22621 ++{
22622 ++ struct acl_object_label *obj;
22623 ++ struct acl_role_label *r;
22624 ++ struct acl_role_label *assigned = NULL;
22625 ++ struct task_struct *tsk;
22626 ++ struct file *filp;
22627 ++ unsigned int i;
22628 ++
22629 ++ FOR_EACH_ROLE_START(r, i)
22630 ++ if (!strcmp(rolename, r->rolename) &&
22631 ++ (r->roletype & GR_ROLE_SPECIAL))
22632 ++ assigned = r;
22633 ++ FOR_EACH_ROLE_END(r,i)
22634 ++
22635 ++ if (!assigned)
22636 ++ return;
22637 ++
22638 ++ read_lock(&tasklist_lock);
22639 ++ read_lock(&grsec_exec_file_lock);
22640 ++
22641 ++ tsk = current->parent;
22642 ++ if (tsk == NULL)
22643 ++ goto out_unlock;
22644 ++
22645 ++ filp = tsk->exec_file;
22646 ++ if (filp == NULL)
22647 ++ goto out_unlock;
22648 ++
22649 ++ tsk->is_writable = 0;
22650 ++
22651 ++ tsk->acl_sp_role = 1;
22652 ++ tsk->acl_role_id = ++acl_sp_role_value;
22653 ++ tsk->role = assigned;
22654 ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
22655 ++
22656 ++ /* ignore additional mmap checks for processes that are writable
22657 ++ by the default ACL */
22658 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
22659 ++ if (unlikely(obj->mode & GR_WRITE))
22660 ++ tsk->is_writable = 1;
22661 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
22662 ++ if (unlikely(obj->mode & GR_WRITE))
22663 ++ tsk->is_writable = 1;
22664 ++
22665 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
22666 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
22667 ++#endif
22668 ++
22669 ++out_unlock:
22670 ++ read_unlock(&grsec_exec_file_lock);
22671 ++ read_unlock(&tasklist_lock);
22672 ++ return;
22673 ++}
22674 ++
22675 ++int gr_check_secure_terminal(struct task_struct *task)
22676 ++{
22677 ++ struct task_struct *p, *p2, *p3;
22678 ++ struct files_struct *files;
22679 ++ struct fdtable *fdt;
22680 ++ struct file *our_file = NULL, *file;
22681 ++ int i;
22682 ++
22683 ++ if (task->signal->tty == NULL)
22684 ++ return 1;
22685 ++
22686 ++ files = get_files_struct(task);
22687 ++ if (files != NULL) {
22688 ++ rcu_read_lock();
22689 ++ fdt = files_fdtable(files);
22690 ++ for (i=0; i < fdt->max_fds; i++) {
22691 ++ file = fcheck_files(files, i);
22692 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
22693 ++ get_file(file);
22694 ++ our_file = file;
22695 ++ }
22696 ++ }
22697 ++ rcu_read_unlock();
22698 ++ put_files_struct(files);
22699 ++ }
22700 ++
22701 ++ if (our_file == NULL)
22702 ++ return 1;
22703 ++
22704 ++ read_lock(&tasklist_lock);
22705 ++ do_each_thread(p2, p) {
22706 ++ files = get_files_struct(p);
22707 ++ if (files == NULL ||
22708 ++ (p->signal && p->signal->tty == task->signal->tty)) {
22709 ++ if (files != NULL)
22710 ++ put_files_struct(files);
22711 ++ continue;
22712 ++ }
22713 ++ rcu_read_lock();
22714 ++ fdt = files_fdtable(files);
22715 ++ for (i=0; i < fdt->max_fds; i++) {
22716 ++ file = fcheck_files(files, i);
22717 ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
22718 ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
22719 ++ p3 = task;
22720 ++ while (p3->pid > 0) {
22721 ++ if (p3 == p)
22722 ++ break;
22723 ++ p3 = p3->parent;
22724 ++ }
22725 ++ if (p3 == p)
22726 ++ break;
22727 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
22728 ++ gr_handle_alertkill(p);
22729 ++ rcu_read_unlock();
22730 ++ put_files_struct(files);
22731 ++ read_unlock(&tasklist_lock);
22732 ++ fput(our_file);
22733 ++ return 0;
22734 ++ }
22735 ++ }
22736 ++ rcu_read_unlock();
22737 ++ put_files_struct(files);
22738 ++ } while_each_thread(p2, p);
22739 ++ read_unlock(&tasklist_lock);
22740 ++
22741 ++ fput(our_file);
22742 ++ return 1;
22743 ++}
22744 ++
22745 ++ssize_t
22746 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
22747 ++{
22748 ++ struct gr_arg_wrapper uwrap;
22749 ++ unsigned char *sprole_salt;
22750 ++ unsigned char *sprole_sum;
22751 ++ int error = sizeof (struct gr_arg_wrapper);
22752 ++ int error2 = 0;
22753 ++
22754 ++ down(&gr_dev_sem);
22755 ++
22756 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
22757 ++ error = -EPERM;
22758 ++ goto out;
22759 ++ }
22760 ++
22761 ++ if (count != sizeof (struct gr_arg_wrapper)) {
22762 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
22763 ++ error = -EINVAL;
22764 ++ goto out;
22765 ++ }
22766 ++
22767 ++
22768 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
22769 ++ gr_auth_expires = 0;
22770 ++ gr_auth_attempts = 0;
22771 ++ }
22772 ++
22773 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
22774 ++ error = -EFAULT;
22775 ++ goto out;
22776 ++ }
22777 ++
22778 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
22779 ++ error = -EINVAL;
22780 ++ goto out;
22781 ++ }
22782 ++
22783 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
22784 ++ error = -EFAULT;
22785 ++ goto out;
22786 ++ }
22787 ++
22788 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
22789 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
22790 ++ time_after(gr_auth_expires, get_seconds())) {
22791 ++ error = -EBUSY;
22792 ++ goto out;
22793 ++ }
22794 ++
22795 ++ /* if non-root trying to do anything other than use a special role,
22796 ++ do not attempt authentication, do not count towards authentication
22797 ++ locking
22798 ++ */
22799 ++
22800 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
22801 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
22802 ++ current->uid) {
22803 ++ error = -EPERM;
22804 ++ goto out;
22805 ++ }
22806 ++
22807 ++ /* ensure pw and special role name are null terminated */
22808 ++
22809 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
22810 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
22811 ++
22812 ++ /* Okay.
22813 ++ * We have our enough of the argument structure..(we have yet
22814 ++ * to copy_from_user the tables themselves) . Copy the tables
22815 ++ * only if we need them, i.e. for loading operations. */
22816 ++
22817 ++ switch (gr_usermode->mode) {
22818 ++ case STATUS:
22819 ++ if (gr_status & GR_READY) {
22820 ++ error = 1;
22821 ++ if (!gr_check_secure_terminal(current))
22822 ++ error = 3;
22823 ++ } else
22824 ++ error = 2;
22825 ++ goto out;
22826 ++ case SHUTDOWN:
22827 ++ if ((gr_status & GR_READY)
22828 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
22829 ++ gr_status &= ~GR_READY;
22830 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
22831 ++ free_variables();
22832 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
22833 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
22834 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
22835 ++ } else if (gr_status & GR_READY) {
22836 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
22837 ++ error = -EPERM;
22838 ++ } else {
22839 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
22840 ++ error = -EAGAIN;
22841 ++ }
22842 ++ break;
22843 ++ case ENABLE:
22844 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
22845 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
22846 ++ else {
22847 ++ if (gr_status & GR_READY)
22848 ++ error = -EAGAIN;
22849 ++ else
22850 ++ error = error2;
22851 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
22852 ++ }
22853 ++ break;
22854 ++ case RELOAD:
22855 ++ if (!(gr_status & GR_READY)) {
22856 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
22857 ++ error = -EAGAIN;
22858 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
22859 ++ lock_kernel();
22860 ++ gr_status &= ~GR_READY;
22861 ++ free_variables();
22862 ++ if (!(error2 = gracl_init(gr_usermode))) {
22863 ++ unlock_kernel();
22864 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
22865 ++ } else {
22866 ++ unlock_kernel();
22867 ++ error = error2;
22868 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
22869 ++ }
22870 ++ } else {
22871 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
22872 ++ error = -EPERM;
22873 ++ }
22874 ++ break;
22875 ++ case SEGVMOD:
22876 ++ if (unlikely(!(gr_status & GR_READY))) {
22877 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
22878 ++ error = -EAGAIN;
22879 ++ break;
22880 ++ }
22881 ++
22882 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
22883 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
22884 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
22885 ++ struct acl_subject_label *segvacl;
22886 ++ segvacl =
22887 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
22888 ++ gr_usermode->segv_device,
22889 ++ current->role);
22890 ++ if (segvacl) {
22891 ++ segvacl->crashes = 0;
22892 ++ segvacl->expires = 0;
22893 ++ }
22894 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
22895 ++ gr_remove_uid(gr_usermode->segv_uid);
22896 ++ }
22897 ++ } else {
22898 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
22899 ++ error = -EPERM;
22900 ++ }
22901 ++ break;
22902 ++ case SPROLE:
22903 ++ case SPROLEPAM:
22904 ++ if (unlikely(!(gr_status & GR_READY))) {
22905 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
22906 ++ error = -EAGAIN;
22907 ++ break;
22908 ++ }
22909 ++
22910 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
22911 ++ current->role->expires = 0;
22912 ++ current->role->auth_attempts = 0;
22913 ++ }
22914 ++
22915 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
22916 ++ time_after(current->role->expires, get_seconds())) {
22917 ++ error = -EBUSY;
22918 ++ goto out;
22919 ++ }
22920 ++
22921 ++ if (lookup_special_role_auth
22922 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
22923 ++ && ((!sprole_salt && !sprole_sum)
22924 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
22925 ++ char *p = "";
22926 ++ assign_special_role(gr_usermode->sp_role);
22927 ++ read_lock(&tasklist_lock);
22928 ++ if (current->parent)
22929 ++ p = current->parent->role->rolename;
22930 ++ read_unlock(&tasklist_lock);
22931 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
22932 ++ p, acl_sp_role_value);
22933 ++ } else {
22934 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
22935 ++ error = -EPERM;
22936 ++ if(!(current->role->auth_attempts++))
22937 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
22938 ++
22939 ++ goto out;
22940 ++ }
22941 ++ break;
22942 ++ case UNSPROLE:
22943 ++ if (unlikely(!(gr_status & GR_READY))) {
22944 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
22945 ++ error = -EAGAIN;
22946 ++ break;
22947 ++ }
22948 ++
22949 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
22950 ++ char *p = "";
22951 ++ int i = 0;
22952 ++
22953 ++ read_lock(&tasklist_lock);
22954 ++ if (current->parent) {
22955 ++ p = current->parent->role->rolename;
22956 ++ i = current->parent->acl_role_id;
22957 ++ }
22958 ++ read_unlock(&tasklist_lock);
22959 ++
22960 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
22961 ++ gr_set_acls(1);
22962 ++ } else {
22963 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
22964 ++ error = -EPERM;
22965 ++ goto out;
22966 ++ }
22967 ++ break;
22968 ++ default:
22969 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
22970 ++ error = -EINVAL;
22971 ++ break;
22972 ++ }
22973 ++
22974 ++ if (error != -EPERM)
22975 ++ goto out;
22976 ++
22977 ++ if(!(gr_auth_attempts++))
22978 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
22979 ++
22980 ++ out:
22981 ++ up(&gr_dev_sem);
22982 ++ return error;
22983 ++}
22984 ++
22985 ++int
22986 ++gr_set_acls(const int type)
22987 ++{
22988 ++ struct acl_object_label *obj;
22989 ++ struct task_struct *task, *task2;
22990 ++ struct file *filp;
22991 ++ struct acl_role_label *role = current->role;
22992 ++ __u16 acl_role_id = current->acl_role_id;
22993 ++
22994 ++ read_lock(&tasklist_lock);
22995 ++ read_lock(&grsec_exec_file_lock);
22996 ++ do_each_thread(task2, task) {
22997 ++ /* check to see if we're called from the exit handler,
22998 ++ if so, only replace ACLs that have inherited the admin
22999 ++ ACL */
23000 ++
23001 ++ if (type && (task->role != role ||
23002 ++ task->acl_role_id != acl_role_id))
23003 ++ continue;
23004 ++
23005 ++ task->acl_role_id = 0;
23006 ++ task->acl_sp_role = 0;
23007 ++
23008 ++ if ((filp = task->exec_file)) {
23009 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
23010 ++
23011 ++ task->acl =
23012 ++ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
23013 ++ task->role);
23014 ++ if (task->acl) {
23015 ++ struct acl_subject_label *curr;
23016 ++ curr = task->acl;
23017 ++
23018 ++ task->is_writable = 0;
23019 ++ /* ignore additional mmap checks for processes that are writable
23020 ++ by the default ACL */
23021 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23022 ++ if (unlikely(obj->mode & GR_WRITE))
23023 ++ task->is_writable = 1;
23024 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
23025 ++ if (unlikely(obj->mode & GR_WRITE))
23026 ++ task->is_writable = 1;
23027 ++
23028 ++ gr_set_proc_res(task);
23029 ++
23030 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
23031 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
23032 ++#endif
23033 ++ } else {
23034 ++ read_unlock(&grsec_exec_file_lock);
23035 ++ read_unlock(&tasklist_lock);
23036 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
23037 ++ return 1;
23038 ++ }
23039 ++ } else {
23040 ++ // it's a kernel process
23041 ++ task->role = kernel_role;
23042 ++ task->acl = kernel_role->root_label;
23043 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
23044 ++ task->acl->mode &= ~GR_PROCFIND;
23045 ++#endif
23046 ++ }
23047 ++ } while_each_thread(task2, task);
23048 ++ read_unlock(&grsec_exec_file_lock);
23049 ++ read_unlock(&tasklist_lock);
23050 ++ return 0;
23051 ++}
23052 ++
23053 ++void
23054 ++gr_learn_resource(const struct task_struct *task,
23055 ++ const int res, const unsigned long wanted, const int gt)
23056 ++{
23057 ++ struct acl_subject_label *acl;
23058 ++
23059 ++ if (unlikely((gr_status & GR_READY) &&
23060 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
23061 ++ goto skip_reslog;
23062 ++
23063 ++#ifdef CONFIG_GRKERNSEC_RESLOG
23064 ++ gr_log_resource(task, res, wanted, gt);
23065 ++#endif
23066 ++ skip_reslog:
23067 ++
23068 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
23069 ++ return;
23070 ++
23071 ++ acl = task->acl;
23072 ++
23073 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
23074 ++ !(acl->resmask & (1 << (unsigned short) res))))
23075 ++ return;
23076 ++
23077 ++ if (wanted >= acl->res[res].rlim_cur) {
23078 ++ unsigned long res_add;
23079 ++
23080 ++ res_add = wanted;
23081 ++ switch (res) {
23082 ++ case RLIMIT_CPU:
23083 ++ res_add += GR_RLIM_CPU_BUMP;
23084 ++ break;
23085 ++ case RLIMIT_FSIZE:
23086 ++ res_add += GR_RLIM_FSIZE_BUMP;
23087 ++ break;
23088 ++ case RLIMIT_DATA:
23089 ++ res_add += GR_RLIM_DATA_BUMP;
23090 ++ break;
23091 ++ case RLIMIT_STACK:
23092 ++ res_add += GR_RLIM_STACK_BUMP;
23093 ++ break;
23094 ++ case RLIMIT_CORE:
23095 ++ res_add += GR_RLIM_CORE_BUMP;
23096 ++ break;
23097 ++ case RLIMIT_RSS:
23098 ++ res_add += GR_RLIM_RSS_BUMP;
23099 ++ break;
23100 ++ case RLIMIT_NPROC:
23101 ++ res_add += GR_RLIM_NPROC_BUMP;
23102 ++ break;
23103 ++ case RLIMIT_NOFILE:
23104 ++ res_add += GR_RLIM_NOFILE_BUMP;
23105 ++ break;
23106 ++ case RLIMIT_MEMLOCK:
23107 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
23108 ++ break;
23109 ++ case RLIMIT_AS:
23110 ++ res_add += GR_RLIM_AS_BUMP;
23111 ++ break;
23112 ++ case RLIMIT_LOCKS:
23113 ++ res_add += GR_RLIM_LOCKS_BUMP;
23114 ++ break;
23115 ++ }
23116 ++
23117 ++ acl->res[res].rlim_cur = res_add;
23118 ++
23119 ++ if (wanted > acl->res[res].rlim_max)
23120 ++ acl->res[res].rlim_max = res_add;
23121 ++
23122 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
23123 ++ task->role->roletype, acl->filename,
23124 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
23125 ++ "", (unsigned long) res);
23126 ++ }
23127 ++
23128 ++ return;
23129 ++}
23130 ++
23131 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23132 ++void
23133 ++pax_set_initial_flags(struct linux_binprm *bprm)
23134 ++{
23135 ++ struct task_struct *task = current;
23136 ++ struct acl_subject_label *proc;
23137 ++ unsigned long flags;
23138 ++
23139 ++ if (unlikely(!(gr_status & GR_READY)))
23140 ++ return;
23141 ++
23142 ++ flags = pax_get_flags(task);
23143 ++
23144 ++ proc = task->acl;
23145 ++
23146 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
23147 ++ flags &= ~MF_PAX_PAGEEXEC;
23148 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
23149 ++ flags &= ~MF_PAX_SEGMEXEC;
23150 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
23151 ++ flags &= ~MF_PAX_RANDMMAP;
23152 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
23153 ++ flags &= ~MF_PAX_EMUTRAMP;
23154 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
23155 ++ flags &= ~MF_PAX_MPROTECT;
23156 ++
23157 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
23158 ++ flags |= MF_PAX_PAGEEXEC;
23159 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
23160 ++ flags |= MF_PAX_SEGMEXEC;
23161 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
23162 ++ flags |= MF_PAX_RANDMMAP;
23163 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
23164 ++ flags |= MF_PAX_EMUTRAMP;
23165 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
23166 ++ flags |= MF_PAX_MPROTECT;
23167 ++
23168 ++ pax_set_flags(task, flags);
23169 ++
23170 ++ return;
23171 ++}
23172 ++#endif
23173 ++
23174 ++#ifdef CONFIG_SYSCTL
23175 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
23176 ++ system to save 35kb of memory */
23177 ++
23178 ++/* we modify the passed in filename, but adjust it back before returning */
23179 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
23180 ++{
23181 ++ struct name_entry *nmatch;
23182 ++ char *p, *lastp = NULL;
23183 ++ struct acl_object_label *obj = NULL, *tmp;
23184 ++ struct acl_subject_label *tmpsubj;
23185 ++ char c = '\0';
23186 ++
23187 ++ read_lock(&gr_inode_lock);
23188 ++
23189 ++ p = name + len - 1;
23190 ++ do {
23191 ++ nmatch = lookup_name_entry(name);
23192 ++ if (lastp != NULL)
23193 ++ *lastp = c;
23194 ++
23195 ++ if (nmatch == NULL)
23196 ++ goto next_component;
23197 ++ tmpsubj = current->acl;
23198 ++ do {
23199 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
23200 ++ if (obj != NULL) {
23201 ++ tmp = obj->globbed;
23202 ++ while (tmp) {
23203 ++ if (!glob_match(tmp->filename, name)) {
23204 ++ obj = tmp;
23205 ++ goto found_obj;
23206 ++ }
23207 ++ tmp = tmp->next;
23208 ++ }
23209 ++ goto found_obj;
23210 ++ }
23211 ++ } while ((tmpsubj = tmpsubj->parent_subject));
23212 ++next_component:
23213 ++ /* end case */
23214 ++ if (p == name)
23215 ++ break;
23216 ++
23217 ++ while (*p != '/')
23218 ++ p--;
23219 ++ if (p == name)
23220 ++ lastp = p + 1;
23221 ++ else {
23222 ++ lastp = p;
23223 ++ p--;
23224 ++ }
23225 ++ c = *lastp;
23226 ++ *lastp = '\0';
23227 ++ } while (1);
23228 ++found_obj:
23229 ++ read_unlock(&gr_inode_lock);
23230 ++ /* obj returned will always be non-null */
23231 ++ return obj;
23232 ++}
23233 ++
23234 ++/* returns 0 when allowing, non-zero on error
23235 ++ op of 0 is used for readdir, so we don't log the names of hidden files
23236 ++*/
23237 ++__u32
23238 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
23239 ++{
23240 ++ ctl_table *tmp;
23241 ++ const char *proc_sys = "/proc/sys";
23242 ++ char *path;
23243 ++ struct acl_object_label *obj;
23244 ++ unsigned short len = 0, pos = 0, depth = 0, i;
23245 ++ __u32 err = 0;
23246 ++ __u32 mode = 0;
23247 ++
23248 ++ if (unlikely(!(gr_status & GR_READY)))
23249 ++ return 0;
23250 ++
23251 ++ /* for now, ignore operations on non-sysctl entries if it's not a
23252 ++ readdir*/
23253 ++ if (table->child != NULL && op != 0)
23254 ++ return 0;
23255 ++
23256 ++ mode |= GR_FIND;
23257 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
23258 ++ if (op & 004)
23259 ++ mode |= GR_READ;
23260 ++ if (op & 002)
23261 ++ mode |= GR_WRITE;
23262 ++
23263 ++ preempt_disable();
23264 ++
23265 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
23266 ++
23267 ++ /* it's only a read/write if it's an actual entry, not a dir
23268 ++ (which are opened for readdir)
23269 ++ */
23270 ++
23271 ++ /* convert the requested sysctl entry into a pathname */
23272 ++
23273 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23274 ++ len += strlen(tmp->procname);
23275 ++ len++;
23276 ++ depth++;
23277 ++ }
23278 ++
23279 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
23280 ++ /* deny */
23281 ++ goto out;
23282 ++ }
23283 ++
23284 ++ memset(path, 0, PAGE_SIZE);
23285 ++
23286 ++ memcpy(path, proc_sys, strlen(proc_sys));
23287 ++
23288 ++ pos += strlen(proc_sys);
23289 ++
23290 ++ for (; depth > 0; depth--) {
23291 ++ path[pos] = '/';
23292 ++ pos++;
23293 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
23294 ++ if (depth == i) {
23295 ++ memcpy(path + pos, tmp->procname,
23296 ++ strlen(tmp->procname));
23297 ++ pos += strlen(tmp->procname);
23298 ++ }
23299 ++ i++;
23300 ++ }
23301 ++ }
23302 ++
23303 ++ obj = gr_lookup_by_name(path, pos);
23304 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
23305 ++
23306 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
23307 ++ ((err & mode) != mode))) {
23308 ++ __u32 new_mode = mode;
23309 ++
23310 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
23311 ++
23312 ++ err = 0;
23313 ++ gr_log_learn_sysctl(current, path, new_mode);
23314 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
23315 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
23316 ++ err = -ENOENT;
23317 ++ } else if (!(err & GR_FIND)) {
23318 ++ err = -ENOENT;
23319 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
23320 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
23321 ++ path, (mode & GR_READ) ? " reading" : "",
23322 ++ (mode & GR_WRITE) ? " writing" : "");
23323 ++ err = -EACCES;
23324 ++ } else if ((err & mode) != mode) {
23325 ++ err = -EACCES;
23326 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
23327 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
23328 ++ path, (mode & GR_READ) ? " reading" : "",
23329 ++ (mode & GR_WRITE) ? " writing" : "");
23330 ++ err = 0;
23331 ++ } else
23332 ++ err = 0;
23333 ++
23334 ++ out:
23335 ++ preempt_enable();
23336 ++
23337 ++ return err;
23338 ++}
23339 ++#endif
23340 ++
23341 ++int
23342 ++gr_handle_proc_ptrace(struct task_struct *task)
23343 ++{
23344 ++ struct file *filp;
23345 ++ struct task_struct *tmp = task;
23346 ++ struct task_struct *curtemp = current;
23347 ++ __u32 retmode;
23348 ++
23349 ++ if (unlikely(!(gr_status & GR_READY)))
23350 ++ return 0;
23351 ++
23352 ++ read_lock(&tasklist_lock);
23353 ++ read_lock(&grsec_exec_file_lock);
23354 ++ filp = task->exec_file;
23355 ++
23356 ++ while (tmp->pid > 0) {
23357 ++ if (tmp == curtemp)
23358 ++ break;
23359 ++ tmp = tmp->parent;
23360 ++ }
23361 ++
23362 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
23363 ++ read_unlock(&grsec_exec_file_lock);
23364 ++ read_unlock(&tasklist_lock);
23365 ++ return 1;
23366 ++ }
23367 ++
23368 ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
23369 ++ read_unlock(&grsec_exec_file_lock);
23370 ++ read_unlock(&tasklist_lock);
23371 ++
23372 ++ if (retmode & GR_NOPTRACE)
23373 ++ return 1;
23374 ++
23375 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
23376 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
23377 ++ && current->pid != task->pid)))
23378 ++ return 1;
23379 ++
23380 ++ return 0;
23381 ++}
23382 ++
23383 ++int
23384 ++gr_handle_ptrace(struct task_struct *task, const long request)
23385 ++{
23386 ++ struct task_struct *tmp = task;
23387 ++ struct task_struct *curtemp = current;
23388 ++ __u32 retmode;
23389 ++
23390 ++ if (unlikely(!(gr_status & GR_READY)))
23391 ++ return 0;
23392 ++
23393 ++ read_lock(&tasklist_lock);
23394 ++ while (tmp->pid > 0) {
23395 ++ if (tmp == curtemp)
23396 ++ break;
23397 ++ tmp = tmp->parent;
23398 ++ }
23399 ++
23400 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
23401 ++ read_unlock(&tasklist_lock);
23402 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23403 ++ return 1;
23404 ++ }
23405 ++ read_unlock(&tasklist_lock);
23406 ++
23407 ++ read_lock(&grsec_exec_file_lock);
23408 ++ if (unlikely(!task->exec_file)) {
23409 ++ read_unlock(&grsec_exec_file_lock);
23410 ++ return 0;
23411 ++ }
23412 ++
23413 ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
23414 ++ read_unlock(&grsec_exec_file_lock);
23415 ++
23416 ++ if (retmode & GR_NOPTRACE) {
23417 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23418 ++ return 1;
23419 ++ }
23420 ++
23421 ++ if (retmode & GR_PTRACERD) {
23422 ++ switch (request) {
23423 ++ case PTRACE_POKETEXT:
23424 ++ case PTRACE_POKEDATA:
23425 ++ case PTRACE_POKEUSR:
23426 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
23427 ++ case PTRACE_SETREGS:
23428 ++ case PTRACE_SETFPREGS:
23429 ++#endif
23430 ++#ifdef CONFIG_X86
23431 ++ case PTRACE_SETFPXREGS:
23432 ++#endif
23433 ++#ifdef CONFIG_ALTIVEC
23434 ++ case PTRACE_SETVRREGS:
23435 ++#endif
23436 ++ return 1;
23437 ++ default:
23438 ++ return 0;
23439 ++ }
23440 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
23441 ++ !(current->role->roletype & GR_ROLE_GOD) &&
23442 ++ (current->acl != task->acl)) {
23443 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
23444 ++ return 1;
23445 ++ }
23446 ++
23447 ++ return 0;
23448 ++}
23449 ++
23450 ++static int is_writable_mmap(const struct file *filp)
23451 ++{
23452 ++ struct task_struct *task = current;
23453 ++ struct acl_object_label *obj, *obj2;
23454 ++
23455 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
23456 ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
23457 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
23458 ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
23459 ++ task->role->root_label);
23460 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
23461 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
23462 ++ return 1;
23463 ++ }
23464 ++ }
23465 ++ return 0;
23466 ++}
23467 ++
23468 ++int
23469 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
23470 ++{
23471 ++ __u32 mode;
23472 ++
23473 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
23474 ++ return 1;
23475 ++
23476 ++ if (is_writable_mmap(file))
23477 ++ return 0;
23478 ++
23479 ++ mode =
23480 ++ gr_search_file(file->f_path.dentry,
23481 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23482 ++ file->f_path.mnt);
23483 ++
23484 ++ if (!gr_tpe_allow(file))
23485 ++ return 0;
23486 ++
23487 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23488 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23489 ++ return 0;
23490 ++ } else if (unlikely(!(mode & GR_EXEC))) {
23491 ++ return 0;
23492 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23493 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23494 ++ return 1;
23495 ++ }
23496 ++
23497 ++ return 1;
23498 ++}
23499 ++
23500 ++int
23501 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23502 ++{
23503 ++ __u32 mode;
23504 ++
23505 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
23506 ++ return 1;
23507 ++
23508 ++ if (is_writable_mmap(file))
23509 ++ return 0;
23510 ++
23511 ++ mode =
23512 ++ gr_search_file(file->f_path.dentry,
23513 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
23514 ++ file->f_path.mnt);
23515 ++
23516 ++ if (!gr_tpe_allow(file))
23517 ++ return 0;
23518 ++
23519 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
23520 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23521 ++ return 0;
23522 ++ } else if (unlikely(!(mode & GR_EXEC))) {
23523 ++ return 0;
23524 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
23525 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
23526 ++ return 1;
23527 ++ }
23528 ++
23529 ++ return 1;
23530 ++}
23531 ++
23532 ++void
23533 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
23534 ++{
23535 ++ unsigned long runtime;
23536 ++ unsigned long cputime;
23537 ++ unsigned int wday, cday;
23538 ++ __u8 whr, chr;
23539 ++ __u8 wmin, cmin;
23540 ++ __u8 wsec, csec;
23541 ++ struct timespec timeval;
23542 ++
23543 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
23544 ++ !(task->acl->mode & GR_PROCACCT)))
23545 ++ return;
23546 ++
23547 ++ do_posix_clock_monotonic_gettime(&timeval);
23548 ++ runtime = timeval.tv_sec - task->start_time.tv_sec;
23549 ++ wday = runtime / (3600 * 24);
23550 ++ runtime -= wday * (3600 * 24);
23551 ++ whr = runtime / 3600;
23552 ++ runtime -= whr * 3600;
23553 ++ wmin = runtime / 60;
23554 ++ runtime -= wmin * 60;
23555 ++ wsec = runtime;
23556 ++
23557 ++ cputime = (task->utime + task->stime) / HZ;
23558 ++ cday = cputime / (3600 * 24);
23559 ++ cputime -= cday * (3600 * 24);
23560 ++ chr = cputime / 3600;
23561 ++ cputime -= chr * 3600;
23562 ++ cmin = cputime / 60;
23563 ++ cputime -= cmin * 60;
23564 ++ csec = cputime;
23565 ++
23566 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
23567 ++
23568 ++ return;
23569 ++}
23570 ++
23571 ++void gr_set_kernel_label(struct task_struct *task)
23572 ++{
23573 ++ if (gr_status & GR_READY) {
23574 ++ task->role = kernel_role;
23575 ++ task->acl = kernel_role->root_label;
23576 ++ }
23577 ++ return;
23578 ++}
23579 ++
23580 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
23581 ++{
23582 ++ struct task_struct *task = current;
23583 ++ struct dentry *dentry = file->f_path.dentry;
23584 ++ struct vfsmount *mnt = file->f_path.mnt;
23585 ++ struct acl_object_label *obj, *tmp;
23586 ++ struct acl_subject_label *subj;
23587 ++ unsigned int bufsize;
23588 ++ int is_not_root;
23589 ++ char *path;
23590 ++
23591 ++ if (unlikely(!(gr_status & GR_READY)))
23592 ++ return 1;
23593 ++
23594 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
23595 ++ return 1;
23596 ++
23597 ++ /* ignore Eric Biederman */
23598 ++ if (IS_PRIVATE(dentry->d_inode))
23599 ++ return 1;
23600 ++
23601 ++ subj = task->acl;
23602 ++ do {
23603 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
23604 ++ if (obj != NULL)
23605 ++ return (obj->mode & GR_FIND) ? 1 : 0;
23606 ++ } while ((subj = subj->parent_subject));
23607 ++
23608 ++ obj = chk_obj_label(dentry, mnt, task->acl);
23609 ++ if (obj->globbed == NULL)
23610 ++ return (obj->mode & GR_FIND) ? 1 : 0;
23611 ++
23612 ++ is_not_root = ((obj->filename[0] == '/') &&
23613 ++ (obj->filename[1] == '\0')) ? 0 : 1;
23614 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
23615 ++
23616 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
23617 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
23618 ++ return 1;
23619 ++
23620 ++ preempt_disable();
23621 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
23622 ++ bufsize);
23623 ++
23624 ++ bufsize = strlen(path);
23625 ++
23626 ++ /* if base is "/", don't append an additional slash */
23627 ++ if (is_not_root)
23628 ++ *(path + bufsize) = '/';
23629 ++ memcpy(path + bufsize + is_not_root, name, namelen);
23630 ++ *(path + bufsize + namelen + is_not_root) = '\0';
23631 ++
23632 ++ tmp = obj->globbed;
23633 ++ while (tmp) {
23634 ++ if (!glob_match(tmp->filename, path)) {
23635 ++ preempt_enable();
23636 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
23637 ++ }
23638 ++ tmp = tmp->next;
23639 ++ }
23640 ++ preempt_enable();
23641 ++ return (obj->mode & GR_FIND) ? 1 : 0;
23642 ++}
23643 ++
23644 ++EXPORT_SYMBOL(gr_learn_resource);
23645 ++EXPORT_SYMBOL(gr_set_kernel_label);
23646 ++#ifdef CONFIG_SECURITY
23647 ++EXPORT_SYMBOL(gr_check_user_change);
23648 ++EXPORT_SYMBOL(gr_check_group_change);
23649 ++#endif
23650 ++
23651 +diff -urNp linux-2.6.26.6/grsecurity/gracl_cap.c linux-2.6.26.6/grsecurity/gracl_cap.c
23652 +--- linux-2.6.26.6/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
23653 ++++ linux-2.6.26.6/grsecurity/gracl_cap.c 2008-10-11 21:54:20.000000000 -0400
23654 +@@ -0,0 +1,129 @@
23655 ++#include <linux/kernel.h>
23656 ++#include <linux/module.h>
23657 ++#include <linux/sched.h>
23658 ++#include <linux/gracl.h>
23659 ++#include <linux/grsecurity.h>
23660 ++#include <linux/grinternal.h>
23661 ++
23662 ++static const char *captab_log[] = {
23663 ++ "CAP_CHOWN",
23664 ++ "CAP_DAC_OVERRIDE",
23665 ++ "CAP_DAC_READ_SEARCH",
23666 ++ "CAP_FOWNER",
23667 ++ "CAP_FSETID",
23668 ++ "CAP_KILL",
23669 ++ "CAP_SETGID",
23670 ++ "CAP_SETUID",
23671 ++ "CAP_SETPCAP",
23672 ++ "CAP_LINUX_IMMUTABLE",
23673 ++ "CAP_NET_BIND_SERVICE",
23674 ++ "CAP_NET_BROADCAST",
23675 ++ "CAP_NET_ADMIN",
23676 ++ "CAP_NET_RAW",
23677 ++ "CAP_IPC_LOCK",
23678 ++ "CAP_IPC_OWNER",
23679 ++ "CAP_SYS_MODULE",
23680 ++ "CAP_SYS_RAWIO",
23681 ++ "CAP_SYS_CHROOT",
23682 ++ "CAP_SYS_PTRACE",
23683 ++ "CAP_SYS_PACCT",
23684 ++ "CAP_SYS_ADMIN",
23685 ++ "CAP_SYS_BOOT",
23686 ++ "CAP_SYS_NICE",
23687 ++ "CAP_SYS_RESOURCE",
23688 ++ "CAP_SYS_TIME",
23689 ++ "CAP_SYS_TTY_CONFIG",
23690 ++ "CAP_MKNOD",
23691 ++ "CAP_LEASE",
23692 ++ "CAP_AUDIT_WRITE",
23693 ++ "CAP_AUDIT_CONTROL",
23694 ++ "CAP_SETFCAP",
23695 ++ "CAP_MAC_OVERRIDE",
23696 ++ "CAP_MAC_ADMIN"
23697 ++};
23698 ++
23699 ++EXPORT_SYMBOL(gr_task_is_capable);
23700 ++EXPORT_SYMBOL(gr_is_capable_nolog);
23701 ++
23702 ++int
23703 ++gr_task_is_capable(struct task_struct *task, const int cap)
23704 ++{
23705 ++ struct acl_subject_label *curracl;
23706 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
23707 ++
23708 ++ if (!gr_acl_is_enabled())
23709 ++ return 1;
23710 ++
23711 ++ curracl = task->acl;
23712 ++
23713 ++ cap_drop = curracl->cap_lower;
23714 ++ cap_mask = curracl->cap_mask;
23715 ++
23716 ++ while ((curracl = curracl->parent_subject)) {
23717 ++ /* if the cap isn't specified in the current computed mask but is specified in the
23718 ++ current level subject, and is lowered in the current level subject, then add
23719 ++ it to the set of dropped capabilities
23720 ++ otherwise, add the current level subject's mask to the current computed mask
23721 ++ */
23722 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
23723 ++ cap_raise(cap_mask, cap);
23724 ++ if (cap_raised(curracl->cap_lower, cap))
23725 ++ cap_raise(cap_drop, cap);
23726 ++ }
23727 ++ }
23728 ++
23729 ++ if (!cap_raised(cap_drop, cap))
23730 ++ return 1;
23731 ++
23732 ++ curracl = task->acl;
23733 ++
23734 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
23735 ++ && cap_raised(task->cap_effective, cap)) {
23736 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
23737 ++ task->role->roletype, task->uid,
23738 ++ task->gid, task->exec_file ?
23739 ++ gr_to_filename(task->exec_file->f_path.dentry,
23740 ++ task->exec_file->f_path.mnt) : curracl->filename,
23741 ++ curracl->filename, 0UL,
23742 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
23743 ++ return 1;
23744 ++ }
23745 ++
23746 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
23747 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
23748 ++ return 0;
23749 ++}
23750 ++
23751 ++int
23752 ++gr_is_capable_nolog(const int cap)
23753 ++{
23754 ++ struct acl_subject_label *curracl;
23755 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
23756 ++
23757 ++ if (!gr_acl_is_enabled())
23758 ++ return 1;
23759 ++
23760 ++ curracl = current->acl;
23761 ++
23762 ++ cap_drop = curracl->cap_lower;
23763 ++ cap_mask = curracl->cap_mask;
23764 ++
23765 ++ while ((curracl = curracl->parent_subject)) {
23766 ++ /* if the cap isn't specified in the current computed mask but is specified in the
23767 ++ current level subject, and is lowered in the current level subject, then add
23768 ++ it to the set of dropped capabilities
23769 ++ otherwise, add the current level subject's mask to the current computed mask
23770 ++ */
23771 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
23772 ++ cap_raise(cap_mask, cap);
23773 ++ if (cap_raised(curracl->cap_lower, cap))
23774 ++ cap_raise(cap_drop, cap);
23775 ++ }
23776 ++ }
23777 ++
23778 ++ if (!cap_raised(cap_drop, cap))
23779 ++ return 1;
23780 ++
23781 ++ return 0;
23782 ++}
23783 ++
23784 +diff -urNp linux-2.6.26.6/grsecurity/gracl_fs.c linux-2.6.26.6/grsecurity/gracl_fs.c
23785 +--- linux-2.6.26.6/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
23786 ++++ linux-2.6.26.6/grsecurity/gracl_fs.c 2008-10-11 21:54:20.000000000 -0400
23787 +@@ -0,0 +1,423 @@
23788 ++#include <linux/kernel.h>
23789 ++#include <linux/sched.h>
23790 ++#include <linux/types.h>
23791 ++#include <linux/fs.h>
23792 ++#include <linux/file.h>
23793 ++#include <linux/stat.h>
23794 ++#include <linux/grsecurity.h>
23795 ++#include <linux/grinternal.h>
23796 ++#include <linux/gracl.h>
23797 ++
23798 ++__u32
23799 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
23800 ++ const struct vfsmount * mnt)
23801 ++{
23802 ++ __u32 mode;
23803 ++
23804 ++ if (unlikely(!dentry->d_inode))
23805 ++ return GR_FIND;
23806 ++
23807 ++ mode =
23808 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
23809 ++
23810 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
23811 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
23812 ++ return mode;
23813 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
23814 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
23815 ++ return 0;
23816 ++ } else if (unlikely(!(mode & GR_FIND)))
23817 ++ return 0;
23818 ++
23819 ++ return GR_FIND;
23820 ++}
23821 ++
23822 ++__u32
23823 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
23824 ++ const int fmode)
23825 ++{
23826 ++ __u32 reqmode = GR_FIND;
23827 ++ __u32 mode;
23828 ++
23829 ++ if (unlikely(!dentry->d_inode))
23830 ++ return reqmode;
23831 ++
23832 ++ if (unlikely(fmode & O_APPEND))
23833 ++ reqmode |= GR_APPEND;
23834 ++ else if (unlikely(fmode & FMODE_WRITE))
23835 ++ reqmode |= GR_WRITE;
23836 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
23837 ++ reqmode |= GR_READ;
23838 ++
23839 ++ mode =
23840 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
23841 ++ mnt);
23842 ++
23843 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
23844 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
23845 ++ reqmode & GR_READ ? " reading" : "",
23846 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23847 ++ GR_APPEND ? " appending" : "");
23848 ++ return reqmode;
23849 ++ } else
23850 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
23851 ++ {
23852 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
23853 ++ reqmode & GR_READ ? " reading" : "",
23854 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23855 ++ GR_APPEND ? " appending" : "");
23856 ++ return 0;
23857 ++ } else if (unlikely((mode & reqmode) != reqmode))
23858 ++ return 0;
23859 ++
23860 ++ return reqmode;
23861 ++}
23862 ++
23863 ++__u32
23864 ++gr_acl_handle_creat(const struct dentry * dentry,
23865 ++ const struct dentry * p_dentry,
23866 ++ const struct vfsmount * p_mnt, const int fmode,
23867 ++ const int imode)
23868 ++{
23869 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
23870 ++ __u32 mode;
23871 ++
23872 ++ if (unlikely(fmode & O_APPEND))
23873 ++ reqmode |= GR_APPEND;
23874 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
23875 ++ reqmode |= GR_READ;
23876 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
23877 ++ reqmode |= GR_SETID;
23878 ++
23879 ++ mode =
23880 ++ gr_check_create(dentry, p_dentry, p_mnt,
23881 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
23882 ++
23883 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
23884 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
23885 ++ reqmode & GR_READ ? " reading" : "",
23886 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23887 ++ GR_APPEND ? " appending" : "");
23888 ++ return reqmode;
23889 ++ } else
23890 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
23891 ++ {
23892 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
23893 ++ reqmode & GR_READ ? " reading" : "",
23894 ++ reqmode & GR_WRITE ? " writing" : reqmode &
23895 ++ GR_APPEND ? " appending" : "");
23896 ++ return 0;
23897 ++ } else if (unlikely((mode & reqmode) != reqmode))
23898 ++ return 0;
23899 ++
23900 ++ return reqmode;
23901 ++}
23902 ++
23903 ++__u32
23904 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
23905 ++ const int fmode)
23906 ++{
23907 ++ __u32 mode, reqmode = GR_FIND;
23908 ++
23909 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
23910 ++ reqmode |= GR_EXEC;
23911 ++ if (fmode & S_IWOTH)
23912 ++ reqmode |= GR_WRITE;
23913 ++ if (fmode & S_IROTH)
23914 ++ reqmode |= GR_READ;
23915 ++
23916 ++ mode =
23917 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
23918 ++ mnt);
23919 ++
23920 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
23921 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
23922 ++ reqmode & GR_READ ? " reading" : "",
23923 ++ reqmode & GR_WRITE ? " writing" : "",
23924 ++ reqmode & GR_EXEC ? " executing" : "");
23925 ++ return reqmode;
23926 ++ } else
23927 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
23928 ++ {
23929 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
23930 ++ reqmode & GR_READ ? " reading" : "",
23931 ++ reqmode & GR_WRITE ? " writing" : "",
23932 ++ reqmode & GR_EXEC ? " executing" : "");
23933 ++ return 0;
23934 ++ } else if (unlikely((mode & reqmode) != reqmode))
23935 ++ return 0;
23936 ++
23937 ++ return reqmode;
23938 ++}
23939 ++
23940 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
23941 ++{
23942 ++ __u32 mode;
23943 ++
23944 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
23945 ++
23946 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
23947 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
23948 ++ return mode;
23949 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
23950 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
23951 ++ return 0;
23952 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
23953 ++ return 0;
23954 ++
23955 ++ return (reqmode);
23956 ++}
23957 ++
23958 ++__u32
23959 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
23960 ++{
23961 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
23962 ++}
23963 ++
23964 ++__u32
23965 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
23966 ++{
23967 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
23968 ++}
23969 ++
23970 ++__u32
23971 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
23972 ++{
23973 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
23974 ++}
23975 ++
23976 ++__u32
23977 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
23978 ++{
23979 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
23980 ++}
23981 ++
23982 ++__u32
23983 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
23984 ++ mode_t mode)
23985 ++{
23986 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
23987 ++ return 1;
23988 ++
23989 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
23990 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
23991 ++ GR_FCHMOD_ACL_MSG);
23992 ++ } else {
23993 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
23994 ++ }
23995 ++}
23996 ++
23997 ++__u32
23998 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
23999 ++ mode_t mode)
24000 ++{
24001 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
24002 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
24003 ++ GR_CHMOD_ACL_MSG);
24004 ++ } else {
24005 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
24006 ++ }
24007 ++}
24008 ++
24009 ++__u32
24010 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
24011 ++{
24012 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
24013 ++}
24014 ++
24015 ++__u32
24016 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
24017 ++{
24018 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
24019 ++}
24020 ++
24021 ++__u32
24022 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
24023 ++{
24024 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
24025 ++ GR_UNIXCONNECT_ACL_MSG);
24026 ++}
24027 ++
24028 ++/* hardlinks require at minimum create permission,
24029 ++ any additional privilege required is based on the
24030 ++ privilege of the file being linked to
24031 ++*/
24032 ++__u32
24033 ++gr_acl_handle_link(const struct dentry * new_dentry,
24034 ++ const struct dentry * parent_dentry,
24035 ++ const struct vfsmount * parent_mnt,
24036 ++ const struct dentry * old_dentry,
24037 ++ const struct vfsmount * old_mnt, const char *to)
24038 ++{
24039 ++ __u32 mode;
24040 ++ __u32 needmode = GR_CREATE | GR_LINK;
24041 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
24042 ++
24043 ++ mode =
24044 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
24045 ++ old_mnt);
24046 ++
24047 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
24048 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24049 ++ return mode;
24050 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24051 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
24052 ++ return 0;
24053 ++ } else if (unlikely((mode & needmode) != needmode))
24054 ++ return 0;
24055 ++
24056 ++ return 1;
24057 ++}
24058 ++
24059 ++__u32
24060 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
24061 ++ const struct dentry * parent_dentry,
24062 ++ const struct vfsmount * parent_mnt, const char *from)
24063 ++{
24064 ++ __u32 needmode = GR_WRITE | GR_CREATE;
24065 ++ __u32 mode;
24066 ++
24067 ++ mode =
24068 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
24069 ++ GR_CREATE | GR_AUDIT_CREATE |
24070 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
24071 ++
24072 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
24073 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24074 ++ return mode;
24075 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
24076 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
24077 ++ return 0;
24078 ++ } else if (unlikely((mode & needmode) != needmode))
24079 ++ return 0;
24080 ++
24081 ++ return (GR_WRITE | GR_CREATE);
24082 ++}
24083 ++
24084 ++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)
24085 ++{
24086 ++ __u32 mode;
24087 ++
24088 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
24089 ++
24090 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
24091 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
24092 ++ return mode;
24093 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
24094 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
24095 ++ return 0;
24096 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
24097 ++ return 0;
24098 ++
24099 ++ return (reqmode);
24100 ++}
24101 ++
24102 ++__u32
24103 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
24104 ++ const struct dentry * parent_dentry,
24105 ++ const struct vfsmount * parent_mnt,
24106 ++ const int mode)
24107 ++{
24108 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
24109 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
24110 ++ reqmode |= GR_SETID;
24111 ++
24112 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24113 ++ reqmode, GR_MKNOD_ACL_MSG);
24114 ++}
24115 ++
24116 ++__u32
24117 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
24118 ++ const struct dentry *parent_dentry,
24119 ++ const struct vfsmount *parent_mnt)
24120 ++{
24121 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
24122 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
24123 ++}
24124 ++
24125 ++#define RENAME_CHECK_SUCCESS(old, new) \
24126 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
24127 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
24128 ++
24129 ++int
24130 ++gr_acl_handle_rename(struct dentry *new_dentry,
24131 ++ struct dentry *parent_dentry,
24132 ++ const struct vfsmount *parent_mnt,
24133 ++ struct dentry *old_dentry,
24134 ++ struct inode *old_parent_inode,
24135 ++ struct vfsmount *old_mnt, const char *newname)
24136 ++{
24137 ++ __u32 comp1, comp2;
24138 ++ int error = 0;
24139 ++
24140 ++ if (unlikely(!gr_acl_is_enabled()))
24141 ++ return 0;
24142 ++
24143 ++ if (!new_dentry->d_inode) {
24144 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
24145 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
24146 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
24147 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
24148 ++ GR_DELETE | GR_AUDIT_DELETE |
24149 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
24150 ++ GR_SUPPRESS, old_mnt);
24151 ++ } else {
24152 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
24153 ++ GR_CREATE | GR_DELETE |
24154 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
24155 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
24156 ++ GR_SUPPRESS, parent_mnt);
24157 ++ comp2 =
24158 ++ gr_search_file(old_dentry,
24159 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
24160 ++ GR_DELETE | GR_AUDIT_DELETE |
24161 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
24162 ++ }
24163 ++
24164 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
24165 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
24166 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24167 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
24168 ++ && !(comp2 & GR_SUPPRESS)) {
24169 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
24170 ++ error = -EACCES;
24171 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
24172 ++ error = -EACCES;
24173 ++
24174 ++ return error;
24175 ++}
24176 ++
24177 ++void
24178 ++gr_acl_handle_exit(void)
24179 ++{
24180 ++ u16 id;
24181 ++ char *rolename;
24182 ++ struct file *exec_file;
24183 ++
24184 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
24185 ++ id = current->acl_role_id;
24186 ++ rolename = current->role->rolename;
24187 ++ gr_set_acls(1);
24188 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
24189 ++ }
24190 ++
24191 ++ write_lock(&grsec_exec_file_lock);
24192 ++ exec_file = current->exec_file;
24193 ++ current->exec_file = NULL;
24194 ++ write_unlock(&grsec_exec_file_lock);
24195 ++
24196 ++ if (exec_file)
24197 ++ fput(exec_file);
24198 ++}
24199 ++
24200 ++int
24201 ++gr_acl_handle_procpidmem(const struct task_struct *task)
24202 ++{
24203 ++ if (unlikely(!gr_acl_is_enabled()))
24204 ++ return 0;
24205 ++
24206 ++ if (task != current && task->acl->mode & GR_PROTPROCFD)
24207 ++ return -EACCES;
24208 ++
24209 ++ return 0;
24210 ++}
24211 +diff -urNp linux-2.6.26.6/grsecurity/gracl_ip.c linux-2.6.26.6/grsecurity/gracl_ip.c
24212 +--- linux-2.6.26.6/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
24213 ++++ linux-2.6.26.6/grsecurity/gracl_ip.c 2008-10-11 21:54:20.000000000 -0400
24214 +@@ -0,0 +1,313 @@
24215 ++#include <linux/kernel.h>
24216 ++#include <asm/uaccess.h>
24217 ++#include <asm/errno.h>
24218 ++#include <net/sock.h>
24219 ++#include <linux/file.h>
24220 ++#include <linux/fs.h>
24221 ++#include <linux/net.h>
24222 ++#include <linux/in.h>
24223 ++#include <linux/skbuff.h>
24224 ++#include <linux/ip.h>
24225 ++#include <linux/udp.h>
24226 ++#include <linux/smp_lock.h>
24227 ++#include <linux/types.h>
24228 ++#include <linux/sched.h>
24229 ++#include <linux/netdevice.h>
24230 ++#include <linux/inetdevice.h>
24231 ++#include <linux/gracl.h>
24232 ++#include <linux/grsecurity.h>
24233 ++#include <linux/grinternal.h>
24234 ++
24235 ++#define GR_BIND 0x01
24236 ++#define GR_CONNECT 0x02
24237 ++#define GR_INVERT 0x04
24238 ++
24239 ++static const char * gr_protocols[256] = {
24240 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
24241 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
24242 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
24243 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
24244 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
24245 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
24246 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
24247 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
24248 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
24249 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
24250 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
24251 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
24252 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
24253 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
24254 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
24255 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
24256 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
24257 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
24258 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
24259 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
24260 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
24261 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
24262 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
24263 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
24264 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
24265 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
24266 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
24267 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
24268 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
24269 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
24270 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
24271 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
24272 ++ };
24273 ++
24274 ++static const char * gr_socktypes[11] = {
24275 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
24276 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
24277 ++ };
24278 ++
24279 ++const char *
24280 ++gr_proto_to_name(unsigned char proto)
24281 ++{
24282 ++ return gr_protocols[proto];
24283 ++}
24284 ++
24285 ++const char *
24286 ++gr_socktype_to_name(unsigned char type)
24287 ++{
24288 ++ return gr_socktypes[type];
24289 ++}
24290 ++
24291 ++int
24292 ++gr_search_socket(const int domain, const int type, const int protocol)
24293 ++{
24294 ++ struct acl_subject_label *curr;
24295 ++
24296 ++ if (unlikely(!gr_acl_is_enabled()))
24297 ++ goto exit;
24298 ++
24299 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
24300 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
24301 ++ goto exit; // let the kernel handle it
24302 ++
24303 ++ curr = current->acl;
24304 ++
24305 ++ if (!curr->ips)
24306 ++ goto exit;
24307 ++
24308 ++ if ((curr->ip_type & (1 << type)) &&
24309 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
24310 ++ goto exit;
24311 ++
24312 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24313 ++ /* we don't place acls on raw sockets , and sometimes
24314 ++ dgram/ip sockets are opened for ioctl and not
24315 ++ bind/connect, so we'll fake a bind learn log */
24316 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
24317 ++ __u32 fakeip = 0;
24318 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24319 ++ current->role->roletype, current->uid,
24320 ++ current->gid, current->exec_file ?
24321 ++ gr_to_filename(current->exec_file->f_path.dentry,
24322 ++ current->exec_file->f_path.mnt) :
24323 ++ curr->filename, curr->filename,
24324 ++ NIPQUAD(fakeip), 0, type,
24325 ++ protocol, GR_CONNECT,
24326 ++NIPQUAD(current->signal->curr_ip));
24327 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
24328 ++ __u32 fakeip = 0;
24329 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24330 ++ current->role->roletype, current->uid,
24331 ++ current->gid, current->exec_file ?
24332 ++ gr_to_filename(current->exec_file->f_path.dentry,
24333 ++ current->exec_file->f_path.mnt) :
24334 ++ curr->filename, curr->filename,
24335 ++ NIPQUAD(fakeip), 0, type,
24336 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
24337 ++ }
24338 ++ /* we'll log when they use connect or bind */
24339 ++ goto exit;
24340 ++ }
24341 ++
24342 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
24343 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
24344 ++
24345 ++ return 0;
24346 ++ exit:
24347 ++ return 1;
24348 ++}
24349 ++
24350 ++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)
24351 ++{
24352 ++ if ((ip->mode & mode) &&
24353 ++ (ip_port >= ip->low) &&
24354 ++ (ip_port <= ip->high) &&
24355 ++ ((ntohl(ip_addr) & our_netmask) ==
24356 ++ (ntohl(our_addr) & our_netmask))
24357 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
24358 ++ && (ip->type & (1 << type))) {
24359 ++ if (ip->mode & GR_INVERT)
24360 ++ return 2; // specifically denied
24361 ++ else
24362 ++ return 1; // allowed
24363 ++ }
24364 ++
24365 ++ return 0; // not specifically allowed, may continue parsing
24366 ++}
24367 ++
24368 ++static int
24369 ++gr_search_connectbind(const int mode, const struct sock *sk,
24370 ++ const struct sockaddr_in *addr, const int type)
24371 ++{
24372 ++ char iface[IFNAMSIZ] = {0};
24373 ++ struct acl_subject_label *curr;
24374 ++ struct acl_ip_label *ip;
24375 ++ struct net_device *dev;
24376 ++ struct in_device *idev;
24377 ++ unsigned long i;
24378 ++ int ret;
24379 ++ __u32 ip_addr = 0;
24380 ++ __u32 our_addr;
24381 ++ __u32 our_netmask;
24382 ++ char *p;
24383 ++ __u16 ip_port = 0;
24384 ++
24385 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
24386 ++ return 1;
24387 ++
24388 ++ curr = current->acl;
24389 ++
24390 ++ if (!curr->ips)
24391 ++ return 1;
24392 ++
24393 ++ ip_addr = addr->sin_addr.s_addr;
24394 ++ ip_port = ntohs(addr->sin_port);
24395 ++
24396 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
24397 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
24398 ++ current->role->roletype, current->uid,
24399 ++ current->gid, current->exec_file ?
24400 ++ gr_to_filename(current->exec_file->f_path.dentry,
24401 ++ current->exec_file->f_path.mnt) :
24402 ++ curr->filename, curr->filename,
24403 ++ NIPQUAD(ip_addr), ip_port, type,
24404 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
24405 ++ return 1;
24406 ++ }
24407 ++
24408 ++ for (i = 0; i < curr->ip_num; i++) {
24409 ++ ip = *(curr->ips + i);
24410 ++ if (ip->iface != NULL) {
24411 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
24412 ++ p = strchr(iface, ':');
24413 ++ if (p != NULL)
24414 ++ *p = '\0';
24415 ++ dev = dev_get_by_name(sock_net(sk), iface);
24416 ++ if (dev == NULL)
24417 ++ continue;
24418 ++ idev = in_dev_get(dev);
24419 ++ if (idev == NULL) {
24420 ++ dev_put(dev);
24421 ++ continue;
24422 ++ }
24423 ++ rcu_read_lock();
24424 ++ for_ifa(idev) {
24425 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
24426 ++ our_addr = ifa->ifa_address;
24427 ++ our_netmask = 0xffffffff;
24428 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24429 ++ if (ret == 1) {
24430 ++ rcu_read_unlock();
24431 ++ in_dev_put(idev);
24432 ++ dev_put(dev);
24433 ++ return 1;
24434 ++ } else if (ret == 2) {
24435 ++ rcu_read_unlock();
24436 ++ in_dev_put(idev);
24437 ++ dev_put(dev);
24438 ++ goto denied;
24439 ++ }
24440 ++ }
24441 ++ } endfor_ifa(idev);
24442 ++ rcu_read_unlock();
24443 ++ in_dev_put(idev);
24444 ++ dev_put(dev);
24445 ++ } else {
24446 ++ our_addr = ip->addr;
24447 ++ our_netmask = ip->netmask;
24448 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
24449 ++ if (ret == 1)
24450 ++ return 1;
24451 ++ else if (ret == 2)
24452 ++ goto denied;
24453 ++ }
24454 ++ }
24455 ++
24456 ++denied:
24457 ++ if (mode == GR_BIND)
24458 ++ 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));
24459 ++ else if (mode == GR_CONNECT)
24460 ++ 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));
24461 ++
24462 ++ return 0;
24463 ++}
24464 ++
24465 ++int
24466 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
24467 ++{
24468 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
24469 ++}
24470 ++
24471 ++int
24472 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
24473 ++{
24474 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
24475 ++}
24476 ++
24477 ++int gr_search_listen(const struct socket *sock)
24478 ++{
24479 ++ struct sock *sk = sock->sk;
24480 ++ struct sockaddr_in addr;
24481 ++
24482 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24483 ++ addr.sin_port = inet_sk(sk)->sport;
24484 ++
24485 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
24486 ++}
24487 ++
24488 ++int gr_search_accept(const struct socket *sock)
24489 ++{
24490 ++ struct sock *sk = sock->sk;
24491 ++ struct sockaddr_in addr;
24492 ++
24493 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
24494 ++ addr.sin_port = inet_sk(sk)->sport;
24495 ++
24496 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
24497 ++}
24498 ++
24499 ++int
24500 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
24501 ++{
24502 ++ if (addr)
24503 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
24504 ++ else {
24505 ++ struct sockaddr_in sin;
24506 ++ const struct inet_sock *inet = inet_sk(sk);
24507 ++
24508 ++ sin.sin_addr.s_addr = inet->daddr;
24509 ++ sin.sin_port = inet->dport;
24510 ++
24511 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
24512 ++ }
24513 ++}
24514 ++
24515 ++int
24516 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
24517 ++{
24518 ++ struct sockaddr_in sin;
24519 ++
24520 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
24521 ++ return 1; // skip this packet
24522 ++
24523 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
24524 ++ sin.sin_port = udp_hdr(skb)->source;
24525 ++
24526 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
24527 ++}
24528 +diff -urNp linux-2.6.26.6/grsecurity/gracl_learn.c linux-2.6.26.6/grsecurity/gracl_learn.c
24529 +--- linux-2.6.26.6/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
24530 ++++ linux-2.6.26.6/grsecurity/gracl_learn.c 2008-10-11 21:54:20.000000000 -0400
24531 +@@ -0,0 +1,211 @@
24532 ++#include <linux/kernel.h>
24533 ++#include <linux/mm.h>
24534 ++#include <linux/sched.h>
24535 ++#include <linux/poll.h>
24536 ++#include <linux/smp_lock.h>
24537 ++#include <linux/string.h>
24538 ++#include <linux/file.h>
24539 ++#include <linux/types.h>
24540 ++#include <linux/vmalloc.h>
24541 ++#include <linux/grinternal.h>
24542 ++
24543 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
24544 ++ size_t count, loff_t *ppos);
24545 ++extern int gr_acl_is_enabled(void);
24546 ++
24547 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
24548 ++static int gr_learn_attached;
24549 ++
24550 ++/* use a 512k buffer */
24551 ++#define LEARN_BUFFER_SIZE (512 * 1024)
24552 ++
24553 ++static DEFINE_SPINLOCK(gr_learn_lock);
24554 ++static DECLARE_MUTEX(gr_learn_user_sem);
24555 ++
24556 ++/* we need to maintain two buffers, so that the kernel context of grlearn
24557 ++ uses a semaphore around the userspace copying, and the other kernel contexts
24558 ++ use a spinlock when copying into the buffer, since they cannot sleep
24559 ++*/
24560 ++static char *learn_buffer;
24561 ++static char *learn_buffer_user;
24562 ++static int learn_buffer_len;
24563 ++static int learn_buffer_user_len;
24564 ++
24565 ++static ssize_t
24566 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
24567 ++{
24568 ++ DECLARE_WAITQUEUE(wait, current);
24569 ++ ssize_t retval = 0;
24570 ++
24571 ++ add_wait_queue(&learn_wait, &wait);
24572 ++ set_current_state(TASK_INTERRUPTIBLE);
24573 ++ do {
24574 ++ down(&gr_learn_user_sem);
24575 ++ spin_lock(&gr_learn_lock);
24576 ++ if (learn_buffer_len)
24577 ++ break;
24578 ++ spin_unlock(&gr_learn_lock);
24579 ++ up(&gr_learn_user_sem);
24580 ++ if (file->f_flags & O_NONBLOCK) {
24581 ++ retval = -EAGAIN;
24582 ++ goto out;
24583 ++ }
24584 ++ if (signal_pending(current)) {
24585 ++ retval = -ERESTARTSYS;
24586 ++ goto out;
24587 ++ }
24588 ++
24589 ++ schedule();
24590 ++ } while (1);
24591 ++
24592 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
24593 ++ learn_buffer_user_len = learn_buffer_len;
24594 ++ retval = learn_buffer_len;
24595 ++ learn_buffer_len = 0;
24596 ++
24597 ++ spin_unlock(&gr_learn_lock);
24598 ++
24599 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
24600 ++ retval = -EFAULT;
24601 ++
24602 ++ up(&gr_learn_user_sem);
24603 ++out:
24604 ++ set_current_state(TASK_RUNNING);
24605 ++ remove_wait_queue(&learn_wait, &wait);
24606 ++ return retval;
24607 ++}
24608 ++
24609 ++static unsigned int
24610 ++poll_learn(struct file * file, poll_table * wait)
24611 ++{
24612 ++ poll_wait(file, &learn_wait, wait);
24613 ++
24614 ++ if (learn_buffer_len)
24615 ++ return (POLLIN | POLLRDNORM);
24616 ++
24617 ++ return 0;
24618 ++}
24619 ++
24620 ++void
24621 ++gr_clear_learn_entries(void)
24622 ++{
24623 ++ char *tmp;
24624 ++
24625 ++ down(&gr_learn_user_sem);
24626 ++ if (learn_buffer != NULL) {
24627 ++ spin_lock(&gr_learn_lock);
24628 ++ tmp = learn_buffer;
24629 ++ learn_buffer = NULL;
24630 ++ spin_unlock(&gr_learn_lock);
24631 ++ vfree(learn_buffer);
24632 ++ }
24633 ++ if (learn_buffer_user != NULL) {
24634 ++ vfree(learn_buffer_user);
24635 ++ learn_buffer_user = NULL;
24636 ++ }
24637 ++ learn_buffer_len = 0;
24638 ++ up(&gr_learn_user_sem);
24639 ++
24640 ++ return;
24641 ++}
24642 ++
24643 ++void
24644 ++gr_add_learn_entry(const char *fmt, ...)
24645 ++{
24646 ++ va_list args;
24647 ++ unsigned int len;
24648 ++
24649 ++ if (!gr_learn_attached)
24650 ++ return;
24651 ++
24652 ++ spin_lock(&gr_learn_lock);
24653 ++
24654 ++ /* leave a gap at the end so we know when it's "full" but don't have to
24655 ++ compute the exact length of the string we're trying to append
24656 ++ */
24657 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
24658 ++ spin_unlock(&gr_learn_lock);
24659 ++ wake_up_interruptible(&learn_wait);
24660 ++ return;
24661 ++ }
24662 ++ if (learn_buffer == NULL) {
24663 ++ spin_unlock(&gr_learn_lock);
24664 ++ return;
24665 ++ }
24666 ++
24667 ++ va_start(args, fmt);
24668 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
24669 ++ va_end(args);
24670 ++
24671 ++ learn_buffer_len += len + 1;
24672 ++
24673 ++ spin_unlock(&gr_learn_lock);
24674 ++ wake_up_interruptible(&learn_wait);
24675 ++
24676 ++ return;
24677 ++}
24678 ++
24679 ++static int
24680 ++open_learn(struct inode *inode, struct file *file)
24681 ++{
24682 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
24683 ++ return -EBUSY;
24684 ++ if (file->f_mode & FMODE_READ) {
24685 ++ int retval = 0;
24686 ++ down(&gr_learn_user_sem);
24687 ++ if (learn_buffer == NULL)
24688 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
24689 ++ if (learn_buffer_user == NULL)
24690 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
24691 ++ if (learn_buffer == NULL) {
24692 ++ retval = -ENOMEM;
24693 ++ goto out_error;
24694 ++ }
24695 ++ if (learn_buffer_user == NULL) {
24696 ++ retval = -ENOMEM;
24697 ++ goto out_error;
24698 ++ }
24699 ++ learn_buffer_len = 0;
24700 ++ learn_buffer_user_len = 0;
24701 ++ gr_learn_attached = 1;
24702 ++out_error:
24703 ++ up(&gr_learn_user_sem);
24704 ++ return retval;
24705 ++ }
24706 ++ return 0;
24707 ++}
24708 ++
24709 ++static int
24710 ++close_learn(struct inode *inode, struct file *file)
24711 ++{
24712 ++ char *tmp;
24713 ++
24714 ++ if (file->f_mode & FMODE_READ) {
24715 ++ down(&gr_learn_user_sem);
24716 ++ if (learn_buffer != NULL) {
24717 ++ spin_lock(&gr_learn_lock);
24718 ++ tmp = learn_buffer;
24719 ++ learn_buffer = NULL;
24720 ++ spin_unlock(&gr_learn_lock);
24721 ++ vfree(tmp);
24722 ++ }
24723 ++ if (learn_buffer_user != NULL) {
24724 ++ vfree(learn_buffer_user);
24725 ++ learn_buffer_user = NULL;
24726 ++ }
24727 ++ learn_buffer_len = 0;
24728 ++ learn_buffer_user_len = 0;
24729 ++ gr_learn_attached = 0;
24730 ++ up(&gr_learn_user_sem);
24731 ++ }
24732 ++
24733 ++ return 0;
24734 ++}
24735 ++
24736 ++struct file_operations grsec_fops = {
24737 ++ .read = read_learn,
24738 ++ .write = write_grsec_handler,
24739 ++ .open = open_learn,
24740 ++ .release = close_learn,
24741 ++ .poll = poll_learn,
24742 ++};
24743 +diff -urNp linux-2.6.26.6/grsecurity/gracl_res.c linux-2.6.26.6/grsecurity/gracl_res.c
24744 +--- linux-2.6.26.6/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
24745 ++++ linux-2.6.26.6/grsecurity/gracl_res.c 2008-10-11 21:54:20.000000000 -0400
24746 +@@ -0,0 +1,45 @@
24747 ++#include <linux/kernel.h>
24748 ++#include <linux/sched.h>
24749 ++#include <linux/gracl.h>
24750 ++#include <linux/grinternal.h>
24751 ++
24752 ++static const char *restab_log[] = {
24753 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
24754 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
24755 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
24756 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
24757 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
24758 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
24759 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
24760 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
24761 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
24762 ++ [RLIMIT_AS] = "RLIMIT_AS",
24763 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
24764 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
24765 ++};
24766 ++
24767 ++void
24768 ++gr_log_resource(const struct task_struct *task,
24769 ++ const int res, const unsigned long wanted, const int gt)
24770 ++{
24771 ++ if (res == RLIMIT_NPROC &&
24772 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
24773 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
24774 ++ return;
24775 ++ else if (res == RLIMIT_MEMLOCK &&
24776 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
24777 ++ return;
24778 ++
24779 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
24780 ++ return;
24781 ++
24782 ++ preempt_disable();
24783 ++
24784 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
24785 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
24786 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
24787 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
24788 ++ preempt_enable_no_resched();
24789 ++
24790 ++ return;
24791 ++}
24792 +diff -urNp linux-2.6.26.6/grsecurity/gracl_segv.c linux-2.6.26.6/grsecurity/gracl_segv.c
24793 +--- linux-2.6.26.6/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
24794 ++++ linux-2.6.26.6/grsecurity/gracl_segv.c 2008-10-11 21:54:20.000000000 -0400
24795 +@@ -0,0 +1,304 @@
24796 ++#include <linux/kernel.h>
24797 ++#include <linux/mm.h>
24798 ++#include <asm/uaccess.h>
24799 ++#include <asm/errno.h>
24800 ++#include <asm/mman.h>
24801 ++#include <net/sock.h>
24802 ++#include <linux/file.h>
24803 ++#include <linux/fs.h>
24804 ++#include <linux/net.h>
24805 ++#include <linux/in.h>
24806 ++#include <linux/smp_lock.h>
24807 ++#include <linux/slab.h>
24808 ++#include <linux/types.h>
24809 ++#include <linux/sched.h>
24810 ++#include <linux/timer.h>
24811 ++#include <linux/gracl.h>
24812 ++#include <linux/grsecurity.h>
24813 ++#include <linux/grinternal.h>
24814 ++
24815 ++static struct crash_uid *uid_set;
24816 ++static unsigned short uid_used;
24817 ++static DEFINE_SPINLOCK(gr_uid_lock);
24818 ++extern rwlock_t gr_inode_lock;
24819 ++extern struct acl_subject_label *
24820 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
24821 ++ struct acl_role_label *role);
24822 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
24823 ++
24824 ++int
24825 ++gr_init_uidset(void)
24826 ++{
24827 ++ uid_set =
24828 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
24829 ++ uid_used = 0;
24830 ++
24831 ++ return uid_set ? 1 : 0;
24832 ++}
24833 ++
24834 ++void
24835 ++gr_free_uidset(void)
24836 ++{
24837 ++ if (uid_set)
24838 ++ kfree(uid_set);
24839 ++
24840 ++ return;
24841 ++}
24842 ++
24843 ++int
24844 ++gr_find_uid(const uid_t uid)
24845 ++{
24846 ++ struct crash_uid *tmp = uid_set;
24847 ++ uid_t buid;
24848 ++ int low = 0, high = uid_used - 1, mid;
24849 ++
24850 ++ while (high >= low) {
24851 ++ mid = (low + high) >> 1;
24852 ++ buid = tmp[mid].uid;
24853 ++ if (buid == uid)
24854 ++ return mid;
24855 ++ if (buid > uid)
24856 ++ high = mid - 1;
24857 ++ if (buid < uid)
24858 ++ low = mid + 1;
24859 ++ }
24860 ++
24861 ++ return -1;
24862 ++}
24863 ++
24864 ++static __inline__ void
24865 ++gr_insertsort(void)
24866 ++{
24867 ++ unsigned short i, j;
24868 ++ struct crash_uid index;
24869 ++
24870 ++ for (i = 1; i < uid_used; i++) {
24871 ++ index = uid_set[i];
24872 ++ j = i;
24873 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
24874 ++ uid_set[j] = uid_set[j - 1];
24875 ++ j--;
24876 ++ }
24877 ++ uid_set[j] = index;
24878 ++ }
24879 ++
24880 ++ return;
24881 ++}
24882 ++
24883 ++static __inline__ void
24884 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
24885 ++{
24886 ++ int loc;
24887 ++
24888 ++ if (uid_used == GR_UIDTABLE_MAX)
24889 ++ return;
24890 ++
24891 ++ loc = gr_find_uid(uid);
24892 ++
24893 ++ if (loc >= 0) {
24894 ++ uid_set[loc].expires = expires;
24895 ++ return;
24896 ++ }
24897 ++
24898 ++ uid_set[uid_used].uid = uid;
24899 ++ uid_set[uid_used].expires = expires;
24900 ++ uid_used++;
24901 ++
24902 ++ gr_insertsort();
24903 ++
24904 ++ return;
24905 ++}
24906 ++
24907 ++void
24908 ++gr_remove_uid(const unsigned short loc)
24909 ++{
24910 ++ unsigned short i;
24911 ++
24912 ++ for (i = loc + 1; i < uid_used; i++)
24913 ++ uid_set[i - 1] = uid_set[i];
24914 ++
24915 ++ uid_used--;
24916 ++
24917 ++ return;
24918 ++}
24919 ++
24920 ++int
24921 ++gr_check_crash_uid(const uid_t uid)
24922 ++{
24923 ++ int loc;
24924 ++ int ret = 0;
24925 ++
24926 ++ if (unlikely(!gr_acl_is_enabled()))
24927 ++ return 0;
24928 ++
24929 ++ spin_lock(&gr_uid_lock);
24930 ++ loc = gr_find_uid(uid);
24931 ++
24932 ++ if (loc < 0)
24933 ++ goto out_unlock;
24934 ++
24935 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
24936 ++ gr_remove_uid(loc);
24937 ++ else
24938 ++ ret = 1;
24939 ++
24940 ++out_unlock:
24941 ++ spin_unlock(&gr_uid_lock);
24942 ++ return ret;
24943 ++}
24944 ++
24945 ++static __inline__ int
24946 ++proc_is_setxid(const struct task_struct *task)
24947 ++{
24948 ++ if (task->uid != task->euid || task->uid != task->suid ||
24949 ++ task->uid != task->fsuid)
24950 ++ return 1;
24951 ++ if (task->gid != task->egid || task->gid != task->sgid ||
24952 ++ task->gid != task->fsgid)
24953 ++ return 1;
24954 ++
24955 ++ return 0;
24956 ++}
24957 ++static __inline__ int
24958 ++gr_fake_force_sig(int sig, struct task_struct *t)
24959 ++{
24960 ++ unsigned long int flags;
24961 ++ int ret, blocked, ignored;
24962 ++ struct k_sigaction *action;
24963 ++
24964 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
24965 ++ action = &t->sighand->action[sig-1];
24966 ++ ignored = action->sa.sa_handler == SIG_IGN;
24967 ++ blocked = sigismember(&t->blocked, sig);
24968 ++ if (blocked || ignored) {
24969 ++ action->sa.sa_handler = SIG_DFL;
24970 ++ if (blocked) {
24971 ++ sigdelset(&t->blocked, sig);
24972 ++ recalc_sigpending_and_wake(t);
24973 ++ }
24974 ++ }
24975 ++ if (action->sa.sa_handler == SIG_DFL)
24976 ++ t->signal->flags &= ~SIGNAL_UNKILLABLE;
24977 ++ ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
24978 ++
24979 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
24980 ++
24981 ++ return ret;
24982 ++}
24983 ++
24984 ++void
24985 ++gr_handle_crash(struct task_struct *task, const int sig)
24986 ++{
24987 ++ struct acl_subject_label *curr;
24988 ++ struct acl_subject_label *curr2;
24989 ++ struct task_struct *tsk, *tsk2;
24990 ++
24991 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
24992 ++ return;
24993 ++
24994 ++ if (unlikely(!gr_acl_is_enabled()))
24995 ++ return;
24996 ++
24997 ++ curr = task->acl;
24998 ++
24999 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
25000 ++ return;
25001 ++
25002 ++ if (time_before_eq(curr->expires, get_seconds())) {
25003 ++ curr->expires = 0;
25004 ++ curr->crashes = 0;
25005 ++ }
25006 ++
25007 ++ curr->crashes++;
25008 ++
25009 ++ if (!curr->expires)
25010 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
25011 ++
25012 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25013 ++ time_after(curr->expires, get_seconds())) {
25014 ++ if (task->uid && proc_is_setxid(task)) {
25015 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25016 ++ spin_lock(&gr_uid_lock);
25017 ++ gr_insert_uid(task->uid, curr->expires);
25018 ++ spin_unlock(&gr_uid_lock);
25019 ++ curr->expires = 0;
25020 ++ curr->crashes = 0;
25021 ++ read_lock(&tasklist_lock);
25022 ++ do_each_thread(tsk2, tsk) {
25023 ++ if (tsk != task && tsk->uid == task->uid)
25024 ++ gr_fake_force_sig(SIGKILL, tsk);
25025 ++ } while_each_thread(tsk2, tsk);
25026 ++ read_unlock(&tasklist_lock);
25027 ++ } else {
25028 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
25029 ++ read_lock(&tasklist_lock);
25030 ++ do_each_thread(tsk2, tsk) {
25031 ++ if (likely(tsk != task)) {
25032 ++ curr2 = tsk->acl;
25033 ++
25034 ++ if (curr2->device == curr->device &&
25035 ++ curr2->inode == curr->inode)
25036 ++ gr_fake_force_sig(SIGKILL, tsk);
25037 ++ }
25038 ++ } while_each_thread(tsk2, tsk);
25039 ++ read_unlock(&tasklist_lock);
25040 ++ }
25041 ++ }
25042 ++
25043 ++ return;
25044 ++}
25045 ++
25046 ++int
25047 ++gr_check_crash_exec(const struct file *filp)
25048 ++{
25049 ++ struct acl_subject_label *curr;
25050 ++
25051 ++ if (unlikely(!gr_acl_is_enabled()))
25052 ++ return 0;
25053 ++
25054 ++ read_lock(&gr_inode_lock);
25055 ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
25056 ++ filp->f_path.dentry->d_inode->i_sb->s_dev,
25057 ++ current->role);
25058 ++ read_unlock(&gr_inode_lock);
25059 ++
25060 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
25061 ++ (!curr->crashes && !curr->expires))
25062 ++ return 0;
25063 ++
25064 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
25065 ++ time_after(curr->expires, get_seconds()))
25066 ++ return 1;
25067 ++ else if (time_before_eq(curr->expires, get_seconds())) {
25068 ++ curr->crashes = 0;
25069 ++ curr->expires = 0;
25070 ++ }
25071 ++
25072 ++ return 0;
25073 ++}
25074 ++
25075 ++void
25076 ++gr_handle_alertkill(struct task_struct *task)
25077 ++{
25078 ++ struct acl_subject_label *curracl;
25079 ++ __u32 curr_ip;
25080 ++ struct task_struct *p, *p2;
25081 ++
25082 ++ if (unlikely(!gr_acl_is_enabled()))
25083 ++ return;
25084 ++
25085 ++ curracl = task->acl;
25086 ++ curr_ip = task->signal->curr_ip;
25087 ++
25088 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
25089 ++ read_lock(&tasklist_lock);
25090 ++ do_each_thread(p2, p) {
25091 ++ if (p->signal->curr_ip == curr_ip)
25092 ++ gr_fake_force_sig(SIGKILL, p);
25093 ++ } while_each_thread(p2, p);
25094 ++ read_unlock(&tasklist_lock);
25095 ++ } else if (curracl->mode & GR_KILLPROC)
25096 ++ gr_fake_force_sig(SIGKILL, task);
25097 ++
25098 ++ return;
25099 ++}
25100 +diff -urNp linux-2.6.26.6/grsecurity/gracl_shm.c linux-2.6.26.6/grsecurity/gracl_shm.c
25101 +--- linux-2.6.26.6/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
25102 ++++ linux-2.6.26.6/grsecurity/gracl_shm.c 2008-10-11 21:54:20.000000000 -0400
25103 +@@ -0,0 +1,33 @@
25104 ++#include <linux/kernel.h>
25105 ++#include <linux/mm.h>
25106 ++#include <linux/sched.h>
25107 ++#include <linux/file.h>
25108 ++#include <linux/ipc.h>
25109 ++#include <linux/gracl.h>
25110 ++#include <linux/grsecurity.h>
25111 ++#include <linux/grinternal.h>
25112 ++
25113 ++int
25114 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25115 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
25116 ++{
25117 ++ struct task_struct *task;
25118 ++
25119 ++ if (!gr_acl_is_enabled())
25120 ++ return 1;
25121 ++
25122 ++ task = find_task_by_pid(shm_cprid);
25123 ++
25124 ++ if (unlikely(!task))
25125 ++ task = find_task_by_pid(shm_lapid);
25126 ++
25127 ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
25128 ++ (task->pid == shm_lapid)) &&
25129 ++ (task->acl->mode & GR_PROTSHM) &&
25130 ++ (task->acl != current->acl))) {
25131 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
25132 ++ return 0;
25133 ++ }
25134 ++
25135 ++ return 1;
25136 ++}
25137 +diff -urNp linux-2.6.26.6/grsecurity/grsec_chdir.c linux-2.6.26.6/grsecurity/grsec_chdir.c
25138 +--- linux-2.6.26.6/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
25139 ++++ linux-2.6.26.6/grsecurity/grsec_chdir.c 2008-10-11 21:54:20.000000000 -0400
25140 +@@ -0,0 +1,19 @@
25141 ++#include <linux/kernel.h>
25142 ++#include <linux/sched.h>
25143 ++#include <linux/fs.h>
25144 ++#include <linux/file.h>
25145 ++#include <linux/grsecurity.h>
25146 ++#include <linux/grinternal.h>
25147 ++
25148 ++void
25149 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
25150 ++{
25151 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25152 ++ if ((grsec_enable_chdir && grsec_enable_group &&
25153 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
25154 ++ !grsec_enable_group)) {
25155 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
25156 ++ }
25157 ++#endif
25158 ++ return;
25159 ++}
25160 +diff -urNp linux-2.6.26.6/grsecurity/grsec_chroot.c linux-2.6.26.6/grsecurity/grsec_chroot.c
25161 +--- linux-2.6.26.6/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
25162 ++++ linux-2.6.26.6/grsecurity/grsec_chroot.c 2008-10-11 21:54:20.000000000 -0400
25163 +@@ -0,0 +1,336 @@
25164 ++#include <linux/kernel.h>
25165 ++#include <linux/module.h>
25166 ++#include <linux/sched.h>
25167 ++#include <linux/file.h>
25168 ++#include <linux/fs.h>
25169 ++#include <linux/mount.h>
25170 ++#include <linux/types.h>
25171 ++#include <linux/pid_namespace.h>
25172 ++#include <linux/grsecurity.h>
25173 ++#include <linux/grinternal.h>
25174 ++
25175 ++int
25176 ++gr_handle_chroot_unix(const pid_t pid)
25177 ++{
25178 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
25179 ++ struct pid *spid = NULL;
25180 ++
25181 ++ if (unlikely(!grsec_enable_chroot_unix))
25182 ++ return 1;
25183 ++
25184 ++ if (likely(!proc_is_chrooted(current)))
25185 ++ return 1;
25186 ++
25187 ++ read_lock(&tasklist_lock);
25188 ++
25189 ++ spid = find_pid(pid);
25190 ++ if (spid) {
25191 ++ struct task_struct *p;
25192 ++ p = pid_task(spid, PIDTYPE_PID);
25193 ++ task_lock(p);
25194 ++ if (unlikely(!have_same_root(current, p))) {
25195 ++ task_unlock(p);
25196 ++ read_unlock(&tasklist_lock);
25197 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
25198 ++ return 0;
25199 ++ }
25200 ++ task_unlock(p);
25201 ++ }
25202 ++ read_unlock(&tasklist_lock);
25203 ++#endif
25204 ++ return 1;
25205 ++}
25206 ++
25207 ++int
25208 ++gr_handle_chroot_nice(void)
25209 ++{
25210 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25211 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
25212 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
25213 ++ return -EPERM;
25214 ++ }
25215 ++#endif
25216 ++ return 0;
25217 ++}
25218 ++
25219 ++int
25220 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
25221 ++{
25222 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25223 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
25224 ++ && proc_is_chrooted(current)) {
25225 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
25226 ++ return -EACCES;
25227 ++ }
25228 ++#endif
25229 ++ return 0;
25230 ++}
25231 ++
25232 ++int
25233 ++gr_handle_chroot_rawio(const struct inode *inode)
25234 ++{
25235 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25236 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
25237 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
25238 ++ return 1;
25239 ++#endif
25240 ++ return 0;
25241 ++}
25242 ++
25243 ++int
25244 ++gr_pid_is_chrooted(struct task_struct *p)
25245 ++{
25246 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25247 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
25248 ++ return 0;
25249 ++
25250 ++ task_lock(p);
25251 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
25252 ++ !have_same_root(current, p)) {
25253 ++ task_unlock(p);
25254 ++ return 1;
25255 ++ }
25256 ++ task_unlock(p);
25257 ++#endif
25258 ++ return 0;
25259 ++}
25260 ++
25261 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
25262 ++
25263 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
25264 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
25265 ++{
25266 ++ struct dentry *dentry = (struct dentry *)u_dentry;
25267 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
25268 ++ struct dentry *realroot;
25269 ++ struct vfsmount *realrootmnt;
25270 ++ struct dentry *currentroot;
25271 ++ struct vfsmount *currentmnt;
25272 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
25273 ++ int ret = 1;
25274 ++
25275 ++ read_lock(&reaper->fs->lock);
25276 ++ realrootmnt = mntget(reaper->fs->root.mnt);
25277 ++ realroot = dget(reaper->fs->root.dentry);
25278 ++ read_unlock(&reaper->fs->lock);
25279 ++
25280 ++ read_lock(&current->fs->lock);
25281 ++ currentmnt = mntget(current->fs->root.mnt);
25282 ++ currentroot = dget(current->fs->root.dentry);
25283 ++ read_unlock(&current->fs->lock);
25284 ++
25285 ++ spin_lock(&dcache_lock);
25286 ++ for (;;) {
25287 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
25288 ++ || (dentry == currentroot && mnt == currentmnt)))
25289 ++ break;
25290 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
25291 ++ if (mnt->mnt_parent == mnt)
25292 ++ break;
25293 ++ dentry = mnt->mnt_mountpoint;
25294 ++ mnt = mnt->mnt_parent;
25295 ++ continue;
25296 ++ }
25297 ++ dentry = dentry->d_parent;
25298 ++ }
25299 ++ spin_unlock(&dcache_lock);
25300 ++
25301 ++ dput(currentroot);
25302 ++ mntput(currentmnt);
25303 ++
25304 ++ /* access is outside of chroot */
25305 ++ if (dentry == realroot && mnt == realrootmnt)
25306 ++ ret = 0;
25307 ++
25308 ++ dput(realroot);
25309 ++ mntput(realrootmnt);
25310 ++ return ret;
25311 ++}
25312 ++#endif
25313 ++
25314 ++int
25315 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
25316 ++{
25317 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
25318 ++ if (!grsec_enable_chroot_fchdir)
25319 ++ return 1;
25320 ++
25321 ++ if (!proc_is_chrooted(current))
25322 ++ return 1;
25323 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
25324 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
25325 ++ return 0;
25326 ++ }
25327 ++#endif
25328 ++ return 1;
25329 ++}
25330 ++
25331 ++int
25332 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25333 ++ const time_t shm_createtime)
25334 ++{
25335 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
25336 ++ struct pid *pid = NULL;
25337 ++ time_t starttime;
25338 ++
25339 ++ if (unlikely(!grsec_enable_chroot_shmat))
25340 ++ return 1;
25341 ++
25342 ++ if (likely(!proc_is_chrooted(current)))
25343 ++ return 1;
25344 ++
25345 ++ read_lock(&tasklist_lock);
25346 ++
25347 ++ pid = find_pid(shm_cprid);
25348 ++ if (pid) {
25349 ++ struct task_struct *p;
25350 ++ p = pid_task(pid, PIDTYPE_PID);
25351 ++ task_lock(p);
25352 ++ starttime = p->start_time.tv_sec;
25353 ++ if (unlikely(!have_same_root(current, p) &&
25354 ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
25355 ++ task_unlock(p);
25356 ++ read_unlock(&tasklist_lock);
25357 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25358 ++ return 0;
25359 ++ }
25360 ++ task_unlock(p);
25361 ++ } else {
25362 ++ pid = find_pid(shm_lapid);
25363 ++ if (pid) {
25364 ++ struct task_struct *p;
25365 ++ p = pid_task(pid, PIDTYPE_PID);
25366 ++ task_lock(p);
25367 ++ if (unlikely(!have_same_root(current, p))) {
25368 ++ task_unlock(p);
25369 ++ read_unlock(&tasklist_lock);
25370 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
25371 ++ return 0;
25372 ++ }
25373 ++ task_unlock(p);
25374 ++ }
25375 ++ }
25376 ++
25377 ++ read_unlock(&tasklist_lock);
25378 ++#endif
25379 ++ return 1;
25380 ++}
25381 ++
25382 ++void
25383 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
25384 ++{
25385 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25386 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
25387 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
25388 ++#endif
25389 ++ return;
25390 ++}
25391 ++
25392 ++int
25393 ++gr_handle_chroot_mknod(const struct dentry *dentry,
25394 ++ const struct vfsmount *mnt, const int mode)
25395 ++{
25396 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25397 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
25398 ++ proc_is_chrooted(current)) {
25399 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
25400 ++ return -EPERM;
25401 ++ }
25402 ++#endif
25403 ++ return 0;
25404 ++}
25405 ++
25406 ++int
25407 ++gr_handle_chroot_mount(const struct dentry *dentry,
25408 ++ const struct vfsmount *mnt, const char *dev_name)
25409 ++{
25410 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
25411 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
25412 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
25413 ++ return -EPERM;
25414 ++ }
25415 ++#endif
25416 ++ return 0;
25417 ++}
25418 ++
25419 ++int
25420 ++gr_handle_chroot_pivot(void)
25421 ++{
25422 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25423 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
25424 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
25425 ++ return -EPERM;
25426 ++ }
25427 ++#endif
25428 ++ return 0;
25429 ++}
25430 ++
25431 ++int
25432 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
25433 ++{
25434 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
25435 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
25436 ++ !gr_is_outside_chroot(dentry, mnt)) {
25437 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
25438 ++ return -EPERM;
25439 ++ }
25440 ++#endif
25441 ++ return 0;
25442 ++}
25443 ++
25444 ++void
25445 ++gr_handle_chroot_caps(struct task_struct *task)
25446 ++{
25447 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25448 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
25449 ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
25450 ++ task->cap_permitted =
25451 ++ cap_drop(task->cap_permitted, chroot_caps);
25452 ++ task->cap_inheritable =
25453 ++ cap_drop(task->cap_inheritable, chroot_caps);
25454 ++ task->cap_effective =
25455 ++ cap_drop(task->cap_effective, chroot_caps);
25456 ++ }
25457 ++#endif
25458 ++ return;
25459 ++}
25460 ++
25461 ++int
25462 ++gr_handle_chroot_sysctl(const int op)
25463 ++{
25464 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25465 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
25466 ++ && (op & 002))
25467 ++ return -EACCES;
25468 ++#endif
25469 ++ return 0;
25470 ++}
25471 ++
25472 ++void
25473 ++gr_handle_chroot_chdir(struct path *path)
25474 ++{
25475 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25476 ++ if (grsec_enable_chroot_chdir)
25477 ++ set_fs_pwd(current->fs, path);
25478 ++#endif
25479 ++ return;
25480 ++}
25481 ++
25482 ++int
25483 ++gr_handle_chroot_chmod(const struct dentry *dentry,
25484 ++ const struct vfsmount *mnt, const int mode)
25485 ++{
25486 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25487 ++ if (grsec_enable_chroot_chmod &&
25488 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
25489 ++ proc_is_chrooted(current)) {
25490 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
25491 ++ return -EPERM;
25492 ++ }
25493 ++#endif
25494 ++ return 0;
25495 ++}
25496 ++
25497 ++#ifdef CONFIG_SECURITY
25498 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
25499 ++#endif
25500 +diff -urNp linux-2.6.26.6/grsecurity/grsec_disabled.c linux-2.6.26.6/grsecurity/grsec_disabled.c
25501 +--- linux-2.6.26.6/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
25502 ++++ linux-2.6.26.6/grsecurity/grsec_disabled.c 2008-10-11 21:54:20.000000000 -0400
25503 +@@ -0,0 +1,418 @@
25504 ++#include <linux/kernel.h>
25505 ++#include <linux/module.h>
25506 ++#include <linux/sched.h>
25507 ++#include <linux/file.h>
25508 ++#include <linux/fs.h>
25509 ++#include <linux/kdev_t.h>
25510 ++#include <linux/net.h>
25511 ++#include <linux/in.h>
25512 ++#include <linux/ip.h>
25513 ++#include <linux/skbuff.h>
25514 ++#include <linux/sysctl.h>
25515 ++
25516 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
25517 ++void
25518 ++pax_set_initial_flags(struct linux_binprm *bprm)
25519 ++{
25520 ++ return;
25521 ++}
25522 ++#endif
25523 ++
25524 ++#ifdef CONFIG_SYSCTL
25525 ++__u32
25526 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
25527 ++{
25528 ++ return 0;
25529 ++}
25530 ++#endif
25531 ++
25532 ++int
25533 ++gr_acl_is_enabled(void)
25534 ++{
25535 ++ return 0;
25536 ++}
25537 ++
25538 ++int
25539 ++gr_handle_rawio(const struct inode *inode)
25540 ++{
25541 ++ return 0;
25542 ++}
25543 ++
25544 ++void
25545 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
25546 ++{
25547 ++ return;
25548 ++}
25549 ++
25550 ++int
25551 ++gr_handle_ptrace(struct task_struct *task, const long request)
25552 ++{
25553 ++ return 0;
25554 ++}
25555 ++
25556 ++int
25557 ++gr_handle_proc_ptrace(struct task_struct *task)
25558 ++{
25559 ++ return 0;
25560 ++}
25561 ++
25562 ++void
25563 ++gr_learn_resource(const struct task_struct *task,
25564 ++ const int res, const unsigned long wanted, const int gt)
25565 ++{
25566 ++ return;
25567 ++}
25568 ++
25569 ++int
25570 ++gr_set_acls(const int type)
25571 ++{
25572 ++ return 0;
25573 ++}
25574 ++
25575 ++int
25576 ++gr_check_hidden_task(const struct task_struct *tsk)
25577 ++{
25578 ++ return 0;
25579 ++}
25580 ++
25581 ++int
25582 ++gr_check_protected_task(const struct task_struct *task)
25583 ++{
25584 ++ return 0;
25585 ++}
25586 ++
25587 ++void
25588 ++gr_copy_label(struct task_struct *tsk)
25589 ++{
25590 ++ return;
25591 ++}
25592 ++
25593 ++void
25594 ++gr_set_pax_flags(struct task_struct *task)
25595 ++{
25596 ++ return;
25597 ++}
25598 ++
25599 ++int
25600 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
25601 ++{
25602 ++ return 0;
25603 ++}
25604 ++
25605 ++void
25606 ++gr_handle_delete(const ino_t ino, const dev_t dev)
25607 ++{
25608 ++ return;
25609 ++}
25610 ++
25611 ++void
25612 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
25613 ++{
25614 ++ return;
25615 ++}
25616 ++
25617 ++void
25618 ++gr_handle_crash(struct task_struct *task, const int sig)
25619 ++{
25620 ++ return;
25621 ++}
25622 ++
25623 ++int
25624 ++gr_check_crash_exec(const struct file *filp)
25625 ++{
25626 ++ return 0;
25627 ++}
25628 ++
25629 ++int
25630 ++gr_check_crash_uid(const uid_t uid)
25631 ++{
25632 ++ return 0;
25633 ++}
25634 ++
25635 ++void
25636 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
25637 ++ struct dentry *old_dentry,
25638 ++ struct dentry *new_dentry,
25639 ++ struct vfsmount *mnt, const __u8 replace)
25640 ++{
25641 ++ return;
25642 ++}
25643 ++
25644 ++int
25645 ++gr_search_socket(const int family, const int type, const int protocol)
25646 ++{
25647 ++ return 1;
25648 ++}
25649 ++
25650 ++int
25651 ++gr_search_connectbind(const int mode, const struct socket *sock,
25652 ++ const struct sockaddr_in *addr)
25653 ++{
25654 ++ return 1;
25655 ++}
25656 ++
25657 ++int
25658 ++gr_task_is_capable(struct task_struct *task, const int cap)
25659 ++{
25660 ++ return 1;
25661 ++}
25662 ++
25663 ++int
25664 ++gr_is_capable_nolog(const int cap)
25665 ++{
25666 ++ return 1;
25667 ++}
25668 ++
25669 ++void
25670 ++gr_handle_alertkill(struct task_struct *task)
25671 ++{
25672 ++ return;
25673 ++}
25674 ++
25675 ++__u32
25676 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
25677 ++{
25678 ++ return 1;
25679 ++}
25680 ++
25681 ++__u32
25682 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
25683 ++ const struct vfsmount * mnt)
25684 ++{
25685 ++ return 1;
25686 ++}
25687 ++
25688 ++__u32
25689 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
25690 ++ const int fmode)
25691 ++{
25692 ++ return 1;
25693 ++}
25694 ++
25695 ++__u32
25696 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
25697 ++{
25698 ++ return 1;
25699 ++}
25700 ++
25701 ++__u32
25702 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
25703 ++{
25704 ++ return 1;
25705 ++}
25706 ++
25707 ++int
25708 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
25709 ++ unsigned int *vm_flags)
25710 ++{
25711 ++ return 1;
25712 ++}
25713 ++
25714 ++__u32
25715 ++gr_acl_handle_truncate(const struct dentry * dentry,
25716 ++ const struct vfsmount * mnt)
25717 ++{
25718 ++ return 1;
25719 ++}
25720 ++
25721 ++__u32
25722 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
25723 ++{
25724 ++ return 1;
25725 ++}
25726 ++
25727 ++__u32
25728 ++gr_acl_handle_access(const struct dentry * dentry,
25729 ++ const struct vfsmount * mnt, const int fmode)
25730 ++{
25731 ++ return 1;
25732 ++}
25733 ++
25734 ++__u32
25735 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
25736 ++ mode_t mode)
25737 ++{
25738 ++ return 1;
25739 ++}
25740 ++
25741 ++__u32
25742 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
25743 ++ mode_t mode)
25744 ++{
25745 ++ return 1;
25746 ++}
25747 ++
25748 ++__u32
25749 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
25750 ++{
25751 ++ return 1;
25752 ++}
25753 ++
25754 ++void
25755 ++grsecurity_init(void)
25756 ++{
25757 ++ return;
25758 ++}
25759 ++
25760 ++__u32
25761 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
25762 ++ const struct dentry * parent_dentry,
25763 ++ const struct vfsmount * parent_mnt,
25764 ++ const int mode)
25765 ++{
25766 ++ return 1;
25767 ++}
25768 ++
25769 ++__u32
25770 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
25771 ++ const struct dentry * parent_dentry,
25772 ++ const struct vfsmount * parent_mnt)
25773 ++{
25774 ++ return 1;
25775 ++}
25776 ++
25777 ++__u32
25778 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
25779 ++ const struct dentry * parent_dentry,
25780 ++ const struct vfsmount * parent_mnt, const char *from)
25781 ++{
25782 ++ return 1;
25783 ++}
25784 ++
25785 ++__u32
25786 ++gr_acl_handle_link(const struct dentry * new_dentry,
25787 ++ const struct dentry * parent_dentry,
25788 ++ const struct vfsmount * parent_mnt,
25789 ++ const struct dentry * old_dentry,
25790 ++ const struct vfsmount * old_mnt, const char *to)
25791 ++{
25792 ++ return 1;
25793 ++}
25794 ++
25795 ++int
25796 ++gr_acl_handle_rename(const struct dentry *new_dentry,
25797 ++ const struct dentry *parent_dentry,
25798 ++ const struct vfsmount *parent_mnt,
25799 ++ const struct dentry *old_dentry,
25800 ++ const struct inode *old_parent_inode,
25801 ++ const struct vfsmount *old_mnt, const char *newname)
25802 ++{
25803 ++ return 0;
25804 ++}
25805 ++
25806 ++int
25807 ++gr_acl_handle_filldir(const struct file *file, const char *name,
25808 ++ const int namelen, const ino_t ino)
25809 ++{
25810 ++ return 1;
25811 ++}
25812 ++
25813 ++int
25814 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
25815 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
25816 ++{
25817 ++ return 1;
25818 ++}
25819 ++
25820 ++int
25821 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
25822 ++{
25823 ++ return 1;
25824 ++}
25825 ++
25826 ++int
25827 ++gr_search_accept(const struct socket *sock)
25828 ++{
25829 ++ return 1;
25830 ++}
25831 ++
25832 ++int
25833 ++gr_search_listen(const struct socket *sock)
25834 ++{
25835 ++ return 1;
25836 ++}
25837 ++
25838 ++int
25839 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
25840 ++{
25841 ++ return 1;
25842 ++}
25843 ++
25844 ++__u32
25845 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
25846 ++{
25847 ++ return 1;
25848 ++}
25849 ++
25850 ++__u32
25851 ++gr_acl_handle_creat(const struct dentry * dentry,
25852 ++ const struct dentry * p_dentry,
25853 ++ const struct vfsmount * p_mnt, const int fmode,
25854 ++ const int imode)
25855 ++{
25856 ++ return 1;
25857 ++}
25858 ++
25859 ++void
25860 ++gr_acl_handle_exit(void)
25861 ++{
25862 ++ return;
25863 ++}
25864 ++
25865 ++int
25866 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
25867 ++{
25868 ++ return 1;
25869 ++}
25870 ++
25871 ++void
25872 ++gr_set_role_label(const uid_t uid, const gid_t gid)
25873 ++{
25874 ++ return;
25875 ++}
25876 ++
25877 ++int
25878 ++gr_acl_handle_procpidmem(const struct task_struct *task)
25879 ++{
25880 ++ return 0;
25881 ++}
25882 ++
25883 ++int
25884 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
25885 ++{
25886 ++ return 1;
25887 ++}
25888 ++
25889 ++int
25890 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
25891 ++{
25892 ++ return 1;
25893 ++}
25894 ++
25895 ++void
25896 ++gr_set_kernel_label(struct task_struct *task)
25897 ++{
25898 ++ return;
25899 ++}
25900 ++
25901 ++int
25902 ++gr_check_user_change(int real, int effective, int fs)
25903 ++{
25904 ++ return 0;
25905 ++}
25906 ++
25907 ++int
25908 ++gr_check_group_change(int real, int effective, int fs)
25909 ++{
25910 ++ return 0;
25911 ++}
25912 ++
25913 ++
25914 ++EXPORT_SYMBOL(gr_task_is_capable);
25915 ++EXPORT_SYMBOL(gr_is_capable_nolog);
25916 ++EXPORT_SYMBOL(gr_learn_resource);
25917 ++EXPORT_SYMBOL(gr_set_kernel_label);
25918 ++#ifdef CONFIG_SECURITY
25919 ++EXPORT_SYMBOL(gr_check_user_change);
25920 ++EXPORT_SYMBOL(gr_check_group_change);
25921 ++#endif
25922 +diff -urNp linux-2.6.26.6/grsecurity/grsec_exec.c linux-2.6.26.6/grsecurity/grsec_exec.c
25923 +--- linux-2.6.26.6/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
25924 ++++ linux-2.6.26.6/grsecurity/grsec_exec.c 2008-10-11 21:54:20.000000000 -0400
25925 +@@ -0,0 +1,88 @@
25926 ++#include <linux/kernel.h>
25927 ++#include <linux/sched.h>
25928 ++#include <linux/file.h>
25929 ++#include <linux/binfmts.h>
25930 ++#include <linux/smp_lock.h>
25931 ++#include <linux/fs.h>
25932 ++#include <linux/types.h>
25933 ++#include <linux/grdefs.h>
25934 ++#include <linux/grinternal.h>
25935 ++#include <linux/capability.h>
25936 ++
25937 ++#include <asm/uaccess.h>
25938 ++
25939 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
25940 ++static char gr_exec_arg_buf[132];
25941 ++static DECLARE_MUTEX(gr_exec_arg_sem);
25942 ++#endif
25943 ++
25944 ++int
25945 ++gr_handle_nproc(void)
25946 ++{
25947 ++#ifdef CONFIG_GRKERNSEC_EXECVE
25948 ++ if (grsec_enable_execve && current->user &&
25949 ++ (atomic_read(&current->user->processes) >
25950 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
25951 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
25952 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
25953 ++ return -EAGAIN;
25954 ++ }
25955 ++#endif
25956 ++ return 0;
25957 ++}
25958 ++
25959 ++void
25960 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
25961 ++{
25962 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
25963 ++ char *grarg = gr_exec_arg_buf;
25964 ++ unsigned int i, x, execlen = 0;
25965 ++ char c;
25966 ++
25967 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
25968 ++ in_group_p(grsec_audit_gid))
25969 ++ || (grsec_enable_execlog && !grsec_enable_group)))
25970 ++ return;
25971 ++
25972 ++ down(&gr_exec_arg_sem);
25973 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
25974 ++
25975 ++ if (unlikely(argv == NULL))
25976 ++ goto log;
25977 ++
25978 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
25979 ++ const char __user *p;
25980 ++ unsigned int len;
25981 ++
25982 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
25983 ++ goto log;
25984 ++ if (!p)
25985 ++ goto log;
25986 ++ len = strnlen_user(p, 128 - execlen);
25987 ++ if (len > 128 - execlen)
25988 ++ len = 128 - execlen;
25989 ++ else if (len > 0)
25990 ++ len--;
25991 ++ if (copy_from_user(grarg + execlen, p, len))
25992 ++ goto log;
25993 ++
25994 ++ /* rewrite unprintable characters */
25995 ++ for (x = 0; x < len; x++) {
25996 ++ c = *(grarg + execlen + x);
25997 ++ if (c < 32 || c > 126)
25998 ++ *(grarg + execlen + x) = ' ';
25999 ++ }
26000 ++
26001 ++ execlen += len;
26002 ++ *(grarg + execlen) = ' ';
26003 ++ *(grarg + execlen + 1) = '\0';
26004 ++ execlen++;
26005 ++ }
26006 ++
26007 ++ log:
26008 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
26009 ++ bprm->file->f_path.mnt, grarg);
26010 ++ up(&gr_exec_arg_sem);
26011 ++#endif
26012 ++ return;
26013 ++}
26014 +diff -urNp linux-2.6.26.6/grsecurity/grsec_fifo.c linux-2.6.26.6/grsecurity/grsec_fifo.c
26015 +--- linux-2.6.26.6/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
26016 ++++ linux-2.6.26.6/grsecurity/grsec_fifo.c 2008-10-11 21:54:20.000000000 -0400
26017 +@@ -0,0 +1,22 @@
26018 ++#include <linux/kernel.h>
26019 ++#include <linux/sched.h>
26020 ++#include <linux/fs.h>
26021 ++#include <linux/file.h>
26022 ++#include <linux/grinternal.h>
26023 ++
26024 ++int
26025 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
26026 ++ const struct dentry *dir, const int flag, const int acc_mode)
26027 ++{
26028 ++#ifdef CONFIG_GRKERNSEC_FIFO
26029 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
26030 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
26031 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
26032 ++ (current->fsuid != dentry->d_inode->i_uid)) {
26033 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
26034 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
26035 ++ return -EACCES;
26036 ++ }
26037 ++#endif
26038 ++ return 0;
26039 ++}
26040 +diff -urNp linux-2.6.26.6/grsecurity/grsec_fork.c linux-2.6.26.6/grsecurity/grsec_fork.c
26041 +--- linux-2.6.26.6/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
26042 ++++ linux-2.6.26.6/grsecurity/grsec_fork.c 2008-10-11 21:54:20.000000000 -0400
26043 +@@ -0,0 +1,15 @@
26044 ++#include <linux/kernel.h>
26045 ++#include <linux/sched.h>
26046 ++#include <linux/grsecurity.h>
26047 ++#include <linux/grinternal.h>
26048 ++#include <linux/errno.h>
26049 ++
26050 ++void
26051 ++gr_log_forkfail(const int retval)
26052 ++{
26053 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
26054 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
26055 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
26056 ++#endif
26057 ++ return;
26058 ++}
26059 +diff -urNp linux-2.6.26.6/grsecurity/grsec_init.c linux-2.6.26.6/grsecurity/grsec_init.c
26060 +--- linux-2.6.26.6/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
26061 ++++ linux-2.6.26.6/grsecurity/grsec_init.c 2008-10-11 21:54:20.000000000 -0400
26062 +@@ -0,0 +1,230 @@
26063 ++#include <linux/kernel.h>
26064 ++#include <linux/sched.h>
26065 ++#include <linux/mm.h>
26066 ++#include <linux/smp_lock.h>
26067 ++#include <linux/gracl.h>
26068 ++#include <linux/slab.h>
26069 ++#include <linux/vmalloc.h>
26070 ++#include <linux/percpu.h>
26071 ++
26072 ++int grsec_enable_link;
26073 ++int grsec_enable_dmesg;
26074 ++int grsec_enable_fifo;
26075 ++int grsec_enable_execve;
26076 ++int grsec_enable_execlog;
26077 ++int grsec_enable_signal;
26078 ++int grsec_enable_forkfail;
26079 ++int grsec_enable_time;
26080 ++int grsec_enable_audit_textrel;
26081 ++int grsec_enable_group;
26082 ++int grsec_audit_gid;
26083 ++int grsec_enable_chdir;
26084 ++int grsec_enable_audit_ipc;
26085 ++int grsec_enable_mount;
26086 ++int grsec_enable_chroot_findtask;
26087 ++int grsec_enable_chroot_mount;
26088 ++int grsec_enable_chroot_shmat;
26089 ++int grsec_enable_chroot_fchdir;
26090 ++int grsec_enable_chroot_double;
26091 ++int grsec_enable_chroot_pivot;
26092 ++int grsec_enable_chroot_chdir;
26093 ++int grsec_enable_chroot_chmod;
26094 ++int grsec_enable_chroot_mknod;
26095 ++int grsec_enable_chroot_nice;
26096 ++int grsec_enable_chroot_execlog;
26097 ++int grsec_enable_chroot_caps;
26098 ++int grsec_enable_chroot_sysctl;
26099 ++int grsec_enable_chroot_unix;
26100 ++int grsec_enable_tpe;
26101 ++int grsec_tpe_gid;
26102 ++int grsec_enable_tpe_all;
26103 ++int grsec_enable_socket_all;
26104 ++int grsec_socket_all_gid;
26105 ++int grsec_enable_socket_client;
26106 ++int grsec_socket_client_gid;
26107 ++int grsec_enable_socket_server;
26108 ++int grsec_socket_server_gid;
26109 ++int grsec_resource_logging;
26110 ++int grsec_lock;
26111 ++
26112 ++DEFINE_SPINLOCK(grsec_alert_lock);
26113 ++unsigned long grsec_alert_wtime = 0;
26114 ++unsigned long grsec_alert_fyet = 0;
26115 ++
26116 ++DEFINE_SPINLOCK(grsec_audit_lock);
26117 ++
26118 ++DEFINE_RWLOCK(grsec_exec_file_lock);
26119 ++
26120 ++char *gr_shared_page[4];
26121 ++
26122 ++char *gr_alert_log_fmt;
26123 ++char *gr_audit_log_fmt;
26124 ++char *gr_alert_log_buf;
26125 ++char *gr_audit_log_buf;
26126 ++
26127 ++extern struct gr_arg *gr_usermode;
26128 ++extern unsigned char *gr_system_salt;
26129 ++extern unsigned char *gr_system_sum;
26130 ++
26131 ++void
26132 ++grsecurity_init(void)
26133 ++{
26134 ++ int j;
26135 ++ /* create the per-cpu shared pages */
26136 ++
26137 ++#ifdef CONFIG_X86
26138 ++ memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
26139 ++#endif
26140 ++
26141 ++ for (j = 0; j < 4; j++) {
26142 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
26143 ++ if (gr_shared_page[j] == NULL) {
26144 ++ panic("Unable to allocate grsecurity shared page");
26145 ++ return;
26146 ++ }
26147 ++ }
26148 ++
26149 ++ /* allocate log buffers */
26150 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
26151 ++ if (!gr_alert_log_fmt) {
26152 ++ panic("Unable to allocate grsecurity alert log format buffer");
26153 ++ return;
26154 ++ }
26155 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
26156 ++ if (!gr_audit_log_fmt) {
26157 ++ panic("Unable to allocate grsecurity audit log format buffer");
26158 ++ return;
26159 ++ }
26160 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26161 ++ if (!gr_alert_log_buf) {
26162 ++ panic("Unable to allocate grsecurity alert log buffer");
26163 ++ return;
26164 ++ }
26165 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
26166 ++ if (!gr_audit_log_buf) {
26167 ++ panic("Unable to allocate grsecurity audit log buffer");
26168 ++ return;
26169 ++ }
26170 ++
26171 ++ /* allocate memory for authentication structure */
26172 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
26173 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
26174 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
26175 ++
26176 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
26177 ++ panic("Unable to allocate grsecurity authentication structure");
26178 ++ return;
26179 ++ }
26180 ++
26181 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
26182 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
26183 ++ grsec_lock = 1;
26184 ++#endif
26185 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
26186 ++ grsec_enable_audit_textrel = 1;
26187 ++#endif
26188 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
26189 ++ grsec_enable_group = 1;
26190 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
26191 ++#endif
26192 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
26193 ++ grsec_enable_chdir = 1;
26194 ++#endif
26195 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26196 ++ grsec_enable_audit_ipc = 1;
26197 ++#endif
26198 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26199 ++ grsec_enable_mount = 1;
26200 ++#endif
26201 ++#ifdef CONFIG_GRKERNSEC_LINK
26202 ++ grsec_enable_link = 1;
26203 ++#endif
26204 ++#ifdef CONFIG_GRKERNSEC_DMESG
26205 ++ grsec_enable_dmesg = 1;
26206 ++#endif
26207 ++#ifdef CONFIG_GRKERNSEC_FIFO
26208 ++ grsec_enable_fifo = 1;
26209 ++#endif
26210 ++#ifdef CONFIG_GRKERNSEC_EXECVE
26211 ++ grsec_enable_execve = 1;
26212 ++#endif
26213 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
26214 ++ grsec_enable_execlog = 1;
26215 ++#endif
26216 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
26217 ++ grsec_enable_signal = 1;
26218 ++#endif
26219 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
26220 ++ grsec_enable_forkfail = 1;
26221 ++#endif
26222 ++#ifdef CONFIG_GRKERNSEC_TIME
26223 ++ grsec_enable_time = 1;
26224 ++#endif
26225 ++#ifdef CONFIG_GRKERNSEC_RESLOG
26226 ++ grsec_resource_logging = 1;
26227 ++#endif
26228 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
26229 ++ grsec_enable_chroot_findtask = 1;
26230 ++#endif
26231 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
26232 ++ grsec_enable_chroot_unix = 1;
26233 ++#endif
26234 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
26235 ++ grsec_enable_chroot_mount = 1;
26236 ++#endif
26237 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
26238 ++ grsec_enable_chroot_fchdir = 1;
26239 ++#endif
26240 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
26241 ++ grsec_enable_chroot_shmat = 1;
26242 ++#endif
26243 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
26244 ++ grsec_enable_chroot_double = 1;
26245 ++#endif
26246 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
26247 ++ grsec_enable_chroot_pivot = 1;
26248 ++#endif
26249 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
26250 ++ grsec_enable_chroot_chdir = 1;
26251 ++#endif
26252 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
26253 ++ grsec_enable_chroot_chmod = 1;
26254 ++#endif
26255 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
26256 ++ grsec_enable_chroot_mknod = 1;
26257 ++#endif
26258 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
26259 ++ grsec_enable_chroot_nice = 1;
26260 ++#endif
26261 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
26262 ++ grsec_enable_chroot_execlog = 1;
26263 ++#endif
26264 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
26265 ++ grsec_enable_chroot_caps = 1;
26266 ++#endif
26267 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
26268 ++ grsec_enable_chroot_sysctl = 1;
26269 ++#endif
26270 ++#ifdef CONFIG_GRKERNSEC_TPE
26271 ++ grsec_enable_tpe = 1;
26272 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
26273 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
26274 ++ grsec_enable_tpe_all = 1;
26275 ++#endif
26276 ++#endif
26277 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
26278 ++ grsec_enable_socket_all = 1;
26279 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
26280 ++#endif
26281 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
26282 ++ grsec_enable_socket_client = 1;
26283 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
26284 ++#endif
26285 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
26286 ++ grsec_enable_socket_server = 1;
26287 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
26288 ++#endif
26289 ++#endif
26290 ++
26291 ++ return;
26292 ++}
26293 +diff -urNp linux-2.6.26.6/grsecurity/grsec_ipc.c linux-2.6.26.6/grsecurity/grsec_ipc.c
26294 +--- linux-2.6.26.6/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
26295 ++++ linux-2.6.26.6/grsecurity/grsec_ipc.c 2008-10-11 21:54:20.000000000 -0400
26296 +@@ -0,0 +1,81 @@
26297 ++#include <linux/kernel.h>
26298 ++#include <linux/sched.h>
26299 ++#include <linux/types.h>
26300 ++#include <linux/ipc.h>
26301 ++#include <linux/grsecurity.h>
26302 ++#include <linux/grinternal.h>
26303 ++
26304 ++void
26305 ++gr_log_msgget(const int ret, const int msgflg)
26306 ++{
26307 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26308 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26309 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26310 ++ !grsec_enable_group)) && (ret >= 0)
26311 ++ && (msgflg & IPC_CREAT))
26312 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
26313 ++#endif
26314 ++ return;
26315 ++}
26316 ++
26317 ++void
26318 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
26319 ++{
26320 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26321 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26322 ++ grsec_enable_audit_ipc) ||
26323 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26324 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
26325 ++#endif
26326 ++ return;
26327 ++}
26328 ++
26329 ++void
26330 ++gr_log_semget(const int err, const int semflg)
26331 ++{
26332 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26333 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26334 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26335 ++ !grsec_enable_group)) && (err >= 0)
26336 ++ && (semflg & IPC_CREAT))
26337 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
26338 ++#endif
26339 ++ return;
26340 ++}
26341 ++
26342 ++void
26343 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
26344 ++{
26345 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26346 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26347 ++ grsec_enable_audit_ipc) ||
26348 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26349 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
26350 ++#endif
26351 ++ return;
26352 ++}
26353 ++
26354 ++void
26355 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
26356 ++{
26357 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26358 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26359 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
26360 ++ !grsec_enable_group)) && (err >= 0)
26361 ++ && (shmflg & IPC_CREAT))
26362 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
26363 ++#endif
26364 ++ return;
26365 ++}
26366 ++
26367 ++void
26368 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
26369 ++{
26370 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
26371 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
26372 ++ grsec_enable_audit_ipc) ||
26373 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
26374 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
26375 ++#endif
26376 ++ return;
26377 ++}
26378 +diff -urNp linux-2.6.26.6/grsecurity/grsec_link.c linux-2.6.26.6/grsecurity/grsec_link.c
26379 +--- linux-2.6.26.6/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
26380 ++++ linux-2.6.26.6/grsecurity/grsec_link.c 2008-10-11 21:54:20.000000000 -0400
26381 +@@ -0,0 +1,39 @@
26382 ++#include <linux/kernel.h>
26383 ++#include <linux/sched.h>
26384 ++#include <linux/fs.h>
26385 ++#include <linux/file.h>
26386 ++#include <linux/grinternal.h>
26387 ++
26388 ++int
26389 ++gr_handle_follow_link(const struct inode *parent,
26390 ++ const struct inode *inode,
26391 ++ const struct dentry *dentry, const struct vfsmount *mnt)
26392 ++{
26393 ++#ifdef CONFIG_GRKERNSEC_LINK
26394 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
26395 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
26396 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
26397 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
26398 ++ return -EACCES;
26399 ++ }
26400 ++#endif
26401 ++ return 0;
26402 ++}
26403 ++
26404 ++int
26405 ++gr_handle_hardlink(const struct dentry *dentry,
26406 ++ const struct vfsmount *mnt,
26407 ++ struct inode *inode, const int mode, const char *to)
26408 ++{
26409 ++#ifdef CONFIG_GRKERNSEC_LINK
26410 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
26411 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
26412 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
26413 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
26414 ++ !capable(CAP_FOWNER) && current->uid) {
26415 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
26416 ++ return -EPERM;
26417 ++ }
26418 ++#endif
26419 ++ return 0;
26420 ++}
26421 +diff -urNp linux-2.6.26.6/grsecurity/grsec_log.c linux-2.6.26.6/grsecurity/grsec_log.c
26422 +--- linux-2.6.26.6/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
26423 ++++ linux-2.6.26.6/grsecurity/grsec_log.c 2008-10-11 21:54:20.000000000 -0400
26424 +@@ -0,0 +1,269 @@
26425 ++#include <linux/kernel.h>
26426 ++#include <linux/sched.h>
26427 ++#include <linux/file.h>
26428 ++#include <linux/tty.h>
26429 ++#include <linux/fs.h>
26430 ++#include <linux/grinternal.h>
26431 ++
26432 ++#define BEGIN_LOCKS(x) \
26433 ++ read_lock(&tasklist_lock); \
26434 ++ read_lock(&grsec_exec_file_lock); \
26435 ++ if (x != GR_DO_AUDIT) \
26436 ++ spin_lock(&grsec_alert_lock); \
26437 ++ else \
26438 ++ spin_lock(&grsec_audit_lock)
26439 ++
26440 ++#define END_LOCKS(x) \
26441 ++ if (x != GR_DO_AUDIT) \
26442 ++ spin_unlock(&grsec_alert_lock); \
26443 ++ else \
26444 ++ spin_unlock(&grsec_audit_lock); \
26445 ++ read_unlock(&grsec_exec_file_lock); \
26446 ++ read_unlock(&tasklist_lock); \
26447 ++ if (x == GR_DONT_AUDIT) \
26448 ++ gr_handle_alertkill(current)
26449 ++
26450 ++enum {
26451 ++ FLOODING,
26452 ++ NO_FLOODING
26453 ++};
26454 ++
26455 ++extern char *gr_alert_log_fmt;
26456 ++extern char *gr_audit_log_fmt;
26457 ++extern char *gr_alert_log_buf;
26458 ++extern char *gr_audit_log_buf;
26459 ++
26460 ++static int gr_log_start(int audit)
26461 ++{
26462 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
26463 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
26464 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26465 ++
26466 ++ if (audit == GR_DO_AUDIT)
26467 ++ goto set_fmt;
26468 ++
26469 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
26470 ++ grsec_alert_wtime = jiffies;
26471 ++ grsec_alert_fyet = 0;
26472 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
26473 ++ grsec_alert_fyet++;
26474 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
26475 ++ grsec_alert_wtime = jiffies;
26476 ++ grsec_alert_fyet++;
26477 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
26478 ++ return FLOODING;
26479 ++ } else return FLOODING;
26480 ++
26481 ++set_fmt:
26482 ++ memset(buf, 0, PAGE_SIZE);
26483 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
26484 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
26485 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
26486 ++ } else if (current->signal->curr_ip) {
26487 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
26488 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
26489 ++ } else if (gr_acl_is_enabled()) {
26490 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
26491 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
26492 ++ } else {
26493 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
26494 ++ strcpy(buf, fmt);
26495 ++ }
26496 ++
26497 ++ return NO_FLOODING;
26498 ++}
26499 ++
26500 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
26501 ++{
26502 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26503 ++ unsigned int len = strlen(buf);
26504 ++
26505 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
26506 ++
26507 ++ return;
26508 ++}
26509 ++
26510 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
26511 ++{
26512 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26513 ++ unsigned int len = strlen(buf);
26514 ++ va_list ap;
26515 ++
26516 ++ va_start(ap, msg);
26517 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
26518 ++ va_end(ap);
26519 ++
26520 ++ return;
26521 ++}
26522 ++
26523 ++static void gr_log_end(int audit)
26524 ++{
26525 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
26526 ++ unsigned int len = strlen(buf);
26527 ++
26528 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
26529 ++ printk("%s\n", buf);
26530 ++
26531 ++ return;
26532 ++}
26533 ++
26534 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
26535 ++{
26536 ++ int logtype;
26537 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
26538 ++ char *str1, *str2, *str3;
26539 ++ int num1, num2;
26540 ++ unsigned long ulong1, ulong2;
26541 ++ struct dentry *dentry;
26542 ++ struct vfsmount *mnt;
26543 ++ struct file *file;
26544 ++ struct task_struct *task;
26545 ++ va_list ap;
26546 ++
26547 ++ BEGIN_LOCKS(audit);
26548 ++ logtype = gr_log_start(audit);
26549 ++ if (logtype == FLOODING) {
26550 ++ END_LOCKS(audit);
26551 ++ return;
26552 ++ }
26553 ++ va_start(ap, argtypes);
26554 ++ switch (argtypes) {
26555 ++ case GR_TTYSNIFF:
26556 ++ task = va_arg(ap, struct task_struct *);
26557 ++ 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);
26558 ++ break;
26559 ++ case GR_SYSCTL_HIDDEN:
26560 ++ str1 = va_arg(ap, char *);
26561 ++ gr_log_middle_varargs(audit, msg, result, str1);
26562 ++ break;
26563 ++ case GR_RBAC:
26564 ++ dentry = va_arg(ap, struct dentry *);
26565 ++ mnt = va_arg(ap, struct vfsmount *);
26566 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
26567 ++ break;
26568 ++ case GR_RBAC_STR:
26569 ++ dentry = va_arg(ap, struct dentry *);
26570 ++ mnt = va_arg(ap, struct vfsmount *);
26571 ++ str1 = va_arg(ap, char *);
26572 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
26573 ++ break;
26574 ++ case GR_STR_RBAC:
26575 ++ str1 = va_arg(ap, char *);
26576 ++ dentry = va_arg(ap, struct dentry *);
26577 ++ mnt = va_arg(ap, struct vfsmount *);
26578 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
26579 ++ break;
26580 ++ case GR_RBAC_MODE2:
26581 ++ dentry = va_arg(ap, struct dentry *);
26582 ++ mnt = va_arg(ap, struct vfsmount *);
26583 ++ str1 = va_arg(ap, char *);
26584 ++ str2 = va_arg(ap, char *);
26585 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
26586 ++ break;
26587 ++ case GR_RBAC_MODE3:
26588 ++ dentry = va_arg(ap, struct dentry *);
26589 ++ mnt = va_arg(ap, struct vfsmount *);
26590 ++ str1 = va_arg(ap, char *);
26591 ++ str2 = va_arg(ap, char *);
26592 ++ str3 = va_arg(ap, char *);
26593 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
26594 ++ break;
26595 ++ case GR_FILENAME:
26596 ++ dentry = va_arg(ap, struct dentry *);
26597 ++ mnt = va_arg(ap, struct vfsmount *);
26598 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
26599 ++ break;
26600 ++ case GR_STR_FILENAME:
26601 ++ str1 = va_arg(ap, char *);
26602 ++ dentry = va_arg(ap, struct dentry *);
26603 ++ mnt = va_arg(ap, struct vfsmount *);
26604 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
26605 ++ break;
26606 ++ case GR_FILENAME_STR:
26607 ++ dentry = va_arg(ap, struct dentry *);
26608 ++ mnt = va_arg(ap, struct vfsmount *);
26609 ++ str1 = va_arg(ap, char *);
26610 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
26611 ++ break;
26612 ++ case GR_FILENAME_TWO_INT:
26613 ++ dentry = va_arg(ap, struct dentry *);
26614 ++ mnt = va_arg(ap, struct vfsmount *);
26615 ++ num1 = va_arg(ap, int);
26616 ++ num2 = va_arg(ap, int);
26617 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
26618 ++ break;
26619 ++ case GR_FILENAME_TWO_INT_STR:
26620 ++ dentry = va_arg(ap, struct dentry *);
26621 ++ mnt = va_arg(ap, struct vfsmount *);
26622 ++ num1 = va_arg(ap, int);
26623 ++ num2 = va_arg(ap, int);
26624 ++ str1 = va_arg(ap, char *);
26625 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
26626 ++ break;
26627 ++ case GR_TEXTREL:
26628 ++ file = va_arg(ap, struct file *);
26629 ++ ulong1 = va_arg(ap, unsigned long);
26630 ++ ulong2 = va_arg(ap, unsigned long);
26631 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
26632 ++ break;
26633 ++ case GR_PTRACE:
26634 ++ task = va_arg(ap, struct task_struct *);
26635 ++ 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);
26636 ++ break;
26637 ++ case GR_RESOURCE:
26638 ++ task = va_arg(ap, struct task_struct *);
26639 ++ ulong1 = va_arg(ap, unsigned long);
26640 ++ str1 = va_arg(ap, char *);
26641 ++ ulong2 = va_arg(ap, unsigned long);
26642 ++ 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);
26643 ++ break;
26644 ++ case GR_CAP:
26645 ++ task = va_arg(ap, struct task_struct *);
26646 ++ str1 = va_arg(ap, char *);
26647 ++ 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);
26648 ++ break;
26649 ++ case GR_SIG:
26650 ++ task = va_arg(ap, struct task_struct *);
26651 ++ num1 = va_arg(ap, int);
26652 ++ 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);
26653 ++ break;
26654 ++ case GR_CRASH1:
26655 ++ task = va_arg(ap, struct task_struct *);
26656 ++ ulong1 = va_arg(ap, unsigned long);
26657 ++ 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);
26658 ++ break;
26659 ++ case GR_CRASH2:
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, ulong1);
26663 ++ break;
26664 ++ case GR_PSACCT:
26665 ++ {
26666 ++ unsigned int wday, cday;
26667 ++ __u8 whr, chr;
26668 ++ __u8 wmin, cmin;
26669 ++ __u8 wsec, csec;
26670 ++ char cur_tty[64] = { 0 };
26671 ++ char parent_tty[64] = { 0 };
26672 ++
26673 ++ task = va_arg(ap, struct task_struct *);
26674 ++ wday = va_arg(ap, unsigned int);
26675 ++ cday = va_arg(ap, unsigned int);
26676 ++ whr = va_arg(ap, int);
26677 ++ chr = va_arg(ap, int);
26678 ++ wmin = va_arg(ap, int);
26679 ++ cmin = va_arg(ap, int);
26680 ++ wsec = va_arg(ap, int);
26681 ++ csec = va_arg(ap, int);
26682 ++ ulong1 = va_arg(ap, unsigned long);
26683 ++
26684 ++ 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);
26685 ++ }
26686 ++ break;
26687 ++ default:
26688 ++ gr_log_middle(audit, msg, ap);
26689 ++ }
26690 ++ va_end(ap);
26691 ++ gr_log_end(audit);
26692 ++ END_LOCKS(audit);
26693 ++}
26694 +diff -urNp linux-2.6.26.6/grsecurity/grsec_mem.c linux-2.6.26.6/grsecurity/grsec_mem.c
26695 +--- linux-2.6.26.6/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
26696 ++++ linux-2.6.26.6/grsecurity/grsec_mem.c 2008-10-11 21:54:20.000000000 -0400
26697 +@@ -0,0 +1,71 @@
26698 ++#include <linux/kernel.h>
26699 ++#include <linux/sched.h>
26700 ++#include <linux/mm.h>
26701 ++#include <linux/mman.h>
26702 ++#include <linux/grinternal.h>
26703 ++
26704 ++void
26705 ++gr_handle_ioperm(void)
26706 ++{
26707 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
26708 ++ return;
26709 ++}
26710 ++
26711 ++void
26712 ++gr_handle_iopl(void)
26713 ++{
26714 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
26715 ++ return;
26716 ++}
26717 ++
26718 ++void
26719 ++gr_handle_mem_write(void)
26720 ++{
26721 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
26722 ++ return;
26723 ++}
26724 ++
26725 ++void
26726 ++gr_handle_kmem_write(void)
26727 ++{
26728 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
26729 ++ return;
26730 ++}
26731 ++
26732 ++void
26733 ++gr_handle_open_port(void)
26734 ++{
26735 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
26736 ++ return;
26737 ++}
26738 ++
26739 ++int
26740 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
26741 ++{
26742 ++ unsigned long start, end;
26743 ++
26744 ++ start = offset;
26745 ++ end = start + vma->vm_end - vma->vm_start;
26746 ++
26747 ++ if (start > end) {
26748 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
26749 ++ return -EPERM;
26750 ++ }
26751 ++
26752 ++ /* allowed ranges : ISA I/O BIOS */
26753 ++ if ((start >= __pa(high_memory))
26754 ++#ifdef CONFIG_X86
26755 ++ || (start >= 0x000a0000 && end <= 0x00100000)
26756 ++ || (start >= 0x00000000 && end <= 0x00001000)
26757 ++#endif
26758 ++ )
26759 ++ return 0;
26760 ++
26761 ++ if (vma->vm_flags & VM_WRITE) {
26762 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
26763 ++ return -EPERM;
26764 ++ } else
26765 ++ vma->vm_flags &= ~VM_MAYWRITE;
26766 ++
26767 ++ return 0;
26768 ++}
26769 +diff -urNp linux-2.6.26.6/grsecurity/grsec_mount.c linux-2.6.26.6/grsecurity/grsec_mount.c
26770 +--- linux-2.6.26.6/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
26771 ++++ linux-2.6.26.6/grsecurity/grsec_mount.c 2008-10-11 21:54:20.000000000 -0400
26772 +@@ -0,0 +1,34 @@
26773 ++#include <linux/kernel.h>
26774 ++#include <linux/sched.h>
26775 ++#include <linux/grsecurity.h>
26776 ++#include <linux/grinternal.h>
26777 ++
26778 ++void
26779 ++gr_log_remount(const char *devname, const int retval)
26780 ++{
26781 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26782 ++ if (grsec_enable_mount && (retval >= 0))
26783 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
26784 ++#endif
26785 ++ return;
26786 ++}
26787 ++
26788 ++void
26789 ++gr_log_unmount(const char *devname, const int retval)
26790 ++{
26791 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26792 ++ if (grsec_enable_mount && (retval >= 0))
26793 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
26794 ++#endif
26795 ++ return;
26796 ++}
26797 ++
26798 ++void
26799 ++gr_log_mount(const char *from, const char *to, const int retval)
26800 ++{
26801 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
26802 ++ if (grsec_enable_mount && (retval >= 0))
26803 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
26804 ++#endif
26805 ++ return;
26806 ++}
26807 +diff -urNp linux-2.6.26.6/grsecurity/grsec_sig.c linux-2.6.26.6/grsecurity/grsec_sig.c
26808 +--- linux-2.6.26.6/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
26809 ++++ linux-2.6.26.6/grsecurity/grsec_sig.c 2008-10-11 21:54:20.000000000 -0400
26810 +@@ -0,0 +1,58 @@
26811 ++#include <linux/kernel.h>
26812 ++#include <linux/sched.h>
26813 ++#include <linux/delay.h>
26814 ++#include <linux/grsecurity.h>
26815 ++#include <linux/grinternal.h>
26816 ++
26817 ++void
26818 ++gr_log_signal(const int sig, const struct task_struct *t)
26819 ++{
26820 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
26821 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
26822 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
26823 ++ if (t->pid == current->pid) {
26824 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
26825 ++ } else {
26826 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
26827 ++ }
26828 ++ }
26829 ++#endif
26830 ++ return;
26831 ++}
26832 ++
26833 ++int
26834 ++gr_handle_signal(const struct task_struct *p, const int sig)
26835 ++{
26836 ++#ifdef CONFIG_GRKERNSEC
26837 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
26838 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
26839 ++ return -EPERM;
26840 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
26841 ++ return -EPERM;
26842 ++ }
26843 ++#endif
26844 ++ return 0;
26845 ++}
26846 ++
26847 ++void gr_handle_brute_attach(struct task_struct *p)
26848 ++{
26849 ++#ifdef CONFIG_GRKERNSEC_BRUTE
26850 ++ read_lock(&tasklist_lock);
26851 ++ read_lock(&grsec_exec_file_lock);
26852 ++ if (p->parent && p->parent->exec_file == p->exec_file)
26853 ++ p->parent->brute = 1;
26854 ++ read_unlock(&grsec_exec_file_lock);
26855 ++ read_unlock(&tasklist_lock);
26856 ++#endif
26857 ++ return;
26858 ++}
26859 ++
26860 ++void gr_handle_brute_check(void)
26861 ++{
26862 ++#ifdef CONFIG_GRKERNSEC_BRUTE
26863 ++ if (current->brute)
26864 ++ msleep(30 * 1000);
26865 ++#endif
26866 ++ return;
26867 ++}
26868 ++
26869 +diff -urNp linux-2.6.26.6/grsecurity/grsec_sock.c linux-2.6.26.6/grsecurity/grsec_sock.c
26870 +--- linux-2.6.26.6/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
26871 ++++ linux-2.6.26.6/grsecurity/grsec_sock.c 2008-10-11 21:54:20.000000000 -0400
26872 +@@ -0,0 +1,274 @@
26873 ++#include <linux/kernel.h>
26874 ++#include <linux/module.h>
26875 ++#include <linux/sched.h>
26876 ++#include <linux/file.h>
26877 ++#include <linux/net.h>
26878 ++#include <linux/in.h>
26879 ++#include <linux/ip.h>
26880 ++#include <net/sock.h>
26881 ++#include <net/inet_sock.h>
26882 ++#include <linux/grsecurity.h>
26883 ++#include <linux/grinternal.h>
26884 ++#include <linux/gracl.h>
26885 ++
26886 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
26887 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
26888 ++EXPORT_SYMBOL(udp_v4_lookup);
26889 ++#endif
26890 ++
26891 ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
26892 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
26893 ++
26894 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
26895 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
26896 ++
26897 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
26898 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
26899 ++
26900 ++#ifdef CONFIG_UNIX_MODULE
26901 ++EXPORT_SYMBOL(gr_acl_handle_unix);
26902 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
26903 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
26904 ++EXPORT_SYMBOL(gr_handle_create);
26905 ++#endif
26906 ++
26907 ++#ifdef CONFIG_GRKERNSEC
26908 ++#define gr_conn_table_size 32749
26909 ++struct conn_table_entry {
26910 ++ struct conn_table_entry *next;
26911 ++ struct signal_struct *sig;
26912 ++};
26913 ++
26914 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
26915 ++DEFINE_SPINLOCK(gr_conn_table_lock);
26916 ++
26917 ++extern const char * gr_socktype_to_name(unsigned char type);
26918 ++extern const char * gr_proto_to_name(unsigned char proto);
26919 ++
26920 ++static __inline__ int
26921 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
26922 ++{
26923 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
26924 ++}
26925 ++
26926 ++static __inline__ int
26927 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
26928 ++ __u16 sport, __u16 dport)
26929 ++{
26930 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
26931 ++ sig->gr_sport == sport && sig->gr_dport == dport))
26932 ++ return 1;
26933 ++ else
26934 ++ return 0;
26935 ++}
26936 ++
26937 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
26938 ++{
26939 ++ struct conn_table_entry **match;
26940 ++ unsigned int index;
26941 ++
26942 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
26943 ++ sig->gr_sport, sig->gr_dport,
26944 ++ gr_conn_table_size);
26945 ++
26946 ++ newent->sig = sig;
26947 ++
26948 ++ match = &gr_conn_table[index];
26949 ++ newent->next = *match;
26950 ++ *match = newent;
26951 ++
26952 ++ return;
26953 ++}
26954 ++
26955 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
26956 ++{
26957 ++ struct conn_table_entry *match, *last = NULL;
26958 ++ unsigned int index;
26959 ++
26960 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
26961 ++ sig->gr_sport, sig->gr_dport,
26962 ++ gr_conn_table_size);
26963 ++
26964 ++ match = gr_conn_table[index];
26965 ++ while (match && !conn_match(match->sig,
26966 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
26967 ++ sig->gr_dport)) {
26968 ++ last = match;
26969 ++ match = match->next;
26970 ++ }
26971 ++
26972 ++ if (match) {
26973 ++ if (last)
26974 ++ last->next = match->next;
26975 ++ else
26976 ++ gr_conn_table[index] = NULL;
26977 ++ kfree(match);
26978 ++ }
26979 ++
26980 ++ return;
26981 ++}
26982 ++
26983 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
26984 ++ __u16 sport, __u16 dport)
26985 ++{
26986 ++ struct conn_table_entry *match;
26987 ++ unsigned int index;
26988 ++
26989 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
26990 ++
26991 ++ match = gr_conn_table[index];
26992 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
26993 ++ match = match->next;
26994 ++
26995 ++ if (match)
26996 ++ return match->sig;
26997 ++ else
26998 ++ return NULL;
26999 ++}
27000 ++
27001 ++#endif
27002 ++
27003 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
27004 ++{
27005 ++#ifdef CONFIG_GRKERNSEC
27006 ++ struct signal_struct *sig = task->signal;
27007 ++ struct conn_table_entry *newent;
27008 ++
27009 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
27010 ++ if (newent == NULL)
27011 ++ return;
27012 ++ /* no bh lock needed since we are called with bh disabled */
27013 ++ spin_lock(&gr_conn_table_lock);
27014 ++ gr_del_task_from_ip_table_nolock(sig);
27015 ++ sig->gr_saddr = inet->rcv_saddr;
27016 ++ sig->gr_daddr = inet->daddr;
27017 ++ sig->gr_sport = inet->sport;
27018 ++ sig->gr_dport = inet->dport;
27019 ++ gr_add_to_task_ip_table_nolock(sig, newent);
27020 ++ spin_unlock(&gr_conn_table_lock);
27021 ++#endif
27022 ++ return;
27023 ++}
27024 ++
27025 ++void gr_del_task_from_ip_table(struct task_struct *task)
27026 ++{
27027 ++#ifdef CONFIG_GRKERNSEC
27028 ++ spin_lock_bh(&gr_conn_table_lock);
27029 ++ gr_del_task_from_ip_table_nolock(task->signal);
27030 ++ spin_unlock_bh(&gr_conn_table_lock);
27031 ++#endif
27032 ++ return;
27033 ++}
27034 ++
27035 ++void
27036 ++gr_attach_curr_ip(const struct sock *sk)
27037 ++{
27038 ++#ifdef CONFIG_GRKERNSEC
27039 ++ struct signal_struct *p, *set;
27040 ++ const struct inet_sock *inet = inet_sk(sk);
27041 ++
27042 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
27043 ++ return;
27044 ++
27045 ++ set = current->signal;
27046 ++
27047 ++ spin_lock_bh(&gr_conn_table_lock);
27048 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
27049 ++ inet->dport, inet->sport);
27050 ++ if (unlikely(p != NULL)) {
27051 ++ set->curr_ip = p->curr_ip;
27052 ++ set->used_accept = 1;
27053 ++ gr_del_task_from_ip_table_nolock(p);
27054 ++ spin_unlock_bh(&gr_conn_table_lock);
27055 ++ return;
27056 ++ }
27057 ++ spin_unlock_bh(&gr_conn_table_lock);
27058 ++
27059 ++ set->curr_ip = inet->daddr;
27060 ++ set->used_accept = 1;
27061 ++#endif
27062 ++ return;
27063 ++}
27064 ++
27065 ++int
27066 ++gr_handle_sock_all(const int family, const int type, const int protocol)
27067 ++{
27068 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27069 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
27070 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
27071 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
27072 ++ return -EACCES;
27073 ++ }
27074 ++#endif
27075 ++ return 0;
27076 ++}
27077 ++
27078 ++int
27079 ++gr_handle_sock_server(const struct sockaddr *sck)
27080 ++{
27081 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27082 ++ if (grsec_enable_socket_server &&
27083 ++ in_group_p(grsec_socket_server_gid) &&
27084 ++ sck && (sck->sa_family != AF_UNIX) &&
27085 ++ (sck->sa_family != AF_LOCAL)) {
27086 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27087 ++ return -EACCES;
27088 ++ }
27089 ++#endif
27090 ++ return 0;
27091 ++}
27092 ++
27093 ++int
27094 ++gr_handle_sock_server_other(const struct sock *sck)
27095 ++{
27096 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27097 ++ if (grsec_enable_socket_server &&
27098 ++ in_group_p(grsec_socket_server_gid) &&
27099 ++ sck && (sck->sk_family != AF_UNIX) &&
27100 ++ (sck->sk_family != AF_LOCAL)) {
27101 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
27102 ++ return -EACCES;
27103 ++ }
27104 ++#endif
27105 ++ return 0;
27106 ++}
27107 ++
27108 ++int
27109 ++gr_handle_sock_client(const struct sockaddr *sck)
27110 ++{
27111 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27112 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
27113 ++ sck && (sck->sa_family != AF_UNIX) &&
27114 ++ (sck->sa_family != AF_LOCAL)) {
27115 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
27116 ++ return -EACCES;
27117 ++ }
27118 ++#endif
27119 ++ return 0;
27120 ++}
27121 ++
27122 ++kernel_cap_t
27123 ++gr_cap_rtnetlink(struct sock *sock)
27124 ++{
27125 ++#ifdef CONFIG_GRKERNSEC
27126 ++ if (!gr_acl_is_enabled())
27127 ++ return current->cap_effective;
27128 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
27129 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
27130 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
27131 ++ return current->cap_effective;
27132 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
27133 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
27134 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
27135 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
27136 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
27137 ++ return current->cap_effective;
27138 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
27139 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
27140 ++ return current->cap_effective;
27141 ++ else
27142 ++ return __cap_empty_set;
27143 ++#else
27144 ++ return current->cap_effective;
27145 ++#endif
27146 ++}
27147 +diff -urNp linux-2.6.26.6/grsecurity/grsec_sysctl.c linux-2.6.26.6/grsecurity/grsec_sysctl.c
27148 +--- linux-2.6.26.6/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
27149 ++++ linux-2.6.26.6/grsecurity/grsec_sysctl.c 2008-10-11 21:54:20.000000000 -0400
27150 +@@ -0,0 +1,435 @@
27151 ++#include <linux/kernel.h>
27152 ++#include <linux/sched.h>
27153 ++#include <linux/sysctl.h>
27154 ++#include <linux/grsecurity.h>
27155 ++#include <linux/grinternal.h>
27156 ++
27157 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27158 ++int grsec_modstop;
27159 ++#endif
27160 ++
27161 ++int
27162 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
27163 ++{
27164 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
27165 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
27166 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27167 ++ return -EACCES;
27168 ++ }
27169 ++#endif
27170 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27171 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
27172 ++ grsec_modstop && (op & 002)) {
27173 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
27174 ++ return -EACCES;
27175 ++ }
27176 ++#endif
27177 ++ return 0;
27178 ++}
27179 ++
27180 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
27181 ++ctl_table grsecurity_table[] = {
27182 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
27183 ++#ifdef CONFIG_GRKERNSEC_LINK
27184 ++ {
27185 ++ .ctl_name = CTL_UNNUMBERED,
27186 ++ .procname = "linking_restrictions",
27187 ++ .data = &grsec_enable_link,
27188 ++ .maxlen = sizeof(int),
27189 ++ .mode = 0600,
27190 ++ .proc_handler = &proc_dointvec,
27191 ++ },
27192 ++#endif
27193 ++#ifdef CONFIG_GRKERNSEC_FIFO
27194 ++ {
27195 ++ .ctl_name = CTL_UNNUMBERED,
27196 ++ .procname = "fifo_restrictions",
27197 ++ .data = &grsec_enable_fifo,
27198 ++ .maxlen = sizeof(int),
27199 ++ .mode = 0600,
27200 ++ .proc_handler = &proc_dointvec,
27201 ++ },
27202 ++#endif
27203 ++#ifdef CONFIG_GRKERNSEC_EXECVE
27204 ++ {
27205 ++ .ctl_name = CTL_UNNUMBERED,
27206 ++ .procname = "execve_limiting",
27207 ++ .data = &grsec_enable_execve,
27208 ++ .maxlen = sizeof(int),
27209 ++ .mode = 0600,
27210 ++ .proc_handler = &proc_dointvec,
27211 ++ },
27212 ++#endif
27213 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
27214 ++ {
27215 ++ .ctl_name = CTL_UNNUMBERED,
27216 ++ .procname = "exec_logging",
27217 ++ .data = &grsec_enable_execlog,
27218 ++ .maxlen = sizeof(int),
27219 ++ .mode = 0600,
27220 ++ .proc_handler = &proc_dointvec,
27221 ++ },
27222 ++#endif
27223 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
27224 ++ {
27225 ++ .ctl_name = CTL_UNNUMBERED,
27226 ++ .procname = "signal_logging",
27227 ++ .data = &grsec_enable_signal,
27228 ++ .maxlen = sizeof(int),
27229 ++ .mode = 0600,
27230 ++ .proc_handler = &proc_dointvec,
27231 ++ },
27232 ++#endif
27233 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
27234 ++ {
27235 ++ .ctl_name = CTL_UNNUMBERED,
27236 ++ .procname = "forkfail_logging",
27237 ++ .data = &grsec_enable_forkfail,
27238 ++ .maxlen = sizeof(int),
27239 ++ .mode = 0600,
27240 ++ .proc_handler = &proc_dointvec,
27241 ++ },
27242 ++#endif
27243 ++#ifdef CONFIG_GRKERNSEC_TIME
27244 ++ {
27245 ++ .ctl_name = CTL_UNNUMBERED,
27246 ++ .procname = "timechange_logging",
27247 ++ .data = &grsec_enable_time,
27248 ++ .maxlen = sizeof(int),
27249 ++ .mode = 0600,
27250 ++ .proc_handler = &proc_dointvec,
27251 ++ },
27252 ++#endif
27253 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
27254 ++ {
27255 ++ .ctl_name = CTL_UNNUMBERED,
27256 ++ .procname = "chroot_deny_shmat",
27257 ++ .data = &grsec_enable_chroot_shmat,
27258 ++ .maxlen = sizeof(int),
27259 ++ .mode = 0600,
27260 ++ .proc_handler = &proc_dointvec,
27261 ++ },
27262 ++#endif
27263 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
27264 ++ {
27265 ++ .ctl_name = CTL_UNNUMBERED,
27266 ++ .procname = "chroot_deny_unix",
27267 ++ .data = &grsec_enable_chroot_unix,
27268 ++ .maxlen = sizeof(int),
27269 ++ .mode = 0600,
27270 ++ .proc_handler = &proc_dointvec,
27271 ++ },
27272 ++#endif
27273 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
27274 ++ {
27275 ++ .ctl_name = CTL_UNNUMBERED,
27276 ++ .procname = "chroot_deny_mount",
27277 ++ .data = &grsec_enable_chroot_mount,
27278 ++ .maxlen = sizeof(int),
27279 ++ .mode = 0600,
27280 ++ .proc_handler = &proc_dointvec,
27281 ++ },
27282 ++#endif
27283 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
27284 ++ {
27285 ++ .ctl_name = CTL_UNNUMBERED,
27286 ++ .procname = "chroot_deny_fchdir",
27287 ++ .data = &grsec_enable_chroot_fchdir,
27288 ++ .maxlen = sizeof(int),
27289 ++ .mode = 0600,
27290 ++ .proc_handler = &proc_dointvec,
27291 ++ },
27292 ++#endif
27293 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
27294 ++ {
27295 ++ .ctl_name = CTL_UNNUMBERED,
27296 ++ .procname = "chroot_deny_chroot",
27297 ++ .data = &grsec_enable_chroot_double,
27298 ++ .maxlen = sizeof(int),
27299 ++ .mode = 0600,
27300 ++ .proc_handler = &proc_dointvec,
27301 ++ },
27302 ++#endif
27303 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
27304 ++ {
27305 ++ .ctl_name = CTL_UNNUMBERED,
27306 ++ .procname = "chroot_deny_pivot",
27307 ++ .data = &grsec_enable_chroot_pivot,
27308 ++ .maxlen = sizeof(int),
27309 ++ .mode = 0600,
27310 ++ .proc_handler = &proc_dointvec,
27311 ++ },
27312 ++#endif
27313 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
27314 ++ {
27315 ++ .ctl_name = CTL_UNNUMBERED,
27316 ++ .procname = "chroot_enforce_chdir",
27317 ++ .data = &grsec_enable_chroot_chdir,
27318 ++ .maxlen = sizeof(int),
27319 ++ .mode = 0600,
27320 ++ .proc_handler = &proc_dointvec,
27321 ++ },
27322 ++#endif
27323 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
27324 ++ {
27325 ++ .ctl_name = CTL_UNNUMBERED,
27326 ++ .procname = "chroot_deny_chmod",
27327 ++ .data = &grsec_enable_chroot_chmod,
27328 ++ .maxlen = sizeof(int),
27329 ++ .mode = 0600,
27330 ++ .proc_handler = &proc_dointvec,
27331 ++ },
27332 ++#endif
27333 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
27334 ++ {
27335 ++ .ctl_name = CTL_UNNUMBERED,
27336 ++ .procname = "chroot_deny_mknod",
27337 ++ .data = &grsec_enable_chroot_mknod,
27338 ++ .maxlen = sizeof(int),
27339 ++ .mode = 0600,
27340 ++ .proc_handler = &proc_dointvec,
27341 ++ },
27342 ++#endif
27343 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
27344 ++ {
27345 ++ .ctl_name = CTL_UNNUMBERED,
27346 ++ .procname = "chroot_restrict_nice",
27347 ++ .data = &grsec_enable_chroot_nice,
27348 ++ .maxlen = sizeof(int),
27349 ++ .mode = 0600,
27350 ++ .proc_handler = &proc_dointvec,
27351 ++ },
27352 ++#endif
27353 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
27354 ++ {
27355 ++ .ctl_name = CTL_UNNUMBERED,
27356 ++ .procname = "chroot_execlog",
27357 ++ .data = &grsec_enable_chroot_execlog,
27358 ++ .maxlen = sizeof(int),
27359 ++ .mode = 0600,
27360 ++ .proc_handler = &proc_dointvec,
27361 ++ },
27362 ++#endif
27363 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
27364 ++ {
27365 ++ .ctl_name = CTL_UNNUMBERED,
27366 ++ .procname = "chroot_caps",
27367 ++ .data = &grsec_enable_chroot_caps,
27368 ++ .maxlen = sizeof(int),
27369 ++ .mode = 0600,
27370 ++ .proc_handler = &proc_dointvec,
27371 ++ },
27372 ++#endif
27373 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
27374 ++ {
27375 ++ .ctl_name = CTL_UNNUMBERED,
27376 ++ .procname = "chroot_deny_sysctl",
27377 ++ .data = &grsec_enable_chroot_sysctl,
27378 ++ .maxlen = sizeof(int),
27379 ++ .mode = 0600,
27380 ++ .proc_handler = &proc_dointvec,
27381 ++ },
27382 ++#endif
27383 ++#ifdef CONFIG_GRKERNSEC_TPE
27384 ++ {
27385 ++ .ctl_name = CTL_UNNUMBERED,
27386 ++ .procname = "tpe",
27387 ++ .data = &grsec_enable_tpe,
27388 ++ .maxlen = sizeof(int),
27389 ++ .mode = 0600,
27390 ++ .proc_handler = &proc_dointvec,
27391 ++ },
27392 ++ {
27393 ++ .ctl_name = CTL_UNNUMBERED,
27394 ++ .procname = "tpe_gid",
27395 ++ .data = &grsec_tpe_gid,
27396 ++ .maxlen = sizeof(int),
27397 ++ .mode = 0600,
27398 ++ .proc_handler = &proc_dointvec,
27399 ++ },
27400 ++#endif
27401 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
27402 ++ {
27403 ++ .ctl_name = CTL_UNNUMBERED,
27404 ++ .procname = "tpe_restrict_all",
27405 ++ .data = &grsec_enable_tpe_all,
27406 ++ .maxlen = sizeof(int),
27407 ++ .mode = 0600,
27408 ++ .proc_handler = &proc_dointvec,
27409 ++ },
27410 ++#endif
27411 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
27412 ++ {
27413 ++ .ctl_name = CTL_UNNUMBERED,
27414 ++ .procname = "socket_all",
27415 ++ .data = &grsec_enable_socket_all,
27416 ++ .maxlen = sizeof(int),
27417 ++ .mode = 0600,
27418 ++ .proc_handler = &proc_dointvec,
27419 ++ },
27420 ++ {
27421 ++ .ctl_name = CTL_UNNUMBERED,
27422 ++ .procname = "socket_all_gid",
27423 ++ .data = &grsec_socket_all_gid,
27424 ++ .maxlen = sizeof(int),
27425 ++ .mode = 0600,
27426 ++ .proc_handler = &proc_dointvec,
27427 ++ },
27428 ++#endif
27429 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
27430 ++ {
27431 ++ .ctl_name = CTL_UNNUMBERED,
27432 ++ .procname = "socket_client",
27433 ++ .data = &grsec_enable_socket_client,
27434 ++ .maxlen = sizeof(int),
27435 ++ .mode = 0600,
27436 ++ .proc_handler = &proc_dointvec,
27437 ++ },
27438 ++ {
27439 ++ .ctl_name = CTL_UNNUMBERED,
27440 ++ .procname = "socket_client_gid",
27441 ++ .data = &grsec_socket_client_gid,
27442 ++ .maxlen = sizeof(int),
27443 ++ .mode = 0600,
27444 ++ .proc_handler = &proc_dointvec,
27445 ++ },
27446 ++#endif
27447 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
27448 ++ {
27449 ++ .ctl_name = CTL_UNNUMBERED,
27450 ++ .procname = "socket_server",
27451 ++ .data = &grsec_enable_socket_server,
27452 ++ .maxlen = sizeof(int),
27453 ++ .mode = 0600,
27454 ++ .proc_handler = &proc_dointvec,
27455 ++ },
27456 ++ {
27457 ++ .ctl_name = CTL_UNNUMBERED,
27458 ++ .procname = "socket_server_gid",
27459 ++ .data = &grsec_socket_server_gid,
27460 ++ .maxlen = sizeof(int),
27461 ++ .mode = 0600,
27462 ++ .proc_handler = &proc_dointvec,
27463 ++ },
27464 ++#endif
27465 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
27466 ++ {
27467 ++ .ctl_name = CTL_UNNUMBERED,
27468 ++ .procname = "audit_group",
27469 ++ .data = &grsec_enable_group,
27470 ++ .maxlen = sizeof(int),
27471 ++ .mode = 0600,
27472 ++ .proc_handler = &proc_dointvec,
27473 ++ },
27474 ++ {
27475 ++ .ctl_name = CTL_UNNUMBERED,
27476 ++ .procname = "audit_gid",
27477 ++ .data = &grsec_audit_gid,
27478 ++ .maxlen = sizeof(int),
27479 ++ .mode = 0600,
27480 ++ .proc_handler = &proc_dointvec,
27481 ++ },
27482 ++#endif
27483 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
27484 ++ {
27485 ++ .ctl_name = CTL_UNNUMBERED,
27486 ++ .procname = "audit_chdir",
27487 ++ .data = &grsec_enable_chdir,
27488 ++ .maxlen = sizeof(int),
27489 ++ .mode = 0600,
27490 ++ .proc_handler = &proc_dointvec,
27491 ++ },
27492 ++#endif
27493 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
27494 ++ {
27495 ++ .ctl_name = CTL_UNNUMBERED,
27496 ++ .procname = "audit_mount",
27497 ++ .data = &grsec_enable_mount,
27498 ++ .maxlen = sizeof(int),
27499 ++ .mode = 0600,
27500 ++ .proc_handler = &proc_dointvec,
27501 ++ },
27502 ++#endif
27503 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
27504 ++ {
27505 ++ .ctl_name = CTL_UNNUMBERED,
27506 ++ .procname = "audit_ipc",
27507 ++ .data = &grsec_enable_audit_ipc,
27508 ++ .maxlen = sizeof(int),
27509 ++ .mode = 0600,
27510 ++ .proc_handler = &proc_dointvec,
27511 ++ },
27512 ++#endif
27513 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
27514 ++ {
27515 ++ .ctl_name = CTL_UNNUMBERED,
27516 ++ .procname = "audit_textrel",
27517 ++ .data = &grsec_enable_audit_textrel,
27518 ++ .maxlen = sizeof(int),
27519 ++ .mode = 0600,
27520 ++ .proc_handler = &proc_dointvec,
27521 ++ },
27522 ++#endif
27523 ++#ifdef CONFIG_GRKERNSEC_DMESG
27524 ++ {
27525 ++ .ctl_name = CTL_UNNUMBERED,
27526 ++ .procname = "dmesg",
27527 ++ .data = &grsec_enable_dmesg,
27528 ++ .maxlen = sizeof(int),
27529 ++ .mode = 0600,
27530 ++ .proc_handler = &proc_dointvec,
27531 ++ },
27532 ++#endif
27533 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
27534 ++ {
27535 ++ .ctl_name = CTL_UNNUMBERED,
27536 ++ .procname = "chroot_findtask",
27537 ++ .data = &grsec_enable_chroot_findtask,
27538 ++ .maxlen = sizeof(int),
27539 ++ .mode = 0600,
27540 ++ .proc_handler = &proc_dointvec,
27541 ++ },
27542 ++#endif
27543 ++#ifdef CONFIG_GRKERNSEC_RESLOG
27544 ++ {
27545 ++ .ctl_name = CTL_UNNUMBERED,
27546 ++ .procname = "resource_logging",
27547 ++ .data = &grsec_resource_logging,
27548 ++ .maxlen = sizeof(int),
27549 ++ .mode = 0600,
27550 ++ .proc_handler = &proc_dointvec,
27551 ++ },
27552 ++#endif
27553 ++ {
27554 ++ .ctl_name = CTL_UNNUMBERED,
27555 ++ .procname = "grsec_lock",
27556 ++ .data = &grsec_lock,
27557 ++ .maxlen = sizeof(int),
27558 ++ .mode = 0600,
27559 ++ .proc_handler = &proc_dointvec,
27560 ++ },
27561 ++#endif
27562 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27563 ++ {
27564 ++ .ctl_name = CTL_UNNUMBERED,
27565 ++ .procname = "disable_modules",
27566 ++ .data = &grsec_modstop,
27567 ++ .maxlen = sizeof(int),
27568 ++ .mode = 0600,
27569 ++ .proc_handler = &proc_dointvec,
27570 ++ },
27571 ++#endif
27572 ++ { .ctl_name = 0 }
27573 ++};
27574 ++#endif
27575 ++
27576 ++int gr_check_modstop(void)
27577 ++{
27578 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
27579 ++ if (grsec_modstop == 1) {
27580 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
27581 ++ return 1;
27582 ++ }
27583 ++#endif
27584 ++ return 0;
27585 ++}
27586 +diff -urNp linux-2.6.26.6/grsecurity/grsec_textrel.c linux-2.6.26.6/grsecurity/grsec_textrel.c
27587 +--- linux-2.6.26.6/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
27588 ++++ linux-2.6.26.6/grsecurity/grsec_textrel.c 2008-10-11 21:54:20.000000000 -0400
27589 +@@ -0,0 +1,16 @@
27590 ++#include <linux/kernel.h>
27591 ++#include <linux/sched.h>
27592 ++#include <linux/mm.h>
27593 ++#include <linux/file.h>
27594 ++#include <linux/grinternal.h>
27595 ++#include <linux/grsecurity.h>
27596 ++
27597 ++void
27598 ++gr_log_textrel(struct vm_area_struct * vma)
27599 ++{
27600 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
27601 ++ if (grsec_enable_audit_textrel)
27602 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
27603 ++#endif
27604 ++ return;
27605 ++}
27606 +diff -urNp linux-2.6.26.6/grsecurity/grsec_time.c linux-2.6.26.6/grsecurity/grsec_time.c
27607 +--- linux-2.6.26.6/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
27608 ++++ linux-2.6.26.6/grsecurity/grsec_time.c 2008-10-11 21:54:20.000000000 -0400
27609 +@@ -0,0 +1,13 @@
27610 ++#include <linux/kernel.h>
27611 ++#include <linux/sched.h>
27612 ++#include <linux/grinternal.h>
27613 ++
27614 ++void
27615 ++gr_log_timechange(void)
27616 ++{
27617 ++#ifdef CONFIG_GRKERNSEC_TIME
27618 ++ if (grsec_enable_time)
27619 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
27620 ++#endif
27621 ++ return;
27622 ++}
27623 +diff -urNp linux-2.6.26.6/grsecurity/grsec_tpe.c linux-2.6.26.6/grsecurity/grsec_tpe.c
27624 +--- linux-2.6.26.6/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
27625 ++++ linux-2.6.26.6/grsecurity/grsec_tpe.c 2008-10-11 21:54:20.000000000 -0400
27626 +@@ -0,0 +1,37 @@
27627 ++#include <linux/kernel.h>
27628 ++#include <linux/sched.h>
27629 ++#include <linux/file.h>
27630 ++#include <linux/fs.h>
27631 ++#include <linux/grinternal.h>
27632 ++
27633 ++extern int gr_acl_tpe_check(void);
27634 ++
27635 ++int
27636 ++gr_tpe_allow(const struct file *file)
27637 ++{
27638 ++#ifdef CONFIG_GRKERNSEC
27639 ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
27640 ++
27641 ++ if (current->uid && ((grsec_enable_tpe &&
27642 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
27643 ++ !in_group_p(grsec_tpe_gid)
27644 ++#else
27645 ++ in_group_p(grsec_tpe_gid)
27646 ++#endif
27647 ++ ) || gr_acl_tpe_check()) &&
27648 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
27649 ++ (inode->i_mode & S_IWOTH))))) {
27650 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
27651 ++ return 0;
27652 ++ }
27653 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
27654 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
27655 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
27656 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
27657 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
27658 ++ return 0;
27659 ++ }
27660 ++#endif
27661 ++#endif
27662 ++ return 1;
27663 ++}
27664 +diff -urNp linux-2.6.26.6/grsecurity/grsum.c linux-2.6.26.6/grsecurity/grsum.c
27665 +--- linux-2.6.26.6/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
27666 ++++ linux-2.6.26.6/grsecurity/grsum.c 2008-10-11 21:54:20.000000000 -0400
27667 +@@ -0,0 +1,59 @@
27668 ++#include <linux/err.h>
27669 ++#include <linux/kernel.h>
27670 ++#include <linux/sched.h>
27671 ++#include <linux/mm.h>
27672 ++#include <linux/scatterlist.h>
27673 ++#include <linux/crypto.h>
27674 ++#include <linux/gracl.h>
27675 ++
27676 ++
27677 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
27678 ++#error "crypto and sha256 must be built into the kernel"
27679 ++#endif
27680 ++
27681 ++int
27682 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
27683 ++{
27684 ++ char *p;
27685 ++ struct crypto_hash *tfm;
27686 ++ struct hash_desc desc;
27687 ++ struct scatterlist sg;
27688 ++ unsigned char temp_sum[GR_SHA_LEN];
27689 ++ volatile int retval = 0;
27690 ++ volatile int dummy = 0;
27691 ++ unsigned int i;
27692 ++
27693 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
27694 ++ if (IS_ERR(tfm)) {
27695 ++ /* should never happen, since sha256 should be built in */
27696 ++ return 1;
27697 ++ }
27698 ++
27699 ++ desc.tfm = tfm;
27700 ++ desc.flags = 0;
27701 ++
27702 ++ crypto_hash_init(&desc);
27703 ++
27704 ++ p = salt;
27705 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
27706 ++ crypto_hash_update(&desc, &sg, sg.length);
27707 ++
27708 ++ p = entry->pw;
27709 ++ sg_set_buf(&sg, p, strlen(p));
27710 ++
27711 ++ crypto_hash_update(&desc, &sg, sg.length);
27712 ++
27713 ++ crypto_hash_final(&desc, temp_sum);
27714 ++
27715 ++ memset(entry->pw, 0, GR_PW_LEN);
27716 ++
27717 ++ for (i = 0; i < GR_SHA_LEN; i++)
27718 ++ if (sum[i] != temp_sum[i])
27719 ++ retval = 1;
27720 ++ else
27721 ++ dummy = 1; // waste a cycle
27722 ++
27723 ++ crypto_free_hash(tfm);
27724 ++
27725 ++ return retval;
27726 ++}
27727 +diff -urNp linux-2.6.26.6/grsecurity/Kconfig linux-2.6.26.6/grsecurity/Kconfig
27728 +--- linux-2.6.26.6/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
27729 ++++ linux-2.6.26.6/grsecurity/Kconfig 2008-10-11 21:54:20.000000000 -0400
27730 +@@ -0,0 +1,863 @@
27731 ++#
27732 ++# grecurity configuration
27733 ++#
27734 ++
27735 ++menu "Grsecurity"
27736 ++
27737 ++config GRKERNSEC
27738 ++ bool "Grsecurity"
27739 ++ select CRYPTO
27740 ++ select CRYPTO_SHA256
27741 ++ select SECURITY
27742 ++ select SECURITY_CAPABILITIES
27743 ++ help
27744 ++ If you say Y here, you will be able to configure many features
27745 ++ that will enhance the security of your system. It is highly
27746 ++ recommended that you say Y here and read through the help
27747 ++ for each option so that you fully understand the features and
27748 ++ can evaluate their usefulness for your machine.
27749 ++
27750 ++choice
27751 ++ prompt "Security Level"
27752 ++ depends on GRKERNSEC
27753 ++ default GRKERNSEC_CUSTOM
27754 ++
27755 ++config GRKERNSEC_LOW
27756 ++ bool "Low"
27757 ++ select GRKERNSEC_LINK
27758 ++ select GRKERNSEC_FIFO
27759 ++ select GRKERNSEC_EXECVE
27760 ++ select GRKERNSEC_RANDNET
27761 ++ select GRKERNSEC_DMESG
27762 ++ select GRKERNSEC_CHROOT_CHDIR
27763 ++ select GRKERNSEC_MODSTOP if (MODULES)
27764 ++
27765 ++ help
27766 ++ If you choose this option, several of the grsecurity options will
27767 ++ be enabled that will give you greater protection against a number
27768 ++ of attacks, while assuring that none of your software will have any
27769 ++ conflicts with the additional security measures. If you run a lot
27770 ++ of unusual software, or you are having problems with the higher
27771 ++ security levels, you should say Y here. With this option, the
27772 ++ following features are enabled:
27773 ++
27774 ++ - Linking restrictions
27775 ++ - FIFO restrictions
27776 ++ - Enforcing RLIMIT_NPROC on execve
27777 ++ - Restricted dmesg
27778 ++ - Enforced chdir("/") on chroot
27779 ++ - Runtime module disabling
27780 ++
27781 ++config GRKERNSEC_MEDIUM
27782 ++ bool "Medium"
27783 ++ select PAX
27784 ++ select PAX_EI_PAX
27785 ++ select PAX_PT_PAX_FLAGS
27786 ++ select PAX_HAVE_ACL_FLAGS
27787 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
27788 ++ select GRKERNSEC_CHROOT_SYSCTL
27789 ++ select GRKERNSEC_LINK
27790 ++ select GRKERNSEC_FIFO
27791 ++ select GRKERNSEC_EXECVE
27792 ++ select GRKERNSEC_DMESG
27793 ++ select GRKERNSEC_RANDNET
27794 ++ select GRKERNSEC_FORKFAIL
27795 ++ select GRKERNSEC_TIME
27796 ++ select GRKERNSEC_SIGNAL
27797 ++ select GRKERNSEC_CHROOT
27798 ++ select GRKERNSEC_CHROOT_UNIX
27799 ++ select GRKERNSEC_CHROOT_MOUNT
27800 ++ select GRKERNSEC_CHROOT_PIVOT
27801 ++ select GRKERNSEC_CHROOT_DOUBLE
27802 ++ select GRKERNSEC_CHROOT_CHDIR
27803 ++ select GRKERNSEC_CHROOT_MKNOD
27804 ++ select GRKERNSEC_PROC
27805 ++ select GRKERNSEC_PROC_USERGROUP
27806 ++ select GRKERNSEC_MODSTOP if (MODULES)
27807 ++ select PAX_RANDUSTACK
27808 ++ select PAX_ASLR
27809 ++ select PAX_RANDMMAP
27810 ++ select PAX_REFCOUNT
27811 ++
27812 ++ help
27813 ++ If you say Y here, several features in addition to those included
27814 ++ in the low additional security level will be enabled. These
27815 ++ features provide even more security to your system, though in rare
27816 ++ cases they may be incompatible with very old or poorly written
27817 ++ software. If you enable this option, make sure that your auth
27818 ++ service (identd) is running as gid 1001. With this option,
27819 ++ the following features (in addition to those provided in the
27820 ++ low additional security level) will be enabled:
27821 ++
27822 ++ - Failed fork logging
27823 ++ - Time change logging
27824 ++ - Signal logging
27825 ++ - Deny mounts in chroot
27826 ++ - Deny double chrooting
27827 ++ - Deny sysctl writes in chroot
27828 ++ - Deny mknod in chroot
27829 ++ - Deny access to abstract AF_UNIX sockets out of chroot
27830 ++ - Deny pivot_root in chroot
27831 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
27832 ++ - /proc restrictions with special GID set to 10 (usually wheel)
27833 ++ - Address Space Layout Randomization (ASLR)
27834 ++
27835 ++config GRKERNSEC_HIGH
27836 ++ bool "High"
27837 ++ select GRKERNSEC_LINK
27838 ++ select GRKERNSEC_FIFO
27839 ++ select GRKERNSEC_EXECVE
27840 ++ select GRKERNSEC_DMESG
27841 ++ select GRKERNSEC_FORKFAIL
27842 ++ select GRKERNSEC_TIME
27843 ++ select GRKERNSEC_SIGNAL
27844 ++ select GRKERNSEC_CHROOT_SHMAT
27845 ++ select GRKERNSEC_CHROOT_UNIX
27846 ++ select GRKERNSEC_CHROOT_MOUNT
27847 ++ select GRKERNSEC_CHROOT_FCHDIR
27848 ++ select GRKERNSEC_CHROOT_PIVOT
27849 ++ select GRKERNSEC_CHROOT_DOUBLE
27850 ++ select GRKERNSEC_CHROOT_CHDIR
27851 ++ select GRKERNSEC_CHROOT_MKNOD
27852 ++ select GRKERNSEC_CHROOT_CAPS
27853 ++ select GRKERNSEC_CHROOT_SYSCTL
27854 ++ select GRKERNSEC_CHROOT_FINDTASK
27855 ++ select GRKERNSEC_PROC
27856 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
27857 ++ select GRKERNSEC_HIDESYM
27858 ++ select GRKERNSEC_BRUTE
27859 ++ select GRKERNSEC_PROC_USERGROUP
27860 ++ select GRKERNSEC_KMEM
27861 ++ select GRKERNSEC_RESLOG
27862 ++ select GRKERNSEC_RANDNET
27863 ++ select GRKERNSEC_PROC_ADD
27864 ++ select GRKERNSEC_CHROOT_CHMOD
27865 ++ select GRKERNSEC_CHROOT_NICE
27866 ++ select GRKERNSEC_AUDIT_MOUNT
27867 ++ select GRKERNSEC_MODSTOP if (MODULES)
27868 ++ select PAX
27869 ++ select PAX_RANDUSTACK
27870 ++ select PAX_ASLR
27871 ++ select PAX_RANDMMAP
27872 ++ select PAX_NOEXEC
27873 ++ select PAX_MPROTECT
27874 ++ select PAX_EI_PAX
27875 ++ select PAX_PT_PAX_FLAGS
27876 ++ select PAX_HAVE_ACL_FLAGS
27877 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
27878 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
27879 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
27880 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
27881 ++ select PAX_PAGEEXEC if (!X86)
27882 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
27883 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
27884 ++ select PAX_SYSCALL if (PPC32)
27885 ++ select PAX_EMUTRAMP if (PARISC)
27886 ++ select PAX_EMUSIGRT if (PARISC)
27887 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
27888 ++ select PAX_REFCOUNT
27889 ++ help
27890 ++ If you say Y here, many of the features of grsecurity will be
27891 ++ enabled, which will protect you against many kinds of attacks
27892 ++ against your system. The heightened security comes at a cost
27893 ++ of an increased chance of incompatibilities with rare software
27894 ++ on your machine. Since this security level enables PaX, you should
27895 ++ view <http://pax.grsecurity.net> and read about the PaX
27896 ++ project. While you are there, download chpax and run it on
27897 ++ binaries that cause problems with PaX. Also remember that
27898 ++ since the /proc restrictions are enabled, you must run your
27899 ++ identd as gid 1001. This security level enables the following
27900 ++ features in addition to those listed in the low and medium
27901 ++ security levels:
27902 ++
27903 ++ - Additional /proc restrictions
27904 ++ - Chmod restrictions in chroot
27905 ++ - No signals, ptrace, or viewing of processes outside of chroot
27906 ++ - Capability restrictions in chroot
27907 ++ - Deny fchdir out of chroot
27908 ++ - Priority restrictions in chroot
27909 ++ - Segmentation-based implementation of PaX
27910 ++ - Mprotect restrictions
27911 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
27912 ++ - Kernel stack randomization
27913 ++ - Mount/unmount/remount logging
27914 ++ - Kernel symbol hiding
27915 ++ - Prevention of memory exhaustion-based exploits
27916 ++config GRKERNSEC_CUSTOM
27917 ++ bool "Custom"
27918 ++ help
27919 ++ If you say Y here, you will be able to configure every grsecurity
27920 ++ option, which allows you to enable many more features that aren't
27921 ++ covered in the basic security levels. These additional features
27922 ++ include TPE, socket restrictions, and the sysctl system for
27923 ++ grsecurity. It is advised that you read through the help for
27924 ++ each option to determine its usefulness in your situation.
27925 ++
27926 ++endchoice
27927 ++
27928 ++menu "Address Space Protection"
27929 ++depends on GRKERNSEC
27930 ++
27931 ++config GRKERNSEC_KMEM
27932 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
27933 ++ help
27934 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
27935 ++ be written to via mmap or otherwise to modify the running kernel.
27936 ++ /dev/port will also not be allowed to be opened. If you have module
27937 ++ support disabled, enabling this will close up four ways that are
27938 ++ currently used to insert malicious code into the running kernel.
27939 ++ Even with all these features enabled, we still highly recommend that
27940 ++ you use the RBAC system, as it is still possible for an attacker to
27941 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
27942 ++ If you are not using XFree86, you may be able to stop this additional
27943 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
27944 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
27945 ++ but only to video memory, which is the only writing we allow in this
27946 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
27947 ++ not be allowed to mprotect it with PROT_WRITE later.
27948 ++ It is highly recommended that you say Y here if you meet all the
27949 ++ conditions above.
27950 ++
27951 ++config GRKERNSEC_IO
27952 ++ bool "Disable privileged I/O"
27953 ++ depends on X86
27954 ++ select RTC
27955 ++ help
27956 ++ If you say Y here, all ioperm and iopl calls will return an error.
27957 ++ Ioperm and iopl can be used to modify the running kernel.
27958 ++ Unfortunately, some programs need this access to operate properly,
27959 ++ the most notable of which are XFree86 and hwclock. hwclock can be
27960 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
27961 ++ enabled if this option is enabled, to ensure that hwclock operates
27962 ++ correctly. XFree86 still will not operate correctly with this option
27963 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
27964 ++ and you still want to protect your kernel against modification,
27965 ++ use the RBAC system.
27966 ++
27967 ++config GRKERNSEC_PROC_MEMMAP
27968 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
27969 ++ depends on PAX_NOEXEC || PAX_ASLR
27970 ++ help
27971 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
27972 ++ give no information about the addresses of its mappings if
27973 ++ PaX features that rely on random addresses are enabled on the task.
27974 ++ If you use PaX it is greatly recommended that you say Y here as it
27975 ++ closes up a hole that makes the full ASLR useless for suid
27976 ++ binaries.
27977 ++
27978 ++config GRKERNSEC_BRUTE
27979 ++ bool "Deter exploit bruteforcing"
27980 ++ help
27981 ++ If you say Y here, attempts to bruteforce exploits against forking
27982 ++ daemons such as apache or sshd will be deterred. When a child of a
27983 ++ forking daemon is killed by PaX or crashes due to an illegal
27984 ++ instruction, the parent process will be delayed 30 seconds upon every
27985 ++ subsequent fork until the administrator is able to assess the
27986 ++ situation and restart the daemon. It is recommended that you also
27987 ++ enable signal logging in the auditing section so that logs are
27988 ++ generated when a process performs an illegal instruction.
27989 ++
27990 ++config GRKERNSEC_MODSTOP
27991 ++ bool "Runtime module disabling"
27992 ++ depends on MODULES
27993 ++ help
27994 ++ If you say Y here, you will be able to disable the ability to (un)load
27995 ++ modules at runtime. This feature is useful if you need the ability
27996 ++ to load kernel modules at boot time, but do not want to allow an
27997 ++ attacker to load a rootkit kernel module into the system, or to remove
27998 ++ a loaded kernel module important to system functioning. You should
27999 ++ enable the /dev/mem protection feature as well, since rootkits can be
28000 ++ inserted into the kernel via other methods than kernel modules. Since
28001 ++ an untrusted module could still be loaded by modifying init scripts and
28002 ++ rebooting the system, it is also recommended that you enable the RBAC
28003 ++ system. If you enable this option, a sysctl option with name
28004 ++ "disable_modules" will be created. Setting this option to "1" disables
28005 ++ module loading. After this option is set, no further writes to it are
28006 ++ allowed until the system is rebooted.
28007 ++
28008 ++config GRKERNSEC_HIDESYM
28009 ++ bool "Hide kernel symbols"
28010 ++ help
28011 ++ If you say Y here, getting information on loaded modules, and
28012 ++ displaying all kernel symbols through a syscall will be restricted
28013 ++ to users with CAP_SYS_MODULE. This option is only effective
28014 ++ provided the following conditions are met:
28015 ++ 1) The kernel using grsecurity is not precompiled by some distribution
28016 ++ 2) You are using the RBAC system and hiding other files such as your
28017 ++ kernel image and System.map
28018 ++ 3) You have the additional /proc restrictions enabled, which removes
28019 ++ /proc/kcore
28020 ++ If the above conditions are met, this option will aid to provide a
28021 ++ useful protection against local and remote kernel exploitation of
28022 ++ overflows and arbitrary read/write vulnerabilities.
28023 ++
28024 ++endmenu
28025 ++menu "Role Based Access Control Options"
28026 ++depends on GRKERNSEC
28027 ++
28028 ++config GRKERNSEC_ACL_HIDEKERN
28029 ++ bool "Hide kernel processes"
28030 ++ help
28031 ++ If you say Y here, all kernel threads will be hidden to all
28032 ++ processes but those whose subject has the "view hidden processes"
28033 ++ flag.
28034 ++
28035 ++config GRKERNSEC_ACL_MAXTRIES
28036 ++ int "Maximum tries before password lockout"
28037 ++ default 3
28038 ++ help
28039 ++ This option enforces the maximum number of times a user can attempt
28040 ++ to authorize themselves with the grsecurity RBAC system before being
28041 ++ denied the ability to attempt authorization again for a specified time.
28042 ++ The lower the number, the harder it will be to brute-force a password.
28043 ++
28044 ++config GRKERNSEC_ACL_TIMEOUT
28045 ++ int "Time to wait after max password tries, in seconds"
28046 ++ default 30
28047 ++ help
28048 ++ This option specifies the time the user must wait after attempting to
28049 ++ authorize to the RBAC system with the maximum number of invalid
28050 ++ passwords. The higher the number, the harder it will be to brute-force
28051 ++ a password.
28052 ++
28053 ++endmenu
28054 ++menu "Filesystem Protections"
28055 ++depends on GRKERNSEC
28056 ++
28057 ++config GRKERNSEC_PROC
28058 ++ bool "Proc restrictions"
28059 ++ help
28060 ++ If you say Y here, the permissions of the /proc filesystem
28061 ++ will be altered to enhance system security and privacy. You MUST
28062 ++ choose either a user only restriction or a user and group restriction.
28063 ++ Depending upon the option you choose, you can either restrict users to
28064 ++ see only the processes they themselves run, or choose a group that can
28065 ++ view all processes and files normally restricted to root if you choose
28066 ++ the "restrict to user only" option. NOTE: If you're running identd as
28067 ++ a non-root user, you will have to run it as the group you specify here.
28068 ++
28069 ++config GRKERNSEC_PROC_USER
28070 ++ bool "Restrict /proc to user only"
28071 ++ depends on GRKERNSEC_PROC
28072 ++ help
28073 ++ If you say Y here, non-root users will only be able to view their own
28074 ++ processes, and restricts them from viewing network-related information,
28075 ++ and viewing kernel symbol and module information.
28076 ++
28077 ++config GRKERNSEC_PROC_USERGROUP
28078 ++ bool "Allow special group"
28079 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
28080 ++ help
28081 ++ If you say Y here, you will be able to select a group that will be
28082 ++ able to view all processes, network-related information, and
28083 ++ kernel and symbol information. This option is useful if you want
28084 ++ to run identd as a non-root user.
28085 ++
28086 ++config GRKERNSEC_PROC_GID
28087 ++ int "GID for special group"
28088 ++ depends on GRKERNSEC_PROC_USERGROUP
28089 ++ default 1001
28090 ++
28091 ++config GRKERNSEC_PROC_ADD
28092 ++ bool "Additional restrictions"
28093 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
28094 ++ help
28095 ++ If you say Y here, additional restrictions will be placed on
28096 ++ /proc that keep normal users from viewing device information and
28097 ++ slabinfo information that could be useful for exploits.
28098 ++
28099 ++config GRKERNSEC_LINK
28100 ++ bool "Linking restrictions"
28101 ++ help
28102 ++ If you say Y here, /tmp race exploits will be prevented, since users
28103 ++ will no longer be able to follow symlinks owned by other users in
28104 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
28105 ++ symlink is the owner of the directory. users will also not be
28106 ++ able to hardlink to files they do not own. If the sysctl option is
28107 ++ enabled, a sysctl option with name "linking_restrictions" is created.
28108 ++
28109 ++config GRKERNSEC_FIFO
28110 ++ bool "FIFO restrictions"
28111 ++ help
28112 ++ If you say Y here, users will not be able to write to FIFOs they don't
28113 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
28114 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
28115 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
28116 ++ created.
28117 ++
28118 ++config GRKERNSEC_CHROOT
28119 ++ bool "Chroot jail restrictions"
28120 ++ help
28121 ++ If you say Y here, you will be able to choose several options that will
28122 ++ make breaking out of a chrooted jail much more difficult. If you
28123 ++ encounter no software incompatibilities with the following options, it
28124 ++ is recommended that you enable each one.
28125 ++
28126 ++config GRKERNSEC_CHROOT_MOUNT
28127 ++ bool "Deny mounts"
28128 ++ depends on GRKERNSEC_CHROOT
28129 ++ help
28130 ++ If you say Y here, processes inside a chroot will not be able to
28131 ++ mount or remount filesystems. If the sysctl option is enabled, a
28132 ++ sysctl option with name "chroot_deny_mount" is created.
28133 ++
28134 ++config GRKERNSEC_CHROOT_DOUBLE
28135 ++ bool "Deny double-chroots"
28136 ++ depends on GRKERNSEC_CHROOT
28137 ++ help
28138 ++ If you say Y here, processes inside a chroot will not be able to chroot
28139 ++ again outside the chroot. This is a widely used method of breaking
28140 ++ out of a chroot jail and should not be allowed. If the sysctl
28141 ++ option is enabled, a sysctl option with name
28142 ++ "chroot_deny_chroot" is created.
28143 ++
28144 ++config GRKERNSEC_CHROOT_PIVOT
28145 ++ bool "Deny pivot_root in chroot"
28146 ++ depends on GRKERNSEC_CHROOT
28147 ++ help
28148 ++ If you say Y here, processes inside a chroot will not be able to use
28149 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
28150 ++ works similar to chroot in that it changes the root filesystem. This
28151 ++ function could be misused in a chrooted process to attempt to break out
28152 ++ of the chroot, and therefore should not be allowed. If the sysctl
28153 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
28154 ++ created.
28155 ++
28156 ++config GRKERNSEC_CHROOT_CHDIR
28157 ++ bool "Enforce chdir(\"/\") on all chroots"
28158 ++ depends on GRKERNSEC_CHROOT
28159 ++ help
28160 ++ If you say Y here, the current working directory of all newly-chrooted
28161 ++ applications will be set to the the root directory of the chroot.
28162 ++ The man page on chroot(2) states:
28163 ++ Note that this call does not change the current working
28164 ++ directory, so that `.' can be outside the tree rooted at
28165 ++ `/'. In particular, the super-user can escape from a
28166 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
28167 ++
28168 ++ It is recommended that you say Y here, since it's not known to break
28169 ++ any software. If the sysctl option is enabled, a sysctl option with
28170 ++ name "chroot_enforce_chdir" is created.
28171 ++
28172 ++config GRKERNSEC_CHROOT_CHMOD
28173 ++ bool "Deny (f)chmod +s"
28174 ++ depends on GRKERNSEC_CHROOT
28175 ++ help
28176 ++ If you say Y here, processes inside a chroot will not be able to chmod
28177 ++ or fchmod files to make them have suid or sgid bits. This protects
28178 ++ against another published method of breaking a chroot. If the sysctl
28179 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
28180 ++ created.
28181 ++
28182 ++config GRKERNSEC_CHROOT_FCHDIR
28183 ++ bool "Deny fchdir out of chroot"
28184 ++ depends on GRKERNSEC_CHROOT
28185 ++ help
28186 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
28187 ++ to a file descriptor of the chrooting process that points to a directory
28188 ++ outside the filesystem will be stopped. If the sysctl option
28189 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
28190 ++
28191 ++config GRKERNSEC_CHROOT_MKNOD
28192 ++ bool "Deny mknod"
28193 ++ depends on GRKERNSEC_CHROOT
28194 ++ help
28195 ++ If you say Y here, processes inside a chroot will not be allowed to
28196 ++ mknod. The problem with using mknod inside a chroot is that it
28197 ++ would allow an attacker to create a device entry that is the same
28198 ++ as one on the physical root of your system, which could range from
28199 ++ anything from the console device to a device for your harddrive (which
28200 ++ they could then use to wipe the drive or steal data). It is recommended
28201 ++ that you say Y here, unless you run into software incompatibilities.
28202 ++ If the sysctl option is enabled, a sysctl option with name
28203 ++ "chroot_deny_mknod" is created.
28204 ++
28205 ++config GRKERNSEC_CHROOT_SHMAT
28206 ++ bool "Deny shmat() out of chroot"
28207 ++ depends on GRKERNSEC_CHROOT
28208 ++ help
28209 ++ If you say Y here, processes inside a chroot will not be able to attach
28210 ++ to shared memory segments that were created outside of the chroot jail.
28211 ++ It is recommended that you say Y here. If the sysctl option is enabled,
28212 ++ a sysctl option with name "chroot_deny_shmat" is created.
28213 ++
28214 ++config GRKERNSEC_CHROOT_UNIX
28215 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
28216 ++ depends on GRKERNSEC_CHROOT
28217 ++ help
28218 ++ If you say Y here, processes inside a chroot will not be able to
28219 ++ connect to abstract (meaning not belonging to a filesystem) Unix
28220 ++ domain sockets that were bound outside of a chroot. It is recommended
28221 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
28222 ++ with name "chroot_deny_unix" is created.
28223 ++
28224 ++config GRKERNSEC_CHROOT_FINDTASK
28225 ++ bool "Protect outside processes"
28226 ++ depends on GRKERNSEC_CHROOT
28227 ++ help
28228 ++ If you say Y here, processes inside a chroot will not be able to
28229 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
28230 ++ or view any process outside of the chroot. If the sysctl
28231 ++ option is enabled, a sysctl option with name "chroot_findtask" is
28232 ++ created.
28233 ++
28234 ++config GRKERNSEC_CHROOT_NICE
28235 ++ bool "Restrict priority changes"
28236 ++ depends on GRKERNSEC_CHROOT
28237 ++ help
28238 ++ If you say Y here, processes inside a chroot will not be able to raise
28239 ++ the priority of processes in the chroot, or alter the priority of
28240 ++ processes outside the chroot. This provides more security than simply
28241 ++ removing CAP_SYS_NICE from the process' capability set. If the
28242 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
28243 ++ is created.
28244 ++
28245 ++config GRKERNSEC_CHROOT_SYSCTL
28246 ++ bool "Deny sysctl writes"
28247 ++ depends on GRKERNSEC_CHROOT
28248 ++ help
28249 ++ If you say Y here, an attacker in a chroot will not be able to
28250 ++ write to sysctl entries, either by sysctl(2) or through a /proc
28251 ++ interface. It is strongly recommended that you say Y here. If the
28252 ++ sysctl option is enabled, a sysctl option with name
28253 ++ "chroot_deny_sysctl" is created.
28254 ++
28255 ++config GRKERNSEC_CHROOT_CAPS
28256 ++ bool "Capability restrictions"
28257 ++ depends on GRKERNSEC_CHROOT
28258 ++ help
28259 ++ If you say Y here, the capabilities on all root processes within a
28260 ++ chroot jail will be lowered to stop module insertion, raw i/o,
28261 ++ system and net admin tasks, rebooting the system, modifying immutable
28262 ++ files, modifying IPC owned by another, and changing the system time.
28263 ++ This is left an option because it can break some apps. Disable this
28264 ++ if your chrooted apps are having problems performing those kinds of
28265 ++ tasks. If the sysctl option is enabled, a sysctl option with
28266 ++ name "chroot_caps" is created.
28267 ++
28268 ++endmenu
28269 ++menu "Kernel Auditing"
28270 ++depends on GRKERNSEC
28271 ++
28272 ++config GRKERNSEC_AUDIT_GROUP
28273 ++ bool "Single group for auditing"
28274 ++ help
28275 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
28276 ++ will only operate on a group you specify. This option is recommended
28277 ++ if you only want to watch certain users instead of having a large
28278 ++ amount of logs from the entire system. If the sysctl option is enabled,
28279 ++ a sysctl option with name "audit_group" is created.
28280 ++
28281 ++config GRKERNSEC_AUDIT_GID
28282 ++ int "GID for auditing"
28283 ++ depends on GRKERNSEC_AUDIT_GROUP
28284 ++ default 1007
28285 ++
28286 ++config GRKERNSEC_EXECLOG
28287 ++ bool "Exec logging"
28288 ++ help
28289 ++ If you say Y here, all execve() calls will be logged (since the
28290 ++ other exec*() calls are frontends to execve(), all execution
28291 ++ will be logged). Useful for shell-servers that like to keep track
28292 ++ of their users. If the sysctl option is enabled, a sysctl option with
28293 ++ name "exec_logging" is created.
28294 ++ WARNING: This option when enabled will produce a LOT of logs, especially
28295 ++ on an active system.
28296 ++
28297 ++config GRKERNSEC_RESLOG
28298 ++ bool "Resource logging"
28299 ++ help
28300 ++ If you say Y here, all attempts to overstep resource limits will
28301 ++ be logged with the resource name, the requested size, and the current
28302 ++ limit. It is highly recommended that you say Y here. If the sysctl
28303 ++ option is enabled, a sysctl option with name "resource_logging" is
28304 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
28305 ++
28306 ++config GRKERNSEC_CHROOT_EXECLOG
28307 ++ bool "Log execs within chroot"
28308 ++ help
28309 ++ If you say Y here, all executions inside a chroot jail will be logged
28310 ++ to syslog. This can cause a large amount of logs if certain
28311 ++ applications (eg. djb's daemontools) are installed on the system, and
28312 ++ is therefore left as an option. If the sysctl option is enabled, a
28313 ++ sysctl option with name "chroot_execlog" is created.
28314 ++
28315 ++config GRKERNSEC_AUDIT_CHDIR
28316 ++ bool "Chdir logging"
28317 ++ help
28318 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
28319 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
28320 ++
28321 ++config GRKERNSEC_AUDIT_MOUNT
28322 ++ bool "(Un)Mount logging"
28323 ++ help
28324 ++ If you say Y here, all mounts and unmounts will be logged. If the
28325 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
28326 ++ created.
28327 ++
28328 ++config GRKERNSEC_AUDIT_IPC
28329 ++ bool "IPC logging"
28330 ++ help
28331 ++ If you say Y here, creation and removal of message queues, semaphores,
28332 ++ and shared memory will be logged. If the sysctl option is enabled, a
28333 ++ sysctl option with name "audit_ipc" is created.
28334 ++
28335 ++config GRKERNSEC_SIGNAL
28336 ++ bool "Signal logging"
28337 ++ help
28338 ++ If you say Y here, certain important signals will be logged, such as
28339 ++ SIGSEGV, which will as a result inform you of when a error in a program
28340 ++ occurred, which in some cases could mean a possible exploit attempt.
28341 ++ If the sysctl option is enabled, a sysctl option with name
28342 ++ "signal_logging" is created.
28343 ++
28344 ++config GRKERNSEC_FORKFAIL
28345 ++ bool "Fork failure logging"
28346 ++ help
28347 ++ If you say Y here, all failed fork() attempts will be logged.
28348 ++ This could suggest a fork bomb, or someone attempting to overstep
28349 ++ their process limit. If the sysctl option is enabled, a sysctl option
28350 ++ with name "forkfail_logging" is created.
28351 ++
28352 ++config GRKERNSEC_TIME
28353 ++ bool "Time change logging"
28354 ++ help
28355 ++ If you say Y here, any changes of the system clock will be logged.
28356 ++ If the sysctl option is enabled, a sysctl option with name
28357 ++ "timechange_logging" is created.
28358 ++
28359 ++config GRKERNSEC_PROC_IPADDR
28360 ++ bool "/proc/<pid>/ipaddr support"
28361 ++ help
28362 ++ If you say Y here, a new entry will be added to each /proc/<pid>
28363 ++ directory that contains the IP address of the person using the task.
28364 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
28365 ++ This information can be useful for IDS/IPSes to perform remote response
28366 ++ to a local attack. The entry is readable by only the owner of the
28367 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
28368 ++ the RBAC system), and thus does not create privacy concerns.
28369 ++
28370 ++config GRKERNSEC_AUDIT_TEXTREL
28371 ++ bool 'ELF text relocations logging (READ HELP)'
28372 ++ depends on PAX_MPROTECT
28373 ++ help
28374 ++ If you say Y here, text relocations will be logged with the filename
28375 ++ of the offending library or binary. The purpose of the feature is
28376 ++ to help Linux distribution developers get rid of libraries and
28377 ++ binaries that need text relocations which hinder the future progress
28378 ++ of PaX. Only Linux distribution developers should say Y here, and
28379 ++ never on a production machine, as this option creates an information
28380 ++ leak that could aid an attacker in defeating the randomization of
28381 ++ a single memory region. If the sysctl option is enabled, a sysctl
28382 ++ option with name "audit_textrel" is created.
28383 ++
28384 ++endmenu
28385 ++
28386 ++menu "Executable Protections"
28387 ++depends on GRKERNSEC
28388 ++
28389 ++config GRKERNSEC_EXECVE
28390 ++ bool "Enforce RLIMIT_NPROC on execs"
28391 ++ help
28392 ++ If you say Y here, users with a resource limit on processes will
28393 ++ have the value checked during execve() calls. The current system
28394 ++ only checks the system limit during fork() calls. If the sysctl option
28395 ++ is enabled, a sysctl option with name "execve_limiting" is created.
28396 ++
28397 ++config GRKERNSEC_DMESG
28398 ++ bool "Dmesg(8) restriction"
28399 ++ help
28400 ++ If you say Y here, non-root users will not be able to use dmesg(8)
28401 ++ to view up to the last 4kb of messages in the kernel's log buffer.
28402 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
28403 ++ created.
28404 ++
28405 ++config GRKERNSEC_TPE
28406 ++ bool "Trusted Path Execution (TPE)"
28407 ++ help
28408 ++ If you say Y here, you will be able to choose a gid to add to the
28409 ++ supplementary groups of users you want to mark as "untrusted."
28410 ++ These users will not be able to execute any files that are not in
28411 ++ root-owned directories writable only by root. If the sysctl option
28412 ++ is enabled, a sysctl option with name "tpe" is created.
28413 ++
28414 ++config GRKERNSEC_TPE_ALL
28415 ++ bool "Partially restrict non-root users"
28416 ++ depends on GRKERNSEC_TPE
28417 ++ help
28418 ++ If you say Y here, All non-root users other than the ones in the
28419 ++ group specified in the main TPE option will only be allowed to
28420 ++ execute files in directories they own that are not group or
28421 ++ world-writable, or in directories owned by root and writable only by
28422 ++ root. If the sysctl option is enabled, a sysctl option with name
28423 ++ "tpe_restrict_all" is created.
28424 ++
28425 ++config GRKERNSEC_TPE_INVERT
28426 ++ bool "Invert GID option"
28427 ++ depends on GRKERNSEC_TPE
28428 ++ help
28429 ++ If you say Y here, the group you specify in the TPE configuration will
28430 ++ decide what group TPE restrictions will be *disabled* for. This
28431 ++ option is useful if you want TPE restrictions to be applied to most
28432 ++ users on the system.
28433 ++
28434 ++config GRKERNSEC_TPE_GID
28435 ++ int "GID for untrusted users"
28436 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
28437 ++ default 1005
28438 ++ help
28439 ++ If you have selected the "Invert GID option" above, setting this
28440 ++ GID determines what group TPE restrictions will be *disabled* for.
28441 ++ If you have not selected the "Invert GID option" above, setting this
28442 ++ GID determines what group TPE restrictions will be *enabled* for.
28443 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28444 ++ is created.
28445 ++
28446 ++config GRKERNSEC_TPE_GID
28447 ++ int "GID for trusted users"
28448 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
28449 ++ default 1005
28450 ++ help
28451 ++ If you have selected the "Invert GID option" above, setting this
28452 ++ GID determines what group TPE restrictions will be *disabled* for.
28453 ++ If you have not selected the "Invert GID option" above, setting this
28454 ++ GID determines what group TPE restrictions will be *enabled* for.
28455 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
28456 ++ is created.
28457 ++
28458 ++endmenu
28459 ++menu "Network Protections"
28460 ++depends on GRKERNSEC
28461 ++
28462 ++config GRKERNSEC_RANDNET
28463 ++ bool "Larger entropy pools"
28464 ++ help
28465 ++ If you say Y here, the entropy pools used for many features of Linux
28466 ++ and grsecurity will be doubled in size. Since several grsecurity
28467 ++ features use additional randomness, it is recommended that you say Y
28468 ++ here. Saying Y here has a similar effect as modifying
28469 ++ /proc/sys/kernel/random/poolsize.
28470 ++
28471 ++config GRKERNSEC_SOCKET
28472 ++ bool "Socket restrictions"
28473 ++ help
28474 ++ If you say Y here, you will be able to choose from several options.
28475 ++ If you assign a GID on your system and add it to the supplementary
28476 ++ groups of users you want to restrict socket access to, this patch
28477 ++ will perform up to three things, based on the option(s) you choose.
28478 ++
28479 ++config GRKERNSEC_SOCKET_ALL
28480 ++ bool "Deny any sockets to group"
28481 ++ depends on GRKERNSEC_SOCKET
28482 ++ help
28483 ++ If you say Y here, you will be able to choose a GID of whose users will
28484 ++ be unable to connect to other hosts from your machine or run server
28485 ++ applications from your machine. If the sysctl option is enabled, a
28486 ++ sysctl option with name "socket_all" is created.
28487 ++
28488 ++config GRKERNSEC_SOCKET_ALL_GID
28489 ++ int "GID to deny all sockets for"
28490 ++ depends on GRKERNSEC_SOCKET_ALL
28491 ++ default 1004
28492 ++ help
28493 ++ Here you can choose the GID to disable socket access for. Remember to
28494 ++ add the users you want socket access disabled for to the GID
28495 ++ specified here. If the sysctl option is enabled, a sysctl option
28496 ++ with name "socket_all_gid" is created.
28497 ++
28498 ++config GRKERNSEC_SOCKET_CLIENT
28499 ++ bool "Deny client sockets to group"
28500 ++ depends on GRKERNSEC_SOCKET
28501 ++ help
28502 ++ If you say Y here, you will be able to choose a GID of whose users will
28503 ++ be unable to connect to other hosts from your machine, but will be
28504 ++ able to run servers. If this option is enabled, all users in the group
28505 ++ you specify will have to use passive mode when initiating ftp transfers
28506 ++ from the shell on your machine. If the sysctl option is enabled, a
28507 ++ sysctl option with name "socket_client" is created.
28508 ++
28509 ++config GRKERNSEC_SOCKET_CLIENT_GID
28510 ++ int "GID to deny client sockets for"
28511 ++ depends on GRKERNSEC_SOCKET_CLIENT
28512 ++ default 1003
28513 ++ help
28514 ++ Here you can choose the GID to disable client socket access for.
28515 ++ Remember to add the users you want client socket access disabled for to
28516 ++ the GID specified here. If the sysctl option is enabled, a sysctl
28517 ++ option with name "socket_client_gid" is created.
28518 ++
28519 ++config GRKERNSEC_SOCKET_SERVER
28520 ++ bool "Deny server sockets to group"
28521 ++ depends on GRKERNSEC_SOCKET
28522 ++ help
28523 ++ If you say Y here, you will be able to choose a GID of whose users will
28524 ++ be unable to run server applications from your machine. If the sysctl
28525 ++ option is enabled, a sysctl option with name "socket_server" is created.
28526 ++
28527 ++config GRKERNSEC_SOCKET_SERVER_GID
28528 ++ int "GID to deny server sockets for"
28529 ++ depends on GRKERNSEC_SOCKET_SERVER
28530 ++ default 1002
28531 ++ help
28532 ++ Here you can choose the GID to disable server socket access for.
28533 ++ Remember to add the users you want server socket access disabled for to
28534 ++ the GID specified here. If the sysctl option is enabled, a sysctl
28535 ++ option with name "socket_server_gid" is created.
28536 ++
28537 ++endmenu
28538 ++menu "Sysctl support"
28539 ++depends on GRKERNSEC && SYSCTL
28540 ++
28541 ++config GRKERNSEC_SYSCTL
28542 ++ bool "Sysctl support"
28543 ++ help
28544 ++ If you say Y here, you will be able to change the options that
28545 ++ grsecurity runs with at bootup, without having to recompile your
28546 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
28547 ++ to enable (1) or disable (0) various features. All the sysctl entries
28548 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
28549 ++ All features enabled in the kernel configuration are disabled at boot
28550 ++ if you do not say Y to the "Turn on features by default" option.
28551 ++ All options should be set at startup, and the grsec_lock entry should
28552 ++ be set to a non-zero value after all the options are set.
28553 ++ *THIS IS EXTREMELY IMPORTANT*
28554 ++
28555 ++config GRKERNSEC_SYSCTL_ON
28556 ++ bool "Turn on features by default"
28557 ++ depends on GRKERNSEC_SYSCTL
28558 ++ help
28559 ++ If you say Y here, instead of having all features enabled in the
28560 ++ kernel configuration disabled at boot time, the features will be
28561 ++ enabled at boot time. It is recommended you say Y here unless
28562 ++ there is some reason you would want all sysctl-tunable features to
28563 ++ be disabled by default. As mentioned elsewhere, it is important
28564 ++ to enable the grsec_lock entry once you have finished modifying
28565 ++ the sysctl entries.
28566 ++
28567 ++endmenu
28568 ++menu "Logging Options"
28569 ++depends on GRKERNSEC
28570 ++
28571 ++config GRKERNSEC_FLOODTIME
28572 ++ int "Seconds in between log messages (minimum)"
28573 ++ default 10
28574 ++ help
28575 ++ This option allows you to enforce the number of seconds between
28576 ++ grsecurity log messages. The default should be suitable for most
28577 ++ people, however, if you choose to change it, choose a value small enough
28578 ++ to allow informative logs to be produced, but large enough to
28579 ++ prevent flooding.
28580 ++
28581 ++config GRKERNSEC_FLOODBURST
28582 ++ int "Number of messages in a burst (maximum)"
28583 ++ default 4
28584 ++ help
28585 ++ This option allows you to choose the maximum number of messages allowed
28586 ++ within the flood time interval you chose in a separate option. The
28587 ++ default should be suitable for most people, however if you find that
28588 ++ many of your logs are being interpreted as flooding, you may want to
28589 ++ raise this value.
28590 ++
28591 ++endmenu
28592 ++
28593 ++endmenu
28594 +diff -urNp linux-2.6.26.6/grsecurity/Makefile linux-2.6.26.6/grsecurity/Makefile
28595 +--- linux-2.6.26.6/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
28596 ++++ linux-2.6.26.6/grsecurity/Makefile 2008-10-11 21:54:20.000000000 -0400
28597 +@@ -0,0 +1,20 @@
28598 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
28599 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
28600 ++# into an RBAC system
28601 ++#
28602 ++# All code in this directory and various hooks inserted throughout the kernel
28603 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
28604 ++
28605 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
28606 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
28607 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
28608 ++
28609 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
28610 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
28611 ++ gracl_learn.o grsec_log.o
28612 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
28613 ++
28614 ++ifndef CONFIG_GRKERNSEC
28615 ++obj-y += grsec_disabled.o
28616 ++endif
28617 ++
28618 +diff -urNp linux-2.6.26.6/include/asm-alpha/elf.h linux-2.6.26.6/include/asm-alpha/elf.h
28619 +--- linux-2.6.26.6/include/asm-alpha/elf.h 2008-10-08 23:24:05.000000000 -0400
28620 ++++ linux-2.6.26.6/include/asm-alpha/elf.h 2008-10-11 21:54:20.000000000 -0400
28621 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
28622 +
28623 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
28624 +
28625 ++#ifdef CONFIG_PAX_ASLR
28626 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
28627 ++
28628 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
28629 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
28630 ++#endif
28631 ++
28632 + /* $0 is set by ld.so to a pointer to a function which might be
28633 + registered using atexit. This provides a mean for the dynamic
28634 + linker to call DT_FINI functions for shared libraries that have
28635 +diff -urNp linux-2.6.26.6/include/asm-alpha/kmap_types.h linux-2.6.26.6/include/asm-alpha/kmap_types.h
28636 +--- linux-2.6.26.6/include/asm-alpha/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28637 ++++ linux-2.6.26.6/include/asm-alpha/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28638 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
28639 + D(10) KM_IRQ1,
28640 + D(11) KM_SOFTIRQ0,
28641 + D(12) KM_SOFTIRQ1,
28642 +-D(13) KM_TYPE_NR
28643 ++D(13) KM_CLEARPAGE,
28644 ++D(14) KM_TYPE_NR
28645 + };
28646 +
28647 + #undef D
28648 +diff -urNp linux-2.6.26.6/include/asm-alpha/pgtable.h linux-2.6.26.6/include/asm-alpha/pgtable.h
28649 +--- linux-2.6.26.6/include/asm-alpha/pgtable.h 2008-10-08 23:24:05.000000000 -0400
28650 ++++ linux-2.6.26.6/include/asm-alpha/pgtable.h 2008-10-11 21:54:20.000000000 -0400
28651 +@@ -101,6 +101,17 @@ struct vm_area_struct;
28652 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
28653 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
28654 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
28655 ++
28656 ++#ifdef CONFIG_PAX_PAGEEXEC
28657 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
28658 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
28659 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
28660 ++#else
28661 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
28662 ++# define PAGE_COPY_NOEXEC PAGE_COPY
28663 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
28664 ++#endif
28665 ++
28666 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
28667 +
28668 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
28669 +diff -urNp linux-2.6.26.6/include/asm-arm/elf.h linux-2.6.26.6/include/asm-arm/elf.h
28670 +--- linux-2.6.26.6/include/asm-arm/elf.h 2008-10-08 23:24:05.000000000 -0400
28671 ++++ linux-2.6.26.6/include/asm-arm/elf.h 2008-10-11 21:54:20.000000000 -0400
28672 +@@ -87,7 +87,14 @@ extern char elf_platform[];
28673 + the loader. We need to make sure that it is out of the way of the program
28674 + that it will "exec", and that there is sufficient room for the brk. */
28675 +
28676 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
28677 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28678 ++
28679 ++#ifdef CONFIG_PAX_ASLR
28680 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
28681 ++
28682 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
28683 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
28684 ++#endif
28685 +
28686 + /* When the program starts, a1 contains a pointer to a function to be
28687 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
28688 +diff -urNp linux-2.6.26.6/include/asm-arm/kmap_types.h linux-2.6.26.6/include/asm-arm/kmap_types.h
28689 +--- linux-2.6.26.6/include/asm-arm/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28690 ++++ linux-2.6.26.6/include/asm-arm/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28691 +@@ -18,6 +18,7 @@ enum km_type {
28692 + KM_IRQ1,
28693 + KM_SOFTIRQ0,
28694 + KM_SOFTIRQ1,
28695 ++ KM_CLEARPAGE,
28696 + KM_TYPE_NR
28697 + };
28698 +
28699 +diff -urNp linux-2.6.26.6/include/asm-avr32/elf.h linux-2.6.26.6/include/asm-avr32/elf.h
28700 +--- linux-2.6.26.6/include/asm-avr32/elf.h 2008-10-08 23:24:05.000000000 -0400
28701 ++++ linux-2.6.26.6/include/asm-avr32/elf.h 2008-10-11 21:54:20.000000000 -0400
28702 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
28703 + the loader. We need to make sure that it is out of the way of the program
28704 + that it will "exec", and that there is sufficient room for the brk. */
28705 +
28706 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
28707 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28708 +
28709 ++#ifdef CONFIG_PAX_ASLR
28710 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
28711 ++
28712 ++#define PAX_DELTA_MMAP_LEN 15
28713 ++#define PAX_DELTA_STACK_LEN 15
28714 ++#endif
28715 +
28716 + /* This yields a mask that user programs can use to figure out what
28717 + instruction set this CPU supports. This could be done in user space,
28718 +diff -urNp linux-2.6.26.6/include/asm-avr32/kmap_types.h linux-2.6.26.6/include/asm-avr32/kmap_types.h
28719 +--- linux-2.6.26.6/include/asm-avr32/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28720 ++++ linux-2.6.26.6/include/asm-avr32/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28721 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
28722 + D(11) KM_IRQ1,
28723 + D(12) KM_SOFTIRQ0,
28724 + D(13) KM_SOFTIRQ1,
28725 +-D(14) KM_TYPE_NR
28726 ++D(14) KM_CLEARPAGE,
28727 ++D(15) KM_TYPE_NR
28728 + };
28729 +
28730 + #undef D
28731 +diff -urNp linux-2.6.26.6/include/asm-blackfin/kmap_types.h linux-2.6.26.6/include/asm-blackfin/kmap_types.h
28732 +--- linux-2.6.26.6/include/asm-blackfin/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28733 ++++ linux-2.6.26.6/include/asm-blackfin/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28734 +@@ -15,6 +15,7 @@ enum km_type {
28735 + KM_IRQ1,
28736 + KM_SOFTIRQ0,
28737 + KM_SOFTIRQ1,
28738 ++ KM_CLEARPAGE,
28739 + KM_TYPE_NR
28740 + };
28741 +
28742 +diff -urNp linux-2.6.26.6/include/asm-cris/kmap_types.h linux-2.6.26.6/include/asm-cris/kmap_types.h
28743 +--- linux-2.6.26.6/include/asm-cris/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28744 ++++ linux-2.6.26.6/include/asm-cris/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28745 +@@ -19,6 +19,7 @@ enum km_type {
28746 + KM_IRQ1,
28747 + KM_SOFTIRQ0,
28748 + KM_SOFTIRQ1,
28749 ++ KM_CLEARPAGE,
28750 + KM_TYPE_NR
28751 + };
28752 +
28753 +diff -urNp linux-2.6.26.6/include/asm-frv/kmap_types.h linux-2.6.26.6/include/asm-frv/kmap_types.h
28754 +--- linux-2.6.26.6/include/asm-frv/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28755 ++++ linux-2.6.26.6/include/asm-frv/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28756 +@@ -23,6 +23,7 @@ enum km_type {
28757 + KM_IRQ1,
28758 + KM_SOFTIRQ0,
28759 + KM_SOFTIRQ1,
28760 ++ KM_CLEARPAGE,
28761 + KM_TYPE_NR
28762 + };
28763 +
28764 +diff -urNp linux-2.6.26.6/include/asm-generic/futex.h linux-2.6.26.6/include/asm-generic/futex.h
28765 +--- linux-2.6.26.6/include/asm-generic/futex.h 2008-10-08 23:24:05.000000000 -0400
28766 ++++ linux-2.6.26.6/include/asm-generic/futex.h 2008-10-11 21:54:20.000000000 -0400
28767 +@@ -6,7 +6,7 @@
28768 + #include <asm/errno.h>
28769 +
28770 + static inline int
28771 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
28772 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
28773 + {
28774 + int op = (encoded_op >> 28) & 7;
28775 + int cmp = (encoded_op >> 24) & 15;
28776 +@@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op,
28777 + }
28778 +
28779 + static inline int
28780 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
28781 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
28782 + {
28783 + return -ENOSYS;
28784 + }
28785 +diff -urNp linux-2.6.26.6/include/asm-generic/vmlinux.lds.h linux-2.6.26.6/include/asm-generic/vmlinux.lds.h
28786 +--- linux-2.6.26.6/include/asm-generic/vmlinux.lds.h 2008-10-08 23:24:05.000000000 -0400
28787 ++++ linux-2.6.26.6/include/asm-generic/vmlinux.lds.h 2008-10-11 21:54:20.000000000 -0400
28788 +@@ -59,6 +59,7 @@
28789 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
28790 + VMLINUX_SYMBOL(__start_rodata) = .; \
28791 + *(.rodata) *(.rodata.*) \
28792 ++ *(.data.read_only) \
28793 + *(__vermagic) /* Kernel version magic */ \
28794 + *(__markers_strings) /* Markers: strings */ \
28795 + } \
28796 +diff -urNp linux-2.6.26.6/include/asm-h8300/kmap_types.h linux-2.6.26.6/include/asm-h8300/kmap_types.h
28797 +--- linux-2.6.26.6/include/asm-h8300/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28798 ++++ linux-2.6.26.6/include/asm-h8300/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28799 +@@ -15,6 +15,7 @@ enum km_type {
28800 + KM_IRQ1,
28801 + KM_SOFTIRQ0,
28802 + KM_SOFTIRQ1,
28803 ++ KM_CLEARPAGE,
28804 + KM_TYPE_NR
28805 + };
28806 +
28807 +diff -urNp linux-2.6.26.6/include/asm-ia64/elf.h linux-2.6.26.6/include/asm-ia64/elf.h
28808 +--- linux-2.6.26.6/include/asm-ia64/elf.h 2008-10-08 23:24:05.000000000 -0400
28809 ++++ linux-2.6.26.6/include/asm-ia64/elf.h 2008-10-11 21:54:20.000000000 -0400
28810 +@@ -187,7 +187,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
28811 + typedef struct ia64_fpreg elf_fpreg_t;
28812 + typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
28813 +
28814 ++#ifdef CONFIG_PAX_ASLR
28815 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
28816 +
28817 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
28818 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
28819 ++#endif
28820 +
28821 + struct pt_regs; /* forward declaration... */
28822 + extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
28823 +diff -urNp linux-2.6.26.6/include/asm-ia64/kmap_types.h linux-2.6.26.6/include/asm-ia64/kmap_types.h
28824 +--- linux-2.6.26.6/include/asm-ia64/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28825 ++++ linux-2.6.26.6/include/asm-ia64/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28826 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
28827 + D(10) KM_IRQ1,
28828 + D(11) KM_SOFTIRQ0,
28829 + D(12) KM_SOFTIRQ1,
28830 +-D(13) KM_TYPE_NR
28831 ++D(13) KM_CLEARPAGE,
28832 ++D(14) KM_TYPE_NR
28833 + };
28834 +
28835 + #undef D
28836 +diff -urNp linux-2.6.26.6/include/asm-ia64/pgtable.h linux-2.6.26.6/include/asm-ia64/pgtable.h
28837 +--- linux-2.6.26.6/include/asm-ia64/pgtable.h 2008-10-08 23:24:05.000000000 -0400
28838 ++++ linux-2.6.26.6/include/asm-ia64/pgtable.h 2008-10-11 21:54:20.000000000 -0400
28839 +@@ -143,6 +143,17 @@
28840 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28841 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28842 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
28843 ++
28844 ++#ifdef CONFIG_PAX_PAGEEXEC
28845 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
28846 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28847 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
28848 ++#else
28849 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
28850 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
28851 ++# define PAGE_COPY_NOEXEC PAGE_COPY
28852 ++#endif
28853 ++
28854 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
28855 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
28856 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
28857 +diff -urNp linux-2.6.26.6/include/asm-m32r/kmap_types.h linux-2.6.26.6/include/asm-m32r/kmap_types.h
28858 +--- linux-2.6.26.6/include/asm-m32r/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28859 ++++ linux-2.6.26.6/include/asm-m32r/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28860 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
28861 + D(10) KM_IRQ1,
28862 + D(11) KM_SOFTIRQ0,
28863 + D(12) KM_SOFTIRQ1,
28864 +-D(13) KM_TYPE_NR
28865 ++D(13) KM_CLEARPAGE,
28866 ++D(14) KM_TYPE_NR
28867 + };
28868 +
28869 + #undef D
28870 +diff -urNp linux-2.6.26.6/include/asm-m68k/kmap_types.h linux-2.6.26.6/include/asm-m68k/kmap_types.h
28871 +--- linux-2.6.26.6/include/asm-m68k/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28872 ++++ linux-2.6.26.6/include/asm-m68k/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28873 +@@ -15,6 +15,7 @@ enum km_type {
28874 + KM_IRQ1,
28875 + KM_SOFTIRQ0,
28876 + KM_SOFTIRQ1,
28877 ++ KM_CLEARPAGE,
28878 + KM_TYPE_NR
28879 + };
28880 +
28881 +diff -urNp linux-2.6.26.6/include/asm-m68knommu/kmap_types.h linux-2.6.26.6/include/asm-m68knommu/kmap_types.h
28882 +--- linux-2.6.26.6/include/asm-m68knommu/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28883 ++++ linux-2.6.26.6/include/asm-m68knommu/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28884 +@@ -15,6 +15,7 @@ enum km_type {
28885 + KM_IRQ1,
28886 + KM_SOFTIRQ0,
28887 + KM_SOFTIRQ1,
28888 ++ KM_CLEARPAGE,
28889 + KM_TYPE_NR
28890 + };
28891 +
28892 +diff -urNp linux-2.6.26.6/include/asm-mips/elf.h linux-2.6.26.6/include/asm-mips/elf.h
28893 +--- linux-2.6.26.6/include/asm-mips/elf.h 2008-10-08 23:24:05.000000000 -0400
28894 ++++ linux-2.6.26.6/include/asm-mips/elf.h 2008-10-11 21:54:20.000000000 -0400
28895 +@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
28896 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
28897 + #endif
28898 +
28899 ++#ifdef CONFIG_PAX_ASLR
28900 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
28901 ++
28902 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
28903 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
28904 ++#endif
28905 ++
28906 + #endif /* _ASM_ELF_H */
28907 +diff -urNp linux-2.6.26.6/include/asm-mips/kmap_types.h linux-2.6.26.6/include/asm-mips/kmap_types.h
28908 +--- linux-2.6.26.6/include/asm-mips/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28909 ++++ linux-2.6.26.6/include/asm-mips/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28910 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
28911 + D(10) KM_IRQ1,
28912 + D(11) KM_SOFTIRQ0,
28913 + D(12) KM_SOFTIRQ1,
28914 +-D(13) KM_TYPE_NR
28915 ++D(13) KM_CLEARPAGE,
28916 ++D(14) KM_TYPE_NR
28917 + };
28918 +
28919 + #undef D
28920 +diff -urNp linux-2.6.26.6/include/asm-mips/page.h linux-2.6.26.6/include/asm-mips/page.h
28921 +--- linux-2.6.26.6/include/asm-mips/page.h 2008-10-08 23:24:05.000000000 -0400
28922 ++++ linux-2.6.26.6/include/asm-mips/page.h 2008-10-11 21:54:20.000000000 -0400
28923 +@@ -79,7 +79,7 @@ extern void copy_user_highpage(struct pa
28924 + #ifdef CONFIG_CPU_MIPS32
28925 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
28926 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
28927 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
28928 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
28929 + #else
28930 + typedef struct { unsigned long long pte; } pte_t;
28931 + #define pte_val(x) ((x).pte)
28932 +diff -urNp linux-2.6.26.6/include/asm-mips/system.h linux-2.6.26.6/include/asm-mips/system.h
28933 +--- linux-2.6.26.6/include/asm-mips/system.h 2008-10-08 23:24:05.000000000 -0400
28934 ++++ linux-2.6.26.6/include/asm-mips/system.h 2008-10-11 21:54:20.000000000 -0400
28935 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
28936 + */
28937 + #define __ARCH_WANT_UNLOCKED_CTXSW
28938 +
28939 +-extern unsigned long arch_align_stack(unsigned long sp);
28940 ++#define arch_align_stack(x) (x)
28941 +
28942 + #endif /* _ASM_SYSTEM_H */
28943 +diff -urNp linux-2.6.26.6/include/asm-parisc/elf.h linux-2.6.26.6/include/asm-parisc/elf.h
28944 +--- linux-2.6.26.6/include/asm-parisc/elf.h 2008-10-08 23:24:05.000000000 -0400
28945 ++++ linux-2.6.26.6/include/asm-parisc/elf.h 2008-10-11 21:54:20.000000000 -0400
28946 +@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
28947 +
28948 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
28949 +
28950 ++#ifdef CONFIG_PAX_ASLR
28951 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
28952 ++
28953 ++#define PAX_DELTA_MMAP_LEN 16
28954 ++#define PAX_DELTA_STACK_LEN 16
28955 ++#endif
28956 ++
28957 + /* This yields a mask that user programs can use to figure out what
28958 + instruction set this CPU supports. This could be done in user space,
28959 + but it's not easy, and we've already done it here. */
28960 +diff -urNp linux-2.6.26.6/include/asm-parisc/kmap_types.h linux-2.6.26.6/include/asm-parisc/kmap_types.h
28961 +--- linux-2.6.26.6/include/asm-parisc/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
28962 ++++ linux-2.6.26.6/include/asm-parisc/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
28963 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
28964 + D(10) KM_IRQ1,
28965 + D(11) KM_SOFTIRQ0,
28966 + D(12) KM_SOFTIRQ1,
28967 +-D(13) KM_TYPE_NR
28968 ++D(13) KM_CLEARPAGE,
28969 ++D(14) KM_TYPE_NR
28970 + };
28971 +
28972 + #undef D
28973 +diff -urNp linux-2.6.26.6/include/asm-parisc/pgtable.h linux-2.6.26.6/include/asm-parisc/pgtable.h
28974 +--- linux-2.6.26.6/include/asm-parisc/pgtable.h 2008-10-08 23:24:05.000000000 -0400
28975 ++++ linux-2.6.26.6/include/asm-parisc/pgtable.h 2008-10-11 21:54:20.000000000 -0400
28976 +@@ -202,6 +202,17 @@
28977 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
28978 + #define PAGE_COPY PAGE_EXECREAD
28979 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
28980 ++
28981 ++#ifdef CONFIG_PAX_PAGEEXEC
28982 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
28983 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
28984 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
28985 ++#else
28986 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
28987 ++# define PAGE_COPY_NOEXEC PAGE_COPY
28988 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
28989 ++#endif
28990 ++
28991 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
28992 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
28993 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
28994 +diff -urNp linux-2.6.26.6/include/asm-powerpc/elf.h linux-2.6.26.6/include/asm-powerpc/elf.h
28995 +--- linux-2.6.26.6/include/asm-powerpc/elf.h 2008-10-08 23:24:05.000000000 -0400
28996 ++++ linux-2.6.26.6/include/asm-powerpc/elf.h 2008-10-11 21:54:20.000000000 -0400
28997 +@@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
28998 + typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
28999 + #endif
29000 +
29001 ++#ifdef CONFIG_PAX_ASLR
29002 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
29003 ++
29004 ++#ifdef __powerpc64__
29005 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
29006 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
29007 ++#else
29008 ++#define PAX_DELTA_MMAP_LEN 15
29009 ++#define PAX_DELTA_STACK_LEN 15
29010 ++#endif
29011 ++#endif
29012 ++
29013 + #ifdef __KERNEL__
29014 + /*
29015 + * This is used to ensure we don't load something for the wrong architecture.
29016 +diff -urNp linux-2.6.26.6/include/asm-powerpc/kmap_types.h linux-2.6.26.6/include/asm-powerpc/kmap_types.h
29017 +--- linux-2.6.26.6/include/asm-powerpc/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29018 ++++ linux-2.6.26.6/include/asm-powerpc/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29019 +@@ -26,6 +26,7 @@ enum km_type {
29020 + KM_SOFTIRQ1,
29021 + KM_PPC_SYNC_PAGE,
29022 + KM_PPC_SYNC_ICACHE,
29023 ++ KM_CLEARPAGE,
29024 + KM_TYPE_NR
29025 + };
29026 +
29027 +diff -urNp linux-2.6.26.6/include/asm-powerpc/page_64.h linux-2.6.26.6/include/asm-powerpc/page_64.h
29028 +--- linux-2.6.26.6/include/asm-powerpc/page_64.h 2008-10-08 23:24:05.000000000 -0400
29029 ++++ linux-2.6.26.6/include/asm-powerpc/page_64.h 2008-10-11 21:54:20.000000000 -0400
29030 +@@ -163,15 +163,18 @@ do { \
29031 + * stack by default, so in the absense of a PT_GNU_STACK program header
29032 + * we turn execute permission off.
29033 + */
29034 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
29035 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29036 ++#define VM_STACK_DEFAULT_FLAGS32 \
29037 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
29038 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29039 +
29040 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
29041 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29042 +
29043 ++#ifndef CONFIG_PAX_PAGEEXEC
29044 + #define VM_STACK_DEFAULT_FLAGS \
29045 + (test_thread_flag(TIF_32BIT) ? \
29046 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
29047 ++#endif
29048 +
29049 + #include <asm-generic/page.h>
29050 +
29051 +diff -urNp linux-2.6.26.6/include/asm-powerpc/page.h linux-2.6.26.6/include/asm-powerpc/page.h
29052 +--- linux-2.6.26.6/include/asm-powerpc/page.h 2008-10-08 23:24:05.000000000 -0400
29053 ++++ linux-2.6.26.6/include/asm-powerpc/page.h 2008-10-11 21:54:20.000000000 -0400
29054 +@@ -100,8 +100,9 @@ extern phys_addr_t kernstart_addr;
29055 + * and needs to be executable. This means the whole heap ends
29056 + * up being executable.
29057 + */
29058 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
29059 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29060 ++#define VM_DATA_DEFAULT_FLAGS32 \
29061 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
29062 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29063 +
29064 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
29065 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
29066 +diff -urNp linux-2.6.26.6/include/asm-ppc/mmu_context.h linux-2.6.26.6/include/asm-ppc/mmu_context.h
29067 +--- linux-2.6.26.6/include/asm-ppc/mmu_context.h 2008-10-08 23:24:05.000000000 -0400
29068 ++++ linux-2.6.26.6/include/asm-ppc/mmu_context.h 2008-10-11 21:54:20.000000000 -0400
29069 +@@ -141,7 +141,8 @@ static inline void get_mmu_context(struc
29070 + static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
29071 + {
29072 + mm->context.id = NO_CONTEXT;
29073 +- mm->context.vdso_base = 0;
29074 ++ if (t == current)
29075 ++ mm->context.vdso_base = ~0UL;
29076 + return 0;
29077 + }
29078 +
29079 +diff -urNp linux-2.6.26.6/include/asm-ppc/pgtable.h linux-2.6.26.6/include/asm-ppc/pgtable.h
29080 +--- linux-2.6.26.6/include/asm-ppc/pgtable.h 2008-10-08 23:24:05.000000000 -0400
29081 ++++ linux-2.6.26.6/include/asm-ppc/pgtable.h 2008-10-11 21:54:20.000000000 -0400
29082 +@@ -390,11 +390,21 @@ extern unsigned long ioremap_bot, iorema
29083 +
29084 + #define PAGE_NONE __pgprot(_PAGE_BASE)
29085 + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
29086 +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
29087 ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
29088 + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
29089 +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
29090 ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
29091 + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
29092 +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
29093 ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
29094 ++
29095 ++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
29096 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
29097 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
29098 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
29099 ++#else
29100 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
29101 ++# define PAGE_COPY_NOEXEC PAGE_COPY
29102 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
29103 ++#endif
29104 +
29105 + #define PAGE_KERNEL __pgprot(_PAGE_RAM)
29106 + #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
29107 +@@ -406,21 +416,21 @@ extern unsigned long ioremap_bot, iorema
29108 + * This is the closest we can get..
29109 + */
29110 + #define __P000 PAGE_NONE
29111 +-#define __P001 PAGE_READONLY_X
29112 +-#define __P010 PAGE_COPY
29113 +-#define __P011 PAGE_COPY_X
29114 +-#define __P100 PAGE_READONLY
29115 ++#define __P001 PAGE_READONLY_NOEXEC
29116 ++#define __P010 PAGE_COPY_NOEXEC
29117 ++#define __P011 PAGE_COPY_NOEXEC
29118 ++#define __P100 PAGE_READONLY_X
29119 + #define __P101 PAGE_READONLY_X
29120 +-#define __P110 PAGE_COPY
29121 ++#define __P110 PAGE_COPY_X
29122 + #define __P111 PAGE_COPY_X
29123 +
29124 + #define __S000 PAGE_NONE
29125 +-#define __S001 PAGE_READONLY_X
29126 +-#define __S010 PAGE_SHARED
29127 +-#define __S011 PAGE_SHARED_X
29128 +-#define __S100 PAGE_READONLY
29129 ++#define __S001 PAGE_READONLY_NOEXEC
29130 ++#define __S010 PAGE_SHARED_NOEXEC
29131 ++#define __S011 PAGE_SHARED_NOEXEC
29132 ++#define __S100 PAGE_READONLY_X
29133 + #define __S101 PAGE_READONLY_X
29134 +-#define __S110 PAGE_SHARED
29135 ++#define __S110 PAGE_SHARED_X
29136 + #define __S111 PAGE_SHARED_X
29137 +
29138 + #ifndef __ASSEMBLY__
29139 +diff -urNp linux-2.6.26.6/include/asm-s390/kmap_types.h linux-2.6.26.6/include/asm-s390/kmap_types.h
29140 +--- linux-2.6.26.6/include/asm-s390/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29141 ++++ linux-2.6.26.6/include/asm-s390/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29142 +@@ -16,6 +16,7 @@ enum km_type {
29143 + KM_IRQ1,
29144 + KM_SOFTIRQ0,
29145 + KM_SOFTIRQ1,
29146 ++ KM_CLEARPAGE,
29147 + KM_TYPE_NR
29148 + };
29149 +
29150 +diff -urNp linux-2.6.26.6/include/asm-sh/kmap_types.h linux-2.6.26.6/include/asm-sh/kmap_types.h
29151 +--- linux-2.6.26.6/include/asm-sh/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29152 ++++ linux-2.6.26.6/include/asm-sh/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29153 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
29154 + D(10) KM_IRQ1,
29155 + D(11) KM_SOFTIRQ0,
29156 + D(12) KM_SOFTIRQ1,
29157 +-D(13) KM_TYPE_NR
29158 ++D(13) KM_CLEARPAGE,
29159 ++D(14) KM_TYPE_NR
29160 + };
29161 +
29162 + #undef D
29163 +diff -urNp linux-2.6.26.6/include/asm-sparc/elf.h linux-2.6.26.6/include/asm-sparc/elf.h
29164 +--- linux-2.6.26.6/include/asm-sparc/elf.h 2008-10-08 23:24:05.000000000 -0400
29165 ++++ linux-2.6.26.6/include/asm-sparc/elf.h 2008-10-11 21:54:20.000000000 -0400
29166 +@@ -119,6 +119,13 @@ typedef struct {
29167 +
29168 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
29169 +
29170 ++#ifdef CONFIG_PAX_ASLR
29171 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
29172 ++
29173 ++#define PAX_DELTA_MMAP_LEN 16
29174 ++#define PAX_DELTA_STACK_LEN 16
29175 ++#endif
29176 ++
29177 + /* This yields a mask that user programs can use to figure out what
29178 + instruction set this cpu supports. This can NOT be done in userspace
29179 + on Sparc. */
29180 +diff -urNp linux-2.6.26.6/include/asm-sparc/kmap_types.h linux-2.6.26.6/include/asm-sparc/kmap_types.h
29181 +--- linux-2.6.26.6/include/asm-sparc/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29182 ++++ linux-2.6.26.6/include/asm-sparc/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29183 +@@ -15,6 +15,7 @@ enum km_type {
29184 + KM_IRQ1,
29185 + KM_SOFTIRQ0,
29186 + KM_SOFTIRQ1,
29187 ++ KM_CLEARPAGE,
29188 + KM_TYPE_NR
29189 + };
29190 +
29191 +diff -urNp linux-2.6.26.6/include/asm-sparc/pgtable.h linux-2.6.26.6/include/asm-sparc/pgtable.h
29192 +--- linux-2.6.26.6/include/asm-sparc/pgtable.h 2008-10-08 23:24:05.000000000 -0400
29193 ++++ linux-2.6.26.6/include/asm-sparc/pgtable.h 2008-10-11 21:54:20.000000000 -0400
29194 +@@ -47,6 +47,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
29195 + BTFIXUPDEF_INT(page_none)
29196 + BTFIXUPDEF_INT(page_copy)
29197 + BTFIXUPDEF_INT(page_readonly)
29198 ++
29199 ++#ifdef CONFIG_PAX_PAGEEXEC
29200 ++BTFIXUPDEF_INT(page_shared_noexec)
29201 ++BTFIXUPDEF_INT(page_copy_noexec)
29202 ++BTFIXUPDEF_INT(page_readonly_noexec)
29203 ++#endif
29204 ++
29205 + BTFIXUPDEF_INT(page_kernel)
29206 +
29207 + #define PMD_SHIFT SUN4C_PMD_SHIFT
29208 +@@ -68,6 +75,16 @@ extern pgprot_t PAGE_SHARED;
29209 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
29210 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
29211 +
29212 ++#ifdef CONFIG_PAX_PAGEEXEC
29213 ++extern pgprot_t PAGE_SHARED_NOEXEC;
29214 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
29215 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
29216 ++#else
29217 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
29218 ++# define PAGE_COPY_NOEXEC PAGE_COPY
29219 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
29220 ++#endif
29221 ++
29222 + extern unsigned long page_kernel;
29223 +
29224 + #ifdef MODULE
29225 +diff -urNp linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h
29226 +--- linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h 2008-10-08 23:24:05.000000000 -0400
29227 ++++ linux-2.6.26.6/include/asm-sparc/pgtsrmmu.h 2008-10-11 21:54:20.000000000 -0400
29228 +@@ -115,6 +115,16 @@
29229 + SRMMU_EXEC | SRMMU_REF)
29230 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29231 + SRMMU_EXEC | SRMMU_REF)
29232 ++
29233 ++#ifdef CONFIG_PAX_PAGEEXEC
29234 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29235 ++ SRMMU_WRITE | SRMMU_REF)
29236 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29237 ++ SRMMU_REF)
29238 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
29239 ++ SRMMU_REF)
29240 ++#endif
29241 ++
29242 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
29243 + SRMMU_DIRTY | SRMMU_REF)
29244 +
29245 +diff -urNp linux-2.6.26.6/include/asm-sparc64/elf.h linux-2.6.26.6/include/asm-sparc64/elf.h
29246 +--- linux-2.6.26.6/include/asm-sparc64/elf.h 2008-10-08 23:24:05.000000000 -0400
29247 ++++ linux-2.6.26.6/include/asm-sparc64/elf.h 2008-10-11 21:54:20.000000000 -0400
29248 +@@ -163,6 +163,12 @@ typedef struct {
29249 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
29250 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
29251 +
29252 ++#ifdef CONFIG_PAX_ASLR
29253 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
29254 ++
29255 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
29256 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
29257 ++#endif
29258 +
29259 + /* This yields a mask that user programs can use to figure out what
29260 + instruction set this cpu supports. */
29261 +diff -urNp linux-2.6.26.6/include/asm-sparc64/kmap_types.h linux-2.6.26.6/include/asm-sparc64/kmap_types.h
29262 +--- linux-2.6.26.6/include/asm-sparc64/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29263 ++++ linux-2.6.26.6/include/asm-sparc64/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29264 +@@ -19,6 +19,7 @@ enum km_type {
29265 + KM_IRQ1,
29266 + KM_SOFTIRQ0,
29267 + KM_SOFTIRQ1,
29268 ++ KM_CLEARPAGE,
29269 + KM_TYPE_NR
29270 + };
29271 +
29272 +diff -urNp linux-2.6.26.6/include/asm-um/kmap_types.h linux-2.6.26.6/include/asm-um/kmap_types.h
29273 +--- linux-2.6.26.6/include/asm-um/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29274 ++++ linux-2.6.26.6/include/asm-um/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29275 +@@ -23,6 +23,7 @@ enum km_type {
29276 + KM_IRQ1,
29277 + KM_SOFTIRQ0,
29278 + KM_SOFTIRQ1,
29279 ++ KM_CLEARPAGE,
29280 + KM_TYPE_NR
29281 + };
29282 +
29283 +diff -urNp linux-2.6.26.6/include/asm-um/page.h linux-2.6.26.6/include/asm-um/page.h
29284 +--- linux-2.6.26.6/include/asm-um/page.h 2008-10-08 23:24:05.000000000 -0400
29285 ++++ linux-2.6.26.6/include/asm-um/page.h 2008-10-11 21:55:07.000000000 -0400
29286 +@@ -14,6 +14,9 @@
29287 + #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
29288 + #define PAGE_MASK (~(PAGE_SIZE-1))
29289 +
29290 ++#define ktla_ktva(addr) (addr)
29291 ++#define ktva_ktla(addr) (addr)
29292 ++
29293 + #ifndef __ASSEMBLY__
29294 +
29295 + struct page;
29296 +diff -urNp linux-2.6.26.6/include/asm-v850/kmap_types.h linux-2.6.26.6/include/asm-v850/kmap_types.h
29297 +--- linux-2.6.26.6/include/asm-v850/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
29298 ++++ linux-2.6.26.6/include/asm-v850/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
29299 +@@ -13,6 +13,7 @@ enum km_type {
29300 + KM_PTE1,
29301 + KM_IRQ0,
29302 + KM_IRQ1,
29303 ++ KM_CLEARPAGE,
29304 + KM_TYPE_NR
29305 + };
29306 +
29307 +diff -urNp linux-2.6.26.6/include/asm-x86/alternative.h linux-2.6.26.6/include/asm-x86/alternative.h
29308 +--- linux-2.6.26.6/include/asm-x86/alternative.h 2008-10-08 23:24:05.000000000 -0400
29309 ++++ linux-2.6.26.6/include/asm-x86/alternative.h 2008-10-11 21:54:20.000000000 -0400
29310 +@@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
29311 + " .byte 662b-661b\n" /* sourcelen */ \
29312 + " .byte 664f-663f\n" /* replacementlen */ \
29313 + ".previous\n" \
29314 +- ".section .altinstr_replacement,\"ax\"\n" \
29315 ++ ".section .altinstr_replacement,\"a\"\n" \
29316 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
29317 + ".previous" :: "i" (feature) : "memory")
29318 +
29319 +@@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
29320 + " .byte 662b-661b\n" /* sourcelen */ \
29321 + " .byte 664f-663f\n" /* replacementlen */ \
29322 + ".previous\n" \
29323 +- ".section .altinstr_replacement,\"ax\"\n" \
29324 ++ ".section .altinstr_replacement,\"a\"\n" \
29325 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
29326 + ".previous" :: "i" (feature), ##input)
29327 +
29328 +@@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
29329 + " .byte 662b-661b\n" /* sourcelen */ \
29330 + " .byte 664f-663f\n" /* replacementlen */ \
29331 + ".previous\n" \
29332 +- ".section .altinstr_replacement,\"ax\"\n" \
29333 ++ ".section .altinstr_replacement,\"a\"\n" \
29334 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
29335 + ".previous" : output : [feat] "i" (feature), ##input)
29336 +
29337 +diff -urNp linux-2.6.26.6/include/asm-x86/apic.h linux-2.6.26.6/include/asm-x86/apic.h
29338 +--- linux-2.6.26.6/include/asm-x86/apic.h 2008-10-08 23:24:05.000000000 -0400
29339 ++++ linux-2.6.26.6/include/asm-x86/apic.h 2008-10-11 21:54:20.000000000 -0400
29340 +@@ -10,7 +10,7 @@
29341 +
29342 + #define ARCH_APICTIMER_STOPS_ON_C3 1
29343 +
29344 +-#define Dprintk(x...)
29345 ++#define Dprintk(x...) do {} while (0)
29346 +
29347 + /*
29348 + * Debugging macros
29349 +diff -urNp linux-2.6.26.6/include/asm-x86/atomic_32.h linux-2.6.26.6/include/asm-x86/atomic_32.h
29350 +--- linux-2.6.26.6/include/asm-x86/atomic_32.h 2008-10-08 23:24:05.000000000 -0400
29351 ++++ linux-2.6.26.6/include/asm-x86/atomic_32.h 2008-10-11 21:54:20.000000000 -0400
29352 +@@ -47,7 +47,15 @@ typedef struct {
29353 + */
29354 + static inline void atomic_add(int i, atomic_t *v)
29355 + {
29356 +- asm volatile(LOCK_PREFIX "addl %1,%0"
29357 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
29358 ++
29359 ++#ifdef CONFIG_PAX_REFCOUNT
29360 ++ "jno 0f\n"
29361 ++ LOCK_PREFIX "subl %1,%0\n"
29362 ++ "into\n0:\n"
29363 ++ _ASM_EXTABLE(0b, 0b)
29364 ++#endif
29365 ++
29366 + : "+m" (v->counter)
29367 + : "ir" (i));
29368 + }
29369 +@@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
29370 + */
29371 + static inline void atomic_sub(int i, atomic_t *v)
29372 + {
29373 +- asm volatile(LOCK_PREFIX "subl %1,%0"
29374 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
29375 ++
29376 ++#ifdef CONFIG_PAX_REFCOUNT
29377 ++ "jno 0f\n"
29378 ++ LOCK_PREFIX "addl %1,%0\n"
29379 ++ "into\n0:\n"
29380 ++ _ASM_EXTABLE(0b, 0b)
29381 ++#endif
29382 ++
29383 + : "+m" (v->counter)
29384 + : "ir" (i));
29385 + }
29386 +@@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
29387 + {
29388 + unsigned char c;
29389 +
29390 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
29391 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
29392 ++
29393 ++#ifdef CONFIG_PAX_REFCOUNT
29394 ++ "jno 0f\n"
29395 ++ LOCK_PREFIX "addl %2,%0\n"
29396 ++ "into\n0:\n"
29397 ++ _ASM_EXTABLE(0b, 0b)
29398 ++#endif
29399 ++
29400 ++ "sete %1\n"
29401 + : "+m" (v->counter), "=qm" (c)
29402 + : "ir" (i) : "memory");
29403 + return c;
29404 +@@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
29405 + */
29406 + static inline void atomic_inc(atomic_t *v)
29407 + {
29408 +- asm volatile(LOCK_PREFIX "incl %0"
29409 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29410 ++
29411 ++#ifdef CONFIG_PAX_REFCOUNT
29412 ++ "into\n0:\n"
29413 ++ ".pushsection .fixup,\"ax\"\n"
29414 ++ "1:\n"
29415 ++ LOCK_PREFIX "decl %0\n"
29416 ++ "jmp 0b\n"
29417 ++ ".popsection\n"
29418 ++ _ASM_EXTABLE(0b, 1b)
29419 ++#endif
29420 ++
29421 + : "+m" (v->counter));
29422 + }
29423 +
29424 +@@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
29425 + */
29426 + static inline void atomic_dec(atomic_t *v)
29427 + {
29428 +- asm volatile(LOCK_PREFIX "decl %0"
29429 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29430 ++
29431 ++#ifdef CONFIG_PAX_REFCOUNT
29432 ++ "into\n0:\n"
29433 ++ ".pushsection .fixup,\"ax\"\n"
29434 ++ "1: \n"
29435 ++ LOCK_PREFIX "incl %0\n"
29436 ++ "jmp 0b\n"
29437 ++ ".popsection\n"
29438 ++ _ASM_EXTABLE(0b, 1b)
29439 ++#endif
29440 ++
29441 + : "+m" (v->counter));
29442 + }
29443 +
29444 +@@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
29445 + {
29446 + unsigned char c;
29447 +
29448 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
29449 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29450 ++
29451 ++#ifdef CONFIG_PAX_REFCOUNT
29452 ++ "into\n0:\n"
29453 ++ ".pushsection .fixup,\"ax\"\n"
29454 ++ "1: \n"
29455 ++ LOCK_PREFIX "incl %0\n"
29456 ++ "jmp 0b\n"
29457 ++ ".popsection\n"
29458 ++ _ASM_EXTABLE(0b, 1b)
29459 ++#endif
29460 ++
29461 ++ "sete %1\n"
29462 + : "+m" (v->counter), "=qm" (c)
29463 + : : "memory");
29464 + return c != 0;
29465 +@@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
29466 + {
29467 + unsigned char c;
29468 +
29469 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
29470 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29471 ++
29472 ++#ifdef CONFIG_PAX_REFCOUNT
29473 ++ "into\n0:\n"
29474 ++ ".pushsection .fixup,\"ax\"\n"
29475 ++ "1: \n"
29476 ++ LOCK_PREFIX "decl %0\n"
29477 ++ "jmp 0b\n"
29478 ++ ".popsection\n"
29479 ++ _ASM_EXTABLE(0b, 1b)
29480 ++#endif
29481 ++
29482 ++ "sete %1\n"
29483 + : "+m" (v->counter), "=qm" (c)
29484 + : : "memory");
29485 + return c != 0;
29486 +@@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
29487 + {
29488 + unsigned char c;
29489 +
29490 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
29491 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
29492 ++
29493 ++#ifdef CONFIG_PAX_REFCOUNT
29494 ++ "jno 0f\n"
29495 ++ LOCK_PREFIX "subl %2,%0\n"
29496 ++ "into\n0:\n"
29497 ++ _ASM_EXTABLE(0b, 0b)
29498 ++#endif
29499 ++
29500 ++ "sets %1\n"
29501 + : "+m" (v->counter), "=qm" (c)
29502 + : "ir" (i) : "memory");
29503 + return c;
29504 +@@ -181,7 +261,15 @@ static inline int atomic_add_return(int
29505 + #endif
29506 + /* Modern 486+ processor */
29507 + __i = i;
29508 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
29509 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
29510 ++
29511 ++#ifdef CONFIG_PAX_REFCOUNT
29512 ++ "jno 0f\n"
29513 ++ "movl %0, %1\n"
29514 ++ "into\n0:\n"
29515 ++ _ASM_EXTABLE(0b, 0b)
29516 ++#endif
29517 ++
29518 + : "+r" (i), "+m" (v->counter)
29519 + : : "memory");
29520 + return i + __i;
29521 +diff -urNp linux-2.6.26.6/include/asm-x86/atomic_64.h linux-2.6.26.6/include/asm-x86/atomic_64.h
29522 +--- linux-2.6.26.6/include/asm-x86/atomic_64.h 2008-10-08 23:24:05.000000000 -0400
29523 ++++ linux-2.6.26.6/include/asm-x86/atomic_64.h 2008-10-11 21:54:20.000000000 -0400
29524 +@@ -54,7 +54,15 @@ typedef struct {
29525 + */
29526 + static inline void atomic_add(int i, atomic_t *v)
29527 + {
29528 +- asm volatile(LOCK_PREFIX "addl %1,%0"
29529 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
29530 ++
29531 ++#ifdef CONFIG_PAX_REFCOUNT
29532 ++ "jno 0f\n"
29533 ++ LOCK_PREFIX "subl %1,%0\n"
29534 ++ "int $4\n0:\n"
29535 ++ _ASM_EXTABLE(0b, 0b)
29536 ++#endif
29537 ++
29538 + : "=m" (v->counter)
29539 + : "ir" (i), "m" (v->counter));
29540 + }
29541 +@@ -68,7 +76,15 @@ static inline void atomic_add(int i, ato
29542 + */
29543 + static inline void atomic_sub(int i, atomic_t *v)
29544 + {
29545 +- asm volatile(LOCK_PREFIX "subl %1,%0"
29546 ++ asm volatile(LOCK_PREFIX "subl %1,%0\n"
29547 ++
29548 ++#ifdef CONFIG_PAX_REFCOUNT
29549 ++ "jno 0f\n"
29550 ++ LOCK_PREFIX "addl %1,%0\n"
29551 ++ "int $4\n0:\n"
29552 ++ _ASM_EXTABLE(0b, 0b)
29553 ++#endif
29554 ++
29555 + : "=m" (v->counter)
29556 + : "ir" (i), "m" (v->counter));
29557 + }
29558 +@@ -86,7 +102,16 @@ static inline int atomic_sub_and_test(in
29559 + {
29560 + unsigned char c;
29561 +
29562 +- asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
29563 ++ asm volatile(LOCK_PREFIX "subl %2,%0\n"
29564 ++
29565 ++#ifdef CONFIG_PAX_REFCOUNT
29566 ++ "jno 0f\n"
29567 ++ LOCK_PREFIX "addl %2,%0\n"
29568 ++ "int $4\n0:\n"
29569 ++ _ASM_EXTABLE(0b, 0b)
29570 ++#endif
29571 ++
29572 ++ "sete %1\n"
29573 + : "=m" (v->counter), "=qm" (c)
29574 + : "ir" (i), "m" (v->counter) : "memory");
29575 + return c;
29576 +@@ -100,7 +125,19 @@ static inline int atomic_sub_and_test(in
29577 + */
29578 + static inline void atomic_inc(atomic_t *v)
29579 + {
29580 +- asm volatile(LOCK_PREFIX "incl %0"
29581 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29582 ++
29583 ++#ifdef CONFIG_PAX_REFCOUNT
29584 ++ "jno 0f\n"
29585 ++ "int $4\n0:\n"
29586 ++ ".pushsection .fixup,\"ax\"\n"
29587 ++ "1:\n"
29588 ++ LOCK_PREFIX "decl %0\n"
29589 ++ "jmp 0b\n"
29590 ++ ".popsection\n"
29591 ++ _ASM_EXTABLE(0b, 1b)
29592 ++#endif
29593 ++
29594 + : "=m" (v->counter)
29595 + : "m" (v->counter));
29596 + }
29597 +@@ -113,7 +150,19 @@ static inline void atomic_inc(atomic_t *
29598 + */
29599 + static inline void atomic_dec(atomic_t *v)
29600 + {
29601 +- asm volatile(LOCK_PREFIX "decl %0"
29602 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29603 ++
29604 ++#ifdef CONFIG_PAX_REFCOUNT
29605 ++ "jno 0f\n"
29606 ++ "int $4\n0:\n"
29607 ++ ".pushsection .fixup,\"ax\"\n"
29608 ++ "1: \n"
29609 ++ LOCK_PREFIX "incl %0\n"
29610 ++ "jmp 0b\n"
29611 ++ ".popsection\n"
29612 ++ _ASM_EXTABLE(0b, 1b)
29613 ++#endif
29614 ++
29615 + : "=m" (v->counter)
29616 + : "m" (v->counter));
29617 + }
29618 +@@ -130,7 +179,20 @@ static inline int atomic_dec_and_test(at
29619 + {
29620 + unsigned char c;
29621 +
29622 +- asm volatile(LOCK_PREFIX "decl %0; sete %1"
29623 ++ asm volatile(LOCK_PREFIX "decl %0\n"
29624 ++
29625 ++#ifdef CONFIG_PAX_REFCOUNT
29626 ++ "jno 0f\n"
29627 ++ "int $4\n0:\n"
29628 ++ ".pushsection .fixup,\"ax\"\n"
29629 ++ "1: \n"
29630 ++ LOCK_PREFIX "incl %0\n"
29631 ++ "jmp 0b\n"
29632 ++ ".popsection\n"
29633 ++ _ASM_EXTABLE(0b, 1b)
29634 ++#endif
29635 ++
29636 ++ "sete %1\n"
29637 + : "=m" (v->counter), "=qm" (c)
29638 + : "m" (v->counter) : "memory");
29639 + return c != 0;
29640 +@@ -148,7 +210,20 @@ static inline int atomic_inc_and_test(at
29641 + {
29642 + unsigned char c;
29643 +
29644 +- asm volatile(LOCK_PREFIX "incl %0; sete %1"
29645 ++ asm volatile(LOCK_PREFIX "incl %0\n"
29646 ++
29647 ++#ifdef CONFIG_PAX_REFCOUNT
29648 ++ "jno 0f\n"
29649 ++ "int $4\n0:\n"
29650 ++ ".pushsection .fixup,\"ax\"\n"
29651 ++ "1: \n"
29652 ++ LOCK_PREFIX "decl %0\n"
29653 ++ "jmp 0b\n"
29654 ++ ".popsection\n"
29655 ++ _ASM_EXTABLE(0b, 1b)
29656 ++#endif
29657 ++
29658 ++ "sete %1\n"
29659 + : "=m" (v->counter), "=qm" (c)
29660 + : "m" (v->counter) : "memory");
29661 + return c != 0;
29662 +@@ -167,7 +242,16 @@ static inline int atomic_add_negative(in
29663 + {
29664 + unsigned char c;
29665 +
29666 +- asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
29667 ++ asm volatile(LOCK_PREFIX "addl %2,%0\n"
29668 ++
29669 ++#ifdef CONFIG_PAX_REFCOUNT
29670 ++ "jno 0f\n"
29671 ++ LOCK_PREFIX "subl %2,%0\n"
29672 ++ "int $4\n0:\n"
29673 ++ _ASM_EXTABLE(0b, 0b)
29674 ++#endif
29675 ++
29676 ++ "sets %1\n"
29677 + : "=m" (v->counter), "=qm" (c)
29678 + : "ir" (i), "m" (v->counter) : "memory");
29679 + return c;
29680 +@@ -183,7 +267,15 @@ static inline int atomic_add_negative(in
29681 + static inline int atomic_add_return(int i, atomic_t *v)
29682 + {
29683 + int __i = i;
29684 +- asm volatile(LOCK_PREFIX "xaddl %0, %1"
29685 ++ asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
29686 ++
29687 ++#ifdef CONFIG_PAX_REFCOUNT
29688 ++ "jno 0f\n"
29689 ++ "movl %0, %1\n"
29690 ++ "int $4\n0:\n"
29691 ++ _ASM_EXTABLE(0b, 0b)
29692 ++#endif
29693 ++
29694 + : "+r" (i), "+m" (v->counter)
29695 + : : "memory");
29696 + return i + __i;
29697 +@@ -232,7 +324,15 @@ typedef struct {
29698 + */
29699 + static inline void atomic64_add(long i, atomic64_t *v)
29700 + {
29701 +- asm volatile(LOCK_PREFIX "addq %1,%0"
29702 ++ asm volatile(LOCK_PREFIX "addq %1,%0\n"
29703 ++
29704 ++#ifdef CONFIG_PAX_REFCOUNT
29705 ++ "jno 0f\n"
29706 ++ LOCK_PREFIX "subq %1,%0\n"
29707 ++ "int $4\n0:\n"
29708 ++ _ASM_EXTABLE(0b, 0b)
29709 ++#endif
29710 ++
29711 + : "=m" (v->counter)
29712 + : "ir" (i), "m" (v->counter));
29713 + }
29714 +@@ -246,7 +346,15 @@ static inline void atomic64_add(long i,
29715 + */
29716 + static inline void atomic64_sub(long i, atomic64_t *v)
29717 + {
29718 +- asm volatile(LOCK_PREFIX "subq %1,%0"
29719 ++ asm volatile(LOCK_PREFIX "subq %1,%0\n"
29720 ++
29721 ++#ifdef CONFIG_PAX_REFCOUNT
29722 ++ "jno 0f\n"
29723 ++ LOCK_PREFIX "addq %1,%0\n"
29724 ++ "int $4\n0:\n"
29725 ++ _ASM_EXTABLE(0b, 0b)
29726 ++#endif
29727 ++
29728 + : "=m" (v->counter)
29729 + : "ir" (i), "m" (v->counter));
29730 + }
29731 +@@ -264,7 +372,16 @@ static inline int atomic64_sub_and_test(
29732 + {
29733 + unsigned char c;
29734 +
29735 +- asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
29736 ++ asm volatile(LOCK_PREFIX "subq %2,%0\n"
29737 ++
29738 ++#ifdef CONFIG_PAX_REFCOUNT
29739 ++ "jno 0f\n"
29740 ++ LOCK_PREFIX "addq %2,%0\n"
29741 ++ "int $4\n0:\n"
29742 ++ _ASM_EXTABLE(0b, 0b)
29743 ++#endif
29744 ++
29745 ++ "sete %1\n"
29746 + : "=m" (v->counter), "=qm" (c)
29747 + : "ir" (i), "m" (v->counter) : "memory");
29748 + return c;
29749 +@@ -278,7 +395,19 @@ static inline int atomic64_sub_and_test(
29750 + */
29751 + static inline void atomic64_inc(atomic64_t *v)
29752 + {
29753 +- asm volatile(LOCK_PREFIX "incq %0"
29754 ++ asm volatile(LOCK_PREFIX "incq %0\n"
29755 ++
29756 ++#ifdef CONFIG_PAX_REFCOUNT
29757 ++ "jno 0f\n"
29758 ++ "int $4\n0:\n"
29759 ++ ".pushsection .fixup,\"ax\"\n"
29760 ++ "1:\n"
29761 ++ LOCK_PREFIX "decq %0\n"
29762 ++ "jmp 0b\n"
29763 ++ ".popsection\n"
29764 ++ _ASM_EXTABLE(0b, 1b)
29765 ++#endif
29766 ++
29767 + : "=m" (v->counter)
29768 + : "m" (v->counter));
29769 + }
29770 +@@ -291,7 +420,19 @@ static inline void atomic64_inc(atomic64
29771 + */
29772 + static inline void atomic64_dec(atomic64_t *v)
29773 + {
29774 +- asm volatile(LOCK_PREFIX "decq %0"
29775 ++ asm volatile(LOCK_PREFIX "decq %0\n"
29776 ++
29777 ++#ifdef CONFIG_PAX_REFCOUNT
29778 ++ "jno 0f\n"
29779 ++ "int $4\n0:\n"
29780 ++ ".pushsection .fixup,\"ax\"\n"
29781 ++ "1: \n"
29782 ++ LOCK_PREFIX "incq %0\n"
29783 ++ "jmp 0b\n"
29784 ++ ".popsection\n"
29785 ++ _ASM_EXTABLE(0b, 1b)
29786 ++#endif
29787 ++
29788 + : "=m" (v->counter)
29789 + : "m" (v->counter));
29790 + }
29791 +@@ -308,7 +449,20 @@ static inline int atomic64_dec_and_test(
29792 + {
29793 + unsigned char c;
29794 +
29795 +- asm volatile(LOCK_PREFIX "decq %0; sete %1"
29796 ++ asm volatile(LOCK_PREFIX "decq %0\n"
29797 ++
29798 ++#ifdef CONFIG_PAX_REFCOUNT
29799 ++ "jno 0f\n"
29800 ++ "int $4\n0:\n"
29801 ++ ".pushsection .fixup,\"ax\"\n"
29802 ++ "1: \n"
29803 ++ LOCK_PREFIX "incq %0\n"
29804 ++ "jmp 0b\n"
29805 ++ ".popsection\n"
29806 ++ _ASM_EXTABLE(0b, 1b)
29807 ++#endif
29808 ++
29809 ++ "sete %1\n"
29810 + : "=m" (v->counter), "=qm" (c)
29811 + : "m" (v->counter) : "memory");
29812 + return c != 0;
29813 +@@ -326,7 +480,20 @@ static inline int atomic64_inc_and_test(
29814 + {
29815 + unsigned char c;
29816 +
29817 +- asm volatile(LOCK_PREFIX "incq %0; sete %1"
29818 ++ asm volatile(LOCK_PREFIX "incq %0\n"
29819 ++
29820 ++#ifdef CONFIG_PAX_REFCOUNT
29821 ++ "jno 0f\n"
29822 ++ "int $4\n0:\n"
29823 ++ ".pushsection .fixup,\"ax\"\n"
29824 ++ "1: \n"
29825 ++ LOCK_PREFIX "decq %0\n"
29826 ++ "jmp 0b\n"
29827 ++ ".popsection\n"
29828 ++ _ASM_EXTABLE(0b, 1b)
29829 ++#endif
29830 ++
29831 ++ "sete %1\n"
29832 + : "=m" (v->counter), "=qm" (c)
29833 + : "m" (v->counter) : "memory");
29834 + return c != 0;
29835 +@@ -345,7 +512,16 @@ static inline int atomic64_add_negative(
29836 + {
29837 + unsigned char c;
29838 +
29839 +- asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
29840 ++ asm volatile(LOCK_PREFIX "addq %2,%0\n"
29841 ++
29842 ++#ifdef CONFIG_PAX_REFCOUNT
29843 ++ "jno 0f\n"
29844 ++ LOCK_PREFIX "subq %2,%0\n"
29845 ++ "int $4\n0:\n"
29846 ++ _ASM_EXTABLE(0b, 0b)
29847 ++#endif
29848 ++
29849 ++ "sets %1\n"
29850 + : "=m" (v->counter), "=qm" (c)
29851 + : "ir" (i), "m" (v->counter) : "memory");
29852 + return c;
29853 +@@ -361,7 +537,15 @@ static inline int atomic64_add_negative(
29854 + static inline long atomic64_add_return(long i, atomic64_t *v)
29855 + {
29856 + long __i = i;
29857 +- asm volatile(LOCK_PREFIX "xaddq %0, %1;"
29858 ++ asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
29859 ++
29860 ++#ifdef CONFIG_PAX_REFCOUNT
29861 ++ "jno 0f\n"
29862 ++ "movq %0, %1\n"
29863 ++ "int $4\n0:\n"
29864 ++ _ASM_EXTABLE(0b, 0b)
29865 ++#endif
29866 ++
29867 + : "+r" (i), "+m" (v->counter)
29868 + : : "memory");
29869 + return i + __i;
29870 +diff -urNp linux-2.6.26.6/include/asm-x86/boot.h linux-2.6.26.6/include/asm-x86/boot.h
29871 +--- linux-2.6.26.6/include/asm-x86/boot.h 2008-10-08 23:24:05.000000000 -0400
29872 ++++ linux-2.6.26.6/include/asm-x86/boot.h 2008-10-11 21:54:20.000000000 -0400
29873 +@@ -13,10 +13,15 @@
29874 + #define ASK_VGA 0xfffd /* ask for it at bootup */
29875 +
29876 + /* Physical address where kernel should be loaded. */
29877 +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
29878 ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
29879 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
29880 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
29881 +
29882 ++#ifndef __ASSEMBLY__
29883 ++extern unsigned char __LOAD_PHYSICAL_ADDR[];
29884 ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
29885 ++#endif
29886 ++
29887 + #ifdef CONFIG_X86_64
29888 + #define BOOT_HEAP_SIZE 0x7000
29889 + #define BOOT_STACK_SIZE 0x4000
29890 +diff -urNp linux-2.6.26.6/include/asm-x86/cache.h linux-2.6.26.6/include/asm-x86/cache.h
29891 +--- linux-2.6.26.6/include/asm-x86/cache.h 2008-10-08 23:24:05.000000000 -0400
29892 ++++ linux-2.6.26.6/include/asm-x86/cache.h 2008-10-11 21:54:20.000000000 -0400
29893 +@@ -6,6 +6,7 @@
29894 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
29895 +
29896 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
29897 ++#define __read_only __attribute__((__section__(".data.read_only")))
29898 +
29899 + #ifdef CONFIG_X86_VSMP
29900 + /* vSMP Internode cacheline shift */
29901 +diff -urNp linux-2.6.26.6/include/asm-x86/checksum_32.h linux-2.6.26.6/include/asm-x86/checksum_32.h
29902 +--- linux-2.6.26.6/include/asm-x86/checksum_32.h 2008-10-08 23:24:05.000000000 -0400
29903 ++++ linux-2.6.26.6/include/asm-x86/checksum_32.h 2008-10-11 21:54:20.000000000 -0400
29904 +@@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
29905 + int len, __wsum sum,
29906 + int *src_err_ptr, int *dst_err_ptr);
29907 +
29908 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
29909 ++ int len, __wsum sum,
29910 ++ int *src_err_ptr, int *dst_err_ptr);
29911 ++
29912 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
29913 ++ int len, __wsum sum,
29914 ++ int *src_err_ptr, int *dst_err_ptr);
29915 ++
29916 + /*
29917 + * Note: when you get a NULL pointer exception here this means someone
29918 + * passed in an incorrect kernel address to one of these functions.
29919 +@@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
29920 + int *err_ptr)
29921 + {
29922 + might_sleep();
29923 +- return csum_partial_copy_generic((__force void *)src, dst,
29924 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
29925 + len, sum, err_ptr, NULL);
29926 + }
29927 +
29928 +@@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
29929 + {
29930 + might_sleep();
29931 + if (access_ok(VERIFY_WRITE, dst, len))
29932 +- return csum_partial_copy_generic(src, (__force void *)dst,
29933 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst,
29934 + len, sum, NULL, err_ptr);
29935 +
29936 + if (len)
29937 +diff -urNp linux-2.6.26.6/include/asm-x86/desc.h linux-2.6.26.6/include/asm-x86/desc.h
29938 +--- linux-2.6.26.6/include/asm-x86/desc.h 2008-10-08 23:24:05.000000000 -0400
29939 ++++ linux-2.6.26.6/include/asm-x86/desc.h 2008-10-11 21:54:20.000000000 -0400
29940 +@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
29941 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
29942 + desc->type = (info->read_exec_only ^ 1) << 1;
29943 + desc->type |= info->contents << 2;
29944 ++ desc->type |= info->seg_not_present ^ 1;
29945 + desc->s = 1;
29946 + desc->dpl = 0x3;
29947 + desc->p = info->seg_not_present ^ 1;
29948 +@@ -27,14 +28,15 @@ static inline void fill_ldt(struct desc_
29949 + }
29950 +
29951 + extern struct desc_ptr idt_descr;
29952 +-extern gate_desc idt_table[];
29953 ++extern gate_desc idt_table[256];
29954 +
29955 +-#ifdef CONFIG_X86_64
29956 +-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
29957 +-extern struct desc_ptr cpu_gdt_descr[];
29958 +-/* the cpu gdt accessor */
29959 +-#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
29960 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
29961 ++static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
29962 ++{
29963 ++ return cpu_gdt_table[cpu];
29964 ++}
29965 +
29966 ++#ifdef CONFIG_X86_64
29967 + static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
29968 + unsigned dpl, unsigned ist, unsigned seg)
29969 + {
29970 +@@ -51,16 +53,6 @@ static inline void pack_gate(gate_desc *
29971 + }
29972 +
29973 + #else
29974 +-struct gdt_page {
29975 +- struct desc_struct gdt[GDT_ENTRIES];
29976 +-} __attribute__((aligned(PAGE_SIZE)));
29977 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
29978 +-
29979 +-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
29980 +-{
29981 +- return per_cpu(gdt_page, cpu).gdt;
29982 +-}
29983 +-
29984 + static inline void pack_gate(gate_desc *gate, unsigned char type,
29985 + unsigned long base, unsigned dpl, unsigned flags,
29986 + unsigned short seg)
29987 +@@ -69,7 +61,6 @@ static inline void pack_gate(gate_desc *
29988 + gate->b = (base & 0xffff0000) |
29989 + (((0x80 | type | (dpl << 5)) & 0xff) << 8);
29990 + }
29991 +-
29992 + #endif
29993 +
29994 + static inline int desc_empty(const void *ptr)
29995 +@@ -106,19 +97,48 @@ static inline int desc_empty(const void
29996 + static inline void native_write_idt_entry(gate_desc *idt, int entry,
29997 + const gate_desc *gate)
29998 + {
29999 ++
30000 ++#ifdef CONFIG_PAX_KERNEXEC
30001 ++ unsigned long cr0;
30002 ++
30003 ++ pax_open_kernel(cr0);
30004 ++#endif
30005 ++
30006 + memcpy(&idt[entry], gate, sizeof(*gate));
30007 ++
30008 ++#ifdef CONFIG_PAX_KERNEXEC
30009 ++ pax_close_kernel(cr0);
30010 ++#endif
30011 ++
30012 + }
30013 +
30014 + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
30015 + const void *desc)
30016 + {
30017 ++
30018 ++#ifdef CONFIG_PAX_KERNEXEC
30019 ++ unsigned long cr0;
30020 ++
30021 ++ pax_open_kernel(cr0);
30022 ++#endif
30023 ++
30024 + memcpy(&ldt[entry], desc, 8);
30025 ++
30026 ++#ifdef CONFIG_PAX_KERNEXEC
30027 ++ pax_close_kernel(cr0);
30028 ++#endif
30029 ++
30030 + }
30031 +
30032 + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
30033 + const void *desc, int type)
30034 + {
30035 + unsigned int size;
30036 ++
30037 ++#ifdef CONFIG_PAX_KERNEXEC
30038 ++ unsigned long cr0;
30039 ++#endif
30040 ++
30041 + switch (type) {
30042 + case DESC_TSS:
30043 + size = sizeof(tss_desc);
30044 +@@ -130,7 +150,17 @@ static inline void native_write_gdt_entr
30045 + size = sizeof(struct desc_struct);
30046 + break;
30047 + }
30048 ++
30049 ++#ifdef CONFIG_PAX_KERNEXEC
30050 ++ pax_open_kernel(cr0);
30051 ++#endif
30052 ++
30053 + memcpy(&gdt[entry], desc, size);
30054 ++
30055 ++#ifdef CONFIG_PAX_KERNEXEC
30056 ++ pax_close_kernel(cr0);
30057 ++#endif
30058 ++
30059 + }
30060 +
30061 + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
30062 +@@ -202,7 +232,19 @@ static inline void native_set_ldt(const
30063 +
30064 + static inline void native_load_tr_desc(void)
30065 + {
30066 ++
30067 ++#ifdef CONFIG_PAX_KERNEXEC
30068 ++ unsigned long cr0;
30069 ++
30070 ++ pax_open_kernel(cr0);
30071 ++#endif
30072 ++
30073 + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
30074 ++
30075 ++#ifdef CONFIG_PAX_KERNEXEC
30076 ++ pax_close_kernel(cr0);
30077 ++#endif
30078 ++
30079 + }
30080 +
30081 + static inline void native_load_gdt(const struct desc_ptr *dtr)
30082 +@@ -237,8 +279,19 @@ static inline void native_load_tls(struc
30083 + unsigned int i;
30084 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
30085 +
30086 ++#ifdef CONFIG_PAX_KERNEXEC
30087 ++ unsigned long cr0;
30088 ++
30089 ++ pax_open_kernel(cr0);
30090 ++#endif
30091 ++
30092 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
30093 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
30094 ++
30095 ++#ifdef CONFIG_PAX_KERNEXEC
30096 ++ pax_close_kernel(cr0);
30097 ++#endif
30098 ++
30099 + }
30100 +
30101 + #define _LDT_empty(info) \
30102 +@@ -354,6 +407,18 @@ static inline void set_system_gate_ist(i
30103 + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
30104 + }
30105 +
30106 ++#ifdef CONFIG_X86_32
30107 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
30108 ++{
30109 ++ struct desc_struct d;
30110 ++
30111 ++ if (likely(limit))
30112 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
30113 ++ pack_descriptor(&d, base, limit, 0xFB, 0xC);
30114 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
30115 ++}
30116 ++#endif
30117 ++
30118 + #else
30119 + /*
30120 + * GET_DESC_BASE reads the descriptor base of the specified segment.
30121 +diff -urNp linux-2.6.26.6/include/asm-x86/e820.h linux-2.6.26.6/include/asm-x86/e820.h
30122 +--- linux-2.6.26.6/include/asm-x86/e820.h 2008-10-08 23:24:05.000000000 -0400
30123 ++++ linux-2.6.26.6/include/asm-x86/e820.h 2008-10-11 21:54:20.000000000 -0400
30124 +@@ -25,7 +25,7 @@ struct e820map {
30125 + #define ISA_START_ADDRESS 0xa0000
30126 + #define ISA_END_ADDRESS 0x100000
30127 +
30128 +-#define BIOS_BEGIN 0x000a0000
30129 ++#define BIOS_BEGIN 0x000c0000
30130 + #define BIOS_END 0x00100000
30131 +
30132 + #ifdef __KERNEL__
30133 +diff -urNp linux-2.6.26.6/include/asm-x86/elf.h linux-2.6.26.6/include/asm-x86/elf.h
30134 +--- linux-2.6.26.6/include/asm-x86/elf.h 2008-10-08 23:24:05.000000000 -0400
30135 ++++ linux-2.6.26.6/include/asm-x86/elf.h 2008-10-11 21:54:20.000000000 -0400
30136 +@@ -251,7 +251,25 @@ extern int force_personality32;
30137 + the loader. We need to make sure that it is out of the way of the program
30138 + that it will "exec", and that there is sufficient room for the brk. */
30139 +
30140 ++#ifdef CONFIG_PAX_SEGMEXEC
30141 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
30142 ++#else
30143 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
30144 ++#endif
30145 ++
30146 ++#ifdef CONFIG_PAX_ASLR
30147 ++#ifdef CONFIG_X86_32
30148 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
30149 ++
30150 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
30151 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
30152 ++#else
30153 ++#define PAX_ELF_ET_DYN_BASE 0x400000UL
30154 ++
30155 ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
30156 ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
30157 ++#endif
30158 ++#endif
30159 +
30160 + /* This yields a mask that user programs can use to figure out what
30161 + instruction set this CPU supports. This could be done in user space,
30162 +@@ -303,8 +321,7 @@ do { \
30163 + #define ARCH_DLINFO \
30164 + do { \
30165 + if (vdso_enabled) \
30166 +- NEW_AUX_ENT(AT_SYSINFO_EHDR, \
30167 +- (unsigned long)current->mm->context.vdso); \
30168 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
30169 + } while (0)
30170 +
30171 + #define AT_SYSINFO 32
30172 +@@ -315,7 +332,7 @@ do { \
30173 +
30174 + #endif /* !CONFIG_X86_32 */
30175 +
30176 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
30177 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
30178 +
30179 + #define VDSO_ENTRY \
30180 + ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
30181 +@@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
30182 + extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
30183 + #define compat_arch_setup_additional_pages syscall32_setup_pages
30184 +
30185 +-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
30186 +-#define arch_randomize_brk arch_randomize_brk
30187 +-
30188 + #endif
30189 +diff -urNp linux-2.6.26.6/include/asm-x86/futex.h linux-2.6.26.6/include/asm-x86/futex.h
30190 +--- linux-2.6.26.6/include/asm-x86/futex.h 2008-10-08 23:24:05.000000000 -0400
30191 ++++ linux-2.6.26.6/include/asm-x86/futex.h 2008-10-11 21:55:52.000000000 -0400
30192 +@@ -11,6 +11,40 @@
30193 + #include <asm/processor.h>
30194 + #include <asm/system.h>
30195 +
30196 ++#ifdef CONFIG_X86_32
30197 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
30198 ++ asm volatile( \
30199 ++ "movw\t%w6, %%ds\n" \
30200 ++ "1:\t" insn "\n" \
30201 ++ "2:\tpushl\t%%ss\n" \
30202 ++ "\tpopl\t%%ds\n" \
30203 ++ "\t.section .fixup,\"ax\"\n" \
30204 ++ "3:\tmov\t%3, %1\n" \
30205 ++ "\tjmp\t2b\n" \
30206 ++ "\t.previous\n" \
30207 ++ _ASM_EXTABLE(1b, 3b) \
30208 ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
30209 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
30210 ++
30211 ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
30212 ++ asm volatile("movw\t%w7, %%es\n" \
30213 ++ "1:\tmovl\t%%es:%2, %0\n" \
30214 ++ "\tmovl\t%0, %3\n" \
30215 ++ "\t" insn "\n" \
30216 ++ "2:\tlock; cmpxchgl %3, %%es:%2\n" \
30217 ++ "\tjnz\t1b\n" \
30218 ++ "3:\tpushl\t%%ss\n" \
30219 ++ "\tpopl\t%%es\n" \
30220 ++ "\t.section .fixup,\"ax\"\n" \
30221 ++ "4:\tmov\t%5, %1\n" \
30222 ++ "\tjmp\t3b\n" \
30223 ++ "\t.previous\n" \
30224 ++ _ASM_EXTABLE(1b, 4b) \
30225 ++ _ASM_EXTABLE(2b, 4b) \
30226 ++ : "=&a" (oldval), "=&r" (ret), \
30227 ++ "+m" (*uaddr), "=&r" (tem) \
30228 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
30229 ++#else
30230 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
30231 + asm volatile("1:\t" insn "\n" \
30232 + "2:\t.section .fixup,\"ax\"\n" \
30233 +@@ -36,8 +70,9 @@
30234 + : "=&a" (oldval), "=&r" (ret), \
30235 + "+m" (*uaddr), "=&r" (tem) \
30236 + : "r" (oparg), "i" (-EFAULT), "1" (0))
30237 ++#endif
30238 +
30239 +-static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
30240 ++static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
30241 + {
30242 + int op = (encoded_op >> 28) & 7;
30243 + int cmp = (encoded_op >> 24) & 15;
30244 +@@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
30245 +
30246 + switch (op) {
30247 + case FUTEX_OP_SET:
30248 ++#ifdef CONFIG_X86_32
30249 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
30250 ++#else
30251 + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
30252 ++#endif
30253 + break;
30254 + case FUTEX_OP_ADD:
30255 ++#ifdef CONFIG_X86_32
30256 ++ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
30257 ++ uaddr, oparg);
30258 ++#else
30259 + __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
30260 + uaddr, oparg);
30261 ++#endif
30262 + break;
30263 + case FUTEX_OP_OR:
30264 + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
30265 +@@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
30266 + return ret;
30267 + }
30268 +
30269 +-static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
30270 ++static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
30271 + int newval)
30272 + {
30273 +
30274 +@@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
30275 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
30276 + return -EFAULT;
30277 +
30278 +- asm volatile("1:\tlock; cmpxchgl %3, %1\n"
30279 ++ asm volatile(
30280 ++#ifdef CONFIG_X86_32
30281 ++ "\tmovw %w5, %%ds\n"
30282 ++ "1:\tlock; cmpxchgl %3, %1\n"
30283 ++ "2:\tpushl %%ss\n"
30284 ++ "\tpopl %%ds\n"
30285 ++ "\t.section .fixup, \"ax\"\n"
30286 ++#else
30287 ++ "1:\tlock; cmpxchgl %3, %1\n"
30288 + "2:\t.section .fixup, \"ax\"\n"
30289 ++#endif
30290 + "3:\tmov %2, %0\n"
30291 + "\tjmp 2b\n"
30292 + "\t.previous\n"
30293 + _ASM_EXTABLE(1b, 3b)
30294 + : "=a" (oldval), "+m" (*uaddr)
30295 ++#ifdef CONFIG_X86_32
30296 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
30297 ++#else
30298 + : "i" (-EFAULT), "r" (newval), "0" (oldval)
30299 ++#endif
30300 + : "memory"
30301 + );
30302 +
30303 +diff -urNp linux-2.6.26.6/include/asm-x86/i387.h linux-2.6.26.6/include/asm-x86/i387.h
30304 +--- linux-2.6.26.6/include/asm-x86/i387.h 2008-10-08 23:24:05.000000000 -0400
30305 ++++ linux-2.6.26.6/include/asm-x86/i387.h 2008-10-11 21:54:20.000000000 -0400
30306 +@@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
30307 + }
30308 +
30309 + /* We need a safe address that is cheap to find and that is already
30310 +- in L1 during context switch. The best choices are unfortunately
30311 +- different for UP and SMP */
30312 +-#ifdef CONFIG_SMP
30313 +-#define safe_address (__per_cpu_offset[0])
30314 +-#else
30315 +-#define safe_address (kstat_cpu(0).cpustat.user)
30316 +-#endif
30317 ++ in L1 during context switch. */
30318 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
30319 +
30320 + /*
30321 + * These must be called with preempt disabled
30322 +diff -urNp linux-2.6.26.6/include/asm-x86/io_64.h linux-2.6.26.6/include/asm-x86/io_64.h
30323 +--- linux-2.6.26.6/include/asm-x86/io_64.h 2008-10-08 23:24:05.000000000 -0400
30324 ++++ linux-2.6.26.6/include/asm-x86/io_64.h 2008-10-11 21:54:20.000000000 -0400
30325 +@@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
30326 + }
30327 + #endif
30328 +
30329 ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
30330 ++static inline int valid_phys_addr_range (unsigned long addr, size_t count)
30331 ++{
30332 ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
30333 ++}
30334 ++
30335 ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
30336 ++{
30337 ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
30338 ++}
30339 ++
30340 + /*
30341 + * Change "struct page" to physical address.
30342 + */
30343 +diff -urNp linux-2.6.26.6/include/asm-x86/irqflags.h linux-2.6.26.6/include/asm-x86/irqflags.h
30344 +--- linux-2.6.26.6/include/asm-x86/irqflags.h 2008-10-08 23:24:05.000000000 -0400
30345 ++++ linux-2.6.26.6/include/asm-x86/irqflags.h 2008-10-11 21:54:20.000000000 -0400
30346 +@@ -120,6 +120,8 @@ static inline unsigned long __raw_local_
30347 + #define INTERRUPT_RETURN iret
30348 + #define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit
30349 + #define GET_CR0_INTO_EAX movl %cr0, %eax
30350 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
30351 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
30352 + #endif
30353 +
30354 +
30355 +diff -urNp linux-2.6.26.6/include/asm-x86/kmap_types.h linux-2.6.26.6/include/asm-x86/kmap_types.h
30356 +--- linux-2.6.26.6/include/asm-x86/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
30357 ++++ linux-2.6.26.6/include/asm-x86/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
30358 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
30359 + D(10) KM_IRQ1,
30360 + D(11) KM_SOFTIRQ0,
30361 + D(12) KM_SOFTIRQ1,
30362 +-D(13) KM_TYPE_NR
30363 ++D(13) KM_CLEARPAGE,
30364 ++D(14) KM_TYPE_NR
30365 + };
30366 +
30367 + #undef D
30368 +diff -urNp linux-2.6.26.6/include/asm-x86/linkage.h linux-2.6.26.6/include/asm-x86/linkage.h
30369 +--- linux-2.6.26.6/include/asm-x86/linkage.h 2008-10-08 23:24:05.000000000 -0400
30370 ++++ linux-2.6.26.6/include/asm-x86/linkage.h 2008-10-11 21:54:20.000000000 -0400
30371 +@@ -7,6 +7,11 @@
30372 + #ifdef CONFIG_X86_64
30373 + #define __ALIGN .p2align 4,,15
30374 + #define __ALIGN_STR ".p2align 4,,15"
30375 ++#else
30376 ++#ifdef CONFIG_X86_ALIGNMENT_16
30377 ++#define __ALIGN .align 16,0x90
30378 ++#define __ALIGN_STR ".align 16,0x90"
30379 ++#endif
30380 + #endif
30381 +
30382 + #ifdef CONFIG_X86_32
30383 +@@ -52,10 +57,5 @@
30384 +
30385 + #endif
30386 +
30387 +-#ifdef CONFIG_X86_ALIGNMENT_16
30388 +-#define __ALIGN .align 16,0x90
30389 +-#define __ALIGN_STR ".align 16,0x90"
30390 +-#endif
30391 +-
30392 + #endif
30393 +
30394 +diff -urNp linux-2.6.26.6/include/asm-x86/local.h linux-2.6.26.6/include/asm-x86/local.h
30395 +--- linux-2.6.26.6/include/asm-x86/local.h 2008-10-08 23:24:05.000000000 -0400
30396 ++++ linux-2.6.26.6/include/asm-x86/local.h 2008-10-11 21:54:20.000000000 -0400
30397 +@@ -18,26 +18,90 @@ typedef struct {
30398 +
30399 + static inline void local_inc(local_t *l)
30400 + {
30401 +- asm volatile(_ASM_INC "%0"
30402 ++ asm volatile(_ASM_INC "%0\n"
30403 ++
30404 ++#ifdef CONFIG_PAX_REFCOUNT
30405 ++#ifdef CONFIG_X86_32
30406 ++ "into\n0:\n"
30407 ++#else
30408 ++ "jno 0f\n"
30409 ++ "int $4\n0:\n"
30410 ++#endif
30411 ++ ".pushsection .fixup,\"ax\"\n"
30412 ++ "1:\n"
30413 ++ _ASM_DEC "%0\n"
30414 ++ "jmp 0b\n"
30415 ++ ".popsection\n"
30416 ++ _ASM_EXTABLE(0b, 1b)
30417 ++#endif
30418 ++
30419 + : "+m" (l->a.counter));
30420 + }
30421 +
30422 + static inline void local_dec(local_t *l)
30423 + {
30424 +- asm volatile(_ASM_DEC "%0"
30425 ++ asm volatile(_ASM_DEC "%0\n"
30426 ++
30427 ++#ifdef CONFIG_PAX_REFCOUNT
30428 ++#ifdef CONFIG_X86_32
30429 ++ "into\n0:\n"
30430 ++#else
30431 ++ "jno 0f\n"
30432 ++ "int $4\n0:\n"
30433 ++#endif
30434 ++ ".pushsection .fixup,\"ax\"\n"
30435 ++ "1:\n"
30436 ++ _ASM_INC "%0\n"
30437 ++ "jmp 0b\n"
30438 ++ ".popsection\n"
30439 ++ _ASM_EXTABLE(0b, 1b)
30440 ++#endif
30441 ++
30442 + : "+m" (l->a.counter));
30443 + }
30444 +
30445 + static inline void local_add(long i, local_t *l)
30446 + {
30447 +- asm volatile(_ASM_ADD "%1,%0"
30448 ++ asm volatile(_ASM_ADD "%1,%0\n"
30449 ++
30450 ++#ifdef CONFIG_PAX_REFCOUNT
30451 ++#ifdef CONFIG_X86_32
30452 ++ "into\n0:\n"
30453 ++#else
30454 ++ "jno 0f\n"
30455 ++ "int $4\n0:\n"
30456 ++#endif
30457 ++ ".pushsection .fixup,\"ax\"\n"
30458 ++ "1:\n"
30459 ++ _ASM_SUB "%1,%0\n"
30460 ++ "jmp 0b\n"
30461 ++ ".popsection\n"
30462 ++ _ASM_EXTABLE(0b, 1b)
30463 ++#endif
30464 ++
30465 + : "+m" (l->a.counter)
30466 + : "ir" (i));
30467 + }
30468 +
30469 + static inline void local_sub(long i, local_t *l)
30470 + {
30471 +- asm volatile(_ASM_SUB "%1,%0"
30472 ++ asm volatile(_ASM_SUB "%1,%0\n"
30473 ++
30474 ++#ifdef CONFIG_PAX_REFCOUNT
30475 ++#ifdef CONFIG_X86_32
30476 ++ "into\n0:\n"
30477 ++#else
30478 ++ "jno 0f\n"
30479 ++ "int $4\n0:\n"
30480 ++#endif
30481 ++ ".pushsection .fixup,\"ax\"\n"
30482 ++ "1:\n"
30483 ++ _ASM_ADD "%1,%0\n"
30484 ++ "jmp 0b\n"
30485 ++ ".popsection\n"
30486 ++ _ASM_EXTABLE(0b, 1b)
30487 ++#endif
30488 ++
30489 + : "+m" (l->a.counter)
30490 + : "ir" (i));
30491 + }
30492 +@@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
30493 + {
30494 + unsigned char c;
30495 +
30496 +- asm volatile(_ASM_SUB "%2,%0; sete %1"
30497 ++ asm volatile(_ASM_SUB "%2,%0\n"
30498 ++
30499 ++#ifdef CONFIG_PAX_REFCOUNT
30500 ++#ifdef CONFIG_X86_32
30501 ++ "into\n0:\n"
30502 ++#else
30503 ++ "jno 0f\n"
30504 ++ "int $4\n0:\n"
30505 ++#endif
30506 ++ ".pushsection .fixup,\"ax\"\n"
30507 ++ "1:\n"
30508 ++ _ASM_ADD "%2,%0\n"
30509 ++ "jmp 0b\n"
30510 ++ ".popsection\n"
30511 ++ _ASM_EXTABLE(0b, 1b)
30512 ++#endif
30513 ++
30514 ++ "sete %1\n"
30515 + : "+m" (l->a.counter), "=qm" (c)
30516 + : "ir" (i) : "memory");
30517 + return c;
30518 +@@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
30519 + {
30520 + unsigned char c;
30521 +
30522 +- asm volatile(_ASM_DEC "%0; sete %1"
30523 ++ asm volatile(_ASM_DEC "%0\n"
30524 ++
30525 ++#ifdef CONFIG_PAX_REFCOUNT
30526 ++#ifdef CONFIG_X86_32
30527 ++ "into\n0:\n"
30528 ++#else
30529 ++ "jno 0f\n"
30530 ++ "int $4\n0:\n"
30531 ++#endif
30532 ++ ".pushsection .fixup,\"ax\"\n"
30533 ++ "1:\n"
30534 ++ _ASM_INC "%0\n"
30535 ++ "jmp 0b\n"
30536 ++ ".popsection\n"
30537 ++ _ASM_EXTABLE(0b, 1b)
30538 ++#endif
30539 ++
30540 ++ "sete %1\n"
30541 + : "+m" (l->a.counter), "=qm" (c)
30542 + : : "memory");
30543 + return c != 0;
30544 +@@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
30545 + {
30546 + unsigned char c;
30547 +
30548 +- asm volatile(_ASM_INC "%0; sete %1"
30549 ++ asm volatile(_ASM_INC "%0\n"
30550 ++
30551 ++#ifdef CONFIG_PAX_REFCOUNT
30552 ++#ifdef CONFIG_X86_32
30553 ++ "into\n0:\n"
30554 ++#else
30555 ++ "jno 0f\n"
30556 ++ "int $4\n0:\n"
30557 ++#endif
30558 ++ ".pushsection .fixup,\"ax\"\n"
30559 ++ "1:\n"
30560 ++ _ASM_DEC "%0\n"
30561 ++ "jmp 0b\n"
30562 ++ ".popsection\n"
30563 ++ _ASM_EXTABLE(0b, 1b)
30564 ++#endif
30565 ++
30566 ++ "sete %1\n"
30567 + : "+m" (l->a.counter), "=qm" (c)
30568 + : : "memory");
30569 + return c != 0;
30570 +@@ -110,7 +225,24 @@ static inline int local_add_negative(lon
30571 + {
30572 + unsigned char c;
30573 +
30574 +- asm volatile(_ASM_ADD "%2,%0; sets %1"
30575 ++ asm volatile(_ASM_ADD "%2,%0\n"
30576 ++
30577 ++#ifdef CONFIG_PAX_REFCOUNT
30578 ++#ifdef CONFIG_X86_32
30579 ++ "into\n0:\n"
30580 ++#else
30581 ++ "jno 0f\n"
30582 ++ "int $4\n0:\n"
30583 ++#endif
30584 ++ ".pushsection .fixup,\"ax\"\n"
30585 ++ "1:\n"
30586 ++ _ASM_SUB "%2,%0\n"
30587 ++ "jmp 0b\n"
30588 ++ ".popsection\n"
30589 ++ _ASM_EXTABLE(0b, 1b)
30590 ++#endif
30591 ++
30592 ++ "sets %1\n"
30593 + : "+m" (l->a.counter), "=qm" (c)
30594 + : "ir" (i) : "memory");
30595 + return c;
30596 +@@ -133,7 +265,23 @@ static inline long local_add_return(long
30597 + #endif
30598 + /* Modern 486+ processor */
30599 + __i = i;
30600 +- asm volatile(_ASM_XADD "%0, %1;"
30601 ++ asm volatile(_ASM_XADD "%0, %1\n"
30602 ++
30603 ++#ifdef CONFIG_PAX_REFCOUNT
30604 ++#ifdef CONFIG_X86_32
30605 ++ "into\n0:\n"
30606 ++#else
30607 ++ "jno 0f\n"
30608 ++ "int $4\n0:\n"
30609 ++#endif
30610 ++ ".pushsection .fixup,\"ax\"\n"
30611 ++ "1:\n"
30612 ++ _ASM_MOV_UL "%0,%1\n"
30613 ++ "jmp 0b\n"
30614 ++ ".popsection\n"
30615 ++ _ASM_EXTABLE(0b, 1b)
30616 ++#endif
30617 ++
30618 + : "+r" (i), "+m" (l->a.counter)
30619 + : : "memory");
30620 + return i + __i;
30621 +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
30622 +--- linux-2.6.26.6/include/asm-x86/mach-default/apm.h 2008-10-08 23:24:05.000000000 -0400
30623 ++++ linux-2.6.26.6/include/asm-x86/mach-default/apm.h 2008-10-11 21:54:20.000000000 -0400
30624 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
30625 + __asm__ __volatile__(APM_DO_ZERO_SEGS
30626 + "pushl %%edi\n\t"
30627 + "pushl %%ebp\n\t"
30628 +- "lcall *%%cs:apm_bios_entry\n\t"
30629 ++ "lcall *%%ss:apm_bios_entry\n\t"
30630 + "setc %%al\n\t"
30631 + "popl %%ebp\n\t"
30632 + "popl %%edi\n\t"
30633 +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
30634 + __asm__ __volatile__(APM_DO_ZERO_SEGS
30635 + "pushl %%edi\n\t"
30636 + "pushl %%ebp\n\t"
30637 +- "lcall *%%cs:apm_bios_entry\n\t"
30638 ++ "lcall *%%ss:apm_bios_entry\n\t"
30639 + "setc %%bl\n\t"
30640 + "popl %%ebp\n\t"
30641 + "popl %%edi\n\t"
30642 +diff -urNp linux-2.6.26.6/include/asm-x86/mman.h linux-2.6.26.6/include/asm-x86/mman.h
30643 +--- linux-2.6.26.6/include/asm-x86/mman.h 2008-10-08 23:24:05.000000000 -0400
30644 ++++ linux-2.6.26.6/include/asm-x86/mman.h 2008-10-11 21:54:20.000000000 -0400
30645 +@@ -16,4 +16,14 @@
30646 + #define MCL_CURRENT 1 /* lock all current mappings */
30647 + #define MCL_FUTURE 2 /* lock all future mappings */
30648 +
30649 ++#ifdef __KERNEL__
30650 ++#ifndef __ASSEMBLY__
30651 ++#ifdef CONFIG_X86_32
30652 ++#define arch_mmap_check i386_mmap_check
30653 ++int i386_mmap_check(unsigned long addr, unsigned long len,
30654 ++ unsigned long flags);
30655 ++#endif
30656 ++#endif
30657 ++#endif
30658 ++
30659 + #endif /* _ASM_X86_MMAN_H */
30660 +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
30661 +--- linux-2.6.26.6/include/asm-x86/mmu_context_32.h 2008-10-08 23:24:05.000000000 -0400
30662 ++++ linux-2.6.26.6/include/asm-x86/mmu_context_32.h 2008-10-11 21:54:20.000000000 -0400
30663 +@@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
30664 + */
30665 + if (unlikely(prev->context.ldt != next->context.ldt))
30666 + load_LDT_nolock(&next->context);
30667 ++
30668 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
30669 ++ if (!nx_enabled) {
30670 ++ smp_mb__before_clear_bit();
30671 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
30672 ++ smp_mb__after_clear_bit();
30673 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
30674 ++ }
30675 ++#endif
30676 ++
30677 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30678 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
30679 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
30680 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
30681 ++#endif
30682 ++
30683 + }
30684 + #ifdef CONFIG_SMP
30685 + else {
30686 +@@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
30687 + */
30688 + load_cr3(next->pgd);
30689 + load_LDT_nolock(&next->context);
30690 ++
30691 ++#ifdef CONFIG_PAX_PAGEEXEC
30692 ++ if (!nx_enabled)
30693 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
30694 ++#endif
30695 ++
30696 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30697 ++#ifdef CONFIG_PAX_PAGEEXEC
30698 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
30699 ++#endif
30700 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
30701 ++#endif
30702 ++
30703 + }
30704 + }
30705 + #endif
30706 +diff -urNp linux-2.6.26.6/include/asm-x86/mmu.h linux-2.6.26.6/include/asm-x86/mmu.h
30707 +--- linux-2.6.26.6/include/asm-x86/mmu.h 2008-10-08 23:24:05.000000000 -0400
30708 ++++ linux-2.6.26.6/include/asm-x86/mmu.h 2008-10-11 21:54:20.000000000 -0400
30709 +@@ -11,13 +11,26 @@
30710 + * cpu_vm_mask is used to optimize ldt flushing.
30711 + */
30712 + typedef struct {
30713 +- void *ldt;
30714 ++ struct desc_struct *ldt;
30715 + #ifdef CONFIG_X86_64
30716 + rwlock_t ldtlock;
30717 + #endif
30718 + int size;
30719 + struct mutex lock;
30720 +- void *vdso;
30721 ++ unsigned long vdso;
30722 ++
30723 ++#ifdef CONFIG_X86_32
30724 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
30725 ++ unsigned long user_cs_base;
30726 ++ unsigned long user_cs_limit;
30727 ++
30728 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
30729 ++ cpumask_t cpu_user_cs_mask;
30730 ++#endif
30731 ++
30732 ++#endif
30733 ++#endif
30734 ++
30735 + } mm_context_t;
30736 +
30737 + #ifdef CONFIG_SMP
30738 +diff -urNp linux-2.6.26.6/include/asm-x86/module.h linux-2.6.26.6/include/asm-x86/module.h
30739 +--- linux-2.6.26.6/include/asm-x86/module.h 2008-10-08 23:24:05.000000000 -0400
30740 ++++ linux-2.6.26.6/include/asm-x86/module.h 2008-10-11 21:54:20.000000000 -0400
30741 +@@ -76,7 +76,12 @@ struct mod_arch_specific {};
30742 + # else
30743 + # define MODULE_STACKSIZE ""
30744 + # endif
30745 +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
30746 ++# ifdef CONFIG_GRKERNSEC
30747 ++# define MODULE_GRSEC "GRSECURITY "
30748 ++# else
30749 ++# define MODULE_GRSEC ""
30750 ++# endif
30751 ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
30752 + #endif
30753 +
30754 + #endif /* _ASM_MODULE_H */
30755 +diff -urNp linux-2.6.26.6/include/asm-x86/page_32.h linux-2.6.26.6/include/asm-x86/page_32.h
30756 +--- linux-2.6.26.6/include/asm-x86/page_32.h 2008-10-08 23:24:05.000000000 -0400
30757 ++++ linux-2.6.26.6/include/asm-x86/page_32.h 2008-10-11 21:54:20.000000000 -0400
30758 +@@ -13,6 +13,23 @@
30759 + */
30760 + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
30761 +
30762 ++#ifdef CONFIG_PAX_KERNEXEC
30763 ++#ifndef __ASSEMBLY__
30764 ++extern unsigned char MODULES_VADDR[];
30765 ++extern unsigned char MODULES_END[];
30766 ++extern unsigned char KERNEL_TEXT_OFFSET[];
30767 ++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
30768 ++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
30769 ++#endif
30770 ++#else
30771 ++#define ktla_ktva(addr) (addr)
30772 ++#define ktva_ktla(addr) (addr)
30773 ++#endif
30774 ++
30775 ++#ifdef CONFIG_PAX_PAGEEXEC
30776 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
30777 ++#endif
30778 ++
30779 + #ifdef CONFIG_X86_PAE
30780 + /* 44=32+12, the limit we can fit into an unsigned long pfn */
30781 + #define __PHYSICAL_MASK_SHIFT 44
30782 +diff -urNp linux-2.6.26.6/include/asm-x86/page_64.h linux-2.6.26.6/include/asm-x86/page_64.h
30783 +--- linux-2.6.26.6/include/asm-x86/page_64.h 2008-10-08 23:24:05.000000000 -0400
30784 ++++ linux-2.6.26.6/include/asm-x86/page_64.h 2008-10-11 21:54:20.000000000 -0400
30785 +@@ -43,6 +43,9 @@
30786 + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
30787 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
30788 +
30789 ++#define ktla_ktva(addr) (addr)
30790 ++#define ktva_ktla(addr) (addr)
30791 ++
30792 + /* See Documentation/x86_64/mm.txt for a description of the memory map. */
30793 + #define __PHYSICAL_MASK_SHIFT 46
30794 + #define __VIRTUAL_MASK_SHIFT 48
30795 +@@ -89,5 +92,6 @@ extern unsigned long init_memory_mapping
30796 + #define pfn_valid(pfn) ((pfn) < end_pfn)
30797 + #endif
30798 +
30799 ++#define nx_enabled (1)
30800 +
30801 + #endif /* _X86_64_PAGE_H */
30802 +diff -urNp linux-2.6.26.6/include/asm-x86/paravirt.h linux-2.6.26.6/include/asm-x86/paravirt.h
30803 +--- linux-2.6.26.6/include/asm-x86/paravirt.h 2008-10-08 23:24:05.000000000 -0400
30804 ++++ linux-2.6.26.6/include/asm-x86/paravirt.h 2008-10-11 21:54:20.000000000 -0400
30805 +@@ -1383,24 +1383,24 @@ static inline unsigned long __raw_local_
30806 +
30807 + #define INTERRUPT_RETURN \
30808 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
30809 +- jmp *%cs:pv_cpu_ops+PV_CPU_iret)
30810 ++ jmp *%ss:pv_cpu_ops+PV_CPU_iret)
30811 +
30812 + #define DISABLE_INTERRUPTS(clobbers) \
30813 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
30814 + PV_SAVE_REGS; \
30815 +- call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
30816 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
30817 + PV_RESTORE_REGS;) \
30818 +
30819 + #define ENABLE_INTERRUPTS(clobbers) \
30820 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
30821 + PV_SAVE_REGS; \
30822 +- call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
30823 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
30824 + PV_RESTORE_REGS;)
30825 +
30826 + #define ENABLE_INTERRUPTS_SYSCALL_RET \
30827 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
30828 + CLBR_NONE, \
30829 +- jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
30830 ++ jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
30831 +
30832 +
30833 + #ifdef CONFIG_X86_32
30834 +diff -urNp linux-2.6.26.6/include/asm-x86/pda.h linux-2.6.26.6/include/asm-x86/pda.h
30835 +--- linux-2.6.26.6/include/asm-x86/pda.h 2008-10-08 23:24:05.000000000 -0400
30836 ++++ linux-2.6.26.6/include/asm-x86/pda.h 2008-10-11 21:54:20.000000000 -0400
30837 +@@ -16,11 +16,9 @@ struct x8664_pda {
30838 + unsigned long oldrsp; /* 24 user rsp for system call */
30839 + int irqcount; /* 32 Irq nesting counter. Starts -1 */
30840 + unsigned int cpunumber; /* 36 Logical CPU number */
30841 +-#ifdef CONFIG_CC_STACKPROTECTOR
30842 + unsigned long stack_canary; /* 40 stack canary value */
30843 + /* gcc-ABI: this canary MUST be at
30844 + offset 40!!! */
30845 +-#endif
30846 + char *irqstackptr;
30847 + unsigned int __softirq_pending;
30848 + unsigned int __nmi_count; /* number of NMI on this CPUs */
30849 +diff -urNp linux-2.6.26.6/include/asm-x86/percpu.h linux-2.6.26.6/include/asm-x86/percpu.h
30850 +--- linux-2.6.26.6/include/asm-x86/percpu.h 2008-10-08 23:24:05.000000000 -0400
30851 ++++ linux-2.6.26.6/include/asm-x86/percpu.h 2008-10-11 21:54:20.000000000 -0400
30852 +@@ -67,6 +67,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
30853 +
30854 + #define __my_cpu_offset x86_read_percpu(this_cpu_off)
30855 +
30856 ++#include <asm-generic/sections.h>
30857 ++#include <linux/threads.h>
30858 ++#define __per_cpu_offset __per_cpu_offset
30859 ++extern unsigned long __per_cpu_offset[NR_CPUS];
30860 ++#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
30861 ++
30862 + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
30863 + #define __percpu_seg "%%fs:"
30864 +
30865 +diff -urNp linux-2.6.26.6/include/asm-x86/pgalloc.h linux-2.6.26.6/include/asm-x86/pgalloc.h
30866 +--- linux-2.6.26.6/include/asm-x86/pgalloc.h 2008-10-08 23:24:05.000000000 -0400
30867 ++++ linux-2.6.26.6/include/asm-x86/pgalloc.h 2008-10-11 21:54:20.000000000 -0400
30868 +@@ -47,7 +47,11 @@ static inline void pmd_populate_kernel(s
30869 + pmd_t *pmd, pte_t *pte)
30870 + {
30871 + paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
30872 ++#ifdef CONFIG_COMPAT_VDSO
30873 + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
30874 ++#else
30875 ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
30876 ++#endif
30877 + }
30878 +
30879 + static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
30880 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable-2level.h linux-2.6.26.6/include/asm-x86/pgtable-2level.h
30881 +--- linux-2.6.26.6/include/asm-x86/pgtable-2level.h 2008-10-08 23:24:05.000000000 -0400
30882 ++++ linux-2.6.26.6/include/asm-x86/pgtable-2level.h 2008-10-11 21:54:20.000000000 -0400
30883 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
30884 +
30885 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
30886 + {
30887 ++
30888 ++#ifdef CONFIG_PAX_KERNEXEC
30889 ++ unsigned long cr0;
30890 ++
30891 ++ pax_open_kernel(cr0);
30892 ++#endif
30893 ++
30894 + *pmdp = pmd;
30895 ++
30896 ++#ifdef CONFIG_PAX_KERNEXEC
30897 ++ pax_close_kernel(cr0);
30898 ++#endif
30899 ++
30900 + }
30901 +
30902 + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
30903 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable_32.h linux-2.6.26.6/include/asm-x86/pgtable_32.h
30904 +--- linux-2.6.26.6/include/asm-x86/pgtable_32.h 2008-10-08 23:24:05.000000000 -0400
30905 ++++ linux-2.6.26.6/include/asm-x86/pgtable_32.h 2008-10-11 21:54:20.000000000 -0400
30906 +@@ -25,8 +25,6 @@
30907 + struct mm_struct;
30908 + struct vm_area_struct;
30909 +
30910 +-extern pgd_t swapper_pg_dir[1024];
30911 +-
30912 + static inline void pgtable_cache_init(void) { }
30913 + static inline void check_pgt_cache(void) { }
30914 + void paging_init(void);
30915 +@@ -45,6 +43,11 @@ void paging_init(void);
30916 + # include <asm/pgtable-2level-defs.h>
30917 + #endif
30918 +
30919 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
30920 ++#ifdef CONFIG_X86_PAE
30921 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
30922 ++#endif
30923 ++
30924 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
30925 + #define PGDIR_MASK (~(PGDIR_SIZE - 1))
30926 +
30927 +@@ -81,7 +84,7 @@ void paging_init(void);
30928 + #undef TEST_ACCESS_OK
30929 +
30930 + /* The boot page tables (all created as a single array) */
30931 +-extern unsigned long pg0[];
30932 ++extern pte_t pg0[];
30933 +
30934 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
30935 +
30936 +@@ -208,6 +211,9 @@ static inline void __init paravirt_paget
30937 +
30938 + #endif /* !__ASSEMBLY__ */
30939 +
30940 ++#define HAVE_ARCH_UNMAPPED_AREA
30941 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
30942 ++
30943 + /*
30944 + * kern_addr_valid() is (1) for FLATMEM and (0) for
30945 + * SPARSEMEM and DISCONTIGMEM
30946 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable-3level.h linux-2.6.26.6/include/asm-x86/pgtable-3level.h
30947 +--- linux-2.6.26.6/include/asm-x86/pgtable-3level.h 2008-10-08 23:24:05.000000000 -0400
30948 ++++ linux-2.6.26.6/include/asm-x86/pgtable-3level.h 2008-10-11 21:54:20.000000000 -0400
30949 +@@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
30950 +
30951 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
30952 + {
30953 ++
30954 ++#ifdef CONFIG_PAX_KERNEXEC
30955 ++ unsigned long cr0;
30956 ++
30957 ++ pax_open_kernel(cr0);
30958 ++#endif
30959 ++
30960 + set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
30961 ++
30962 ++#ifdef CONFIG_PAX_KERNEXEC
30963 ++ pax_close_kernel(cr0);
30964 ++#endif
30965 ++
30966 + }
30967 +
30968 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
30969 + {
30970 ++
30971 ++#ifdef CONFIG_PAX_KERNEXEC
30972 ++ unsigned long cr0;
30973 ++
30974 ++ pax_open_kernel(cr0);
30975 ++#endif
30976 ++
30977 + set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
30978 ++
30979 ++#ifdef CONFIG_PAX_KERNEXEC
30980 ++ pax_close_kernel(cr0);
30981 ++#endif
30982 ++
30983 + }
30984 +
30985 + /*
30986 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable_64.h linux-2.6.26.6/include/asm-x86/pgtable_64.h
30987 +--- linux-2.6.26.6/include/asm-x86/pgtable_64.h 2008-10-08 23:24:05.000000000 -0400
30988 ++++ linux-2.6.26.6/include/asm-x86/pgtable_64.h 2008-10-11 21:54:20.000000000 -0400
30989 +@@ -101,7 +101,19 @@ static inline pte_t native_ptep_get_and_
30990 +
30991 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
30992 + {
30993 ++
30994 ++#ifdef CONFIG_PAX_KERNEXEC
30995 ++ unsigned long cr0;
30996 ++
30997 ++ pax_open_kernel(cr0);
30998 ++#endif
30999 ++
31000 + *pmdp = pmd;
31001 ++
31002 ++#ifdef CONFIG_PAX_KERNEXEC
31003 ++ pax_close_kernel(cr0);
31004 ++#endif
31005 ++
31006 + }
31007 +
31008 + static inline void native_pmd_clear(pmd_t *pmd)
31009 +@@ -153,17 +165,17 @@ static inline void native_pgd_clear(pgd_
31010 +
31011 + static inline int pgd_bad(pgd_t pgd)
31012 + {
31013 +- return (pgd_val(pgd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
31014 ++ return (pgd_val(pgd) & ~(PTE_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
31015 + }
31016 +
31017 + static inline int pud_bad(pud_t pud)
31018 + {
31019 +- return (pud_val(pud) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
31020 ++ return (pud_val(pud) & ~(PTE_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
31021 + }
31022 +
31023 + static inline int pmd_bad(pmd_t pmd)
31024 + {
31025 +- return (pmd_val(pmd) & ~(PTE_MASK | _PAGE_USER)) != _KERNPG_TABLE;
31026 ++ return (pmd_val(pmd) & ~(PTE_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
31027 + }
31028 +
31029 + #define pte_none(x) (!pte_val((x)))
31030 +diff -urNp linux-2.6.26.6/include/asm-x86/pgtable.h linux-2.6.26.6/include/asm-x86/pgtable.h
31031 +--- linux-2.6.26.6/include/asm-x86/pgtable.h 2008-10-08 23:24:05.000000000 -0400
31032 ++++ linux-2.6.26.6/include/asm-x86/pgtable.h 2008-10-11 21:54:20.000000000 -0400
31033 +@@ -83,6 +83,9 @@
31034 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
31035 + _PAGE_ACCESSED)
31036 +
31037 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
31038 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
31039 ++
31040 + #ifdef CONFIG_X86_32
31041 + #define _PAGE_KERNEL_EXEC \
31042 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
31043 +@@ -104,7 +107,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
31044 + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
31045 + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
31046 + #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
31047 +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
31048 ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
31049 + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
31050 + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
31051 +
31052 +@@ -158,10 +161,17 @@ extern unsigned long empty_zero_page[PAG
31053 + extern spinlock_t pgd_lock;
31054 + extern struct list_head pgd_list;
31055 +
31056 ++extern pteval_t __supported_pte_mask;
31057 ++
31058 + /*
31059 + * The following only work if pte_present() is true.
31060 + * Undefined behaviour if not..
31061 + */
31062 ++static inline int pte_user(pte_t pte)
31063 ++{
31064 ++ return pte_val(pte) & _PAGE_USER;
31065 ++}
31066 ++
31067 + static inline int pte_dirty(pte_t pte)
31068 + {
31069 + return pte_val(pte) & _PAGE_DIRTY;
31070 +@@ -223,9 +233,29 @@ static inline pte_t pte_wrprotect(pte_t
31071 + return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW);
31072 + }
31073 +
31074 ++static inline pte_t pte_mkread(pte_t pte)
31075 ++{
31076 ++ return __pte(pte_val(pte) | _PAGE_USER);
31077 ++}
31078 ++
31079 + static inline pte_t pte_mkexec(pte_t pte)
31080 + {
31081 +- return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
31082 ++#ifdef CONFIG_X86_PAE
31083 ++ if (__supported_pte_mask & _PAGE_NX)
31084 ++ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
31085 ++ else
31086 ++#endif
31087 ++ return __pte(pte_val(pte) | _PAGE_USER);
31088 ++}
31089 ++
31090 ++static inline pte_t pte_exprotect(pte_t pte)
31091 ++{
31092 ++#ifdef CONFIG_X86_PAE
31093 ++ if (__supported_pte_mask & _PAGE_NX)
31094 ++ return __pte(pte_val(pte) | _PAGE_NX);
31095 ++ else
31096 ++#endif
31097 ++ return __pte(pte_val(pte) & ~_PAGE_USER);
31098 + }
31099 +
31100 + static inline pte_t pte_mkdirty(pte_t pte)
31101 +@@ -268,8 +298,6 @@ static inline pte_t pte_mkspecial(pte_t
31102 + return pte;
31103 + }
31104 +
31105 +-extern pteval_t __supported_pte_mask;
31106 +-
31107 + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
31108 + {
31109 + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
31110 +@@ -480,7 +508,19 @@ static inline void ptep_set_wrprotect(st
31111 + */
31112 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
31113 + {
31114 +- memcpy(dst, src, count * sizeof(pgd_t));
31115 ++
31116 ++#ifdef CONFIG_PAX_KERNEXEC
31117 ++ unsigned long cr0;
31118 ++
31119 ++ pax_open_kernel(cr0);
31120 ++#endif
31121 ++
31122 ++ memcpy(dst, src, count * sizeof(pgd_t));
31123 ++
31124 ++#ifdef CONFIG_PAX_KERNEXEC
31125 ++ pax_close_kernel(cr0);
31126 ++#endif
31127 ++
31128 + }
31129 +
31130 +
31131 +diff -urNp linux-2.6.26.6/include/asm-x86/processor.h linux-2.6.26.6/include/asm-x86/processor.h
31132 +--- linux-2.6.26.6/include/asm-x86/processor.h 2008-10-08 23:24:05.000000000 -0400
31133 ++++ linux-2.6.26.6/include/asm-x86/processor.h 2008-10-11 21:54:20.000000000 -0400
31134 +@@ -273,7 +273,7 @@ struct tss_struct {
31135 +
31136 + } __attribute__((packed));
31137 +
31138 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
31139 ++extern struct tss_struct init_tss[NR_CPUS];
31140 +
31141 + /*
31142 + * Save the original ist values for checking stack pointers during debugging
31143 +@@ -814,11 +814,20 @@ static inline void spin_lock_prefetch(co
31144 + * User space process size: 3GB (default).
31145 + */
31146 + #define TASK_SIZE PAGE_OFFSET
31147 ++
31148 ++#ifdef CONFIG_PAX_SEGMEXEC
31149 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
31150 ++#endif
31151 ++
31152 ++#ifdef CONFIG_PAX_SEGMEXEC
31153 ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
31154 ++#else
31155 + #define STACK_TOP TASK_SIZE
31156 +-#define STACK_TOP_MAX STACK_TOP
31157 ++#endif
31158 ++#define STACK_TOP_MAX TASK_SIZE
31159 +
31160 + #define INIT_THREAD { \
31161 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
31162 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
31163 + .vm86_info = NULL, \
31164 + .sysenter_cs = __KERNEL_CS, \
31165 + .io_bitmap_ptr = NULL, \
31166 +@@ -833,7 +842,7 @@ static inline void spin_lock_prefetch(co
31167 + */
31168 + #define INIT_TSS { \
31169 + .x86_tss = { \
31170 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
31171 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
31172 + .ss0 = __KERNEL_DS, \
31173 + .ss1 = __KERNEL_CS, \
31174 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
31175 +@@ -844,11 +853,7 @@ static inline void spin_lock_prefetch(co
31176 + extern unsigned long thread_saved_pc(struct task_struct *tsk);
31177 +
31178 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
31179 +-#define KSTK_TOP(info) \
31180 +-({ \
31181 +- unsigned long *__ptr = (unsigned long *)(info); \
31182 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
31183 +-})
31184 ++#define KSTK_TOP(info) ((info)->task.thread.sp0)
31185 +
31186 + /*
31187 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
31188 +@@ -863,7 +868,7 @@ extern unsigned long thread_saved_pc(str
31189 + #define task_pt_regs(task) \
31190 + ({ \
31191 + struct pt_regs *__regs__; \
31192 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
31193 ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
31194 + __regs__ - 1; \
31195 + })
31196 +
31197 +@@ -879,7 +884,7 @@ extern unsigned long thread_saved_pc(str
31198 + * space during mmap's.
31199 + */
31200 + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
31201 +- 0xc0000000 : 0xFFFFe000)
31202 ++ 0xc0000000 : 0xFFFFf000)
31203 +
31204 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
31205 + IA32_PAGE_OFFSET : TASK_SIZE64)
31206 +@@ -916,6 +921,10 @@ extern void start_thread(struct pt_regs
31207 + */
31208 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
31209 +
31210 ++#ifdef CONFIG_PAX_SEGMEXEC
31211 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
31212 ++#endif
31213 ++
31214 + #define KSTK_EIP(task) (task_pt_regs(task)->ip)
31215 +
31216 + /* Get/set a process' ability to use the timestamp counter instruction */
31217 +diff -urNp linux-2.6.26.6/include/asm-x86/ptrace.h linux-2.6.26.6/include/asm-x86/ptrace.h
31218 +--- linux-2.6.26.6/include/asm-x86/ptrace.h 2008-10-08 23:24:05.000000000 -0400
31219 ++++ linux-2.6.26.6/include/asm-x86/ptrace.h 2008-10-11 21:54:20.000000000 -0400
31220 +@@ -56,7 +56,6 @@ struct pt_regs {
31221 + };
31222 +
31223 + #include <asm/vm86.h>
31224 +-#include <asm/segment.h>
31225 +
31226 + #endif /* __KERNEL__ */
31227 +
31228 +@@ -129,6 +128,7 @@ struct pt_regs {
31229 +
31230 + /* the DS BTS struct is used for ptrace as well */
31231 + #include <asm/ds.h>
31232 ++#include <asm/segment.h>
31233 +
31234 + struct task_struct;
31235 +
31236 +@@ -152,28 +152,29 @@ static inline unsigned long regs_return_
31237 + }
31238 +
31239 + /*
31240 +- * user_mode_vm(regs) determines whether a register set came from user mode.
31241 ++ * user_mode(regs) determines whether a register set came from user mode.
31242 + * This is true if V8086 mode was enabled OR if the register set was from
31243 + * protected mode with RPL-3 CS value. This tricky test checks that with
31244 + * one comparison. Many places in the kernel can bypass this full check
31245 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
31246 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
31247 ++ * be used.
31248 + */
31249 +-static inline int user_mode(struct pt_regs *regs)
31250 ++static inline int user_mode_novm(struct pt_regs *regs)
31251 + {
31252 + #ifdef CONFIG_X86_32
31253 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
31254 + #else
31255 +- return !!(regs->cs & 3);
31256 ++ return !!(regs->cs & SEGMENT_RPL_MASK);
31257 + #endif
31258 + }
31259 +
31260 +-static inline int user_mode_vm(struct pt_regs *regs)
31261 ++static inline int user_mode(struct pt_regs *regs)
31262 + {
31263 + #ifdef CONFIG_X86_32
31264 + return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
31265 + USER_RPL;
31266 + #else
31267 +- return user_mode(regs);
31268 ++ return user_mode_novm(regs);
31269 + #endif
31270 + }
31271 +
31272 +diff -urNp linux-2.6.26.6/include/asm-x86/reboot.h linux-2.6.26.6/include/asm-x86/reboot.h
31273 +--- linux-2.6.26.6/include/asm-x86/reboot.h 2008-10-08 23:24:05.000000000 -0400
31274 ++++ linux-2.6.26.6/include/asm-x86/reboot.h 2008-10-11 21:54:20.000000000 -0400
31275 +@@ -14,7 +14,7 @@ struct machine_ops {
31276 +
31277 + extern struct machine_ops machine_ops;
31278 +
31279 +-void machine_real_restart(unsigned char *code, int length);
31280 ++void machine_real_restart(const unsigned char *code, unsigned int length);
31281 + void native_machine_crash_shutdown(struct pt_regs *regs);
31282 + void native_machine_shutdown(void);
31283 +
31284 +diff -urNp linux-2.6.26.6/include/asm-x86/rwsem.h linux-2.6.26.6/include/asm-x86/rwsem.h
31285 +--- linux-2.6.26.6/include/asm-x86/rwsem.h 2008-10-08 23:24:05.000000000 -0400
31286 ++++ linux-2.6.26.6/include/asm-x86/rwsem.h 2008-10-11 21:54:20.000000000 -0400
31287 +@@ -106,10 +106,26 @@ static inline void __down_read(struct rw
31288 + {
31289 + asm volatile("# beginning down_read\n\t"
31290 + LOCK_PREFIX " incl (%%eax)\n\t"
31291 ++
31292 ++#ifdef CONFIG_PAX_REFCOUNT
31293 ++#ifdef CONFIG_X86_32
31294 ++ "into\n0:\n"
31295 ++#else
31296 ++ "jno 0f\n"
31297 ++ "int $4\n0:\n"
31298 ++#endif
31299 ++ ".pushsection .fixup,\"ax\"\n"
31300 ++ "1:\n"
31301 ++ LOCK_PREFIX "decl (%%eax)\n"
31302 ++ "jmp 0b\n"
31303 ++ ".popsection\n"
31304 ++ _ASM_EXTABLE(0b, 1b)
31305 ++#endif
31306 ++
31307 + /* adds 0x00000001, returns the old value */
31308 +- " jns 1f\n"
31309 ++ " jns 2f\n"
31310 + " call call_rwsem_down_read_failed\n"
31311 +- "1:\n\t"
31312 ++ "2:\n\t"
31313 + "# ending down_read\n\t"
31314 + : "+m" (sem->count)
31315 + : "a" (sem)
31316 +@@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
31317 + __s32 result, tmp;
31318 + asm volatile("# beginning __down_read_trylock\n\t"
31319 + " movl %0,%1\n\t"
31320 +- "1:\n\t"
31321 ++ "2:\n\t"
31322 + " movl %1,%2\n\t"
31323 + " addl %3,%2\n\t"
31324 +- " jle 2f\n\t"
31325 ++
31326 ++#ifdef CONFIG_PAX_REFCOUNT
31327 ++#ifdef CONFIG_X86_32
31328 ++ "into\n0:\n"
31329 ++#else
31330 ++ "jno 0f\n"
31331 ++ "int $4\n0:\n"
31332 ++#endif
31333 ++ ".pushsection .fixup,\"ax\"\n"
31334 ++ "1:\n"
31335 ++ "subl %3,%2\n"
31336 ++ "jmp 0b\n"
31337 ++ ".popsection\n"
31338 ++ _ASM_EXTABLE(0b, 1b)
31339 ++#endif
31340 ++
31341 ++ " jle 3f\n\t"
31342 + LOCK_PREFIX " cmpxchgl %2,%0\n\t"
31343 +- " jnz 1b\n\t"
31344 +- "2:\n\t"
31345 ++ " jnz 2b\n\t"
31346 ++ "3:\n\t"
31347 + "# ending __down_read_trylock\n\t"
31348 + : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
31349 + : "i" (RWSEM_ACTIVE_READ_BIAS)
31350 +@@ -148,12 +180,28 @@ static inline void __down_write_nested(s
31351 + tmp = RWSEM_ACTIVE_WRITE_BIAS;
31352 + asm volatile("# beginning down_write\n\t"
31353 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
31354 ++
31355 ++#ifdef CONFIG_PAX_REFCOUNT
31356 ++#ifdef CONFIG_X86_32
31357 ++ "into\n0:\n"
31358 ++#else
31359 ++ "jno 0f\n"
31360 ++ "int $4\n0:\n"
31361 ++#endif
31362 ++ ".pushsection .fixup,\"ax\"\n"
31363 ++ "1:\n"
31364 ++ "movl %%edx,(%%eax)\n"
31365 ++ "jmp 0b\n"
31366 ++ ".popsection\n"
31367 ++ _ASM_EXTABLE(0b, 1b)
31368 ++#endif
31369 ++
31370 + /* subtract 0x0000ffff, returns the old value */
31371 + " testl %%edx,%%edx\n\t"
31372 + /* was the count 0 before? */
31373 +- " jz 1f\n"
31374 ++ " jz 2f\n"
31375 + " call call_rwsem_down_write_failed\n"
31376 +- "1:\n"
31377 ++ "2:\n"
31378 + "# ending down_write"
31379 + : "+m" (sem->count), "=d" (tmp)
31380 + : "a" (sem), "1" (tmp)
31381 +@@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
31382 + __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
31383 + asm volatile("# beginning __up_read\n\t"
31384 + LOCK_PREFIX " xadd %%edx,(%%eax)\n\t"
31385 ++
31386 ++#ifdef CONFIG_PAX_REFCOUNT
31387 ++#ifdef CONFIG_X86_32
31388 ++ "into\n0:\n"
31389 ++#else
31390 ++ "jno 0f\n"
31391 ++ "int $4\n0:\n"
31392 ++#endif
31393 ++ ".pushsection .fixup,\"ax\"\n"
31394 ++ "1:\n"
31395 ++ "movl %%edx,(%%eax)\n"
31396 ++ "jmp 0b\n"
31397 ++ ".popsection\n"
31398 ++ _ASM_EXTABLE(0b, 1b)
31399 ++#endif
31400 ++
31401 + /* subtracts 1, returns the old value */
31402 +- " jns 1f\n\t"
31403 ++ " jns 2f\n\t"
31404 + " call call_rwsem_wake\n"
31405 +- "1:\n"
31406 ++ "2:\n"
31407 + "# ending __up_read\n"
31408 + : "+m" (sem->count), "=d" (tmp)
31409 + : "a" (sem), "1" (tmp)
31410 +@@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
31411 + asm volatile("# beginning __up_write\n\t"
31412 + " movl %2,%%edx\n\t"
31413 + LOCK_PREFIX " xaddl %%edx,(%%eax)\n\t"
31414 ++
31415 ++#ifdef CONFIG_PAX_REFCOUNT
31416 ++#ifdef CONFIG_X86_32
31417 ++ "into\n0:\n"
31418 ++#else
31419 ++ "jno 0f\n"
31420 ++ "int $4\n0:\n"
31421 ++#endif
31422 ++ ".pushsection .fixup,\"ax\"\n"
31423 ++ "1:\n"
31424 ++ "movl %%edx,(%%eax)\n"
31425 ++ "jmp 0b\n"
31426 ++ ".popsection\n"
31427 ++ _ASM_EXTABLE(0b, 1b)
31428 ++#endif
31429 ++
31430 + /* tries to transition
31431 + 0xffff0001 -> 0x00000000 */
31432 +- " jz 1f\n"
31433 ++ " jz 2f\n"
31434 + " call call_rwsem_wake\n"
31435 +- "1:\n\t"
31436 ++ "2:\n\t"
31437 + "# ending __up_write\n"
31438 + : "+m" (sem->count)
31439 + : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
31440 +@@ -222,10 +302,26 @@ static inline void __downgrade_write(str
31441 + {
31442 + asm volatile("# beginning __downgrade_write\n\t"
31443 + LOCK_PREFIX " addl %2,(%%eax)\n\t"
31444 ++
31445 ++#ifdef CONFIG_PAX_REFCOUNT
31446 ++#ifdef CONFIG_X86_32
31447 ++ "into\n0:\n"
31448 ++#else
31449 ++ "jno 0f\n"
31450 ++ "int $4\n0:\n"
31451 ++#endif
31452 ++ ".pushsection .fixup,\"ax\"\n"
31453 ++ "1:\n"
31454 ++ LOCK_PREFIX "subl %2,(%%eax)\n"
31455 ++ "jmp 0b\n"
31456 ++ ".popsection\n"
31457 ++ _ASM_EXTABLE(0b, 1b)
31458 ++#endif
31459 ++
31460 + /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
31461 +- " jns 1f\n\t"
31462 ++ " jns 2f\n\t"
31463 + " call call_rwsem_downgrade_wake\n"
31464 +- "1:\n\t"
31465 ++ "2:\n\t"
31466 + "# ending __downgrade_write\n"
31467 + : "+m" (sem->count)
31468 + : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
31469 +@@ -237,7 +333,23 @@ static inline void __downgrade_write(str
31470 + */
31471 + static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
31472 + {
31473 +- asm volatile(LOCK_PREFIX "addl %1,%0"
31474 ++ asm volatile(LOCK_PREFIX "addl %1,%0\n"
31475 ++
31476 ++#ifdef CONFIG_PAX_REFCOUNT
31477 ++#ifdef CONFIG_X86_32
31478 ++ "into\n0:\n"
31479 ++#else
31480 ++ "jno 0f\n"
31481 ++ "int $4\n0:\n"
31482 ++#endif
31483 ++ ".pushsection .fixup,\"ax\"\n"
31484 ++ "1:\n"
31485 ++ LOCK_PREFIX "subl %1,%0\n"
31486 ++ "jmp 0b\n"
31487 ++ ".popsection\n"
31488 ++ _ASM_EXTABLE(0b, 1b)
31489 ++#endif
31490 ++
31491 + : "+m" (sem->count)
31492 + : "ir" (delta));
31493 + }
31494 +@@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
31495 + {
31496 + int tmp = delta;
31497 +
31498 +- asm volatile(LOCK_PREFIX "xadd %0,%1"
31499 ++ asm volatile(LOCK_PREFIX "xadd %0,%1\n"
31500 ++
31501 ++#ifdef CONFIG_PAX_REFCOUNT
31502 ++#ifdef CONFIG_X86_32
31503 ++ "into\n0:\n"
31504 ++#else
31505 ++ "jno 0f\n"
31506 ++ "int $4\n0:\n"
31507 ++#endif
31508 ++ ".pushsection .fixup,\"ax\"\n"
31509 ++ "1:\n"
31510 ++ "movl %0,%1\n"
31511 ++ "jmp 0b\n"
31512 ++ ".popsection\n"
31513 ++ _ASM_EXTABLE(0b, 1b)
31514 ++#endif
31515 ++
31516 + : "+r" (tmp), "+m" (sem->count)
31517 + : : "memory");
31518 +
31519 +diff -urNp linux-2.6.26.6/include/asm-x86/segment.h linux-2.6.26.6/include/asm-x86/segment.h
31520 +--- linux-2.6.26.6/include/asm-x86/segment.h 2008-10-08 23:24:05.000000000 -0400
31521 ++++ linux-2.6.26.6/include/asm-x86/segment.h 2008-10-11 21:54:20.000000000 -0400
31522 +@@ -83,13 +83,19 @@
31523 + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
31524 + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
31525 +
31526 +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
31527 ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
31528 + #ifdef CONFIG_SMP
31529 + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
31530 + #else
31531 + #define __KERNEL_PERCPU 0
31532 + #endif
31533 +
31534 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
31535 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
31536 ++
31537 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
31538 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
31539 ++
31540 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
31541 +
31542 + /*
31543 +@@ -130,10 +136,10 @@
31544 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
31545 +
31546 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
31547 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
31548 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
31549 +
31550 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
31551 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
31552 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
31553 +
31554 +
31555 + #else
31556 +diff -urNp linux-2.6.26.6/include/asm-x86/spinlock.h linux-2.6.26.6/include/asm-x86/spinlock.h
31557 +--- linux-2.6.26.6/include/asm-x86/spinlock.h 2008-10-08 23:24:05.000000000 -0400
31558 ++++ linux-2.6.26.6/include/asm-x86/spinlock.h 2008-10-11 21:54:20.000000000 -0400
31559 +@@ -227,18 +227,50 @@ static inline int __raw_write_can_lock(r
31560 + static inline void __raw_read_lock(raw_rwlock_t *rw)
31561 + {
31562 + asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
31563 +- "jns 1f\n"
31564 +- "call __read_lock_failed\n\t"
31565 ++
31566 ++#ifdef CONFIG_PAX_REFCOUNT
31567 ++#ifdef CONFIG_X86_32
31568 ++ "into\n0:\n"
31569 ++#else
31570 ++ "jno 0f\n"
31571 ++ "int $4\n0:\n"
31572 ++#endif
31573 ++ ".pushsection .fixup,\"ax\"\n"
31574 + "1:\n"
31575 ++ LOCK_PREFIX " addl $1,(%0)\n"
31576 ++ "jmp 0b\n"
31577 ++ ".popsection\n"
31578 ++ _ASM_EXTABLE(0b, 1b)
31579 ++#endif
31580 ++
31581 ++ "jns 2f\n"
31582 ++ "call __read_lock_failed\n\t"
31583 ++ "2:\n"
31584 + ::LOCK_PTR_REG (rw) : "memory");
31585 + }
31586 +
31587 + static inline void __raw_write_lock(raw_rwlock_t *rw)
31588 + {
31589 + asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
31590 +- "jz 1f\n"
31591 +- "call __write_lock_failed\n\t"
31592 ++
31593 ++#ifdef CONFIG_PAX_REFCOUNT
31594 ++#ifdef CONFIG_X86_32
31595 ++ "into\n0:\n"
31596 ++#else
31597 ++ "jno 0f\n"
31598 ++ "int $4\n0:\n"
31599 ++#endif
31600 ++ ".pushsection .fixup,\"ax\"\n"
31601 + "1:\n"
31602 ++ LOCK_PREFIX " addl %1,(%0)\n"
31603 ++ "jmp 0b\n"
31604 ++ ".popsection\n"
31605 ++ _ASM_EXTABLE(0b, 1b)
31606 ++#endif
31607 ++
31608 ++ "jz 2f\n"
31609 ++ "call __write_lock_failed\n\t"
31610 ++ "2:\n"
31611 + ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
31612 + }
31613 +
31614 +@@ -265,12 +297,45 @@ static inline int __raw_write_trylock(ra
31615 +
31616 + static inline void __raw_read_unlock(raw_rwlock_t *rw)
31617 + {
31618 +- asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
31619 ++ asm volatile(LOCK_PREFIX "incl %0\n"
31620 ++
31621 ++#ifdef CONFIG_PAX_REFCOUNT
31622 ++#ifdef CONFIG_X86_32
31623 ++ "into\n0:\n"
31624 ++#else
31625 ++ "jno 0f\n"
31626 ++ "int $4\n0:\n"
31627 ++#endif
31628 ++ ".pushsection .fixup,\"ax\"\n"
31629 ++ "1:\n"
31630 ++ LOCK_PREFIX "decl %0\n"
31631 ++ "jmp 0b\n"
31632 ++ ".popsection\n"
31633 ++ _ASM_EXTABLE(0b, 1b)
31634 ++#endif
31635 ++
31636 ++ :"+m" (rw->lock) : : "memory");
31637 + }
31638 +
31639 + static inline void __raw_write_unlock(raw_rwlock_t *rw)
31640 + {
31641 +- asm volatile(LOCK_PREFIX "addl %1, %0"
31642 ++ asm volatile(LOCK_PREFIX "addl %1, %0\n"
31643 ++
31644 ++#ifdef CONFIG_PAX_REFCOUNT
31645 ++#ifdef CONFIG_X86_32
31646 ++ "into\n0:\n"
31647 ++#else
31648 ++ "jno 0f\n"
31649 ++ "int $4\n0:\n"
31650 ++#endif
31651 ++ ".pushsection .fixup,\"ax\"\n"
31652 ++ "1:\n"
31653 ++ LOCK_PREFIX "subl %1,%0\n"
31654 ++ "jmp 0b\n"
31655 ++ ".popsection\n"
31656 ++ _ASM_EXTABLE(0b, 1b)
31657 ++#endif
31658 ++
31659 + : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
31660 + }
31661 +
31662 +diff -urNp linux-2.6.26.6/include/asm-x86/system.h linux-2.6.26.6/include/asm-x86/system.h
31663 +--- linux-2.6.26.6/include/asm-x86/system.h 2008-10-08 23:24:05.000000000 -0400
31664 ++++ linux-2.6.26.6/include/asm-x86/system.h 2008-10-11 21:54:20.000000000 -0400
31665 +@@ -92,6 +92,8 @@ do { \
31666 + ".globl thread_return\n" \
31667 + "thread_return:\n\t" \
31668 + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
31669 ++ "movq %P[task_canary](%%rsi),%%r8\n\t" \
31670 ++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
31671 + "movq %P[thread_info](%%rsi),%%r8\n\t" \
31672 + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
31673 + "movq %%rax,%%rdi\n\t" \
31674 +@@ -103,7 +105,9 @@ do { \
31675 + [ti_flags] "i" (offsetof(struct thread_info, flags)), \
31676 + [tif_fork] "i" (TIF_FORK), \
31677 + [thread_info] "i" (offsetof(struct task_struct, stack)), \
31678 +- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
31679 ++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
31680 ++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
31681 ++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
31682 + : "memory", "cc" __EXTRA_CLOBBER)
31683 + #endif
31684 +
31685 +@@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
31686 + {
31687 + unsigned long __limit;
31688 + asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
31689 +- return __limit + 1;
31690 ++ return __limit;
31691 + }
31692 +
31693 + static inline void native_clts(void)
31694 +@@ -291,6 +295,21 @@ static inline void native_wbinvd(void)
31695 +
31696 + #define stts() write_cr0(8 | read_cr0())
31697 +
31698 ++#define pax_open_kernel(cr0) \
31699 ++do { \
31700 ++ typecheck(unsigned long, cr0); \
31701 ++ preempt_disable(); \
31702 ++ cr0 = read_cr0(); \
31703 ++ write_cr0(cr0 & ~X86_CR0_WP); \
31704 ++} while (0)
31705 ++
31706 ++#define pax_close_kernel(cr0) \
31707 ++do { \
31708 ++ typecheck(unsigned long, cr0); \
31709 ++ write_cr0(cr0); \
31710 ++ preempt_enable_no_resched(); \
31711 ++} while (0)
31712 ++
31713 + #endif /* __KERNEL__ */
31714 +
31715 + static inline void clflush(volatile void *__p)
31716 +@@ -306,7 +325,7 @@ void enable_hlt(void);
31717 + extern int es7000_plat;
31718 + void cpu_idle_wait(void);
31719 +
31720 +-extern unsigned long arch_align_stack(unsigned long sp);
31721 ++#define arch_align_stack(x) (x)
31722 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
31723 +
31724 + void default_idle(void);
31725 +diff -urNp linux-2.6.26.6/include/asm-x86/uaccess_32.h linux-2.6.26.6/include/asm-x86/uaccess_32.h
31726 +--- linux-2.6.26.6/include/asm-x86/uaccess_32.h 2008-10-08 23:24:05.000000000 -0400
31727 ++++ linux-2.6.26.6/include/asm-x86/uaccess_32.h 2008-10-11 21:54:20.000000000 -0400
31728 +@@ -10,6 +10,7 @@
31729 + #include <linux/string.h>
31730 + #include <asm/asm.h>
31731 + #include <asm/page.h>
31732 ++#include <asm/segment.h>
31733 +
31734 + #define VERIFY_READ 0
31735 + #define VERIFY_WRITE 1
31736 +@@ -30,7 +31,8 @@
31737 +
31738 + #define get_ds() (KERNEL_DS)
31739 + #define get_fs() (current_thread_info()->addr_limit)
31740 +-#define set_fs(x) (current_thread_info()->addr_limit = (x))
31741 ++void __set_fs(mm_segment_t x, int cpu);
31742 ++void set_fs(mm_segment_t x);
31743 +
31744 + #define segment_eq(a, b) ((a).seg == (b).seg)
31745 +
31746 +@@ -106,6 +108,7 @@ struct exception_table_entry {
31747 + };
31748 +
31749 + extern int fixup_exception(struct pt_regs *regs);
31750 ++#define ARCH_HAS_SORT_EXTABLE
31751 +
31752 + /*
31753 + * These are the main single-value transfer routines. They automatically
31754 +@@ -320,9 +323,12 @@ extern void __put_user_8(void);
31755 +
31756 +
31757 + #define __put_user_u64(x, addr, err) \
31758 +- asm volatile("1: movl %%eax,0(%2)\n" \
31759 +- "2: movl %%edx,4(%2)\n" \
31760 ++ asm volatile(" movw %w5,%%ds\n" \
31761 ++ "1: movl %%eax,%%ds:0(%2)\n" \
31762 ++ "2: movl %%edx,%%ds:4(%2)\n" \
31763 + "3:\n" \
31764 ++ " pushl %%ss\n" \
31765 ++ " popl %%ds\n" \
31766 + ".section .fixup,\"ax\"\n" \
31767 + "4: movl %3,%0\n" \
31768 + " jmp 3b\n" \
31769 +@@ -330,7 +336,8 @@ extern void __put_user_8(void);
31770 + _ASM_EXTABLE(1b, 4b) \
31771 + _ASM_EXTABLE(2b, 4b) \
31772 + : "=r" (err) \
31773 +- : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
31774 ++ : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err), \
31775 ++ "r"(__USER_DS))
31776 +
31777 + #ifdef CONFIG_X86_WP_WORKS_OK
31778 +
31779 +@@ -377,15 +384,19 @@ struct __large_struct { unsigned long bu
31780 + * aliasing issues.
31781 + */
31782 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
31783 +- asm volatile("1: mov"itype" %"rtype"1,%2\n" \
31784 ++ asm volatile(" movw %w5,%%ds\n" \
31785 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
31786 + "2:\n" \
31787 ++ " pushl %%ss\n" \
31788 ++ " popl %%ds\n" \
31789 + ".section .fixup,\"ax\"\n" \
31790 + "3: movl %3,%0\n" \
31791 + " jmp 2b\n" \
31792 + ".previous\n" \
31793 + _ASM_EXTABLE(1b, 3b) \
31794 + : "=r"(err) \
31795 +- : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err))
31796 ++ : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
31797 ++ "r"(__USER_DS))
31798 +
31799 +
31800 + #define __get_user_nocheck(x, ptr, size) \
31801 +@@ -419,8 +430,11 @@ do { \
31802 + } while (0)
31803 +
31804 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
31805 +- asm volatile("1: mov"itype" %2,%"rtype"1\n" \
31806 ++ asm volatile(" movw %w5,%%ds\n" \
31807 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
31808 + "2:\n" \
31809 ++ " pushl %%ss\n" \
31810 ++ " popl %%ds\n" \
31811 + ".section .fixup,\"ax\"\n" \
31812 + "3: movl %3,%0\n" \
31813 + " xor"itype" %"rtype"1,%"rtype"1\n" \
31814 +@@ -428,7 +442,7 @@ do { \
31815 + ".previous\n" \
31816 + _ASM_EXTABLE(1b, 3b) \
31817 + : "=r" (err), ltype (x) \
31818 +- : "m" (__m(addr)), "i" (errret), "0" (err))
31819 ++ : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
31820 +
31821 +
31822 + unsigned long __must_check __copy_to_user_ll
31823 +diff -urNp linux-2.6.26.6/include/asm-x86/uaccess_64.h linux-2.6.26.6/include/asm-x86/uaccess_64.h
31824 +--- linux-2.6.26.6/include/asm-x86/uaccess_64.h 2008-10-08 23:24:05.000000000 -0400
31825 ++++ linux-2.6.26.6/include/asm-x86/uaccess_64.h 2008-10-11 21:54:20.000000000 -0400
31826 +@@ -71,6 +71,7 @@ struct exception_table_entry {
31827 + extern int fixup_exception(struct pt_regs *regs);
31828 +
31829 + #define ARCH_HAS_SEARCH_EXTABLE
31830 ++#define ARCH_HAS_SORT_EXTABLE
31831 +
31832 + /*
31833 + * These are the main single-value transfer routines. They automatically
31834 +diff -urNp linux-2.6.26.6/include/asm-xtensa/kmap_types.h linux-2.6.26.6/include/asm-xtensa/kmap_types.h
31835 +--- linux-2.6.26.6/include/asm-xtensa/kmap_types.h 2008-10-08 23:24:05.000000000 -0400
31836 ++++ linux-2.6.26.6/include/asm-xtensa/kmap_types.h 2008-10-11 21:54:20.000000000 -0400
31837 +@@ -25,6 +25,7 @@ enum km_type {
31838 + KM_IRQ1,
31839 + KM_SOFTIRQ0,
31840 + KM_SOFTIRQ1,
31841 ++ KM_CLEARPAGE,
31842 + KM_TYPE_NR
31843 + };
31844 +
31845 +diff -urNp linux-2.6.26.6/include/linux/a.out.h linux-2.6.26.6/include/linux/a.out.h
31846 +--- linux-2.6.26.6/include/linux/a.out.h 2008-10-08 23:24:05.000000000 -0400
31847 ++++ linux-2.6.26.6/include/linux/a.out.h 2008-10-11 21:54:20.000000000 -0400
31848 +@@ -39,6 +39,14 @@ enum machine_type {
31849 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
31850 + };
31851 +
31852 ++/* Constants for the N_FLAGS field */
31853 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
31854 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
31855 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
31856 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
31857 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
31858 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
31859 ++
31860 + #if !defined (N_MAGIC)
31861 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
31862 + #endif
31863 +diff -urNp linux-2.6.26.6/include/linux/cache.h linux-2.6.26.6/include/linux/cache.h
31864 +--- linux-2.6.26.6/include/linux/cache.h 2008-10-08 23:24:05.000000000 -0400
31865 ++++ linux-2.6.26.6/include/linux/cache.h 2008-10-11 21:54:20.000000000 -0400
31866 +@@ -16,6 +16,10 @@
31867 + #define __read_mostly
31868 + #endif
31869 +
31870 ++#ifndef __read_only
31871 ++#define __read_only __read_mostly
31872 ++#endif
31873 ++
31874 + #ifndef ____cacheline_aligned
31875 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
31876 + #endif
31877 +diff -urNp linux-2.6.26.6/include/linux/capability.h linux-2.6.26.6/include/linux/capability.h
31878 +--- linux-2.6.26.6/include/linux/capability.h 2008-10-08 23:24:05.000000000 -0400
31879 ++++ linux-2.6.26.6/include/linux/capability.h 2008-10-11 21:54:20.000000000 -0400
31880 +@@ -504,6 +504,7 @@ extern const kernel_cap_t __cap_init_eff
31881 + kernel_cap_t cap_set_effective(const kernel_cap_t pE_new);
31882 +
31883 + int capable(int cap);
31884 ++int capable_nolog(int cap);
31885 + int __capable(struct task_struct *t, int cap);
31886 +
31887 + #endif /* __KERNEL__ */
31888 +diff -urNp linux-2.6.26.6/include/linux/cpumask.h linux-2.6.26.6/include/linux/cpumask.h
31889 +--- linux-2.6.26.6/include/linux/cpumask.h 2008-10-08 23:24:05.000000000 -0400
31890 ++++ linux-2.6.26.6/include/linux/cpumask.h 2008-10-11 21:55:52.000000000 -0400
31891 +@@ -233,14 +233,14 @@ extern cpumask_t *cpumask_of_cpu_map;
31892 + #else
31893 + #define cpumask_of_cpu(cpu) \
31894 + (*({ \
31895 +- typeof(_unused_cpumask_arg_) m; \
31896 +- if (sizeof(m) == sizeof(unsigned long)) { \
31897 +- m.bits[0] = 1UL<<(cpu); \
31898 ++ typeof(_unused_cpumask_arg_) __m; \
31899 ++ if (sizeof(__m) == sizeof(unsigned long)) { \
31900 ++ __m.bits[0] = 1UL<<(cpu); \
31901 + } else { \
31902 +- cpus_clear(m); \
31903 +- cpu_set((cpu), m); \
31904 ++ cpus_clear(__m); \
31905 ++ cpu_set((cpu), __m); \
31906 + } \
31907 +- &m; \
31908 ++ &__m; \
31909 + }))
31910 + #endif
31911 +
31912 +diff -urNp linux-2.6.26.6/include/linux/elf.h linux-2.6.26.6/include/linux/elf.h
31913 +--- linux-2.6.26.6/include/linux/elf.h 2008-10-08 23:24:05.000000000 -0400
31914 ++++ linux-2.6.26.6/include/linux/elf.h 2008-10-11 21:54:20.000000000 -0400
31915 +@@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
31916 +
31917 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
31918 +
31919 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
31920 ++
31921 ++/* Constants for the e_flags field */
31922 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
31923 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
31924 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
31925 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
31926 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
31927 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
31928 ++
31929 + /* These constants define the different elf file types */
31930 + #define ET_NONE 0
31931 + #define ET_REL 1
31932 +@@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
31933 + #define DT_DEBUG 21
31934 + #define DT_TEXTREL 22
31935 + #define DT_JMPREL 23
31936 ++#define DT_FLAGS 30
31937 ++ #define DF_TEXTREL 0x00000004
31938 + #define DT_ENCODING 32
31939 + #define OLD_DT_LOOS 0x60000000
31940 + #define DT_LOOS 0x6000000d
31941 +@@ -230,6 +242,19 @@ typedef struct elf64_hdr {
31942 + #define PF_W 0x2
31943 + #define PF_X 0x1
31944 +
31945 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
31946 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
31947 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
31948 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
31949 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
31950 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
31951 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
31952 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
31953 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
31954 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
31955 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
31956 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
31957 ++
31958 + typedef struct elf32_phdr{
31959 + Elf32_Word p_type;
31960 + Elf32_Off p_offset;
31961 +@@ -322,6 +347,8 @@ typedef struct elf64_shdr {
31962 + #define EI_OSABI 7
31963 + #define EI_PAD 8
31964 +
31965 ++#define EI_PAX 14
31966 ++
31967 + #define ELFMAG0 0x7f /* EI_MAG */
31968 + #define ELFMAG1 'E'
31969 + #define ELFMAG2 'L'
31970 +@@ -382,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
31971 + #define elf_phdr elf32_phdr
31972 + #define elf_note elf32_note
31973 + #define elf_addr_t Elf32_Off
31974 ++#define elf_dyn Elf32_Dyn
31975 +
31976 + #else
31977 +
31978 +@@ -390,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
31979 + #define elf_phdr elf64_phdr
31980 + #define elf_note elf64_note
31981 + #define elf_addr_t Elf64_Off
31982 ++#define elf_dyn Elf64_Dyn
31983 +
31984 + #endif
31985 +
31986 +diff -urNp linux-2.6.26.6/include/linux/gracl.h linux-2.6.26.6/include/linux/gracl.h
31987 +--- linux-2.6.26.6/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
31988 ++++ linux-2.6.26.6/include/linux/gracl.h 2008-10-11 21:54:20.000000000 -0400
31989 +@@ -0,0 +1,318 @@
31990 ++#ifndef GR_ACL_H
31991 ++#define GR_ACL_H
31992 ++
31993 ++#include <linux/grdefs.h>
31994 ++#include <linux/resource.h>
31995 ++#include <linux/capability.h>
31996 ++#include <linux/dcache.h>
31997 ++#include <asm/resource.h>
31998 ++
31999 ++/* Major status information */
32000 ++
32001 ++#define GR_VERSION "grsecurity 2.1.12"
32002 ++#define GRSECURITY_VERSION 0x2112
32003 ++
32004 ++enum {
32005 ++
32006 ++ SHUTDOWN = 0,
32007 ++ ENABLE = 1,
32008 ++ SPROLE = 2,
32009 ++ RELOAD = 3,
32010 ++ SEGVMOD = 4,
32011 ++ STATUS = 5,
32012 ++ UNSPROLE = 6,
32013 ++ PASSSET = 7,
32014 ++ SPROLEPAM = 8
32015 ++};
32016 ++
32017 ++/* Password setup definitions
32018 ++ * kernel/grhash.c */
32019 ++enum {
32020 ++ GR_PW_LEN = 128,
32021 ++ GR_SALT_LEN = 16,
32022 ++ GR_SHA_LEN = 32,
32023 ++};
32024 ++
32025 ++enum {
32026 ++ GR_SPROLE_LEN = 64,
32027 ++};
32028 ++
32029 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
32030 ++
32031 ++/* Begin Data Structures */
32032 ++
32033 ++struct sprole_pw {
32034 ++ unsigned char *rolename;
32035 ++ unsigned char salt[GR_SALT_LEN];
32036 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
32037 ++};
32038 ++
32039 ++struct name_entry {
32040 ++ __u32 key;
32041 ++ ino_t inode;
32042 ++ dev_t device;
32043 ++ char *name;
32044 ++ __u16 len;
32045 ++ __u8 deleted;
32046 ++ struct name_entry *prev;
32047 ++ struct name_entry *next;
32048 ++};
32049 ++
32050 ++struct inodev_entry {
32051 ++ struct name_entry *nentry;
32052 ++ struct inodev_entry *prev;
32053 ++ struct inodev_entry *next;
32054 ++};
32055 ++
32056 ++struct acl_role_db {
32057 ++ struct acl_role_label **r_hash;
32058 ++ __u32 r_size;
32059 ++};
32060 ++
32061 ++struct inodev_db {
32062 ++ struct inodev_entry **i_hash;
32063 ++ __u32 i_size;
32064 ++};
32065 ++
32066 ++struct name_db {
32067 ++ struct name_entry **n_hash;
32068 ++ __u32 n_size;
32069 ++};
32070 ++
32071 ++struct crash_uid {
32072 ++ uid_t uid;
32073 ++ unsigned long expires;
32074 ++};
32075 ++
32076 ++struct gr_hash_struct {
32077 ++ void **table;
32078 ++ void **nametable;
32079 ++ void *first;
32080 ++ __u32 table_size;
32081 ++ __u32 used_size;
32082 ++ int type;
32083 ++};
32084 ++
32085 ++/* Userspace Grsecurity ACL data structures */
32086 ++
32087 ++struct acl_subject_label {
32088 ++ char *filename;
32089 ++ ino_t inode;
32090 ++ dev_t device;
32091 ++ __u32 mode;
32092 ++ kernel_cap_t cap_mask;
32093 ++ kernel_cap_t cap_lower;
32094 ++
32095 ++ struct rlimit res[GR_NLIMITS];
32096 ++ __u16 resmask;
32097 ++
32098 ++ __u8 user_trans_type;
32099 ++ __u8 group_trans_type;
32100 ++ uid_t *user_transitions;
32101 ++ gid_t *group_transitions;
32102 ++ __u16 user_trans_num;
32103 ++ __u16 group_trans_num;
32104 ++
32105 ++ __u32 ip_proto[8];
32106 ++ __u32 ip_type;
32107 ++ struct acl_ip_label **ips;
32108 ++ __u32 ip_num;
32109 ++
32110 ++ __u32 crashes;
32111 ++ unsigned long expires;
32112 ++
32113 ++ struct acl_subject_label *parent_subject;
32114 ++ struct gr_hash_struct *hash;
32115 ++ struct acl_subject_label *prev;
32116 ++ struct acl_subject_label *next;
32117 ++
32118 ++ struct acl_object_label **obj_hash;
32119 ++ __u32 obj_hash_size;
32120 ++ __u16 pax_flags;
32121 ++};
32122 ++
32123 ++struct role_allowed_ip {
32124 ++ __u32 addr;
32125 ++ __u32 netmask;
32126 ++
32127 ++ struct role_allowed_ip *prev;
32128 ++ struct role_allowed_ip *next;
32129 ++};
32130 ++
32131 ++struct role_transition {
32132 ++ char *rolename;
32133 ++
32134 ++ struct role_transition *prev;
32135 ++ struct role_transition *next;
32136 ++};
32137 ++
32138 ++struct acl_role_label {
32139 ++ char *rolename;
32140 ++ uid_t uidgid;
32141 ++ __u16 roletype;
32142 ++
32143 ++ __u16 auth_attempts;
32144 ++ unsigned long expires;
32145 ++
32146 ++ struct acl_subject_label *root_label;
32147 ++ struct gr_hash_struct *hash;
32148 ++
32149 ++ struct acl_role_label *prev;
32150 ++ struct acl_role_label *next;
32151 ++
32152 ++ struct role_transition *transitions;
32153 ++ struct role_allowed_ip *allowed_ips;
32154 ++ uid_t *domain_children;
32155 ++ __u16 domain_child_num;
32156 ++
32157 ++ struct acl_subject_label **subj_hash;
32158 ++ __u32 subj_hash_size;
32159 ++};
32160 ++
32161 ++struct user_acl_role_db {
32162 ++ struct acl_role_label **r_table;
32163 ++ __u32 num_pointers; /* Number of allocations to track */
32164 ++ __u32 num_roles; /* Number of roles */
32165 ++ __u32 num_domain_children; /* Number of domain children */
32166 ++ __u32 num_subjects; /* Number of subjects */
32167 ++ __u32 num_objects; /* Number of objects */
32168 ++};
32169 ++
32170 ++struct acl_object_label {
32171 ++ char *filename;
32172 ++ ino_t inode;
32173 ++ dev_t device;
32174 ++ __u32 mode;
32175 ++
32176 ++ struct acl_subject_label *nested;
32177 ++ struct acl_object_label *globbed;
32178 ++
32179 ++ /* next two structures not used */
32180 ++
32181 ++ struct acl_object_label *prev;
32182 ++ struct acl_object_label *next;
32183 ++};
32184 ++
32185 ++struct acl_ip_label {
32186 ++ char *iface;
32187 ++ __u32 addr;
32188 ++ __u32 netmask;
32189 ++ __u16 low, high;
32190 ++ __u8 mode;
32191 ++ __u32 type;
32192 ++ __u32 proto[8];
32193 ++
32194 ++ /* next two structures not used */
32195 ++
32196 ++ struct acl_ip_label *prev;
32197 ++ struct acl_ip_label *next;
32198 ++};
32199 ++
32200 ++struct gr_arg {
32201 ++ struct user_acl_role_db role_db;
32202 ++ unsigned char pw[GR_PW_LEN];
32203 ++ unsigned char salt[GR_SALT_LEN];
32204 ++ unsigned char sum[GR_SHA_LEN];
32205 ++ unsigned char sp_role[GR_SPROLE_LEN];
32206 ++ struct sprole_pw *sprole_pws;
32207 ++ dev_t segv_device;
32208 ++ ino_t segv_inode;
32209 ++ uid_t segv_uid;
32210 ++ __u16 num_sprole_pws;
32211 ++ __u16 mode;
32212 ++};
32213 ++
32214 ++struct gr_arg_wrapper {
32215 ++ struct gr_arg *arg;
32216 ++ __u32 version;
32217 ++ __u32 size;
32218 ++};
32219 ++
32220 ++struct subject_map {
32221 ++ struct acl_subject_label *user;
32222 ++ struct acl_subject_label *kernel;
32223 ++ struct subject_map *prev;
32224 ++ struct subject_map *next;
32225 ++};
32226 ++
32227 ++struct acl_subj_map_db {
32228 ++ struct subject_map **s_hash;
32229 ++ __u32 s_size;
32230 ++};
32231 ++
32232 ++/* End Data Structures Section */
32233 ++
32234 ++/* Hash functions generated by empirical testing by Brad Spengler
32235 ++ Makes good use of the low bits of the inode. Generally 0-1 times
32236 ++ in loop for successful match. 0-3 for unsuccessful match.
32237 ++ Shift/add algorithm with modulus of table size and an XOR*/
32238 ++
32239 ++static __inline__ unsigned int
32240 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
32241 ++{
32242 ++ return (((uid << type) + (uid ^ type)) % sz);
32243 ++}
32244 ++
32245 ++ static __inline__ unsigned int
32246 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
32247 ++{
32248 ++ return ((const unsigned long)userp % sz);
32249 ++}
32250 ++
32251 ++static __inline__ unsigned int
32252 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
32253 ++{
32254 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
32255 ++}
32256 ++
32257 ++static __inline__ unsigned int
32258 ++nhash(const char *name, const __u16 len, const unsigned int sz)
32259 ++{
32260 ++ return full_name_hash(name, len) % sz;
32261 ++}
32262 ++
32263 ++#define FOR_EACH_ROLE_START(role,iter) \
32264 ++ role = NULL; \
32265 ++ iter = 0; \
32266 ++ while (iter < acl_role_set.r_size) { \
32267 ++ if (role == NULL) \
32268 ++ role = acl_role_set.r_hash[iter]; \
32269 ++ if (role == NULL) { \
32270 ++ iter++; \
32271 ++ continue; \
32272 ++ }
32273 ++
32274 ++#define FOR_EACH_ROLE_END(role,iter) \
32275 ++ role = role->next; \
32276 ++ if (role == NULL) \
32277 ++ iter++; \
32278 ++ }
32279 ++
32280 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
32281 ++ subj = NULL; \
32282 ++ iter = 0; \
32283 ++ while (iter < role->subj_hash_size) { \
32284 ++ if (subj == NULL) \
32285 ++ subj = role->subj_hash[iter]; \
32286 ++ if (subj == NULL) { \
32287 ++ iter++; \
32288 ++ continue; \
32289 ++ }
32290 ++
32291 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
32292 ++ subj = subj->next; \
32293 ++ if (subj == NULL) \
32294 ++ iter++; \
32295 ++ }
32296 ++
32297 ++
32298 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
32299 ++ subj = role->hash->first; \
32300 ++ while (subj != NULL) {
32301 ++
32302 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
32303 ++ subj = subj->next; \
32304 ++ }
32305 ++
32306 ++#endif
32307 ++
32308 +diff -urNp linux-2.6.26.6/include/linux/gralloc.h linux-2.6.26.6/include/linux/gralloc.h
32309 +--- linux-2.6.26.6/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
32310 ++++ linux-2.6.26.6/include/linux/gralloc.h 2008-10-11 21:54:20.000000000 -0400
32311 +@@ -0,0 +1,8 @@
32312 ++#ifndef __GRALLOC_H
32313 ++#define __GRALLOC_H
32314 ++
32315 ++void acl_free_all(void);
32316 ++int acl_alloc_stack_init(unsigned long size);
32317 ++void *acl_alloc(unsigned long len);
32318 ++
32319 ++#endif
32320 +diff -urNp linux-2.6.26.6/include/linux/grdefs.h linux-2.6.26.6/include/linux/grdefs.h
32321 +--- linux-2.6.26.6/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
32322 ++++ linux-2.6.26.6/include/linux/grdefs.h 2008-10-11 21:54:20.000000000 -0400
32323 +@@ -0,0 +1,131 @@
32324 ++#ifndef GRDEFS_H
32325 ++#define GRDEFS_H
32326 ++
32327 ++/* Begin grsecurity status declarations */
32328 ++
32329 ++enum {
32330 ++ GR_READY = 0x01,
32331 ++ GR_STATUS_INIT = 0x00 // disabled state
32332 ++};
32333 ++
32334 ++/* Begin ACL declarations */
32335 ++
32336 ++/* Role flags */
32337 ++
32338 ++enum {
32339 ++ GR_ROLE_USER = 0x0001,
32340 ++ GR_ROLE_GROUP = 0x0002,
32341 ++ GR_ROLE_DEFAULT = 0x0004,
32342 ++ GR_ROLE_SPECIAL = 0x0008,
32343 ++ GR_ROLE_AUTH = 0x0010,
32344 ++ GR_ROLE_NOPW = 0x0020,
32345 ++ GR_ROLE_GOD = 0x0040,
32346 ++ GR_ROLE_LEARN = 0x0080,
32347 ++ GR_ROLE_TPE = 0x0100,
32348 ++ GR_ROLE_DOMAIN = 0x0200,
32349 ++ GR_ROLE_PAM = 0x0400
32350 ++};
32351 ++
32352 ++/* ACL Subject and Object mode flags */
32353 ++enum {
32354 ++ GR_DELETED = 0x80000000
32355 ++};
32356 ++
32357 ++/* ACL Object-only mode flags */
32358 ++enum {
32359 ++ GR_READ = 0x00000001,
32360 ++ GR_APPEND = 0x00000002,
32361 ++ GR_WRITE = 0x00000004,
32362 ++ GR_EXEC = 0x00000008,
32363 ++ GR_FIND = 0x00000010,
32364 ++ GR_INHERIT = 0x00000020,
32365 ++ GR_SETID = 0x00000040,
32366 ++ GR_CREATE = 0x00000080,
32367 ++ GR_DELETE = 0x00000100,
32368 ++ GR_LINK = 0x00000200,
32369 ++ GR_AUDIT_READ = 0x00000400,
32370 ++ GR_AUDIT_APPEND = 0x00000800,
32371 ++ GR_AUDIT_WRITE = 0x00001000,
32372 ++ GR_AUDIT_EXEC = 0x00002000,
32373 ++ GR_AUDIT_FIND = 0x00004000,
32374 ++ GR_AUDIT_INHERIT= 0x00008000,
32375 ++ GR_AUDIT_SETID = 0x00010000,
32376 ++ GR_AUDIT_CREATE = 0x00020000,
32377 ++ GR_AUDIT_DELETE = 0x00040000,
32378 ++ GR_AUDIT_LINK = 0x00080000,
32379 ++ GR_PTRACERD = 0x00100000,
32380 ++ GR_NOPTRACE = 0x00200000,
32381 ++ GR_SUPPRESS = 0x00400000,
32382 ++ GR_NOLEARN = 0x00800000
32383 ++};
32384 ++
32385 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
32386 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
32387 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
32388 ++
32389 ++/* ACL subject-only mode flags */
32390 ++enum {
32391 ++ GR_KILL = 0x00000001,
32392 ++ GR_VIEW = 0x00000002,
32393 ++ GR_PROTECTED = 0x00000004,
32394 ++ GR_LEARN = 0x00000008,
32395 ++ GR_OVERRIDE = 0x00000010,
32396 ++ /* just a placeholder, this mode is only used in userspace */
32397 ++ GR_DUMMY = 0x00000020,
32398 ++ GR_PROTSHM = 0x00000040,
32399 ++ GR_KILLPROC = 0x00000080,
32400 ++ GR_KILLIPPROC = 0x00000100,
32401 ++ /* just a placeholder, this mode is only used in userspace */
32402 ++ GR_NOTROJAN = 0x00000200,
32403 ++ GR_PROTPROCFD = 0x00000400,
32404 ++ GR_PROCACCT = 0x00000800,
32405 ++ GR_RELAXPTRACE = 0x00001000,
32406 ++ GR_NESTED = 0x00002000,
32407 ++ GR_INHERITLEARN = 0x00004000,
32408 ++ GR_PROCFIND = 0x00008000,
32409 ++ GR_POVERRIDE = 0x00010000,
32410 ++ GR_KERNELAUTH = 0x00020000,
32411 ++};
32412 ++
32413 ++enum {
32414 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
32415 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
32416 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
32417 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
32418 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
32419 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
32420 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
32421 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
32422 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
32423 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
32424 ++};
32425 ++
32426 ++enum {
32427 ++ GR_ID_USER = 0x01,
32428 ++ GR_ID_GROUP = 0x02,
32429 ++};
32430 ++
32431 ++enum {
32432 ++ GR_ID_ALLOW = 0x01,
32433 ++ GR_ID_DENY = 0x02,
32434 ++};
32435 ++
32436 ++#define GR_CRASH_RES 11
32437 ++#define GR_UIDTABLE_MAX 500
32438 ++
32439 ++/* begin resource learning section */
32440 ++enum {
32441 ++ GR_RLIM_CPU_BUMP = 60,
32442 ++ GR_RLIM_FSIZE_BUMP = 50000,
32443 ++ GR_RLIM_DATA_BUMP = 10000,
32444 ++ GR_RLIM_STACK_BUMP = 1000,
32445 ++ GR_RLIM_CORE_BUMP = 10000,
32446 ++ GR_RLIM_RSS_BUMP = 500000,
32447 ++ GR_RLIM_NPROC_BUMP = 1,
32448 ++ GR_RLIM_NOFILE_BUMP = 5,
32449 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
32450 ++ GR_RLIM_AS_BUMP = 500000,
32451 ++ GR_RLIM_LOCKS_BUMP = 2
32452 ++};
32453 ++
32454 ++#endif
32455 +diff -urNp linux-2.6.26.6/include/linux/grinternal.h linux-2.6.26.6/include/linux/grinternal.h
32456 +--- linux-2.6.26.6/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
32457 ++++ linux-2.6.26.6/include/linux/grinternal.h 2008-10-11 21:54:20.000000000 -0400
32458 +@@ -0,0 +1,210 @@
32459 ++#ifndef __GRINTERNAL_H
32460 ++#define __GRINTERNAL_H
32461 ++
32462 ++#ifdef CONFIG_GRKERNSEC
32463 ++
32464 ++#include <linux/fs.h>
32465 ++#include <linux/gracl.h>
32466 ++#include <linux/grdefs.h>
32467 ++#include <linux/grmsg.h>
32468 ++
32469 ++void gr_add_learn_entry(const char *fmt, ...);
32470 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
32471 ++ const struct vfsmount *mnt);
32472 ++__u32 gr_check_create(const struct dentry *new_dentry,
32473 ++ const struct dentry *parent,
32474 ++ const struct vfsmount *mnt, const __u32 mode);
32475 ++int gr_check_protected_task(const struct task_struct *task);
32476 ++__u32 to_gr_audit(const __u32 reqmode);
32477 ++int gr_set_acls(const int type);
32478 ++
32479 ++int gr_acl_is_enabled(void);
32480 ++char gr_roletype_to_char(void);
32481 ++
32482 ++void gr_handle_alertkill(struct task_struct *task);
32483 ++char *gr_to_filename(const struct dentry *dentry,
32484 ++ const struct vfsmount *mnt);
32485 ++char *gr_to_filename1(const struct dentry *dentry,
32486 ++ const struct vfsmount *mnt);
32487 ++char *gr_to_filename2(const struct dentry *dentry,
32488 ++ const struct vfsmount *mnt);
32489 ++char *gr_to_filename3(const struct dentry *dentry,
32490 ++ const struct vfsmount *mnt);
32491 ++
32492 ++extern int grsec_enable_link;
32493 ++extern int grsec_enable_fifo;
32494 ++extern int grsec_enable_execve;
32495 ++extern int grsec_enable_shm;
32496 ++extern int grsec_enable_execlog;
32497 ++extern int grsec_enable_signal;
32498 ++extern int grsec_enable_forkfail;
32499 ++extern int grsec_enable_time;
32500 ++extern int grsec_enable_chroot_shmat;
32501 ++extern int grsec_enable_chroot_findtask;
32502 ++extern int grsec_enable_chroot_mount;
32503 ++extern int grsec_enable_chroot_double;
32504 ++extern int grsec_enable_chroot_pivot;
32505 ++extern int grsec_enable_chroot_chdir;
32506 ++extern int grsec_enable_chroot_chmod;
32507 ++extern int grsec_enable_chroot_mknod;
32508 ++extern int grsec_enable_chroot_fchdir;
32509 ++extern int grsec_enable_chroot_nice;
32510 ++extern int grsec_enable_chroot_execlog;
32511 ++extern int grsec_enable_chroot_caps;
32512 ++extern int grsec_enable_chroot_sysctl;
32513 ++extern int grsec_enable_chroot_unix;
32514 ++extern int grsec_enable_tpe;
32515 ++extern int grsec_tpe_gid;
32516 ++extern int grsec_enable_tpe_all;
32517 ++extern int grsec_enable_sidcaps;
32518 ++extern int grsec_enable_socket_all;
32519 ++extern int grsec_socket_all_gid;
32520 ++extern int grsec_enable_socket_client;
32521 ++extern int grsec_socket_client_gid;
32522 ++extern int grsec_enable_socket_server;
32523 ++extern int grsec_socket_server_gid;
32524 ++extern int grsec_audit_gid;
32525 ++extern int grsec_enable_group;
32526 ++extern int grsec_enable_audit_ipc;
32527 ++extern int grsec_enable_audit_textrel;
32528 ++extern int grsec_enable_mount;
32529 ++extern int grsec_enable_chdir;
32530 ++extern int grsec_resource_logging;
32531 ++extern int grsec_lock;
32532 ++
32533 ++extern spinlock_t grsec_alert_lock;
32534 ++extern unsigned long grsec_alert_wtime;
32535 ++extern unsigned long grsec_alert_fyet;
32536 ++
32537 ++extern spinlock_t grsec_audit_lock;
32538 ++
32539 ++extern rwlock_t grsec_exec_file_lock;
32540 ++
32541 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
32542 ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \
32543 ++ tsk->exec_file->f_vfsmnt) : "/")
32544 ++
32545 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
32546 ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
32547 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
32548 ++
32549 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
32550 ++ gr_to_filename(tsk->exec_file->f_path.dentry, \
32551 ++ tsk->exec_file->f_vfsmnt) : "/")
32552 ++
32553 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
32554 ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
32555 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
32556 ++
32557 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
32558 ++ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
32559 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
32560 ++ (tsk_a->fs->root.dentry->d_inode->i_ino != \
32561 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
32562 ++
32563 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
32564 ++ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
32565 ++ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
32566 ++ (tsk_a->fs->root.dentry->d_inode->i_ino == \
32567 ++ tsk_b->fs->root.dentry->d_inode->i_ino))
32568 ++
32569 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
32570 ++ task->pid, task->uid, \
32571 ++ task->euid, task->gid, task->egid, \
32572 ++ gr_parent_task_fullpath(task), \
32573 ++ task->parent->comm, task->parent->pid, \
32574 ++ task->parent->uid, task->parent->euid, \
32575 ++ task->parent->gid, task->parent->egid
32576 ++
32577 ++#define GR_CHROOT_CAPS {{ \
32578 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
32579 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
32580 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
32581 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
32582 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
32583 ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
32584 ++
32585 ++#define security_learn(normal_msg,args...) \
32586 ++({ \
32587 ++ read_lock(&grsec_exec_file_lock); \
32588 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
32589 ++ read_unlock(&grsec_exec_file_lock); \
32590 ++})
32591 ++
32592 ++enum {
32593 ++ GR_DO_AUDIT,
32594 ++ GR_DONT_AUDIT,
32595 ++ GR_DONT_AUDIT_GOOD
32596 ++};
32597 ++
32598 ++enum {
32599 ++ GR_TTYSNIFF,
32600 ++ GR_RBAC,
32601 ++ GR_RBAC_STR,
32602 ++ GR_STR_RBAC,
32603 ++ GR_RBAC_MODE2,
32604 ++ GR_RBAC_MODE3,
32605 ++ GR_FILENAME,
32606 ++ GR_SYSCTL_HIDDEN,
32607 ++ GR_NOARGS,
32608 ++ GR_ONE_INT,
32609 ++ GR_ONE_INT_TWO_STR,
32610 ++ GR_ONE_STR,
32611 ++ GR_STR_INT,
32612 ++ GR_TWO_INT,
32613 ++ GR_THREE_INT,
32614 ++ GR_FIVE_INT_TWO_STR,
32615 ++ GR_TWO_STR,
32616 ++ GR_THREE_STR,
32617 ++ GR_FOUR_STR,
32618 ++ GR_STR_FILENAME,
32619 ++ GR_FILENAME_STR,
32620 ++ GR_FILENAME_TWO_INT,
32621 ++ GR_FILENAME_TWO_INT_STR,
32622 ++ GR_TEXTREL,
32623 ++ GR_PTRACE,
32624 ++ GR_RESOURCE,
32625 ++ GR_CAP,
32626 ++ GR_SIG,
32627 ++ GR_CRASH1,
32628 ++ GR_CRASH2,
32629 ++ GR_PSACCT
32630 ++};
32631 ++
32632 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
32633 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
32634 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
32635 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
32636 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
32637 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
32638 ++#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)
32639 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
32640 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
32641 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
32642 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
32643 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
32644 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
32645 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
32646 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
32647 ++#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)
32648 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
32649 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
32650 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
32651 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
32652 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
32653 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
32654 ++#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)
32655 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
32656 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
32657 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
32658 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
32659 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
32660 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
32661 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
32662 ++#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)
32663 ++
32664 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
32665 ++
32666 ++#endif
32667 ++
32668 ++#endif
32669 +diff -urNp linux-2.6.26.6/include/linux/grmsg.h linux-2.6.26.6/include/linux/grmsg.h
32670 +--- linux-2.6.26.6/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
32671 ++++ linux-2.6.26.6/include/linux/grmsg.h 2008-10-11 21:54:20.000000000 -0400
32672 +@@ -0,0 +1,108 @@
32673 ++#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"
32674 ++#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"
32675 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
32676 ++#define GR_STOPMOD_MSG "denied modification of module state by "
32677 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
32678 ++#define GR_IOPL_MSG "denied use of iopl() by "
32679 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
32680 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
32681 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
32682 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
32683 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
32684 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
32685 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
32686 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
32687 ++#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"
32688 ++#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"
32689 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
32690 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
32691 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
32692 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
32693 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
32694 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
32695 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
32696 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
32697 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
32698 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
32699 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
32700 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
32701 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
32702 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
32703 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
32704 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
32705 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
32706 ++#define GR_NPROC_MSG "denied overstep of process limit by "
32707 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
32708 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
32709 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
32710 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
32711 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
32712 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
32713 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
32714 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
32715 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
32716 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
32717 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
32718 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
32719 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
32720 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
32721 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
32722 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
32723 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
32724 ++#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"
32725 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
32726 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
32727 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
32728 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
32729 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
32730 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
32731 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
32732 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
32733 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
32734 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
32735 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
32736 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
32737 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
32738 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
32739 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
32740 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
32741 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
32742 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
32743 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
32744 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
32745 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
32746 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
32747 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
32748 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
32749 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
32750 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
32751 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
32752 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
32753 ++#define GR_TIME_MSG "time set by "
32754 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
32755 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
32756 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
32757 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
32758 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
32759 ++#define GR_BIND_MSG "denied bind() by "
32760 ++#define GR_CONNECT_MSG "denied connect() by "
32761 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
32762 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
32763 ++#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"
32764 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
32765 ++#define GR_CAP_ACL_MSG "use of %s denied for "
32766 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
32767 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
32768 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
32769 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
32770 ++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
32771 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
32772 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
32773 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
32774 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
32775 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
32776 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
32777 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
32778 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
32779 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
32780 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
32781 +diff -urNp linux-2.6.26.6/include/linux/grsecurity.h linux-2.6.26.6/include/linux/grsecurity.h
32782 +--- linux-2.6.26.6/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
32783 ++++ linux-2.6.26.6/include/linux/grsecurity.h 2008-10-11 21:54:20.000000000 -0400
32784 +@@ -0,0 +1,200 @@
32785 ++#ifndef GR_SECURITY_H
32786 ++#define GR_SECURITY_H
32787 ++#include <linux/fs.h>
32788 ++#include <linux/binfmts.h>
32789 ++#include <linux/gracl.h>
32790 ++
32791 ++/* notify of brain-dead configs */
32792 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
32793 ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
32794 ++#endif
32795 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
32796 ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
32797 ++#endif
32798 ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
32799 ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
32800 ++#endif
32801 ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
32802 ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
32803 ++#endif
32804 ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
32805 ++#error "CONFIG_PAX enabled, but no PaX options are enabled."
32806 ++#endif
32807 ++
32808 ++void gr_handle_brute_attach(struct task_struct *p);
32809 ++void gr_handle_brute_check(void);
32810 ++
32811 ++char gr_roletype_to_char(void);
32812 ++
32813 ++int gr_check_user_change(int real, int effective, int fs);
32814 ++int gr_check_group_change(int real, int effective, int fs);
32815 ++
32816 ++void gr_del_task_from_ip_table(struct task_struct *p);
32817 ++
32818 ++int gr_pid_is_chrooted(struct task_struct *p);
32819 ++int gr_handle_chroot_nice(void);
32820 ++int gr_handle_chroot_sysctl(const int op);
32821 ++int gr_handle_chroot_setpriority(struct task_struct *p,
32822 ++ const int niceval);
32823 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
32824 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
32825 ++ const struct vfsmount *mnt);
32826 ++void gr_handle_chroot_caps(struct task_struct *task);
32827 ++void gr_handle_chroot_chdir(struct path *path);
32828 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
32829 ++ const struct vfsmount *mnt, const int mode);
32830 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
32831 ++ const struct vfsmount *mnt, const int mode);
32832 ++int gr_handle_chroot_mount(const struct dentry *dentry,
32833 ++ const struct vfsmount *mnt,
32834 ++ const char *dev_name);
32835 ++int gr_handle_chroot_pivot(void);
32836 ++int gr_handle_chroot_unix(const pid_t pid);
32837 ++
32838 ++int gr_handle_rawio(const struct inode *inode);
32839 ++int gr_handle_nproc(void);
32840 ++
32841 ++void gr_handle_ioperm(void);
32842 ++void gr_handle_iopl(void);
32843 ++
32844 ++int gr_tpe_allow(const struct file *file);
32845 ++
32846 ++int gr_random_pid(void);
32847 ++
32848 ++void gr_log_forkfail(const int retval);
32849 ++void gr_log_timechange(void);
32850 ++void gr_log_signal(const int sig, const struct task_struct *t);
32851 ++void gr_log_chdir(const struct dentry *dentry,
32852 ++ const struct vfsmount *mnt);
32853 ++void gr_log_chroot_exec(const struct dentry *dentry,
32854 ++ const struct vfsmount *mnt);
32855 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
32856 ++void gr_log_remount(const char *devname, const int retval);
32857 ++void gr_log_unmount(const char *devname, const int retval);
32858 ++void gr_log_mount(const char *from, const char *to, const int retval);
32859 ++void gr_log_msgget(const int ret, const int msgflg);
32860 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
32861 ++void gr_log_semget(const int err, const int semflg);
32862 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
32863 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
32864 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
32865 ++void gr_log_textrel(struct vm_area_struct *vma);
32866 ++
32867 ++int gr_handle_follow_link(const struct inode *parent,
32868 ++ const struct inode *inode,
32869 ++ const struct dentry *dentry,
32870 ++ const struct vfsmount *mnt);
32871 ++int gr_handle_fifo(const struct dentry *dentry,
32872 ++ const struct vfsmount *mnt,
32873 ++ const struct dentry *dir, const int flag,
32874 ++ const int acc_mode);
32875 ++int gr_handle_hardlink(const struct dentry *dentry,
32876 ++ const struct vfsmount *mnt,
32877 ++ struct inode *inode,
32878 ++ const int mode, const char *to);
32879 ++
32880 ++int gr_task_is_capable(struct task_struct *task, const int cap);
32881 ++int gr_is_capable_nolog(const int cap);
32882 ++void gr_learn_resource(const struct task_struct *task, const int limit,
32883 ++ const unsigned long wanted, const int gt);
32884 ++void gr_copy_label(struct task_struct *tsk);
32885 ++void gr_handle_crash(struct task_struct *task, const int sig);
32886 ++int gr_handle_signal(const struct task_struct *p, const int sig);
32887 ++int gr_check_crash_uid(const uid_t uid);
32888 ++int gr_check_protected_task(const struct task_struct *task);
32889 ++int gr_acl_handle_mmap(const struct file *file,
32890 ++ const unsigned long prot);
32891 ++int gr_acl_handle_mprotect(const struct file *file,
32892 ++ const unsigned long prot);
32893 ++int gr_check_hidden_task(const struct task_struct *tsk);
32894 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
32895 ++ const struct vfsmount *mnt);
32896 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
32897 ++ const struct vfsmount *mnt);
32898 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
32899 ++ const struct vfsmount *mnt, const int fmode);
32900 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
32901 ++ const struct vfsmount *mnt, mode_t mode);
32902 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
32903 ++ const struct vfsmount *mnt, mode_t mode);
32904 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
32905 ++ const struct vfsmount *mnt);
32906 ++int gr_handle_ptrace(struct task_struct *task, const long request);
32907 ++int gr_handle_proc_ptrace(struct task_struct *task);
32908 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
32909 ++ const struct vfsmount *mnt);
32910 ++int gr_check_crash_exec(const struct file *filp);
32911 ++int gr_acl_is_enabled(void);
32912 ++void gr_set_kernel_label(struct task_struct *task);
32913 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
32914 ++ const gid_t gid);
32915 ++int gr_set_proc_label(const struct dentry *dentry,
32916 ++ const struct vfsmount *mnt);
32917 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
32918 ++ const struct vfsmount *mnt);
32919 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
32920 ++ const struct vfsmount *mnt, const int fmode);
32921 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
32922 ++ const struct dentry *p_dentry,
32923 ++ const struct vfsmount *p_mnt, const int fmode,
32924 ++ const int imode);
32925 ++void gr_handle_create(const struct dentry *dentry,
32926 ++ const struct vfsmount *mnt);
32927 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
32928 ++ const struct dentry *parent_dentry,
32929 ++ const struct vfsmount *parent_mnt,
32930 ++ const int mode);
32931 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
32932 ++ const struct dentry *parent_dentry,
32933 ++ const struct vfsmount *parent_mnt);
32934 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
32935 ++ const struct vfsmount *mnt);
32936 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
32937 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
32938 ++ const struct vfsmount *mnt);
32939 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
32940 ++ const struct dentry *parent_dentry,
32941 ++ const struct vfsmount *parent_mnt,
32942 ++ const char *from);
32943 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
32944 ++ const struct dentry *parent_dentry,
32945 ++ const struct vfsmount *parent_mnt,
32946 ++ const struct dentry *old_dentry,
32947 ++ const struct vfsmount *old_mnt, const char *to);
32948 ++int gr_acl_handle_rename(struct dentry *new_dentry,
32949 ++ struct dentry *parent_dentry,
32950 ++ const struct vfsmount *parent_mnt,
32951 ++ struct dentry *old_dentry,
32952 ++ struct inode *old_parent_inode,
32953 ++ struct vfsmount *old_mnt, const char *newname);
32954 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
32955 ++ struct dentry *old_dentry,
32956 ++ struct dentry *new_dentry,
32957 ++ struct vfsmount *mnt, const __u8 replace);
32958 ++__u32 gr_check_link(const struct dentry *new_dentry,
32959 ++ const struct dentry *parent_dentry,
32960 ++ const struct vfsmount *parent_mnt,
32961 ++ const struct dentry *old_dentry,
32962 ++ const struct vfsmount *old_mnt);
32963 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
32964 ++ const unsigned int namelen, const ino_t ino);
32965 ++
32966 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
32967 ++ const struct vfsmount *mnt);
32968 ++void gr_acl_handle_exit(void);
32969 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
32970 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
32971 ++
32972 ++#ifdef CONFIG_GRKERNSEC
32973 ++void gr_handle_mem_write(void);
32974 ++void gr_handle_kmem_write(void);
32975 ++void gr_handle_open_port(void);
32976 ++int gr_handle_mem_mmap(const unsigned long offset,
32977 ++ struct vm_area_struct *vma);
32978 ++
32979 ++extern int grsec_enable_dmesg;
32980 ++extern int grsec_enable_randsrc;
32981 ++extern int grsec_enable_shm;
32982 ++#endif
32983 ++
32984 ++#endif
32985 +diff -urNp linux-2.6.26.6/include/linux/highmem.h linux-2.6.26.6/include/linux/highmem.h
32986 +--- linux-2.6.26.6/include/linux/highmem.h 2008-10-08 23:24:05.000000000 -0400
32987 ++++ linux-2.6.26.6/include/linux/highmem.h 2008-10-11 21:54:20.000000000 -0400
32988 +@@ -122,6 +122,13 @@ static inline void clear_highpage(struct
32989 + kunmap_atomic(kaddr, KM_USER0);
32990 + }
32991 +
32992 ++static inline void sanitize_highpage(struct page *page)
32993 ++{
32994 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
32995 ++ clear_page(kaddr);
32996 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
32997 ++}
32998 ++
32999 + static inline void zero_user_segments(struct page *page,
33000 + unsigned start1, unsigned end1,
33001 + unsigned start2, unsigned end2)
33002 +diff -urNp linux-2.6.26.6/include/linux/jbd2.h linux-2.6.26.6/include/linux/jbd2.h
33003 +--- linux-2.6.26.6/include/linux/jbd2.h 2008-10-08 23:24:05.000000000 -0400
33004 ++++ linux-2.6.26.6/include/linux/jbd2.h 2008-10-11 21:54:20.000000000 -0400
33005 +@@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
33006 + } \
33007 + } while (0)
33008 + #else
33009 +-#define jbd_debug(f, a...) /**/
33010 ++#define jbd_debug(f, a...) do {} while (0)
33011 + #endif
33012 +
33013 + static inline void *jbd2_alloc(size_t size, gfp_t flags)
33014 +diff -urNp linux-2.6.26.6/include/linux/jbd.h linux-2.6.26.6/include/linux/jbd.h
33015 +--- linux-2.6.26.6/include/linux/jbd.h 2008-10-08 23:24:05.000000000 -0400
33016 ++++ linux-2.6.26.6/include/linux/jbd.h 2008-10-11 21:54:20.000000000 -0400
33017 +@@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
33018 + } \
33019 + } while (0)
33020 + #else
33021 +-#define jbd_debug(f, a...) /**/
33022 ++#define jbd_debug(f, a...) do {} while (0)
33023 + #endif
33024 +
33025 + static inline void *jbd_alloc(size_t size, gfp_t flags)
33026 +diff -urNp linux-2.6.26.6/include/linux/libata.h linux-2.6.26.6/include/linux/libata.h
33027 +--- linux-2.6.26.6/include/linux/libata.h 2008-10-08 23:24:05.000000000 -0400
33028 ++++ linux-2.6.26.6/include/linux/libata.h 2008-10-11 21:54:20.000000000 -0400
33029 +@@ -63,11 +63,11 @@
33030 + #ifdef ATA_VERBOSE_DEBUG
33031 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
33032 + #else
33033 +-#define VPRINTK(fmt, args...)
33034 ++#define VPRINTK(fmt, args...) do {} while (0)
33035 + #endif /* ATA_VERBOSE_DEBUG */
33036 + #else
33037 +-#define DPRINTK(fmt, args...)
33038 +-#define VPRINTK(fmt, args...)
33039 ++#define DPRINTK(fmt, args...) do {} while (0)
33040 ++#define VPRINTK(fmt, args...) do {} while (0)
33041 + #endif /* ATA_DEBUG */
33042 +
33043 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
33044 +diff -urNp linux-2.6.26.6/include/linux/mm.h linux-2.6.26.6/include/linux/mm.h
33045 +--- linux-2.6.26.6/include/linux/mm.h 2008-10-08 23:24:05.000000000 -0400
33046 ++++ linux-2.6.26.6/include/linux/mm.h 2008-10-11 21:54:20.000000000 -0400
33047 +@@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
33048 + #include <asm/page.h>
33049 + #include <asm/pgtable.h>
33050 + #include <asm/processor.h>
33051 ++#include <asm/mman.h>
33052 +
33053 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
33054 +
33055 +@@ -109,6 +110,14 @@ extern unsigned int kobjsize(const void
33056 + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
33057 + #define VM_MIXEDMAP 0x10000000 /* Can contain "struct page" and pure PFN pages */
33058 +
33059 ++#ifdef CONFIG_PAX_PAGEEXEC
33060 ++#define VM_PAGEEXEC 0x20000000 /* vma->vm_page_prot needs special handling */
33061 ++#endif
33062 ++
33063 ++#ifdef CONFIG_PAX_MPROTECT
33064 ++#define VM_MAYNOTWRITE 0x40000000 /* vma cannot be granted VM_WRITE any more */
33065 ++#endif
33066 ++
33067 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
33068 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
33069 + #endif
33070 +@@ -858,6 +867,8 @@ struct shrinker {
33071 + extern void register_shrinker(struct shrinker *);
33072 + extern void unregister_shrinker(struct shrinker *);
33073 +
33074 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
33075 ++
33076 + int vma_wants_writenotify(struct vm_area_struct *vma);
33077 +
33078 + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
33079 +@@ -1109,6 +1120,7 @@ out:
33080 + }
33081 +
33082 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
33083 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
33084 +
33085 + extern unsigned long do_brk(unsigned long, unsigned long);
33086 +
33087 +@@ -1161,6 +1173,10 @@ extern struct vm_area_struct * find_vma(
33088 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
33089 + struct vm_area_struct **pprev);
33090 +
33091 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
33092 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
33093 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
33094 ++
33095 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
33096 + NULL if none. Assume start_addr < end_addr. */
33097 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
33098 +@@ -1177,7 +1193,6 @@ static inline unsigned long vma_pages(st
33099 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
33100 + }
33101 +
33102 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
33103 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
33104 + int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
33105 + unsigned long pfn, unsigned long size, pgprot_t);
33106 +@@ -1266,5 +1281,11 @@ int vmemmap_populate_basepages(struct pa
33107 + int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
33108 + void vmemmap_populate_print_last(void);
33109 +
33110 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
33111 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
33112 ++#else
33113 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
33114 ++#endif
33115 ++
33116 + #endif /* __KERNEL__ */
33117 + #endif /* _LINUX_MM_H */
33118 +diff -urNp linux-2.6.26.6/include/linux/mm_types.h linux-2.6.26.6/include/linux/mm_types.h
33119 +--- linux-2.6.26.6/include/linux/mm_types.h 2008-10-08 23:24:05.000000000 -0400
33120 ++++ linux-2.6.26.6/include/linux/mm_types.h 2008-10-11 21:54:20.000000000 -0400
33121 +@@ -157,6 +157,8 @@ struct vm_area_struct {
33122 + #ifdef CONFIG_NUMA
33123 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
33124 + #endif
33125 ++
33126 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
33127 + };
33128 +
33129 + struct mm_struct {
33130 +@@ -244,6 +246,24 @@ struct mm_struct {
33131 + struct file *exe_file;
33132 + unsigned long num_exe_file_vmas;
33133 + #endif
33134 ++
33135 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
33136 ++ unsigned long pax_flags;
33137 ++#endif
33138 ++
33139 ++#ifdef CONFIG_PAX_DLRESOLVE
33140 ++ unsigned long call_dl_resolve;
33141 ++#endif
33142 ++
33143 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
33144 ++ unsigned long call_syscall;
33145 ++#endif
33146 ++
33147 ++#ifdef CONFIG_PAX_ASLR
33148 ++ unsigned long delta_mmap; /* randomized offset */
33149 ++ unsigned long delta_stack; /* randomized offset */
33150 ++#endif
33151 ++
33152 + };
33153 +
33154 + #endif /* _LINUX_MM_TYPES_H */
33155 +diff -urNp linux-2.6.26.6/include/linux/module.h linux-2.6.26.6/include/linux/module.h
33156 +--- linux-2.6.26.6/include/linux/module.h 2008-10-08 23:24:05.000000000 -0400
33157 ++++ linux-2.6.26.6/include/linux/module.h 2008-10-11 21:54:20.000000000 -0400
33158 +@@ -279,16 +279,16 @@ struct module
33159 + int (*init)(void);
33160 +
33161 + /* If this is non-NULL, vfree after init() returns */
33162 +- void *module_init;
33163 ++ void *module_init_rx, *module_init_rw;
33164 +
33165 + /* Here is the actual code + data, vfree'd on unload. */
33166 +- void *module_core;
33167 ++ void *module_core_rx, *module_core_rw;
33168 +
33169 + /* Here are the sizes of the init and core sections */
33170 +- unsigned long init_size, core_size;
33171 ++ unsigned long init_size_rw, core_size_rw;
33172 +
33173 + /* The size of the executable code in each section. */
33174 +- unsigned long init_text_size, core_text_size;
33175 ++ unsigned long init_size_rx, core_size_rx;
33176 +
33177 + /* The handle returned from unwind_add_table. */
33178 + void *unwind_info;
33179 +diff -urNp linux-2.6.26.6/include/linux/moduleloader.h linux-2.6.26.6/include/linux/moduleloader.h
33180 +--- linux-2.6.26.6/include/linux/moduleloader.h 2008-10-08 23:24:05.000000000 -0400
33181 ++++ linux-2.6.26.6/include/linux/moduleloader.h 2008-10-11 21:54:20.000000000 -0400
33182 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
33183 + sections. Returns NULL on failure. */
33184 + void *module_alloc(unsigned long size);
33185 +
33186 ++#ifdef CONFIG_PAX_KERNEXEC
33187 ++void *module_alloc_exec(unsigned long size);
33188 ++#else
33189 ++#define module_alloc_exec(x) module_alloc(x)
33190 ++#endif
33191 ++
33192 + /* Free memory returned from module_alloc. */
33193 + void module_free(struct module *mod, void *module_region);
33194 +
33195 ++#ifdef CONFIG_PAX_KERNEXEC
33196 ++void module_free_exec(struct module *mod, void *module_region);
33197 ++#else
33198 ++#define module_free_exec(x, y) module_free(x, y)
33199 ++#endif
33200 ++
33201 + /* Apply the given relocation to the (simplified) ELF. Return -error
33202 + or 0. */
33203 + int apply_relocate(Elf_Shdr *sechdrs,
33204 +diff -urNp linux-2.6.26.6/include/linux/namei.h linux-2.6.26.6/include/linux/namei.h
33205 +--- linux-2.6.26.6/include/linux/namei.h 2008-10-08 23:24:05.000000000 -0400
33206 ++++ linux-2.6.26.6/include/linux/namei.h 2008-10-11 21:54:20.000000000 -0400
33207 +@@ -21,7 +21,7 @@ struct nameidata {
33208 + unsigned int flags;
33209 + int last_type;
33210 + unsigned depth;
33211 +- char *saved_names[MAX_NESTED_LINKS + 1];
33212 ++ const char *saved_names[MAX_NESTED_LINKS + 1];
33213 +
33214 + /* Intent data */
33215 + union {
33216 +@@ -83,12 +83,12 @@ extern int follow_up(struct vfsmount **,
33217 + extern struct dentry *lock_rename(struct dentry *, struct dentry *);
33218 + extern void unlock_rename(struct dentry *, struct dentry *);
33219 +
33220 +-static inline void nd_set_link(struct nameidata *nd, char *path)
33221 ++static inline void nd_set_link(struct nameidata *nd, const char *path)
33222 + {
33223 + nd->saved_names[nd->depth] = path;
33224 + }
33225 +
33226 +-static inline char *nd_get_link(struct nameidata *nd)
33227 ++static inline const char *nd_get_link(struct nameidata *nd)
33228 + {
33229 + return nd->saved_names[nd->depth];
33230 + }
33231 +diff -urNp linux-2.6.26.6/include/linux/nodemask.h linux-2.6.26.6/include/linux/nodemask.h
33232 +--- linux-2.6.26.6/include/linux/nodemask.h 2008-10-08 23:24:05.000000000 -0400
33233 ++++ linux-2.6.26.6/include/linux/nodemask.h 2008-10-11 21:55:52.000000000 -0400
33234 +@@ -442,11 +442,11 @@ static inline int num_node_state(enum no
33235 +
33236 + #define any_online_node(mask) \
33237 + ({ \
33238 +- int node; \
33239 +- for_each_node_mask(node, (mask)) \
33240 +- if (node_online(node)) \
33241 ++ int __node; \
33242 ++ for_each_node_mask(__node, (mask)) \
33243 ++ if (node_online(__node)) \
33244 + break; \
33245 +- node; \
33246 ++ __node; \
33247 + })
33248 +
33249 + #define num_online_nodes() num_node_state(N_ONLINE)
33250 +diff -urNp linux-2.6.26.6/include/linux/percpu.h linux-2.6.26.6/include/linux/percpu.h
33251 +--- linux-2.6.26.6/include/linux/percpu.h 2008-10-08 23:24:05.000000000 -0400
33252 ++++ linux-2.6.26.6/include/linux/percpu.h 2008-10-11 21:54:20.000000000 -0400
33253 +@@ -43,7 +43,7 @@
33254 + #endif
33255 +
33256 + #define PERCPU_ENOUGH_ROOM \
33257 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
33258 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
33259 + #endif /* PERCPU_ENOUGH_ROOM */
33260 +
33261 + /*
33262 +diff -urNp linux-2.6.26.6/include/linux/poison.h linux-2.6.26.6/include/linux/poison.h
33263 +--- linux-2.6.26.6/include/linux/poison.h 2008-10-08 23:24:05.000000000 -0400
33264 ++++ linux-2.6.26.6/include/linux/poison.h 2008-10-11 21:54:20.000000000 -0400
33265 +@@ -7,8 +7,8 @@
33266 + * under normal circumstances, used to verify that nobody uses
33267 + * non-initialized list entries.
33268 + */
33269 +-#define LIST_POISON1 ((void *) 0x00100100)
33270 +-#define LIST_POISON2 ((void *) 0x00200200)
33271 ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
33272 ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
33273 +
33274 + /********** include/linux/timer.h **********/
33275 + /*
33276 +diff -urNp linux-2.6.26.6/include/linux/random.h linux-2.6.26.6/include/linux/random.h
33277 +--- linux-2.6.26.6/include/linux/random.h 2008-10-08 23:24:05.000000000 -0400
33278 ++++ linux-2.6.26.6/include/linux/random.h 2008-10-11 21:54:20.000000000 -0400
33279 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
33280 + u32 random32(void);
33281 + void srandom32(u32 seed);
33282 +
33283 ++static inline unsigned long pax_get_random_long(void)
33284 ++{
33285 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
33286 ++}
33287 ++
33288 + #endif /* __KERNEL___ */
33289 +
33290 + #endif /* _LINUX_RANDOM_H */
33291 +diff -urNp linux-2.6.26.6/include/linux/sched.h linux-2.6.26.6/include/linux/sched.h
33292 +--- linux-2.6.26.6/include/linux/sched.h 2008-10-08 23:24:05.000000000 -0400
33293 ++++ linux-2.6.26.6/include/linux/sched.h 2008-10-11 21:54:20.000000000 -0400
33294 +@@ -95,6 +95,7 @@ struct exec_domain;
33295 + struct futex_pi_state;
33296 + struct robust_list_head;
33297 + struct bio;
33298 ++struct linux_binprm;
33299 +
33300 + /*
33301 + * List of flags we want to share for kernel threads,
33302 +@@ -542,6 +543,15 @@ struct signal_struct {
33303 + unsigned audit_tty;
33304 + struct tty_audit_buf *tty_audit_buf;
33305 + #endif
33306 ++
33307 ++#ifdef CONFIG_GRKERNSEC
33308 ++ u32 curr_ip;
33309 ++ u32 gr_saddr;
33310 ++ u32 gr_daddr;
33311 ++ u16 gr_sport;
33312 ++ u16 gr_dport;
33313 ++ u8 used_accept:1;
33314 ++#endif
33315 + };
33316 +
33317 + /* Context switch must be unlocked if interrupts are to be enabled */
33318 +@@ -1025,7 +1035,7 @@ struct sched_rt_entity {
33319 +
33320 + struct task_struct {
33321 + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
33322 +- void *stack;
33323 ++ struct thread_info *stack;
33324 + atomic_t usage;
33325 + unsigned int flags; /* per process flags, defined below */
33326 + unsigned int ptrace;
33327 +@@ -1095,10 +1105,9 @@ struct task_struct {
33328 + pid_t pid;
33329 + pid_t tgid;
33330 +
33331 +-#ifdef CONFIG_CC_STACKPROTECTOR
33332 + /* Canary value for the -fstack-protector gcc feature */
33333 + unsigned long stack_canary;
33334 +-#endif
33335 ++
33336 + /*
33337 + * pointers to (original) parent process, youngest child, younger sibling,
33338 + * older sibling, respectively. (p->father can be replaced with
33339 +@@ -1119,8 +1128,8 @@ struct task_struct {
33340 + struct list_head thread_group;
33341 +
33342 + struct completion *vfork_done; /* for vfork() */
33343 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
33344 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
33345 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
33346 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
33347 +
33348 + unsigned int rt_priority;
33349 + cputime_t utime, stime, utimescaled, stimescaled;
33350 +@@ -1303,8 +1312,64 @@ struct task_struct {
33351 + int latency_record_count;
33352 + struct latency_record latency_record[LT_SAVECOUNT];
33353 + #endif
33354 ++
33355 ++#ifdef CONFIG_GRKERNSEC
33356 ++ /* grsecurity */
33357 ++ struct acl_subject_label *acl;
33358 ++ struct acl_role_label *role;
33359 ++ struct file *exec_file;
33360 ++ u16 acl_role_id;
33361 ++ u8 acl_sp_role;
33362 ++ u8 is_writable;
33363 ++ u8 brute;
33364 ++#endif
33365 ++
33366 + };
33367 +
33368 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
33369 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
33370 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
33371 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
33372 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
33373 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
33374 ++
33375 ++#ifdef CONFIG_PAX_SOFTMODE
33376 ++extern unsigned int pax_softmode;
33377 ++#endif
33378 ++
33379 ++extern int pax_check_flags(unsigned long *);
33380 ++
33381 ++/* if tsk != current then task_lock must be held on it */
33382 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
33383 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
33384 ++{
33385 ++ if (likely(tsk->mm))
33386 ++ return tsk->mm->pax_flags;
33387 ++ else
33388 ++ return 0UL;
33389 ++}
33390 ++
33391 ++/* if tsk != current then task_lock must be held on it */
33392 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
33393 ++{
33394 ++ if (likely(tsk->mm)) {
33395 ++ tsk->mm->pax_flags = flags;
33396 ++ return 0;
33397 ++ }
33398 ++ return -EINVAL;
33399 ++}
33400 ++#endif
33401 ++
33402 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
33403 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
33404 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
33405 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
33406 ++#endif
33407 ++
33408 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
33409 ++void pax_report_insns(void *pc, void *sp);
33410 ++void pax_report_refcount_overflow(struct pt_regs *regs);
33411 ++
33412 + /*
33413 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
33414 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
33415 +@@ -1855,7 +1920,7 @@ extern void __cleanup_sighand(struct sig
33416 + extern void exit_itimers(struct signal_struct *);
33417 + extern void flush_itimer_signals(void);
33418 +
33419 +-extern NORET_TYPE void do_group_exit(int);
33420 ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
33421 +
33422 + extern void daemonize(const char *, ...);
33423 + extern int allow_signal(int);
33424 +@@ -1957,8 +2022,8 @@ static inline void unlock_task_sighand(s
33425 +
33426 + #ifndef __HAVE_THREAD_FUNCTIONS
33427 +
33428 +-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
33429 +-#define task_stack_page(task) ((task)->stack)
33430 ++#define task_thread_info(task) ((task)->stack)
33431 ++#define task_stack_page(task) ((void *)(task)->stack)
33432 +
33433 + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
33434 + {
33435 +@@ -2130,6 +2195,12 @@ extern void arch_pick_mmap_layout(struct
33436 + static inline void arch_pick_mmap_layout(struct mm_struct *mm)
33437 + {
33438 + mm->mmap_base = TASK_UNMAPPED_BASE;
33439 ++
33440 ++#ifdef CONFIG_PAX_RANDMMAP
33441 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
33442 ++ mm->mmap_base += mm->delta_mmap;
33443 ++#endif
33444 ++
33445 + mm->get_unmapped_area = arch_get_unmapped_area;
33446 + mm->unmap_area = arch_unmap_area;
33447 + }
33448 +diff -urNp linux-2.6.26.6/include/linux/screen_info.h linux-2.6.26.6/include/linux/screen_info.h
33449 +--- linux-2.6.26.6/include/linux/screen_info.h 2008-10-08 23:24:05.000000000 -0400
33450 ++++ linux-2.6.26.6/include/linux/screen_info.h 2008-10-11 21:54:20.000000000 -0400
33451 +@@ -42,7 +42,8 @@ struct screen_info {
33452 + __u16 pages; /* 0x32 */
33453 + __u16 vesa_attributes; /* 0x34 */
33454 + __u32 capabilities; /* 0x36 */
33455 +- __u8 _reserved[6]; /* 0x3a */
33456 ++ __u16 vesapm_size; /* 0x3a */
33457 ++ __u8 _reserved[4]; /* 0x3c */
33458 + } __attribute__((packed));
33459 +
33460 + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
33461 +diff -urNp linux-2.6.26.6/include/linux/shm.h linux-2.6.26.6/include/linux/shm.h
33462 +--- linux-2.6.26.6/include/linux/shm.h 2008-10-08 23:24:05.000000000 -0400
33463 ++++ linux-2.6.26.6/include/linux/shm.h 2008-10-11 21:54:20.000000000 -0400
33464 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
33465 + pid_t shm_cprid;
33466 + pid_t shm_lprid;
33467 + struct user_struct *mlock_user;
33468 ++#ifdef CONFIG_GRKERNSEC
33469 ++ time_t shm_createtime;
33470 ++ pid_t shm_lapid;
33471 ++#endif
33472 + };
33473 +
33474 + /* shm_mode upper byte flags */
33475 +diff -urNp linux-2.6.26.6/include/linux/slab.h linux-2.6.26.6/include/linux/slab.h
33476 +--- linux-2.6.26.6/include/linux/slab.h 2008-10-08 23:24:05.000000000 -0400
33477 ++++ linux-2.6.26.6/include/linux/slab.h 2008-10-11 21:54:20.000000000 -0400
33478 +@@ -45,10 +45,9 @@
33479 + * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
33480 + * Both make kfree a no-op.
33481 + */
33482 +-#define ZERO_SIZE_PTR ((void *)16)
33483 ++#define ZERO_SIZE_PTR ((void *)-1024L)
33484 +
33485 +-#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
33486 +- (unsigned long)ZERO_SIZE_PTR)
33487 ++#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
33488 +
33489 + /*
33490 + * struct kmem_cache related prototypes
33491 +diff -urNp linux-2.6.26.6/include/linux/sysctl.h linux-2.6.26.6/include/linux/sysctl.h
33492 +--- linux-2.6.26.6/include/linux/sysctl.h 2008-10-08 23:24:05.000000000 -0400
33493 ++++ linux-2.6.26.6/include/linux/sysctl.h 2008-10-11 21:54:20.000000000 -0400
33494 +@@ -163,9 +163,21 @@ enum
33495 + KERN_MAX_LOCK_DEPTH=74,
33496 + KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
33497 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
33498 +-};
33499 ++#ifdef CONFIG_GRKERNSEC
33500 ++ KERN_GRSECURITY=98, /* grsecurity */
33501 ++#endif
33502 ++
33503 ++#ifdef CONFIG_PAX_SOFTMODE
33504 ++ KERN_PAX=99, /* PaX control */
33505 ++#endif
33506 +
33507 ++};
33508 +
33509 ++#ifdef CONFIG_PAX_SOFTMODE
33510 ++enum {
33511 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
33512 ++};
33513 ++#endif
33514 +
33515 + /* CTL_VM names: */
33516 + enum
33517 +diff -urNp linux-2.6.26.6/include/linux/thread_info.h linux-2.6.26.6/include/linux/thread_info.h
33518 +--- linux-2.6.26.6/include/linux/thread_info.h 2008-10-08 23:24:05.000000000 -0400
33519 ++++ linux-2.6.26.6/include/linux/thread_info.h 2008-10-11 21:55:52.000000000 -0400
33520 +@@ -23,7 +23,7 @@ struct restart_block {
33521 + };
33522 + /* For futex_wait */
33523 + struct {
33524 +- u32 *uaddr;
33525 ++ u32 __user *uaddr;
33526 + u32 val;
33527 + u32 flags;
33528 + u32 bitset;
33529 +diff -urNp linux-2.6.26.6/include/linux/uaccess.h linux-2.6.26.6/include/linux/uaccess.h
33530 +--- linux-2.6.26.6/include/linux/uaccess.h 2008-10-08 23:24:05.000000000 -0400
33531 ++++ linux-2.6.26.6/include/linux/uaccess.h 2008-10-11 21:54:20.000000000 -0400
33532 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
33533 + long ret; \
33534 + mm_segment_t old_fs = get_fs(); \
33535 + \
33536 +- set_fs(KERNEL_DS); \
33537 + pagefault_disable(); \
33538 ++ set_fs(KERNEL_DS); \
33539 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
33540 +- pagefault_enable(); \
33541 + set_fs(old_fs); \
33542 ++ pagefault_enable(); \
33543 + ret; \
33544 + })
33545 +
33546 +diff -urNp linux-2.6.26.6/include/net/sctp/sctp.h linux-2.6.26.6/include/net/sctp/sctp.h
33547 +--- linux-2.6.26.6/include/net/sctp/sctp.h 2008-10-08 23:24:05.000000000 -0400
33548 ++++ linux-2.6.26.6/include/net/sctp/sctp.h 2008-10-11 21:54:20.000000000 -0400
33549 +@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
33550 +
33551 + #else /* SCTP_DEBUG */
33552 +
33553 +-#define SCTP_DEBUG_PRINTK(whatever...)
33554 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
33555 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
33556 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
33557 + #define SCTP_ENABLE_DEBUG
33558 + #define SCTP_DISABLE_DEBUG
33559 + #define SCTP_ASSERT(expr, str, func)
33560 +diff -urNp linux-2.6.26.6/include/sound/core.h linux-2.6.26.6/include/sound/core.h
33561 +--- linux-2.6.26.6/include/sound/core.h 2008-10-08 23:24:05.000000000 -0400
33562 ++++ linux-2.6.26.6/include/sound/core.h 2008-10-11 21:54:20.000000000 -0400
33563 +@@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
33564 +
33565 + #else /* !CONFIG_SND_DEBUG */
33566 +
33567 +-#define snd_printd(fmt, args...) /* nothing */
33568 ++#define snd_printd(fmt, args...) do {} while (0)
33569 + #define snd_assert(expr, args...) (void)(expr)
33570 +-#define snd_BUG() /* nothing */
33571 ++#define snd_BUG() do {} while (0)
33572 +
33573 + #endif /* CONFIG_SND_DEBUG */
33574 +
33575 +@@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
33576 + */
33577 + #define snd_printdd(format, args...) snd_printk(format, ##args)
33578 + #else
33579 +-#define snd_printdd(format, args...) /* nothing */
33580 ++#define snd_printdd(format, args...) do {} while (0)
33581 + #endif
33582 +
33583 +
33584 +diff -urNp linux-2.6.26.6/include/video/uvesafb.h linux-2.6.26.6/include/video/uvesafb.h
33585 +--- linux-2.6.26.6/include/video/uvesafb.h 2008-10-08 23:24:05.000000000 -0400
33586 ++++ linux-2.6.26.6/include/video/uvesafb.h 2008-10-11 21:54:20.000000000 -0400
33587 +@@ -175,6 +175,7 @@ struct uvesafb_par {
33588 + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
33589 + u8 pmi_setpal; /* PMI for palette changes */
33590 + u16 *pmi_base; /* protected mode interface location */
33591 ++ u8 *pmi_code; /* protected mode code location */
33592 + void *pmi_start;
33593 + void *pmi_pal;
33594 + u8 *vbe_state_orig; /*
33595 +diff -urNp linux-2.6.26.6/init/do_mounts.c linux-2.6.26.6/init/do_mounts.c
33596 +--- linux-2.6.26.6/init/do_mounts.c 2008-10-08 23:24:05.000000000 -0400
33597 ++++ linux-2.6.26.6/init/do_mounts.c 2008-10-11 21:54:20.000000000 -0400
33598 +@@ -213,11 +213,11 @@ static void __init get_fs_names(char *pa
33599 +
33600 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
33601 + {
33602 +- int err = sys_mount(name, "/root", fs, flags, data);
33603 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
33604 + if (err)
33605 + return err;
33606 +
33607 +- sys_chdir("/root");
33608 ++ sys_chdir((char __user *)"/root");
33609 + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
33610 + printk("VFS: Mounted root (%s filesystem)%s.\n",
33611 + current->fs->pwd.mnt->mnt_sb->s_type->name,
33612 +@@ -303,18 +303,18 @@ void __init change_floppy(char *fmt, ...
33613 + va_start(args, fmt);
33614 + vsprintf(buf, fmt, args);
33615 + va_end(args);
33616 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
33617 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
33618 + if (fd >= 0) {
33619 + sys_ioctl(fd, FDEJECT, 0);
33620 + sys_close(fd);
33621 + }
33622 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
33623 +- fd = sys_open("/dev/console", O_RDWR, 0);
33624 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
33625 + if (fd >= 0) {
33626 + sys_ioctl(fd, TCGETS, (long)&termios);
33627 + termios.c_lflag &= ~ICANON;
33628 + sys_ioctl(fd, TCSETSF, (long)&termios);
33629 +- sys_read(fd, &c, 1);
33630 ++ sys_read(fd, (char __user *)&c, 1);
33631 + termios.c_lflag |= ICANON;
33632 + sys_ioctl(fd, TCSETSF, (long)&termios);
33633 + sys_close(fd);
33634 +@@ -400,7 +400,7 @@ void __init prepare_namespace(void)
33635 +
33636 + mount_root();
33637 + out:
33638 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
33639 +- sys_chroot(".");
33640 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
33641 ++ sys_chroot((char __user *)".");
33642 + }
33643 +
33644 +diff -urNp linux-2.6.26.6/init/do_mounts.h linux-2.6.26.6/init/do_mounts.h
33645 +--- linux-2.6.26.6/init/do_mounts.h 2008-10-08 23:24:05.000000000 -0400
33646 ++++ linux-2.6.26.6/init/do_mounts.h 2008-10-11 21:54:20.000000000 -0400
33647 +@@ -15,15 +15,15 @@ extern char *root_device_name;
33648 +
33649 + static inline int create_dev(char *name, dev_t dev)
33650 + {
33651 +- sys_unlink(name);
33652 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
33653 ++ sys_unlink((char __user *)name);
33654 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
33655 + }
33656 +
33657 + #if BITS_PER_LONG == 32
33658 + static inline u32 bstat(char *name)
33659 + {
33660 + struct stat64 stat;
33661 +- if (sys_stat64(name, &stat) != 0)
33662 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
33663 + return 0;
33664 + if (!S_ISBLK(stat.st_mode))
33665 + return 0;
33666 +diff -urNp linux-2.6.26.6/init/do_mounts_initrd.c linux-2.6.26.6/init/do_mounts_initrd.c
33667 +--- linux-2.6.26.6/init/do_mounts_initrd.c 2008-10-08 23:24:05.000000000 -0400
33668 ++++ linux-2.6.26.6/init/do_mounts_initrd.c 2008-10-11 21:55:52.000000000 -0400
33669 +@@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
33670 + sys_close(old_fd);sys_close(root_fd);
33671 + sys_close(0);sys_close(1);sys_close(2);
33672 + sys_setsid();
33673 +- (void) sys_open("/dev/console",O_RDWR,0);
33674 ++ (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
33675 + (void) sys_dup(0);
33676 + (void) sys_dup(0);
33677 + return kernel_execve(shell, argv, envp_init);
33678 +@@ -47,13 +47,13 @@ static void __init handle_initrd(void)
33679 + create_dev("/dev/root.old", Root_RAM0);
33680 + /* mount initrd on rootfs' /root */
33681 + mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
33682 +- sys_mkdir("/old", 0700);
33683 +- root_fd = sys_open("/", 0, 0);
33684 +- old_fd = sys_open("/old", 0, 0);
33685 ++ sys_mkdir((const char __user *)"/old", 0700);
33686 ++ root_fd = sys_open((const char __user *)"/", 0, 0);
33687 ++ old_fd = sys_open((const char __user *)"/old", 0, 0);
33688 + /* move initrd over / and chdir/chroot in initrd root */
33689 +- sys_chdir("/root");
33690 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
33691 +- sys_chroot(".");
33692 ++ sys_chdir((const char __user *)"/root");
33693 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
33694 ++ sys_chroot((const char __user *)".");
33695 +
33696 + /*
33697 + * In case that a resume from disk is carried out by linuxrc or one of
33698 +@@ -70,15 +70,15 @@ static void __init handle_initrd(void)
33699 +
33700 + /* move initrd to rootfs' /old */
33701 + sys_fchdir(old_fd);
33702 +- sys_mount("/", ".", NULL, MS_MOVE, NULL);
33703 ++ sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
33704 + /* switch root and cwd back to / of rootfs */
33705 + sys_fchdir(root_fd);
33706 +- sys_chroot(".");
33707 ++ sys_chroot((const char __user *)".");
33708 + sys_close(old_fd);
33709 + sys_close(root_fd);
33710 +
33711 + if (new_decode_dev(real_root_dev) == Root_RAM0) {
33712 +- sys_chdir("/old");
33713 ++ sys_chdir((const char __user *)"/old");
33714 + return;
33715 + }
33716 +
33717 +@@ -86,17 +86,17 @@ static void __init handle_initrd(void)
33718 + mount_root();
33719 +
33720 + printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
33721 +- error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
33722 ++ error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
33723 + if (!error)
33724 + printk("okay\n");
33725 + else {
33726 +- int fd = sys_open("/dev/root.old", O_RDWR, 0);
33727 ++ int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
33728 + if (error == -ENOENT)
33729 + printk("/initrd does not exist. Ignored.\n");
33730 + else
33731 + printk("failed\n");
33732 + printk(KERN_NOTICE "Unmounting old root\n");
33733 +- sys_umount("/old", MNT_DETACH);
33734 ++ sys_umount((char __user *)"/old", MNT_DETACH);
33735 + printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
33736 + if (fd < 0) {
33737 + error = fd;
33738 +@@ -119,11 +119,11 @@ int __init initrd_load(void)
33739 + * mounted in the normal path.
33740 + */
33741 + if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
33742 +- sys_unlink("/initrd.image");
33743 ++ sys_unlink((const char __user *)"/initrd.image");
33744 + handle_initrd();
33745 + return 1;
33746 + }
33747 + }
33748 +- sys_unlink("/initrd.image");
33749 ++ sys_unlink((const char __user *)"/initrd.image");
33750 + return 0;
33751 + }
33752 +diff -urNp linux-2.6.26.6/init/do_mounts_md.c linux-2.6.26.6/init/do_mounts_md.c
33753 +--- linux-2.6.26.6/init/do_mounts_md.c 2008-10-08 23:24:05.000000000 -0400
33754 ++++ linux-2.6.26.6/init/do_mounts_md.c 2008-10-11 21:54:20.000000000 -0400
33755 +@@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
33756 + partitioned ? "_d" : "", minor,
33757 + md_setup_args[ent].device_names);
33758 +
33759 +- fd = sys_open(name, 0, 0);
33760 ++ fd = sys_open((char __user *)name, 0, 0);
33761 + if (fd < 0) {
33762 + printk(KERN_ERR "md: open failed - cannot start "
33763 + "array %s\n", name);
33764 +@@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
33765 + * array without it
33766 + */
33767 + sys_close(fd);
33768 +- fd = sys_open(name, 0, 0);
33769 ++ fd = sys_open((char __user *)name, 0, 0);
33770 + sys_ioctl(fd, BLKRRPART, 0);
33771 + }
33772 + sys_close(fd);
33773 +@@ -270,7 +270,7 @@ void __init md_run_setup(void)
33774 + if (raid_noautodetect)
33775 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
33776 + else {
33777 +- int fd = sys_open("/dev/md0", 0, 0);
33778 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
33779 + if (fd >= 0) {
33780 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
33781 + sys_close(fd);
33782 +diff -urNp linux-2.6.26.6/init/initramfs.c linux-2.6.26.6/init/initramfs.c
33783 +--- linux-2.6.26.6/init/initramfs.c 2008-10-08 23:24:05.000000000 -0400
33784 ++++ linux-2.6.26.6/init/initramfs.c 2008-10-11 21:54:20.000000000 -0400
33785 +@@ -240,7 +240,7 @@ static int __init maybe_link(void)
33786 + if (nlink >= 2) {
33787 + char *old = find_link(major, minor, ino, mode, collected);
33788 + if (old)
33789 +- return (sys_link(old, collected) < 0) ? -1 : 1;
33790 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
33791 + }
33792 + return 0;
33793 + }
33794 +@@ -249,11 +249,11 @@ static void __init clean_path(char *path
33795 + {
33796 + struct stat st;
33797 +
33798 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
33799 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
33800 + if (S_ISDIR(st.st_mode))
33801 +- sys_rmdir(path);
33802 ++ sys_rmdir((char __user *)path);
33803 + else
33804 +- sys_unlink(path);
33805 ++ sys_unlink((char __user *)path);
33806 + }
33807 + }
33808 +
33809 +@@ -276,7 +276,7 @@ static int __init do_name(void)
33810 + int openflags = O_WRONLY|O_CREAT;
33811 + if (ml != 1)
33812 + openflags |= O_TRUNC;
33813 +- wfd = sys_open(collected, openflags, mode);
33814 ++ wfd = sys_open((char __user *)collected, openflags, mode);
33815 +
33816 + if (wfd >= 0) {
33817 + sys_fchown(wfd, uid, gid);
33818 +@@ -285,15 +285,15 @@ static int __init do_name(void)
33819 + }
33820 + }
33821 + } else if (S_ISDIR(mode)) {
33822 +- sys_mkdir(collected, mode);
33823 +- sys_chown(collected, uid, gid);
33824 +- sys_chmod(collected, mode);
33825 ++ sys_mkdir((char __user *)collected, mode);
33826 ++ sys_chown((char __user *)collected, uid, gid);
33827 ++ sys_chmod((char __user *)collected, mode);
33828 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
33829 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
33830 + if (maybe_link() == 0) {
33831 +- sys_mknod(collected, mode, rdev);
33832 +- sys_chown(collected, uid, gid);
33833 +- sys_chmod(collected, mode);
33834 ++ sys_mknod((char __user *)collected, mode, rdev);
33835 ++ sys_chown((char __user *)collected, uid, gid);
33836 ++ sys_chmod((char __user *)collected, mode);
33837 + }
33838 + }
33839 + return 0;
33840 +@@ -302,13 +302,13 @@ static int __init do_name(void)
33841 + static int __init do_copy(void)
33842 + {
33843 + if (count >= body_len) {
33844 +- sys_write(wfd, victim, body_len);
33845 ++ sys_write(wfd, (char __user *)victim, body_len);
33846 + sys_close(wfd);
33847 + eat(body_len);
33848 + state = SkipIt;
33849 + return 0;
33850 + } else {
33851 +- sys_write(wfd, victim, count);
33852 ++ sys_write(wfd, (char __user *)victim, count);
33853 + body_len -= count;
33854 + eat(count);
33855 + return 1;
33856 +@@ -319,8 +319,8 @@ static int __init do_symlink(void)
33857 + {
33858 + collected[N_ALIGN(name_len) + body_len] = '\0';
33859 + clean_path(collected, 0);
33860 +- sys_symlink(collected + N_ALIGN(name_len), collected);
33861 +- sys_lchown(collected, uid, gid);
33862 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
33863 ++ sys_lchown((char __user *)collected, uid, gid);
33864 + state = SkipIt;
33865 + next_state = Reset;
33866 + return 0;
33867 +diff -urNp linux-2.6.26.6/init/Kconfig linux-2.6.26.6/init/Kconfig
33868 +--- linux-2.6.26.6/init/Kconfig 2008-10-08 23:24:05.000000000 -0400
33869 ++++ linux-2.6.26.6/init/Kconfig 2008-10-11 21:54:20.000000000 -0400
33870 +@@ -572,6 +572,7 @@ config SYSCTL_SYSCALL_CHECK
33871 + config KALLSYMS
33872 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
33873 + default y
33874 ++ depends on !GRKERNSEC_HIDESYM
33875 + help
33876 + Say Y here to let the kernel print out symbolic crash information and
33877 + symbolic stack backtraces. This increases the size of the kernel
33878 +@@ -791,8 +792,8 @@ config MARKERS
33879 + source "arch/Kconfig"
33880 +
33881 + config PROC_PAGE_MONITOR
33882 +- default y
33883 +- depends on PROC_FS && MMU
33884 ++ default n
33885 ++ depends on PROC_FS && MMU && !GRKERNSEC
33886 + bool "Enable /proc page monitoring" if EMBEDDED
33887 + help
33888 + Various /proc files exist to monitor process memory utilization:
33889 +@@ -804,9 +805,9 @@ endmenu # General setup
33890 +
33891 + config SLABINFO
33892 + bool
33893 +- depends on PROC_FS
33894 ++ depends on PROC_FS && !GRKERNSEC_PROC_ADD
33895 + depends on SLAB || SLUB_DEBUG
33896 +- default y
33897 ++ default n
33898 +
33899 + config RT_MUTEXES
33900 + boolean
33901 +diff -urNp linux-2.6.26.6/init/main.c linux-2.6.26.6/init/main.c
33902 +--- linux-2.6.26.6/init/main.c 2008-10-08 23:24:05.000000000 -0400
33903 ++++ linux-2.6.26.6/init/main.c 2008-10-11 21:54:20.000000000 -0400
33904 +@@ -103,6 +103,7 @@ static inline void mark_rodata_ro(void)
33905 + #ifdef CONFIG_TC
33906 + extern void tc_init(void);
33907 + #endif
33908 ++extern void grsecurity_init(void);
33909 +
33910 + enum system_states system_state;
33911 + EXPORT_SYMBOL(system_state);
33912 +@@ -189,6 +190,40 @@ static int __init set_reset_devices(char
33913 +
33914 + __setup("reset_devices", set_reset_devices);
33915 +
33916 ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
33917 ++static int __init setup_pax_nouderef(char *str)
33918 ++{
33919 ++ unsigned int cpu;
33920 ++
33921 ++#ifdef CONFIG_PAX_KERNEXEC
33922 ++ unsigned long cr0;
33923 ++
33924 ++ pax_open_kernel(cr0);
33925 ++#endif
33926 ++
33927 ++ for (cpu = 0; cpu < NR_CPUS; cpu++)
33928 ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
33929 ++
33930 ++#ifdef CONFIG_PAX_KERNEXEC
33931 ++ pax_close_kernel(cr0);
33932 ++#endif
33933 ++
33934 ++ return 1;
33935 ++}
33936 ++__setup("pax_nouderef", setup_pax_nouderef);
33937 ++#endif
33938 ++
33939 ++#ifdef CONFIG_PAX_SOFTMODE
33940 ++unsigned int pax_softmode;
33941 ++
33942 ++static int __init setup_pax_softmode(char *str)
33943 ++{
33944 ++ get_option(&str, &pax_softmode);
33945 ++ return 1;
33946 ++}
33947 ++__setup("pax_softmode=", setup_pax_softmode);
33948 ++#endif
33949 ++
33950 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
33951 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
33952 + static const char *panic_later, *panic_param;
33953 +@@ -387,7 +422,7 @@ static void __init setup_nr_cpu_ids(void
33954 + }
33955 +
33956 + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
33957 +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
33958 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
33959 +
33960 + EXPORT_SYMBOL(__per_cpu_offset);
33961 +
33962 +@@ -697,6 +732,7 @@ static void __init do_one_initcall(initc
33963 + {
33964 + int count = preempt_count();
33965 + ktime_t t0, t1, delta;
33966 ++ const char *msg1 = "", *msg2 = "";
33967 + char msgbuf[64];
33968 + int result;
33969 +
33970 +@@ -722,16 +758,16 @@ static void __init do_one_initcall(initc
33971 + sprintf(msgbuf, "error code %d ", result);
33972 +
33973 + if (preempt_count() != count) {
33974 +- strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
33975 ++ msg1 = " preemption imbalance";
33976 + preempt_count() = count;
33977 + }
33978 + if (irqs_disabled()) {
33979 +- strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
33980 ++ msg2 = " disabled interrupts";
33981 + local_irq_enable();
33982 + }
33983 +- if (msgbuf[0]) {
33984 ++ if (msgbuf[0] || *msg1 || *msg2) {
33985 + print_fn_descriptor_symbol(KERN_WARNING "initcall %s", fn);
33986 +- printk(" returned with %s\n", msgbuf);
33987 ++ printk(" returned with %s%s%s\n", msgbuf, msg1, msg2);
33988 + }
33989 + }
33990 +
33991 +@@ -878,6 +914,8 @@ static int __init kernel_init(void * unu
33992 + prepare_namespace();
33993 + }
33994 +
33995 ++ grsecurity_init();
33996 ++
33997 + /*
33998 + * Ok, we have completed the initial bootup, and
33999 + * we're essentially up and running. Get rid of the
34000 +diff -urNp linux-2.6.26.6/init/noinitramfs.c linux-2.6.26.6/init/noinitramfs.c
34001 +--- linux-2.6.26.6/init/noinitramfs.c 2008-10-08 23:24:05.000000000 -0400
34002 ++++ linux-2.6.26.6/init/noinitramfs.c 2008-10-11 21:54:20.000000000 -0400
34003 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
34004 + {
34005 + int err;
34006 +
34007 +- err = sys_mkdir("/dev", 0755);
34008 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
34009 + if (err < 0)
34010 + goto out;
34011 +
34012 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
34013 + if (err < 0)
34014 + goto out;
34015 +
34016 +- err = sys_mkdir("/root", 0700);
34017 ++ err = sys_mkdir((const char __user *)"/root", 0700);
34018 + if (err < 0)
34019 + goto out;
34020 +
34021 +diff -urNp linux-2.6.26.6/ipc/ipc_sysctl.c linux-2.6.26.6/ipc/ipc_sysctl.c
34022 +--- linux-2.6.26.6/ipc/ipc_sysctl.c 2008-10-08 23:24:05.000000000 -0400
34023 ++++ linux-2.6.26.6/ipc/ipc_sysctl.c 2008-10-11 21:54:20.000000000 -0400
34024 +@@ -222,7 +222,7 @@ static struct ctl_table ipc_kern_table[]
34025 + .proc_handler = proc_ipc_dointvec,
34026 + .strategy = sysctl_ipc_data,
34027 + },
34028 +- {}
34029 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
34030 + };
34031 +
34032 + static struct ctl_table ipc_root_table[] = {
34033 +@@ -232,7 +232,7 @@ static struct ctl_table ipc_root_table[]
34034 + .mode = 0555,
34035 + .child = ipc_kern_table,
34036 + },
34037 +- {}
34038 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
34039 + };
34040 +
34041 + static int __init ipc_sysctl_init(void)
34042 +diff -urNp linux-2.6.26.6/ipc/msg.c linux-2.6.26.6/ipc/msg.c
34043 +--- linux-2.6.26.6/ipc/msg.c 2008-10-08 23:24:05.000000000 -0400
34044 ++++ linux-2.6.26.6/ipc/msg.c 2008-10-11 21:54:20.000000000 -0400
34045 +@@ -38,6 +38,7 @@
34046 + #include <linux/rwsem.h>
34047 + #include <linux/nsproxy.h>
34048 + #include <linux/ipc_namespace.h>
34049 ++#include <linux/grsecurity.h>
34050 +
34051 + #include <asm/current.h>
34052 + #include <asm/uaccess.h>
34053 +@@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
34054 + struct ipc_namespace *ns;
34055 + struct ipc_ops msg_ops;
34056 + struct ipc_params msg_params;
34057 ++ long err;
34058 +
34059 + ns = current->nsproxy->ipc_ns;
34060 +
34061 +@@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
34062 + msg_params.key = key;
34063 + msg_params.flg = msgflg;
34064 +
34065 +- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
34066 ++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
34067 ++
34068 ++ gr_log_msgget(err, msgflg);
34069 ++
34070 ++ return err;
34071 + }
34072 +
34073 + static inline unsigned long
34074 +@@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
34075 +
34076 + switch (cmd) {
34077 + case IPC_RMID:
34078 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
34079 + freeque(ns, ipcp);
34080 + goto out_up;
34081 + case IPC_SET:
34082 +diff -urNp linux-2.6.26.6/ipc/sem.c linux-2.6.26.6/ipc/sem.c
34083 +--- linux-2.6.26.6/ipc/sem.c 2008-10-08 23:24:05.000000000 -0400
34084 ++++ linux-2.6.26.6/ipc/sem.c 2008-10-11 21:54:20.000000000 -0400
34085 +@@ -83,6 +83,7 @@
34086 + #include <linux/rwsem.h>
34087 + #include <linux/nsproxy.h>
34088 + #include <linux/ipc_namespace.h>
34089 ++#include <linux/grsecurity.h>
34090 +
34091 + #include <asm/uaccess.h>
34092 + #include "util.h"
34093 +@@ -314,6 +315,7 @@ asmlinkage long sys_semget(key_t key, in
34094 + struct ipc_namespace *ns;
34095 + struct ipc_ops sem_ops;
34096 + struct ipc_params sem_params;
34097 ++ long err;
34098 +
34099 + ns = current->nsproxy->ipc_ns;
34100 +
34101 +@@ -328,7 +330,11 @@ asmlinkage long sys_semget(key_t key, in
34102 + sem_params.flg = semflg;
34103 + sem_params.u.nsems = nsems;
34104 +
34105 +- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
34106 ++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
34107 ++
34108 ++ gr_log_semget(err, semflg);
34109 ++
34110 ++ return err;
34111 + }
34112 +
34113 + /* Manage the doubly linked list sma->sem_pending as a FIFO:
34114 +@@ -876,6 +882,7 @@ static int semctl_down(struct ipc_namesp
34115 +
34116 + switch(cmd){
34117 + case IPC_RMID:
34118 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
34119 + freeary(ns, ipcp);
34120 + goto out_up;
34121 + case IPC_SET:
34122 +diff -urNp linux-2.6.26.6/ipc/shm.c linux-2.6.26.6/ipc/shm.c
34123 +--- linux-2.6.26.6/ipc/shm.c 2008-10-08 23:24:05.000000000 -0400
34124 ++++ linux-2.6.26.6/ipc/shm.c 2008-10-11 21:54:20.000000000 -0400
34125 +@@ -39,6 +39,7 @@
34126 + #include <linux/nsproxy.h>
34127 + #include <linux/mount.h>
34128 + #include <linux/ipc_namespace.h>
34129 ++#include <linux/grsecurity.h>
34130 +
34131 + #include <asm/uaccess.h>
34132 +
34133 +@@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
34134 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
34135 + #endif
34136 +
34137 ++#ifdef CONFIG_GRKERNSEC
34138 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
34139 ++ const time_t shm_createtime, const uid_t cuid,
34140 ++ const int shmid);
34141 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
34142 ++ const time_t shm_createtime);
34143 ++#endif
34144 ++
34145 + void shm_init_ns(struct ipc_namespace *ns)
34146 + {
34147 + ns->shm_ctlmax = SHMMAX;
34148 +@@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
34149 + struct shmid_kernel *shp;
34150 + shp = container_of(ipcp, struct shmid_kernel, shm_perm);
34151 +
34152 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
34153 ++
34154 + if (shp->shm_nattch){
34155 + shp->shm_perm.mode |= SHM_DEST;
34156 + /* Do not find it any more */
34157 +@@ -407,6 +418,14 @@ static int newseg(struct ipc_namespace *
34158 + shp->shm_lprid = 0;
34159 + shp->shm_atim = shp->shm_dtim = 0;
34160 + shp->shm_ctim = get_seconds();
34161 ++#ifdef CONFIG_GRKERNSEC
34162 ++ {
34163 ++ struct timespec timeval;
34164 ++ do_posix_clock_monotonic_gettime(&timeval);
34165 ++
34166 ++ shp->shm_createtime = timeval.tv_sec;
34167 ++ }
34168 ++#endif
34169 + shp->shm_segsz = size;
34170 + shp->shm_nattch = 0;
34171 + shp->shm_file = file;
34172 +@@ -460,6 +479,7 @@ asmlinkage long sys_shmget (key_t key, s
34173 + struct ipc_namespace *ns;
34174 + struct ipc_ops shm_ops;
34175 + struct ipc_params shm_params;
34176 ++ long err;
34177 +
34178 + ns = current->nsproxy->ipc_ns;
34179 +
34180 +@@ -471,7 +491,11 @@ asmlinkage long sys_shmget (key_t key, s
34181 + shm_params.flg = shmflg;
34182 + shm_params.u.size = size;
34183 +
34184 +- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
34185 ++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
34186 ++
34187 ++ gr_log_shmget(err, shmflg, size);
34188 ++
34189 ++ return err;
34190 + }
34191 +
34192 + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
34193 +@@ -883,9 +907,21 @@ long do_shmat(int shmid, char __user *sh
34194 + if (err)
34195 + goto out_unlock;
34196 +
34197 ++#ifdef CONFIG_GRKERNSEC
34198 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
34199 ++ shp->shm_perm.cuid, shmid) ||
34200 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
34201 ++ err = -EACCES;
34202 ++ goto out_unlock;
34203 ++ }
34204 ++#endif
34205 ++
34206 + path.dentry = dget(shp->shm_file->f_path.dentry);
34207 + path.mnt = shp->shm_file->f_path.mnt;
34208 + shp->shm_nattch++;
34209 ++#ifdef CONFIG_GRKERNSEC
34210 ++ shp->shm_lapid = current->pid;
34211 ++#endif
34212 + size = i_size_read(path.dentry->d_inode);
34213 + shm_unlock(shp);
34214 +
34215 +diff -urNp linux-2.6.26.6/kernel/acct.c linux-2.6.26.6/kernel/acct.c
34216 +--- linux-2.6.26.6/kernel/acct.c 2008-10-08 23:24:05.000000000 -0400
34217 ++++ linux-2.6.26.6/kernel/acct.c 2008-10-11 21:54:20.000000000 -0400
34218 +@@ -519,7 +519,7 @@ static void do_acct_process(struct pid_n
34219 + */
34220 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
34221 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
34222 +- file->f_op->write(file, (char *)&ac,
34223 ++ file->f_op->write(file, (char __user *)&ac,
34224 + sizeof(acct_t), &file->f_pos);
34225 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
34226 + set_fs(fs);
34227 +diff -urNp linux-2.6.26.6/kernel/capability.c linux-2.6.26.6/kernel/capability.c
34228 +--- linux-2.6.26.6/kernel/capability.c 2008-10-08 23:24:05.000000000 -0400
34229 ++++ linux-2.6.26.6/kernel/capability.c 2008-10-11 21:54:20.000000000 -0400
34230 +@@ -13,6 +13,7 @@
34231 + #include <linux/security.h>
34232 + #include <linux/syscalls.h>
34233 + #include <linux/pid_namespace.h>
34234 ++#include <linux/grsecurity.h>
34235 + #include <asm/uaccess.h>
34236 +
34237 + /*
34238 +@@ -384,15 +385,25 @@ out:
34239 +
34240 + int __capable(struct task_struct *t, int cap)
34241 + {
34242 +- if (security_capable(t, cap) == 0) {
34243 ++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
34244 + t->flags |= PF_SUPERPRIV;
34245 + return 1;
34246 + }
34247 + return 0;
34248 + }
34249 +
34250 ++int capable_nolog(int cap)
34251 ++{
34252 ++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
34253 ++ current->flags |= PF_SUPERPRIV;
34254 ++ return 1;
34255 ++ }
34256 ++ return 0;
34257 ++}
34258 ++
34259 + int capable(int cap)
34260 + {
34261 + return __capable(current, cap);
34262 + }
34263 + EXPORT_SYMBOL(capable);
34264 ++EXPORT_SYMBOL(capable_nolog);
34265 +diff -urNp linux-2.6.26.6/kernel/configs.c linux-2.6.26.6/kernel/configs.c
34266 +--- linux-2.6.26.6/kernel/configs.c 2008-10-08 23:24:05.000000000 -0400
34267 ++++ linux-2.6.26.6/kernel/configs.c 2008-10-11 21:54:20.000000000 -0400
34268 +@@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
34269 + struct proc_dir_entry *entry;
34270 +
34271 + /* create the current config file */
34272 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
34273 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
34274 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
34275 ++ &ikconfig_file_ops);
34276 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34277 ++ entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
34278 ++ &ikconfig_file_ops);
34279 ++#endif
34280 ++#else
34281 + entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
34282 + &ikconfig_file_ops);
34283 ++#endif
34284 ++
34285 + if (!entry)
34286 + return -ENOMEM;
34287 +
34288 +diff -urNp linux-2.6.26.6/kernel/cpu.c linux-2.6.26.6/kernel/cpu.c
34289 +--- linux-2.6.26.6/kernel/cpu.c 2008-10-08 23:24:05.000000000 -0400
34290 ++++ linux-2.6.26.6/kernel/cpu.c 2008-10-11 21:54:20.000000000 -0400
34291 +@@ -18,7 +18,7 @@
34292 + /* Serializes the updates to cpu_online_map, cpu_present_map */
34293 + static DEFINE_MUTEX(cpu_add_remove_lock);
34294 +
34295 +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
34296 ++static RAW_NOTIFIER_HEAD(cpu_chain);
34297 +
34298 + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
34299 + * Should always be manipulated under cpu_add_remove_lock
34300 +diff -urNp linux-2.6.26.6/kernel/exit.c linux-2.6.26.6/kernel/exit.c
34301 +--- linux-2.6.26.6/kernel/exit.c 2008-10-08 23:24:05.000000000 -0400
34302 ++++ linux-2.6.26.6/kernel/exit.c 2008-10-11 21:54:20.000000000 -0400
34303 +@@ -45,6 +45,11 @@
34304 + #include <linux/resource.h>
34305 + #include <linux/blkdev.h>
34306 + #include <linux/task_io_accounting_ops.h>
34307 ++#include <linux/grsecurity.h>
34308 ++
34309 ++#ifdef CONFIG_GRKERNSEC
34310 ++extern rwlock_t grsec_exec_file_lock;
34311 ++#endif
34312 +
34313 + #include <asm/uaccess.h>
34314 + #include <asm/unistd.h>
34315 +@@ -132,6 +137,7 @@ static void __exit_signal(struct task_st
34316 + */
34317 + flush_sigqueue(&tsk->pending);
34318 +
34319 ++ gr_del_task_from_ip_table(tsk);
34320 + tsk->signal = NULL;
34321 + tsk->sighand = NULL;
34322 + spin_unlock(&sighand->siglock);
34323 +@@ -312,12 +318,23 @@ static void reparent_to_kthreadd(void)
34324 + {
34325 + write_lock_irq(&tasklist_lock);
34326 +
34327 ++#ifdef CONFIG_GRKERNSEC
34328 ++ write_lock(&grsec_exec_file_lock);
34329 ++ if (current->exec_file) {
34330 ++ fput(current->exec_file);
34331 ++ current->exec_file = NULL;
34332 ++ }
34333 ++ write_unlock(&grsec_exec_file_lock);
34334 ++#endif
34335 ++
34336 + ptrace_unlink(current);
34337 + /* Reparent to init */
34338 + remove_parent(current);
34339 + current->real_parent = current->parent = kthreadd_task;
34340 + add_parent(current);
34341 +
34342 ++ gr_set_kernel_label(current);
34343 ++
34344 + /* Set the exit signal to SIGCHLD so we signal init on exit */
34345 + current->exit_signal = SIGCHLD;
34346 +
34347 +@@ -411,6 +428,17 @@ void daemonize(const char *name, ...)
34348 + vsnprintf(current->comm, sizeof(current->comm), name, args);
34349 + va_end(args);
34350 +
34351 ++#ifdef CONFIG_GRKERNSEC
34352 ++ write_lock(&grsec_exec_file_lock);
34353 ++ if (current->exec_file) {
34354 ++ fput(current->exec_file);
34355 ++ current->exec_file = NULL;
34356 ++ }
34357 ++ write_unlock(&grsec_exec_file_lock);
34358 ++#endif
34359 ++
34360 ++ gr_set_kernel_label(current);
34361 ++
34362 + /*
34363 + * If we were started as result of loading a module, close all of the
34364 + * user space pages. We don't need them, and if we didn't close them
34365 +@@ -1046,6 +1074,9 @@ NORET_TYPE void do_exit(long code)
34366 + tsk->exit_code = code;
34367 + taskstats_exit(tsk, group_dead);
34368 +
34369 ++ gr_acl_handle_psacct(tsk, code);
34370 ++ gr_acl_handle_exit();
34371 ++
34372 + exit_mm(tsk);
34373 +
34374 + if (group_dead)
34375 +@@ -1256,7 +1287,7 @@ static int wait_task_zombie(struct task_
34376 + if (unlikely(noreap)) {
34377 + uid_t uid = p->uid;
34378 + int exit_code = p->exit_code;
34379 +- int why, status;
34380 ++ int why;
34381 +
34382 + get_task_struct(p);
34383 + read_unlock(&tasklist_lock);
34384 +diff -urNp linux-2.6.26.6/kernel/fork.c linux-2.6.26.6/kernel/fork.c
34385 +--- linux-2.6.26.6/kernel/fork.c 2008-10-08 23:24:05.000000000 -0400
34386 ++++ linux-2.6.26.6/kernel/fork.c 2008-10-11 21:54:20.000000000 -0400
34387 +@@ -54,6 +54,7 @@
34388 + #include <linux/tty.h>
34389 + #include <linux/proc_fs.h>
34390 + #include <linux/blkdev.h>
34391 ++#include <linux/grsecurity.h>
34392 +
34393 + #include <asm/pgtable.h>
34394 + #include <asm/pgalloc.h>
34395 +@@ -213,7 +214,7 @@ static struct task_struct *dup_task_stru
34396 + setup_thread_stack(tsk, orig);
34397 +
34398 + #ifdef CONFIG_CC_STACKPROTECTOR
34399 +- tsk->stack_canary = get_random_int();
34400 ++ tsk->stack_canary = pax_get_random_long();
34401 + #endif
34402 +
34403 + /* One for us, one for whoever does the "release_task()" (usually parent) */
34404 +@@ -250,8 +251,8 @@ static int dup_mmap(struct mm_struct *mm
34405 + mm->locked_vm = 0;
34406 + mm->mmap = NULL;
34407 + mm->mmap_cache = NULL;
34408 +- mm->free_area_cache = oldmm->mmap_base;
34409 +- mm->cached_hole_size = ~0UL;
34410 ++ mm->free_area_cache = oldmm->free_area_cache;
34411 ++ mm->cached_hole_size = oldmm->cached_hole_size;
34412 + mm->map_count = 0;
34413 + cpus_clear(mm->cpu_vm_mask);
34414 + mm->mm_rb = RB_ROOT;
34415 +@@ -288,6 +289,7 @@ static int dup_mmap(struct mm_struct *mm
34416 + tmp->vm_flags &= ~VM_LOCKED;
34417 + tmp->vm_mm = mm;
34418 + tmp->vm_next = NULL;
34419 ++ tmp->vm_mirror = NULL;
34420 + anon_vma_link(tmp);
34421 + file = tmp->vm_file;
34422 + if (file) {
34423 +@@ -324,6 +326,31 @@ static int dup_mmap(struct mm_struct *mm
34424 + if (retval)
34425 + goto out;
34426 + }
34427 ++
34428 ++#ifdef CONFIG_PAX_SEGMEXEC
34429 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
34430 ++ struct vm_area_struct *mpnt_m;
34431 ++
34432 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
34433 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
34434 ++
34435 ++ if (!mpnt->vm_mirror)
34436 ++ continue;
34437 ++
34438 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
34439 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
34440 ++ mpnt->vm_mirror = mpnt_m;
34441 ++ } else {
34442 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
34443 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
34444 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
34445 ++ mpnt->vm_mirror->vm_mirror = mpnt;
34446 ++ }
34447 ++ }
34448 ++ BUG_ON(mpnt_m);
34449 ++ }
34450 ++#endif
34451 ++
34452 + /* a new mm has just been created */
34453 + arch_dup_mmap(oldmm, mm);
34454 + retval = 0;
34455 +@@ -505,7 +532,7 @@ void mm_release(struct task_struct *tsk,
34456 + if (tsk->clear_child_tid
34457 + && !(tsk->flags & PF_SIGNALED)
34458 + && atomic_read(&mm->mm_users) > 1) {
34459 +- u32 __user * tidptr = tsk->clear_child_tid;
34460 ++ pid_t __user * tidptr = tsk->clear_child_tid;
34461 + tsk->clear_child_tid = NULL;
34462 +
34463 + /*
34464 +@@ -513,7 +540,7 @@ void mm_release(struct task_struct *tsk,
34465 + * not set up a proper pointer then tough luck.
34466 + */
34467 + put_user(0, tidptr);
34468 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
34469 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
34470 + }
34471 + }
34472 +
34473 +@@ -914,6 +941,9 @@ static struct task_struct *copy_process(
34474 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
34475 + #endif
34476 + retval = -EAGAIN;
34477 ++
34478 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
34479 ++
34480 + if (atomic_read(&p->user->processes) >=
34481 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
34482 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
34483 +@@ -1080,6 +1110,8 @@ static struct task_struct *copy_process(
34484 + if (clone_flags & CLONE_THREAD)
34485 + p->tgid = current->tgid;
34486 +
34487 ++ gr_copy_label(p);
34488 ++
34489 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
34490 + /*
34491 + * Clear TID on mm_release()?
34492 +@@ -1269,6 +1301,8 @@ bad_fork_cleanup_count:
34493 + bad_fork_free:
34494 + free_task(p);
34495 + fork_out:
34496 ++ gr_log_forkfail(retval);
34497 ++
34498 + return ERR_PTR(retval);
34499 + }
34500 +
34501 +@@ -1361,6 +1395,8 @@ long do_fork(unsigned long clone_flags,
34502 + if (clone_flags & CLONE_PARENT_SETTID)
34503 + put_user(nr, parent_tidptr);
34504 +
34505 ++ gr_handle_brute_check();
34506 ++
34507 + if (clone_flags & CLONE_VFORK) {
34508 + p->vfork_done = &vfork;
34509 + init_completion(&vfork);
34510 +diff -urNp linux-2.6.26.6/kernel/futex.c linux-2.6.26.6/kernel/futex.c
34511 +--- linux-2.6.26.6/kernel/futex.c 2008-10-08 23:24:05.000000000 -0400
34512 ++++ linux-2.6.26.6/kernel/futex.c 2008-10-11 21:55:52.000000000 -0400
34513 +@@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
34514 + struct page *page;
34515 + int err;
34516 +
34517 ++#ifdef CONFIG_PAX_SEGMEXEC
34518 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
34519 ++ return -EFAULT;
34520 ++#endif
34521 ++
34522 + /*
34523 + * The futex address must be "naturally" aligned.
34524 + */
34525 +@@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
34526 + * The futex is hashed differently depending on whether
34527 + * it's in a shared or private mapping. So check vma first.
34528 + */
34529 +- vma = find_extend_vma(mm, address);
34530 +- if (unlikely(!vma))
34531 ++ vma = find_vma(mm, address);
34532 ++ if (unlikely(!vma || address < vma->vm_start))
34533 + return -EFAULT;
34534 +
34535 + /*
34536 +@@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
34537 + struct restart_block *restart;
34538 + restart = &current_thread_info()->restart_block;
34539 + restart->fn = futex_wait_restart;
34540 +- restart->futex.uaddr = (u32 *)uaddr;
34541 ++ restart->futex.uaddr = uaddr;
34542 + restart->futex.val = val;
34543 + restart->futex.time = abs_time->tv64;
34544 + restart->futex.bitset = bitset;
34545 +@@ -1906,7 +1911,7 @@ retry:
34546 + */
34547 + static inline int fetch_robust_entry(struct robust_list __user **entry,
34548 + struct robust_list __user * __user *head,
34549 +- int *pi)
34550 ++ unsigned int *pi)
34551 + {
34552 + unsigned long uentry;
34553 +
34554 +diff -urNp linux-2.6.26.6/kernel/irq/handle.c linux-2.6.26.6/kernel/irq/handle.c
34555 +--- linux-2.6.26.6/kernel/irq/handle.c 2008-10-08 23:24:05.000000000 -0400
34556 ++++ linux-2.6.26.6/kernel/irq/handle.c 2008-10-11 21:54:20.000000000 -0400
34557 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
34558 + .depth = 1,
34559 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
34560 + #ifdef CONFIG_SMP
34561 +- .affinity = CPU_MASK_ALL
34562 ++ .affinity = CPU_MASK_ALL,
34563 ++ .cpu = 0,
34564 + #endif
34565 + }
34566 + };
34567 +diff -urNp linux-2.6.26.6/kernel/kallsyms.c linux-2.6.26.6/kernel/kallsyms.c
34568 +--- linux-2.6.26.6/kernel/kallsyms.c 2008-10-08 23:24:05.000000000 -0400
34569 ++++ linux-2.6.26.6/kernel/kallsyms.c 2008-10-11 21:54:20.000000000 -0400
34570 +@@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
34571 +
34572 + static inline int is_kernel(unsigned long addr)
34573 + {
34574 ++
34575 ++#ifdef CONFIG_PAX_KERNEXEC
34576 ++
34577 ++#ifdef CONFIG_MODULES
34578 ++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
34579 ++ ktla_ktva(addr) < (unsigned long)MODULES_END)
34580 ++ return 0;
34581 ++#endif
34582 ++
34583 ++ if (is_kernel_inittext(addr))
34584 ++ return 1;
34585 ++#endif
34586 ++
34587 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
34588 + return 1;
34589 + return in_gate_area_no_task(addr);
34590 +@@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
34591 +
34592 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
34593 + {
34594 +- iter->name[0] = '\0';
34595 + iter->nameoff = get_symbol_offset(new_pos);
34596 + iter->pos = new_pos;
34597 + }
34598 +@@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
34599 + struct kallsym_iter *iter;
34600 + int ret;
34601 +
34602 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
34603 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
34604 + if (!iter)
34605 + return -ENOMEM;
34606 + reset_iter(iter, 0);
34607 +@@ -472,7 +484,15 @@ static const struct file_operations kall
34608 +
34609 + static int __init kallsyms_init(void)
34610 + {
34611 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
34612 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
34613 ++ proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
34614 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
34615 ++ proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
34616 ++#endif
34617 ++#else
34618 + proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
34619 ++#endif
34620 + return 0;
34621 + }
34622 + __initcall(kallsyms_init);
34623 +diff -urNp linux-2.6.26.6/kernel/kmod.c linux-2.6.26.6/kernel/kmod.c
34624 +--- linux-2.6.26.6/kernel/kmod.c 2008-10-08 23:24:05.000000000 -0400
34625 ++++ linux-2.6.26.6/kernel/kmod.c 2008-10-11 21:54:20.000000000 -0400
34626 +@@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
34627 + return -ENOMEM;
34628 + }
34629 +
34630 +- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
34631 ++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
34632 + atomic_dec(&kmod_concurrent);
34633 + return ret;
34634 + }
34635 +diff -urNp linux-2.6.26.6/kernel/kprobes.c linux-2.6.26.6/kernel/kprobes.c
34636 +--- linux-2.6.26.6/kernel/kprobes.c 2008-10-08 23:24:05.000000000 -0400
34637 ++++ linux-2.6.26.6/kernel/kprobes.c 2008-10-11 21:54:20.000000000 -0400
34638 +@@ -174,7 +174,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
34639 + * kernel image and loaded module images reside. This is required
34640 + * so x86_64 can correctly handle the %rip-relative fixups.
34641 + */
34642 +- kip->insns = module_alloc(PAGE_SIZE);
34643 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
34644 + if (!kip->insns) {
34645 + kfree(kip);
34646 + return NULL;
34647 +@@ -206,7 +206,7 @@ static int __kprobes collect_one_slot(st
34648 + hlist_add_head(&kip->hlist,
34649 + &kprobe_insn_pages);
34650 + } else {
34651 +- module_free(NULL, kip->insns);
34652 ++ module_free_exec(NULL, kip->insns);
34653 + kfree(kip);
34654 + }
34655 + return 1;
34656 +diff -urNp linux-2.6.26.6/kernel/lockdep.c linux-2.6.26.6/kernel/lockdep.c
34657 +--- linux-2.6.26.6/kernel/lockdep.c 2008-10-08 23:24:05.000000000 -0400
34658 ++++ linux-2.6.26.6/kernel/lockdep.c 2008-10-11 21:54:20.000000000 -0400
34659 +@@ -598,6 +598,10 @@ static int static_obj(void *obj)
34660 + int i;
34661 + #endif
34662 +
34663 ++#ifdef CONFIG_PAX_KERNEXEC
34664 ++ start = (unsigned long )&_data;
34665 ++#endif
34666 ++
34667 + /*
34668 + * static variable?
34669 + */
34670 +@@ -609,9 +613,12 @@ static int static_obj(void *obj)
34671 + * percpu var?
34672 + */
34673 + for_each_possible_cpu(i) {
34674 ++#ifdef CONFIG_X86_32
34675 ++ start = per_cpu_offset(i);
34676 ++#else
34677 + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
34678 +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
34679 +- + per_cpu_offset(i);
34680 ++#endif
34681 ++ end = start + PERCPU_ENOUGH_ROOM;
34682 +
34683 + if ((addr >= start) && (addr < end))
34684 + return 1;
34685 +diff -urNp linux-2.6.26.6/kernel/module.c linux-2.6.26.6/kernel/module.c
34686 +--- linux-2.6.26.6/kernel/module.c 2008-10-08 23:24:05.000000000 -0400
34687 ++++ linux-2.6.26.6/kernel/module.c 2008-10-11 21:55:52.000000000 -0400
34688 +@@ -44,6 +44,11 @@
34689 + #include <linux/unwind.h>
34690 + #include <asm/uaccess.h>
34691 + #include <asm/cacheflush.h>
34692 ++
34693 ++#ifdef CONFIG_PAX_KERNEXEC
34694 ++#include <asm/desc.h>
34695 ++#endif
34696 ++
34697 + #include <linux/license.h>
34698 + #include <asm/sections.h>
34699 +
34700 +@@ -70,6 +75,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
34701 +
34702 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
34703 +
34704 ++extern int gr_check_modstop(void);
34705 ++
34706 + int register_module_notifier(struct notifier_block * nb)
34707 + {
34708 + return blocking_notifier_chain_register(&module_notify_list, nb);
34709 +@@ -273,7 +280,7 @@ static unsigned long find_symbol(const c
34710 +
34711 + /* Now try modules. */
34712 + list_for_each_entry(mod, &modules, list) {
34713 +- struct symsearch arr[] = {
34714 ++ struct symsearch modarr[] = {
34715 + { mod->syms, mod->syms + mod->num_syms, mod->crcs,
34716 + always_ok },
34717 + { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
34718 +@@ -289,7 +296,7 @@ static unsigned long find_symbol(const c
34719 + mod->unused_gpl_crcs, gpl_only_unused_warning },
34720 + };
34721 +
34722 +- ks = search_symarrays(arr, ARRAY_SIZE(arr),
34723 ++ ks = search_symarrays(modarr, ARRAY_SIZE(modarr),
34724 + name, gplok, warn, crc);
34725 + if (ks) {
34726 + if (owner)
34727 +@@ -352,6 +359,8 @@ static inline unsigned int block_size(in
34728 + return val;
34729 + }
34730 +
34731 ++EXPORT_SYMBOL(__per_cpu_start);
34732 ++
34733 + static void *percpu_modalloc(unsigned long size, unsigned long align,
34734 + const char *name)
34735 + {
34736 +@@ -359,7 +368,7 @@ static void *percpu_modalloc(unsigned lo
34737 + unsigned int i;
34738 + void *ptr;
34739 +
34740 +- if (align > PAGE_SIZE) {
34741 ++ if (align-1 >= PAGE_SIZE) {
34742 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
34743 + name, align, PAGE_SIZE);
34744 + align = PAGE_SIZE;
34745 +@@ -441,7 +450,11 @@ static void percpu_modcopy(void *pcpudes
34746 + int cpu;
34747 +
34748 + for_each_possible_cpu(cpu)
34749 ++#ifdef CONFIG_X86_32
34750 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
34751 ++#else
34752 + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
34753 ++#endif
34754 + }
34755 +
34756 + static int percpu_modinit(void)
34757 +@@ -692,6 +705,9 @@ sys_delete_module(const char __user *nam
34758 + char name[MODULE_NAME_LEN];
34759 + int ret, forced = 0;
34760 +
34761 ++ if (gr_check_modstop())
34762 ++ return -EPERM;
34763 ++
34764 + if (!capable(CAP_SYS_MODULE))
34765 + return -EPERM;
34766 +
34767 +@@ -1400,16 +1416,19 @@ static void free_module(struct module *m
34768 + module_unload_free(mod);
34769 +
34770 + /* This may be NULL, but that's OK */
34771 +- module_free(mod, mod->module_init);
34772 ++ module_free(mod, mod->module_init_rw);
34773 ++ module_free_exec(mod, mod->module_init_rx);
34774 + kfree(mod->args);
34775 + if (mod->percpu)
34776 + percpu_modfree(mod->percpu);
34777 +
34778 + /* Free lock-classes: */
34779 +- lockdep_free_key_range(mod->module_core, mod->core_size);
34780 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
34781 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
34782 +
34783 + /* Finally, free the core (containing the module structure) */
34784 +- module_free(mod, mod->module_core);
34785 ++ module_free_exec(mod, mod->module_core_rx);
34786 ++ module_free(mod, mod->module_core_rw);
34787 + }
34788 +
34789 + void *__symbol_get(const char *symbol)
34790 +@@ -1473,10 +1492,14 @@ static int simplify_symbols(Elf_Shdr *se
34791 + struct module *mod)
34792 + {
34793 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
34794 +- unsigned long secbase;
34795 ++ unsigned long secbase, symbol;
34796 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
34797 + int ret = 0;
34798 +
34799 ++#ifdef CONFIG_PAX_KERNEXEC
34800 ++ unsigned long cr0;
34801 ++#endif
34802 ++
34803 + for (i = 1; i < n; i++) {
34804 + switch (sym[i].st_shndx) {
34805 + case SHN_COMMON:
34806 +@@ -1495,10 +1518,19 @@ static int simplify_symbols(Elf_Shdr *se
34807 + break;
34808 +
34809 + case SHN_UNDEF:
34810 +- sym[i].st_value
34811 +- = resolve_symbol(sechdrs, versindex,
34812 ++ symbol = resolve_symbol(sechdrs, versindex,
34813 + strtab + sym[i].st_name, mod);
34814 +
34815 ++#ifdef CONFIG_PAX_KERNEXEC
34816 ++ pax_open_kernel(cr0);
34817 ++#endif
34818 ++
34819 ++ sym[i].st_value = symbol;
34820 ++
34821 ++#ifdef CONFIG_PAX_KERNEXEC
34822 ++ pax_close_kernel(cr0);
34823 ++#endif
34824 ++
34825 + /* Ok if resolved. */
34826 + if (!IS_ERR_VALUE(sym[i].st_value))
34827 + break;
34828 +@@ -1513,11 +1545,27 @@ static int simplify_symbols(Elf_Shdr *se
34829 +
34830 + default:
34831 + /* Divert to percpu allocation if a percpu var. */
34832 +- if (sym[i].st_shndx == pcpuindex)
34833 ++ if (sym[i].st_shndx == pcpuindex) {
34834 ++
34835 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
34836 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
34837 ++#else
34838 + secbase = (unsigned long)mod->percpu;
34839 +- else
34840 ++#endif
34841 ++
34842 ++ } else
34843 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
34844 ++
34845 ++#ifdef CONFIG_PAX_KERNEXEC
34846 ++ pax_open_kernel(cr0);
34847 ++#endif
34848 ++
34849 + sym[i].st_value += secbase;
34850 ++
34851 ++#ifdef CONFIG_PAX_KERNEXEC
34852 ++ pax_close_kernel(cr0);
34853 ++#endif
34854 ++
34855 + break;
34856 + }
34857 + }
34858 +@@ -1569,11 +1617,14 @@ static void layout_sections(struct modul
34859 + || strncmp(secstrings + s->sh_name,
34860 + ".init", 5) == 0)
34861 + continue;
34862 +- s->sh_entsize = get_offset(&mod->core_size, s);
34863 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
34864 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
34865 ++ else
34866 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
34867 + DEBUGP("\t%s\n", secstrings + s->sh_name);
34868 + }
34869 + if (m == 0)
34870 +- mod->core_text_size = mod->core_size;
34871 ++ mod->core_size_rx = mod->core_size_rx;
34872 + }
34873 +
34874 + DEBUGP("Init section allocation order:\n");
34875 +@@ -1587,12 +1638,15 @@ static void layout_sections(struct modul
34876 + || strncmp(secstrings + s->sh_name,
34877 + ".init", 5) != 0)
34878 + continue;
34879 +- s->sh_entsize = (get_offset(&mod->init_size, s)
34880 +- | INIT_OFFSET_MASK);
34881 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
34882 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
34883 ++ else
34884 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
34885 ++ s->sh_entsize |= INIT_OFFSET_MASK;
34886 + DEBUGP("\t%s\n", secstrings + s->sh_name);
34887 + }
34888 + if (m == 0)
34889 +- mod->init_text_size = mod->init_size;
34890 ++ mod->init_size_rx = mod->init_size_rx;
34891 + }
34892 + }
34893 +
34894 +@@ -1719,14 +1773,31 @@ static void add_kallsyms(struct module *
34895 + {
34896 + unsigned int i;
34897 +
34898 ++#ifdef CONFIG_PAX_KERNEXEC
34899 ++ unsigned long cr0;
34900 ++#endif
34901 ++
34902 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
34903 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
34904 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
34905 +
34906 + /* Set types up while we still have access to sections. */
34907 +- for (i = 0; i < mod->num_symtab; i++)
34908 +- mod->symtab[i].st_info
34909 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
34910 ++
34911 ++ for (i = 0; i < mod->num_symtab; i++) {
34912 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
34913 ++
34914 ++#ifdef CONFIG_PAX_KERNEXEC
34915 ++ pax_open_kernel(cr0);
34916 ++#endif
34917 ++
34918 ++ mod->symtab[i].st_info = type;
34919 ++
34920 ++#ifdef CONFIG_PAX_KERNEXEC
34921 ++ pax_close_kernel(cr0);
34922 ++#endif
34923 ++
34924 ++ }
34925 ++
34926 + }
34927 + #else
34928 + static inline void add_kallsyms(struct module *mod,
34929 +@@ -1776,6 +1847,10 @@ static struct module *load_module(void _
34930 + struct exception_table_entry *extable;
34931 + mm_segment_t old_fs;
34932 +
34933 ++#ifdef CONFIG_PAX_KERNEXEC
34934 ++ unsigned long cr0;
34935 ++#endif
34936 ++
34937 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
34938 + umod, len, uargs);
34939 + if (len < sizeof(*hdr))
34940 +@@ -1935,21 +2010,57 @@ static struct module *load_module(void _
34941 + layout_sections(mod, hdr, sechdrs, secstrings);
34942 +
34943 + /* Do the allocs. */
34944 +- ptr = module_alloc(mod->core_size);
34945 ++ ptr = module_alloc(mod->core_size_rw);
34946 + if (!ptr) {
34947 + err = -ENOMEM;
34948 + goto free_percpu;
34949 + }
34950 +- memset(ptr, 0, mod->core_size);
34951 +- mod->module_core = ptr;
34952 ++ memset(ptr, 0, mod->core_size_rw);
34953 ++ mod->module_core_rw = ptr;
34954 ++
34955 ++ ptr = module_alloc(mod->init_size_rw);
34956 ++ if (!ptr && mod->init_size_rw) {
34957 ++ err = -ENOMEM;
34958 ++ goto free_core_rw;
34959 ++ }
34960 ++ memset(ptr, 0, mod->init_size_rw);
34961 ++ mod->module_init_rw = ptr;
34962 ++
34963 ++ ptr = module_alloc_exec(mod->core_size_rx);
34964 ++ if (!ptr) {
34965 ++ err = -ENOMEM;
34966 ++ goto free_init_rw;
34967 ++ }
34968 +
34969 +- ptr = module_alloc(mod->init_size);
34970 +- if (!ptr && mod->init_size) {
34971 ++#ifdef CONFIG_PAX_KERNEXEC
34972 ++ pax_open_kernel(cr0);
34973 ++#endif
34974 ++
34975 ++ memset(ptr, 0, mod->core_size_rx);
34976 ++
34977 ++#ifdef CONFIG_PAX_KERNEXEC
34978 ++ pax_close_kernel(cr0);
34979 ++#endif
34980 ++
34981 ++ mod->module_core_rx = ptr;
34982 ++
34983 ++ ptr = module_alloc_exec(mod->init_size_rx);
34984 ++ if (!ptr && mod->init_size_rx) {
34985 + err = -ENOMEM;
34986 +- goto free_core;
34987 ++ goto free_core_rx;
34988 + }
34989 +- memset(ptr, 0, mod->init_size);
34990 +- mod->module_init = ptr;
34991 ++
34992 ++#ifdef CONFIG_PAX_KERNEXEC
34993 ++ pax_open_kernel(cr0);
34994 ++#endif
34995 ++
34996 ++ memset(ptr, 0, mod->init_size_rx);
34997 ++
34998 ++#ifdef CONFIG_PAX_KERNEXEC
34999 ++ pax_close_kernel(cr0);
35000 ++#endif
35001 ++
35002 ++ mod->module_init_rx = ptr;
35003 +
35004 + /* Transfer each section which specifies SHF_ALLOC */
35005 + DEBUGP("final section addresses:\n");
35006 +@@ -1959,17 +2070,41 @@ static struct module *load_module(void _
35007 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
35008 + continue;
35009 +
35010 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
35011 +- dest = mod->module_init
35012 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
35013 +- else
35014 +- dest = mod->module_core + sechdrs[i].sh_entsize;
35015 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
35016 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
35017 ++ dest = mod->module_init_rw
35018 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
35019 ++ else
35020 ++ dest = mod->module_init_rx
35021 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
35022 ++ } else {
35023 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
35024 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
35025 ++ else
35026 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
35027 ++ }
35028 ++
35029 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
35030 +
35031 +- if (sechdrs[i].sh_type != SHT_NOBITS)
35032 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
35033 +- sechdrs[i].sh_size);
35034 ++#ifdef CONFIG_PAX_KERNEXEC
35035 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
35036 ++ pax_open_kernel(cr0);
35037 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
35038 ++ pax_close_kernel(cr0);
35039 ++ } else
35040 ++#endif
35041 ++
35042 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
35043 ++ }
35044 + /* Update sh_addr to point to copy in image. */
35045 +- sechdrs[i].sh_addr = (unsigned long)dest;
35046 ++
35047 ++#ifdef CONFIG_PAX_KERNEXEC
35048 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
35049 ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
35050 ++ else
35051 ++#endif
35052 ++
35053 ++ sechdrs[i].sh_addr = (unsigned long)dest;
35054 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
35055 + }
35056 + /* Module has been moved. */
35057 +@@ -2052,8 +2187,8 @@ static struct module *load_module(void _
35058 +
35059 + /* Now do relocations. */
35060 + for (i = 1; i < hdr->e_shnum; i++) {
35061 +- const char *strtab = (char *)sechdrs[strindex].sh_addr;
35062 + unsigned int info = sechdrs[i].sh_info;
35063 ++ strtab = (char *)sechdrs[strindex].sh_addr;
35064 +
35065 + /* Not a valid relocation section? */
35066 + if (info >= hdr->e_shnum)
35067 +@@ -2112,12 +2247,12 @@ static struct module *load_module(void _
35068 + * Do it before processing of module parameters, so the module
35069 + * can provide parameter accessor functions of its own.
35070 + */
35071 +- if (mod->module_init)
35072 +- flush_icache_range((unsigned long)mod->module_init,
35073 +- (unsigned long)mod->module_init
35074 +- + mod->init_size);
35075 +- flush_icache_range((unsigned long)mod->module_core,
35076 +- (unsigned long)mod->module_core + mod->core_size);
35077 ++ if (mod->module_init_rx)
35078 ++ flush_icache_range((unsigned long)mod->module_init_rx,
35079 ++ (unsigned long)mod->module_init_rx
35080 ++ + mod->init_size_rx);
35081 ++ flush_icache_range((unsigned long)mod->module_core_rx,
35082 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
35083 +
35084 + set_fs(old_fs);
35085 +
35086 +@@ -2170,9 +2305,13 @@ static struct module *load_module(void _
35087 + kobject_put(&mod->mkobj.kobj);
35088 + free_unload:
35089 + module_unload_free(mod);
35090 +- module_free(mod, mod->module_init);
35091 +- free_core:
35092 +- module_free(mod, mod->module_core);
35093 ++ module_free_exec(mod, mod->module_init_rx);
35094 ++ free_core_rx:
35095 ++ module_free_exec(mod, mod->module_core_rx);
35096 ++ free_init_rw:
35097 ++ module_free(mod, mod->module_init_rw);
35098 ++ free_core_rw:
35099 ++ module_free(mod, mod->module_core_rw);
35100 + free_percpu:
35101 + if (percpu)
35102 + percpu_modfree(percpu);
35103 +@@ -2197,6 +2336,9 @@ sys_init_module(void __user *umod,
35104 + struct module *mod;
35105 + int ret = 0;
35106 +
35107 ++ if (gr_check_modstop())
35108 ++ return -EPERM;
35109 ++
35110 + /* Must have permission */
35111 + if (!capable(CAP_SYS_MODULE))
35112 + return -EPERM;
35113 +@@ -2252,10 +2394,12 @@ sys_init_module(void __user *umod,
35114 + /* Drop initial reference. */
35115 + module_put(mod);
35116 + unwind_remove_table(mod->unwind_info, 1);
35117 +- module_free(mod, mod->module_init);
35118 +- mod->module_init = NULL;
35119 +- mod->init_size = 0;
35120 +- mod->init_text_size = 0;
35121 ++ module_free(mod, mod->module_init_rw);
35122 ++ module_free_exec(mod, mod->module_init_rx);
35123 ++ mod->module_init_rw = NULL;
35124 ++ mod->module_init_rx = NULL;
35125 ++ mod->init_size_rw = 0;
35126 ++ mod->init_size_rx = 0;
35127 + mutex_unlock(&module_mutex);
35128 +
35129 + return 0;
35130 +@@ -2263,6 +2407,13 @@ sys_init_module(void __user *umod,
35131 +
35132 + static inline int within(unsigned long addr, void *start, unsigned long size)
35133 + {
35134 ++
35135 ++#ifdef CONFIG_PAX_KERNEXEC
35136 ++ if (ktla_ktva(addr) >= (unsigned long)start &&
35137 ++ ktla_ktva(addr) < (unsigned long)start + size)
35138 ++ return 1;
35139 ++#endif
35140 ++
35141 + return ((void *)addr >= start && (void *)addr < start + size);
35142 + }
35143 +
35144 +@@ -2286,10 +2437,14 @@ static const char *get_ksymbol(struct mo
35145 + unsigned long nextval;
35146 +
35147 + /* At worse, next value is at end of module */
35148 +- if (within(addr, mod->module_init, mod->init_size))
35149 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
35150 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
35151 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
35152 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
35153 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
35154 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
35155 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
35156 + else
35157 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
35158 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
35159 +
35160 + /* Scan for closest preceeding symbol, and next symbol. (ELF
35161 + starts real symbols at 1). */
35162 +@@ -2334,8 +2489,10 @@ const char *module_address_lookup(unsign
35163 +
35164 + preempt_disable();
35165 + list_for_each_entry(mod, &modules, list) {
35166 +- if (within(addr, mod->module_init, mod->init_size)
35167 +- || within(addr, mod->module_core, mod->core_size)) {
35168 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
35169 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
35170 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
35171 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35172 + if (modname)
35173 + *modname = mod->name;
35174 + ret = get_ksymbol(mod, addr, size, offset);
35175 +@@ -2357,8 +2514,10 @@ int lookup_module_symbol_name(unsigned l
35176 +
35177 + preempt_disable();
35178 + list_for_each_entry(mod, &modules, list) {
35179 +- if (within(addr, mod->module_init, mod->init_size) ||
35180 +- within(addr, mod->module_core, mod->core_size)) {
35181 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
35182 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
35183 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
35184 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35185 + const char *sym;
35186 +
35187 + sym = get_ksymbol(mod, addr, NULL, NULL);
35188 +@@ -2381,8 +2540,10 @@ int lookup_module_symbol_attrs(unsigned
35189 +
35190 + preempt_disable();
35191 + list_for_each_entry(mod, &modules, list) {
35192 +- if (within(addr, mod->module_init, mod->init_size) ||
35193 +- within(addr, mod->module_core, mod->core_size)) {
35194 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
35195 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
35196 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
35197 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35198 + const char *sym;
35199 +
35200 + sym = get_ksymbol(mod, addr, size, offset);
35201 +@@ -2513,7 +2674,7 @@ static int m_show(struct seq_file *m, vo
35202 + char buf[8];
35203 +
35204 + seq_printf(m, "%s %lu",
35205 +- mod->name, mod->init_size + mod->core_size);
35206 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
35207 + print_unload_info(m, mod);
35208 +
35209 + /* Informative for users. */
35210 +@@ -2522,7 +2683,7 @@ static int m_show(struct seq_file *m, vo
35211 + mod->state == MODULE_STATE_COMING ? "Loading":
35212 + "Live");
35213 + /* Used by oprofile and other similar tools. */
35214 +- seq_printf(m, " 0x%p", mod->module_core);
35215 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
35216 +
35217 + /* Taints info */
35218 + if (mod->taints)
35219 +@@ -2578,7 +2739,8 @@ int is_module_address(unsigned long addr
35220 + preempt_disable();
35221 +
35222 + list_for_each_entry(mod, &modules, list) {
35223 +- if (within(addr, mod->module_core, mod->core_size)) {
35224 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
35225 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
35226 + preempt_enable();
35227 + return 1;
35228 + }
35229 +@@ -2596,8 +2758,8 @@ struct module *__module_text_address(uns
35230 + struct module *mod;
35231 +
35232 + list_for_each_entry(mod, &modules, list)
35233 +- if (within(addr, mod->module_init, mod->init_text_size)
35234 +- || within(addr, mod->module_core, mod->core_text_size))
35235 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
35236 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
35237 + return mod;
35238 + return NULL;
35239 + }
35240 +diff -urNp linux-2.6.26.6/kernel/mutex.c linux-2.6.26.6/kernel/mutex.c
35241 +--- linux-2.6.26.6/kernel/mutex.c 2008-10-08 23:24:05.000000000 -0400
35242 ++++ linux-2.6.26.6/kernel/mutex.c 2008-10-11 21:54:20.000000000 -0400
35243 +@@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
35244 + *
35245 + * This function is similar to (but not equivalent to) down().
35246 + */
35247 +-void inline __sched mutex_lock(struct mutex *lock)
35248 ++inline void __sched mutex_lock(struct mutex *lock)
35249 + {
35250 + might_sleep();
35251 + /*
35252 +diff -urNp linux-2.6.26.6/kernel/panic.c linux-2.6.26.6/kernel/panic.c
35253 +--- linux-2.6.26.6/kernel/panic.c 2008-10-08 23:24:05.000000000 -0400
35254 ++++ linux-2.6.26.6/kernel/panic.c 2008-10-11 21:54:20.000000000 -0400
35255 +@@ -327,6 +327,8 @@ EXPORT_SYMBOL(warn_on_slowpath);
35256 + */
35257 + void __stack_chk_fail(void)
35258 + {
35259 ++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
35260 ++ dump_stack();
35261 + panic("stack-protector: Kernel stack is corrupted");
35262 + }
35263 + EXPORT_SYMBOL(__stack_chk_fail);
35264 +diff -urNp linux-2.6.26.6/kernel/pid.c linux-2.6.26.6/kernel/pid.c
35265 +--- linux-2.6.26.6/kernel/pid.c 2008-10-08 23:24:05.000000000 -0400
35266 ++++ linux-2.6.26.6/kernel/pid.c 2008-10-11 21:54:20.000000000 -0400
35267 +@@ -35,6 +35,7 @@
35268 + #include <linux/pid_namespace.h>
35269 + #include <linux/init_task.h>
35270 + #include <linux/syscalls.h>
35271 ++#include <linux/grsecurity.h>
35272 +
35273 + #define pid_hashfn(nr, ns) \
35274 + hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
35275 +@@ -44,7 +45,7 @@ struct pid init_struct_pid = INIT_STRUCT
35276 +
35277 + int pid_max = PID_MAX_DEFAULT;
35278 +
35279 +-#define RESERVED_PIDS 300
35280 ++#define RESERVED_PIDS 500
35281 +
35282 + int pid_max_min = RESERVED_PIDS + 1;
35283 + int pid_max_max = PID_MAX_LIMIT;
35284 +@@ -386,7 +387,14 @@ EXPORT_SYMBOL(pid_task);
35285 + struct task_struct *find_task_by_pid_type_ns(int type, int nr,
35286 + struct pid_namespace *ns)
35287 + {
35288 +- return pid_task(find_pid_ns(nr, ns), type);
35289 ++ struct task_struct *task;
35290 ++
35291 ++ task = pid_task(find_pid_ns(nr, ns), type);
35292 ++
35293 ++ if (gr_pid_is_chrooted(task))
35294 ++ return NULL;
35295 ++
35296 ++ return task;
35297 + }
35298 +
35299 + EXPORT_SYMBOL(find_task_by_pid_type_ns);
35300 +diff -urNp linux-2.6.26.6/kernel/posix-cpu-timers.c linux-2.6.26.6/kernel/posix-cpu-timers.c
35301 +--- linux-2.6.26.6/kernel/posix-cpu-timers.c 2008-10-08 23:24:05.000000000 -0400
35302 ++++ linux-2.6.26.6/kernel/posix-cpu-timers.c 2008-10-11 21:55:52.000000000 -0400
35303 +@@ -6,6 +6,7 @@
35304 + #include <linux/posix-timers.h>
35305 + #include <linux/errno.h>
35306 + #include <linux/math64.h>
35307 ++#include <linux/grsecurity.h>
35308 + #include <asm/uaccess.h>
35309 +
35310 + static int check_clock(const clockid_t which_clock)
35311 +@@ -1173,6 +1174,7 @@ static void check_process_timers(struct
35312 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
35313 + return;
35314 + }
35315 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
35316 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
35317 + /*
35318 + * At the soft limit, send a SIGXCPU every second.
35319 +@@ -1367,17 +1369,17 @@ void run_posix_cpu_timers(struct task_st
35320 + * timer call will interfere.
35321 + */
35322 + list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
35323 +- int firing;
35324 ++ int __firing;
35325 + spin_lock(&timer->it_lock);
35326 + list_del_init(&timer->it.cpu.entry);
35327 +- firing = timer->it.cpu.firing;
35328 ++ __firing = timer->it.cpu.firing;
35329 + timer->it.cpu.firing = 0;
35330 + /*
35331 + * The firing flag is -1 if we collided with a reset
35332 + * of the timer, which already reported this
35333 + * almost-firing as an overrun. So don't generate an event.
35334 + */
35335 +- if (likely(firing >= 0)) {
35336 ++ if (likely(__firing >= 0)) {
35337 + cpu_timer_fire(timer);
35338 + }
35339 + spin_unlock(&timer->it_lock);
35340 +diff -urNp linux-2.6.26.6/kernel/power/poweroff.c linux-2.6.26.6/kernel/power/poweroff.c
35341 +--- linux-2.6.26.6/kernel/power/poweroff.c 2008-10-08 23:24:05.000000000 -0400
35342 ++++ linux-2.6.26.6/kernel/power/poweroff.c 2008-10-11 21:54:20.000000000 -0400
35343 +@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
35344 + .enable_mask = SYSRQ_ENABLE_BOOT,
35345 + };
35346 +
35347 +-static int pm_sysrq_init(void)
35348 ++static int __init pm_sysrq_init(void)
35349 + {
35350 + register_sysrq_key('o', &sysrq_poweroff_op);
35351 + return 0;
35352 +diff -urNp linux-2.6.26.6/kernel/printk.c linux-2.6.26.6/kernel/printk.c
35353 +--- linux-2.6.26.6/kernel/printk.c 2008-10-08 23:24:05.000000000 -0400
35354 ++++ linux-2.6.26.6/kernel/printk.c 2008-10-11 21:54:20.000000000 -0400
35355 +@@ -32,6 +32,7 @@
35356 + #include <linux/security.h>
35357 + #include <linux/bootmem.h>
35358 + #include <linux/syscalls.h>
35359 ++#include <linux/grsecurity.h>
35360 +
35361 + #include <asm/uaccess.h>
35362 +
35363 +@@ -302,6 +303,11 @@ int do_syslog(int type, char __user *buf
35364 + char c;
35365 + int error = 0;
35366 +
35367 ++#ifdef CONFIG_GRKERNSEC_DMESG
35368 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
35369 ++ return -EPERM;
35370 ++#endif
35371 ++
35372 + error = security_syslog(type);
35373 + if (error)
35374 + return error;
35375 +diff -urNp linux-2.6.26.6/kernel/ptrace.c linux-2.6.26.6/kernel/ptrace.c
35376 +--- linux-2.6.26.6/kernel/ptrace.c 2008-10-08 23:24:05.000000000 -0400
35377 ++++ linux-2.6.26.6/kernel/ptrace.c 2008-10-11 21:54:20.000000000 -0400
35378 +@@ -21,6 +21,7 @@
35379 + #include <linux/audit.h>
35380 + #include <linux/pid_namespace.h>
35381 + #include <linux/syscalls.h>
35382 ++#include <linux/grsecurity.h>
35383 +
35384 + #include <asm/pgtable.h>
35385 + #include <asm/uaccess.h>
35386 +@@ -140,12 +141,12 @@ int __ptrace_may_attach(struct task_stru
35387 + (current->uid != task->uid) ||
35388 + (current->gid != task->egid) ||
35389 + (current->gid != task->sgid) ||
35390 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
35391 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
35392 + return -EPERM;
35393 + smp_rmb();
35394 + if (task->mm)
35395 + dumpable = get_dumpable(task->mm);
35396 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
35397 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
35398 + return -EPERM;
35399 +
35400 + return security_ptrace(current, task);
35401 +@@ -201,7 +202,7 @@ repeat:
35402 +
35403 + /* Go */
35404 + task->ptrace |= PT_PTRACED;
35405 +- if (capable(CAP_SYS_PTRACE))
35406 ++ if (capable_nolog(CAP_SYS_PTRACE))
35407 + task->ptrace |= PT_PTRACE_CAP;
35408 +
35409 + __ptrace_link(task, current);
35410 +@@ -571,6 +572,11 @@ asmlinkage long sys_ptrace(long request,
35411 + if (ret < 0)
35412 + goto out_put_task_struct;
35413 +
35414 ++ if (gr_handle_ptrace(child, request)) {
35415 ++ ret = -EPERM;
35416 ++ goto out_put_task_struct;
35417 ++ }
35418 ++
35419 + ret = arch_ptrace(child, request, addr, data);
35420 + if (ret < 0)
35421 + goto out_put_task_struct;
35422 +diff -urNp linux-2.6.26.6/kernel/relay.c linux-2.6.26.6/kernel/relay.c
35423 +--- linux-2.6.26.6/kernel/relay.c 2008-10-08 23:24:05.000000000 -0400
35424 ++++ linux-2.6.26.6/kernel/relay.c 2008-10-11 21:54:20.000000000 -0400
35425 +@@ -1179,7 +1179,7 @@ static int subbuf_splice_actor(struct fi
35426 + return 0;
35427 +
35428 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
35429 +- if (ret < 0 || ret < total_len)
35430 ++ if ((int)ret < 0 || ret < total_len)
35431 + return ret;
35432 +
35433 + if (read_start + ret == nonpad_end)
35434 +diff -urNp linux-2.6.26.6/kernel/resource.c linux-2.6.26.6/kernel/resource.c
35435 +--- linux-2.6.26.6/kernel/resource.c 2008-10-08 23:24:05.000000000 -0400
35436 ++++ linux-2.6.26.6/kernel/resource.c 2008-10-11 21:54:20.000000000 -0400
35437 +@@ -131,8 +131,18 @@ static const struct file_operations proc
35438 +
35439 + static int __init ioresources_init(void)
35440 + {
35441 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
35442 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
35443 ++ proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
35444 ++ proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
35445 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
35446 ++ proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
35447 ++ proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
35448 ++#endif
35449 ++#else
35450 + proc_create("ioports", 0, NULL, &proc_ioports_operations);
35451 + proc_create("iomem", 0, NULL, &proc_iomem_operations);
35452 ++#endif
35453 + return 0;
35454 + }
35455 + __initcall(ioresources_init);
35456 +diff -urNp linux-2.6.26.6/kernel/sched.c linux-2.6.26.6/kernel/sched.c
35457 +--- linux-2.6.26.6/kernel/sched.c 2008-10-08 23:24:05.000000000 -0400
35458 ++++ linux-2.6.26.6/kernel/sched.c 2008-10-11 21:54:20.000000000 -0400
35459 +@@ -70,6 +70,7 @@
35460 + #include <linux/bootmem.h>
35461 + #include <linux/debugfs.h>
35462 + #include <linux/ctype.h>
35463 ++#include <linux/grsecurity.h>
35464 +
35465 + #include <asm/tlb.h>
35466 + #include <asm/irq_regs.h>
35467 +@@ -4714,7 +4715,8 @@ asmlinkage long sys_nice(int increment)
35468 + if (nice > 19)
35469 + nice = 19;
35470 +
35471 +- if (increment < 0 && !can_nice(current, nice))
35472 ++ if (increment < 0 && (!can_nice(current, nice) ||
35473 ++ gr_handle_chroot_nice()))
35474 + return -EPERM;
35475 +
35476 + retval = security_task_setnice(current, nice);
35477 +@@ -5961,7 +5963,7 @@ static struct ctl_table sd_ctl_dir[] = {
35478 + .procname = "sched_domain",
35479 + .mode = 0555,
35480 + },
35481 +- {0, },
35482 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35483 + };
35484 +
35485 + static struct ctl_table sd_ctl_root[] = {
35486 +@@ -5971,7 +5973,7 @@ static struct ctl_table sd_ctl_root[] =
35487 + .mode = 0555,
35488 + .child = sd_ctl_dir,
35489 + },
35490 +- {0, },
35491 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35492 + };
35493 +
35494 + static struct ctl_table *sd_alloc_ctl_entry(int n)
35495 +diff -urNp linux-2.6.26.6/kernel/signal.c linux-2.6.26.6/kernel/signal.c
35496 +--- linux-2.6.26.6/kernel/signal.c 2008-10-08 23:24:05.000000000 -0400
35497 ++++ linux-2.6.26.6/kernel/signal.c 2008-10-11 21:55:52.000000000 -0400
35498 +@@ -25,6 +25,7 @@
35499 + #include <linux/capability.h>
35500 + #include <linux/freezer.h>
35501 + #include <linux/pid_namespace.h>
35502 ++#include <linux/grsecurity.h>
35503 + #include <linux/nsproxy.h>
35504 +
35505 + #include <asm/param.h>
35506 +@@ -597,6 +598,9 @@ static int check_kill_permission(int sig
35507 + }
35508 + }
35509 +
35510 ++ if (gr_handle_signal(t, sig))
35511 ++ return -EPERM;
35512 ++
35513 + return security_task_kill(t, info, sig, 0);
35514 + }
35515 +
35516 +@@ -888,8 +892,8 @@ static void print_fatal_signal(struct pt
35517 + for (i = 0; i < 16; i++) {
35518 + unsigned char insn;
35519 +
35520 +- __get_user(insn, (unsigned char *)(regs->ip + i));
35521 +- printk("%02x ", insn);
35522 ++ if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
35523 ++ printk("%02x ", insn);
35524 + }
35525 + }
35526 + #endif
35527 +@@ -912,7 +916,7 @@ __group_send_sig_info(int sig, struct si
35528 + return send_signal(sig, info, p, 1);
35529 + }
35530 +
35531 +-static int
35532 ++int
35533 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
35534 + {
35535 + return send_signal(sig, info, t, 0);
35536 +@@ -950,8 +954,12 @@ force_sig_info(int sig, struct siginfo *
35537 + if (action->sa.sa_handler == SIG_DFL)
35538 + t->signal->flags &= ~SIGNAL_UNKILLABLE;
35539 + ret = specific_send_sig_info(sig, info, t);
35540 ++
35541 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
35542 +
35543 ++ gr_log_signal(sig, t);
35544 ++ gr_handle_crash(t, sig);
35545 ++
35546 + return ret;
35547 + }
35548 +
35549 +@@ -1022,6 +1030,8 @@ int group_send_sig_info(int sig, struct
35550 + ret = __group_send_sig_info(sig, info, p);
35551 + unlock_task_sighand(p, &flags);
35552 + }
35553 ++ if (!ret)
35554 ++ gr_log_signal(sig, p);
35555 + }
35556 +
35557 + return ret;
35558 +diff -urNp linux-2.6.26.6/kernel/softirq.c linux-2.6.26.6/kernel/softirq.c
35559 +--- linux-2.6.26.6/kernel/softirq.c 2008-10-08 23:24:05.000000000 -0400
35560 ++++ linux-2.6.26.6/kernel/softirq.c 2008-10-11 21:54:20.000000000 -0400
35561 +@@ -482,9 +482,9 @@ void tasklet_kill(struct tasklet_struct
35562 + printk("Attempt to kill tasklet from interrupt\n");
35563 +
35564 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
35565 +- do
35566 ++ do {
35567 + yield();
35568 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
35569 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
35570 + }
35571 + tasklet_unlock_wait(t);
35572 + clear_bit(TASKLET_STATE_SCHED, &t->state);
35573 +diff -urNp linux-2.6.26.6/kernel/sys.c linux-2.6.26.6/kernel/sys.c
35574 +--- linux-2.6.26.6/kernel/sys.c 2008-10-08 23:24:05.000000000 -0400
35575 ++++ linux-2.6.26.6/kernel/sys.c 2008-10-11 21:54:20.000000000 -0400
35576 +@@ -33,6 +33,7 @@
35577 + #include <linux/task_io_accounting_ops.h>
35578 + #include <linux/seccomp.h>
35579 + #include <linux/cpu.h>
35580 ++#include <linux/grsecurity.h>
35581 +
35582 + #include <linux/compat.h>
35583 + #include <linux/syscalls.h>
35584 +@@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
35585 + error = -EACCES;
35586 + goto out;
35587 + }
35588 ++
35589 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
35590 ++ error = -EACCES;
35591 ++ goto out;
35592 ++ }
35593 ++
35594 + no_nice = security_task_setnice(p, niceval);
35595 + if (no_nice) {
35596 + error = no_nice;
35597 +@@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
35598 + if ((who != current->uid) && !(user = find_user(who)))
35599 + goto out_unlock; /* No processes for this user */
35600 +
35601 +- do_each_thread(g, p)
35602 ++ do_each_thread(g, p) {
35603 + if (p->uid == who)
35604 + error = set_one_prio(p, niceval, error);
35605 +- while_each_thread(g, p);
35606 ++ } while_each_thread(g, p);
35607 + if (who != current->uid)
35608 + free_uid(user); /* For find_user() */
35609 + break;
35610 +@@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
35611 + if ((who != current->uid) && !(user = find_user(who)))
35612 + goto out_unlock; /* No processes for this user */
35613 +
35614 +- do_each_thread(g, p)
35615 ++ do_each_thread(g, p) {
35616 + if (p->uid == who) {
35617 + niceval = 20 - task_nice(p);
35618 + if (niceval > retval)
35619 + retval = niceval;
35620 + }
35621 +- while_each_thread(g, p);
35622 ++ } while_each_thread(g, p);
35623 + if (who != current->uid)
35624 + free_uid(user); /* for find_user() */
35625 + break;
35626 +@@ -514,6 +521,10 @@ asmlinkage long sys_setregid(gid_t rgid,
35627 + else
35628 + return -EPERM;
35629 + }
35630 ++
35631 ++ if (gr_check_group_change(new_rgid, new_egid, -1))
35632 ++ return -EPERM;
35633 ++
35634 + if (new_egid != old_egid) {
35635 + set_dumpable(current->mm, suid_dumpable);
35636 + smp_wmb();
35637 +@@ -521,6 +532,9 @@ asmlinkage long sys_setregid(gid_t rgid,
35638 + if (rgid != (gid_t) -1 ||
35639 + (egid != (gid_t) -1 && egid != old_rgid))
35640 + current->sgid = new_egid;
35641 ++
35642 ++ gr_set_role_label(current, current->uid, new_rgid);
35643 ++
35644 + current->fsgid = new_egid;
35645 + current->egid = new_egid;
35646 + current->gid = new_rgid;
35647 +@@ -543,11 +557,17 @@ asmlinkage long sys_setgid(gid_t gid)
35648 + if (retval)
35649 + return retval;
35650 +
35651 ++ if (gr_check_group_change(gid, gid, gid))
35652 ++ return -EPERM;
35653 ++
35654 + if (capable(CAP_SETGID)) {
35655 + if (old_egid != gid) {
35656 + set_dumpable(current->mm, suid_dumpable);
35657 + smp_wmb();
35658 + }
35659 ++
35660 ++ gr_set_role_label(current, current->uid, gid);
35661 ++
35662 + current->gid = current->egid = current->sgid = current->fsgid = gid;
35663 + } else if ((gid == current->gid) || (gid == current->sgid)) {
35664 + if (old_egid != gid) {
35665 +@@ -585,6 +605,9 @@ static int set_user(uid_t new_ruid, int
35666 + set_dumpable(current->mm, suid_dumpable);
35667 + smp_wmb();
35668 + }
35669 ++
35670 ++ gr_set_role_label(current, new_ruid, current->gid);
35671 ++
35672 + current->uid = new_ruid;
35673 + return 0;
35674 + }
35675 +@@ -634,6 +657,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
35676 + return -EPERM;
35677 + }
35678 +
35679 ++ if (gr_check_user_change(new_ruid, new_euid, -1))
35680 ++ return -EPERM;
35681 ++
35682 + if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
35683 + return -EAGAIN;
35684 +
35685 +@@ -680,6 +706,12 @@ asmlinkage long sys_setuid(uid_t uid)
35686 + old_suid = current->suid;
35687 + new_suid = old_suid;
35688 +
35689 ++ if (gr_check_crash_uid(uid))
35690 ++ return -EPERM;
35691 ++
35692 ++ if (gr_check_user_change(uid, uid, uid))
35693 ++ return -EPERM;
35694 ++
35695 + if (capable(CAP_SETUID)) {
35696 + if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
35697 + return -EAGAIN;
35698 +@@ -727,6 +759,10 @@ asmlinkage long sys_setresuid(uid_t ruid
35699 + (suid != current->euid) && (suid != current->suid))
35700 + return -EPERM;
35701 + }
35702 ++
35703 ++ if (gr_check_user_change(ruid, euid, -1))
35704 ++ return -EPERM;
35705 ++
35706 + if (ruid != (uid_t) -1) {
35707 + if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
35708 + return -EAGAIN;
35709 +@@ -781,6 +817,10 @@ asmlinkage long sys_setresgid(gid_t rgid
35710 + (sgid != current->egid) && (sgid != current->sgid))
35711 + return -EPERM;
35712 + }
35713 ++
35714 ++ if (gr_check_group_change(rgid, egid, -1))
35715 ++ return -EPERM;
35716 ++
35717 + if (egid != (gid_t) -1) {
35718 + if (egid != current->egid) {
35719 + set_dumpable(current->mm, suid_dumpable);
35720 +@@ -789,8 +829,10 @@ asmlinkage long sys_setresgid(gid_t rgid
35721 + current->egid = egid;
35722 + }
35723 + current->fsgid = current->egid;
35724 +- if (rgid != (gid_t) -1)
35725 ++ if (rgid != (gid_t) -1) {
35726 ++ gr_set_role_label(current, current->uid, rgid);
35727 + current->gid = rgid;
35728 ++ }
35729 + if (sgid != (gid_t) -1)
35730 + current->sgid = sgid;
35731 +
35732 +@@ -825,6 +867,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
35733 + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
35734 + return old_fsuid;
35735 +
35736 ++ if (gr_check_user_change(-1, -1, uid))
35737 ++ return old_fsuid;
35738 ++
35739 + if (uid == current->uid || uid == current->euid ||
35740 + uid == current->suid || uid == current->fsuid ||
35741 + capable(CAP_SETUID)) {
35742 +@@ -857,6 +902,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
35743 + if (gid == current->gid || gid == current->egid ||
35744 + gid == current->sgid || gid == current->fsgid ||
35745 + capable(CAP_SETGID)) {
35746 ++ if (gr_check_group_change(-1, -1, gid))
35747 ++ return old_fsgid;
35748 ++
35749 + if (gid != old_fsgid) {
35750 + set_dumpable(current->mm, suid_dumpable);
35751 + smp_wmb();
35752 +@@ -938,7 +986,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
35753 + write_lock_irq(&tasklist_lock);
35754 +
35755 + err = -ESRCH;
35756 +- p = find_task_by_vpid(pid);
35757 ++ /* grsec: replaced find_task_by_vpid with equivalent call which
35758 ++ lacks the chroot restriction
35759 ++ */
35760 ++ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
35761 + if (!p)
35762 + goto out;
35763 +
35764 +@@ -1672,7 +1723,7 @@ asmlinkage long sys_prctl(int option, un
35765 + error = get_dumpable(current->mm);
35766 + break;
35767 + case PR_SET_DUMPABLE:
35768 +- if (arg2 < 0 || arg2 > 1) {
35769 ++ if (arg2 > 1) {
35770 + error = -EINVAL;
35771 + break;
35772 + }
35773 +diff -urNp linux-2.6.26.6/kernel/sysctl.c linux-2.6.26.6/kernel/sysctl.c
35774 +--- linux-2.6.26.6/kernel/sysctl.c 2008-10-08 23:24:05.000000000 -0400
35775 ++++ linux-2.6.26.6/kernel/sysctl.c 2008-10-11 21:54:20.000000000 -0400
35776 +@@ -59,6 +59,13 @@
35777 + static int deprecated_sysctl_warning(struct __sysctl_args *args);
35778 +
35779 + #if defined(CONFIG_SYSCTL)
35780 ++#include <linux/grsecurity.h>
35781 ++#include <linux/grinternal.h>
35782 ++
35783 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
35784 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
35785 ++ const int op);
35786 ++extern int gr_handle_chroot_sysctl(const int op);
35787 +
35788 + /* External variables not in a header file. */
35789 + extern int C_A_D;
35790 +@@ -152,6 +159,7 @@ static int proc_do_cad_pid(struct ctl_ta
35791 + static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
35792 + void __user *buffer, size_t *lenp, loff_t *ppos);
35793 + #endif
35794 ++extern ctl_table grsecurity_table[];
35795 +
35796 + static struct ctl_table root_table[];
35797 + static struct ctl_table_root sysctl_table_root;
35798 +@@ -179,6 +187,21 @@ extern struct ctl_table inotify_table[];
35799 + int sysctl_legacy_va_layout;
35800 + #endif
35801 +
35802 ++#ifdef CONFIG_PAX_SOFTMODE
35803 ++static ctl_table pax_table[] = {
35804 ++ {
35805 ++ .ctl_name = CTL_UNNUMBERED,
35806 ++ .procname = "softmode",
35807 ++ .data = &pax_softmode,
35808 ++ .maxlen = sizeof(unsigned int),
35809 ++ .mode = 0600,
35810 ++ .proc_handler = &proc_dointvec,
35811 ++ },
35812 ++
35813 ++ { .ctl_name = 0 }
35814 ++};
35815 ++#endif
35816 ++
35817 + extern int prove_locking;
35818 + extern int lock_stat;
35819 +
35820 +@@ -215,6 +238,7 @@ static struct ctl_table root_table[] = {
35821 + .mode = 0555,
35822 + .child = dev_table,
35823 + },
35824 ++
35825 + /*
35826 + * NOTE: do not add new entries to this table unless you have read
35827 + * Documentation/sysctl/ctl_unnumbered.txt
35828 +@@ -813,6 +837,25 @@ static struct ctl_table kern_table[] = {
35829 + .child = key_sysctls,
35830 + },
35831 + #endif
35832 ++
35833 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
35834 ++ {
35835 ++ .ctl_name = CTL_UNNUMBERED,
35836 ++ .procname = "grsecurity",
35837 ++ .mode = 0500,
35838 ++ .child = grsecurity_table,
35839 ++ },
35840 ++#endif
35841 ++
35842 ++#ifdef CONFIG_PAX_SOFTMODE
35843 ++ {
35844 ++ .ctl_name = CTL_UNNUMBERED,
35845 ++ .procname = "pax",
35846 ++ .mode = 0500,
35847 ++ .child = pax_table,
35848 ++ },
35849 ++#endif
35850 ++
35851 + /*
35852 + * NOTE: do not add new entries to this table unless you have read
35853 + * Documentation/sysctl/ctl_unnumbered.txt
35854 +@@ -1140,6 +1183,7 @@ static struct ctl_table vm_table[] = {
35855 + .extra2 = &one,
35856 + },
35857 + #endif
35858 ++
35859 + /*
35860 + * NOTE: do not add new entries to this table unless you have read
35861 + * Documentation/sysctl/ctl_unnumbered.txt
35862 +@@ -1472,6 +1516,8 @@ static int do_sysctl_strategy(struct ctl
35863 + return 0;
35864 + }
35865 +
35866 ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
35867 ++
35868 + static int parse_table(int __user *name, int nlen,
35869 + void __user *oldval, size_t __user *oldlenp,
35870 + void __user *newval, size_t newlen,
35871 +@@ -1490,7 +1536,7 @@ repeat:
35872 + if (n == table->ctl_name) {
35873 + int error;
35874 + if (table->child) {
35875 +- if (sysctl_perm(root, table, 001))
35876 ++ if (sysctl_perm_nochk(root, table, 001))
35877 + return -EPERM;
35878 + name++;
35879 + nlen--;
35880 +@@ -1575,6 +1621,33 @@ int sysctl_perm(struct ctl_table_root *r
35881 + int error;
35882 + int mode;
35883 +
35884 ++ if (table->parent != NULL && table->parent->procname != NULL &&
35885 ++ table->procname != NULL &&
35886 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
35887 ++ return -EACCES;
35888 ++ if (gr_handle_chroot_sysctl(op))
35889 ++ return -EACCES;
35890 ++ error = gr_handle_sysctl(table, op);
35891 ++ if (error)
35892 ++ return error;
35893 ++
35894 ++ error = security_sysctl(table, op);
35895 ++ if (error)
35896 ++ return error;
35897 ++
35898 ++ if (root->permissions)
35899 ++ mode = root->permissions(root, current->nsproxy, table);
35900 ++ else
35901 ++ mode = table->mode;
35902 ++
35903 ++ return test_perm(mode, op);
35904 ++}
35905 ++
35906 ++static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
35907 ++{
35908 ++ int error;
35909 ++ int mode;
35910 ++
35911 + error = security_sysctl(table, op);
35912 + if (error)
35913 + return error;
35914 +diff -urNp linux-2.6.26.6/kernel/time/tick-broadcast.c linux-2.6.26.6/kernel/time/tick-broadcast.c
35915 +--- linux-2.6.26.6/kernel/time/tick-broadcast.c 2008-10-08 23:24:05.000000000 -0400
35916 ++++ linux-2.6.26.6/kernel/time/tick-broadcast.c 2008-10-11 21:55:52.000000000 -0400
35917 +@@ -113,7 +113,7 @@ int tick_device_uses_broadcast(struct cl
35918 + * then clear the broadcast bit.
35919 + */
35920 + if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
35921 +- int cpu = smp_processor_id();
35922 ++ cpu = smp_processor_id();
35923 +
35924 + cpu_clear(cpu, tick_broadcast_mask);
35925 + tick_broadcast_clear_oneshot(cpu);
35926 +diff -urNp linux-2.6.26.6/kernel/time.c linux-2.6.26.6/kernel/time.c
35927 +--- linux-2.6.26.6/kernel/time.c 2008-10-08 23:24:05.000000000 -0400
35928 ++++ linux-2.6.26.6/kernel/time.c 2008-10-11 21:54:20.000000000 -0400
35929 +@@ -37,6 +37,7 @@
35930 + #include <linux/fs.h>
35931 + #include <linux/slab.h>
35932 + #include <linux/math64.h>
35933 ++#include <linux/grsecurity.h>
35934 +
35935 + #include <asm/uaccess.h>
35936 + #include <asm/unistd.h>
35937 +@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
35938 + return err;
35939 +
35940 + do_settimeofday(&tv);
35941 ++
35942 ++ gr_log_timechange();
35943 ++
35944 + return 0;
35945 + }
35946 +
35947 +@@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct
35948 + return -EFAULT;
35949 + }
35950 +
35951 ++ gr_log_timechange();
35952 ++
35953 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
35954 + }
35955 +
35956 +@@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
35957 + * Avoid unnecessary multiplications/divisions in the
35958 + * two most common HZ cases:
35959 + */
35960 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
35961 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
35962 + {
35963 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
35964 + return (MSEC_PER_SEC / HZ) * j;
35965 +@@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
35966 + }
35967 + EXPORT_SYMBOL(jiffies_to_msecs);
35968 +
35969 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
35970 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
35971 + {
35972 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
35973 + return (USEC_PER_SEC / HZ) * j;
35974 +diff -urNp linux-2.6.26.6/kernel/utsname_sysctl.c linux-2.6.26.6/kernel/utsname_sysctl.c
35975 +--- linux-2.6.26.6/kernel/utsname_sysctl.c 2008-10-08 23:24:05.000000000 -0400
35976 ++++ linux-2.6.26.6/kernel/utsname_sysctl.c 2008-10-11 21:54:20.000000000 -0400
35977 +@@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
35978 + .proc_handler = proc_do_uts_string,
35979 + .strategy = sysctl_uts_string,
35980 + },
35981 +- {}
35982 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35983 + };
35984 +
35985 + static struct ctl_table uts_root_table[] = {
35986 +@@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
35987 + .mode = 0555,
35988 + .child = uts_kern_table,
35989 + },
35990 +- {}
35991 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35992 + };
35993 +
35994 + static int __init utsname_sysctl_init(void)
35995 +diff -urNp linux-2.6.26.6/lib/radix-tree.c linux-2.6.26.6/lib/radix-tree.c
35996 +--- linux-2.6.26.6/lib/radix-tree.c 2008-10-08 23:24:05.000000000 -0400
35997 ++++ linux-2.6.26.6/lib/radix-tree.c 2008-10-11 21:54:20.000000000 -0400
35998 +@@ -81,7 +81,7 @@ struct radix_tree_preload {
35999 + int nr;
36000 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
36001 + };
36002 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
36003 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
36004 +
36005 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
36006 + {
36007 +diff -urNp linux-2.6.26.6/localversion-grsec linux-2.6.26.6/localversion-grsec
36008 +--- linux-2.6.26.6/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
36009 ++++ linux-2.6.26.6/localversion-grsec 2008-10-11 21:54:20.000000000 -0400
36010 +@@ -0,0 +1 @@
36011 ++-grsec
36012 +diff -urNp linux-2.6.26.6/Makefile linux-2.6.26.6/Makefile
36013 +--- linux-2.6.26.6/Makefile 2008-10-08 23:24:05.000000000 -0400
36014 ++++ linux-2.6.26.6/Makefile 2008-10-11 21:54:20.000000000 -0400
36015 +@@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
36016 +
36017 + HOSTCC = gcc
36018 + HOSTCXX = g++
36019 +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
36020 ++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
36021 + HOSTCXXFLAGS = -O2
36022 +
36023 + # Decide whether to build built-in, modular, or both.
36024 +@@ -607,7 +607,7 @@ export mod_strip_cmd
36025 +
36026 +
36027 + ifeq ($(KBUILD_EXTMOD),)
36028 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
36029 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
36030 +
36031 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
36032 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
36033 +diff -urNp linux-2.6.26.6/mm/filemap.c linux-2.6.26.6/mm/filemap.c
36034 +--- linux-2.6.26.6/mm/filemap.c 2008-10-08 23:24:05.000000000 -0400
36035 ++++ linux-2.6.26.6/mm/filemap.c 2008-10-11 21:54:20.000000000 -0400
36036 +@@ -33,6 +33,7 @@
36037 + #include <linux/cpuset.h>
36038 + #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
36039 + #include <linux/memcontrol.h>
36040 ++#include <linux/grsecurity.h>
36041 + #include "internal.h"
36042 +
36043 + /*
36044 +@@ -1488,7 +1489,7 @@ int generic_file_mmap(struct file * file
36045 + struct address_space *mapping = file->f_mapping;
36046 +
36047 + if (!mapping->a_ops->readpage)
36048 +- return -ENOEXEC;
36049 ++ return -ENODEV;
36050 + file_accessed(file);
36051 + vma->vm_ops = &generic_file_vm_ops;
36052 + vma->vm_flags |= VM_CAN_NONLINEAR;
36053 +@@ -1848,6 +1849,7 @@ inline int generic_write_checks(struct f
36054 + *pos = i_size_read(inode);
36055 +
36056 + if (limit != RLIM_INFINITY) {
36057 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
36058 + if (*pos >= limit) {
36059 + send_sig(SIGXFSZ, current, 0);
36060 + return -EFBIG;
36061 +diff -urNp linux-2.6.26.6/mm/fremap.c linux-2.6.26.6/mm/fremap.c
36062 +--- linux-2.6.26.6/mm/fremap.c 2008-10-08 23:24:05.000000000 -0400
36063 ++++ linux-2.6.26.6/mm/fremap.c 2008-10-11 21:54:20.000000000 -0400
36064 +@@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
36065 + retry:
36066 + vma = find_vma(mm, start);
36067 +
36068 ++#ifdef CONFIG_PAX_SEGMEXEC
36069 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
36070 ++ up_read(&mm->mmap_sem);
36071 ++ return err;
36072 ++ }
36073 ++#endif
36074 ++
36075 + /*
36076 + * Make sure the vma is shared, that it supports prefaulting,
36077 + * and that the remapped range is valid and fully within
36078 +diff -urNp linux-2.6.26.6/mm/hugetlb.c linux-2.6.26.6/mm/hugetlb.c
36079 +--- linux-2.6.26.6/mm/hugetlb.c 2008-10-08 23:24:05.000000000 -0400
36080 ++++ linux-2.6.26.6/mm/hugetlb.c 2008-10-11 21:55:52.000000000 -0400
36081 +@@ -603,7 +603,6 @@ static unsigned long set_max_huge_pages(
36082 + }
36083 +
36084 + while (count > persistent_huge_pages) {
36085 +- int ret;
36086 + /*
36087 + * If this allocation races such that we no longer need the
36088 + * page, free_huge_page will handle it by freeing the page
36089 +@@ -867,6 +866,26 @@ void unmap_hugepage_range(struct vm_area
36090 + }
36091 + }
36092 +
36093 ++#ifdef CONFIG_PAX_SEGMEXEC
36094 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
36095 ++{
36096 ++ struct mm_struct *mm = vma->vm_mm;
36097 ++ struct vm_area_struct *vma_m;
36098 ++ unsigned long address_m;
36099 ++ pte_t *ptep_m;
36100 ++
36101 ++ vma_m = pax_find_mirror_vma(vma);
36102 ++ if (!vma_m)
36103 ++ return;
36104 ++
36105 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36106 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36107 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
36108 ++ get_page(page_m);
36109 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
36110 ++}
36111 ++#endif
36112 ++
36113 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
36114 + unsigned long address, pte_t *ptep, pte_t pte)
36115 + {
36116 +@@ -902,6 +921,11 @@ static int hugetlb_cow(struct mm_struct
36117 + huge_ptep_clear_flush(vma, address, ptep);
36118 + set_huge_pte_at(mm, address, ptep,
36119 + make_huge_pte(vma, new_page, 1));
36120 ++
36121 ++#ifdef CONFIG_PAX_SEGMEXEC
36122 ++ pax_mirror_huge_pte(vma, address, new_page);
36123 ++#endif
36124 ++
36125 + /* Make the old page be freed below */
36126 + new_page = old_page;
36127 + }
36128 +@@ -974,6 +998,10 @@ retry:
36129 + && (vma->vm_flags & VM_SHARED)));
36130 + set_huge_pte_at(mm, address, ptep, new_pte);
36131 +
36132 ++#ifdef CONFIG_PAX_SEGMEXEC
36133 ++ pax_mirror_huge_pte(vma, address, page);
36134 ++#endif
36135 ++
36136 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
36137 + /* Optimization, do the COW without a second fault */
36138 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
36139 +@@ -999,6 +1027,27 @@ int hugetlb_fault(struct mm_struct *mm,
36140 + int ret;
36141 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
36142 +
36143 ++#ifdef CONFIG_PAX_SEGMEXEC
36144 ++ struct vm_area_struct *vma_m;
36145 ++
36146 ++ vma_m = pax_find_mirror_vma(vma);
36147 ++ if (vma_m) {
36148 ++ unsigned long address_m;
36149 ++
36150 ++ if (vma->vm_start > vma_m->vm_start) {
36151 ++ address_m = address;
36152 ++ address -= SEGMEXEC_TASK_SIZE;
36153 ++ vma = vma_m;
36154 ++ } else
36155 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36156 ++
36157 ++ if (!huge_pte_alloc(mm, address_m))
36158 ++ return VM_FAULT_OOM;
36159 ++ address_m &= HPAGE_MASK;
36160 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
36161 ++ }
36162 ++#endif
36163 ++
36164 + ptep = huge_pte_alloc(mm, address);
36165 + if (!ptep)
36166 + return VM_FAULT_OOM;
36167 +diff -urNp linux-2.6.26.6/mm/madvise.c linux-2.6.26.6/mm/madvise.c
36168 +--- linux-2.6.26.6/mm/madvise.c 2008-10-08 23:24:05.000000000 -0400
36169 ++++ linux-2.6.26.6/mm/madvise.c 2008-10-11 21:54:20.000000000 -0400
36170 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
36171 + pgoff_t pgoff;
36172 + int new_flags = vma->vm_flags;
36173 +
36174 ++#ifdef CONFIG_PAX_SEGMEXEC
36175 ++ struct vm_area_struct *vma_m;
36176 ++#endif
36177 ++
36178 + switch (behavior) {
36179 + case MADV_NORMAL:
36180 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
36181 +@@ -92,6 +96,13 @@ success:
36182 + /*
36183 + * vm_flags is protected by the mmap_sem held in write mode.
36184 + */
36185 ++
36186 ++#ifdef CONFIG_PAX_SEGMEXEC
36187 ++ vma_m = pax_find_mirror_vma(vma);
36188 ++ if (vma_m)
36189 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
36190 ++#endif
36191 ++
36192 + vma->vm_flags = new_flags;
36193 +
36194 + out:
36195 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
36196 +
36197 + case MADV_DONTNEED:
36198 + error = madvise_dontneed(vma, prev, start, end);
36199 ++
36200 ++#ifdef CONFIG_PAX_SEGMEXEC
36201 ++ if (!error) {
36202 ++ struct vm_area_struct *vma_m, *prev_m;
36203 ++
36204 ++ vma_m = pax_find_mirror_vma(vma);
36205 ++ if (vma_m)
36206 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
36207 ++ }
36208 ++#endif
36209 ++
36210 + break;
36211 +
36212 + default:
36213 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
36214 + if (end < start)
36215 + goto out;
36216 +
36217 ++#ifdef CONFIG_PAX_SEGMEXEC
36218 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
36219 ++ if (end > SEGMEXEC_TASK_SIZE)
36220 ++ goto out;
36221 ++ } else
36222 ++#endif
36223 ++
36224 ++ if (end > TASK_SIZE)
36225 ++ goto out;
36226 ++
36227 + error = 0;
36228 + if (end == start)
36229 + goto out;
36230 +diff -urNp linux-2.6.26.6/mm/memory.c linux-2.6.26.6/mm/memory.c
36231 +--- linux-2.6.26.6/mm/memory.c 2008-10-08 23:24:05.000000000 -0400
36232 ++++ linux-2.6.26.6/mm/memory.c 2008-10-11 21:54:20.000000000 -0400
36233 +@@ -51,6 +51,7 @@
36234 + #include <linux/init.h>
36235 + #include <linux/writeback.h>
36236 + #include <linux/memcontrol.h>
36237 ++#include <linux/grsecurity.h>
36238 +
36239 + #include <asm/pgalloc.h>
36240 + #include <asm/uaccess.h>
36241 +@@ -1082,11 +1083,11 @@ int get_user_pages(struct task_struct *t
36242 + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
36243 + i = 0;
36244 +
36245 +- do {
36246 ++ while (len) {
36247 + struct vm_area_struct *vma;
36248 + unsigned int foll_flags;
36249 +
36250 +- vma = find_extend_vma(mm, start);
36251 ++ vma = find_vma(mm, start);
36252 + if (!vma && in_gate_area(tsk, start)) {
36253 + unsigned long pg = start & PAGE_MASK;
36254 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
36255 +@@ -1126,7 +1127,7 @@ int get_user_pages(struct task_struct *t
36256 + continue;
36257 + }
36258 +
36259 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
36260 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
36261 + || !(vm_flags & vma->vm_flags))
36262 + return i ? : -EFAULT;
36263 +
36264 +@@ -1199,7 +1200,7 @@ int get_user_pages(struct task_struct *t
36265 + start += PAGE_SIZE;
36266 + len--;
36267 + } while (len && start < vma->vm_end);
36268 +- } while (len);
36269 ++ }
36270 + return i;
36271 + }
36272 + EXPORT_SYMBOL(get_user_pages);
36273 +@@ -1668,6 +1669,186 @@ static inline void cow_user_page(struct
36274 + copy_user_highpage(dst, src, va, vma);
36275 + }
36276 +
36277 ++#ifdef CONFIG_PAX_SEGMEXEC
36278 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
36279 ++{
36280 ++ struct mm_struct *mm = vma->vm_mm;
36281 ++ spinlock_t *ptl;
36282 ++ pte_t *pte, entry;
36283 ++
36284 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
36285 ++ entry = *pte;
36286 ++ if (!pte_present(entry)) {
36287 ++ if (!pte_none(entry)) {
36288 ++ BUG_ON(pte_file(entry));
36289 ++ free_swap_and_cache(pte_to_swp_entry(entry));
36290 ++ pte_clear_not_present_full(mm, address, pte, 0);
36291 ++ }
36292 ++ } else {
36293 ++ struct page *page;
36294 ++
36295 ++ flush_cache_page(vma, address, pte_pfn(entry));
36296 ++ entry = ptep_clear_flush(vma, address, pte);
36297 ++ BUG_ON(pte_dirty(entry));
36298 ++ page = vm_normal_page(vma, address, entry);
36299 ++ if (page) {
36300 ++ update_hiwater_rss(mm);
36301 ++ if (PageAnon(page))
36302 ++ dec_mm_counter(mm, anon_rss);
36303 ++ else
36304 ++ dec_mm_counter(mm, file_rss);
36305 ++ page_remove_rmap(page, vma);
36306 ++ page_cache_release(page);
36307 ++ }
36308 ++ }
36309 ++ pte_unmap_unlock(pte, ptl);
36310 ++}
36311 ++
36312 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
36313 ++ *
36314 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
36315 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
36316 ++ */
36317 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
36318 ++{
36319 ++ struct mm_struct *mm = vma->vm_mm;
36320 ++ unsigned long address_m;
36321 ++ spinlock_t *ptl_m;
36322 ++ struct vm_area_struct *vma_m;
36323 ++ pmd_t *pmd_m;
36324 ++ pte_t *pte_m, entry_m;
36325 ++
36326 ++ BUG_ON(!page_m || !PageAnon(page_m));
36327 ++
36328 ++ vma_m = pax_find_mirror_vma(vma);
36329 ++ if (!vma_m)
36330 ++ return;
36331 ++
36332 ++ BUG_ON(!PageLocked(page_m));
36333 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36334 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36335 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
36336 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
36337 ++ ptl_m = pte_lockptr(mm, pmd_m);
36338 ++ if (ptl != ptl_m) {
36339 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
36340 ++ if (!pte_none(*pte_m))
36341 ++ goto out;
36342 ++ }
36343 ++
36344 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
36345 ++ page_cache_get(page_m);
36346 ++ page_add_anon_rmap(page_m, vma_m, address_m);
36347 ++ inc_mm_counter(mm, anon_rss);
36348 ++ set_pte_at(mm, address_m, pte_m, entry_m);
36349 ++ update_mmu_cache(vma_m, address_m, entry_m);
36350 ++out:
36351 ++ if (ptl != ptl_m)
36352 ++ spin_unlock(ptl_m);
36353 ++ pte_unmap_nested(pte_m);
36354 ++ unlock_page(page_m);
36355 ++}
36356 ++
36357 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
36358 ++{
36359 ++ struct mm_struct *mm = vma->vm_mm;
36360 ++ unsigned long address_m;
36361 ++ spinlock_t *ptl_m;
36362 ++ struct vm_area_struct *vma_m;
36363 ++ pmd_t *pmd_m;
36364 ++ pte_t *pte_m, entry_m;
36365 ++
36366 ++ BUG_ON(!page_m || PageAnon(page_m));
36367 ++
36368 ++ vma_m = pax_find_mirror_vma(vma);
36369 ++ if (!vma_m)
36370 ++ return;
36371 ++
36372 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36373 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36374 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
36375 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
36376 ++ ptl_m = pte_lockptr(mm, pmd_m);
36377 ++ if (ptl != ptl_m) {
36378 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
36379 ++ if (!pte_none(*pte_m))
36380 ++ goto out;
36381 ++ }
36382 ++
36383 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
36384 ++ page_cache_get(page_m);
36385 ++ page_add_file_rmap(page_m);
36386 ++ inc_mm_counter(mm, file_rss);
36387 ++ set_pte_at(mm, address_m, pte_m, entry_m);
36388 ++ update_mmu_cache(vma_m, address_m, entry_m);
36389 ++out:
36390 ++ if (ptl != ptl_m)
36391 ++ spin_unlock(ptl_m);
36392 ++ pte_unmap_nested(pte_m);
36393 ++}
36394 ++
36395 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
36396 ++{
36397 ++ struct mm_struct *mm = vma->vm_mm;
36398 ++ unsigned long address_m;
36399 ++ spinlock_t *ptl_m;
36400 ++ struct vm_area_struct *vma_m;
36401 ++ pmd_t *pmd_m;
36402 ++ pte_t *pte_m, entry_m;
36403 ++
36404 ++ vma_m = pax_find_mirror_vma(vma);
36405 ++ if (!vma_m)
36406 ++ return;
36407 ++
36408 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
36409 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36410 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
36411 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
36412 ++ ptl_m = pte_lockptr(mm, pmd_m);
36413 ++ if (ptl != ptl_m) {
36414 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
36415 ++ if (!pte_none(*pte_m))
36416 ++ goto out;
36417 ++ }
36418 ++
36419 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
36420 ++ set_pte_at(mm, address_m, pte_m, entry_m);
36421 ++out:
36422 ++ if (ptl != ptl_m)
36423 ++ spin_unlock(ptl_m);
36424 ++ pte_unmap_nested(pte_m);
36425 ++}
36426 ++
36427 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
36428 ++{
36429 ++ struct page *page_m;
36430 ++ pte_t entry;
36431 ++
36432 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
36433 ++ goto out;
36434 ++
36435 ++ entry = *pte;
36436 ++ page_m = vm_normal_page(vma, address, entry);
36437 ++ if (!page_m)
36438 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
36439 ++ else if (PageAnon(page_m)) {
36440 ++ if (pax_find_mirror_vma(vma)) {
36441 ++ pte_unmap_unlock(pte, ptl);
36442 ++ lock_page(page_m);
36443 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
36444 ++ if (pte_same(entry, *pte))
36445 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
36446 ++ else
36447 ++ unlock_page(page_m);
36448 ++ }
36449 ++ } else
36450 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
36451 ++
36452 ++out:
36453 ++ pte_unmap_unlock(pte, ptl);
36454 ++}
36455 ++#endif
36456 ++
36457 + /*
36458 + * This routine handles present pages, when users try to write
36459 + * to a shared page. It is done by copying the page to a new address
36460 +@@ -1796,6 +1977,12 @@ gotten:
36461 + */
36462 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
36463 + if (likely(pte_same(*page_table, orig_pte))) {
36464 ++
36465 ++#ifdef CONFIG_PAX_SEGMEXEC
36466 ++ if (pax_find_mirror_vma(vma))
36467 ++ BUG_ON(TestSetPageLocked(new_page));
36468 ++#endif
36469 ++
36470 + if (old_page) {
36471 + if (!PageAnon(old_page)) {
36472 + dec_mm_counter(mm, file_rss);
36473 +@@ -1844,6 +2031,10 @@ gotten:
36474 + page_remove_rmap(old_page, vma);
36475 + }
36476 +
36477 ++#ifdef CONFIG_PAX_SEGMEXEC
36478 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
36479 ++#endif
36480 ++
36481 + /* Free the old page.. */
36482 + new_page = old_page;
36483 + ret |= VM_FAULT_WRITE;
36484 +@@ -2103,6 +2294,7 @@ int vmtruncate(struct inode * inode, lof
36485 + unsigned long limit;
36486 +
36487 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
36488 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
36489 + if (limit != RLIM_INFINITY && offset > limit)
36490 + goto out_sig;
36491 + if (offset > inode->i_sb->s_maxbytes)
36492 +@@ -2253,6 +2445,11 @@ static int do_swap_page(struct mm_struct
36493 + swap_free(entry);
36494 + if (vm_swap_full())
36495 + remove_exclusive_swap_page(page);
36496 ++
36497 ++#ifdef CONFIG_PAX_SEGMEXEC
36498 ++ if (write_access || !pax_find_mirror_vma(vma))
36499 ++#endif
36500 ++
36501 + unlock_page(page);
36502 +
36503 + if (write_access) {
36504 +@@ -2264,6 +2461,11 @@ static int do_swap_page(struct mm_struct
36505 +
36506 + /* No need to invalidate - it was non-present before */
36507 + update_mmu_cache(vma, address, pte);
36508 ++
36509 ++#ifdef CONFIG_PAX_SEGMEXEC
36510 ++ pax_mirror_anon_pte(vma, address, page, ptl);
36511 ++#endif
36512 ++
36513 + unlock:
36514 + pte_unmap_unlock(page_table, ptl);
36515 + out:
36516 +@@ -2308,6 +2510,12 @@ static int do_anonymous_page(struct mm_s
36517 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
36518 + if (!pte_none(*page_table))
36519 + goto release;
36520 ++
36521 ++#ifdef CONFIG_PAX_SEGMEXEC
36522 ++ if (pax_find_mirror_vma(vma))
36523 ++ BUG_ON(TestSetPageLocked(page));
36524 ++#endif
36525 ++
36526 + inc_mm_counter(mm, anon_rss);
36527 + lru_cache_add_active(page);
36528 + page_add_new_anon_rmap(page, vma, address);
36529 +@@ -2315,6 +2523,11 @@ static int do_anonymous_page(struct mm_s
36530 +
36531 + /* No need to invalidate - it was non-present before */
36532 + update_mmu_cache(vma, address, entry);
36533 ++
36534 ++#ifdef CONFIG_PAX_SEGMEXEC
36535 ++ pax_mirror_anon_pte(vma, address, page, ptl);
36536 ++#endif
36537 ++
36538 + unlock:
36539 + pte_unmap_unlock(page_table, ptl);
36540 + return 0;
36541 +@@ -2443,6 +2656,12 @@ static int __do_fault(struct mm_struct *
36542 + */
36543 + /* Only go through if we didn't race with anybody else... */
36544 + if (likely(pte_same(*page_table, orig_pte))) {
36545 ++
36546 ++#ifdef CONFIG_PAX_SEGMEXEC
36547 ++ if (anon && pax_find_mirror_vma(vma))
36548 ++ BUG_ON(TestSetPageLocked(page));
36549 ++#endif
36550 ++
36551 + flush_icache_page(vma, page);
36552 + entry = mk_pte(page, vma->vm_page_prot);
36553 + if (flags & FAULT_FLAG_WRITE)
36554 +@@ -2463,6 +2682,14 @@ static int __do_fault(struct mm_struct *
36555 +
36556 + /* no need to invalidate: a not-present page won't be cached */
36557 + update_mmu_cache(vma, address, entry);
36558 ++
36559 ++#ifdef CONFIG_PAX_SEGMEXEC
36560 ++ if (anon)
36561 ++ pax_mirror_anon_pte(vma, address, page, ptl);
36562 ++ else
36563 ++ pax_mirror_file_pte(vma, address, page, ptl);
36564 ++#endif
36565 ++
36566 + } else {
36567 + mem_cgroup_uncharge_page(page);
36568 + if (anon)
36569 +@@ -2549,6 +2776,11 @@ static noinline int do_no_pfn(struct mm_
36570 + if (write_access)
36571 + entry = maybe_mkwrite(pte_mkdirty(entry), vma);
36572 + set_pte_at(mm, address, page_table, entry);
36573 ++
36574 ++#ifdef CONFIG_PAX_SEGMEXEC
36575 ++ pax_mirror_pfn_pte(vma, address, pfn, ptl);
36576 ++#endif
36577 ++
36578 + }
36579 + pte_unmap_unlock(page_table, ptl);
36580 + return 0;
36581 +@@ -2651,6 +2883,12 @@ static inline int handle_pte_fault(struc
36582 + if (write_access)
36583 + flush_tlb_page(vma, address);
36584 + }
36585 ++
36586 ++#ifdef CONFIG_PAX_SEGMEXEC
36587 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
36588 ++ return 0;
36589 ++#endif
36590 ++
36591 + unlock:
36592 + pte_unmap_unlock(pte, ptl);
36593 + return 0;
36594 +@@ -2667,6 +2905,10 @@ int handle_mm_fault(struct mm_struct *mm
36595 + pmd_t *pmd;
36596 + pte_t *pte;
36597 +
36598 ++#ifdef CONFIG_PAX_SEGMEXEC
36599 ++ struct vm_area_struct *vma_m;
36600 ++#endif
36601 ++
36602 + __set_current_state(TASK_RUNNING);
36603 +
36604 + count_vm_event(PGFAULT);
36605 +@@ -2674,6 +2916,34 @@ int handle_mm_fault(struct mm_struct *mm
36606 + if (unlikely(is_vm_hugetlb_page(vma)))
36607 + return hugetlb_fault(mm, vma, address, write_access);
36608 +
36609 ++#ifdef CONFIG_PAX_SEGMEXEC
36610 ++ vma_m = pax_find_mirror_vma(vma);
36611 ++ if (vma_m) {
36612 ++ unsigned long address_m;
36613 ++ pgd_t *pgd_m;
36614 ++ pud_t *pud_m;
36615 ++ pmd_t *pmd_m;
36616 ++
36617 ++ if (vma->vm_start > vma_m->vm_start) {
36618 ++ address_m = address;
36619 ++ address -= SEGMEXEC_TASK_SIZE;
36620 ++ vma = vma_m;
36621 ++ } else
36622 ++ address_m = address + SEGMEXEC_TASK_SIZE;
36623 ++
36624 ++ pgd_m = pgd_offset(mm, address_m);
36625 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
36626 ++ if (!pud_m)
36627 ++ return VM_FAULT_OOM;
36628 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
36629 ++ if (!pmd_m)
36630 ++ return VM_FAULT_OOM;
36631 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
36632 ++ return VM_FAULT_OOM;
36633 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
36634 ++ }
36635 ++#endif
36636 ++
36637 + pgd = pgd_offset(mm, address);
36638 + pud = pud_alloc(mm, pgd, address);
36639 + if (!pud)
36640 +@@ -2781,7 +3051,7 @@ static int __init gate_vma_init(void)
36641 + gate_vma.vm_start = FIXADDR_USER_START;
36642 + gate_vma.vm_end = FIXADDR_USER_END;
36643 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
36644 +- gate_vma.vm_page_prot = __P101;
36645 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
36646 + /*
36647 + * Make sure the vDSO gets into every core dump.
36648 + * Dumping its contents makes post-mortem fully interpretable later
36649 +diff -urNp linux-2.6.26.6/mm/mempolicy.c linux-2.6.26.6/mm/mempolicy.c
36650 +--- linux-2.6.26.6/mm/mempolicy.c 2008-10-08 23:24:05.000000000 -0400
36651 ++++ linux-2.6.26.6/mm/mempolicy.c 2008-10-11 21:54:20.000000000 -0400
36652 +@@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
36653 + struct vm_area_struct *next;
36654 + int err;
36655 +
36656 ++#ifdef CONFIG_PAX_SEGMEXEC
36657 ++ struct vm_area_struct *vma_m;
36658 ++#endif
36659 ++
36660 + err = 0;
36661 + for (; vma && vma->vm_start < end; vma = next) {
36662 + next = vma->vm_next;
36663 +@@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
36664 + err = policy_vma(vma, new);
36665 + if (err)
36666 + break;
36667 ++
36668 ++#ifdef CONFIG_PAX_SEGMEXEC
36669 ++ vma_m = pax_find_mirror_vma(vma);
36670 ++ if (vma_m) {
36671 ++ err = policy_vma(vma_m, new);
36672 ++ if (err)
36673 ++ break;
36674 ++ }
36675 ++#endif
36676 ++
36677 + }
36678 + return err;
36679 + }
36680 +@@ -952,6 +966,17 @@ static long do_mbind(unsigned long start
36681 +
36682 + if (end < start)
36683 + return -EINVAL;
36684 ++
36685 ++#ifdef CONFIG_PAX_SEGMEXEC
36686 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
36687 ++ if (end > SEGMEXEC_TASK_SIZE)
36688 ++ return -EINVAL;
36689 ++ } else
36690 ++#endif
36691 ++
36692 ++ if (end > TASK_SIZE)
36693 ++ return -EINVAL;
36694 ++
36695 + if (end == start)
36696 + return 0;
36697 +
36698 +diff -urNp linux-2.6.26.6/mm/mlock.c linux-2.6.26.6/mm/mlock.c
36699 +--- linux-2.6.26.6/mm/mlock.c 2008-10-08 23:24:05.000000000 -0400
36700 ++++ linux-2.6.26.6/mm/mlock.c 2008-10-11 21:54:20.000000000 -0400
36701 +@@ -12,6 +12,7 @@
36702 + #include <linux/syscalls.h>
36703 + #include <linux/sched.h>
36704 + #include <linux/module.h>
36705 ++#include <linux/grsecurity.h>
36706 +
36707 + int can_do_mlock(void)
36708 + {
36709 +@@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
36710 + return -EINVAL;
36711 + if (end == start)
36712 + return 0;
36713 ++
36714 ++#ifdef CONFIG_PAX_SEGMEXEC
36715 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
36716 ++ if (end > SEGMEXEC_TASK_SIZE)
36717 ++ return -EINVAL;
36718 ++ } else
36719 ++#endif
36720 ++
36721 ++ if (end > TASK_SIZE)
36722 ++ return -EINVAL;
36723 ++
36724 + vma = find_vma_prev(current->mm, start, &prev);
36725 + if (!vma || vma->vm_start > start)
36726 + return -ENOMEM;
36727 +@@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
36728 + lock_limit >>= PAGE_SHIFT;
36729 +
36730 + /* check against resource limits */
36731 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
36732 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
36733 + error = do_mlock(start, len, 1);
36734 + up_write(&current->mm->mmap_sem);
36735 +@@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
36736 + static int do_mlockall(int flags)
36737 + {
36738 + struct vm_area_struct * vma, * prev = NULL;
36739 +- unsigned int def_flags = 0;
36740 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
36741 +
36742 + if (flags & MCL_FUTURE)
36743 +- def_flags = VM_LOCKED;
36744 ++ def_flags |= VM_LOCKED;
36745 + current->mm->def_flags = def_flags;
36746 + if (flags == MCL_FUTURE)
36747 + goto out;
36748 +@@ -182,6 +195,12 @@ static int do_mlockall(int flags)
36749 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
36750 + unsigned int newflags;
36751 +
36752 ++#ifdef CONFIG_PAX_SEGMEXEC
36753 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
36754 ++ break;
36755 ++#endif
36756 ++
36757 ++ BUG_ON(vma->vm_end > TASK_SIZE);
36758 + newflags = vma->vm_flags | VM_LOCKED;
36759 + if (!(flags & MCL_CURRENT))
36760 + newflags &= ~VM_LOCKED;
36761 +@@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
36762 + lock_limit >>= PAGE_SHIFT;
36763 +
36764 + ret = -ENOMEM;
36765 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
36766 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
36767 + capable(CAP_IPC_LOCK))
36768 + ret = do_mlockall(flags);
36769 +diff -urNp linux-2.6.26.6/mm/mmap.c linux-2.6.26.6/mm/mmap.c
36770 +--- linux-2.6.26.6/mm/mmap.c 2008-10-08 23:24:05.000000000 -0400
36771 ++++ linux-2.6.26.6/mm/mmap.c 2008-10-11 21:54:20.000000000 -0400
36772 +@@ -26,6 +26,7 @@
36773 + #include <linux/mount.h>
36774 + #include <linux/mempolicy.h>
36775 + #include <linux/rmap.h>
36776 ++#include <linux/grsecurity.h>
36777 +
36778 + #include <asm/uaccess.h>
36779 + #include <asm/cacheflush.h>
36780 +@@ -40,6 +41,16 @@
36781 + #define arch_rebalance_pgtables(addr, len) (addr)
36782 + #endif
36783 +
36784 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
36785 ++{
36786 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
36787 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
36788 ++ up_read(&mm->mmap_sem);
36789 ++ BUG();
36790 ++ }
36791 ++#endif
36792 ++}
36793 ++
36794 + static void unmap_region(struct mm_struct *mm,
36795 + struct vm_area_struct *vma, struct vm_area_struct *prev,
36796 + unsigned long start, unsigned long end);
36797 +@@ -65,15 +76,23 @@ static void unmap_region(struct mm_struc
36798 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
36799 + *
36800 + */
36801 +-pgprot_t protection_map[16] = {
36802 ++pgprot_t protection_map[16] __read_only = {
36803 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
36804 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
36805 + };
36806 +
36807 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
36808 + {
36809 +- return protection_map[vm_flags &
36810 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
36811 ++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
36812 ++
36813 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
36814 ++ if (!nx_enabled &&
36815 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
36816 ++ (vm_flags & (VM_READ | VM_WRITE)))
36817 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
36818 ++#endif
36819 ++
36820 ++ return prot;
36821 + }
36822 + EXPORT_SYMBOL(vm_get_page_prot);
36823 +
36824 +@@ -228,6 +247,7 @@ static struct vm_area_struct *remove_vma
36825 + struct vm_area_struct *next = vma->vm_next;
36826 +
36827 + might_sleep();
36828 ++ BUG_ON(vma->vm_mirror);
36829 + if (vma->vm_ops && vma->vm_ops->close)
36830 + vma->vm_ops->close(vma);
36831 + if (vma->vm_file) {
36832 +@@ -264,6 +284,7 @@ asmlinkage unsigned long sys_brk(unsigne
36833 + * not page aligned -Ram Gupta
36834 + */
36835 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
36836 ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
36837 + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
36838 + (mm->end_data - mm->start_data) > rlim)
36839 + goto out;
36840 +@@ -365,8 +386,12 @@ find_vma_prepare(struct mm_struct *mm, u
36841 +
36842 + if (vma_tmp->vm_end > addr) {
36843 + vma = vma_tmp;
36844 +- if (vma_tmp->vm_start <= addr)
36845 +- return vma;
36846 ++ if (vma_tmp->vm_start <= addr) {
36847 ++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
36848 ++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
36849 ++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
36850 ++ break;
36851 ++ }
36852 + __rb_link = &__rb_parent->rb_left;
36853 + } else {
36854 + rb_prev = __rb_parent;
36855 +@@ -693,6 +718,12 @@ static int
36856 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
36857 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
36858 + {
36859 ++
36860 ++#ifdef CONFIG_PAX_SEGMEXEC
36861 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
36862 ++ return 0;
36863 ++#endif
36864 ++
36865 + if (is_mergeable_vma(vma, file, vm_flags) &&
36866 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
36867 + if (vma->vm_pgoff == vm_pgoff)
36868 +@@ -712,6 +743,12 @@ static int
36869 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
36870 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
36871 + {
36872 ++
36873 ++#ifdef CONFIG_PAX_SEGMEXEC
36874 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
36875 ++ return 0;
36876 ++#endif
36877 ++
36878 + if (is_mergeable_vma(vma, file, vm_flags) &&
36879 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
36880 + pgoff_t vm_pglen;
36881 +@@ -754,12 +791,19 @@ can_vma_merge_after(struct vm_area_struc
36882 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
36883 + struct vm_area_struct *prev, unsigned long addr,
36884 + unsigned long end, unsigned long vm_flags,
36885 +- struct anon_vma *anon_vma, struct file *file,
36886 ++ struct anon_vma *anon_vma, struct file *file,
36887 + pgoff_t pgoff, struct mempolicy *policy)
36888 + {
36889 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
36890 + struct vm_area_struct *area, *next;
36891 +
36892 ++#ifdef CONFIG_PAX_SEGMEXEC
36893 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
36894 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
36895 ++
36896 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
36897 ++#endif
36898 ++
36899 + /*
36900 + * We later require that vma->vm_flags == vm_flags,
36901 + * so this tests vma->vm_flags & VM_SPECIAL, too.
36902 +@@ -775,6 +819,15 @@ struct vm_area_struct *vma_merge(struct
36903 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
36904 + next = next->vm_next;
36905 +
36906 ++#ifdef CONFIG_PAX_SEGMEXEC
36907 ++ if (prev)
36908 ++ prev_m = pax_find_mirror_vma(prev);
36909 ++ if (area)
36910 ++ area_m = pax_find_mirror_vma(area);
36911 ++ if (next)
36912 ++ next_m = pax_find_mirror_vma(next);
36913 ++#endif
36914 ++
36915 + /*
36916 + * Can it merge with the predecessor?
36917 + */
36918 +@@ -794,9 +847,24 @@ struct vm_area_struct *vma_merge(struct
36919 + /* cases 1, 6 */
36920 + vma_adjust(prev, prev->vm_start,
36921 + next->vm_end, prev->vm_pgoff, NULL);
36922 +- } else /* cases 2, 5, 7 */
36923 ++
36924 ++#ifdef CONFIG_PAX_SEGMEXEC
36925 ++ if (prev_m)
36926 ++ vma_adjust(prev_m, prev_m->vm_start,
36927 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
36928 ++#endif
36929 ++
36930 ++ } else { /* cases 2, 5, 7 */
36931 + vma_adjust(prev, prev->vm_start,
36932 + end, prev->vm_pgoff, NULL);
36933 ++
36934 ++#ifdef CONFIG_PAX_SEGMEXEC
36935 ++ if (prev_m)
36936 ++ vma_adjust(prev_m, prev_m->vm_start,
36937 ++ end_m, prev_m->vm_pgoff, NULL);
36938 ++#endif
36939 ++
36940 ++ }
36941 + return prev;
36942 + }
36943 +
36944 +@@ -807,12 +875,27 @@ struct vm_area_struct *vma_merge(struct
36945 + mpol_equal(policy, vma_policy(next)) &&
36946 + can_vma_merge_before(next, vm_flags,
36947 + anon_vma, file, pgoff+pglen)) {
36948 +- if (prev && addr < prev->vm_end) /* case 4 */
36949 ++ if (prev && addr < prev->vm_end) { /* case 4 */
36950 + vma_adjust(prev, prev->vm_start,
36951 + addr, prev->vm_pgoff, NULL);
36952 +- else /* cases 3, 8 */
36953 ++
36954 ++#ifdef CONFIG_PAX_SEGMEXEC
36955 ++ if (prev_m)
36956 ++ vma_adjust(prev_m, prev_m->vm_start,
36957 ++ addr_m, prev_m->vm_pgoff, NULL);
36958 ++#endif
36959 ++
36960 ++ } else { /* cases 3, 8 */
36961 + vma_adjust(area, addr, next->vm_end,
36962 + next->vm_pgoff - pglen, NULL);
36963 ++
36964 ++#ifdef CONFIG_PAX_SEGMEXEC
36965 ++ if (area_m)
36966 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
36967 ++ next_m->vm_pgoff - pglen, NULL);
36968 ++#endif
36969 ++
36970 ++ }
36971 + return area;
36972 + }
36973 +
36974 +@@ -887,14 +970,11 @@ none:
36975 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
36976 + struct file *file, long pages)
36977 + {
36978 +- const unsigned long stack_flags
36979 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
36980 +-
36981 + if (file) {
36982 + mm->shared_vm += pages;
36983 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
36984 + mm->exec_vm += pages;
36985 +- } else if (flags & stack_flags)
36986 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
36987 + mm->stack_vm += pages;
36988 + if (flags & (VM_RESERVED|VM_IO))
36989 + mm->reserved_vm += pages;
36990 +@@ -922,7 +1002,7 @@ unsigned long do_mmap_pgoff(struct file
36991 + * (the exception is when the underlying filesystem is noexec
36992 + * mounted, in which case we dont add PROT_EXEC.)
36993 + */
36994 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
36995 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
36996 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
36997 + prot |= PROT_EXEC;
36998 +
36999 +@@ -932,15 +1012,15 @@ unsigned long do_mmap_pgoff(struct file
37000 + if (!(flags & MAP_FIXED))
37001 + addr = round_hint_to_min(addr);
37002 +
37003 +- error = arch_mmap_check(addr, len, flags);
37004 +- if (error)
37005 +- return error;
37006 +-
37007 + /* Careful about overflows.. */
37008 + len = PAGE_ALIGN(len);
37009 + if (!len || len > TASK_SIZE)
37010 + return -ENOMEM;
37011 +
37012 ++ error = arch_mmap_check(addr, len, flags);
37013 ++ if (error)
37014 ++ return error;
37015 ++
37016 + /* offset overflow? */
37017 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
37018 + return -EOVERFLOW;
37019 +@@ -952,7 +1032,7 @@ unsigned long do_mmap_pgoff(struct file
37020 + /* Obtain the address to map to. we verify (or select) it and ensure
37021 + * that it represents a valid section of the address space.
37022 + */
37023 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
37024 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
37025 + if (addr & ~PAGE_MASK)
37026 + return addr;
37027 +
37028 +@@ -963,6 +1043,26 @@ unsigned long do_mmap_pgoff(struct file
37029 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
37030 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
37031 +
37032 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
37033 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
37034 ++
37035 ++#ifdef CONFIG_PAX_MPROTECT
37036 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
37037 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
37038 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
37039 ++ else
37040 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
37041 ++ }
37042 ++#endif
37043 ++
37044 ++ }
37045 ++#endif
37046 ++
37047 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
37048 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
37049 ++ vm_flags &= ~VM_PAGEEXEC;
37050 ++#endif
37051 ++
37052 + if (flags & MAP_LOCKED) {
37053 + if (!can_do_mlock())
37054 + return -EPERM;
37055 +@@ -975,6 +1075,7 @@ unsigned long do_mmap_pgoff(struct file
37056 + locked += mm->locked_vm;
37057 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
37058 + lock_limit >>= PAGE_SHIFT;
37059 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
37060 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
37061 + return -EAGAIN;
37062 + }
37063 +@@ -1043,6 +1144,9 @@ unsigned long do_mmap_pgoff(struct file
37064 + if (error)
37065 + return error;
37066 +
37067 ++ if (!gr_acl_handle_mmap(file, prot))
37068 ++ return -EACCES;
37069 ++
37070 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
37071 + accountable);
37072 + }
37073 +@@ -1056,10 +1160,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
37074 + */
37075 + int vma_wants_writenotify(struct vm_area_struct *vma)
37076 + {
37077 +- unsigned int vm_flags = vma->vm_flags;
37078 ++ unsigned long vm_flags = vma->vm_flags;
37079 +
37080 + /* If it was private or non-writable, the write bit is already clear */
37081 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
37082 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
37083 + return 0;
37084 +
37085 + /* The backer wishes to know when pages are first written to? */
37086 +@@ -1093,14 +1197,24 @@ unsigned long mmap_region(struct file *f
37087 + unsigned long charged = 0;
37088 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
37089 +
37090 ++#ifdef CONFIG_PAX_SEGMEXEC
37091 ++ struct vm_area_struct *vma_m = NULL;
37092 ++#endif
37093 ++
37094 ++ /*
37095 ++ * mm->mmap_sem is required to protect against another thread
37096 ++ * changing the mappings in case we sleep.
37097 ++ */
37098 ++ verify_mm_writelocked(mm);
37099 ++
37100 + /* Clear old maps */
37101 + error = -ENOMEM;
37102 +-munmap_back:
37103 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37104 + if (vma && vma->vm_start < addr + len) {
37105 + if (do_munmap(mm, addr, len))
37106 + return -ENOMEM;
37107 +- goto munmap_back;
37108 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37109 ++ BUG_ON(vma && vma->vm_start < addr + len);
37110 + }
37111 +
37112 + /* Check against address space limit. */
37113 +@@ -1144,6 +1258,16 @@ munmap_back:
37114 + goto unacct_error;
37115 + }
37116 +
37117 ++#ifdef CONFIG_PAX_SEGMEXEC
37118 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
37119 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37120 ++ if (!vma_m) {
37121 ++ error = -ENOMEM;
37122 ++ goto free_vma;
37123 ++ }
37124 ++ }
37125 ++#endif
37126 ++
37127 + vma->vm_mm = mm;
37128 + vma->vm_start = addr;
37129 + vma->vm_end = addr + len;
37130 +@@ -1166,6 +1290,19 @@ munmap_back:
37131 + error = file->f_op->mmap(file, vma);
37132 + if (error)
37133 + goto unmap_and_free_vma;
37134 ++
37135 ++#ifdef CONFIG_PAX_SEGMEXEC
37136 ++ if (vma_m && (vm_flags & VM_EXECUTABLE))
37137 ++ added_exe_file_vma(mm);
37138 ++#endif
37139 ++
37140 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
37141 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
37142 ++ vma->vm_flags |= VM_PAGEEXEC;
37143 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
37144 ++ }
37145 ++#endif
37146 ++
37147 + if (vm_flags & VM_EXECUTABLE)
37148 + added_exe_file_vma(mm);
37149 + } else if (vm_flags & VM_SHARED) {
37150 +@@ -1198,12 +1335,29 @@ munmap_back:
37151 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
37152 + mpol_put(vma_policy(vma));
37153 + kmem_cache_free(vm_area_cachep, vma);
37154 ++ vma = NULL;
37155 + fput(file);
37156 ++
37157 ++#ifdef CONFIG_PAX_SEGMEXEC
37158 ++ if (vma_m) {
37159 ++ kmem_cache_free(vm_area_cachep, vma_m);
37160 ++
37161 ++ if (vm_flags & VM_EXECUTABLE)
37162 ++ removed_exe_file_vma(mm);
37163 ++ }
37164 ++#endif
37165 ++
37166 + if (vm_flags & VM_EXECUTABLE)
37167 + removed_exe_file_vma(mm);
37168 + } else {
37169 + vma_link(mm, vma, prev, rb_link, rb_parent);
37170 + file = vma->vm_file;
37171 ++
37172 ++#ifdef CONFIG_PAX_SEGMEXEC
37173 ++ if (vma_m)
37174 ++ pax_mirror_vma(vma_m, vma);
37175 ++#endif
37176 ++
37177 + }
37178 +
37179 + /* Once vma denies write, undo our temporary denial count */
37180 +@@ -1212,6 +1366,7 @@ munmap_back:
37181 + out:
37182 + mm->total_vm += len >> PAGE_SHIFT;
37183 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
37184 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
37185 + if (vm_flags & VM_LOCKED) {
37186 + mm->locked_vm += len >> PAGE_SHIFT;
37187 + make_pages_present(addr, addr + len);
37188 +@@ -1230,6 +1385,12 @@ unmap_and_free_vma:
37189 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
37190 + charged = 0;
37191 + free_vma:
37192 ++
37193 ++#ifdef CONFIG_PAX_SEGMEXEC
37194 ++ if (vma_m)
37195 ++ kmem_cache_free(vm_area_cachep, vma_m);
37196 ++#endif
37197 ++
37198 + kmem_cache_free(vm_area_cachep, vma);
37199 + unacct_error:
37200 + if (charged)
37201 +@@ -1263,6 +1424,10 @@ arch_get_unmapped_area(struct file *filp
37202 + if (flags & MAP_FIXED)
37203 + return addr;
37204 +
37205 ++#ifdef CONFIG_PAX_RANDMMAP
37206 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
37207 ++#endif
37208 ++
37209 + if (addr) {
37210 + addr = PAGE_ALIGN(addr);
37211 + vma = find_vma(mm, addr);
37212 +@@ -1271,10 +1436,10 @@ arch_get_unmapped_area(struct file *filp
37213 + return addr;
37214 + }
37215 + if (len > mm->cached_hole_size) {
37216 +- start_addr = addr = mm->free_area_cache;
37217 ++ start_addr = addr = mm->free_area_cache;
37218 + } else {
37219 +- start_addr = addr = TASK_UNMAPPED_BASE;
37220 +- mm->cached_hole_size = 0;
37221 ++ start_addr = addr = mm->mmap_base;
37222 ++ mm->cached_hole_size = 0;
37223 + }
37224 +
37225 + full_search:
37226 +@@ -1285,9 +1450,8 @@ full_search:
37227 + * Start a new search - just in case we missed
37228 + * some holes.
37229 + */
37230 +- if (start_addr != TASK_UNMAPPED_BASE) {
37231 +- addr = TASK_UNMAPPED_BASE;
37232 +- start_addr = addr;
37233 ++ if (start_addr != mm->mmap_base) {
37234 ++ start_addr = addr = mm->mmap_base;
37235 + mm->cached_hole_size = 0;
37236 + goto full_search;
37237 + }
37238 +@@ -1309,10 +1473,16 @@ full_search:
37239 +
37240 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
37241 + {
37242 ++
37243 ++#ifdef CONFIG_PAX_SEGMEXEC
37244 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
37245 ++ return;
37246 ++#endif
37247 ++
37248 + /*
37249 + * Is this a new hole at the lowest possible address?
37250 + */
37251 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
37252 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
37253 + mm->free_area_cache = addr;
37254 + mm->cached_hole_size = ~0UL;
37255 + }
37256 +@@ -1330,7 +1500,7 @@ arch_get_unmapped_area_topdown(struct fi
37257 + {
37258 + struct vm_area_struct *vma;
37259 + struct mm_struct *mm = current->mm;
37260 +- unsigned long addr = addr0;
37261 ++ unsigned long base = mm->mmap_base, addr = addr0;
37262 +
37263 + /* requested length too big for entire address space */
37264 + if (len > TASK_SIZE)
37265 +@@ -1339,6 +1509,10 @@ arch_get_unmapped_area_topdown(struct fi
37266 + if (flags & MAP_FIXED)
37267 + return addr;
37268 +
37269 ++#ifdef CONFIG_PAX_RANDMMAP
37270 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
37271 ++#endif
37272 ++
37273 + /* requesting a specific address */
37274 + if (addr) {
37275 + addr = PAGE_ALIGN(addr);
37276 +@@ -1396,13 +1570,21 @@ bottomup:
37277 + * can happen with large stack limits and large mmap()
37278 + * allocations.
37279 + */
37280 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
37281 ++
37282 ++#ifdef CONFIG_PAX_RANDMMAP
37283 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
37284 ++ mm->mmap_base += mm->delta_mmap;
37285 ++#endif
37286 ++
37287 ++ mm->free_area_cache = mm->mmap_base;
37288 + mm->cached_hole_size = ~0UL;
37289 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
37290 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
37291 + /*
37292 + * Restore the topdown base:
37293 + */
37294 +- mm->free_area_cache = mm->mmap_base;
37295 ++ mm->mmap_base = base;
37296 ++ mm->free_area_cache = base;
37297 + mm->cached_hole_size = ~0UL;
37298 +
37299 + return addr;
37300 +@@ -1411,6 +1593,12 @@ bottomup:
37301 +
37302 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
37303 + {
37304 ++
37305 ++#ifdef CONFIG_PAX_SEGMEXEC
37306 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
37307 ++ return;
37308 ++#endif
37309 ++
37310 + /*
37311 + * Is this a new hole at the highest possible address?
37312 + */
37313 +@@ -1418,8 +1606,10 @@ void arch_unmap_area_topdown(struct mm_s
37314 + mm->free_area_cache = addr;
37315 +
37316 + /* dont allow allocations above current base */
37317 +- if (mm->free_area_cache > mm->mmap_base)
37318 ++ if (mm->free_area_cache > mm->mmap_base) {
37319 + mm->free_area_cache = mm->mmap_base;
37320 ++ mm->cached_hole_size = ~0UL;
37321 ++ }
37322 + }
37323 +
37324 + unsigned long
37325 +@@ -1519,6 +1709,33 @@ out:
37326 + return prev ? prev->vm_next : vma;
37327 + }
37328 +
37329 ++#ifdef CONFIG_PAX_SEGMEXEC
37330 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
37331 ++{
37332 ++ struct vm_area_struct *vma_m;
37333 ++
37334 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
37335 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
37336 ++ BUG_ON(vma->vm_mirror);
37337 ++ return NULL;
37338 ++ }
37339 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
37340 ++ vma_m = vma->vm_mirror;
37341 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
37342 ++ BUG_ON(vma->vm_file != vma_m->vm_file);
37343 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
37344 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
37345 ++
37346 ++#ifdef CONFIG_PAX_MPROTECT
37347 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
37348 ++#else
37349 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
37350 ++#endif
37351 ++
37352 ++ return vma_m;
37353 ++}
37354 ++#endif
37355 ++
37356 + /*
37357 + * Verify that the stack growth is acceptable and
37358 + * update accounting. This is shared with both the
37359 +@@ -1535,6 +1752,7 @@ static int acct_stack_growth(struct vm_a
37360 + return -ENOMEM;
37361 +
37362 + /* Stack limit test */
37363 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
37364 + if (size > rlim[RLIMIT_STACK].rlim_cur)
37365 + return -ENOMEM;
37366 +
37367 +@@ -1544,6 +1762,7 @@ static int acct_stack_growth(struct vm_a
37368 + unsigned long limit;
37369 + locked = mm->locked_vm + grow;
37370 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
37371 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
37372 + if (locked > limit && !capable(CAP_IPC_LOCK))
37373 + return -ENOMEM;
37374 + }
37375 +@@ -1558,7 +1777,7 @@ static int acct_stack_growth(struct vm_a
37376 + * Overcommit.. This must be the final test, as it will
37377 + * update security statistics.
37378 + */
37379 +- if (security_vm_enough_memory(grow))
37380 ++ if (security_vm_enough_memory_mm(mm, grow))
37381 + return -ENOMEM;
37382 +
37383 + /* Ok, everything looks good - let it rip */
37384 +@@ -1579,35 +1798,40 @@ static inline
37385 + #endif
37386 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
37387 + {
37388 +- int error;
37389 ++ int error, locknext;
37390 +
37391 + if (!(vma->vm_flags & VM_GROWSUP))
37392 + return -EFAULT;
37393 +
37394 ++ /* Also guard against wrapping around to address 0. */
37395 ++ if (address < PAGE_ALIGN(address+1))
37396 ++ address = PAGE_ALIGN(address+1);
37397 ++ else
37398 ++ return -ENOMEM;
37399 ++
37400 + /*
37401 + * We must make sure the anon_vma is allocated
37402 + * so that the anon_vma locking is not a noop.
37403 + */
37404 + if (unlikely(anon_vma_prepare(vma)))
37405 + return -ENOMEM;
37406 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
37407 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
37408 ++ return -ENOMEM;
37409 + anon_vma_lock(vma);
37410 ++ if (locknext)
37411 ++ anon_vma_lock(vma->vm_next);
37412 +
37413 + /*
37414 + * vma->vm_start/vm_end cannot change under us because the caller
37415 + * is required to hold the mmap_sem in read mode. We need the
37416 +- * anon_vma lock to serialize against concurrent expand_stacks.
37417 +- * Also guard against wrapping around to address 0.
37418 ++ * anon_vma locks to serialize against concurrent expand_stacks
37419 ++ * and expand_upwards.
37420 + */
37421 +- if (address < PAGE_ALIGN(address+4))
37422 +- address = PAGE_ALIGN(address+4);
37423 +- else {
37424 +- anon_vma_unlock(vma);
37425 +- return -ENOMEM;
37426 +- }
37427 + error = 0;
37428 +
37429 + /* Somebody else might have raced and expanded it already */
37430 +- if (address > vma->vm_end) {
37431 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
37432 + unsigned long size, grow;
37433 +
37434 + size = address - vma->vm_start;
37435 +@@ -1617,6 +1841,8 @@ int expand_upwards(struct vm_area_struct
37436 + if (!error)
37437 + vma->vm_end = address;
37438 + }
37439 ++ if (locknext)
37440 ++ anon_vma_unlock(vma->vm_next);
37441 + anon_vma_unlock(vma);
37442 + return error;
37443 + }
37444 +@@ -1628,7 +1854,8 @@ int expand_upwards(struct vm_area_struct
37445 + static inline int expand_downwards(struct vm_area_struct *vma,
37446 + unsigned long address)
37447 + {
37448 +- int error;
37449 ++ int error, lockprev = 0;
37450 ++ struct vm_area_struct *prev = NULL;
37451 +
37452 + /*
37453 + * We must make sure the anon_vma is allocated
37454 +@@ -1642,6 +1869,15 @@ static inline int expand_downwards(struc
37455 + if (error)
37456 + return error;
37457 +
37458 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
37459 ++ find_vma_prev(vma->vm_mm, address, &prev);
37460 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
37461 ++#endif
37462 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
37463 ++ return -ENOMEM;
37464 ++ if (lockprev)
37465 ++ anon_vma_lock(prev);
37466 ++
37467 + anon_vma_lock(vma);
37468 +
37469 + /*
37470 +@@ -1651,9 +1887,15 @@ static inline int expand_downwards(struc
37471 + */
37472 +
37473 + /* Somebody else might have raced and expanded it already */
37474 +- if (address < vma->vm_start) {
37475 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
37476 + unsigned long size, grow;
37477 +
37478 ++#ifdef CONFIG_PAX_SEGMEXEC
37479 ++ struct vm_area_struct *vma_m;
37480 ++
37481 ++ vma_m = pax_find_mirror_vma(vma);
37482 ++#endif
37483 ++
37484 + size = vma->vm_end - address;
37485 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
37486 +
37487 +@@ -1661,9 +1903,20 @@ static inline int expand_downwards(struc
37488 + if (!error) {
37489 + vma->vm_start = address;
37490 + vma->vm_pgoff -= grow;
37491 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
37492 ++
37493 ++#ifdef CONFIG_PAX_SEGMEXEC
37494 ++ if (vma_m) {
37495 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
37496 ++ vma_m->vm_pgoff -= grow;
37497 ++ }
37498 ++#endif
37499 ++
37500 + }
37501 + }
37502 + anon_vma_unlock(vma);
37503 ++ if (lockprev)
37504 ++ anon_vma_unlock(prev);
37505 + return error;
37506 + }
37507 +
37508 +@@ -1735,6 +1988,13 @@ static void remove_vma_list(struct mm_st
37509 + do {
37510 + long nrpages = vma_pages(vma);
37511 +
37512 ++#ifdef CONFIG_PAX_SEGMEXEC
37513 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
37514 ++ vma = remove_vma(vma);
37515 ++ continue;
37516 ++ }
37517 ++#endif
37518 ++
37519 + mm->total_vm -= nrpages;
37520 + if (vma->vm_flags & VM_LOCKED)
37521 + mm->locked_vm -= nrpages;
37522 +@@ -1781,6 +2041,16 @@ detach_vmas_to_be_unmapped(struct mm_str
37523 +
37524 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
37525 + do {
37526 ++
37527 ++#ifdef CONFIG_PAX_SEGMEXEC
37528 ++ if (vma->vm_mirror) {
37529 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
37530 ++ vma->vm_mirror->vm_mirror = NULL;
37531 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
37532 ++ vma->vm_mirror = NULL;
37533 ++ }
37534 ++#endif
37535 ++
37536 + rb_erase(&vma->vm_rb, &mm->mm_rb);
37537 + mm->map_count--;
37538 + tail_vma = vma;
37539 +@@ -1800,6 +2070,108 @@ detach_vmas_to_be_unmapped(struct mm_str
37540 + * Split a vma into two pieces at address 'addr', a new vma is allocated
37541 + * either for the first part or the tail.
37542 + */
37543 ++
37544 ++#ifdef CONFIG_PAX_SEGMEXEC
37545 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
37546 ++ unsigned long addr, int new_below)
37547 ++{
37548 ++ struct mempolicy *pol;
37549 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
37550 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
37551 ++
37552 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
37553 ++ return -EINVAL;
37554 ++
37555 ++ vma_m = pax_find_mirror_vma(vma);
37556 ++ if (vma_m) {
37557 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
37558 ++ if (mm->map_count >= sysctl_max_map_count-1)
37559 ++ return -ENOMEM;
37560 ++ } else if (mm->map_count >= sysctl_max_map_count)
37561 ++ return -ENOMEM;
37562 ++
37563 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
37564 ++ if (!new)
37565 ++ return -ENOMEM;
37566 ++
37567 ++ if (vma_m) {
37568 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
37569 ++ if (!new_m) {
37570 ++ kmem_cache_free(vm_area_cachep, new);
37571 ++ return -ENOMEM;
37572 ++ }
37573 ++ }
37574 ++
37575 ++ /* most fields are the same, copy all, and then fixup */
37576 ++ *new = *vma;
37577 ++
37578 ++ if (new_below)
37579 ++ new->vm_end = addr;
37580 ++ else {
37581 ++ new->vm_start = addr;
37582 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
37583 ++ }
37584 ++
37585 ++ if (vma_m) {
37586 ++ *new_m = *vma_m;
37587 ++ new_m->vm_mirror = new;
37588 ++ new->vm_mirror = new_m;
37589 ++
37590 ++ if (new_below)
37591 ++ new_m->vm_end = addr_m;
37592 ++ else {
37593 ++ new_m->vm_start = addr_m;
37594 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
37595 ++ }
37596 ++ }
37597 ++
37598 ++ pol = mpol_dup(vma_policy(vma));
37599 ++ if (IS_ERR(pol)) {
37600 ++ if (new_m)
37601 ++ kmem_cache_free(vm_area_cachep, new_m);
37602 ++ kmem_cache_free(vm_area_cachep, new);
37603 ++ return PTR_ERR(pol);
37604 ++ }
37605 ++ vma_set_policy(new, pol);
37606 ++
37607 ++ if (new->vm_file) {
37608 ++ get_file(new->vm_file);
37609 ++ if (vma->vm_flags & VM_EXECUTABLE)
37610 ++ added_exe_file_vma(mm);
37611 ++ }
37612 ++
37613 ++ if (new->vm_ops && new->vm_ops->open)
37614 ++ new->vm_ops->open(new);
37615 ++
37616 ++ if (new_below)
37617 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
37618 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
37619 ++ else
37620 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
37621 ++
37622 ++ if (vma_m) {
37623 ++ mpol_get(pol);
37624 ++ vma_set_policy(new_m, pol);
37625 ++
37626 ++ if (new_m->vm_file) {
37627 ++ get_file(new_m->vm_file);
37628 ++ if (vma_m->vm_flags & VM_EXECUTABLE)
37629 ++ added_exe_file_vma(mm);
37630 ++ }
37631 ++
37632 ++ if (new_m->vm_ops && new_m->vm_ops->open)
37633 ++ new_m->vm_ops->open(new_m);
37634 ++
37635 ++ if (new_below)
37636 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
37637 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
37638 ++ else
37639 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
37640 ++ }
37641 ++
37642 ++ return 0;
37643 ++}
37644 ++#else
37645 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
37646 + unsigned long addr, int new_below)
37647 + {
37648 +@@ -1850,17 +2222,37 @@ int split_vma(struct mm_struct * mm, str
37649 +
37650 + return 0;
37651 + }
37652 ++#endif
37653 +
37654 + /* Munmap is split into 2 main parts -- this part which finds
37655 + * what needs doing, and the areas themselves, which do the
37656 + * work. This now handles partial unmappings.
37657 + * Jeremy Fitzhardinge <jeremy@××××.org>
37658 + */
37659 ++#ifdef CONFIG_PAX_SEGMEXEC
37660 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
37661 ++{
37662 ++ int ret = __do_munmap(mm, start, len);
37663 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
37664 ++ return ret;
37665 ++
37666 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
37667 ++}
37668 ++
37669 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
37670 ++#else
37671 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
37672 ++#endif
37673 + {
37674 + unsigned long end;
37675 + struct vm_area_struct *vma, *prev, *last;
37676 +
37677 ++ /*
37678 ++ * mm->mmap_sem is required to protect against another thread
37679 ++ * changing the mappings in case we sleep.
37680 ++ */
37681 ++ verify_mm_writelocked(mm);
37682 ++
37683 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
37684 + return -EINVAL;
37685 +
37686 +@@ -1910,6 +2302,8 @@ int do_munmap(struct mm_struct *mm, unsi
37687 + /* Fix up all other VM information */
37688 + remove_vma_list(mm, vma);
37689 +
37690 ++ track_exec_limit(mm, start, end, 0UL);
37691 ++
37692 + return 0;
37693 + }
37694 +
37695 +@@ -1922,22 +2316,18 @@ asmlinkage long sys_munmap(unsigned long
37696 +
37697 + profile_munmap(addr);
37698 +
37699 ++#ifdef CONFIG_PAX_SEGMEXEC
37700 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
37701 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
37702 ++ return -EINVAL;
37703 ++#endif
37704 ++
37705 + down_write(&mm->mmap_sem);
37706 + ret = do_munmap(mm, addr, len);
37707 + up_write(&mm->mmap_sem);
37708 + return ret;
37709 + }
37710 +
37711 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
37712 +-{
37713 +-#ifdef CONFIG_DEBUG_VM
37714 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
37715 +- WARN_ON(1);
37716 +- up_read(&mm->mmap_sem);
37717 +- }
37718 +-#endif
37719 +-}
37720 +-
37721 + /*
37722 + * this is really a simplified "do_mmap". it only handles
37723 + * anonymous maps. eventually we may be able to do some
37724 +@@ -1951,6 +2341,11 @@ unsigned long do_brk(unsigned long addr,
37725 + struct rb_node ** rb_link, * rb_parent;
37726 + pgoff_t pgoff = addr >> PAGE_SHIFT;
37727 + int error;
37728 ++ unsigned long charged;
37729 ++
37730 ++#ifdef CONFIG_PAX_SEGMEXEC
37731 ++ struct vm_area_struct *vma_m = NULL;
37732 ++#endif
37733 +
37734 + len = PAGE_ALIGN(len);
37735 + if (!len)
37736 +@@ -1968,19 +2363,34 @@ unsigned long do_brk(unsigned long addr,
37737 +
37738 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
37739 +
37740 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
37741 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
37742 ++ flags &= ~VM_EXEC;
37743 ++
37744 ++#ifdef CONFIG_PAX_MPROTECT
37745 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
37746 ++ flags &= ~VM_MAYEXEC;
37747 ++#endif
37748 ++
37749 ++ }
37750 ++#endif
37751 ++
37752 + error = arch_mmap_check(addr, len, flags);
37753 + if (error)
37754 + return error;
37755 +
37756 ++ charged = len >> PAGE_SHIFT;
37757 ++
37758 + /*
37759 + * mlock MCL_FUTURE?
37760 + */
37761 + if (mm->def_flags & VM_LOCKED) {
37762 + unsigned long locked, lock_limit;
37763 +- locked = len >> PAGE_SHIFT;
37764 ++ locked = charged;
37765 + locked += mm->locked_vm;
37766 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
37767 + lock_limit >>= PAGE_SHIFT;
37768 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
37769 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
37770 + return -EAGAIN;
37771 + }
37772 +@@ -1994,22 +2404,22 @@ unsigned long do_brk(unsigned long addr,
37773 + /*
37774 + * Clear old maps. this also does some error checking for us
37775 + */
37776 +- munmap_back:
37777 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37778 + if (vma && vma->vm_start < addr + len) {
37779 + if (do_munmap(mm, addr, len))
37780 + return -ENOMEM;
37781 +- goto munmap_back;
37782 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
37783 ++ BUG_ON(vma && vma->vm_start < addr + len);
37784 + }
37785 +
37786 + /* Check against address space limits *after* clearing old maps... */
37787 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
37788 ++ if (!may_expand_vm(mm, charged))
37789 + return -ENOMEM;
37790 +
37791 + if (mm->map_count > sysctl_max_map_count)
37792 + return -ENOMEM;
37793 +
37794 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
37795 ++ if (security_vm_enough_memory(charged))
37796 + return -ENOMEM;
37797 +
37798 + /* Can we just expand an old private anonymous mapping? */
37799 +@@ -2022,10 +2432,21 @@ unsigned long do_brk(unsigned long addr,
37800 + */
37801 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37802 + if (!vma) {
37803 +- vm_unacct_memory(len >> PAGE_SHIFT);
37804 ++ vm_unacct_memory(charged);
37805 + return -ENOMEM;
37806 + }
37807 +
37808 ++#ifdef CONFIG_PAX_SEGMEXEC
37809 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
37810 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37811 ++ if (!vma_m) {
37812 ++ kmem_cache_free(vm_area_cachep, vma);
37813 ++ vm_unacct_memory(charged);
37814 ++ return -ENOMEM;
37815 ++ }
37816 ++ }
37817 ++#endif
37818 ++
37819 + vma->vm_mm = mm;
37820 + vma->vm_start = addr;
37821 + vma->vm_end = addr + len;
37822 +@@ -2033,12 +2454,19 @@ unsigned long do_brk(unsigned long addr,
37823 + vma->vm_flags = flags;
37824 + vma->vm_page_prot = vm_get_page_prot(flags);
37825 + vma_link(mm, vma, prev, rb_link, rb_parent);
37826 ++
37827 ++#ifdef CONFIG_PAX_SEGMEXEC
37828 ++ if (vma_m)
37829 ++ pax_mirror_vma(vma_m, vma);
37830 ++#endif
37831 ++
37832 + out:
37833 +- mm->total_vm += len >> PAGE_SHIFT;
37834 ++ mm->total_vm += charged;
37835 + if (flags & VM_LOCKED) {
37836 +- mm->locked_vm += len >> PAGE_SHIFT;
37837 ++ mm->locked_vm += charged;
37838 + make_pages_present(addr, addr + len);
37839 + }
37840 ++ track_exec_limit(mm, addr, addr + len, flags);
37841 + return addr;
37842 + }
37843 +
37844 +@@ -2069,8 +2497,10 @@ void exit_mmap(struct mm_struct *mm)
37845 + * Walk the list again, actually closing and freeing it,
37846 + * with preemption enabled, without holding any MM locks.
37847 + */
37848 +- while (vma)
37849 ++ while (vma) {
37850 ++ vma->vm_mirror = NULL;
37851 + vma = remove_vma(vma);
37852 ++ }
37853 +
37854 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
37855 + }
37856 +@@ -2084,6 +2514,10 @@ int insert_vm_struct(struct mm_struct *
37857 + struct vm_area_struct * __vma, * prev;
37858 + struct rb_node ** rb_link, * rb_parent;
37859 +
37860 ++#ifdef CONFIG_PAX_SEGMEXEC
37861 ++ struct vm_area_struct *vma_m = NULL;
37862 ++#endif
37863 ++
37864 + /*
37865 + * The vm_pgoff of a purely anonymous vma should be irrelevant
37866 + * until its first write fault, when page's anon_vma and index
37867 +@@ -2106,7 +2540,22 @@ int insert_vm_struct(struct mm_struct *
37868 + if ((vma->vm_flags & VM_ACCOUNT) &&
37869 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
37870 + return -ENOMEM;
37871 ++
37872 ++#ifdef CONFIG_PAX_SEGMEXEC
37873 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
37874 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
37875 ++ if (!vma_m)
37876 ++ return -ENOMEM;
37877 ++ }
37878 ++#endif
37879 ++
37880 + vma_link(mm, vma, prev, rb_link, rb_parent);
37881 ++
37882 ++#ifdef CONFIG_PAX_SEGMEXEC
37883 ++ if (vma_m)
37884 ++ pax_mirror_vma(vma_m, vma);
37885 ++#endif
37886 ++
37887 + return 0;
37888 + }
37889 +
37890 +@@ -2124,6 +2573,8 @@ struct vm_area_struct *copy_vma(struct v
37891 + struct rb_node **rb_link, *rb_parent;
37892 + struct mempolicy *pol;
37893 +
37894 ++ BUG_ON(vma->vm_mirror);
37895 ++
37896 + /*
37897 + * If anonymous vma has not yet been faulted, update new pgoff
37898 + * to match new location, to increase its chance of merging.
37899 +@@ -2167,6 +2618,35 @@ struct vm_area_struct *copy_vma(struct v
37900 + return new_vma;
37901 + }
37902 +
37903 ++#ifdef CONFIG_PAX_SEGMEXEC
37904 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
37905 ++{
37906 ++ struct vm_area_struct *prev_m;
37907 ++ struct rb_node **rb_link_m, *rb_parent_m;
37908 ++ struct mempolicy *pol_m;
37909 ++
37910 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
37911 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
37912 ++ BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
37913 ++ *vma_m = *vma;
37914 ++ pol_m = vma_policy(vma_m);
37915 ++ mpol_get(pol_m);
37916 ++ vma_set_policy(vma_m, pol_m);
37917 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
37918 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
37919 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
37920 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
37921 ++ if (vma_m->vm_file)
37922 ++ get_file(vma_m->vm_file);
37923 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
37924 ++ vma_m->vm_ops->open(vma_m);
37925 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
37926 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
37927 ++ vma_m->vm_mirror = vma;
37928 ++ vma->vm_mirror = vma_m;
37929 ++}
37930 ++#endif
37931 ++
37932 + /*
37933 + * Return true if the calling process may expand its vm space by the passed
37934 + * number of pages
37935 +@@ -2177,7 +2657,7 @@ int may_expand_vm(struct mm_struct *mm,
37936 + unsigned long lim;
37937 +
37938 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
37939 +-
37940 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
37941 + if (cur + npages > lim)
37942 + return 0;
37943 + return 1;
37944 +@@ -2246,6 +2726,15 @@ int install_special_mapping(struct mm_st
37945 + vma->vm_start = addr;
37946 + vma->vm_end = addr + len;
37947 +
37948 ++#ifdef CONFIG_PAX_MPROTECT
37949 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
37950 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
37951 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
37952 ++ else
37953 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
37954 ++ }
37955 ++#endif
37956 ++
37957 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
37958 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
37959 +
37960 +diff -urNp linux-2.6.26.6/mm/mprotect.c linux-2.6.26.6/mm/mprotect.c
37961 +--- linux-2.6.26.6/mm/mprotect.c 2008-10-08 23:24:05.000000000 -0400
37962 ++++ linux-2.6.26.6/mm/mprotect.c 2008-10-11 21:54:20.000000000 -0400
37963 +@@ -21,10 +21,17 @@
37964 + #include <linux/syscalls.h>
37965 + #include <linux/swap.h>
37966 + #include <linux/swapops.h>
37967 ++#include <linux/grsecurity.h>
37968 ++
37969 ++#ifdef CONFIG_PAX_MPROTECT
37970 ++#include <linux/elf.h>
37971 ++#endif
37972 ++
37973 + #include <asm/uaccess.h>
37974 + #include <asm/pgtable.h>
37975 + #include <asm/cacheflush.h>
37976 + #include <asm/tlbflush.h>
37977 ++#include <asm/mmu_context.h>
37978 +
37979 + #ifndef pgprot_modify
37980 + static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
37981 +@@ -134,6 +141,48 @@ static void change_protection(struct vm_
37982 + flush_tlb_range(vma, start, end);
37983 + }
37984 +
37985 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
37986 ++/* called while holding the mmap semaphor for writing except stack expansion */
37987 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
37988 ++{
37989 ++ unsigned long oldlimit, newlimit = 0UL;
37990 ++
37991 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
37992 ++ return;
37993 ++
37994 ++ spin_lock(&mm->page_table_lock);
37995 ++ oldlimit = mm->context.user_cs_limit;
37996 ++ if ((prot & VM_EXEC) && oldlimit < end)
37997 ++ /* USER_CS limit moved up */
37998 ++ newlimit = end;
37999 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
38000 ++ /* USER_CS limit moved down */
38001 ++ newlimit = start;
38002 ++
38003 ++ if (newlimit) {
38004 ++ mm->context.user_cs_limit = newlimit;
38005 ++
38006 ++#ifdef CONFIG_SMP
38007 ++ wmb();
38008 ++ cpus_clear(mm->context.cpu_user_cs_mask);
38009 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
38010 ++#endif
38011 ++
38012 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
38013 ++ }
38014 ++ spin_unlock(&mm->page_table_lock);
38015 ++ if (newlimit == end) {
38016 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
38017 ++
38018 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
38019 ++ if (is_vm_hugetlb_page(vma))
38020 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
38021 ++ else
38022 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
38023 ++ }
38024 ++}
38025 ++#endif
38026 ++
38027 + int
38028 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
38029 + unsigned long start, unsigned long end, unsigned long newflags)
38030 +@@ -146,6 +195,14 @@ mprotect_fixup(struct vm_area_struct *vm
38031 + int error;
38032 + int dirty_accountable = 0;
38033 +
38034 ++#ifdef CONFIG_PAX_SEGMEXEC
38035 ++ struct vm_area_struct *vma_m = NULL;
38036 ++ unsigned long start_m, end_m;
38037 ++
38038 ++ start_m = start + SEGMEXEC_TASK_SIZE;
38039 ++ end_m = end + SEGMEXEC_TASK_SIZE;
38040 ++#endif
38041 ++
38042 + if (newflags == oldflags) {
38043 + *pprev = vma;
38044 + return 0;
38045 +@@ -168,6 +225,38 @@ mprotect_fixup(struct vm_area_struct *vm
38046 + }
38047 + }
38048 +
38049 ++#ifdef CONFIG_PAX_SEGMEXEC
38050 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
38051 ++ if (start != vma->vm_start) {
38052 ++ error = split_vma(mm, vma, start, 1);
38053 ++ if (error)
38054 ++ goto fail;
38055 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
38056 ++ *pprev = (*pprev)->vm_next;
38057 ++ }
38058 ++
38059 ++ if (end != vma->vm_end) {
38060 ++ error = split_vma(mm, vma, end, 0);
38061 ++ if (error)
38062 ++ goto fail;
38063 ++ }
38064 ++
38065 ++ if (pax_find_mirror_vma(vma)) {
38066 ++ error = __do_munmap(mm, start_m, end_m - start_m);
38067 ++ if (error)
38068 ++ goto fail;
38069 ++ } else {
38070 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38071 ++ if (!vma_m) {
38072 ++ error = -ENOMEM;
38073 ++ goto fail;
38074 ++ }
38075 ++ vma->vm_flags = newflags;
38076 ++ pax_mirror_vma(vma_m, vma);
38077 ++ }
38078 ++ }
38079 ++#endif
38080 ++
38081 + /*
38082 + * First try to merge with previous and/or next vma.
38083 + */
38084 +@@ -220,6 +309,70 @@ fail:
38085 + return error;
38086 + }
38087 +
38088 ++#ifdef CONFIG_PAX_MPROTECT
38089 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
38090 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
38091 ++ *
38092 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
38093 ++ * basis because we want to allow the common case and not the special ones.
38094 ++ */
38095 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
38096 ++{
38097 ++ struct elfhdr elf_h;
38098 ++ struct elf_phdr elf_p;
38099 ++ elf_addr_t dyn_offset = 0UL;
38100 ++ elf_dyn dyn;
38101 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
38102 ++
38103 ++#ifndef CONFIG_PAX_NOELFRELOCS
38104 ++ if ((vma->vm_start != start) ||
38105 ++ !vma->vm_file ||
38106 ++ !(vma->vm_flags & VM_MAYEXEC) ||
38107 ++ (vma->vm_flags & VM_MAYNOTWRITE))
38108 ++#endif
38109 ++
38110 ++ return;
38111 ++
38112 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
38113 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
38114 ++
38115 ++#ifdef CONFIG_PAX_ETEXECRELOCS
38116 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
38117 ++#else
38118 ++ elf_h.e_type != ET_DYN ||
38119 ++#endif
38120 ++
38121 ++ !elf_check_arch(&elf_h) ||
38122 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
38123 ++ elf_h.e_phnum > j)
38124 ++ return;
38125 ++
38126 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
38127 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
38128 ++ return;
38129 ++ if (elf_p.p_type == PT_DYNAMIC) {
38130 ++ dyn_offset = elf_p.p_offset;
38131 ++ j = i;
38132 ++ }
38133 ++ }
38134 ++ if (elf_h.e_phnum <= j)
38135 ++ return;
38136 ++
38137 ++ i = 0UL;
38138 ++ do {
38139 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
38140 ++ return;
38141 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
38142 ++ gr_log_textrel(vma);
38143 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
38144 ++ return;
38145 ++ }
38146 ++ i++;
38147 ++ } while (dyn.d_tag != DT_NULL);
38148 ++ return;
38149 ++}
38150 ++#endif
38151 ++
38152 + asmlinkage long
38153 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
38154 + {
38155 +@@ -239,6 +392,17 @@ sys_mprotect(unsigned long start, size_t
38156 + end = start + len;
38157 + if (end <= start)
38158 + return -ENOMEM;
38159 ++
38160 ++#ifdef CONFIG_PAX_SEGMEXEC
38161 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
38162 ++ if (end > SEGMEXEC_TASK_SIZE)
38163 ++ return -EINVAL;
38164 ++ } else
38165 ++#endif
38166 ++
38167 ++ if (end > TASK_SIZE)
38168 ++ return -EINVAL;
38169 ++
38170 + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
38171 + return -EINVAL;
38172 +
38173 +@@ -246,7 +410,7 @@ sys_mprotect(unsigned long start, size_t
38174 + /*
38175 + * Does the application expect PROT_READ to imply PROT_EXEC:
38176 + */
38177 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
38178 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
38179 + prot |= PROT_EXEC;
38180 +
38181 + vm_flags = calc_vm_prot_bits(prot);
38182 +@@ -278,6 +442,16 @@ sys_mprotect(unsigned long start, size_t
38183 + if (start > vma->vm_start)
38184 + prev = vma;
38185 +
38186 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
38187 ++ error = -EACCES;
38188 ++ goto out;
38189 ++ }
38190 ++
38191 ++#ifdef CONFIG_PAX_MPROTECT
38192 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
38193 ++ pax_handle_maywrite(vma, start);
38194 ++#endif
38195 ++
38196 + for (nstart = start ; ; ) {
38197 + unsigned long newflags;
38198 +
38199 +@@ -291,6 +465,12 @@ sys_mprotect(unsigned long start, size_t
38200 + goto out;
38201 + }
38202 +
38203 ++#ifdef CONFIG_PAX_MPROTECT
38204 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
38205 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
38206 ++ newflags &= ~VM_MAYWRITE;
38207 ++#endif
38208 ++
38209 + error = security_file_mprotect(vma, reqprot, prot);
38210 + if (error)
38211 + goto out;
38212 +@@ -301,6 +481,9 @@ sys_mprotect(unsigned long start, size_t
38213 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
38214 + if (error)
38215 + goto out;
38216 ++
38217 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
38218 ++
38219 + nstart = tmp;
38220 +
38221 + if (nstart < prev->vm_end)
38222 +diff -urNp linux-2.6.26.6/mm/mremap.c linux-2.6.26.6/mm/mremap.c
38223 +--- linux-2.6.26.6/mm/mremap.c 2008-10-08 23:24:05.000000000 -0400
38224 ++++ linux-2.6.26.6/mm/mremap.c 2008-10-11 21:54:20.000000000 -0400
38225 +@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
38226 + continue;
38227 + pte = ptep_clear_flush(vma, old_addr, old_pte);
38228 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
38229 ++
38230 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
38231 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
38232 ++ pte = pte_exprotect(pte);
38233 ++#endif
38234 ++
38235 + set_pte_at(mm, new_addr, new_pte, pte);
38236 + }
38237 +
38238 +@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
38239 + struct vm_area_struct *vma;
38240 + unsigned long ret = -EINVAL;
38241 + unsigned long charged = 0;
38242 ++ unsigned long pax_task_size = TASK_SIZE;
38243 +
38244 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
38245 + goto out;
38246 +@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
38247 + if (!new_len)
38248 + goto out;
38249 +
38250 ++#ifdef CONFIG_PAX_SEGMEXEC
38251 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
38252 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
38253 ++#endif
38254 ++
38255 ++ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
38256 ++ old_len > pax_task_size || addr > pax_task_size-old_len)
38257 ++ goto out;
38258 ++
38259 + /* new_addr is only valid if MREMAP_FIXED is specified */
38260 + if (flags & MREMAP_FIXED) {
38261 + if (new_addr & ~PAGE_MASK)
38262 +@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
38263 + if (!(flags & MREMAP_MAYMOVE))
38264 + goto out;
38265 +
38266 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
38267 ++ if (new_addr > pax_task_size - new_len)
38268 + goto out;
38269 +
38270 + /* Check if the location we're moving into overlaps the
38271 + * old location at all, and fail if it does.
38272 + */
38273 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
38274 +- goto out;
38275 +-
38276 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
38277 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
38278 + goto out;
38279 +
38280 + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
38281 +@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
38282 + ret = -EINVAL;
38283 + goto out;
38284 + }
38285 ++
38286 ++#ifdef CONFIG_PAX_SEGMEXEC
38287 ++ if (pax_find_mirror_vma(vma)) {
38288 ++ ret = -EINVAL;
38289 ++ goto out;
38290 ++ }
38291 ++#endif
38292 ++
38293 + /* We can't remap across vm area boundaries */
38294 + if (old_len > vma->vm_end - addr)
38295 + goto out;
38296 +@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
38297 + if (old_len == vma->vm_end - addr &&
38298 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
38299 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
38300 +- unsigned long max_addr = TASK_SIZE;
38301 ++ unsigned long max_addr = pax_task_size;
38302 + if (vma->vm_next)
38303 + max_addr = vma->vm_next->vm_start;
38304 + /* can we just expand the current mapping? */
38305 +@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
38306 + addr + new_len);
38307 + }
38308 + ret = addr;
38309 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
38310 + goto out;
38311 + }
38312 + }
38313 +@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
38314 + */
38315 + ret = -ENOMEM;
38316 + if (flags & MREMAP_MAYMOVE) {
38317 ++ unsigned long map_flags = 0;
38318 + if (!(flags & MREMAP_FIXED)) {
38319 +- unsigned long map_flags = 0;
38320 + if (vma->vm_flags & VM_MAYSHARE)
38321 + map_flags |= MAP_SHARED;
38322 +
38323 +@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
38324 + if (ret)
38325 + goto out;
38326 + }
38327 ++ map_flags = vma->vm_flags;
38328 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
38329 ++ if (!(ret & ~PAGE_MASK)) {
38330 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
38331 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
38332 ++ }
38333 + }
38334 + out:
38335 + if (ret & ~PAGE_MASK)
38336 +diff -urNp linux-2.6.26.6/mm/nommu.c linux-2.6.26.6/mm/nommu.c
38337 +--- linux-2.6.26.6/mm/nommu.c 2008-10-08 23:24:05.000000000 -0400
38338 ++++ linux-2.6.26.6/mm/nommu.c 2008-10-11 21:54:20.000000000 -0400
38339 +@@ -416,15 +416,6 @@ struct vm_area_struct *find_vma(struct m
38340 + }
38341 + EXPORT_SYMBOL(find_vma);
38342 +
38343 +-/*
38344 +- * find a VMA
38345 +- * - we don't extend stack VMAs under NOMMU conditions
38346 +- */
38347 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
38348 +-{
38349 +- return find_vma(mm, addr);
38350 +-}
38351 +-
38352 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
38353 + {
38354 + return -ENOMEM;
38355 +diff -urNp linux-2.6.26.6/mm/page_alloc.c linux-2.6.26.6/mm/page_alloc.c
38356 +--- linux-2.6.26.6/mm/page_alloc.c 2008-10-08 23:24:05.000000000 -0400
38357 ++++ linux-2.6.26.6/mm/page_alloc.c 2008-10-11 21:54:20.000000000 -0400
38358 +@@ -497,9 +497,20 @@ static void free_pages_bulk(struct zone
38359 +
38360 + static void free_one_page(struct zone *zone, struct page *page, int order)
38361 + {
38362 ++
38363 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
38364 ++ unsigned long index = 1UL << order;
38365 ++#endif
38366 ++
38367 + spin_lock(&zone->lock);
38368 + zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
38369 + zone->pages_scanned = 0;
38370 ++
38371 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
38372 ++ for (; index; --index)
38373 ++ sanitize_highpage(page + index - 1);
38374 ++#endif
38375 ++
38376 + __free_one_page(page, zone, order);
38377 + spin_unlock(&zone->lock);
38378 + }
38379 +@@ -617,8 +628,10 @@ static int prep_new_page(struct page *pa
38380 + arch_alloc_page(page, order);
38381 + kernel_map_pages(page, 1 << order, 1);
38382 +
38383 ++#ifndef CONFIG_PAX_MEMORY_SANITIZE
38384 + if (gfp_flags & __GFP_ZERO)
38385 + prep_zero_page(page, order, gfp_flags);
38386 ++#endif
38387 +
38388 + if (order && (gfp_flags & __GFP_COMP))
38389 + prep_compound_page(page, order);
38390 +@@ -990,6 +1003,11 @@ static void free_hot_cold_page(struct pa
38391 + list_add(&page->lru, &pcp->list);
38392 + set_page_private(page, get_pageblock_migratetype(page));
38393 + pcp->count++;
38394 ++
38395 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
38396 ++ sanitize_highpage(page);
38397 ++#endif
38398 ++
38399 + if (pcp->count >= pcp->high) {
38400 + free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
38401 + pcp->count -= pcp->batch;
38402 +diff -urNp linux-2.6.26.6/mm/rmap.c linux-2.6.26.6/mm/rmap.c
38403 +--- linux-2.6.26.6/mm/rmap.c 2008-10-08 23:24:05.000000000 -0400
38404 ++++ linux-2.6.26.6/mm/rmap.c 2008-10-11 21:54:20.000000000 -0400
38405 +@@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
38406 + struct mm_struct *mm = vma->vm_mm;
38407 + struct anon_vma *allocated, *locked;
38408 +
38409 ++#ifdef CONFIG_PAX_SEGMEXEC
38410 ++ struct vm_area_struct *vma_m;
38411 ++#endif
38412 ++
38413 + anon_vma = find_mergeable_anon_vma(vma);
38414 + if (anon_vma) {
38415 + allocated = NULL;
38416 +@@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
38417 + /* page_table_lock to protect against threads */
38418 + spin_lock(&mm->page_table_lock);
38419 + if (likely(!vma->anon_vma)) {
38420 ++
38421 ++#ifdef CONFIG_PAX_SEGMEXEC
38422 ++ vma_m = pax_find_mirror_vma(vma);
38423 ++ if (vma_m) {
38424 ++ vma_m->anon_vma = anon_vma;
38425 ++ __anon_vma_link(vma_m);
38426 ++ }
38427 ++#endif
38428 ++
38429 + vma->anon_vma = anon_vma;
38430 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
38431 + allocated = NULL;
38432 +diff -urNp linux-2.6.26.6/mm/shmem.c linux-2.6.26.6/mm/shmem.c
38433 +--- linux-2.6.26.6/mm/shmem.c 2008-10-08 23:24:05.000000000 -0400
38434 ++++ linux-2.6.26.6/mm/shmem.c 2008-10-11 21:54:20.000000000 -0400
38435 +@@ -2460,7 +2460,7 @@ static struct file_system_type tmpfs_fs_
38436 + .get_sb = shmem_get_sb,
38437 + .kill_sb = kill_litter_super,
38438 + };
38439 +-static struct vfsmount *shm_mnt;
38440 ++struct vfsmount *shm_mnt;
38441 +
38442 + static int __init init_tmpfs(void)
38443 + {
38444 +diff -urNp linux-2.6.26.6/mm/slab.c linux-2.6.26.6/mm/slab.c
38445 +--- linux-2.6.26.6/mm/slab.c 2008-10-08 23:24:05.000000000 -0400
38446 ++++ linux-2.6.26.6/mm/slab.c 2008-10-11 21:54:20.000000000 -0400
38447 +@@ -304,7 +304,7 @@ struct kmem_list3 {
38448 + * Need this for bootstrapping a per node allocator.
38449 + */
38450 + #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
38451 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
38452 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
38453 + #define CACHE_CACHE 0
38454 + #define SIZE_AC MAX_NUMNODES
38455 + #define SIZE_L3 (2 * MAX_NUMNODES)
38456 +@@ -653,14 +653,14 @@ struct cache_names {
38457 + static struct cache_names __initdata cache_names[] = {
38458 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
38459 + #include <linux/kmalloc_sizes.h>
38460 +- {NULL,}
38461 ++ {NULL, NULL}
38462 + #undef CACHE
38463 + };
38464 +
38465 + static struct arraycache_init initarray_cache __initdata =
38466 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
38467 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
38468 + static struct arraycache_init initarray_generic =
38469 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
38470 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
38471 +
38472 + /* internal cache of cache description objs */
38473 + static struct kmem_cache cache_cache = {
38474 +@@ -3005,7 +3005,7 @@ retry:
38475 + * there must be at least one object available for
38476 + * allocation.
38477 + */
38478 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
38479 ++ BUG_ON(slabp->inuse >= cachep->num);
38480 +
38481 + while (slabp->inuse < cachep->num && batchcount--) {
38482 + STATS_INC_ALLOCED(cachep);
38483 +diff -urNp linux-2.6.26.6/mm/swap.c linux-2.6.26.6/mm/swap.c
38484 +--- linux-2.6.26.6/mm/swap.c 2008-10-08 23:24:05.000000000 -0400
38485 ++++ linux-2.6.26.6/mm/swap.c 2008-10-11 21:54:20.000000000 -0400
38486 +@@ -34,9 +34,9 @@
38487 + /* How many pages do we try to swap or page in/out together? */
38488 + int page_cluster;
38489 +
38490 +-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
38491 +-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
38492 +-static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
38493 ++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
38494 ++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
38495 ++static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
38496 +
38497 + /*
38498 + * This path almost never happens for VM activity - pages are normally
38499 +diff -urNp linux-2.6.26.6/mm/tiny-shmem.c linux-2.6.26.6/mm/tiny-shmem.c
38500 +--- linux-2.6.26.6/mm/tiny-shmem.c 2008-10-08 23:24:05.000000000 -0400
38501 ++++ linux-2.6.26.6/mm/tiny-shmem.c 2008-10-11 21:54:20.000000000 -0400
38502 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
38503 + .kill_sb = kill_litter_super,
38504 + };
38505 +
38506 +-static struct vfsmount *shm_mnt;
38507 ++struct vfsmount *shm_mnt;
38508 +
38509 + static int __init init_tmpfs(void)
38510 + {
38511 +diff -urNp linux-2.6.26.6/mm/vmalloc.c linux-2.6.26.6/mm/vmalloc.c
38512 +--- linux-2.6.26.6/mm/vmalloc.c 2008-10-08 23:24:05.000000000 -0400
38513 ++++ linux-2.6.26.6/mm/vmalloc.c 2008-10-11 21:54:20.000000000 -0400
38514 +@@ -248,20 +248,15 @@ __get_vm_area_node(unsigned long size, u
38515 + (unsigned long)tmp->addr, align);
38516 + continue;
38517 + }
38518 +- if ((size + addr) < addr)
38519 +- goto out;
38520 + if (size + addr <= (unsigned long)tmp->addr)
38521 +- goto found;
38522 ++ break;
38523 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
38524 +- if (addr > end - size)
38525 +- goto out;
38526 + }
38527 + if ((size + addr) < addr)
38528 + goto out;
38529 + if (addr > end - size)
38530 + goto out;
38531 +
38532 +-found:
38533 + area->next = *p;
38534 + *p = area;
38535 +
38536 +@@ -653,7 +648,7 @@ EXPORT_SYMBOL(vmalloc_node);
38537 +
38538 + void *vmalloc_exec(unsigned long size)
38539 + {
38540 +- return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
38541 ++ return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
38542 + }
38543 +
38544 + #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
38545 +diff -urNp linux-2.6.26.6/net/bridge/br_stp_if.c linux-2.6.26.6/net/bridge/br_stp_if.c
38546 +--- linux-2.6.26.6/net/bridge/br_stp_if.c 2008-10-08 23:24:05.000000000 -0400
38547 ++++ linux-2.6.26.6/net/bridge/br_stp_if.c 2008-10-11 21:54:20.000000000 -0400
38548 +@@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
38549 + char *envp[] = { NULL };
38550 +
38551 + if (br->stp_enabled == BR_USER_STP) {
38552 +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
38553 ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
38554 + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
38555 + br->dev->name, r);
38556 +
38557 +diff -urNp linux-2.6.26.6/net/core/flow.c linux-2.6.26.6/net/core/flow.c
38558 +--- linux-2.6.26.6/net/core/flow.c 2008-10-08 23:24:05.000000000 -0400
38559 ++++ linux-2.6.26.6/net/core/flow.c 2008-10-11 21:54:20.000000000 -0400
38560 +@@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
38561 +
38562 + static u32 flow_hash_shift;
38563 + #define flow_hash_size (1 << flow_hash_shift)
38564 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
38565 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
38566 +
38567 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
38568 +
38569 +@@ -52,7 +52,7 @@ struct flow_percpu_info {
38570 + u32 hash_rnd;
38571 + int count;
38572 + };
38573 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
38574 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
38575 +
38576 + #define flow_hash_rnd_recalc(cpu) \
38577 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
38578 +@@ -69,7 +69,7 @@ struct flow_flush_info {
38579 + atomic_t cpuleft;
38580 + struct completion completion;
38581 + };
38582 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
38583 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
38584 +
38585 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
38586 +
38587 +diff -urNp linux-2.6.26.6/net/dccp/ccids/ccid3.c linux-2.6.26.6/net/dccp/ccids/ccid3.c
38588 +--- linux-2.6.26.6/net/dccp/ccids/ccid3.c 2008-10-08 23:24:05.000000000 -0400
38589 ++++ linux-2.6.26.6/net/dccp/ccids/ccid3.c 2008-10-11 21:54:20.000000000 -0400
38590 +@@ -43,7 +43,7 @@
38591 + static int ccid3_debug;
38592 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
38593 + #else
38594 +-#define ccid3_pr_debug(format, a...)
38595 ++#define ccid3_pr_debug(format, a...) do {} while (0)
38596 + #endif
38597 +
38598 + /*
38599 +diff -urNp linux-2.6.26.6/net/dccp/dccp.h linux-2.6.26.6/net/dccp/dccp.h
38600 +--- linux-2.6.26.6/net/dccp/dccp.h 2008-10-08 23:24:05.000000000 -0400
38601 ++++ linux-2.6.26.6/net/dccp/dccp.h 2008-10-11 21:54:20.000000000 -0400
38602 +@@ -43,8 +43,8 @@ extern int dccp_debug;
38603 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
38604 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
38605 + #else
38606 +-#define dccp_pr_debug(format, a...)
38607 +-#define dccp_pr_debug_cat(format, a...)
38608 ++#define dccp_pr_debug(format, a...) do {} while (0)
38609 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
38610 + #endif
38611 +
38612 + extern struct inet_hashinfo dccp_hashinfo;
38613 +diff -urNp linux-2.6.26.6/net/ipv4/inet_connection_sock.c linux-2.6.26.6/net/ipv4/inet_connection_sock.c
38614 +--- linux-2.6.26.6/net/ipv4/inet_connection_sock.c 2008-10-08 23:24:05.000000000 -0400
38615 ++++ linux-2.6.26.6/net/ipv4/inet_connection_sock.c 2008-10-11 21:54:20.000000000 -0400
38616 +@@ -15,6 +15,7 @@
38617 +
38618 + #include <linux/module.h>
38619 + #include <linux/jhash.h>
38620 ++#include <linux/grsecurity.h>
38621 +
38622 + #include <net/inet_connection_sock.h>
38623 + #include <net/inet_hashtables.h>
38624 +diff -urNp linux-2.6.26.6/net/ipv4/inet_hashtables.c linux-2.6.26.6/net/ipv4/inet_hashtables.c
38625 +--- linux-2.6.26.6/net/ipv4/inet_hashtables.c 2008-10-08 23:24:05.000000000 -0400
38626 ++++ linux-2.6.26.6/net/ipv4/inet_hashtables.c 2008-10-11 21:54:20.000000000 -0400
38627 +@@ -18,11 +18,14 @@
38628 + #include <linux/sched.h>
38629 + #include <linux/slab.h>
38630 + #include <linux/wait.h>
38631 ++#include <linux/grsecurity.h>
38632 +
38633 + #include <net/inet_connection_sock.h>
38634 + #include <net/inet_hashtables.h>
38635 + #include <net/ip.h>
38636 +
38637 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
38638 ++
38639 + /*
38640 + * Allocate and initialize a new local port bind bucket.
38641 + * The bindhash mutex for snum's hash chain must be held here.
38642 +@@ -484,6 +487,8 @@ ok:
38643 + }
38644 + spin_unlock(&head->lock);
38645 +
38646 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
38647 ++
38648 + if (tw) {
38649 + inet_twsk_deschedule(tw, death_row);
38650 + inet_twsk_put(tw);
38651 +diff -urNp linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c
38652 +--- linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
38653 ++++ linux-2.6.26.6/net/ipv4/netfilter/ipt_stealth.c 2008-10-11 21:54:20.000000000 -0400
38654 +@@ -0,0 +1,114 @@
38655 ++/* Kernel module to add stealth support.
38656 ++ *
38657 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
38658 ++ *
38659 ++ */
38660 ++
38661 ++#include <linux/kernel.h>
38662 ++#include <linux/module.h>
38663 ++#include <linux/skbuff.h>
38664 ++#include <linux/net.h>
38665 ++#include <linux/sched.h>
38666 ++#include <linux/inet.h>
38667 ++#include <linux/stddef.h>
38668 ++
38669 ++#include <net/ip.h>
38670 ++#include <net/sock.h>
38671 ++#include <net/tcp.h>
38672 ++#include <net/udp.h>
38673 ++#include <net/route.h>
38674 ++#include <net/inet_common.h>
38675 ++
38676 ++#include <linux/netfilter_ipv4/ip_tables.h>
38677 ++
38678 ++MODULE_LICENSE("GPL");
38679 ++
38680 ++extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
38681 ++
38682 ++static bool
38683 ++match(const struct sk_buff *skb,
38684 ++ const struct net_device *in,
38685 ++ const struct net_device *out,
38686 ++ const struct xt_match *match,
38687 ++ const void *matchinfo,
38688 ++ int offset,
38689 ++ unsigned int protoff,
38690 ++ bool *hotdrop)
38691 ++{
38692 ++ struct iphdr *ip = ip_hdr(skb);
38693 ++ struct tcphdr th;
38694 ++ struct udphdr uh;
38695 ++ struct sock *sk = NULL;
38696 ++
38697 ++ if (!ip || offset) return false;
38698 ++
38699 ++ switch(ip->protocol) {
38700 ++ case IPPROTO_TCP:
38701 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
38702 ++ *hotdrop = true;
38703 ++ return false;
38704 ++ }
38705 ++ if (!(th.syn && !th.ack)) return false;
38706 ++ sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
38707 ++ break;
38708 ++ case IPPROTO_UDP:
38709 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
38710 ++ *hotdrop = true;
38711 ++ return false;
38712 ++ }
38713 ++ sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
38714 ++ break;
38715 ++ default:
38716 ++ return false;
38717 ++ }
38718 ++
38719 ++ if(!sk) // port is being listened on, match this
38720 ++ return true;
38721 ++ else {
38722 ++ sock_put(sk);
38723 ++ return false;
38724 ++ }
38725 ++}
38726 ++
38727 ++/* Called when user tries to insert an entry of this type. */
38728 ++static bool
38729 ++checkentry(const char *tablename,
38730 ++ const void *nip,
38731 ++ const struct xt_match *match,
38732 ++ void *matchinfo,
38733 ++ unsigned int hook_mask)
38734 ++{
38735 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
38736 ++
38737 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
38738 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
38739 ++ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
38740 ++ return true;
38741 ++
38742 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
38743 ++
38744 ++ return false;
38745 ++}
38746 ++
38747 ++
38748 ++static struct xt_match stealth_match __read_mostly = {
38749 ++ .name = "stealth",
38750 ++ .family = AF_INET,
38751 ++ .match = match,
38752 ++ .checkentry = checkentry,
38753 ++ .destroy = NULL,
38754 ++ .me = THIS_MODULE
38755 ++};
38756 ++
38757 ++static int __init init(void)
38758 ++{
38759 ++ return xt_register_match(&stealth_match);
38760 ++}
38761 ++
38762 ++static void __exit fini(void)
38763 ++{
38764 ++ xt_unregister_match(&stealth_match);
38765 ++}
38766 ++
38767 ++module_init(init);
38768 ++module_exit(fini);
38769 +diff -urNp linux-2.6.26.6/net/ipv4/netfilter/Kconfig linux-2.6.26.6/net/ipv4/netfilter/Kconfig
38770 +--- linux-2.6.26.6/net/ipv4/netfilter/Kconfig 2008-10-08 23:24:05.000000000 -0400
38771 ++++ linux-2.6.26.6/net/ipv4/netfilter/Kconfig 2008-10-11 21:54:20.000000000 -0400
38772 +@@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
38773 + If you want to compile it as a module, say M here and read
38774 + <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
38775 +
38776 ++config IP_NF_MATCH_STEALTH
38777 ++ tristate "stealth match support"
38778 ++ depends on IP_NF_IPTABLES
38779 ++ help
38780 ++ Enabling this option will drop all syn packets coming to unserved tcp
38781 ++ ports as well as all packets coming to unserved udp ports. If you
38782 ++ are using your system to route any type of packets (ie. via NAT)
38783 ++ you should put this module at the end of your ruleset, since it will
38784 ++ drop packets that aren't going to ports that are listening on your
38785 ++ machine itself, it doesn't take into account that the packet might be
38786 ++ destined for someone on your internal network if you're using NAT for
38787 ++ instance.
38788 ++
38789 ++ To compile it as a module, choose M here. If unsure, say N.
38790 ++
38791 + # `filter', generic and specific targets
38792 + config IP_NF_FILTER
38793 + tristate "Packet filtering"
38794 +@@ -396,4 +411,3 @@ config IP_NF_ARP_MANGLE
38795 + hardware and network addresses.
38796 +
38797 + endmenu
38798 +-
38799 +diff -urNp linux-2.6.26.6/net/ipv4/netfilter/Makefile linux-2.6.26.6/net/ipv4/netfilter/Makefile
38800 +--- linux-2.6.26.6/net/ipv4/netfilter/Makefile 2008-10-08 23:24:05.000000000 -0400
38801 ++++ linux-2.6.26.6/net/ipv4/netfilter/Makefile 2008-10-11 21:54:20.000000000 -0400
38802 +@@ -58,6 +58,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
38803 + obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
38804 + obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
38805 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
38806 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
38807 + obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
38808 + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
38809 +
38810 +diff -urNp linux-2.6.26.6/net/ipv4/tcp_ipv4.c linux-2.6.26.6/net/ipv4/tcp_ipv4.c
38811 +--- linux-2.6.26.6/net/ipv4/tcp_ipv4.c 2008-10-08 23:24:05.000000000 -0400
38812 ++++ linux-2.6.26.6/net/ipv4/tcp_ipv4.c 2008-10-11 21:54:20.000000000 -0400
38813 +@@ -61,6 +61,7 @@
38814 + #include <linux/jhash.h>
38815 + #include <linux/init.h>
38816 + #include <linux/times.h>
38817 ++#include <linux/grsecurity.h>
38818 +
38819 + #include <net/net_namespace.h>
38820 + #include <net/icmp.h>
38821 +diff -urNp linux-2.6.26.6/net/ipv4/udp.c linux-2.6.26.6/net/ipv4/udp.c
38822 +--- linux-2.6.26.6/net/ipv4/udp.c 2008-10-08 23:24:05.000000000 -0400
38823 ++++ linux-2.6.26.6/net/ipv4/udp.c 2008-10-11 21:54:20.000000000 -0400
38824 +@@ -99,6 +99,7 @@
38825 + #include <linux/skbuff.h>
38826 + #include <linux/proc_fs.h>
38827 + #include <linux/seq_file.h>
38828 ++#include <linux/grsecurity.h>
38829 + #include <net/net_namespace.h>
38830 + #include <net/icmp.h>
38831 + #include <net/route.h>
38832 +@@ -106,6 +107,11 @@
38833 + #include <net/xfrm.h>
38834 + #include "udp_impl.h"
38835 +
38836 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
38837 ++ const struct sk_buff *skb);
38838 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
38839 ++ const struct sockaddr_in *addr);
38840 ++
38841 + /*
38842 + * Snmp MIB for the UDP layer
38843 + */
38844 +@@ -307,6 +313,13 @@ static struct sock *__udp4_lib_lookup(st
38845 + return result;
38846 + }
38847 +
38848 ++struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
38849 ++ __be32 daddr, __be16 dport, int dif)
38850 ++{
38851 ++ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
38852 ++}
38853 ++
38854 ++
38855 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
38856 + __be16 loc_port, __be32 loc_addr,
38857 + __be16 rmt_port, __be32 rmt_addr,
38858 +@@ -594,9 +607,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
38859 + dport = usin->sin_port;
38860 + if (dport == 0)
38861 + return -EINVAL;
38862 ++
38863 ++ if (!gr_search_udp_sendmsg(sk, usin))
38864 ++ return -EPERM;
38865 + } else {
38866 + if (sk->sk_state != TCP_ESTABLISHED)
38867 + return -EDESTADDRREQ;
38868 ++
38869 ++ if (!gr_search_udp_sendmsg(sk, NULL))
38870 ++ return -EPERM;
38871 ++
38872 + daddr = inet->daddr;
38873 + dport = inet->dport;
38874 + /* Open fast path for connected socket.
38875 +@@ -858,6 +878,11 @@ try_again:
38876 + if (!skb)
38877 + goto out;
38878 +
38879 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
38880 ++ err = -EPERM;
38881 ++ goto out_free;
38882 ++ }
38883 ++
38884 + ulen = skb->len - sizeof(struct udphdr);
38885 + copied = len;
38886 + if (copied > ulen)
38887 +diff -urNp linux-2.6.26.6/net/ipv6/exthdrs.c linux-2.6.26.6/net/ipv6/exthdrs.c
38888 +--- linux-2.6.26.6/net/ipv6/exthdrs.c 2008-10-08 23:24:05.000000000 -0400
38889 ++++ linux-2.6.26.6/net/ipv6/exthdrs.c 2008-10-11 21:54:20.000000000 -0400
38890 +@@ -626,7 +626,7 @@ static struct tlvtype_proc tlvprochopopt
38891 + .type = IPV6_TLV_JUMBO,
38892 + .func = ipv6_hop_jumbo,
38893 + },
38894 +- { -1, }
38895 ++ { -1, NULL }
38896 + };
38897 +
38898 + int ipv6_parse_hopopts(struct sk_buff *skb)
38899 +diff -urNp linux-2.6.26.6/net/ipv6/raw.c linux-2.6.26.6/net/ipv6/raw.c
38900 +--- linux-2.6.26.6/net/ipv6/raw.c 2008-10-08 23:24:05.000000000 -0400
38901 ++++ linux-2.6.26.6/net/ipv6/raw.c 2008-10-11 21:54:20.000000000 -0400
38902 +@@ -602,7 +602,7 @@ out:
38903 + return err;
38904 + }
38905 +
38906 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
38907 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
38908 + struct flowi *fl, struct rt6_info *rt,
38909 + unsigned int flags)
38910 + {
38911 +diff -urNp linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c
38912 +--- linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c 2008-10-08 23:24:05.000000000 -0400
38913 ++++ linux-2.6.26.6/net/irda/ircomm/ircomm_tty.c 2008-10-11 21:54:20.000000000 -0400
38914 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
38915 + IRDA_DEBUG(2, "%s()\n", __func__ );
38916 +
38917 + line = tty->index;
38918 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
38919 ++ if (line >= IRCOMM_TTY_PORTS) {
38920 + return -ENODEV;
38921 + }
38922 +
38923 +diff -urNp linux-2.6.26.6/net/sctp/socket.c linux-2.6.26.6/net/sctp/socket.c
38924 +--- linux-2.6.26.6/net/sctp/socket.c 2008-10-08 23:24:05.000000000 -0400
38925 ++++ linux-2.6.26.6/net/sctp/socket.c 2008-10-11 21:55:52.000000000 -0400
38926 +@@ -1386,7 +1386,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
38927 + struct sctp_sndrcvinfo *sinfo;
38928 + struct sctp_initmsg *sinit;
38929 + sctp_assoc_t associd = 0;
38930 +- sctp_cmsgs_t cmsgs = { NULL };
38931 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
38932 + int err;
38933 + sctp_scope_t scope;
38934 + long timeo;
38935 +@@ -5472,7 +5472,6 @@ pp_found:
38936 + */
38937 + int reuse = sk->sk_reuse;
38938 + struct sock *sk2;
38939 +- struct hlist_node *node;
38940 +
38941 + SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
38942 + if (pp->fastreuse && sk->sk_reuse &&
38943 +diff -urNp linux-2.6.26.6/net/socket.c linux-2.6.26.6/net/socket.c
38944 +--- linux-2.6.26.6/net/socket.c 2008-10-08 23:24:05.000000000 -0400
38945 ++++ linux-2.6.26.6/net/socket.c 2008-10-11 21:54:20.000000000 -0400
38946 +@@ -85,6 +85,7 @@
38947 + #include <linux/audit.h>
38948 + #include <linux/wireless.h>
38949 + #include <linux/nsproxy.h>
38950 ++#include <linux/in.h>
38951 +
38952 + #include <asm/uaccess.h>
38953 + #include <asm/unistd.h>
38954 +@@ -94,6 +95,21 @@
38955 + #include <net/sock.h>
38956 + #include <linux/netfilter.h>
38957 +
38958 ++extern void gr_attach_curr_ip(const struct sock *sk);
38959 ++extern int gr_handle_sock_all(const int family, const int type,
38960 ++ const int protocol);
38961 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
38962 ++extern int gr_handle_sock_server_other(const struct socket *sck);
38963 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
38964 ++extern int gr_search_connect(const struct socket * sock,
38965 ++ const struct sockaddr_in * addr);
38966 ++extern int gr_search_bind(const struct socket * sock,
38967 ++ const struct sockaddr_in * addr);
38968 ++extern int gr_search_listen(const struct socket * sock);
38969 ++extern int gr_search_accept(const struct socket * sock);
38970 ++extern int gr_search_socket(const int domain, const int type,
38971 ++ const int protocol);
38972 ++
38973 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
38974 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
38975 + unsigned long nr_segs, loff_t pos);
38976 +@@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
38977 + mnt);
38978 + }
38979 +
38980 +-static struct vfsmount *sock_mnt __read_mostly;
38981 ++struct vfsmount *sock_mnt __read_mostly;
38982 +
38983 + static struct file_system_type sock_fs_type = {
38984 + .name = "sockfs",
38985 +@@ -1218,6 +1234,16 @@ asmlinkage long sys_socket(int family, i
38986 + int retval;
38987 + struct socket *sock;
38988 +
38989 ++ if(!gr_search_socket(family, type, protocol)) {
38990 ++ retval = -EACCES;
38991 ++ goto out;
38992 ++ }
38993 ++
38994 ++ if (gr_handle_sock_all(family, type, protocol)) {
38995 ++ retval = -EACCES;
38996 ++ goto out;
38997 ++ }
38998 ++
38999 + retval = sock_create(family, type, protocol, &sock);
39000 + if (retval < 0)
39001 + goto out;
39002 +@@ -1348,6 +1374,12 @@ asmlinkage long sys_bind(int fd, struct
39003 + if (sock) {
39004 + err = move_addr_to_kernel(umyaddr, addrlen, address);
39005 + if (err >= 0) {
39006 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
39007 ++ gr_handle_sock_server((struct sockaddr *)address)) {
39008 ++ err = -EACCES;
39009 ++ goto error;
39010 ++ }
39011 ++
39012 + err = security_socket_bind(sock,
39013 + (struct sockaddr *)address,
39014 + addrlen);
39015 +@@ -1356,6 +1388,7 @@ asmlinkage long sys_bind(int fd, struct
39016 + (struct sockaddr *)
39017 + address, addrlen);
39018 + }
39019 ++error:
39020 + fput_light(sock->file, fput_needed);
39021 + }
39022 + return err;
39023 +@@ -1379,10 +1412,17 @@ asmlinkage long sys_listen(int fd, int b
39024 + if ((unsigned)backlog > somaxconn)
39025 + backlog = somaxconn;
39026 +
39027 ++ if (gr_handle_sock_server_other(sock) ||
39028 ++ !gr_search_listen(sock)) {
39029 ++ err = -EPERM;
39030 ++ goto error;
39031 ++ }
39032 ++
39033 + err = security_socket_listen(sock, backlog);
39034 + if (!err)
39035 + err = sock->ops->listen(sock, backlog);
39036 +
39037 ++error:
39038 + fput_light(sock->file, fput_needed);
39039 + }
39040 + return err;
39041 +@@ -1419,6 +1459,13 @@ asmlinkage long sys_accept(int fd, struc
39042 + newsock->type = sock->type;
39043 + newsock->ops = sock->ops;
39044 +
39045 ++ if (gr_handle_sock_server_other(sock) ||
39046 ++ !gr_search_accept(sock)) {
39047 ++ err = -EPERM;
39048 ++ sock_release(newsock);
39049 ++ goto out_put;
39050 ++ }
39051 ++
39052 + /*
39053 + * We don't need try_module_get here, as the listening socket (sock)
39054 + * has the protocol module (sock->ops->owner) held.
39055 +@@ -1462,6 +1509,7 @@ asmlinkage long sys_accept(int fd, struc
39056 + err = newfd;
39057 +
39058 + security_socket_post_accept(sock, newsock);
39059 ++ gr_attach_curr_ip(newsock->sk);
39060 +
39061 + out_put:
39062 + fput_light(sock->file, fput_needed);
39063 +@@ -1495,6 +1543,7 @@ asmlinkage long sys_connect(int fd, stru
39064 + {
39065 + struct socket *sock;
39066 + char address[MAX_SOCK_ADDR];
39067 ++ struct sockaddr *sck;
39068 + int err, fput_needed;
39069 +
39070 + sock = sockfd_lookup_light(fd, &err, &fput_needed);
39071 +@@ -1504,6 +1553,13 @@ asmlinkage long sys_connect(int fd, stru
39072 + if (err < 0)
39073 + goto out_put;
39074 +
39075 ++ sck = (struct sockaddr *)address;
39076 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
39077 ++ gr_handle_sock_client(sck)) {
39078 ++ err = -EACCES;
39079 ++ goto out_put;
39080 ++ }
39081 ++
39082 + err =
39083 + security_socket_connect(sock, (struct sockaddr *)address, addrlen);
39084 + if (err)
39085 +@@ -1770,6 +1826,7 @@ asmlinkage long sys_shutdown(int fd, int
39086 + err = sock->ops->shutdown(sock, how);
39087 + fput_light(sock->file, fput_needed);
39088 + }
39089 ++
39090 + return err;
39091 + }
39092 +
39093 +diff -urNp linux-2.6.26.6/net/unix/af_unix.c linux-2.6.26.6/net/unix/af_unix.c
39094 +--- linux-2.6.26.6/net/unix/af_unix.c 2008-10-08 23:24:05.000000000 -0400
39095 ++++ linux-2.6.26.6/net/unix/af_unix.c 2008-10-11 21:54:20.000000000 -0400
39096 +@@ -116,6 +116,7 @@
39097 + #include <linux/mount.h>
39098 + #include <net/checksum.h>
39099 + #include <linux/security.h>
39100 ++#include <linux/grsecurity.h>
39101 +
39102 + static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
39103 + static DEFINE_SPINLOCK(unix_table_lock);
39104 +@@ -727,6 +728,12 @@ static struct sock *unix_find_other(stru
39105 + err = -ECONNREFUSED;
39106 + if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
39107 + goto put_fail;
39108 ++
39109 ++ if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
39110 ++ err = -EACCES;
39111 ++ goto put_fail;
39112 ++ }
39113 ++
39114 + u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
39115 + if (!u)
39116 + goto put_fail;
39117 +@@ -747,6 +754,13 @@ static struct sock *unix_find_other(stru
39118 + if (u) {
39119 + struct dentry *dentry;
39120 + dentry = unix_sk(u)->dentry;
39121 ++
39122 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
39123 ++ err = -EPERM;
39124 ++ sock_put(u);
39125 ++ goto fail;
39126 ++ }
39127 ++
39128 + if (dentry)
39129 + touch_atime(unix_sk(u)->mnt, dentry);
39130 + } else
39131 +@@ -829,10 +843,20 @@ static int unix_bind(struct socket *sock
39132 + err = mnt_want_write(nd.path.mnt);
39133 + if (err)
39134 + goto out_mknod_dput;
39135 ++
39136 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
39137 ++ err = -EACCES;
39138 ++ mnt_drop_write(nd.path.mnt);
39139 ++ goto out_mknod_dput;
39140 ++ }
39141 ++
39142 + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
39143 + mnt_drop_write(nd.path.mnt);
39144 + if (err)
39145 + goto out_mknod_dput;
39146 ++
39147 ++ gr_handle_create(dentry, nd.path.mnt);
39148 ++
39149 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
39150 + dput(nd.path.dentry);
39151 + nd.path.dentry = dentry;
39152 +@@ -850,6 +874,10 @@ static int unix_bind(struct socket *sock
39153 + goto out_unlock;
39154 + }
39155 +
39156 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
39157 ++ sk->sk_peercred.pid = current->pid;
39158 ++#endif
39159 ++
39160 + list = &unix_socket_table[addr->hash];
39161 + } else {
39162 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
39163 +diff -urNp linux-2.6.26.6/scripts/pnmtologo.c linux-2.6.26.6/scripts/pnmtologo.c
39164 +--- linux-2.6.26.6/scripts/pnmtologo.c 2008-10-08 23:24:05.000000000 -0400
39165 ++++ linux-2.6.26.6/scripts/pnmtologo.c 2008-10-11 21:54:20.000000000 -0400
39166 +@@ -237,14 +237,14 @@ static void write_header(void)
39167 + fprintf(out, " * Linux logo %s\n", logoname);
39168 + fputs(" */\n\n", out);
39169 + fputs("#include <linux/linux_logo.h>\n\n", out);
39170 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
39171 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
39172 + logoname);
39173 + }
39174 +
39175 + static void write_footer(void)
39176 + {
39177 + fputs("\n};\n\n", out);
39178 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
39179 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
39180 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
39181 + fprintf(out, " .width\t= %d,\n", logo_width);
39182 + fprintf(out, " .height\t= %d,\n", logo_height);
39183 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
39184 + fputs("\n};\n\n", out);
39185 +
39186 + /* write logo clut */
39187 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
39188 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
39189 + logoname);
39190 + write_hex_cnt = 0;
39191 + for (i = 0; i < logo_clutsize; i++) {
39192 +diff -urNp linux-2.6.26.6/security/commoncap.c linux-2.6.26.6/security/commoncap.c
39193 +--- linux-2.6.26.6/security/commoncap.c 2008-10-08 23:24:05.000000000 -0400
39194 ++++ linux-2.6.26.6/security/commoncap.c 2008-10-11 21:54:20.000000000 -0400
39195 +@@ -26,10 +26,13 @@
39196 + #include <linux/sched.h>
39197 + #include <linux/prctl.h>
39198 + #include <linux/securebits.h>
39199 ++#include <linux/grsecurity.h>
39200 ++
39201 ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
39202 +
39203 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
39204 + {
39205 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
39206 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
39207 + return 0;
39208 + }
39209 +
39210 +@@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
39211 + int cap_capable (struct task_struct *tsk, int cap)
39212 + {
39213 + /* Derived from include/linux/sched.h:capable. */
39214 +- if (cap_raised(tsk->cap_effective, cap))
39215 ++ if (cap_raised (tsk->cap_effective, cap))
39216 ++ return 0;
39217 ++ return -EPERM;
39218 ++}
39219 ++
39220 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
39221 ++{
39222 ++ /* tsk = current for all callers */
39223 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
39224 + return 0;
39225 + return -EPERM;
39226 + }
39227 +@@ -356,8 +367,11 @@ void cap_bprm_apply_creds (struct linux_
39228 + }
39229 + }
39230 +
39231 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
39232 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
39233 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
39234 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
39235 ++
39236 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
39237 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
39238 +
39239 + /* For init, we want to retain the capabilities set
39240 + * in the init_task struct. Thus we skip the usual
39241 +@@ -370,6 +384,8 @@ void cap_bprm_apply_creds (struct linux_
39242 + cap_clear(current->cap_effective);
39243 + }
39244 +
39245 ++ gr_handle_chroot_caps(current);
39246 ++
39247 + /* AUD: Audit candidate if current->cap_effective is set */
39248 +
39249 + current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
39250 +@@ -684,7 +700,7 @@ int cap_vm_enough_memory(struct mm_struc
39251 + {
39252 + int cap_sys_admin = 0;
39253 +
39254 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
39255 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
39256 + cap_sys_admin = 1;
39257 + return __vm_enough_memory(mm, pages, cap_sys_admin);
39258 + }
39259 +diff -urNp linux-2.6.26.6/security/dummy.c linux-2.6.26.6/security/dummy.c
39260 +--- linux-2.6.26.6/security/dummy.c 2008-10-08 23:24:05.000000000 -0400
39261 ++++ linux-2.6.26.6/security/dummy.c 2008-10-11 21:54:20.000000000 -0400
39262 +@@ -29,6 +29,7 @@
39263 + #include <linux/file.h>
39264 + #include <linux/prctl.h>
39265 + #include <linux/securebits.h>
39266 ++#include <linux/grsecurity.h>
39267 +
39268 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
39269 + {
39270 +@@ -142,8 +143,11 @@ static void dummy_bprm_apply_creds (stru
39271 + }
39272 + }
39273 +
39274 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
39275 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
39276 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
39277 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
39278 ++
39279 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
39280 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
39281 +
39282 + dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
39283 + }
39284 +diff -urNp linux-2.6.26.6/security/Kconfig linux-2.6.26.6/security/Kconfig
39285 +--- linux-2.6.26.6/security/Kconfig 2008-10-08 23:24:05.000000000 -0400
39286 ++++ linux-2.6.26.6/security/Kconfig 2008-10-11 21:56:26.000000000 -0400
39287 +@@ -4,6 +4,447 @@
39288 +
39289 + menu "Security options"
39290 +
39291 ++source grsecurity/Kconfig
39292 ++
39293 ++menu "PaX"
39294 ++
39295 ++config PAX
39296 ++ bool "Enable various PaX features"
39297 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
39298 ++ help
39299 ++ This allows you to enable various PaX features. PaX adds
39300 ++ intrusion prevention mechanisms to the kernel that reduce
39301 ++ the risks posed by exploitable memory corruption bugs.
39302 ++
39303 ++menu "PaX Control"
39304 ++ depends on PAX
39305 ++
39306 ++config PAX_SOFTMODE
39307 ++ bool 'Support soft mode'
39308 ++ help
39309 ++ Enabling this option will allow you to run PaX in soft mode, that
39310 ++ is, PaX features will not be enforced by default, only on executables
39311 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
39312 ++ is the only way to mark executables for soft mode use.
39313 ++
39314 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
39315 ++ line option on boot. Furthermore you can control various PaX features
39316 ++ at runtime via the entries in /proc/sys/kernel/pax.
39317 ++
39318 ++config PAX_EI_PAX
39319 ++ bool 'Use legacy ELF header marking'
39320 ++ help
39321 ++ Enabling this option will allow you to control PaX features on
39322 ++ a per executable basis via the 'chpax' utility available at
39323 ++ http://pax.grsecurity.net/. The control flags will be read from
39324 ++ an otherwise reserved part of the ELF header. This marking has
39325 ++ numerous drawbacks (no support for soft-mode, toolchain does not
39326 ++ know about the non-standard use of the ELF header) therefore it
39327 ++ has been deprecated in favour of PT_PAX_FLAGS support.
39328 ++
39329 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
39330 ++ program header then you MUST enable this option otherwise they
39331 ++ will not get any protection.
39332 ++
39333 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
39334 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
39335 ++
39336 ++config PAX_PT_PAX_FLAGS
39337 ++ bool 'Use ELF program header marking'
39338 ++ help
39339 ++ Enabling this option will allow you to control PaX features on
39340 ++ a per executable basis via the 'paxctl' utility available at
39341 ++ http://pax.grsecurity.net/. The control flags will be read from
39342 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
39343 ++ has the benefits of supporting both soft mode and being fully
39344 ++ integrated into the toolchain (the binutils patch is available
39345 ++ from http://pax.grsecurity.net).
39346 ++
39347 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
39348 ++ program header then you MUST enable the EI_PAX marking support
39349 ++ otherwise they will not get any protection.
39350 ++
39351 ++ Note that if you enable the legacy EI_PAX marking support as well,
39352 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
39353 ++
39354 ++choice
39355 ++ prompt 'MAC system integration'
39356 ++ default PAX_HAVE_ACL_FLAGS
39357 ++ help
39358 ++ Mandatory Access Control systems have the option of controlling
39359 ++ PaX flags on a per executable basis, choose the method supported
39360 ++ by your particular system.
39361 ++
39362 ++ - "none": if your MAC system does not interact with PaX,
39363 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
39364 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
39365 ++
39366 ++ NOTE: this option is for developers/integrators only.
39367 ++
39368 ++ config PAX_NO_ACL_FLAGS
39369 ++ bool 'none'
39370 ++
39371 ++ config PAX_HAVE_ACL_FLAGS
39372 ++ bool 'direct'
39373 ++
39374 ++ config PAX_HOOK_ACL_FLAGS
39375 ++ bool 'hook'
39376 ++endchoice
39377 ++
39378 ++endmenu
39379 ++
39380 ++menu "Non-executable pages"
39381 ++ depends on PAX
39382 ++
39383 ++config PAX_NOEXEC
39384 ++ bool "Enforce non-executable pages"
39385 ++ 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)
39386 ++ help
39387 ++ By design some architectures do not allow for protecting memory
39388 ++ pages against execution or even if they do, Linux does not make
39389 ++ use of this feature. In practice this means that if a page is
39390 ++ readable (such as the stack or heap) it is also executable.
39391 ++
39392 ++ There is a well known exploit technique that makes use of this
39393 ++ fact and a common programming mistake where an attacker can
39394 ++ introduce code of his choice somewhere in the attacked program's
39395 ++ memory (typically the stack or the heap) and then execute it.
39396 ++
39397 ++ If the attacked program was running with different (typically
39398 ++ higher) privileges than that of the attacker, then he can elevate
39399 ++ his own privilege level (e.g. get a root shell, write to files for
39400 ++ which he does not have write access to, etc).
39401 ++
39402 ++ Enabling this option will let you choose from various features
39403 ++ that prevent the injection and execution of 'foreign' code in
39404 ++ a program.
39405 ++
39406 ++ This will also break programs that rely on the old behaviour and
39407 ++ expect that dynamically allocated memory via the malloc() family
39408 ++ of functions is executable (which it is not). Notable examples
39409 ++ are the XFree86 4.x server, the java runtime and wine.
39410 ++
39411 ++config PAX_PAGEEXEC
39412 ++ bool "Paging based non-executable pages"
39413 ++ 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)
39414 ++ help
39415 ++ This implementation is based on the paging feature of the CPU.
39416 ++ On i386 without hardware non-executable bit support there is a
39417 ++ variable but usually low performance impact, however on Intel's
39418 ++ P4 core based CPUs it is very high so you should not enable this
39419 ++ for kernels meant to be used on such CPUs.
39420 ++
39421 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
39422 ++ with hardware non-executable bit support there is no performance
39423 ++ impact, on ppc the impact is negligible.
39424 ++
39425 ++ Note that several architectures require various emulations due to
39426 ++ badly designed userland ABIs, this will cause a performance impact
39427 ++ but will disappear as soon as userland is fixed (e.g., ppc users
39428 ++ can make use of the secure-plt feature found in binutils).
39429 ++
39430 ++config PAX_SEGMEXEC
39431 ++ bool "Segmentation based non-executable pages"
39432 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
39433 ++ help
39434 ++ This implementation is based on the segmentation feature of the
39435 ++ CPU and has a very small performance impact, however applications
39436 ++ will be limited to a 1.5 GB address space instead of the normal
39437 ++ 3 GB.
39438 ++
39439 ++config PAX_EMUTRAMP
39440 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
39441 ++ default y if PARISC || PPC32
39442 ++ help
39443 ++ There are some programs and libraries that for one reason or
39444 ++ another attempt to execute special small code snippets from
39445 ++ non-executable memory pages. Most notable examples are the
39446 ++ signal handler return code generated by the kernel itself and
39447 ++ the GCC trampolines.
39448 ++
39449 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
39450 ++ such programs will no longer work under your kernel.
39451 ++
39452 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
39453 ++ utilities to enable trampoline emulation for the affected programs
39454 ++ yet still have the protection provided by the non-executable pages.
39455 ++
39456 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
39457 ++ well, otherwise your system will not even boot.
39458 ++
39459 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
39460 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
39461 ++ for the affected files.
39462 ++
39463 ++ NOTE: enabling this feature *may* open up a loophole in the
39464 ++ protection provided by non-executable pages that an attacker
39465 ++ could abuse. Therefore the best solution is to not have any
39466 ++ files on your system that would require this option. This can
39467 ++ be achieved by not using libc5 (which relies on the kernel
39468 ++ signal handler return code) and not using or rewriting programs
39469 ++ that make use of the nested function implementation of GCC.
39470 ++ Skilled users can just fix GCC itself so that it implements
39471 ++ nested function calls in a way that does not interfere with PaX.
39472 ++
39473 ++config PAX_EMUSIGRT
39474 ++ bool "Automatically emulate sigreturn trampolines"
39475 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
39476 ++ default y
39477 ++ help
39478 ++ Enabling this option will have the kernel automatically detect
39479 ++ and emulate signal return trampolines executing on the stack
39480 ++ that would otherwise lead to task termination.
39481 ++
39482 ++ This solution is intended as a temporary one for users with
39483 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
39484 ++ Modula-3 runtime, etc) or executables linked to such, basically
39485 ++ everything that does not specify its own SA_RESTORER function in
39486 ++ normal executable memory like glibc 2.1+ does.
39487 ++
39488 ++ On parisc and ppc you MUST enable this option, otherwise your
39489 ++ system will not even boot.
39490 ++
39491 ++ NOTE: this feature cannot be disabled on a per executable basis
39492 ++ and since it *does* open up a loophole in the protection provided
39493 ++ by non-executable pages, the best solution is to not have any
39494 ++ files on your system that would require this option.
39495 ++
39496 ++config PAX_MPROTECT
39497 ++ bool "Restrict mprotect()"
39498 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
39499 ++ help
39500 ++ Enabling this option will prevent programs from
39501 ++ - changing the executable status of memory pages that were
39502 ++ not originally created as executable,
39503 ++ - making read-only executable pages writable again,
39504 ++ - creating executable pages from anonymous memory.
39505 ++
39506 ++ You should say Y here to complete the protection provided by
39507 ++ the enforcement of non-executable pages.
39508 ++
39509 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
39510 ++ this feature on a per file basis.
39511 ++
39512 ++config PAX_NOELFRELOCS
39513 ++ bool "Disallow ELF text relocations"
39514 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
39515 ++ help
39516 ++ Non-executable pages and mprotect() restrictions are effective
39517 ++ in preventing the introduction of new executable code into an
39518 ++ attacked task's address space. There remain only two venues
39519 ++ for this kind of attack: if the attacker can execute already
39520 ++ existing code in the attacked task then he can either have it
39521 ++ create and mmap() a file containing his code or have it mmap()
39522 ++ an already existing ELF library that does not have position
39523 ++ independent code in it and use mprotect() on it to make it
39524 ++ writable and copy his code there. While protecting against
39525 ++ the former approach is beyond PaX, the latter can be prevented
39526 ++ by having only PIC ELF libraries on one's system (which do not
39527 ++ need to relocate their code). If you are sure this is your case,
39528 ++ then enable this option otherwise be careful as you may not even
39529 ++ be able to boot or log on your system (for example, some PAM
39530 ++ modules are erroneously compiled as non-PIC by default).
39531 ++
39532 ++ NOTE: if you are using dynamic ELF executables (as suggested
39533 ++ when using ASLR) then you must have made sure that you linked
39534 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
39535 ++ referenced there has already been updated to support this).
39536 ++
39537 ++config PAX_ETEXECRELOCS
39538 ++ bool "Allow ELF ET_EXEC text relocations"
39539 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
39540 ++ default y
39541 ++ help
39542 ++ On some architectures there are incorrectly created applications
39543 ++ that require text relocations and would not work without enabling
39544 ++ this option. If you are an alpha, ia64 or parisc user, you should
39545 ++ enable this option and disable it once you have made sure that
39546 ++ none of your applications need it.
39547 ++
39548 ++config PAX_EMUPLT
39549 ++ bool "Automatically emulate ELF PLT"
39550 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
39551 ++ default y
39552 ++ help
39553 ++ Enabling this option will have the kernel automatically detect
39554 ++ and emulate the Procedure Linkage Table entries in ELF files.
39555 ++ On some architectures such entries are in writable memory, and
39556 ++ become non-executable leading to task termination. Therefore
39557 ++ it is mandatory that you enable this option on alpha, parisc,
39558 ++ ppc (if secure-plt is not used throughout in userland), sparc
39559 ++ and sparc64, otherwise your system would not even boot.
39560 ++
39561 ++ NOTE: this feature *does* open up a loophole in the protection
39562 ++ provided by the non-executable pages, therefore the proper
39563 ++ solution is to modify the toolchain to produce a PLT that does
39564 ++ not need to be writable.
39565 ++
39566 ++config PAX_DLRESOLVE
39567 ++ bool
39568 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
39569 ++ default y
39570 ++
39571 ++config PAX_SYSCALL
39572 ++ bool
39573 ++ depends on PAX_PAGEEXEC && PPC32
39574 ++ default y
39575 ++
39576 ++config PAX_KERNEXEC
39577 ++ bool "Enforce non-executable kernel pages"
39578 ++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
39579 ++ help
39580 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
39581 ++ that is, enabling this option will make it harder to inject
39582 ++ and execute 'foreign' code in kernel memory itself.
39583 ++
39584 ++endmenu
39585 ++
39586 ++menu "Address Space Layout Randomization"
39587 ++ depends on PAX
39588 ++
39589 ++config PAX_ASLR
39590 ++ bool "Address Space Layout Randomization"
39591 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
39592 ++ help
39593 ++ Many if not most exploit techniques rely on the knowledge of
39594 ++ certain addresses in the attacked program. The following options
39595 ++ will allow the kernel to apply a certain amount of randomization
39596 ++ to specific parts of the program thereby forcing an attacker to
39597 ++ guess them in most cases. Any failed guess will most likely crash
39598 ++ the attacked program which allows the kernel to detect such attempts
39599 ++ and react on them. PaX itself provides no reaction mechanisms,
39600 ++ instead it is strongly encouraged that you make use of Nergal's
39601 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
39602 ++ (http://www.grsecurity.net/) built-in crash detection features or
39603 ++ develop one yourself.
39604 ++
39605 ++ By saying Y here you can choose to randomize the following areas:
39606 ++ - top of the task's kernel stack
39607 ++ - top of the task's userland stack
39608 ++ - base address for mmap() requests that do not specify one
39609 ++ (this includes all libraries)
39610 ++ - base address of the main executable
39611 ++
39612 ++ It is strongly recommended to say Y here as address space layout
39613 ++ randomization has negligible impact on performance yet it provides
39614 ++ a very effective protection.
39615 ++
39616 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
39617 ++ this feature on a per file basis.
39618 ++
39619 ++config PAX_RANDKSTACK
39620 ++ bool "Randomize kernel stack base"
39621 ++ depends on PAX_ASLR && X86_TSC && X86_32
39622 ++ help
39623 ++ By saying Y here the kernel will randomize every task's kernel
39624 ++ stack on every system call. This will not only force an attacker
39625 ++ to guess it but also prevent him from making use of possible
39626 ++ leaked information about it.
39627 ++
39628 ++ Since the kernel stack is a rather scarce resource, randomization
39629 ++ may cause unexpected stack overflows, therefore you should very
39630 ++ carefully test your system. Note that once enabled in the kernel
39631 ++ configuration, this feature cannot be disabled on a per file basis.
39632 ++
39633 ++config PAX_RANDUSTACK
39634 ++ bool "Randomize user stack base"
39635 ++ depends on PAX_ASLR
39636 ++ help
39637 ++ By saying Y here the kernel will randomize every task's userland
39638 ++ stack. The randomization is done in two steps where the second
39639 ++ one may apply a big amount of shift to the top of the stack and
39640 ++ cause problems for programs that want to use lots of memory (more
39641 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
39642 ++ For this reason the second step can be controlled by 'chpax' or
39643 ++ 'paxctl' on a per file basis.
39644 ++
39645 ++config PAX_RANDMMAP
39646 ++ bool "Randomize mmap() base"
39647 ++ depends on PAX_ASLR
39648 ++ help
39649 ++ By saying Y here the kernel will use a randomized base address for
39650 ++ mmap() requests that do not specify one themselves. As a result
39651 ++ all dynamically loaded libraries will appear at random addresses
39652 ++ and therefore be harder to exploit by a technique where an attacker
39653 ++ attempts to execute library code for his purposes (e.g. spawn a
39654 ++ shell from an exploited program that is running at an elevated
39655 ++ privilege level).
39656 ++
39657 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
39658 ++ base address will be randomized as well, completing the full
39659 ++ randomization of the address space layout. Attacking such programs
39660 ++ becomes a guess game. You can find an example of doing this at
39661 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
39662 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
39663 ++
39664 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
39665 ++ feature on a per file basis.
39666 ++
39667 ++endmenu
39668 ++
39669 ++menu "Miscellaneous hardening features"
39670 ++
39671 ++config PAX_MEMORY_SANITIZE
39672 ++ bool "Sanitize all freed memory"
39673 ++ help
39674 ++ By saying Y here the kernel will erase memory pages as soon as they
39675 ++ are freed. This in turn reduces the lifetime of data stored in the
39676 ++ pages, making it less likely that sensitive information such as
39677 ++ passwords, cryptographic secrets, etc stay in memory for too long.
39678 ++
39679 ++ This is especially useful for programs whose runtime is short, long
39680 ++ lived processes and the kernel itself benefit from this as long as
39681 ++ they operate on whole memory pages and ensure timely freeing of pages
39682 ++ that may hold sensitive information.
39683 ++
39684 ++ The tradeoff is performance impact, on a single CPU system kernel
39685 ++ compilation sees a 3% slowdown, other systems and workloads may vary
39686 ++ and you are advised to test this feature on your expected workload
39687 ++ before deploying it.
39688 ++
39689 ++ Note that this feature does not protect data stored in live pages,
39690 ++ e.g., process memory swapped to disk may stay there for a long time.
39691 ++
39692 ++config PAX_MEMORY_UDEREF
39693 ++ bool "Prevent invalid userland pointer dereference"
39694 ++ depends on X86_32 && !COMPAT_VDSO && !UML_X86
39695 ++ help
39696 ++ By saying Y here the kernel will be prevented from dereferencing
39697 ++ userland pointers in contexts where the kernel expects only kernel
39698 ++ pointers. This is both a useful runtime debugging feature and a
39699 ++ security measure that prevents exploiting a class of kernel bugs.
39700 ++
39701 ++ The tradeoff is that some virtualization solutions may experience
39702 ++ a huge slowdown and therefore you should not enable this feature
39703 ++ for kernels meant to run in such environments. Whether a given VM
39704 ++ solution is affected or not is best determined by simply trying it
39705 ++ out, the performance impact will be obvious right on boot as this
39706 ++ mechanism engages from very early on. A good rule of thumb is that
39707 ++ VMs running on CPUs without hardware virtualization support (i.e.,
39708 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
39709 ++
39710 ++config PAX_REFCOUNT
39711 ++ bool "Prevent various kernel object reference counter overflows"
39712 ++ depends on X86
39713 ++ help
39714 ++ By saying Y here the kernel will detect and prevent overflowing
39715 ++ various (but not all) kinds of object reference counters. Such
39716 ++ overflows can normally occur due to bugs only and are often, if
39717 ++ not always, exploitable.
39718 ++
39719 ++ The tradeoff is that data structures protected by an oveflowed
39720 ++ refcount will never be freed and therefore will leak memory. Note
39721 ++ that this leak also happens even without this protection but in
39722 ++ that case the overflow can eventually trigger the freeing of the
39723 ++ data structure while it is still being used elsewhere, resulting
39724 ++ in the exploitable situation that this feature prevents.
39725 ++
39726 ++ Since this has a negligible performance impact, you should enable
39727 ++ this feature.
39728 ++endmenu
39729 ++
39730 ++endmenu
39731 ++
39732 + config KEYS
39733 + bool "Enable access key retention support"
39734 + help
39735 +diff -urNp linux-2.6.26.6/sound/core/oss/pcm_oss.c linux-2.6.26.6/sound/core/oss/pcm_oss.c
39736 +--- linux-2.6.26.6/sound/core/oss/pcm_oss.c 2008-10-08 23:24:05.000000000 -0400
39737 ++++ linux-2.6.26.6/sound/core/oss/pcm_oss.c 2008-10-11 21:54:20.000000000 -0400
39738 +@@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
39739 + }
39740 + }
39741 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
39742 +-#define snd_pcm_oss_proc_init(pcm)
39743 +-#define snd_pcm_oss_proc_done(pcm)
39744 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
39745 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
39746 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
39747 +
39748 + /*
39749 +diff -urNp linux-2.6.26.6/sound/core/seq/seq_lock.h linux-2.6.26.6/sound/core/seq/seq_lock.h
39750 +--- linux-2.6.26.6/sound/core/seq/seq_lock.h 2008-10-08 23:24:05.000000000 -0400
39751 ++++ linux-2.6.26.6/sound/core/seq/seq_lock.h 2008-10-11 21:54:20.000000000 -0400
39752 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
39753 + #else /* SMP || CONFIG_SND_DEBUG */
39754 +
39755 + typedef spinlock_t snd_use_lock_t; /* dummy */
39756 +-#define snd_use_lock_init(lockp) /**/
39757 +-#define snd_use_lock_use(lockp) /**/
39758 +-#define snd_use_lock_free(lockp) /**/
39759 +-#define snd_use_lock_sync(lockp) /**/
39760 ++#define snd_use_lock_init(lockp) do {} while (0)
39761 ++#define snd_use_lock_use(lockp) do {} while (0)
39762 ++#define snd_use_lock_free(lockp) do {} while (0)
39763 ++#define snd_use_lock_sync(lockp) do {} while (0)
39764 +
39765 + #endif /* SMP || CONFIG_SND_DEBUG */
39766 +
39767 +diff -urNp linux-2.6.26.6/sound/pci/ac97/ac97_patch.c linux-2.6.26.6/sound/pci/ac97/ac97_patch.c
39768 +--- linux-2.6.26.6/sound/pci/ac97/ac97_patch.c 2008-10-08 23:24:05.000000000 -0400
39769 ++++ linux-2.6.26.6/sound/pci/ac97/ac97_patch.c 2008-10-11 21:54:20.000000000 -0400
39770 +@@ -1497,7 +1497,7 @@ static const struct snd_ac97_res_table a
39771 + { AC97_VIDEO, 0x9f1f },
39772 + { AC97_AUX, 0x9f1f },
39773 + { AC97_PCM, 0x9f1f },
39774 +- { } /* terminator */
39775 ++ { 0, 0 } /* terminator */
39776 + };
39777 +
39778 + static int patch_ad1819(struct snd_ac97 * ac97)
39779 +@@ -3591,7 +3591,7 @@ static struct snd_ac97_res_table lm4550_
39780 + { AC97_AUX, 0x1f1f },
39781 + { AC97_PCM, 0x1f1f },
39782 + { AC97_REC_GAIN, 0x0f0f },
39783 +- { } /* terminator */
39784 ++ { 0, 0 } /* terminator */
39785 + };
39786 +
39787 + static int patch_lm4550(struct snd_ac97 *ac97)
39788 +diff -urNp linux-2.6.26.6/sound/pci/ens1370.c linux-2.6.26.6/sound/pci/ens1370.c
39789 +--- linux-2.6.26.6/sound/pci/ens1370.c 2008-10-08 23:24:05.000000000 -0400
39790 ++++ linux-2.6.26.6/sound/pci/ens1370.c 2008-10-11 21:54:20.000000000 -0400
39791 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
39792 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
39793 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
39794 + #endif
39795 +- { 0, }
39796 ++ { 0, 0, 0, 0, 0, 0, 0 }
39797 + };
39798 +
39799 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
39800 +diff -urNp linux-2.6.26.6/sound/pci/intel8x0.c linux-2.6.26.6/sound/pci/intel8x0.c
39801 +--- linux-2.6.26.6/sound/pci/intel8x0.c 2008-10-08 23:24:05.000000000 -0400
39802 ++++ linux-2.6.26.6/sound/pci/intel8x0.c 2008-10-11 21:54:20.000000000 -0400
39803 +@@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
39804 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
39805 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
39806 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
39807 +- { 0, }
39808 ++ { 0, 0, 0, 0, 0, 0, 0 }
39809 + };
39810 +
39811 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
39812 +@@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
39813 + .type = AC97_TUNE_HP_ONLY
39814 + },
39815 + #endif
39816 +- { } /* terminator */
39817 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
39818 + };
39819 +
39820 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
39821 +diff -urNp linux-2.6.26.6/sound/pci/intel8x0m.c linux-2.6.26.6/sound/pci/intel8x0m.c
39822 +--- linux-2.6.26.6/sound/pci/intel8x0m.c 2008-10-08 23:24:05.000000000 -0400
39823 ++++ linux-2.6.26.6/sound/pci/intel8x0m.c 2008-10-11 21:54:20.000000000 -0400
39824 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
39825 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
39826 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
39827 + #endif
39828 +- { 0, }
39829 ++ { 0, 0, 0, 0, 0, 0, 0 }
39830 + };
39831 +
39832 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
39833 +@@ -1257,7 +1257,7 @@ static struct shortname_table {
39834 + { 0x5455, "ALi M5455" },
39835 + { 0x746d, "AMD AMD8111" },
39836 + #endif
39837 +- { 0 },
39838 ++ { 0, NULL },
39839 + };
39840 +
39841 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
39842 +diff -urNp linux-2.6.26.6/virt/kvm/kvm_main.c linux-2.6.26.6/virt/kvm/kvm_main.c
39843 +--- linux-2.6.26.6/virt/kvm/kvm_main.c 2008-10-08 23:24:05.000000000 -0400
39844 ++++ linux-2.6.26.6/virt/kvm/kvm_main.c 2008-10-11 21:55:52.000000000 -0400
39845 +@@ -1182,7 +1182,6 @@ static int kvm_dev_ioctl_create_vm(void)
39846 + static long kvm_dev_ioctl(struct file *filp,
39847 + unsigned int ioctl, unsigned long arg)
39848 + {
39849 +- void __user *argp = (void __user *)arg;
39850 + long r = -EINVAL;
39851 +
39852 + switch (ioctl) {
39853 +@@ -1199,7 +1198,7 @@ static long kvm_dev_ioctl(struct file *f
39854 + r = kvm_dev_ioctl_create_vm();
39855 + break;
39856 + case KVM_CHECK_EXTENSION:
39857 +- r = kvm_dev_ioctl_check_extension((long)argp);
39858 ++ r = kvm_dev_ioctl_check_extension(arg);
39859 + break;
39860 + case KVM_GET_VCPU_MMAP_SIZE:
39861 + r = -EINVAL;
39862 +@@ -1231,6 +1230,9 @@ static struct miscdevice kvm_dev = {
39863 + KVM_MINOR,
39864 + "kvm",
39865 + &kvm_chardev_ops,
39866 ++ {NULL, NULL},
39867 ++ NULL,
39868 ++ NULL
39869 + };
39870 +
39871 + static void hardware_enable(void *junk)
39872
39873 Added: hardened/2.6/tags/2.6.26-10/4421_grsec-remove-localversion-grsec.patch
39874 ===================================================================
39875 --- hardened/2.6/tags/2.6.26-10/4421_grsec-remove-localversion-grsec.patch (rev 0)
39876 +++ hardened/2.6/tags/2.6.26-10/4421_grsec-remove-localversion-grsec.patch 2009-01-21 00:11:21 UTC (rev 1482)
39877 @@ -0,0 +1,9 @@
39878 +From: Kerin Millar <kerframil@×××××.com>
39879 +
39880 +Remove grsecurity's localversion-grsec file as it is inconsistent with
39881 +Gentoo's kernel practices and naming scheme.
39882 +
39883 +--- a/localversion-grsec 2008-02-24 14:26:59.000000000 +0000
39884 ++++ b/localversion-grsec 1970-01-01 01:00:00.000000000 +0100
39885 +@@ -1 +0,0 @@
39886 +--grsec
39887
39888 Added: hardened/2.6/tags/2.6.26-10/4422_grsec-mute-warnings.patch
39889 ===================================================================
39890 --- hardened/2.6/tags/2.6.26-10/4422_grsec-mute-warnings.patch (rev 0)
39891 +++ hardened/2.6/tags/2.6.26-10/4422_grsec-mute-warnings.patch 2009-01-21 00:11:21 UTC (rev 1482)
39892 @@ -0,0 +1,28 @@
39893 +From: Gordon Malm <gengor@g.o>
39894 +
39895 +Updated patch for kernel series 2.6.24.
39896 +
39897 +The credits/description from the original version of this patch remain accurate
39898 +and are included below.
39899 +
39900 +---
39901 +From: Alexander Gabert <gaberta@××××××××.de>
39902 +
39903 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
39904 +It removes the -W options added by the patch and restores the original
39905 +warning flags of vanilla kernel versions.
39906 +
39907 +Acked-by: Christian Heim <phreak@g.o>
39908 +---
39909 +
39910 +--- a/Makefile
39911 ++++ b/Makefile
39912 +@@ -214,7 +214,7 @@
39913 +
39914 + HOSTCC = gcc
39915 + HOSTCXX = g++
39916 +-HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
39917 ++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
39918 + HOSTCXXFLAGS = -O2
39919 +
39920 + # Decide whether to build built-in, modular, or both.
39921
39922 Added: hardened/2.6/tags/2.6.26-10/4425_grsec-pax-without-grsec.patch
39923 ===================================================================
39924 --- hardened/2.6/tags/2.6.26-10/4425_grsec-pax-without-grsec.patch (rev 0)
39925 +++ hardened/2.6/tags/2.6.26-10/4425_grsec-pax-without-grsec.patch 2009-01-21 00:11:21 UTC (rev 1482)
39926 @@ -0,0 +1,47 @@
39927 +From: Gordon Malm <gengor@g.o>
39928 +
39929 +Allow PaX options to be selected without first selecting CONFIG_GRKERNSEC.
39930 +
39931 +This patch has been updated to keep current with newer kernel versions.
39932 +The original version of this patch contained no credits/description.
39933 +
39934 +--- a/arch/x86/mm/fault.c
39935 ++++ b/arch/x86/mm/fault.c
39936 +@@ -422,10 +422,12 @@ static void show_fault_oops(struct pt_re
39937 + #else
39938 + if (init_mm.start_code <= address && address < init_mm.end_code)
39939 + #endif
39940 ++#ifdef CONFIG_GRKERNSEC
39941 + if (current->signal->curr_ip)
39942 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
39943 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
39944 + else
39945 ++#endif
39946 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
39947 + current->comm, task_pid_nr(current), current->uid, current->euid);
39948 + #endif
39949 +--- a/fs/exec.c
39950 ++++ b/fs/exec.c
39951 +@@ -1682,9 +1682,11 @@ void pax_report_fault(struct pt_regs *re
39952 + }
39953 + up_read(&mm->mmap_sem);
39954 + }
39955 ++#ifdef CONFIG_GRKERNSEC
39956 + if (tsk->signal->curr_ip)
39957 + 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);
39958 + else
39959 ++#endif
39960 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
39961 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
39962 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
39963 +--- a/security/Kconfig
39964 ++++ b/security/Kconfig
39965 +@@ -10,7 +10,7 @@ menu "PaX"
39966 +
39967 + config PAX
39968 + bool "Enable various PaX features"
39969 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
39970 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
39971 + help
39972 + This allows you to enable various PaX features. PaX adds
39973 + intrusion prevention mechanisms to the kernel that reduce
39974
39975 Added: hardened/2.6/tags/2.6.26-10/4430_grsec-kconfig-default-gids.patch
39976 ===================================================================
39977 --- hardened/2.6/tags/2.6.26-10/4430_grsec-kconfig-default-gids.patch (rev 0)
39978 +++ hardened/2.6/tags/2.6.26-10/4430_grsec-kconfig-default-gids.patch 2009-01-21 00:11:21 UTC (rev 1482)
39979 @@ -0,0 +1,76 @@
39980 +From: Kerin Millar <kerframil@×××××.com>
39981 +
39982 +grsecurity contains a number of options which allow certain protections
39983 +to be applied to or exempted from members of a given group. However, the
39984 +default GIDs specified in the upstream patch are entirely arbitrary and
39985 +there is no telling which (if any) groups the GIDs will correlate with
39986 +on an end-user's system. Because some users don't pay a great deal of
39987 +attention to the finer points of kernel configuration, it is probably
39988 +wise to specify some reasonable defaults so as to stop careless users
39989 +from shooting themselves in the foot.
39990 +
39991 +--- a/grsecurity/Kconfig
39992 ++++ b/grsecurity/Kconfig
39993 +@@ -352,7 +564,7 @@
39994 + config GRKERNSEC_PROC_GID
39995 + int "GID for special group"
39996 + depends on GRKERNSEC_PROC_USERGROUP
39997 +- default 1001
39998 ++ default 10
39999 +
40000 + config GRKERNSEC_PROC_ADD
40001 + bool "Additional restrictions"
40002 +@@ -547,7 +759,7 @@
40003 + config GRKERNSEC_AUDIT_GID
40004 + int "GID for auditing"
40005 + depends on GRKERNSEC_AUDIT_GROUP
40006 +- default 1007
40007 ++ default 100
40008 +
40009 + config GRKERNSEC_EXECLOG
40010 + bool "Exec logging"
40011 +@@ -700,7 +912,7 @@
40012 + config GRKERNSEC_TPE_GID
40013 + int "GID for untrusted users"
40014 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
40015 +- default 1005
40016 ++ default 100
40017 + help
40018 + If you have selected the "Invert GID option" above, setting this
40019 + GID determines what group TPE restrictions will be *disabled* for.
40020 +@@ -712,7 +924,7 @@
40021 + config GRKERNSEC_TPE_GID
40022 + int "GID for trusted users"
40023 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
40024 +- default 1005
40025 ++ default 10
40026 + help
40027 + If you have selected the "Invert GID option" above, setting this
40028 + GID determines what group TPE restrictions will be *disabled* for.
40029 +@@ -754,7 +966,7 @@
40030 + config GRKERNSEC_SOCKET_ALL_GID
40031 + int "GID to deny all sockets for"
40032 + depends on GRKERNSEC_SOCKET_ALL
40033 +- default 1004
40034 ++ default 65534
40035 + help
40036 + Here you can choose the GID to disable socket access for. Remember to
40037 + add the users you want socket access disabled for to the GID
40038 +@@ -775,7 +987,7 @@
40039 + config GRKERNSEC_SOCKET_CLIENT_GID
40040 + int "GID to deny client sockets for"
40041 + depends on GRKERNSEC_SOCKET_CLIENT
40042 +- default 1003
40043 ++ default 65534
40044 + help
40045 + Here you can choose the GID to disable client socket access for.
40046 + Remember to add the users you want client socket access disabled for to
40047 +@@ -793,7 +1005,7 @@
40048 + config GRKERNSEC_SOCKET_SERVER_GID
40049 + int "GID to deny server sockets for"
40050 + depends on GRKERNSEC_SOCKET_SERVER
40051 +- default 1002
40052 ++ default 65534
40053 + help
40054 + Here you can choose the GID to disable server socket access for.
40055 + Remember to add the users you want server socket access disabled for to
40056
40057 Added: hardened/2.6/tags/2.6.26-10/4435_grsec-kconfig-gentoo.patch
40058 ===================================================================
40059 --- hardened/2.6/tags/2.6.26-10/4435_grsec-kconfig-gentoo.patch (rev 0)
40060 +++ hardened/2.6/tags/2.6.26-10/4435_grsec-kconfig-gentoo.patch 2009-01-21 00:11:21 UTC (rev 1482)
40061 @@ -0,0 +1,243 @@
40062 +From: Gordon Malm <gengor@g.o>
40063 +From: Kerin Millar <kerframil@×××××.com>
40064 +
40065 +Add Hardened Gentoo [server/workstation] predefined grsecurity
40066 +levels. They're designed to provide a comparitively high level of
40067 +security while remaining generally suitable for as great a majority
40068 +of the userbase as possible (particularly new users).
40069 +
40070 +Make Hardened Gentoo [workstation] predefined grsecurity level the
40071 +default. The Hardened Gentoo [server] level is more restrictive
40072 +and conflicts with some software and thus would be less suitable.
40073 +
40074 +The original version of this patch was conceived and created by:
40075 +Ned Ludd <solar@g.o>
40076 +
40077 +--- a/grsecurity/Kconfig
40078 ++++ b/grsecurity/Kconfig
40079 +@@ -20,7 +20,7 @@ config GRKERNSEC
40080 + choice
40081 + prompt "Security Level"
40082 + depends on GRKERNSEC
40083 +- default GRKERNSEC_CUSTOM
40084 ++ default GRKERNSEC_HARDENED_WORKSTATION
40085 +
40086 + config GRKERNSEC_LOW
40087 + bool "Low"
40088 +@@ -183,6 +183,216 @@ config GRKERNSEC_HIGH
40089 + - Mount/unmount/remount logging
40090 + - Kernel symbol hiding
40091 + - Prevention of memory exhaustion-based exploits
40092 ++
40093 ++config GRKERNSEC_HARDENED_SERVER
40094 ++ bool "Hardened Gentoo [server]"
40095 ++ select GRKERNSEC_AUDIT_MOUNT
40096 ++ select GRKERNSEC_BRUTE
40097 ++ select GRKERNSEC_CHROOT
40098 ++ select GRKERNSEC_CHROOT_CAPS
40099 ++ select GRKERNSEC_CHROOT_CHDIR
40100 ++ select GRKERNSEC_CHROOT_CHMOD
40101 ++ select GRKERNSEC_CHROOT_DOUBLE
40102 ++ select GRKERNSEC_CHROOT_FCHDIR
40103 ++ select GRKERNSEC_CHROOT_FINDTASK
40104 ++ select GRKERNSEC_CHROOT_MKNOD
40105 ++ select GRKERNSEC_CHROOT_MOUNT
40106 ++ select GRKERNSEC_CHROOT_NICE
40107 ++ select GRKERNSEC_CHROOT_PIVOT
40108 ++ select GRKERNSEC_CHROOT_SHMAT
40109 ++ select GRKERNSEC_CHROOT_SYSCTL
40110 ++ select GRKERNSEC_CHROOT_UNIX
40111 ++ select GRKERNSEC_DMESG
40112 ++ select GRKERNSEC_EXECVE
40113 ++ select GRKERNSEC_FIFO
40114 ++ select GRKERNSEC_FORKFAIL
40115 ++ select GRKERNSEC_HIDESYM
40116 ++ select GRKERNSEC_IO if (X86)
40117 ++ select GRKERNSEC_KMEM
40118 ++ select GRKERNSEC_LINK
40119 ++ select GRKERNSEC_MODSTOP if (MODULES)
40120 ++ select GRKERNSEC_PROC
40121 ++ select GRKERNSEC_PROC_ADD
40122 ++ select GRKERNSEC_PROC_IPADDR
40123 ++ select GRKERNSEC_PROC_MEMMAP
40124 ++ select GRKERNSEC_PROC_USERGROUP
40125 ++ select GRKERNSEC_RANDNET
40126 ++ select GRKERNSEC_RESLOG
40127 ++ select GRKERNSEC_SIGNAL
40128 ++# select GRKERNSEC_SOCKET
40129 ++# select GRKERNSEC_SOCKET_SERVER
40130 ++ select GRKERNSEC_SYSCTL
40131 ++ select GRKERNSEC_SYSCTL_ON
40132 ++ select GRKERNSEC_TIME
40133 ++ select PAX
40134 ++ select PAX_ASLR
40135 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
40136 ++ select PAX_EI_PAX
40137 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
40138 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
40139 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
40140 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
40141 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
40142 ++ select PAX_MEMORY_SANITIZE
40143 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO && !UML_X86)
40144 ++ select PAX_MPROTECT if (!PPC64)
40145 ++ select PAX_HAVE_ACL_FLAGS
40146 ++ select PAX_NOELFRELOCS if (X86)
40147 ++ select PAX_NOEXEC
40148 ++ select PAX_PAGEEXEC
40149 ++ select PAX_PT_PAX_FLAGS
40150 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
40151 ++ select PAX_RANDMMAP
40152 ++ select PAX_RANDUSTACK
40153 ++ select PAX_REFCOUNT if (X86)
40154 ++ select PAX_SEGMEXEC if (X86_32)
40155 ++ select PAX_SYSCALL if (PPC32)
40156 ++ help
40157 ++ If you say Y here, a configuration will be used that is endorsed by
40158 ++ the Hardened Gentoo project. Therefore, many of the protections
40159 ++ made available by grsecurity and PaX will be enabled.
40160 ++
40161 ++ Hardened Gentoo's pre-defined security levels are designed to provide
40162 ++ a high level of security while minimizing incompatibilities with the
40163 ++ majority of available software. For further information, please
40164 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
40165 ++ well as the Hardened Gentoo Primer at
40166 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
40167 ++
40168 ++ This Hardened Gentoo [server] level is identical to the
40169 ++ Hardened Gentoo [workstation] level, but with the GRKERNSEC_IO,
40170 ++ PAX_KERNEXEC and PAX_NOELFRELOCS security features enabled.
40171 ++ Accordingly, this is the preferred security level if the system will
40172 ++ not be utilizing software incompatible with the aforementioned
40173 ++ grsecurity/PaX features.
40174 ++
40175 ++ You may wish to emerge paxctl, a utility which allows you to toggle
40176 ++ PaX features on problematic binaries on an individual basis. Note that
40177 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
40178 ++ Translated, this means that if you wish to toggle PaX features on
40179 ++ binaries provided by applications that are distributed only in binary
40180 ++ format (rather than being built locally from sources), you will need to
40181 ++ run paxctl -C on the binaries beforehand so as to inject the missing
40182 ++ headers.
40183 ++
40184 ++ When this level is selected, some options cannot be changed. However,
40185 ++ you may opt to fully customize the options that are selected by
40186 ++ choosing "Custom" in the Security Level menu. You may find it helpful
40187 ++ to inherit the options selected by the "Hardened Gentoo [server]"
40188 ++ security level as a starting point for further configuration. To
40189 ++ accomplish this, select this security level then exit the menuconfig
40190 ++ interface, saving changes when prompted. Then, run make menuconfig
40191 ++ again and select the "Custom" level.
40192 ++
40193 ++ Note that this security level probably should not be used if the
40194 ++ target system is a 32bit x86 virtualized guest. If you intend to run
40195 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
40196 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
40197 ++ impact on performance.
40198 ++
40199 ++config GRKERNSEC_HARDENED_WORKSTATION
40200 ++ bool "Hardened Gentoo [workstation]"
40201 ++ select GRKERNSEC_AUDIT_MOUNT
40202 ++ select GRKERNSEC_BRUTE
40203 ++ select GRKERNSEC_CHROOT
40204 ++ select GRKERNSEC_CHROOT_CAPS
40205 ++ select GRKERNSEC_CHROOT_CHDIR
40206 ++ select GRKERNSEC_CHROOT_CHMOD
40207 ++ select GRKERNSEC_CHROOT_DOUBLE
40208 ++ select GRKERNSEC_CHROOT_FCHDIR
40209 ++ select GRKERNSEC_CHROOT_FINDTASK
40210 ++ select GRKERNSEC_CHROOT_MKNOD
40211 ++ select GRKERNSEC_CHROOT_MOUNT
40212 ++ select GRKERNSEC_CHROOT_NICE
40213 ++ select GRKERNSEC_CHROOT_PIVOT
40214 ++ select GRKERNSEC_CHROOT_SHMAT
40215 ++ select GRKERNSEC_CHROOT_SYSCTL
40216 ++ select GRKERNSEC_CHROOT_UNIX
40217 ++ select GRKERNSEC_DMESG
40218 ++ select GRKERNSEC_EXECVE
40219 ++ select GRKERNSEC_FIFO
40220 ++ select GRKERNSEC_FORKFAIL
40221 ++ select GRKERNSEC_HIDESYM
40222 ++ select GRKERNSEC_KMEM
40223 ++ select GRKERNSEC_LINK
40224 ++ select GRKERNSEC_MODSTOP if (MODULES)
40225 ++ select GRKERNSEC_PROC
40226 ++ select GRKERNSEC_PROC_ADD
40227 ++ select GRKERNSEC_PROC_IPADDR
40228 ++ select GRKERNSEC_PROC_MEMMAP
40229 ++ select GRKERNSEC_PROC_USERGROUP
40230 ++ select GRKERNSEC_RANDNET
40231 ++ select GRKERNSEC_RESLOG
40232 ++ select GRKERNSEC_SIGNAL
40233 ++# select GRKERNSEC_SOCKET
40234 ++# select GRKERNSEC_SOCKET_SERVER
40235 ++ select GRKERNSEC_SYSCTL
40236 ++ select GRKERNSEC_SYSCTL_ON
40237 ++ select GRKERNSEC_TIME
40238 ++ select PAX
40239 ++ select PAX_ASLR
40240 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
40241 ++ select PAX_EI_PAX
40242 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
40243 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
40244 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
40245 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
40246 ++ select PAX_MEMORY_SANITIZE
40247 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO && !UML_X86)
40248 ++ select PAX_MPROTECT if (!PPC64)
40249 ++ select PAX_HAVE_ACL_FLAGS
40250 ++ select PAX_NOEXEC
40251 ++ select PAX_PAGEEXEC
40252 ++ select PAX_PT_PAX_FLAGS
40253 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
40254 ++ select PAX_RANDMMAP
40255 ++ select PAX_RANDUSTACK
40256 ++ select PAX_REFCOUNT if (X86)
40257 ++ select PAX_SEGMEXEC if (X86_32)
40258 ++ select PAX_SYSCALL if (PPC32)
40259 ++ help
40260 ++ If you say Y here, a configuration will be used that is endorsed by
40261 ++ the Hardened Gentoo project. Therefore, many of the protections
40262 ++ made available by grsecurity and PaX will be enabled.
40263 ++
40264 ++ Hardened Gentoo's pre-defined security levels are designed to provide
40265 ++ a high level of security while minimizing incompatibilities with the
40266 ++ majority of available software. For further information, please
40267 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
40268 ++ well as the Hardened Gentoo Primer at
40269 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
40270 ++
40271 ++ This Hardened Gentoo [workstation] level is designed for machines
40272 ++ which are intended to run software not compatible with the
40273 ++ GRKERNSEC_IO, PAX_KERNEXEC and PAX_NOELFRELOCS features of grsecurity.
40274 ++ Accordingly, this security level is suitable for use with the X server
40275 ++ "Xorg" and/or any system that will act as host OS to the virtualization
40276 ++ softwares vmware-server or virtualbox.
40277 ++
40278 ++ You may wish to emerge paxctl, a utility which allows you to toggle
40279 ++ PaX features on problematic binaries on an individual basis. Note that
40280 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
40281 ++ Translated, this means that if you wish to toggle PaX features on
40282 ++ binaries provided by applications that are distributed only in binary
40283 ++ format (rather than being built locally from sources), you will need to
40284 ++ run paxctl -C on the binaries beforehand so as to inject the missing
40285 ++ headers.
40286 ++
40287 ++ When this level is selected, some options cannot be changed. However,
40288 ++ you may opt to fully customize the options that are selected by
40289 ++ choosing "Custom" in the Security Level menu. You may find it helpful
40290 ++ to inherit the options selected by the "Hardened Gentoo [workstation]"
40291 ++ security level as a starting point for further configuration. To
40292 ++ accomplish this, select this security level then exit the menuconfig
40293 ++ interface, saving changes when prompted. Then, run make menuconfig
40294 ++ again and select the "Custom" level.
40295 ++
40296 ++ Note that this security level probably should not be used if the
40297 ++ target system is a 32bit x86 virtualized guest. If you intend to run
40298 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
40299 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
40300 ++ impact on performance.
40301 ++
40302 + config GRKERNSEC_CUSTOM
40303 + bool "Custom"
40304 + help
40305
40306 Added: hardened/2.6/tags/2.6.26-10/4440_selinux-avc_audit-log-curr_ip.patch
40307 ===================================================================
40308 --- hardened/2.6/tags/2.6.26-10/4440_selinux-avc_audit-log-curr_ip.patch (rev 0)
40309 +++ hardened/2.6/tags/2.6.26-10/4440_selinux-avc_audit-log-curr_ip.patch 2009-01-21 00:11:21 UTC (rev 1482)
40310 @@ -0,0 +1,65 @@
40311 +From: Gordon Malm <gengor@g.o>
40312 +
40313 +This is a reworked version of the original
40314 +*_selinux-avc_audit-log-curr_ip.patch carried in earlier releases of
40315 +hardened-sources.
40316 +
40317 +Dropping the patch, or simply fixing the #ifdef of the original patch
40318 +could break automated logging setups so this route was necessary.
40319 +
40320 +Suggestions for improving the help text are welcome.
40321 +
40322 +The original patch's description is still accurate and included below.
40323 +
40324 +---
40325 +Provides support for a new field ipaddr within the SELinux
40326 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
40327 +provided by grSecurity patch to be applied before.
40328 +
40329 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
40330 +---
40331 +
40332 +--- a/grsecurity/Kconfig
40333 ++++ b/grsecurity/Kconfig
40334 +@@ -1044,6 +1044,27 @@ endmenu
40335 + menu "Logging Options"
40336 + depends on GRKERNSEC
40337 +
40338 ++config GRKERNSEC_SELINUX_AVC_LOG_IPADDR
40339 ++ def_bool n
40340 ++ prompt "Add source IP address to SELinux AVC log messages"
40341 ++ depends on GRKERNSEC && SECURITY_SELINUX
40342 ++ help
40343 ++ If you say Y here, a new field "ipaddr=" will be added to many SELinux
40344 ++ AVC log messages. The value of this field in any given message
40345 ++ represents the source IP address of the remote machine/user that created
40346 ++ the offending process.
40347 ++
40348 ++ This information is sourced from task_struct->curr_ip provided by
40349 ++ grsecurity's GRKERNSEC top-level configuration option. One limitation
40350 ++ is that only IPv4 is supported.
40351 ++
40352 ++ In many instances SELinux AVC log messages already log a superior level
40353 ++ of information that also includes source port and destination ip/port.
40354 ++ Additionally, SELinux's AVC log code supports IPv6.
40355 ++
40356 ++ However, grsecurity's task_struct->curr_ip will sometimes (often?)
40357 ++ provide the offender's IP address where stock SELinux logging fails to.
40358 ++
40359 + config GRKERNSEC_FLOODTIME
40360 + int "Seconds in between log messages (minimum)"
40361 + default 10
40362 +--- a/security/selinux/avc.c
40363 ++++ b/security/selinux/avc.c
40364 +@@ -202,6 +202,11 @@ static void avc_dump_query(struct audit_
40365 + char *scontext;
40366 + u32 scontext_len;
40367 +
40368 ++#ifdef CONFIG_GRKERNSEC_SELINUX_AVC_LOG_IPADDR
40369 ++ if (current->signal->curr_ip)
40370 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
40371 ++#endif
40372 ++
40373 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
40374 + if (rc)
40375 + audit_log_format(ab, "ssid=%d", ssid);
40376
40377 Added: hardened/2.6/tags/2.6.26-10/4445_disable-compat_vdso.patch
40378 ===================================================================
40379 --- hardened/2.6/tags/2.6.26-10/4445_disable-compat_vdso.patch (rev 0)
40380 +++ hardened/2.6/tags/2.6.26-10/4445_disable-compat_vdso.patch 2009-01-21 00:11:21 UTC (rev 1482)
40381 @@ -0,0 +1,74 @@
40382 +From: Gordon Malm <gengor@g.o>
40383 +From: Kerin Millar <kerframil@×××××.com>
40384 +
40385 +COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It
40386 +conflicts with various parts of PaX, crashing the system if enabled
40387 +while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents
40388 +a number of important PaX options from appearing in the configuration
40389 +menu, including all PaX NOEXEC implementations. Unfortunately, the
40390 +reason for the disappearance of these PaX configuration options is
40391 +often far from obvious to inexperienced users.
40392 +
40393 +Therefore, we disable the COMPAT_VDSO menu entry entirely. However,
40394 +COMPAT_VDSO operation can still be enabled via bootparam and sysctl
40395 +interfaces. Consequently, we must also disable the ability to select
40396 +COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so
40397 +that selecting COMPAT_VDSO operation at boot/runtime has no effect if
40398 +conflicting PaX options are enabled, leaving VDSO_ENABLED operation
40399 +intact.
40400 +
40401 +Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138
40402 +
40403 +--- a/arch/x86/Kconfig
40404 ++++ b/arch/x86/Kconfig
40405 +@@ -1215,16 +1215,7 @@ config HOTPLUG_CPU
40406 +
40407 + config COMPAT_VDSO
40408 + def_bool n
40409 +- prompt "Compat VDSO support"
40410 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
40411 +- help
40412 +- Map the 32-bit VDSO to the predictable old-style address too.
40413 +- ---help---
40414 +- Say N here if you are running a sufficiently recent glibc
40415 +- version (2.3.3 or later), to remove the high-mapped
40416 +- VDSO mapping and to exclusively use the randomized VDSO.
40417 +-
40418 +- If unsure, say Y.
40419 +
40420 + endmenu
40421 +
40422 +--- a/arch/x86/vdso/vdso32-setup.c
40423 ++++ b/arch/x86/vdso/vdso32-setup.c
40424 +@@ -333,17 +333,21 @@ int arch_setup_additional_pages(struct l
40425 +
40426 + map_compat_vdso(compat);
40427 +
40428 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
40429 + if (compat)
40430 + addr = VDSO_HIGH_BASE;
40431 + else {
40432 ++#endif
40433 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
40434 + if (IS_ERR_VALUE(addr)) {
40435 + ret = addr;
40436 + goto up_fail;
40437 + }
40438 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
40439 + }
40440 +
40441 + if (compat_uses_vma || !compat) {
40442 ++#endif
40443 + /*
40444 + * MAYWRITE to allow gdb to COW and set breakpoints
40445 + *
40446 +@@ -361,7 +365,9 @@ int arch_setup_additional_pages(struct l
40447 +
40448 + if (ret)
40449 + goto up_fail;
40450 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
40451 + }
40452 ++#endif
40453 +
40454 + current->mm->context.vdso = addr;
40455 + current_thread_info()->sysenter_return =
40456
40457 Added: hardened/2.6/tags/2.6.26-10/4450_pax-2.6.26.7-test32-to-test33.patch
40458 ===================================================================
40459 --- hardened/2.6/tags/2.6.26-10/4450_pax-2.6.26.7-test32-to-test33.patch (rev 0)
40460 +++ hardened/2.6/tags/2.6.26-10/4450_pax-2.6.26.7-test32-to-test33.patch 2009-01-21 00:11:21 UTC (rev 1482)
40461 @@ -0,0 +1,92 @@
40462 +From: Gordon Malm <gengor@g.o>
40463 +
40464 +PaX: Add changes from pax-2.6.26.7-test33 which are not
40465 +integrated into main grsecurity-2.6.26.X patch.
40466 +
40467 +--- a/arch/mips/kernel/binfmt_elfn32.c
40468 ++++ b/arch/mips/kernel/binfmt_elfn32.c
40469 +@@ -51,10 +51,10 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
40470 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
40471 +
40472 + #ifdef CONFIG_PAX_ASLR
40473 +-#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40474 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40475 +
40476 +-#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40477 +-#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40478 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40479 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40480 + #endif
40481 +
40482 + #include <asm/processor.h>
40483 +--- a/arch/mips/kernel/binfmt_elfo32.c
40484 ++++ b/arch/mips/kernel/binfmt_elfo32.c
40485 +@@ -53,10 +53,10 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
40486 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
40487 +
40488 + #ifdef CONFIG_PAX_ASLR
40489 +-#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40490 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40491 +
40492 +-#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40493 +-#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40494 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40495 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40496 + #endif
40497 +
40498 + #include <asm/processor.h>
40499 +--- a/arch/mips/kernel/process.c
40500 ++++ b/arch/mips/kernel/process.c
40501 +@@ -464,15 +464,3 @@ unsigned long get_wchan(struct task_stru
40502 + out:
40503 + return pc;
40504 + }
40505 +-
40506 +-/*
40507 +- * Don't forget that the stack pointer must be aligned on a 8 bytes
40508 +- * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
40509 +- */
40510 +-unsigned long arch_align_stack(unsigned long sp)
40511 +-{
40512 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
40513 +- sp -= get_random_int() & ~PAGE_MASK;
40514 +-
40515 +- return sp & ALMASK;
40516 +-}
40517 +--- a/include/asm-mips/elf.h
40518 ++++ b/include/asm-mips/elf.h
40519 +@@ -369,10 +369,10 @@ extern int dump_task_fpu(struct task_str
40520 + #endif
40521 +
40522 + #ifdef CONFIG_PAX_ASLR
40523 +-#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40524 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
40525 +
40526 +-#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40527 +-#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40528 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40529 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
40530 + #endif
40531 +
40532 + #endif /* _ASM_ELF_H */
40533 +--- a/include/asm-mips/system.h
40534 ++++ b/include/asm-mips/system.h
40535 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
40536 + */
40537 + #define __ARCH_WANT_UNLOCKED_CTXSW
40538 +
40539 +-#define arch_align_stack(x) (x)
40540 ++#define arch_align_stack(x) ((x) & ALMASK)
40541 +
40542 + #endif /* _ASM_SYSTEM_H */
40543 +--- a/include/asm-x86/system.h
40544 ++++ b/include/asm-x86/system.h
40545 +@@ -325,7 +325,7 @@ void enable_hlt(void);
40546 + extern int es7000_plat;
40547 + void cpu_idle_wait(void);
40548 +
40549 +-#define arch_align_stack(x) (x)
40550 ++#define arch_align_stack(x) ((x) & ~0xfUL)
40551 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
40552 +
40553 + void default_idle(void);
40554
40555 Added: hardened/2.6/tags/2.6.26-10/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch
40556 ===================================================================
40557 --- hardened/2.6/tags/2.6.26-10/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch (rev 0)
40558 +++ hardened/2.6/tags/2.6.26-10/4455_grsec-make-PAX_REFCOUNT-conditional-on-x86.patch 2009-01-21 00:11:21 UTC (rev 1482)
40559 @@ -0,0 +1,32 @@
40560 +From: Gordon Malm <gengor@g.o>
40561 +
40562 +Make selection of PAX_REFCOUNT depend on X86.
40563 +PAX_REFCOUNT is an X86-only feature.
40564 +
40565 +Fixes bug #246763.
40566 +
40567 +Thanks to Tom Lloyd for reporting.
40568 +
40569 +This patch is present in upstream grsecurity patches as of
40570 +grsecurity-2.1.12-2.6.27.7-200811201849.patch.
40571 +
40572 +--- a/grsecurity/Kconfig
40573 ++++ b/grsecurity/Kconfig
40574 +@@ -77,7 +77,7 @@ config GRKERNSEC_MEDIUM
40575 + select PAX_RANDUSTACK
40576 + select PAX_ASLR
40577 + select PAX_RANDMMAP
40578 +- select PAX_REFCOUNT
40579 ++ select PAX_REFCOUNT if (X86)
40580 +
40581 + help
40582 + If you say Y here, several features in addition to those included
40583 +@@ -155,7 +155,7 @@ config GRKERNSEC_HIGH
40584 + select PAX_EMUTRAMP if (PARISC)
40585 + select PAX_EMUSIGRT if (PARISC)
40586 + select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
40587 +- select PAX_REFCOUNT
40588 ++ select PAX_REFCOUNT if (X86)
40589 + help
40590 + If you say Y here, many of the features of grsecurity will be
40591 + enabled, which will protect you against many kinds of attacks
40592
40593 Added: hardened/2.6/tags/2.6.26-10/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
40594 ===================================================================
40595 --- hardened/2.6/tags/2.6.26-10/4460_pax-fix-mmap-BUG_ON-task-size-check.patch (rev 0)
40596 +++ hardened/2.6/tags/2.6.26-10/4460_pax-fix-mmap-BUG_ON-task-size-check.patch 2009-01-21 00:11:21 UTC (rev 1482)
40597 @@ -0,0 +1,22 @@
40598 +From: Gordon Malm <gengor@g.o>
40599 +
40600 +Fix incorrect vma task size check under SEGMEXEC.
40601 +
40602 +Fixes bug #246607.
40603 +
40604 +Thanks to Hugo Mildenberger for reporting and PaX Team for the fix.
40605 +
40606 +This patch is present in upstream grsecurity patches as of
40607 +pax-linux-2.6.27.7-test22.patch.
40608 +
40609 +--- a/mm/mmap.c
40610 ++++ b/mm/mmap.c
40611 +@@ -1719,7 +1719,7 @@ struct vm_area_struct *pax_find_mirror_v
40612 + BUG_ON(vma->vm_mirror);
40613 + return NULL;
40614 + }
40615 +- BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
40616 ++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
40617 + vma_m = vma->vm_mirror;
40618 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
40619 + BUG_ON(vma->vm_file != vma_m->vm_file);