Gentoo Archives: gentoo-commits

From: "Gordon Malm (gengor)" <gengor@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1478 - in hardened/2.6/tags: . 2.6.25-13
Date: Tue, 20 Jan 2009 21:29:42
Message-Id: E1LPO8Z-0004l5-98@stork.gentoo.org
1 Author: gengor
2 Date: 2009-01-20 21:27:53 +0000 (Tue, 20 Jan 2009)
3 New Revision: 1478
4
5 Added:
6 hardened/2.6/tags/2.6.25-13/
7 hardened/2.6/tags/2.6.25-13/0000_README
8 hardened/2.6/tags/2.6.25-13/1017_linux-2.6.25.18.patch
9 hardened/2.6/tags/2.6.25-13/1018_linux-2.6.25.19.patch
10 hardened/2.6/tags/2.6.25-13/1019_linux-2.6.25.20.patch
11 hardened/2.6/tags/2.6.25-13/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
12 hardened/2.6/tags/2.6.25-13/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
13 hardened/2.6/tags/2.6.25-13/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
14 hardened/2.6/tags/2.6.25-13/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
15 hardened/2.6/tags/2.6.25-13/1405_i-oat-fix-async_tx.callback-checking.patch
16 hardened/2.6/tags/2.6.25-13/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
17 hardened/2.6/tags/2.6.25-13/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
18 hardened/2.6/tags/2.6.25-13/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
19 hardened/2.6/tags/2.6.25-13/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
20 hardened/2.6/tags/2.6.25-13/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
21 hardened/2.6/tags/2.6.25-13/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch
22 hardened/2.6/tags/2.6.25-13/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
23 hardened/2.6/tags/2.6.25-13/1413_block-fix-nr_phys_segments-miscalculation-bug.patch
24 hardened/2.6/tags/2.6.25-13/1414_dm-raid1-flush-workqueue-before-destruction.patch
25 hardened/2.6/tags/2.6.25-13/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch
26 hardened/2.6/tags/2.6.25-13/1416_touch_mnt_namespace-when-the-mount-flags-change.patch
27 hardened/2.6/tags/2.6.25-13/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch
28 hardened/2.6/tags/2.6.25-13/1418_usb-ehci-fix-handling-of-dead-controllers.patch
29 hardened/2.6/tags/2.6.25-13/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
30 hardened/2.6/tags/2.6.25-13/1420_usb-ehci-fix-divide-by-zero-bug.patch
31 hardened/2.6/tags/2.6.25-13/1421_usb-fix-ps3-usb-shutdown-problems.patch
32 hardened/2.6/tags/2.6.25-13/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
33 hardened/2.6/tags/2.6.25-13/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch
34 hardened/2.6/tags/2.6.25-13/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
35 hardened/2.6/tags/2.6.25-13/1425_enforce-a-minimum-sg_io-timeout.patch
36 hardened/2.6/tags/2.6.25-13/1503_hfsplus-check-read_mapping_page-return-value.patch
37 hardened/2.6/tags/2.6.25-13/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch
38 hardened/2.6/tags/2.6.25-13/1505_hfs-fix-namelength-memory-corruption.patch
39 hardened/2.6/tags/2.6.25-13/1506_inotify-fix-watch-removal-or-umount-races.patch
40 hardened/2.6/tags/2.6.25-13/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
41 hardened/2.6/tags/2.6.25-13/1800_sched-disable-hrtick.patch
42 hardened/2.6/tags/2.6.25-13/4420_grsec-2.1.12-2.6.25.16-200808201644.patch
43 hardened/2.6/tags/2.6.25-13/4421_grsec-remove-localversion-grsec.patch
44 hardened/2.6/tags/2.6.25-13/4422_grsec-mute-warnings.patch
45 hardened/2.6/tags/2.6.25-13/4425_grsec-pax-without-grsec.patch
46 hardened/2.6/tags/2.6.25-13/4430_grsec-kconfig-default-gids.patch
47 hardened/2.6/tags/2.6.25-13/4435_grsec-kconfig-gentoo.patch
48 hardened/2.6/tags/2.6.25-13/4440_selinux-avc_audit-log-curr_ip.patch
49 hardened/2.6/tags/2.6.25-13/4445_disable-compat_vdso.patch
50 hardened/2.6/tags/2.6.25-13/4450_pax-remove-read_implies_exec-for-pax-binaries.patch
51 hardened/2.6/tags/2.6.25-13/4455_pax-fix-uvesafb-compile-and-misc.patch
52 hardened/2.6/tags/2.6.25-13/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
53 hardened/2.6/tags/2.6.25-13/4465_pax-fix-false-RLIMIT_STACK-warnings.patch
54 Log:
55 Tag 2.6.25-13 hardened-extras patchset
56
57 Added: hardened/2.6/tags/2.6.25-13/0000_README
58 ===================================================================
59 --- hardened/2.6/tags/2.6.25-13/0000_README (rev 0)
60 +++ hardened/2.6/tags/2.6.25-13/0000_README 2009-01-20 21:27:53 UTC (rev 1478)
61 @@ -0,0 +1,117 @@
62 +README
63 +-----------------------------------------------------------------------------
64 +
65 +Individual Patch Descriptions:
66 +-----------------------------------------------------------------------------
67 +Patch: 1017_linux-2.6.25.18.patch
68 +From: http://www.kernel.org
69 +Desc: Linux 2.6.25.18
70 +
71 +Patch: 1018_linux-2.6.25.19.patch
72 +From: http://www.kernel.org
73 +Desc: Linux 2.6.25.19
74 +
75 +Patch: 1019_linux-2.6.25.20.patch
76 +From: http://www.kernel.org
77 +Desc: Linux 2.6.25.20
78 +
79 +Patch: 1401* -> 1412*
80 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
81 + a=commit;h=ff413e9814b3914ddf3d4634e9a6cc1c6b21e787
82 +Desc: Backported subset of 2.6.27.6 -stable release patches
83 +
84 +Patch: 1413* -> 1422*
85 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
86 + a=commit;h=526550b7f86d9d395ee1b27ed804e6ffc3feb17c
87 +Desc: Backported subset of 2.6.27.7 -stable release patches
88 +
89 +Patch: 1423*
90 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
91 + a=commit;h=1db886b63e735c3439e5c2f6813c5207c2206895
92 +Desc: Backported subset of 2.6.27.8 -stable release patches
93 +
94 +Patch: 1424* -> 1425*
95 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
96 + a=commit;h=2ef6627be7502193f7c42f694a651fa710507089
97 +Desc: Backported subset of 2.6.27.9 -stable release patches
98 +
99 +Patch: 1503_hfsplus-check-read_mapping_page-return-value.patch
100 +From: Eric Sesterhenn <snakebyte@×××.de>
101 +Desc: hfsplus: check return value of read_mapping_page()
102 +
103 +Patch: 1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch
104 +From: Eric Sesterhenn <snakebyte@×××.de>
105 +Desc: hfsplus: fix buffer overflow when mounting corrupted image
106 +
107 +Patch: 1505_hfs-fix-namelength-memory-corruption.patch
108 +From: Eric Sesterhenn <snakebyte@×××.de>
109 +Desc: hfsplug: Fix stack corruption due to corrupted hfs filesystem
110 +
111 +Patch: 1506_inotify-fix-watch-removal-or-umount-races.patch
112 +From: Al Viro <viro@×××××××××××××××.uk>
113 +Desc: Fix inotify watch removal/umount races (bug #248754)
114 +
115 +Patch: 1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
116 +From: Wei Yongjun <yjwei@××××××××××.com>
117 +Desc: Avoid memory overflow while FWD-TSN chunk received with bad stream ID
118 + (bug #254907)
119 +
120 +Patch: 1800_sched-disable-hrtick.patch
121 +From: Kerin Millar <kerframil@×××××.com>
122 +Desc: Disable high-resolution scheduler ticks (bug #247453)
123 +
124 +Patch: 4420_grsec-2.1.12-2.6.25.16-200808201644.patch
125 +From: http://www.grsecurity.net
126 +Desc: hardened-sources base patch from upstream grsecurity
127 +Note: Ported to 2.6.25.16, adding PaX -test27 through -test30, fixed
128 + missing check in arch/x86/kernel/ioport.c -> do_iopl()
129 +
130 +Patch: 4421_grsec-remove-localversion-grsec.patch
131 +From: Kerin Millar <kerframil@×××××.com>
132 +Desc: Removes grsecurity's localversion-grsec file
133 +
134 +Patch: 4422_grsec-mute-warnings.patch
135 +From: Alexander Gabert <gaberta@××××××××.de>
136 + Gordon Malm <gengor@g.o>
137 +Desc: Removes verbose compile warning settings from grsecurity, restores
138 + mainline Linux kernel behavior
139 +
140 +Patch: 4425_grsec-pax-without-grsec.patch
141 +From: Gordon Malm <gengor@g.o>
142 +Desc: Allows PaX features to be selected without enabling GRKERNSEC
143 +
144 +Patch: 4430_grsec-kconfig-default-gids.patch
145 +From: Kerin Millar <kerframil@×××××.com>
146 +Desc: Sets sane(r) default GIDs on various grsecurity group-dependent
147 + features
148 +
149 +Patch: 4435_grsec-kconfig-gentoo.patch
150 +From: Gordon Malm <gengor@g.o>
151 + Kerin Millar <kerframil@×××××.com>
152 +Desc: Adds Hardened Gentoo [server/workstation] security levels, sets
153 + Hardened Gentoo [workstation] as default
154 +
155 +Patch: 4440_selinux-avc_audit-log-curr_ip.patch
156 +From: Gordon Malm <gengor@g.o>
157 +Desc: Configurable option to add src IP address to SELinux log messages
158 +
159 +Patch: 4445_disable-compat_vdso.patch
160 +From: Gordon Malm <gengor@g.o>
161 + Kerin Millar <kerframil@×××××.com>
162 +Desc: Disables VDSO_COMPAT operation completely
163 +
164 +Patch: 4450_pax-remove-read_implies_exec-for-pax-binaries.patch
165 +From: Gordon Malm <gengor@g.o>
166 +Desc: Remove READ_IMPLIES_EXEC personality for PaX controlled binaries
167 +
168 +Patch: 4455_pax-fix-uvesafb-compile-and-misc.patch
169 +From: Gordon Malm <gengor@g.o>
170 +Desc: Fixes compilation and miscellaneous other problems in uvesafb
171 +
172 +Patch: 4460_pax-fix-mmap-BUG_ON-task-size-check.patch
173 +From: Gordon Malm <gengor@g.o>
174 +Desc: Fix incorrect vma task size check under SEGMEXEC
175 +
176 +Patch: 4465_pax-fix-false-RLIMIT_STACK-warnings.patch
177 +From: Gordon Malm <gengor@g.o>
178 +Desc: Fix false-positive RLIMIT_STACK warnings
179
180 Added: hardened/2.6/tags/2.6.25-13/1017_linux-2.6.25.18.patch
181 ===================================================================
182 --- hardened/2.6/tags/2.6.25-13/1017_linux-2.6.25.18.patch (rev 0)
183 +++ hardened/2.6/tags/2.6.25-13/1017_linux-2.6.25.18.patch 2009-01-20 21:27:53 UTC (rev 1478)
184 @@ -0,0 +1,1023 @@
185 +diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
186 +index 36652ea..bec6496 100644
187 +--- a/arch/x86/kernel/hpet.c
188 ++++ b/arch/x86/kernel/hpet.c
189 +@@ -222,8 +222,8 @@ static void hpet_legacy_clockevent_register(void)
190 + /* Calculate the min / max delta */
191 + hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
192 + &hpet_clockevent);
193 +- hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
194 +- &hpet_clockevent);
195 ++ /* 5 usec minimum reprogramming delta. */
196 ++ hpet_clockevent.min_delta_ns = 5000;
197 +
198 + /*
199 + * Start hpet with the boot cpu mask and make it
200 +@@ -282,15 +282,22 @@ static void hpet_legacy_set_mode(enum clock_event_mode mode,
201 + }
202 +
203 + static int hpet_legacy_next_event(unsigned long delta,
204 +- struct clock_event_device *evt)
205 ++ struct clock_event_device *evt)
206 + {
207 +- unsigned long cnt;
208 ++ u32 cnt;
209 +
210 + cnt = hpet_readl(HPET_COUNTER);
211 +- cnt += delta;
212 ++ cnt += (u32) delta;
213 + hpet_writel(cnt, HPET_T0_CMP);
214 +
215 +- return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
216 ++ /*
217 ++ * We need to read back the CMP register to make sure that
218 ++ * what we wrote hit the chip before we compare it to the
219 ++ * counter.
220 ++ */
221 ++ WARN_ON((u32)hpet_readl(HPET_T0_CMP) != cnt);
222 ++
223 ++ return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
224 + }
225 +
226 + /*
227 +diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
228 +index 5921e5f..84ec3cd 100644
229 +--- a/arch/x86/kernel/io_delay.c
230 ++++ b/arch/x86/kernel/io_delay.c
231 +@@ -92,6 +92,14 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
232 + DMI_MATCH(DMI_BOARD_NAME, "30BF")
233 + }
234 + },
235 ++ {
236 ++ .callback = dmi_io_delay_0xed_port,
237 ++ .ident = "Presario F700",
238 ++ .matches = {
239 ++ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
240 ++ DMI_MATCH(DMI_BOARD_NAME, "30D3")
241 ++ }
242 ++ },
243 + { }
244 + };
245 +
246 +diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
247 +index 12affe1..72f9826 100644
248 +--- a/arch/x86/kernel/vmi_32.c
249 ++++ b/arch/x86/kernel/vmi_32.c
250 +@@ -234,7 +234,7 @@ static void vmi_write_ldt_entry(struct desc_struct *dt, int entry,
251 + const void *desc)
252 + {
253 + u32 *ldt_entry = (u32 *)desc;
254 +- vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
255 ++ vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
256 + }
257 +
258 + static void vmi_load_sp0(struct tss_struct *tss,
259 +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
260 +index 7222a18..a9b8796 100644
261 +--- a/drivers/acpi/ec.c
262 ++++ b/drivers/acpi/ec.c
263 +@@ -228,6 +228,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
264 + if (acpi_ec_check_status(ec, event))
265 + goto end;
266 + }
267 ++ if (acpi_ec_check_status(ec,event))
268 ++ return 0;
269 + }
270 + pr_err(PREFIX "acpi_ec_wait timeout,"
271 + " status = %d, expect_event = %d\n",
272 +diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
273 +index 42fb635..87b9a17 100644
274 +--- a/drivers/acpi/processor_perflib.c
275 ++++ b/drivers/acpi/processor_perflib.c
276 +@@ -70,7 +70,7 @@ static DEFINE_MUTEX(performance_mutex);
277 + * 0 -> cpufreq low level drivers initialized -> consider _PPC values
278 + * 1 -> ignore _PPC totally -> forced by user through boot param
279 + */
280 +-static unsigned int ignore_ppc = -1;
281 ++static int ignore_ppc = -1;
282 + module_param(ignore_ppc, uint, 0644);
283 + MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
284 + "limited by BIOS, this should help");
285 +diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
286 +index 393e679..342255b 100644
287 +--- a/drivers/i2c/i2c-dev.c
288 ++++ b/drivers/i2c/i2c-dev.c
289 +@@ -574,8 +574,10 @@ static int __init i2c_dev_init(void)
290 + goto out;
291 +
292 + i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
293 +- if (IS_ERR(i2c_dev_class))
294 ++ if (IS_ERR(i2c_dev_class)) {
295 ++ res = PTR_ERR(i2c_dev_class);
296 + goto out_unreg_chrdev;
297 ++ }
298 +
299 + res = i2c_add_driver(&i2cdev_driver);
300 + if (res)
301 +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
302 +index 91ded3e..3318642 100644
303 +--- a/drivers/mmc/card/block.c
304 ++++ b/drivers/mmc/card/block.c
305 +@@ -103,8 +103,10 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
306 + check_disk_change(inode->i_bdev);
307 + ret = 0;
308 +
309 +- if ((filp->f_mode & FMODE_WRITE) && md->read_only)
310 ++ if ((filp->f_mode & FMODE_WRITE) && md->read_only) {
311 ++ mmc_blk_put(md);
312 + ret = -EROFS;
313 ++ }
314 + }
315 +
316 + return ret;
317 +diff --git a/drivers/net/niu.c b/drivers/net/niu.c
318 +index d11ba61..5fd6a65 100644
319 +--- a/drivers/net/niu.c
320 ++++ b/drivers/net/niu.c
321 +@@ -5230,6 +5230,56 @@ static void niu_netif_start(struct niu *np)
322 + niu_enable_interrupts(np, 1);
323 + }
324 +
325 ++static void niu_reset_buffers(struct niu *np)
326 ++{
327 ++ int i, j, k, err;
328 ++
329 ++ if (np->rx_rings) {
330 ++ for (i = 0; i < np->num_rx_rings; i++) {
331 ++ struct rx_ring_info *rp = &np->rx_rings[i];
332 ++
333 ++ for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
334 ++ struct page *page;
335 ++
336 ++ page = rp->rxhash[j];
337 ++ while (page) {
338 ++ struct page *next =
339 ++ (struct page *) page->mapping;
340 ++ u64 base = page->index;
341 ++ base = base >> RBR_DESCR_ADDR_SHIFT;
342 ++ rp->rbr[k++] = cpu_to_le32(base);
343 ++ page = next;
344 ++ }
345 ++ }
346 ++ for (; k < MAX_RBR_RING_SIZE; k++) {
347 ++ err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
348 ++ if (unlikely(err))
349 ++ break;
350 ++ }
351 ++
352 ++ rp->rbr_index = rp->rbr_table_size - 1;
353 ++ rp->rcr_index = 0;
354 ++ rp->rbr_pending = 0;
355 ++ rp->rbr_refill_pending = 0;
356 ++ }
357 ++ }
358 ++ if (np->tx_rings) {
359 ++ for (i = 0; i < np->num_tx_rings; i++) {
360 ++ struct tx_ring_info *rp = &np->tx_rings[i];
361 ++
362 ++ for (j = 0; j < MAX_TX_RING_SIZE; j++) {
363 ++ if (rp->tx_buffs[j].skb)
364 ++ (void) release_tx_packet(np, rp, j);
365 ++ }
366 ++
367 ++ rp->pending = MAX_TX_RING_SIZE;
368 ++ rp->prod = 0;
369 ++ rp->cons = 0;
370 ++ rp->wrap_bit = 0;
371 ++ }
372 ++ }
373 ++}
374 ++
375 + static void niu_reset_task(struct work_struct *work)
376 + {
377 + struct niu *np = container_of(work, struct niu, reset_task);
378 +@@ -5252,6 +5302,12 @@ static void niu_reset_task(struct work_struct *work)
379 +
380 + niu_stop_hw(np);
381 +
382 ++ spin_unlock_irqrestore(&np->lock, flags);
383 ++
384 ++ niu_reset_buffers(np);
385 ++
386 ++ spin_lock_irqsave(&np->lock, flags);
387 ++
388 + err = niu_init_hw(np);
389 + if (!err) {
390 + np->timer.expires = jiffies + HZ;
391 +diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
392 +index 147e26a..1dcc79f 100644
393 +--- a/drivers/spi/pxa2xx_spi.c
394 ++++ b/drivers/spi/pxa2xx_spi.c
395 +@@ -48,9 +48,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
396 +
397 + #define MAX_BUSES 3
398 +
399 +-#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
400 +-#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
401 +-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
402 ++#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
403 ++#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
404 ++#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0)
405 ++#define MAX_DMA_LEN 8191
406 +
407 + /*
408 + * for testing SSCR1 changes that require SSP restart, basically
409 +@@ -142,7 +143,6 @@ struct driver_data {
410 + size_t tx_map_len;
411 + u8 n_bytes;
412 + u32 dma_width;
413 +- int cs_change;
414 + int (*write)(struct driver_data *drv_data);
415 + int (*read)(struct driver_data *drv_data);
416 + irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
417 +@@ -404,8 +404,45 @@ static void giveback(struct driver_data *drv_data)
418 + struct spi_transfer,
419 + transfer_list);
420 +
421 ++ /* Delay if requested before any change in chip select */
422 ++ if (last_transfer->delay_usecs)
423 ++ udelay(last_transfer->delay_usecs);
424 ++
425 ++ /* Drop chip select UNLESS cs_change is true or we are returning
426 ++ * a message with an error, or next message is for another chip
427 ++ */
428 + if (!last_transfer->cs_change)
429 + drv_data->cs_control(PXA2XX_CS_DEASSERT);
430 ++ else {
431 ++ struct spi_message *next_msg;
432 ++
433 ++ /* Holding of cs was hinted, but we need to make sure
434 ++ * the next message is for the same chip. Don't waste
435 ++ * time with the following tests unless this was hinted.
436 ++ *
437 ++ * We cannot postpone this until pump_messages, because
438 ++ * after calling msg->complete (below) the driver that
439 ++ * sent the current message could be unloaded, which
440 ++ * could invalidate the cs_control() callback...
441 ++ */
442 ++
443 ++ /* get a pointer to the next message, if any */
444 ++ spin_lock_irqsave(&drv_data->lock, flags);
445 ++ if (list_empty(&drv_data->queue))
446 ++ next_msg = NULL;
447 ++ else
448 ++ next_msg = list_entry(drv_data->queue.next,
449 ++ struct spi_message, queue);
450 ++ spin_unlock_irqrestore(&drv_data->lock, flags);
451 ++
452 ++ /* see if the next and current messages point
453 ++ * to the same chip
454 ++ */
455 ++ if (next_msg && next_msg->spi != msg->spi)
456 ++ next_msg = NULL;
457 ++ if (!next_msg || msg->state == ERROR_STATE)
458 ++ drv_data->cs_control(PXA2XX_CS_DEASSERT);
459 ++ }
460 +
461 + msg->state = NULL;
462 + if (msg->complete)
463 +@@ -488,10 +525,9 @@ static void dma_transfer_complete(struct driver_data *drv_data)
464 + msg->actual_length += drv_data->len -
465 + (drv_data->rx_end - drv_data->rx);
466 +
467 +- /* Release chip select if requested, transfer delays are
468 +- * handled in pump_transfers */
469 +- if (drv_data->cs_change)
470 +- drv_data->cs_control(PXA2XX_CS_DEASSERT);
471 ++ /* Transfer delays and chip select release are
472 ++ * handled in pump_transfers or giveback
473 ++ */
474 +
475 + /* Move to next transfer */
476 + msg->state = next_transfer(drv_data);
477 +@@ -600,10 +636,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
478 + drv_data->cur_msg->actual_length += drv_data->len -
479 + (drv_data->rx_end - drv_data->rx);
480 +
481 +- /* Release chip select if requested, transfer delays are
482 +- * handled in pump_transfers */
483 +- if (drv_data->cs_change)
484 +- drv_data->cs_control(PXA2XX_CS_DEASSERT);
485 ++ /* Transfer delays and chip select release are
486 ++ * handled in pump_transfers or giveback
487 ++ */
488 +
489 + /* Move to next transfer */
490 + drv_data->cur_msg->state = next_transfer(drv_data);
491 +@@ -837,23 +872,40 @@ static void pump_transfers(unsigned long data)
492 + return;
493 + }
494 +
495 +- /* Delay if requested at end of transfer*/
496 ++ /* Delay if requested at end of transfer before CS change */
497 + if (message->state == RUNNING_STATE) {
498 + previous = list_entry(transfer->transfer_list.prev,
499 + struct spi_transfer,
500 + transfer_list);
501 + if (previous->delay_usecs)
502 + udelay(previous->delay_usecs);
503 ++
504 ++ /* Drop chip select only if cs_change is requested */
505 ++ if (previous->cs_change)
506 ++ drv_data->cs_control(PXA2XX_CS_DEASSERT);
507 + }
508 +
509 +- /* Check transfer length */
510 +- if (transfer->len > 8191)
511 +- {
512 +- dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
513 +- "length greater than 8191\n");
514 +- message->status = -EINVAL;
515 +- giveback(drv_data);
516 +- return;
517 ++ /* Check for transfers that need multiple DMA segments */
518 ++ if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
519 ++
520 ++ /* reject already-mapped transfers; PIO won't always work */
521 ++ if (message->is_dma_mapped
522 ++ || transfer->rx_dma || transfer->tx_dma) {
523 ++ dev_err(&drv_data->pdev->dev,
524 ++ "pump_transfers: mapped transfer length "
525 ++ "of %u is greater than %d\n",
526 ++ transfer->len, MAX_DMA_LEN);
527 ++ message->status = -EINVAL;
528 ++ giveback(drv_data);
529 ++ return;
530 ++ }
531 ++
532 ++ /* warn ... we force this to PIO mode */
533 ++ if (printk_ratelimit())
534 ++ dev_warn(&message->spi->dev, "pump_transfers: "
535 ++ "DMA disabled for transfer length %ld "
536 ++ "greater than %d\n",
537 ++ (long)drv_data->len, MAX_DMA_LEN);
538 + }
539 +
540 + /* Setup the transfer state based on the type of transfer */
541 +@@ -875,7 +927,6 @@ static void pump_transfers(unsigned long data)
542 + drv_data->len = transfer->len & DCMD_LENGTH;
543 + drv_data->write = drv_data->tx ? chip->write : null_writer;
544 + drv_data->read = drv_data->rx ? chip->read : null_reader;
545 +- drv_data->cs_change = transfer->cs_change;
546 +
547 + /* Change speed and bit per word on a per transfer */
548 + cr0 = chip->cr0;
549 +@@ -922,7 +973,7 @@ static void pump_transfers(unsigned long data)
550 + &dma_thresh))
551 + if (printk_ratelimit())
552 + dev_warn(&message->spi->dev,
553 +- "pump_transfer: "
554 ++ "pump_transfers: "
555 + "DMA burst size reduced to "
556 + "match bits_per_word\n");
557 + }
558 +@@ -936,8 +987,23 @@ static void pump_transfers(unsigned long data)
559 +
560 + message->state = RUNNING_STATE;
561 +
562 +- /* Try to map dma buffer and do a dma transfer if successful */
563 +- if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
564 ++ /* Try to map dma buffer and do a dma transfer if successful, but
565 ++ * only if the length is non-zero and less than MAX_DMA_LEN.
566 ++ *
567 ++ * Zero-length non-descriptor DMA is illegal on PXA2xx; force use
568 ++ * of PIO instead. Care is needed above because the transfer may
569 ++ * have have been passed with buffers that are already dma mapped.
570 ++ * A zero-length transfer in PIO mode will not try to write/read
571 ++ * to/from the buffers
572 ++ *
573 ++ * REVISIT large transfers are exactly where we most want to be
574 ++ * using DMA. If this happens much, split those transfers into
575 ++ * multiple DMA segments rather than forcing PIO.
576 ++ */
577 ++ drv_data->dma_mapped = 0;
578 ++ if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
579 ++ drv_data->dma_mapped = map_dma_buffers(drv_data);
580 ++ if (drv_data->dma_mapped) {
581 +
582 + /* Ensure we have the correct interrupt handler */
583 + drv_data->transfer_handler = dma_transfer;
584 +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
585 +index 27533b3..ed7b123 100644
586 +--- a/drivers/usb/core/hcd.c
587 ++++ b/drivers/usb/core/hcd.c
588 +@@ -1877,7 +1877,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
589 + * with IRQF_SHARED. As usb_hcd_irq() will always disable
590 + * interrupts we can remove it here.
591 + */
592 +- irqflags &= ~IRQF_DISABLED;
593 ++ if (irqflags & IRQF_SHARED)
594 ++ irqflags &= ~IRQF_DISABLED;
595 +
596 + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
597 + hcd->driver->description, hcd->self.busnum);
598 +diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
599 +index dd1bed8..85286fb 100644
600 +--- a/include/asm-generic/rtc.h
601 ++++ b/include/asm-generic/rtc.h
602 +@@ -17,6 +17,7 @@
603 + #include <linux/mc146818rtc.h>
604 + #include <linux/rtc.h>
605 + #include <linux/bcd.h>
606 ++#include <linux/delay.h>
607 +
608 + #define RTC_PIE 0x40 /* periodic interrupt enable */
609 + #define RTC_AIE 0x20 /* alarm interrupt enable */
610 +@@ -45,7 +46,6 @@ static inline unsigned char rtc_is_updating(void)
611 +
612 + static inline unsigned int get_rtc_time(struct rtc_time *time)
613 + {
614 +- unsigned long uip_watchdog = jiffies;
615 + unsigned char ctrl;
616 + unsigned long flags;
617 +
618 +@@ -55,19 +55,15 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
619 +
620 + /*
621 + * read RTC once any update in progress is done. The update
622 +- * can take just over 2ms. We wait 10 to 20ms. There is no need to
623 ++ * can take just over 2ms. We wait 20ms. There is no need to
624 + * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
625 + * If you need to know *exactly* when a second has started, enable
626 + * periodic update complete interrupts, (via ioctl) and then
627 + * immediately read /dev/rtc which will block until you get the IRQ.
628 + * Once the read clears, read the RTC time (again via ioctl). Easy.
629 + */
630 +-
631 +- if (rtc_is_updating() != 0)
632 +- while (jiffies - uip_watchdog < 2*HZ/100) {
633 +- barrier();
634 +- cpu_relax();
635 +- }
636 ++ if (rtc_is_updating())
637 ++ mdelay(20);
638 +
639 + /*
640 + * Only the values that we read from the RTC are set. We leave
641 +diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
642 +index c33b0dc..ed3a5d4 100644
643 +--- a/include/linux/clockchips.h
644 ++++ b/include/linux/clockchips.h
645 +@@ -127,6 +127,8 @@ extern int clockevents_register_notifier(struct notifier_block *nb);
646 + extern int clockevents_program_event(struct clock_event_device *dev,
647 + ktime_t expires, ktime_t now);
648 +
649 ++extern void clockevents_handle_noop(struct clock_event_device *dev);
650 ++
651 + #ifdef CONFIG_GENERIC_CLOCKEVENTS
652 + extern void clockevents_notify(unsigned long reason, void *arg);
653 + #else
654 +diff --git a/include/net/netlink.h b/include/net/netlink.h
655 +index 112dcdf..5383fdf 100644
656 +--- a/include/net/netlink.h
657 ++++ b/include/net/netlink.h
658 +@@ -704,7 +704,7 @@ static inline int nla_len(const struct nlattr *nla)
659 + */
660 + static inline int nla_ok(const struct nlattr *nla, int remaining)
661 + {
662 +- return remaining >= sizeof(*nla) &&
663 ++ return remaining >= (int) sizeof(*nla) &&
664 + nla->nla_len >= sizeof(*nla) &&
665 + nla->nla_len <= remaining;
666 + }
667 +diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
668 +index 3d1e3e1..1876b52 100644
669 +--- a/kernel/time/clockevents.c
670 ++++ b/kernel/time/clockevents.c
671 +@@ -177,7 +177,7 @@ void clockevents_register_device(struct clock_event_device *dev)
672 + /*
673 + * Noop handler when we shut down an event device
674 + */
675 +-static void clockevents_handle_noop(struct clock_event_device *dev)
676 ++void clockevents_handle_noop(struct clock_event_device *dev)
677 + {
678 + }
679 +
680 +@@ -199,7 +199,6 @@ void clockevents_exchange_device(struct clock_event_device *old,
681 + * released list and do a notify add later.
682 + */
683 + if (old) {
684 +- old->event_handler = clockevents_handle_noop;
685 + clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED);
686 + list_del(&old->list);
687 + list_add(&old->list, &clockevents_released);
688 +diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
689 +index 5fd9b94..a1dac40 100644
690 +--- a/kernel/time/ntp.c
691 ++++ b/kernel/time/ntp.c
692 +@@ -205,7 +205,7 @@ static void sync_cmos_clock(unsigned long dummy)
693 + if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
694 + fail = update_persistent_clock(now);
695 +
696 +- next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
697 ++ next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
698 + if (next.tv_nsec <= 0)
699 + next.tv_nsec += NSEC_PER_SEC;
700 +
701 +diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
702 +index e1bd50c..0edd345 100644
703 +--- a/kernel/time/tick-broadcast.c
704 ++++ b/kernel/time/tick-broadcast.c
705 +@@ -174,6 +174,8 @@ static void tick_do_periodic_broadcast(void)
706 + */
707 + static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
708 + {
709 ++ ktime_t next;
710 ++
711 + tick_do_periodic_broadcast();
712 +
713 + /*
714 +@@ -184,10 +186,13 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
715 +
716 + /*
717 + * Setup the next period for devices, which do not have
718 +- * periodic mode:
719 ++ * periodic mode. We read dev->next_event first and add to it
720 ++ * when the event alrady expired. clockevents_program_event()
721 ++ * sets dev->next_event only when the event is really
722 ++ * programmed to the device.
723 + */
724 +- for (;;) {
725 +- ktime_t next = ktime_add(dev->next_event, tick_period);
726 ++ for (next = dev->next_event; ;) {
727 ++ next = ktime_add(next, tick_period);
728 +
729 + if (!clockevents_program_event(dev, next, ktime_get()))
730 + return;
731 +@@ -204,7 +209,7 @@ static void tick_do_broadcast_on_off(void *why)
732 + struct clock_event_device *bc, *dev;
733 + struct tick_device *td;
734 + unsigned long flags, *reason = why;
735 +- int cpu;
736 ++ int cpu, bc_stopped;
737 +
738 + spin_lock_irqsave(&tick_broadcast_lock, flags);
739 +
740 +@@ -222,6 +227,8 @@ static void tick_do_broadcast_on_off(void *why)
741 + if (!tick_device_is_functional(dev))
742 + goto out;
743 +
744 ++ bc_stopped = cpus_empty(tick_broadcast_mask);
745 ++
746 + switch (*reason) {
747 + case CLOCK_EVT_NOTIFY_BROADCAST_ON:
748 + case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
749 +@@ -243,9 +250,10 @@ static void tick_do_broadcast_on_off(void *why)
750 + break;
751 + }
752 +
753 +- if (cpus_empty(tick_broadcast_mask))
754 +- clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
755 +- else {
756 ++ if (cpus_empty(tick_broadcast_mask)) {
757 ++ if (!bc_stopped)
758 ++ clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
759 ++ } else if (bc_stopped) {
760 + if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
761 + tick_broadcast_start_periodic(bc);
762 + else
763 +@@ -362,16 +370,8 @@ cpumask_t *tick_get_broadcast_oneshot_mask(void)
764 + static int tick_broadcast_set_event(ktime_t expires, int force)
765 + {
766 + struct clock_event_device *bc = tick_broadcast_device.evtdev;
767 +- ktime_t now = ktime_get();
768 +- int res;
769 +-
770 +- for(;;) {
771 +- res = clockevents_program_event(bc, expires, now);
772 +- if (!res || !force)
773 +- return res;
774 +- now = ktime_get();
775 +- expires = ktime_add(now, ktime_set(0, bc->min_delta_ns));
776 +- }
777 ++
778 ++ return tick_dev_program_event(bc, expires, force);
779 + }
780 +
781 + int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
782 +@@ -490,14 +490,52 @@ static void tick_broadcast_clear_oneshot(int cpu)
783 + cpu_clear(cpu, tick_broadcast_oneshot_mask);
784 + }
785 +
786 ++static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires)
787 ++{
788 ++ struct tick_device *td;
789 ++ int cpu;
790 ++
791 ++ for_each_cpu_mask(cpu, *mask) {
792 ++ td = &per_cpu(tick_cpu_device, cpu);
793 ++ if (td->evtdev)
794 ++ td->evtdev->next_event = expires;
795 ++ }
796 ++}
797 ++
798 + /**
799 + * tick_broadcast_setup_oneshot - setup the broadcast device
800 + */
801 + void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
802 + {
803 +- bc->event_handler = tick_handle_oneshot_broadcast;
804 +- clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
805 +- bc->next_event.tv64 = KTIME_MAX;
806 ++ /* Set it up only once ! */
807 ++ if (bc->event_handler != tick_handle_oneshot_broadcast) {
808 ++ int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;
809 ++ int cpu = smp_processor_id();
810 ++ cpumask_t mask;
811 ++
812 ++ bc->event_handler = tick_handle_oneshot_broadcast;
813 ++ clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
814 ++
815 ++ /* Take the do_timer update */
816 ++ tick_do_timer_cpu = cpu;
817 ++
818 ++ /*
819 ++ * We must be careful here. There might be other CPUs
820 ++ * waiting for periodic broadcast. We need to set the
821 ++ * oneshot_mask bits for those and program the
822 ++ * broadcast device to fire.
823 ++ */
824 ++ mask = tick_broadcast_mask;
825 ++ cpu_clear(cpu, mask);
826 ++ cpus_or(tick_broadcast_oneshot_mask,
827 ++ tick_broadcast_oneshot_mask, mask);
828 ++
829 ++ if (was_periodic && !cpus_empty(mask)) {
830 ++ tick_broadcast_init_next_event(&mask, tick_next_period);
831 ++ tick_broadcast_set_event(tick_next_period, 1);
832 ++ } else
833 ++ bc->next_event.tv64 = KTIME_MAX;
834 ++ }
835 + }
836 +
837 + /*
838 +diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
839 +index 1bea399..d106d61 100644
840 +--- a/kernel/time/tick-common.c
841 ++++ b/kernel/time/tick-common.c
842 +@@ -159,6 +159,7 @@ static void tick_setup_device(struct tick_device *td,
843 + } else {
844 + handler = td->evtdev->event_handler;
845 + next_event = td->evtdev->next_event;
846 ++ td->evtdev->event_handler = clockevents_handle_noop;
847 + }
848 +
849 + td->evtdev = newdev;
850 +diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
851 +index f13f2b7..0ffc291 100644
852 +--- a/kernel/time/tick-internal.h
853 ++++ b/kernel/time/tick-internal.h
854 +@@ -17,6 +17,8 @@ extern void tick_handle_periodic(struct clock_event_device *dev);
855 + extern void tick_setup_oneshot(struct clock_event_device *newdev,
856 + void (*handler)(struct clock_event_device *),
857 + ktime_t nextevt);
858 ++extern int tick_dev_program_event(struct clock_event_device *dev,
859 ++ ktime_t expires, int force);
860 + extern int tick_program_event(ktime_t expires, int force);
861 + extern void tick_oneshot_notify(void);
862 + extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
863 +diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
864 +index 0258d31..0737da0 100644
865 +--- a/kernel/time/tick-oneshot.c
866 ++++ b/kernel/time/tick-oneshot.c
867 +@@ -23,24 +23,56 @@
868 + #include "tick-internal.h"
869 +
870 + /**
871 +- * tick_program_event
872 ++ * tick_program_event internal worker function
873 + */
874 +-int tick_program_event(ktime_t expires, int force)
875 ++int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
876 ++ int force)
877 + {
878 +- struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
879 + ktime_t now = ktime_get();
880 ++ int i;
881 +
882 +- while (1) {
883 ++ for (i = 0;;) {
884 + int ret = clockevents_program_event(dev, expires, now);
885 +
886 + if (!ret || !force)
887 + return ret;
888 ++
889 ++ /*
890 ++ * We tried 2 times to program the device with the given
891 ++ * min_delta_ns. If that's not working then we double it
892 ++ * and emit a warning.
893 ++ */
894 ++ if (++i > 2) {
895 ++ /* Increase the min. delta and try again */
896 ++ if (!dev->min_delta_ns)
897 ++ dev->min_delta_ns = 5000;
898 ++ else
899 ++ dev->min_delta_ns += dev->min_delta_ns >> 1;
900 ++
901 ++ printk(KERN_WARNING
902 ++ "CE: %s increasing min_delta_ns to %lu nsec\n",
903 ++ dev->name ? dev->name : "?",
904 ++ dev->min_delta_ns << 1);
905 ++
906 ++ i = 0;
907 ++ }
908 ++
909 + now = ktime_get();
910 +- expires = ktime_add(now, ktime_set(0, dev->min_delta_ns));
911 ++ expires = ktime_add_ns(now, dev->min_delta_ns);
912 + }
913 + }
914 +
915 + /**
916 ++ * tick_program_event
917 ++ */
918 ++int tick_program_event(ktime_t expires, int force)
919 ++{
920 ++ struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
921 ++
922 ++ return tick_dev_program_event(dev, expires, force);
923 ++}
924 ++
925 ++/**
926 + * tick_resume_onshot - resume oneshot mode
927 + */
928 + void tick_resume_oneshot(void)
929 +@@ -61,7 +93,7 @@ void tick_setup_oneshot(struct clock_event_device *newdev,
930 + {
931 + newdev->event_handler = handler;
932 + clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT);
933 +- clockevents_program_event(newdev, next_event, ktime_get());
934 ++ tick_dev_program_event(newdev, next_event, 1);
935 + }
936 +
937 + /**
938 +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
939 +index 9703c87..b924502 100644
940 +--- a/net/ipv4/udp.c
941 ++++ b/net/ipv4/udp.c
942 +@@ -956,6 +956,27 @@ int udp_disconnect(struct sock *sk, int flags)
943 + return 0;
944 + }
945 +
946 ++static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
947 ++{
948 ++ int is_udplite = IS_UDPLITE(sk);
949 ++ int rc;
950 ++
951 ++ if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
952 ++ /* Note that an ENOMEM error is charged twice */
953 ++ if (rc == -ENOMEM)
954 ++ UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS,
955 ++ is_udplite);
956 ++ goto drop;
957 ++ }
958 ++
959 ++ return 0;
960 ++
961 ++drop:
962 ++ UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
963 ++ kfree_skb(skb);
964 ++ return -1;
965 ++}
966 ++
967 + /* returns:
968 + * -1: error
969 + * 0: success
970 +@@ -1046,14 +1067,16 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
971 + goto drop;
972 + }
973 +
974 +- if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
975 +- /* Note that an ENOMEM error is charged twice */
976 +- if (rc == -ENOMEM)
977 +- UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite);
978 +- goto drop;
979 +- }
980 ++ rc = 0;
981 +
982 +- return 0;
983 ++ bh_lock_sock(sk);
984 ++ if (!sock_owned_by_user(sk))
985 ++ rc = __udp_queue_rcv_skb(sk, skb);
986 ++ else
987 ++ sk_add_backlog(sk, skb);
988 ++ bh_unlock_sock(sk);
989 ++
990 ++ return rc;
991 +
992 + drop:
993 + UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
994 +@@ -1091,15 +1114,7 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
995 + skb1 = skb_clone(skb, GFP_ATOMIC);
996 +
997 + if (skb1) {
998 +- int ret = 0;
999 +-
1000 +- bh_lock_sock_nested(sk);
1001 +- if (!sock_owned_by_user(sk))
1002 +- ret = udp_queue_rcv_skb(sk, skb1);
1003 +- else
1004 +- sk_add_backlog(sk, skb1);
1005 +- bh_unlock_sock(sk);
1006 +-
1007 ++ int ret = udp_queue_rcv_skb(sk, skb1);
1008 + if (ret > 0)
1009 + /* we should probably re-process instead
1010 + * of dropping packets here. */
1011 +@@ -1192,13 +1207,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1012 + uh->dest, inet_iif(skb), udptable);
1013 +
1014 + if (sk != NULL) {
1015 +- int ret = 0;
1016 +- bh_lock_sock_nested(sk);
1017 +- if (!sock_owned_by_user(sk))
1018 +- ret = udp_queue_rcv_skb(sk, skb);
1019 +- else
1020 +- sk_add_backlog(sk, skb);
1021 +- bh_unlock_sock(sk);
1022 ++ int ret = udp_queue_rcv_skb(sk, skb);
1023 + sock_put(sk);
1024 +
1025 + /* a return value > 0 means to resubmit the input, but
1026 +@@ -1493,7 +1502,7 @@ struct proto udp_prot = {
1027 + .sendmsg = udp_sendmsg,
1028 + .recvmsg = udp_recvmsg,
1029 + .sendpage = udp_sendpage,
1030 +- .backlog_rcv = udp_queue_rcv_skb,
1031 ++ .backlog_rcv = __udp_queue_rcv_skb,
1032 + .hash = udp_lib_hash,
1033 + .unhash = udp_lib_unhash,
1034 + .get_port = udp_v4_get_port,
1035 +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
1036 +index fb1c192..d650e10 100644
1037 +--- a/net/ipv6/ip6_output.c
1038 ++++ b/net/ipv6/ip6_output.c
1039 +@@ -930,39 +930,39 @@ static int ip6_dst_lookup_tail(struct sock *sk,
1040 + }
1041 +
1042 + #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1043 +- /*
1044 +- * Here if the dst entry we've looked up
1045 +- * has a neighbour entry that is in the INCOMPLETE
1046 +- * state and the src address from the flow is
1047 +- * marked as OPTIMISTIC, we release the found
1048 +- * dst entry and replace it instead with the
1049 +- * dst entry of the nexthop router
1050 +- */
1051 +- if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
1052 +- struct inet6_ifaddr *ifp;
1053 +- struct flowi fl_gw;
1054 +- int redirect;
1055 +-
1056 +- ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src,
1057 +- (*dst)->dev, 1);
1058 +-
1059 +- redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
1060 +- if (ifp)
1061 +- in6_ifa_put(ifp);
1062 +-
1063 +- if (redirect) {
1064 +- /*
1065 +- * We need to get the dst entry for the
1066 +- * default router instead
1067 +- */
1068 +- dst_release(*dst);
1069 +- memcpy(&fl_gw, fl, sizeof(struct flowi));
1070 +- memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
1071 +- *dst = ip6_route_output(sk, &fl_gw);
1072 +- if ((err = (*dst)->error))
1073 +- goto out_err_release;
1074 +- }
1075 ++ /*
1076 ++ * Here if the dst entry we've looked up
1077 ++ * has a neighbour entry that is in the INCOMPLETE
1078 ++ * state and the src address from the flow is
1079 ++ * marked as OPTIMISTIC, we release the found
1080 ++ * dst entry and replace it instead with the
1081 ++ * dst entry of the nexthop router
1082 ++ */
1083 ++ if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
1084 ++ struct inet6_ifaddr *ifp;
1085 ++ struct flowi fl_gw;
1086 ++ int redirect;
1087 ++
1088 ++ ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src,
1089 ++ (*dst)->dev, 1);
1090 ++
1091 ++ redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
1092 ++ if (ifp)
1093 ++ in6_ifa_put(ifp);
1094 ++
1095 ++ if (redirect) {
1096 ++ /*
1097 ++ * We need to get the dst entry for the
1098 ++ * default router instead
1099 ++ */
1100 ++ dst_release(*dst);
1101 ++ memcpy(&fl_gw, fl, sizeof(struct flowi));
1102 ++ memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
1103 ++ *dst = ip6_route_output(sk, &fl_gw);
1104 ++ if ((err = (*dst)->error))
1105 ++ goto out_err_release;
1106 + }
1107 ++ }
1108 + #endif
1109 +
1110 + return 0;
1111 +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
1112 +index 53739de..4e36c57 100644
1113 +--- a/net/ipv6/udp.c
1114 ++++ b/net/ipv6/udp.c
1115 +@@ -373,7 +373,7 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
1116 + uh->source, saddr, dif))) {
1117 + struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
1118 + if (buff) {
1119 +- bh_lock_sock_nested(sk2);
1120 ++ bh_lock_sock(sk2);
1121 + if (!sock_owned_by_user(sk2))
1122 + udpv6_queue_rcv_skb(sk2, buff);
1123 + else
1124 +@@ -381,7 +381,7 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
1125 + bh_unlock_sock(sk2);
1126 + }
1127 + }
1128 +- bh_lock_sock_nested(sk);
1129 ++ bh_lock_sock(sk);
1130 + if (!sock_owned_by_user(sk))
1131 + udpv6_queue_rcv_skb(sk, skb);
1132 + else
1133 +@@ -499,7 +499,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1134 +
1135 + /* deliver */
1136 +
1137 +- bh_lock_sock_nested(sk);
1138 ++ bh_lock_sock(sk);
1139 + if (!sock_owned_by_user(sk))
1140 + udpv6_queue_rcv_skb(sk, skb);
1141 + else
1142 +diff --git a/net/sctp/associola.c b/net/sctp/associola.c
1143 +index d29f792..1eefac2 100644
1144 +--- a/net/sctp/associola.c
1145 ++++ b/net/sctp/associola.c
1146 +@@ -588,11 +588,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
1147 + /* Check to see if this is a duplicate. */
1148 + peer = sctp_assoc_lookup_paddr(asoc, addr);
1149 + if (peer) {
1150 ++ /* An UNKNOWN state is only set on transports added by
1151 ++ * user in sctp_connectx() call. Such transports should be
1152 ++ * considered CONFIRMED per RFC 4960, Section 5.4.
1153 ++ */
1154 + if (peer->state == SCTP_UNKNOWN) {
1155 +- if (peer_state == SCTP_ACTIVE)
1156 +- peer->state = SCTP_ACTIVE;
1157 +- if (peer_state == SCTP_UNCONFIRMED)
1158 +- peer->state = SCTP_UNCONFIRMED;
1159 ++ peer->state = SCTP_ACTIVE;
1160 + }
1161 + return peer;
1162 + }
1163 +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
1164 +index 36ebb39..d024fd0 100644
1165 +--- a/net/sctp/sm_make_chunk.c
1166 ++++ b/net/sctp/sm_make_chunk.c
1167 +@@ -1886,11 +1886,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
1168 + /* if the peer reports AUTH, assume that he
1169 + * supports AUTH.
1170 + */
1171 +- asoc->peer.auth_capable = 1;
1172 ++ if (sctp_auth_enable)
1173 ++ asoc->peer.auth_capable = 1;
1174 + break;
1175 + case SCTP_CID_ASCONF:
1176 + case SCTP_CID_ASCONF_ACK:
1177 +- asoc->peer.asconf_capable = 1;
1178 ++ if (sctp_addip_enable)
1179 ++ asoc->peer.asconf_capable = 1;
1180 + break;
1181 + default:
1182 + break;
1183 +@@ -2319,12 +2321,10 @@ clean_up:
1184 + /* Release the transport structures. */
1185 + list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
1186 + transport = list_entry(pos, struct sctp_transport, transports);
1187 +- list_del_init(pos);
1188 +- sctp_transport_free(transport);
1189 ++ if (transport->state != SCTP_ACTIVE)
1190 ++ sctp_assoc_rm_peer(asoc, transport);
1191 + }
1192 +
1193 +- asoc->peer.transport_count = 0;
1194 +-
1195 + nomem:
1196 + return 0;
1197 + }
1198 +@@ -2454,6 +2454,9 @@ static int sctp_process_param(struct sctp_association *asoc,
1199 + break;
1200 +
1201 + case SCTP_PARAM_SET_PRIMARY:
1202 ++ if (!sctp_addip_enable)
1203 ++ goto fall_through;
1204 ++
1205 + addr_param = param.v + sizeof(sctp_addip_param_t);
1206 +
1207 + af = sctp_get_af_specific(param_type2af(param.p->type));
1208
1209 Added: hardened/2.6/tags/2.6.25-13/1018_linux-2.6.25.19.patch
1210 ===================================================================
1211 --- hardened/2.6/tags/2.6.25-13/1018_linux-2.6.25.19.patch (rev 0)
1212 +++ hardened/2.6/tags/2.6.25-13/1018_linux-2.6.25.19.patch 2009-01-20 21:27:53 UTC (rev 1478)
1213 @@ -0,0 +1,461 @@
1214 +diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
1215 +index 5fed98c..2fb2dfe 100644
1216 +--- a/arch/x86/kernel/alternative.c
1217 ++++ b/arch/x86/kernel/alternative.c
1218 +@@ -457,7 +457,7 @@ void __init alternative_instructions(void)
1219 + _text, _etext);
1220 +
1221 + /* Only switch to UP mode if we don't immediately boot others */
1222 +- if (num_possible_cpus() == 1 || setup_max_cpus <= 1)
1223 ++ if (num_present_cpus() == 1 || setup_max_cpus <= 1)
1224 + alternatives_smp_switch(0);
1225 + }
1226 + #endif
1227 +diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
1228 +index f49c970..ca21808 100644
1229 +--- a/arch/x86/kernel/cpu/mtrr/generic.c
1230 ++++ b/arch/x86/kernel/cpu/mtrr/generic.c
1231 +@@ -251,7 +251,12 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
1232 + tmp |= ~((1<<(hi - 1)) - 1);
1233 +
1234 + if (tmp != mask_lo) {
1235 +- WARN_ON("mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
1236 ++ static int once = 1;
1237 ++
1238 ++ if (once) {
1239 ++ printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
1240 ++ once = 0;
1241 ++ }
1242 + mask_lo = tmp;
1243 + }
1244 + }
1245 +diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
1246 +index f239b30..0338d89 100644
1247 +--- a/arch/x86/kernel/io_apic_32.c
1248 ++++ b/arch/x86/kernel/io_apic_32.c
1249 +@@ -2305,6 +2305,9 @@ void __init setup_IO_APIC(void)
1250 + for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
1251 + set_bit(i, used_vectors);
1252 +
1253 ++ /* Mark FIRST_DEVICE_VECTOR which is assigned to IRQ0 as used. */
1254 ++ set_bit(FIRST_DEVICE_VECTOR, used_vectors);
1255 ++
1256 + enable_IO_APIC();
1257 +
1258 + if (acpi_ioapic)
1259 +diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
1260 +index f96b2e4..4f8b47e 100644
1261 +--- a/arch/x86/mm/ioremap.c
1262 ++++ b/arch/x86/mm/ioremap.c
1263 +@@ -438,7 +438,7 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
1264 + */
1265 + offset = phys_addr & ~PAGE_MASK;
1266 + phys_addr &= PAGE_MASK;
1267 +- size = PAGE_ALIGN(last_addr) - phys_addr;
1268 ++ size = PAGE_ALIGN(last_addr + 1) - phys_addr;
1269 +
1270 + /*
1271 + * Mappings have to fit in the FIX_BTMAP area.
1272 +diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
1273 +index a043bb1..ed2a83f 100644
1274 +--- a/drivers/char/drm/i915_dma.c
1275 ++++ b/drivers/char/drm/i915_dma.c
1276 +@@ -836,7 +836,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
1277 + DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
1278 + DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1279 + DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1280 +- DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1281 ++ DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1282 + };
1283 +
1284 + int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1285 +diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
1286 +index 613ec81..31143e9 100644
1287 +--- a/drivers/char/tty_io.c
1288 ++++ b/drivers/char/tty_io.c
1289 +@@ -3373,7 +3373,7 @@ int tty_ioctl(struct inode *inode, struct file *file,
1290 + case TIOCSTI:
1291 + return tiocsti(tty, p);
1292 + case TIOCGWINSZ:
1293 +- return tiocgwinsz(tty, p);
1294 ++ return tiocgwinsz(real_tty, p);
1295 + case TIOCSWINSZ:
1296 + return tiocswinsz(tty, real_tty, p);
1297 + case TIOCCONS:
1298 +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
1299 +index e12c132..48b9f28 100644
1300 +--- a/drivers/hwmon/it87.c
1301 ++++ b/drivers/hwmon/it87.c
1302 +@@ -46,6 +46,8 @@
1303 + #include <linux/err.h>
1304 + #include <linux/mutex.h>
1305 + #include <linux/sysfs.h>
1306 ++#include <linux/string.h>
1307 ++#include <linux/dmi.h>
1308 + #include <asm/io.h>
1309 +
1310 + #define DRVNAME "it87"
1311 +@@ -235,6 +237,8 @@ struct it87_sio_data {
1312 + enum chips type;
1313 + /* Values read from Super-I/O config space */
1314 + u8 vid_value;
1315 ++ /* Values set based on DMI strings */
1316 ++ u8 skip_pwm;
1317 + };
1318 +
1319 + /* For each registered chip, we need to keep some data in memory.
1320 +@@ -952,6 +956,7 @@ static int __init it87_find(unsigned short *address,
1321 + {
1322 + int err = -ENODEV;
1323 + u16 chip_type;
1324 ++ const char *board_vendor, *board_name;
1325 +
1326 + superio_enter();
1327 + chip_type = force_id ? force_id : superio_inw(DEVID);
1328 +@@ -1009,6 +1014,25 @@ static int __init it87_find(unsigned short *address,
1329 + pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
1330 + }
1331 +
1332 ++ sio_data->skip_pwm = 0;
1333 ++ /* Disable specific features based on DMI strings */
1334 ++ board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1335 ++ board_name = dmi_get_system_info(DMI_BOARD_NAME);
1336 ++ if (board_vendor && board_name) {
1337 ++ if (strcmp(board_vendor, "nVIDIA") == 0
1338 ++ && strcmp(board_name, "FN68PT") == 0) {
1339 ++ /* On the Shuttle SN68PT, FAN_CTL2 is apparently not
1340 ++ connected to a fan, but to something else. One user
1341 ++ has reported instant system power-off when changing
1342 ++ the PWM2 duty cycle, so we disable it.
1343 ++ I use the board name string as the trigger in case
1344 ++ the same board is ever used in other systems. */
1345 ++ pr_info("it87: Disabling pwm2 due to "
1346 ++ "hardware constraints\n");
1347 ++ sio_data->skip_pwm = (1 << 1);
1348 ++ }
1349 ++ }
1350 ++
1351 + exit:
1352 + superio_exit();
1353 + return err;
1354 +@@ -1157,22 +1181,25 @@ static int __devinit it87_probe(struct platform_device *pdev)
1355 + if ((err = device_create_file(dev,
1356 + &sensor_dev_attr_pwm1_enable.dev_attr))
1357 + || (err = device_create_file(dev,
1358 +- &sensor_dev_attr_pwm2_enable.dev_attr))
1359 +- || (err = device_create_file(dev,
1360 + &sensor_dev_attr_pwm3_enable.dev_attr))
1361 + || (err = device_create_file(dev,
1362 + &sensor_dev_attr_pwm1.dev_attr))
1363 + || (err = device_create_file(dev,
1364 +- &sensor_dev_attr_pwm2.dev_attr))
1365 +- || (err = device_create_file(dev,
1366 + &sensor_dev_attr_pwm3.dev_attr))
1367 + || (err = device_create_file(dev,
1368 + &dev_attr_pwm1_freq))
1369 + || (err = device_create_file(dev,
1370 +- &dev_attr_pwm2_freq))
1371 +- || (err = device_create_file(dev,
1372 + &dev_attr_pwm3_freq)))
1373 + goto ERROR4;
1374 ++ if (!(sio_data->skip_pwm & (1 << 1))) {
1375 ++ if ((err = device_create_file(dev,
1376 ++ &sensor_dev_attr_pwm2_enable.dev_attr))
1377 ++ || (err = device_create_file(dev,
1378 ++ &sensor_dev_attr_pwm2.dev_attr))
1379 ++ || (err = device_create_file(dev,
1380 ++ &dev_attr_pwm2_freq)))
1381 ++ goto ERROR4;
1382 ++ }
1383 + }
1384 +
1385 + if (data->type == it8712 || data->type == it8716
1386 +diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
1387 +index 594522a..b1cca43 100644
1388 +--- a/drivers/media/video/bt8xx/bttv-driver.c
1389 ++++ b/drivers/media/video/bt8xx/bttv-driver.c
1390 +@@ -3422,7 +3422,7 @@ static int radio_open(struct inode *inode, struct file *file)
1391 + dprintk("bttv: open minor=%d\n",minor);
1392 +
1393 + for (i = 0; i < bttv_num; i++) {
1394 +- if (bttvs[i].radio_dev->minor == minor) {
1395 ++ if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
1396 + btv = &bttvs[i];
1397 + break;
1398 + }
1399 +diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
1400 +index 01ebcec..db55c5c 100644
1401 +--- a/drivers/media/video/tvaudio.c
1402 ++++ b/drivers/media/video/tvaudio.c
1403 +@@ -1804,7 +1804,7 @@ static int chip_command(struct i2c_client *client,
1404 + break;
1405 + case VIDIOC_S_FREQUENCY:
1406 + chip->mode = 0; /* automatic */
1407 +- if (desc->checkmode) {
1408 ++ if (desc->checkmode && desc->setmode) {
1409 + desc->setmode(chip,V4L2_TUNER_MODE_MONO);
1410 + if (chip->prevmode != V4L2_TUNER_MODE_MONO)
1411 + chip->prevmode = -1; /* reset previous mode */
1412 +diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
1413 +index fea4946..2e9a4e2 100644
1414 +--- a/drivers/media/video/zoran_driver.c
1415 ++++ b/drivers/media/video/zoran_driver.c
1416 +@@ -139,7 +139,7 @@ const struct zoran_format zoran_formats[] = {
1417 + }, {
1418 + .name = "16-bit RGB BE",
1419 + ZFMT(-1,
1420 +- V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
1421 ++ V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
1422 + .depth = 16,
1423 + .flags = ZORAN_FORMAT_CAPTURE |
1424 + ZORAN_FORMAT_OVERLAY,
1425 +diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
1426 +index d84408a..d7bd408 100644
1427 +--- a/drivers/net/wireless/b43legacy/xmit.c
1428 ++++ b/drivers/net/wireless/b43legacy/xmit.c
1429 +@@ -624,7 +624,7 @@ void b43legacy_handle_hwtxstatus(struct b43legacy_wldev *dev,
1430 + tmp = hw->count;
1431 + status.frame_count = (tmp >> 4);
1432 + status.rts_count = (tmp & 0x0F);
1433 +- tmp = hw->flags;
1434 ++ tmp = hw->flags << 1;
1435 + status.supp_reason = ((tmp & 0x1C) >> 2);
1436 + status.pm_indicated = !!(tmp & 0x80);
1437 + status.intermediate = !!(tmp & 0x40);
1438 +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
1439 +index 0222824..66fd680 100644
1440 +--- a/drivers/video/console/fbcon.c
1441 ++++ b/drivers/video/console/fbcon.c
1442 +@@ -2974,8 +2974,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
1443 + p = &fb_display[vc->vc_num];
1444 + set_blitting_type(vc, info);
1445 + var_to_display(p, &info->var, info);
1446 +- cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
1447 +- rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
1448 ++ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1449 ++ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1450 + cols /= vc->vc_font.width;
1451 + rows /= vc->vc_font.height;
1452 + vc_resize(vc, cols, rows);
1453 +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
1454 +index 69a2e19..9f341b8 100644
1455 +--- a/fs/cifs/cifsglob.h
1456 ++++ b/fs/cifs/cifsglob.h
1457 +@@ -315,6 +315,7 @@ struct cifs_search_info {
1458 + __u32 resume_key;
1459 + char *ntwrk_buf_start;
1460 + char *srch_entries_start;
1461 ++ char *last_entry;
1462 + char *presume_name;
1463 + unsigned int resume_name_len;
1464 + unsigned endOfSearch:1;
1465 +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
1466 +index 30bbe44..6fe47f7 100644
1467 +--- a/fs/cifs/cifssmb.c
1468 ++++ b/fs/cifs/cifssmb.c
1469 +@@ -3598,6 +3598,8 @@ findFirstRetry:
1470 + le16_to_cpu(parms->SearchCount);
1471 + psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
1472 + psrch_inf->entries_in_buffer;
1473 ++ psrch_inf->last_entry = psrch_inf->srch_entries_start +
1474 ++ le16_to_cpu(parms->LastNameOffset);
1475 + *pnetfid = parms->SearchHandle;
1476 + } else {
1477 + cifs_buf_release(pSMB);
1478 +@@ -3712,6 +3714,8 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
1479 + le16_to_cpu(parms->SearchCount);
1480 + psrch_inf->index_of_last_entry +=
1481 + psrch_inf->entries_in_buffer;
1482 ++ psrch_inf->last_entry = psrch_inf->srch_entries_start +
1483 ++ le16_to_cpu(parms->LastNameOffset);
1484 + /* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
1485 + psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
1486 +
1487 +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
1488 +index 32b445e..2948aab 100644
1489 +--- a/fs/cifs/readdir.c
1490 ++++ b/fs/cifs/readdir.c
1491 +@@ -633,6 +633,70 @@ static int is_dir_changed(struct file *file)
1492 +
1493 + }
1494 +
1495 ++static int cifs_save_resume_key(const char *current_entry,
1496 ++ struct cifsFileInfo *cifsFile)
1497 ++{
1498 ++ int rc = 0;
1499 ++ unsigned int len = 0;
1500 ++ __u16 level;
1501 ++ char *filename;
1502 ++
1503 ++ if ((cifsFile == NULL) || (current_entry == NULL))
1504 ++ return -EINVAL;
1505 ++
1506 ++ level = cifsFile->srch_inf.info_level;
1507 ++
1508 ++ if (level == SMB_FIND_FILE_UNIX) {
1509 ++ FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
1510 ++
1511 ++ filename = &pFindData->FileName[0];
1512 ++ if (cifsFile->srch_inf.unicode) {
1513 ++ len = cifs_unicode_bytelen(filename);
1514 ++ } else {
1515 ++ /* BB should we make this strnlen of PATH_MAX? */
1516 ++ len = strnlen(filename, PATH_MAX);
1517 ++ }
1518 ++ cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1519 ++ } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
1520 ++ FILE_DIRECTORY_INFO *pFindData =
1521 ++ (FILE_DIRECTORY_INFO *)current_entry;
1522 ++ filename = &pFindData->FileName[0];
1523 ++ len = le32_to_cpu(pFindData->FileNameLength);
1524 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1525 ++ } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
1526 ++ FILE_FULL_DIRECTORY_INFO *pFindData =
1527 ++ (FILE_FULL_DIRECTORY_INFO *)current_entry;
1528 ++ filename = &pFindData->FileName[0];
1529 ++ len = le32_to_cpu(pFindData->FileNameLength);
1530 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1531 ++ } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
1532 ++ SEARCH_ID_FULL_DIR_INFO *pFindData =
1533 ++ (SEARCH_ID_FULL_DIR_INFO *)current_entry;
1534 ++ filename = &pFindData->FileName[0];
1535 ++ len = le32_to_cpu(pFindData->FileNameLength);
1536 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1537 ++ } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
1538 ++ FILE_BOTH_DIRECTORY_INFO *pFindData =
1539 ++ (FILE_BOTH_DIRECTORY_INFO *)current_entry;
1540 ++ filename = &pFindData->FileName[0];
1541 ++ len = le32_to_cpu(pFindData->FileNameLength);
1542 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1543 ++ } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
1544 ++ FIND_FILE_STANDARD_INFO *pFindData =
1545 ++ (FIND_FILE_STANDARD_INFO *)current_entry;
1546 ++ filename = &pFindData->FileName[0];
1547 ++ /* one byte length, no name conversion */
1548 ++ len = (unsigned int)pFindData->FileNameLength;
1549 ++ cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1550 ++ } else {
1551 ++ cFYI(1, ("Unknown findfirst level %d", level));
1552 ++ return -EINVAL;
1553 ++ }
1554 ++ cifsFile->srch_inf.resume_name_len = len;
1555 ++ cifsFile->srch_inf.presume_name = filename;
1556 ++ return rc;
1557 ++}
1558 ++
1559 + /* find the corresponding entry in the search */
1560 + /* Note that the SMB server returns search entries for . and .. which
1561 + complicates logic here if we choose to parse for them and we do not
1562 +@@ -694,6 +758,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
1563 + while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
1564 + (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
1565 + cFYI(1, ("calling findnext2"));
1566 ++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
1567 + rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
1568 + &cifsFile->srch_inf);
1569 + if (rc)
1570 +@@ -910,69 +975,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
1571 + return rc;
1572 + }
1573 +
1574 +-static int cifs_save_resume_key(const char *current_entry,
1575 +- struct cifsFileInfo *cifsFile)
1576 +-{
1577 +- int rc = 0;
1578 +- unsigned int len = 0;
1579 +- __u16 level;
1580 +- char *filename;
1581 +-
1582 +- if ((cifsFile == NULL) || (current_entry == NULL))
1583 +- return -EINVAL;
1584 +-
1585 +- level = cifsFile->srch_inf.info_level;
1586 +-
1587 +- if (level == SMB_FIND_FILE_UNIX) {
1588 +- FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
1589 +-
1590 +- filename = &pFindData->FileName[0];
1591 +- if (cifsFile->srch_inf.unicode) {
1592 +- len = cifs_unicode_bytelen(filename);
1593 +- } else {
1594 +- /* BB should we make this strnlen of PATH_MAX? */
1595 +- len = strnlen(filename, PATH_MAX);
1596 +- }
1597 +- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1598 +- } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
1599 +- FILE_DIRECTORY_INFO *pFindData =
1600 +- (FILE_DIRECTORY_INFO *)current_entry;
1601 +- filename = &pFindData->FileName[0];
1602 +- len = le32_to_cpu(pFindData->FileNameLength);
1603 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1604 +- } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
1605 +- FILE_FULL_DIRECTORY_INFO *pFindData =
1606 +- (FILE_FULL_DIRECTORY_INFO *)current_entry;
1607 +- filename = &pFindData->FileName[0];
1608 +- len = le32_to_cpu(pFindData->FileNameLength);
1609 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1610 +- } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
1611 +- SEARCH_ID_FULL_DIR_INFO *pFindData =
1612 +- (SEARCH_ID_FULL_DIR_INFO *)current_entry;
1613 +- filename = &pFindData->FileName[0];
1614 +- len = le32_to_cpu(pFindData->FileNameLength);
1615 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1616 +- } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
1617 +- FILE_BOTH_DIRECTORY_INFO *pFindData =
1618 +- (FILE_BOTH_DIRECTORY_INFO *)current_entry;
1619 +- filename = &pFindData->FileName[0];
1620 +- len = le32_to_cpu(pFindData->FileNameLength);
1621 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1622 +- } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
1623 +- FIND_FILE_STANDARD_INFO *pFindData =
1624 +- (FIND_FILE_STANDARD_INFO *)current_entry;
1625 +- filename = &pFindData->FileName[0];
1626 +- /* one byte length, no name conversion */
1627 +- len = (unsigned int)pFindData->FileNameLength;
1628 +- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1629 +- } else {
1630 +- cFYI(1, ("Unknown findfirst level %d", level));
1631 +- return -EINVAL;
1632 +- }
1633 +- cifsFile->srch_inf.resume_name_len = len;
1634 +- cifsFile->srch_inf.presume_name = filename;
1635 +- return rc;
1636 +-}
1637 +
1638 + int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1639 + {
1640 +diff --git a/fs/splice.c b/fs/splice.c
1641 +index eeb1a86..51d7c85 100644
1642 +--- a/fs/splice.c
1643 ++++ b/fs/splice.c
1644 +@@ -891,6 +891,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
1645 + if (unlikely(!(out->f_mode & FMODE_WRITE)))
1646 + return -EBADF;
1647 +
1648 ++ if (unlikely(out->f_flags & O_APPEND))
1649 ++ return -EINVAL;
1650 ++
1651 + ret = rw_verify_area(WRITE, out, ppos, len);
1652 + if (unlikely(ret < 0))
1653 + return ret;
1654 +diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
1655 +index 0a6d2e5..cdeaffe 100644
1656 +--- a/kernel/sched_rt.c
1657 ++++ b/kernel/sched_rt.c
1658 +@@ -91,12 +91,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);
1659 +
1660 + static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
1661 + {
1662 ++ struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
1663 + struct sched_rt_entity *rt_se = rt_rq->rt_se;
1664 +
1665 +- if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) {
1666 +- struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
1667 +-
1668 +- enqueue_rt_entity(rt_se);
1669 ++ if (rt_rq->rt_nr_running) {
1670 ++ if (rt_se && !on_rt_rq(rt_se))
1671 ++ enqueue_rt_entity(rt_se);
1672 + if (rt_rq->highest_prio < curr->prio)
1673 + resched_task(curr);
1674 + }
1675
1676 Added: hardened/2.6/tags/2.6.25-13/1019_linux-2.6.25.20.patch
1677 ===================================================================
1678 --- hardened/2.6/tags/2.6.25-13/1019_linux-2.6.25.20.patch (rev 0)
1679 +++ hardened/2.6/tags/2.6.25-13/1019_linux-2.6.25.20.patch 2009-01-20 21:27:53 UTC (rev 1478)
1680 @@ -0,0 +1,796 @@
1681 +diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
1682 +index 56ff552..d9f3f51 100644
1683 +--- a/arch/sparc64/kernel/trampoline.S
1684 ++++ b/arch/sparc64/kernel/trampoline.S
1685 +@@ -328,6 +328,12 @@ after_lock_tlb:
1686 +
1687 + wrpr %g0, 0, %wstate
1688 +
1689 ++ sethi %hi(prom_entry_lock), %g2
1690 ++1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
1691 ++ membar #StoreLoad | #StoreStore
1692 ++ brnz,pn %g1, 1b
1693 ++ nop
1694 ++
1695 + /* As a hack, put &init_thread_union into %g6.
1696 + * prom_world() loads from here to restore the %asi
1697 + * register.
1698 +@@ -337,7 +343,7 @@ after_lock_tlb:
1699 +
1700 + sethi %hi(is_sun4v), %o0
1701 + lduw [%o0 + %lo(is_sun4v)], %o0
1702 +- brz,pt %o0, 1f
1703 ++ brz,pt %o0, 2f
1704 + nop
1705 +
1706 + TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
1707 +@@ -369,10 +375,10 @@ after_lock_tlb:
1708 + call %o1
1709 + add %sp, (2047 + 128), %o0
1710 +
1711 +- ba,pt %xcc, 2f
1712 ++ ba,pt %xcc, 3f
1713 + nop
1714 +
1715 +-1: sethi %hi(sparc64_ttable_tl0), %o0
1716 ++2: sethi %hi(sparc64_ttable_tl0), %o0
1717 + set prom_set_trap_table_name, %g2
1718 + stx %g2, [%sp + 2047 + 128 + 0x00]
1719 + mov 1, %g2
1720 +@@ -386,7 +392,11 @@ after_lock_tlb:
1721 + call %o1
1722 + add %sp, (2047 + 128), %o0
1723 +
1724 +-2: ldx [%l0], %g6
1725 ++3: sethi %hi(prom_entry_lock), %g2
1726 ++ stb %g0, [%g2 + %lo(prom_entry_lock)]
1727 ++ membar #StoreStore | #StoreLoad
1728 ++
1729 ++ ldx [%l0], %g6
1730 + ldx [%g6 + TI_TASK], %g4
1731 +
1732 + mov 1, %g5
1733 +diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
1734 +index fa44fb9..4fdd886 100644
1735 +--- a/drivers/acpi/dock.c
1736 ++++ b/drivers/acpi/dock.c
1737 +@@ -599,14 +599,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
1738 + static void dock_notify(acpi_handle handle, u32 event, void *data)
1739 + {
1740 + struct dock_station *ds = data;
1741 ++ struct acpi_device *tmp;
1742 +
1743 + switch (event) {
1744 + case ACPI_NOTIFY_BUS_CHECK:
1745 +- if (!dock_in_progress(ds) && dock_present(ds)) {
1746 ++ if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
1747 ++ &tmp)) {
1748 + begin_dock(ds);
1749 + dock(ds);
1750 + if (!dock_present(ds)) {
1751 + printk(KERN_ERR PREFIX "Unable to dock!\n");
1752 ++ complete_dock(ds);
1753 + break;
1754 + }
1755 + atomic_notifier_call_chain(&dock_notifier_list,
1756 +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
1757 +index 980a741..4f65f59 100644
1758 +--- a/drivers/acpi/video.c
1759 ++++ b/drivers/acpi/video.c
1760 +@@ -624,6 +624,76 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
1761 + * device : video output device (LCD, CRT, ..)
1762 + *
1763 + * Return Value:
1764 ++ * Maximum brightness level
1765 ++ *
1766 ++ * Allocate and initialize device->brightness.
1767 ++ */
1768 ++
1769 ++static int
1770 ++acpi_video_init_brightness(struct acpi_video_device *device)
1771 ++{
1772 ++ union acpi_object *obj = NULL;
1773 ++ int i, max_level = 0, count = 0;
1774 ++ union acpi_object *o;
1775 ++ struct acpi_video_device_brightness *br = NULL;
1776 ++
1777 ++ if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
1778 ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
1779 ++ "LCD brightness level\n"));
1780 ++ goto out;
1781 ++ }
1782 ++
1783 ++ if (obj->package.count < 2)
1784 ++ goto out;
1785 ++
1786 ++ br = kzalloc(sizeof(*br), GFP_KERNEL);
1787 ++ if (!br) {
1788 ++ printk(KERN_ERR "can't allocate memory\n");
1789 ++ goto out;
1790 ++ }
1791 ++
1792 ++ br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
1793 ++ GFP_KERNEL);
1794 ++ if (!br->levels)
1795 ++ goto out_free;
1796 ++
1797 ++ for (i = 0; i < obj->package.count; i++) {
1798 ++ o = (union acpi_object *)&obj->package.elements[i];
1799 ++ if (o->type != ACPI_TYPE_INTEGER) {
1800 ++ printk(KERN_ERR PREFIX "Invalid data\n");
1801 ++ continue;
1802 ++ }
1803 ++ br->levels[count] = (u32) o->integer.value;
1804 ++
1805 ++ if (br->levels[count] > max_level)
1806 ++ max_level = br->levels[count];
1807 ++ count++;
1808 ++ }
1809 ++
1810 ++ if (count < 2)
1811 ++ goto out_free_levels;
1812 ++
1813 ++ br->count = count;
1814 ++ device->brightness = br;
1815 ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
1816 ++ kfree(obj);
1817 ++ return max_level;
1818 ++
1819 ++out_free_levels:
1820 ++ kfree(br->levels);
1821 ++out_free:
1822 ++ kfree(br);
1823 ++out:
1824 ++ device->brightness = NULL;
1825 ++ kfree(obj);
1826 ++ return 0;
1827 ++}
1828 ++
1829 ++/*
1830 ++ * Arg:
1831 ++ * device : video output device (LCD, CRT, ..)
1832 ++ *
1833 ++ * Return Value:
1834 + * None
1835 + *
1836 + * Find out all required AML methods defined under the output
1837 +@@ -633,10 +703,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
1838 + static void acpi_video_device_find_cap(struct acpi_video_device *device)
1839 + {
1840 + acpi_handle h_dummy1;
1841 +- int i;
1842 + u32 max_level = 0;
1843 +- union acpi_object *obj = NULL;
1844 +- struct acpi_video_device_brightness *br = NULL;
1845 +
1846 +
1847 + memset(&device->cap, 0, sizeof(device->cap));
1848 +@@ -665,53 +732,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
1849 + device->cap._DSS = 1;
1850 + }
1851 +
1852 +- if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
1853 +-
1854 +- if (obj->package.count >= 2) {
1855 +- int count = 0;
1856 +- union acpi_object *o;
1857 +-
1858 +- br = kzalloc(sizeof(*br), GFP_KERNEL);
1859 +- if (!br) {
1860 +- printk(KERN_ERR "can't allocate memory\n");
1861 +- } else {
1862 +- br->levels = kmalloc(obj->package.count *
1863 +- sizeof *(br->levels), GFP_KERNEL);
1864 +- if (!br->levels)
1865 +- goto out;
1866 +-
1867 +- for (i = 0; i < obj->package.count; i++) {
1868 +- o = (union acpi_object *)&obj->package.
1869 +- elements[i];
1870 +- if (o->type != ACPI_TYPE_INTEGER) {
1871 +- printk(KERN_ERR PREFIX "Invalid data\n");
1872 +- continue;
1873 +- }
1874 +- br->levels[count] = (u32) o->integer.value;
1875 +-
1876 +- if (br->levels[count] > max_level)
1877 +- max_level = br->levels[count];
1878 +- count++;
1879 +- }
1880 +- out:
1881 +- if (count < 2) {
1882 +- kfree(br->levels);
1883 +- kfree(br);
1884 +- } else {
1885 +- br->count = count;
1886 +- device->brightness = br;
1887 +- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1888 +- "found %d brightness levels\n",
1889 +- count));
1890 +- }
1891 +- }
1892 +- }
1893 +-
1894 +- } else {
1895 +- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
1896 +- }
1897 +-
1898 +- kfree(obj);
1899 ++ max_level = acpi_video_init_brightness(device);
1900 +
1901 + if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
1902 + int result;
1903 +@@ -1710,6 +1731,8 @@ static void
1904 + acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1905 + {
1906 + unsigned long level_current, level_next;
1907 ++ if (!device->brightness)
1908 ++ return;
1909 + acpi_video_device_lcd_get_level_current(device, &level_current);
1910 + level_next = acpi_video_get_next_level(device, level_current, event);
1911 + acpi_video_device_lcd_set_level(device, level_next);
1912 +diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
1913 +index b54112f..00b8539 100644
1914 +--- a/drivers/edac/cell_edac.c
1915 ++++ b/drivers/edac/cell_edac.c
1916 +@@ -141,7 +141,7 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
1917 + csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT;
1918 + csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
1919 + csrow->mtype = MEM_XDR;
1920 +- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
1921 ++ csrow->edac_mode = EDAC_SECDED;
1922 + dev_dbg(mci->dev,
1923 + "Initialized on node %d, chanmask=0x%x,"
1924 + " first_page=0x%lx, nr_pages=0x%x\n",
1925 +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
1926 +index d8db2f8..5ca1916 100644
1927 +--- a/drivers/gpio/gpiolib.c
1928 ++++ b/drivers/gpio/gpiolib.c
1929 +@@ -426,7 +426,7 @@ int gpio_get_value_cansleep(unsigned gpio)
1930 +
1931 + might_sleep_if(extra_checks);
1932 + chip = gpio_to_chip(gpio);
1933 +- return chip->get(chip, gpio - chip->base);
1934 ++ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
1935 + }
1936 + EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
1937 +
1938 +diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
1939 +index 69f94c9..9335d71 100644
1940 +--- a/drivers/net/wireless/libertas/scan.c
1941 ++++ b/drivers/net/wireless/libertas/scan.c
1942 +@@ -787,8 +787,8 @@ static int lbs_process_bss(struct bss_descriptor *bss,
1943 +
1944 + switch (elem->id) {
1945 + case MFIE_TYPE_SSID:
1946 +- bss->ssid_len = elem->len;
1947 +- memcpy(bss->ssid, elem->data, elem->len);
1948 ++ bss->ssid_len = min_t(int, 32, elem->len);
1949 ++ memcpy(bss->ssid, elem->data, bss->ssid_len);
1950 + lbs_deb_scan("got SSID IE: '%s', len %u\n",
1951 + escape_essid(bss->ssid, bss->ssid_len),
1952 + bss->ssid_len);
1953 +diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
1954 +index 8dededd..bd54e81 100644
1955 +--- a/fs/ext2/dir.c
1956 ++++ b/fs/ext2/dir.c
1957 +@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
1958 + return err;
1959 + }
1960 +
1961 +-static void ext2_check_page(struct page *page)
1962 ++static void ext2_check_page(struct page *page, int quiet)
1963 + {
1964 + struct inode *dir = page->mapping->host;
1965 + struct super_block *sb = dir->i_sb;
1966 +@@ -146,10 +146,10 @@ out:
1967 + /* Too bad, we had an error */
1968 +
1969 + Ebadsize:
1970 +- ext2_error(sb, "ext2_check_page",
1971 +- "size of directory #%lu is not a multiple of chunk size",
1972 +- dir->i_ino
1973 +- );
1974 ++ if (!quiet)
1975 ++ ext2_error(sb, __func__,
1976 ++ "size of directory #%lu is not a multiple "
1977 ++ "of chunk size", dir->i_ino);
1978 + goto fail;
1979 + Eshort:
1980 + error = "rec_len is smaller than minimal";
1981 +@@ -166,32 +166,36 @@ Espan:
1982 + Einumber:
1983 + error = "inode out of bounds";
1984 + bad_entry:
1985 +- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
1986 +- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
1987 +- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
1988 +- (unsigned long) le32_to_cpu(p->inode),
1989 +- rec_len, p->name_len);
1990 ++ if (!quiet)
1991 ++ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
1992 ++ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
1993 ++ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
1994 ++ (unsigned long) le32_to_cpu(p->inode),
1995 ++ rec_len, p->name_len);
1996 + goto fail;
1997 + Eend:
1998 +- p = (ext2_dirent *)(kaddr + offs);
1999 +- ext2_error (sb, "ext2_check_page",
2000 +- "entry in directory #%lu spans the page boundary"
2001 +- "offset=%lu, inode=%lu",
2002 +- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
2003 +- (unsigned long) le32_to_cpu(p->inode));
2004 ++ if (!quiet) {
2005 ++ p = (ext2_dirent *)(kaddr + offs);
2006 ++ ext2_error(sb, "ext2_check_page",
2007 ++ "entry in directory #%lu spans the page boundary"
2008 ++ "offset=%lu, inode=%lu",
2009 ++ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
2010 ++ (unsigned long) le32_to_cpu(p->inode));
2011 ++ }
2012 + fail:
2013 + SetPageChecked(page);
2014 + SetPageError(page);
2015 + }
2016 +
2017 +-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
2018 ++static struct page * ext2_get_page(struct inode *dir, unsigned long n,
2019 ++ int quiet)
2020 + {
2021 + struct address_space *mapping = dir->i_mapping;
2022 + struct page *page = read_mapping_page(mapping, n, NULL);
2023 + if (!IS_ERR(page)) {
2024 + kmap(page);
2025 + if (!PageChecked(page))
2026 +- ext2_check_page(page);
2027 ++ ext2_check_page(page, quiet);
2028 + if (PageError(page))
2029 + goto fail;
2030 + }
2031 +@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
2032 + for ( ; n < npages; n++, offset = 0) {
2033 + char *kaddr, *limit;
2034 + ext2_dirent *de;
2035 +- struct page *page = ext2_get_page(inode, n);
2036 ++ struct page *page = ext2_get_page(inode, n, 0);
2037 +
2038 + if (IS_ERR(page)) {
2039 + ext2_error(sb, __FUNCTION__,
2040 +@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
2041 + struct page *page = NULL;
2042 + struct ext2_inode_info *ei = EXT2_I(dir);
2043 + ext2_dirent * de;
2044 ++ int dir_has_error = 0;
2045 +
2046 + if (npages == 0)
2047 + goto out;
2048 +@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
2049 + n = start;
2050 + do {
2051 + char *kaddr;
2052 +- page = ext2_get_page(dir, n);
2053 ++ page = ext2_get_page(dir, n, dir_has_error);
2054 + if (!IS_ERR(page)) {
2055 + kaddr = page_address(page);
2056 + de = (ext2_dirent *) kaddr;
2057 +@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
2058 + de = ext2_next_entry(de);
2059 + }
2060 + ext2_put_page(page);
2061 +- }
2062 ++ } else
2063 ++ dir_has_error = 1;
2064 ++
2065 + if (++n >= npages)
2066 + n = 0;
2067 + /* next page is past the blocks we've got */
2068 +@@ -414,7 +421,7 @@ found:
2069 +
2070 + struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
2071 + {
2072 +- struct page *page = ext2_get_page(dir, 0);
2073 ++ struct page *page = ext2_get_page(dir, 0, 0);
2074 + ext2_dirent *de = NULL;
2075 +
2076 + if (!IS_ERR(page)) {
2077 +@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
2078 + for (n = 0; n <= npages; n++) {
2079 + char *dir_end;
2080 +
2081 +- page = ext2_get_page(dir, n);
2082 ++ page = ext2_get_page(dir, n, 0);
2083 + err = PTR_ERR(page);
2084 + if (IS_ERR(page))
2085 + goto out;
2086 +@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode)
2087 + {
2088 + struct page *page = NULL;
2089 + unsigned long i, npages = dir_pages(inode);
2090 ++ int dir_has_error = 0;
2091 +
2092 + for (i = 0; i < npages; i++) {
2093 + char *kaddr;
2094 + ext2_dirent * de;
2095 +- page = ext2_get_page(inode, i);
2096 ++ page = ext2_get_page(inode, i, dir_has_error);
2097 +
2098 +- if (IS_ERR(page))
2099 ++ if (IS_ERR(page)) {
2100 ++ dir_has_error = 1;
2101 + continue;
2102 ++ }
2103 +
2104 + kaddr = page_address(page);
2105 + de = (ext2_dirent *)kaddr;
2106 +diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
2107 +index 8ca3bfd..fba60c0 100644
2108 +--- a/fs/ext3/dir.c
2109 ++++ b/fs/ext3/dir.c
2110 +@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
2111 + int err;
2112 + struct inode *inode = filp->f_path.dentry->d_inode;
2113 + int ret = 0;
2114 ++ int dir_has_error = 0;
2115 +
2116 + sb = inode->i_sb;
2117 +
2118 +@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
2119 + * of recovering data when there's a bad sector
2120 + */
2121 + if (!bh) {
2122 +- ext3_error (sb, "ext3_readdir",
2123 +- "directory #%lu contains a hole at offset %lu",
2124 +- inode->i_ino, (unsigned long)filp->f_pos);
2125 ++ if (!dir_has_error) {
2126 ++ ext3_error(sb, __func__, "directory #%lu "
2127 ++ "contains a hole at offset %lld",
2128 ++ inode->i_ino, filp->f_pos);
2129 ++ dir_has_error = 1;
2130 ++ }
2131 + /* corrupt size? Maybe no more blocks to read */
2132 + if (filp->f_pos > inode->i_blocks << 9)
2133 + break;
2134 +diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
2135 +index 2c23bad..50ea8ed 100644
2136 +--- a/fs/ext4/dir.c
2137 ++++ b/fs/ext4/dir.c
2138 +@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * filp,
2139 + int err;
2140 + struct inode *inode = filp->f_path.dentry->d_inode;
2141 + int ret = 0;
2142 ++ int dir_has_error = 0;
2143 +
2144 + sb = inode->i_sb;
2145 +
2146 +@@ -147,9 +148,13 @@ static int ext4_readdir(struct file * filp,
2147 + * of recovering data when there's a bad sector
2148 + */
2149 + if (!bh) {
2150 +- ext4_error (sb, "ext4_readdir",
2151 +- "directory #%lu contains a hole at offset %lu",
2152 +- inode->i_ino, (unsigned long)filp->f_pos);
2153 ++ if (!dir_has_error) {
2154 ++ ext4_error(sb, __func__, "directory #%lu "
2155 ++ "contains a hole at offset %Lu",
2156 ++ inode->i_ino,
2157 ++ (unsigned long long) filp->f_pos);
2158 ++ dir_has_error = 1;
2159 ++ }
2160 + /* corrupt size? Maybe no more blocks to read */
2161 + if (filp->f_pos > inode->i_blocks << 9)
2162 + break;
2163 +diff --git a/include/linux/sched.h b/include/linux/sched.h
2164 +index 6a1e7af..b9254bc 100644
2165 +--- a/include/linux/sched.h
2166 ++++ b/include/linux/sched.h
2167 +@@ -1256,6 +1256,8 @@ struct task_struct {
2168 + atomic_t fs_excl; /* holding fs exclusive resources */
2169 + struct rcu_head rcu;
2170 +
2171 ++ struct list_head *scm_work_list;
2172 ++
2173 + /*
2174 + * cache last used pipe for splice
2175 + */
2176 +diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
2177 +index bb46e76..408f743 100644
2178 +--- a/include/math-emu/op-common.h
2179 ++++ b/include/math-emu/op-common.h
2180 +@@ -139,18 +139,27 @@ do { \
2181 + if (X##_e <= _FP_WFRACBITS_##fs) \
2182 + { \
2183 + _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
2184 +- _FP_ROUND(wc, X); \
2185 + if (_FP_FRAC_HIGH_##fs(X) \
2186 + & (_FP_OVERFLOW_##fs >> 1)) \
2187 + { \
2188 + X##_e = 1; \
2189 + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
2190 +- FP_SET_EXCEPTION(FP_EX_INEXACT); \
2191 + } \
2192 + else \
2193 + { \
2194 +- X##_e = 0; \
2195 +- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
2196 ++ _FP_ROUND(wc, X); \
2197 ++ if (_FP_FRAC_HIGH_##fs(X) \
2198 ++ & (_FP_OVERFLOW_##fs >> 1)) \
2199 ++ { \
2200 ++ X##_e = 1; \
2201 ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
2202 ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \
2203 ++ } \
2204 ++ else \
2205 ++ { \
2206 ++ X##_e = 0; \
2207 ++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
2208 ++ } \
2209 + } \
2210 + if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
2211 + (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
2212 +diff --git a/include/net/scm.h b/include/net/scm.h
2213 +index 06df126..33e9986 100644
2214 +--- a/include/net/scm.h
2215 ++++ b/include/net/scm.h
2216 +@@ -14,8 +14,9 @@
2217 +
2218 + struct scm_fp_list
2219 + {
2220 +- int count;
2221 +- struct file *fp[SCM_MAX_FD];
2222 ++ struct list_head list;
2223 ++ int count;
2224 ++ struct file *fp[SCM_MAX_FD];
2225 + };
2226 +
2227 + struct scm_cookie
2228 +diff --git a/net/core/dev.c b/net/core/dev.c
2229 +index 37ffd7a..bd08aa7 100644
2230 +--- a/net/core/dev.c
2231 ++++ b/net/core/dev.c
2232 +@@ -3593,14 +3593,11 @@ static int dev_new_index(struct net *net)
2233 + }
2234 +
2235 + /* Delayed registration/unregisteration */
2236 +-static DEFINE_SPINLOCK(net_todo_list_lock);
2237 + static LIST_HEAD(net_todo_list);
2238 +
2239 + static void net_set_todo(struct net_device *dev)
2240 + {
2241 +- spin_lock(&net_todo_list_lock);
2242 + list_add_tail(&dev->todo_list, &net_todo_list);
2243 +- spin_unlock(&net_todo_list_lock);
2244 + }
2245 +
2246 + static void rollback_registered(struct net_device *dev)
2247 +@@ -3909,33 +3906,24 @@ static void netdev_wait_allrefs(struct net_device *dev)
2248 + * free_netdev(y1);
2249 + * free_netdev(y2);
2250 + *
2251 +- * We are invoked by rtnl_unlock() after it drops the semaphore.
2252 ++ * We are invoked by rtnl_unlock().
2253 + * This allows us to deal with problems:
2254 + * 1) We can delete sysfs objects which invoke hotplug
2255 + * without deadlocking with linkwatch via keventd.
2256 + * 2) Since we run with the RTNL semaphore not held, we can sleep
2257 + * safely in order to wait for the netdev refcnt to drop to zero.
2258 ++ *
2259 ++ * We must not return until all unregister events added during
2260 ++ * the interval the lock was held have been completed.
2261 + */
2262 +-static DEFINE_MUTEX(net_todo_run_mutex);
2263 + void netdev_run_todo(void)
2264 + {
2265 + struct list_head list;
2266 +
2267 +- /* Need to guard against multiple cpu's getting out of order. */
2268 +- mutex_lock(&net_todo_run_mutex);
2269 +-
2270 +- /* Not safe to do outside the semaphore. We must not return
2271 +- * until all unregister events invoked by the local processor
2272 +- * have been completed (either by this todo run, or one on
2273 +- * another cpu).
2274 +- */
2275 +- if (list_empty(&net_todo_list))
2276 +- goto out;
2277 +-
2278 + /* Snapshot list, allow later requests */
2279 +- spin_lock(&net_todo_list_lock);
2280 + list_replace_init(&net_todo_list, &list);
2281 +- spin_unlock(&net_todo_list_lock);
2282 ++
2283 ++ __rtnl_unlock();
2284 +
2285 + while (!list_empty(&list)) {
2286 + struct net_device *dev
2287 +@@ -3965,9 +3953,6 @@ void netdev_run_todo(void)
2288 + /* Free network device */
2289 + kobject_put(&dev->dev.kobj);
2290 + }
2291 +-
2292 +-out:
2293 +- mutex_unlock(&net_todo_run_mutex);
2294 + }
2295 +
2296 + static struct net_device_stats *internal_stats(struct net_device *dev)
2297 +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
2298 +index 0cb2772..aa53778 100644
2299 +--- a/net/core/rtnetlink.c
2300 ++++ b/net/core/rtnetlink.c
2301 +@@ -73,7 +73,7 @@ void __rtnl_unlock(void)
2302 +
2303 + void rtnl_unlock(void)
2304 + {
2305 +- mutex_unlock(&rtnl_mutex);
2306 ++ /* This fellow will unlock it for us. */
2307 + netdev_run_todo();
2308 + }
2309 +
2310 +diff --git a/net/core/scm.c b/net/core/scm.c
2311 +index 10f5c65..ab242cc 100644
2312 +--- a/net/core/scm.c
2313 ++++ b/net/core/scm.c
2314 +@@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
2315 + if (!fpl)
2316 + return -ENOMEM;
2317 + *fplp = fpl;
2318 ++ INIT_LIST_HEAD(&fpl->list);
2319 + fpl->count = 0;
2320 + }
2321 + fpp = &fpl->fp[fpl->count];
2322 +@@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm)
2323 +
2324 + if (fpl) {
2325 + scm->fp = NULL;
2326 +- for (i=fpl->count-1; i>=0; i--)
2327 +- fput(fpl->fp[i]);
2328 +- kfree(fpl);
2329 ++ if (current->scm_work_list) {
2330 ++ list_add_tail(&fpl->list, current->scm_work_list);
2331 ++ } else {
2332 ++ LIST_HEAD(work_list);
2333 ++
2334 ++ current->scm_work_list = &work_list;
2335 ++
2336 ++ list_add(&fpl->list, &work_list);
2337 ++ while (!list_empty(&work_list)) {
2338 ++ fpl = list_first_entry(&work_list, struct scm_fp_list, list);
2339 ++
2340 ++ list_del(&fpl->list);
2341 ++ for (i=fpl->count-1; i>=0; i--)
2342 ++ fput(fpl->fp[i]);
2343 ++ kfree(fpl);
2344 ++ }
2345 ++
2346 ++ current->scm_work_list = NULL;
2347 ++ }
2348 + }
2349 + }
2350 +
2351 +@@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
2352 +
2353 + new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
2354 + if (new_fpl) {
2355 ++ INIT_LIST_HEAD(&new_fpl->list);
2356 + for (i=fpl->count-1; i>=0; i--)
2357 + get_file(fpl->fp[i]);
2358 + memcpy(new_fpl, fpl, sizeof(*fpl));
2359 +diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
2360 +index 50ad6ef..4618ea0 100644
2361 +--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
2362 ++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
2363 +@@ -138,10 +138,12 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
2364 + const struct net_device *out,
2365 + int (*okfn)(struct sk_buff *))
2366 + {
2367 ++#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
2368 + /* Previously seen (loopback)? Ignore. Do this before
2369 + fragment check. */
2370 + if (skb->nfct)
2371 + return NF_ACCEPT;
2372 ++#endif
2373 +
2374 + /* Gather fragments. */
2375 + if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
2376 +diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
2377 +index 8e4148d..1b0a738 100644
2378 +--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
2379 ++++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
2380 +@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
2381 + *obj = kmalloc(sizeof(struct snmp_object) + len,
2382 + GFP_ATOMIC);
2383 + if (*obj == NULL) {
2384 ++ kfree(p);
2385 + kfree(id);
2386 + if (net_ratelimit())
2387 + printk("OOM in bsalg (%d)\n", __LINE__);
2388 +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
2389 +index 12750f2..4d18fd2 100644
2390 +--- a/net/ipv6/tcp_ipv6.c
2391 ++++ b/net/ipv6/tcp_ipv6.c
2392 +@@ -1130,7 +1130,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
2393 + *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
2394 + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
2395 + *topt++ = htonl(tcp_time_stamp);
2396 +- *topt = htonl(ts);
2397 ++ *topt++ = htonl(ts);
2398 + }
2399 +
2400 + #ifdef CONFIG_TCP_MD5SIG
2401 +diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
2402 +index c63e933..4b5741b 100644
2403 +--- a/net/netfilter/xt_iprange.c
2404 ++++ b/net/netfilter/xt_iprange.c
2405 +@@ -67,7 +67,7 @@ iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
2406 + if (info->flags & IPRANGE_SRC) {
2407 + m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
2408 + m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
2409 +- m ^= info->flags & IPRANGE_SRC_INV;
2410 ++ m ^= !!(info->flags & IPRANGE_SRC_INV);
2411 + if (m) {
2412 + pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
2413 + NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
2414 +@@ -81,7 +81,7 @@ iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
2415 + if (info->flags & IPRANGE_DST) {
2416 + m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
2417 + m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
2418 +- m ^= info->flags & IPRANGE_DST_INV;
2419 ++ m ^= !!(info->flags & IPRANGE_DST_INV);
2420 + if (m) {
2421 + pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
2422 + NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
2423 +@@ -123,14 +123,14 @@ iprange_mt6(const struct sk_buff *skb, const struct net_device *in,
2424 + if (info->flags & IPRANGE_SRC) {
2425 + m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
2426 + m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
2427 +- m ^= info->flags & IPRANGE_SRC_INV;
2428 ++ m ^= !!(info->flags & IPRANGE_SRC_INV);
2429 + if (m)
2430 + return false;
2431 + }
2432 + if (info->flags & IPRANGE_DST) {
2433 + m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
2434 + m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
2435 +- m ^= info->flags & IPRANGE_DST_INV;
2436 ++ m ^= !!(info->flags & IPRANGE_DST_INV);
2437 + if (m)
2438 + return false;
2439 + }
2440 +diff --git a/security/commoncap.c b/security/commoncap.c
2441 +index 06d5c94..37205a1 100644
2442 +--- a/security/commoncap.c
2443 ++++ b/security/commoncap.c
2444 +@@ -244,10 +244,10 @@ static int get_file_caps(struct linux_binprm *bprm)
2445 + struct vfs_cap_data vcaps;
2446 + struct inode *inode;
2447 +
2448 +- if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
2449 +- bprm_clear_caps(bprm);
2450 ++ bprm_clear_caps(bprm);
2451 ++
2452 ++ if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
2453 + return 0;
2454 +- }
2455 +
2456 + dentry = dget(bprm->file->f_dentry);
2457 + inode = dentry->d_inode;
2458 +diff --git a/sound/core/control.c b/sound/core/control.c
2459 +index 01a1a5a..7ac4bbb 100644
2460 +--- a/sound/core/control.c
2461 ++++ b/sound/core/control.c
2462 +@@ -1426,12 +1426,12 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
2463 + cardnum = card->number;
2464 + snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
2465 +
2466 +- down_read(&card->controls_rwsem);
2467 ++ read_lock(&card->ctl_files_rwlock);
2468 + list_for_each_entry(ctl, &card->ctl_files, list) {
2469 + wake_up(&ctl->change_sleep);
2470 + kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
2471 + }
2472 +- up_read(&card->controls_rwsem);
2473 ++ read_unlock(&card->ctl_files_rwlock);
2474 +
2475 + if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
2476 + card, -1)) < 0)
2477
2478 Added: hardened/2.6/tags/2.6.25-13/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
2479 ===================================================================
2480 --- hardened/2.6/tags/2.6.25-13/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch (rev 0)
2481 +++ hardened/2.6/tags/2.6.25-13/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch 2009-01-20 21:27:53 UTC (rev 1478)
2482 @@ -0,0 +1,65 @@
2483 +Added-By: Gordon Malm <gengor@g.o>
2484 +
2485 +---
2486 +
2487 +From jejb@××××××.org Mon Nov 10 15:14:35 2008
2488 +From: Li Zefan <lizf@××××××××××.com>
2489 +Date: Fri, 7 Nov 2008 00:05:48 GMT
2490 +Subject: cgroups: fix invalid cgrp->dentry before cgroup has been completely removed
2491 +To: stable@××××××.org
2492 +Message-ID: <200811070005.mA705mbU003066@×××××××××××.org>
2493 +
2494 +From: Li Zefan <lizf@××××××××××.com>
2495 +
2496 +commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream
2497 +
2498 +This fixes an oops when reading /proc/sched_debug.
2499 +
2500 +A cgroup won't be removed completely until finishing cgroup_diput(), so we
2501 +shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a
2502 +group is being removed while cgroup_path() gets called, we may trigger
2503 +NULL dereference BUG.
2504 +
2505 +The bug can be reproduced:
2506 +
2507 + # cat test.sh
2508 + #!/bin/sh
2509 + mount -t cgroup -o cpu xxx /mnt
2510 + for (( ; ; ))
2511 + {
2512 + mkdir /mnt/sub
2513 + rmdir /mnt/sub
2514 + }
2515 + # ./test.sh &
2516 + # cat /proc/sched_debug
2517 +
2518 +BUG: unable to handle kernel NULL pointer dereference at 00000038
2519 +IP: [<c045a47f>] cgroup_path+0x39/0x90
2520 +..
2521 +Call Trace:
2522 + [<c0420344>] ? print_cfs_rq+0x6e/0x75d
2523 + [<c0421160>] ? sched_debug_show+0x72d/0xc1e
2524 +..
2525 +
2526 +Signed-off-by: Li Zefan <lizf@××××××××××.com>
2527 +Acked-by: Paul Menage <menage@××××××.com>
2528 +Cc: Peter Zijlstra <a.p.zijlstra@××××××.nl>
2529 +Cc: Ingo Molnar <mingo@××××.hu>
2530 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
2531 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2532 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2533 +
2534 +---
2535 + kernel/cgroup.c | 1 -
2536 + 1 file changed, 1 deletion(-)
2537 +
2538 +--- a/kernel/cgroup.c
2539 ++++ b/kernel/cgroup.c
2540 +@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *un
2541 + list_del(&cgrp->sibling);
2542 + spin_lock(&cgrp->dentry->d_lock);
2543 + d = dget(cgrp->dentry);
2544 +- cgrp->dentry = NULL;
2545 + spin_unlock(&d->d_lock);
2546 +
2547 + cgroup_d_remove_dir(d);
2548
2549 Added: hardened/2.6/tags/2.6.25-13/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
2550 ===================================================================
2551 --- hardened/2.6/tags/2.6.25-13/1402_cpqarry-fix-return-value-of-cpqarray_init.patch (rev 0)
2552 +++ hardened/2.6/tags/2.6.25-13/1402_cpqarry-fix-return-value-of-cpqarray_init.patch 2009-01-20 21:27:53 UTC (rev 1478)
2553 @@ -0,0 +1,55 @@
2554 +Added-By: Gordon Malm <gengor@g.o>
2555 +
2556 +---
2557 +
2558 +From 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 Mon Sep 17 00:00:00 2001
2559 +From: Andrey Borzenkov <arvidjaar@××××.ru>
2560 +Date: Thu, 6 Nov 2008 12:53:15 -0800
2561 +Subject: cpqarry: fix return value of cpqarray_init()
2562 +
2563 +From: Andrey Borzenkov <arvidjaar@××××.ru>
2564 +
2565 +commit 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 upstream.
2566 +
2567 +As reported by Dick Gevers on Compaq ProLiant:
2568 +
2569 +Oct 13 18:06:51 dvgcpl kernel: Compaq SMART2 Driver (v 2.6.0)
2570 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: 'cpqarray'->init
2571 +suspiciously returned 1, it should follow 0/-E convention
2572 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: loading module anyway...
2573 +Oct 13 18:06:51 dvgcpl kernel: Pid: 315, comm: modprobe Not tainted
2574 +2.6.27-desktop-0.rc8.2mnb #1
2575 +Oct 13 18:06:51 dvgcpl kernel: [<c0380612>] ? printk+0x18/0x1e
2576 +Oct 13 18:06:51 dvgcpl kernel: [<c0158f85>] sys_init_module+0x155/0x1c0
2577 +Oct 13 18:06:51 dvgcpl kernel: [<c0103f06>] syscall_call+0x7/0xb
2578 +Oct 13 18:06:51 dvgcpl kernel: =======================
2579 +
2580 +Make it return 0 on success and -ENODEV if no array was found.
2581 +
2582 +Reported-by: Dick Gevers <dvgevers@××××××.nl>
2583 +Signed-off-by: Andrey Borzenkov <arvidjaar@××××.ru>
2584 +Cc: Jens Axboe <jens.axboe@××××××.com>
2585 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
2586 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2587 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2588 +
2589 +---
2590 + drivers/block/cpqarray.c | 7 ++++++-
2591 + 1 file changed, 6 insertions(+), 1 deletion(-)
2592 +
2593 +--- a/drivers/block/cpqarray.c
2594 ++++ b/drivers/block/cpqarray.c
2595 +@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
2596 + num_cntlrs_reg++;
2597 + }
2598 +
2599 +- return(num_cntlrs_reg);
2600 ++ if (num_cntlrs_reg)
2601 ++ return 0;
2602 ++ else {
2603 ++ pci_unregister_driver(&cpqarray_pci_driver);
2604 ++ return -ENODEV;
2605 ++ }
2606 + }
2607 +
2608 + /* Function to find the first free pointer into our hba[] array */
2609
2610 Added: hardened/2.6/tags/2.6.25-13/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
2611 ===================================================================
2612 --- hardened/2.6/tags/2.6.25-13/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch (rev 0)
2613 +++ hardened/2.6/tags/2.6.25-13/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch 2009-01-20 21:27:53 UTC (rev 1478)
2614 @@ -0,0 +1,82 @@
2615 +Added-By: Gordon Malm <gengor@g.o>
2616 +
2617 +---
2618 +
2619 +From jejb@××××××.org Mon Nov 10 15:08:55 2008
2620 +From: Arthur Jones <ajones@××××××××.com>
2621 +Date: Fri, 7 Nov 2008 00:05:17 GMT
2622 +Subject: ext3: wait on all pending commits in ext3_sync_fs
2623 +To: stable@××××××.org
2624 +Message-ID: <200811070005.mA705Htq002320@×××××××××××.org>
2625 +
2626 +From: Arthur Jones <ajones@××××××××.com>
2627 +
2628 +commit c87591b719737b4e91eb1a9fa8fd55a4ff1886d6 upstream
2629 +
2630 +In ext3_sync_fs, we only wait for a commit to finish if we started it, but
2631 +there may be one already in progress which will not be synced.
2632 +
2633 +In the case of a data=ordered umount with pending long symlinks which are
2634 +delayed due to a long list of other I/O on the backing block device, this
2635 +causes the buffer associated with the long symlinks to not be moved to the
2636 +inode dirty list in the second phase of fsync_super. Then, before they
2637 +can be dirtied again, kjournald exits, seeing the UMOUNT flag and the
2638 +dirty pages are never written to the backing block device, causing long
2639 +symlink corruption and exposing new or previously freed block data to
2640 +userspace.
2641 +
2642 +This can be reproduced with a script created
2643 +by Eric Sandeen <sandeen@××××××.com>:
2644 +
2645 + #!/bin/bash
2646 +
2647 + umount /mnt/test2
2648 + mount /dev/sdb4 /mnt/test2
2649 + rm -f /mnt/test2/*
2650 + dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512
2651 + touch
2652 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
2653 + ln -s
2654 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
2655 + /mnt/test2/link
2656 + umount /mnt/test2
2657 + mount /dev/sdb4 /mnt/test2
2658 + ls /mnt/test2/
2659 + umount /mnt/test2
2660 +
2661 +To ensure all commits are synced, we flush all journal commits now when
2662 +sync_fs'ing ext3.
2663 +
2664 +Signed-off-by: Arthur Jones <ajones@××××××××.com>
2665 +Cc: Eric Sandeen <sandeen@××××××.com>
2666 +Cc: Theodore Ts'o <tytso@×××.edu>
2667 +Cc: <linux-ext4@×××××××××××.org>
2668 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
2669 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2670 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2671 +
2672 +---
2673 + fs/ext3/super.c | 11 +++++------
2674 + 1 file changed, 5 insertions(+), 6 deletions(-)
2675 +
2676 +--- a/fs/ext3/super.c
2677 ++++ b/fs/ext3/super.c
2678 +@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct sup
2679 +
2680 + static int ext3_sync_fs(struct super_block *sb, int wait)
2681 + {
2682 +- tid_t target;
2683 +-
2684 + sb->s_dirt = 0;
2685 +- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
2686 +- if (wait)
2687 +- log_wait_commit(EXT3_SB(sb)->s_journal, target);
2688 +- }
2689 ++ if (wait)
2690 ++ ext3_force_commit(sb);
2691 ++ else
2692 ++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
2693 ++
2694 + return 0;
2695 + }
2696 +
2697
2698 Added: hardened/2.6/tags/2.6.25-13/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
2699 ===================================================================
2700 --- hardened/2.6/tags/2.6.25-13/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch (rev 0)
2701 +++ hardened/2.6/tags/2.6.25-13/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch 2009-01-20 21:27:53 UTC (rev 1478)
2702 @@ -0,0 +1,48 @@
2703 +Added-By: Gordon Malm <gengor@g.o>
2704 +
2705 +---
2706 +
2707 +From jkosina@××××.cz Tue Nov 11 15:52:41 2008
2708 +From: Jiri Kosina <jkosina@××××.cz>
2709 +Date: Tue, 11 Nov 2008 23:45:38 +0100 (CET)
2710 +Subject: HID: fix incorrent length condition in hidraw_write()
2711 +To: stable@××××××.org
2712 +Cc: Paul Stoffregen <paul@××××.com>
2713 +Message-ID: <alpine.LNX.1.10.0811112344180.24889@××××××××××.cz>
2714 +
2715 +From: Jiri Kosina <jkosina@××××.cz>
2716 +
2717 +upstream commit 2b107d629dc0c35de606bb7b010b829cd247a93a
2718 +
2719 +From: Jiri Kosina <jkosina@××××.cz>
2720 +
2721 +The bound check on the buffer length
2722 +
2723 + if (count > HID_MIN_BUFFER_SIZE)
2724 +
2725 +is of course incorrent, the proper check is
2726 +
2727 + if (count > HID_MAX_BUFFER_SIZE)
2728 +
2729 +Fix it.
2730 +
2731 +Reported-by: Jerry Ryle <jerry@×××××××××.com>
2732 +Signed-off-by: Jiri Kosina <jkosina@××××.cz>
2733 +Cc: Paul Stoffregen <paul@××××.com>
2734 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2735 +
2736 +---
2737 + drivers/hid/hidraw.c | 2 +-
2738 + 1 file changed, 1 insertion(+), 1 deletion(-)
2739 +
2740 +--- a/drivers/hid/hidraw.c
2741 ++++ b/drivers/hid/hidraw.c
2742 +@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file
2743 + if (!dev->hid_output_raw_report)
2744 + return -ENODEV;
2745 +
2746 +- if (count > HID_MIN_BUFFER_SIZE) {
2747 ++ if (count > HID_MAX_BUFFER_SIZE) {
2748 + printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
2749 + task_pid_nr(current));
2750 + return -EINVAL;
2751
2752 Added: hardened/2.6/tags/2.6.25-13/1405_i-oat-fix-async_tx.callback-checking.patch
2753 ===================================================================
2754 --- hardened/2.6/tags/2.6.25-13/1405_i-oat-fix-async_tx.callback-checking.patch (rev 0)
2755 +++ hardened/2.6/tags/2.6.25-13/1405_i-oat-fix-async_tx.callback-checking.patch 2009-01-20 21:27:53 UTC (rev 1478)
2756 @@ -0,0 +1,48 @@
2757 +Added-By: Gordon Malm <gengor@g.o>
2758 +
2759 +Note: Backported to earlier kernels. Original message included below.
2760 +
2761 +---
2762 +
2763 +From jejb@××××××.org Tue Nov 11 10:17:05 2008
2764 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2765 +Date: Tue, 11 Nov 2008 17:50:05 GMT
2766 +Subject: I/OAT: fix async_tx.callback checking
2767 +To: jejb@××××××.org, stable@××××××.org
2768 +Message-ID: <200811111750.mABHo5Ai025612@×××××××××××.org>
2769 +
2770 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2771 +
2772 +commit 12ccea24e309d815d058cdc6ee8bf2c4b85f0c5f upstream
2773 +
2774 +async_tx.callback should be checked for the first
2775 +not the last descriptor in the chain.
2776 +
2777 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2778 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2779 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2780 +
2781 +---
2782 + drivers/dma/ioat_dma.c | 4 ++--
2783 + 1 file changed, 2 insertions(+), 2 deletions(-)
2784 +
2785 +--- a/drivers/dma/ioat_dma.c
2786 ++++ b/drivers/dma/ioat_dma.c
2787 +@@ -251,7 +251,7 @@ static dma_cookie_t ioat1_tx_submit(stru
2788 + } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan)));
2789 +
2790 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
2791 +- if (new->async_tx.callback) {
2792 ++ if (first->async_tx.callback) {
2793 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
2794 + if (first != new) {
2795 + /* move callback into to last desc */
2796 +@@ -336,7 +336,7 @@ static dma_cookie_t ioat2_tx_submit(stru
2797 + } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan)));
2798 +
2799 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
2800 +- if (new->async_tx.callback) {
2801 ++ if (first->async_tx.callback) {
2802 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
2803 + if (first != new) {
2804 + /* move callback into to last desc */
2805
2806 Added: hardened/2.6/tags/2.6.25-13/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
2807 ===================================================================
2808 --- hardened/2.6/tags/2.6.25-13/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch (rev 0)
2809 +++ hardened/2.6/tags/2.6.25-13/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch 2009-01-20 21:27:53 UTC (rev 1478)
2810 @@ -0,0 +1,54 @@
2811 +Added-By: Gordon Malm <gengor@g.o>
2812 +
2813 +Note: Backported to earlier kernels. Original message below.
2814 +
2815 +---
2816 +
2817 +From jejb@××××××.org Tue Nov 11 10:15:37 2008
2818 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2819 +Date: Tue, 11 Nov 2008 17:50:09 GMT
2820 +Subject: I/OAT: fix channel resources free for not allocated channels
2821 +To: stable@××××××.org
2822 +Message-ID: <200811111750.mABHo9IU025655@×××××××××××.org>
2823 +
2824 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2825 +
2826 +commit c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca upstream
2827 +
2828 +If the ioatdma driver is loaded but not used it does not allocate descriptors.
2829 +Before it frees channel resources it should first be sure
2830 +that they have been previously allocated.
2831 +
2832 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2833 +Tested-by: Tom Picard <tom.s.picard@×××××.com>
2834 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
2835 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2836 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2837 +
2838 +---
2839 + drivers/dma/ioat_dma.c | 7 +++++++
2840 + 1 file changed, 7 insertions(+)
2841 +
2842 +--- a/drivers/dma/ioat_dma.c
2843 ++++ b/drivers/dma/ioat_dma.c
2844 +@@ -524,6 +524,12 @@ static void ioat_dma_free_chan_resources
2845 + struct ioat_desc_sw *desc, *_desc;
2846 + int in_use_descs = 0;
2847 +
2848 ++ /* Before freeing channel resources first check
2849 ++ * if they have been previously allocated for this channel.
2850 ++ */
2851 ++ if (ioat_chan->desccount == 0)
2852 ++ return;
2853 ++
2854 + tasklet_disable(&ioat_chan->cleanup_task);
2855 + ioat_dma_memcpy_cleanup(ioat_chan);
2856 +
2857 +@@ -585,6 +591,7 @@ static void ioat_dma_free_chan_resources
2858 + ioat_chan->last_completion = ioat_chan->completion_addr = 0;
2859 + ioat_chan->pending = 0;
2860 + ioat_chan->dmacount = 0;
2861 ++ ioat_chan->desccount = 0;
2862 + }
2863 +
2864 + /**
2865
2866 Added: hardened/2.6/tags/2.6.25-13/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
2867 ===================================================================
2868 --- hardened/2.6/tags/2.6.25-13/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch (rev 0)
2869 +++ hardened/2.6/tags/2.6.25-13/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch 2009-01-20 21:27:53 UTC (rev 1478)
2870 @@ -0,0 +1,89 @@
2871 +Added-By: Gordon Malm <gengor@g.o>
2872 +
2873 +---
2874 +
2875 +From jejb@××××××.org Tue Nov 11 10:16:31 2008
2876 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2877 +Date: Tue, 11 Nov 2008 17:50:07 GMT
2878 +Subject: I/OAT: fix dma_pin_iovec_pages() error handling
2879 +To: stable@××××××.org
2880 +Message-ID: <200811111750.mABHo7v5025633@×××××××××××.org>
2881 +
2882 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2883 +
2884 +commit c2c0b4c5434c0a25f7f7796b29155d53805909f5 upstream
2885 +
2886 +Error handling needs to be modified in dma_pin_iovec_pages().
2887 +It should return NULL instead of ERR_PTR
2888 +(pinned_list is checked for NULL in tcp_recvmsg() to determine
2889 +if iovec pages have been successfully pinned down).
2890 +In case of error for the first iovec,
2891 +local_list->nr_iovecs needs to be initialized.
2892 +
2893 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2894 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2895 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2896 +
2897 +---
2898 + drivers/dma/iovlock.c | 17 ++++++-----------
2899 + 1 file changed, 6 insertions(+), 11 deletions(-)
2900 +
2901 +--- a/drivers/dma/iovlock.c
2902 ++++ b/drivers/dma/iovlock.c
2903 +@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pa
2904 + int nr_iovecs = 0;
2905 + int iovec_len_used = 0;
2906 + int iovec_pages_used = 0;
2907 +- long err;
2908 +
2909 + /* don't pin down non-user-based iovecs */
2910 + if (segment_eq(get_fs(), KERNEL_DS))
2911 +@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa
2912 + local_list = kmalloc(sizeof(*local_list)
2913 + + (nr_iovecs * sizeof (struct dma_page_list))
2914 + + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
2915 +- if (!local_list) {
2916 +- err = -ENOMEM;
2917 ++ if (!local_list)
2918 + goto out;
2919 +- }
2920 +
2921 + /* list of pages starts right after the page list array */
2922 + pages = (struct page **) &local_list->page_list[nr_iovecs];
2923 +
2924 ++ local_list->nr_iovecs = 0;
2925 ++
2926 + for (i = 0; i < nr_iovecs; i++) {
2927 + struct dma_page_list *page_list = &local_list->page_list[i];
2928 +
2929 + len -= iov[i].iov_len;
2930 +
2931 +- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
2932 +- err = -EFAULT;
2933 ++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
2934 + goto unpin;
2935 +- }
2936 +
2937 + page_list->nr_pages = num_pages_spanned(&iov[i]);
2938 + page_list->base_address = iov[i].iov_base;
2939 +@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa
2940 + NULL);
2941 + up_read(&current->mm->mmap_sem);
2942 +
2943 +- if (ret != page_list->nr_pages) {
2944 +- err = -ENOMEM;
2945 ++ if (ret != page_list->nr_pages)
2946 + goto unpin;
2947 +- }
2948 +
2949 + local_list->nr_iovecs = i + 1;
2950 + }
2951 +@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa
2952 + unpin:
2953 + dma_unpin_iovec_pages(local_list);
2954 + out:
2955 +- return ERR_PTR(err);
2956 ++ return NULL;
2957 + }
2958 +
2959 + void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
2960
2961 Added: hardened/2.6/tags/2.6.25-13/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
2962 ===================================================================
2963 --- hardened/2.6/tags/2.6.25-13/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch (rev 0)
2964 +++ hardened/2.6/tags/2.6.25-13/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch 2009-01-20 21:27:53 UTC (rev 1478)
2965 @@ -0,0 +1,51 @@
2966 +Added-By: Gordon Malm <gengor@g.o>
2967 +
2968 +---
2969 +
2970 +From jejb@××××××.org Tue Nov 11 09:53:44 2008
2971 +From: David Woodhouse <David.Woodhouse@×××××.com>
2972 +Date: Fri, 7 Nov 2008 00:08:59 GMT
2973 +Subject: JFFS2: Fix lack of locking in thread_should_wake()
2974 +To: stable@××××××.org
2975 +Message-ID: <200811070008.mA708xQE008191@×××××××××××.org>
2976 +
2977 +From: David Woodhouse <David.Woodhouse@×××××.com>
2978 +
2979 +commit b27cf88e9592953ae292d05324887f2f44979433 upstream
2980 +
2981 +The thread_should_wake() function trawls through the list of 'very
2982 +dirty' eraseblocks, determining whether the background GC thread should
2983 +wake. Doing this without holding the appropriate locks is a bad idea.
2984 +
2985 +OLPC Trac #8615
2986 +
2987 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
2988 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2989 +
2990 +---
2991 + fs/jffs2/background.c | 10 +++++-----
2992 + 1 file changed, 5 insertions(+), 5 deletions(-)
2993 +
2994 +--- a/fs/jffs2/background.c
2995 ++++ b/fs/jffs2/background.c
2996 +@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(
2997 + for (;;) {
2998 + allow_signal(SIGHUP);
2999 + again:
3000 ++ spin_lock(&c->erase_completion_lock);
3001 + if (!jffs2_thread_should_wake(c)) {
3002 + set_current_state (TASK_INTERRUPTIBLE);
3003 ++ spin_unlock(&c->erase_completion_lock);
3004 + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
3005 +- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
3006 +- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
3007 +- matter - We don't care if we miss a wakeup, because the GC thread
3008 +- is only an optimisation anyway. */
3009 + schedule();
3010 +- }
3011 ++ } else
3012 ++ spin_unlock(&c->erase_completion_lock);
3013 ++
3014 +
3015 + /* This thread is purely an optimisation. But if it runs when
3016 + other things could be running, it actually makes things a
3017
3018 Added: hardened/2.6/tags/2.6.25-13/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
3019 ===================================================================
3020 --- hardened/2.6/tags/2.6.25-13/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch (rev 0)
3021 +++ hardened/2.6/tags/2.6.25-13/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch 2009-01-20 21:27:53 UTC (rev 1478)
3022 @@ -0,0 +1,70 @@
3023 +Added-By: Gordon Malm <gengor@g.o>
3024 +
3025 +---
3026 +
3027 +From jejb@××××××.org Tue Nov 11 09:53:08 2008
3028 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
3029 +Date: Fri, 7 Nov 2008 00:08:19 GMT
3030 +Subject: JFFS2: fix race condition in jffs2_lzo_compress()
3031 +To: stable@××××××.org
3032 +Message-ID: <200811070008.mA708Jdo007031@×××××××××××.org>
3033 +
3034 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
3035 +
3036 +commit dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 upstream
3037 +
3038 +deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However,
3039 +jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the
3040 +compressed data from lzo_compress_buf. Correct this by moving the mutex
3041 +unlock after the copy.
3042 +
3043 +In addition, document what deflate_mutex actually protects.
3044 +
3045 +Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
3046 +Acked-by: Richard Purdie <rpurdie@××××××××××.com>
3047 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
3048 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
3049 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3050 +
3051 +---
3052 + fs/jffs2/compr_lzo.c | 15 +++++++++------
3053 + 1 file changed, 9 insertions(+), 6 deletions(-)
3054 +
3055 +--- a/fs/jffs2/compr_lzo.c
3056 ++++ b/fs/jffs2/compr_lzo.c
3057 +@@ -19,7 +19,7 @@
3058 +
3059 + static void *lzo_mem;
3060 + static void *lzo_compress_buf;
3061 +-static DEFINE_MUTEX(deflate_mutex);
3062 ++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
3063 +
3064 + static void free_workspace(void)
3065 + {
3066 +@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned c
3067 +
3068 + mutex_lock(&deflate_mutex);
3069 + ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
3070 +- mutex_unlock(&deflate_mutex);
3071 +-
3072 + if (ret != LZO_E_OK)
3073 +- return -1;
3074 ++ goto fail;
3075 +
3076 + if (compress_size > *dstlen)
3077 +- return -1;
3078 ++ goto fail;
3079 +
3080 + memcpy(cpage_out, lzo_compress_buf, compress_size);
3081 +- *dstlen = compress_size;
3082 ++ mutex_unlock(&deflate_mutex);
3083 +
3084 ++ *dstlen = compress_size;
3085 + return 0;
3086 ++
3087 ++ fail:
3088 ++ mutex_unlock(&deflate_mutex);
3089 ++ return -1;
3090 + }
3091 +
3092 + static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
3093
3094 Added: hardened/2.6/tags/2.6.25-13/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
3095 ===================================================================
3096 --- hardened/2.6/tags/2.6.25-13/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch (rev 0)
3097 +++ hardened/2.6/tags/2.6.25-13/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch 2009-01-20 21:27:53 UTC (rev 1478)
3098 @@ -0,0 +1,51 @@
3099 +Added-By: Gordon Malm <gengor@g.o>
3100 +
3101 +Note: Changed patch slightly to eliminate fuzz.
3102 +
3103 +---
3104 +
3105 +From jejb@××××××.org Tue Nov 11 09:47:32 2008
3106 +From: Andre Noll <maan@×××××××××××.org>
3107 +Date: Fri, 7 Nov 2008 00:07:46 GMT
3108 +Subject: md: linear: Fix a division by zero bug for very small arrays.
3109 +To: stable@××××××.org
3110 +Message-ID: <200811070007.mA707k6d006270@×××××××××××.org>
3111 +
3112 +From: Andre Noll <maan@×××××××××××.org>
3113 +
3114 +commit f1cd14ae52985634d0389e934eba25b5ecf24565 upstream
3115 +
3116 +Date: Thu, 6 Nov 2008 19:41:24 +1100
3117 +Subject: md: linear: Fix a division by zero bug for very small arrays.
3118 +
3119 +We currently oops with a divide error on starting a linear software
3120 +raid array consisting of at least two very small (< 500K) devices.
3121 +
3122 +The bug is caused by the calculation of the hash table size which
3123 +tries to compute sector_div(sz, base) with "base" being zero due to
3124 +the small size of the component devices of the array.
3125 +
3126 +Fix this by requiring the hash spacing to be at least one which
3127 +implies that also "base" is non-zero.
3128 +
3129 +This bug has existed since about 2.6.14.
3130 +
3131 +Signed-off-by: Andre Noll <maan@×××××××××××.org>
3132 +Signed-off-by: NeilBrown <neilb@××××.de>
3133 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3134 +
3135 +---
3136 + drivers/md/linear.c | 2 ++
3137 + 1 file changed, 2 insertions(+)
3138 +
3139 +--- a/drivers/md/linear.c
3140 ++++ b/drivers/md/linear.c
3141 +@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_
3142 +
3143 + min_spacing = conf->array_size;
3144 + sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
3145 ++ if (min_spacing == 0)
3146 ++ min_spacing = 1;
3147 +
3148 + /* min_spacing is the minimum spacing that will fit the hash
3149 + * table in one PAGE. This may be much smaller than needed.
3150
3151 Added: hardened/2.6/tags/2.6.25-13/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch
3152 ===================================================================
3153 --- hardened/2.6/tags/2.6.25-13/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch (rev 0)
3154 +++ hardened/2.6/tags/2.6.25-13/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch 2009-01-20 21:27:53 UTC (rev 1478)
3155 @@ -0,0 +1,42 @@
3156 +Added-By: Gordon Malm <gengor@g.o>
3157 +
3158 +---
3159 +
3160 +From 493890e75d98810a3470b4aae23be628ee5e9667 Mon Sep 17 00:00:00 2001
3161 +From: Pierre Ossman <drzeus@××××××.cx>
3162 +Date: Sun, 26 Oct 2008 12:37:25 +0100
3163 +Subject: mmc: increase SD write timeout for crappy cards
3164 +
3165 +From: Pierre Ossman <drzeus@××××××.cx>
3166 +
3167 +commit 493890e75d98810a3470b4aae23be628ee5e9667 upstream.
3168 +
3169 +It seems that some cards are slightly out of spec and occasionally
3170 +will not be able to complete a write in the alloted 250 ms [1].
3171 +Incease the timeout slightly to allow even these cards to function
3172 +properly.
3173 +
3174 +[1] http://lkml.org/lkml/2008/9/23/390
3175 +
3176 +Signed-off-by: Pierre Ossman <drzeus@××××××.cx>
3177 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3178 +
3179 +---
3180 + drivers/mmc/core/core.c | 6 +++++-
3181 + 1 file changed, 5 insertions(+), 1 deletion(-)
3182 +
3183 +--- a/drivers/mmc/core/core.c
3184 ++++ b/drivers/mmc/core/core.c
3185 +@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_dat
3186 + (card->host->ios.clock / 1000);
3187 +
3188 + if (data->flags & MMC_DATA_WRITE)
3189 +- limit_us = 250000;
3190 ++ /*
3191 ++ * The limit is really 250 ms, but that is
3192 ++ * insufficient for some crappy cards.
3193 ++ */
3194 ++ limit_us = 300000;
3195 + else
3196 + limit_us = 100000;
3197 +
3198
3199 Added: hardened/2.6/tags/2.6.25-13/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
3200 ===================================================================
3201 --- hardened/2.6/tags/2.6.25-13/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch (rev 0)
3202 +++ hardened/2.6/tags/2.6.25-13/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch 2009-01-20 21:27:53 UTC (rev 1478)
3203 @@ -0,0 +1,213 @@
3204 +Added-By: Gordon Malm <gengor@g.o>
3205 +
3206 +Note: Backported to ealier kernels. Original message included below.
3207 +
3208 +---
3209 +
3210 +From jejb@××××××.org Tue Nov 11 09:59:05 2008
3211 +From: Miklos Szeredi <mszeredi@××××.cz>
3212 +Date: Sun, 9 Nov 2008 19:50:02 GMT
3213 +Subject: net: unix: fix inflight counting bug in garbage collector
3214 +To: stable@××××××.org
3215 +Message-ID: <200811091950.mA9Jo2iL003804@×××××××××××.org>
3216 +
3217 +From: Miklos Szeredi <mszeredi@××××.cz>
3218 +
3219 +commit 6209344f5a3795d34b7f2c0061f49802283b6bdd upstream
3220 +
3221 +Previously I assumed that the receive queues of candidates don't
3222 +change during the GC. This is only half true, nothing can be received
3223 +from the queues (see comment in unix_gc()), but buffers could be added
3224 +through the other half of the socket pair, which may still have file
3225 +descriptors referring to it.
3226 +
3227 +This can result in inc_inflight_move_tail() erronously increasing the
3228 +"inflight" counter for a unix socket for which dec_inflight() wasn't
3229 +previously called. This in turn can trigger the "BUG_ON(total_refs <
3230 +inflight_refs)" in a later garbage collection run.
3231 +
3232 +Fix this by only manipulating the "inflight" counter for sockets which
3233 +are candidates themselves. Duplicating the file references in
3234 +unix_attach_fds() is also needed to prevent a socket becoming a
3235 +candidate for GC while the skb that contains it is not yet queued.
3236 +
3237 +Reported-by: Andrea Bittau <a.bittau@×××××××××.uk>
3238 +Signed-off-by: Miklos Szeredi <mszeredi@××××.cz>
3239 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
3240 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3241 +
3242 +---
3243 + include/net/af_unix.h | 1 +
3244 + net/unix/af_unix.c | 31 ++++++++++++++++++++++++-------
3245 + net/unix/garbage.c | 49 +++++++++++++++++++++++++++++++++++++------------
3246 + 3 files changed, 62 insertions(+), 19 deletions(-)
3247 +
3248 +--- a/include/net/af_unix.h
3249 ++++ b/include/net/af_unix.h
3250 +@@ -54,6 +54,7 @@ struct unix_sock {
3251 + atomic_t inflight;
3252 + spinlock_t lock;
3253 + unsigned int gc_candidate : 1;
3254 ++ unsigned int gc_maybe_cycle : 1;
3255 + wait_queue_head_t peer_wait;
3256 + };
3257 + #define unix_sk(__sk) ((struct unix_sock *)__sk)
3258 +--- a/net/unix/af_unix.c
3259 ++++ b/net/unix/af_unix.c
3260 +@@ -1302,14 +1302,23 @@ static void unix_destruct_fds(struct sk_
3261 + sock_wfree(skb);
3262 + }
3263 +
3264 +-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
3265 ++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
3266 + {
3267 + int i;
3268 ++
3269 ++ /*
3270 ++ * Need to duplicate file references for the sake of garbage
3271 ++ * collection. Otherwise a socket in the fps might become a
3272 ++ * candidate for GC while the skb is not yet queued.
3273 ++ */
3274 ++ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
3275 ++ if (!UNIXCB(skb).fp)
3276 ++ return -ENOMEM;
3277 ++
3278 + for (i=scm->fp->count-1; i>=0; i--)
3279 + unix_inflight(scm->fp->fp[i]);
3280 +- UNIXCB(skb).fp = scm->fp;
3281 + skb->destructor = unix_destruct_fds;
3282 +- scm->fp = NULL;
3283 ++ return 0;
3284 + }
3285 +
3286 + /*
3287 +@@ -1368,8 +1377,11 @@ static int unix_dgram_sendmsg(struct kio
3288 + goto out;
3289 +
3290 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
3291 +- if (siocb->scm->fp)
3292 +- unix_attach_fds(siocb->scm, skb);
3293 ++ if (siocb->scm->fp) {
3294 ++ err = unix_attach_fds(siocb->scm, skb);
3295 ++ if (err)
3296 ++ goto out_free;
3297 ++ }
3298 + unix_get_secdata(siocb->scm, skb);
3299 +
3300 + skb_reset_transport_header(skb);
3301 +@@ -1538,8 +1550,13 @@ static int unix_stream_sendmsg(struct ki
3302 + size = min_t(int, size, skb_tailroom(skb));
3303 +
3304 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
3305 +- if (siocb->scm->fp)
3306 +- unix_attach_fds(siocb->scm, skb);
3307 ++ if (siocb->scm->fp) {
3308 ++ err = unix_attach_fds(siocb->scm, skb);
3309 ++ if (err) {
3310 ++ kfree_skb(skb);
3311 ++ goto out_err;
3312 ++ }
3313 ++ }
3314 +
3315 + if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
3316 + kfree_skb(skb);
3317 +--- a/net/unix/garbage.c
3318 ++++ b/net/unix/garbage.c
3319 +@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x
3320 + */
3321 + struct sock *sk = unix_get_socket(*fp++);
3322 + if (sk) {
3323 +- hit = true;
3324 +- func(unix_sk(sk));
3325 ++ struct unix_sock *u = unix_sk(sk);
3326 ++
3327 ++ /*
3328 ++ * Ignore non-candidates, they could
3329 ++ * have been added to the queues after
3330 ++ * starting the garbage collection
3331 ++ */
3332 ++ if (u->gc_candidate) {
3333 ++ hit = true;
3334 ++ func(u);
3335 ++ }
3336 + }
3337 + }
3338 + if (hit && hitlist != NULL) {
3339 +@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struc
3340 + {
3341 + atomic_inc(&u->inflight);
3342 + /*
3343 +- * If this is still a candidate, move it to the end of the
3344 +- * list, so that it's checked even if it was already passed
3345 +- * over
3346 ++ * If this still might be part of a cycle, move it to the end
3347 ++ * of the list, so that it's checked even if it was already
3348 ++ * passed over
3349 + */
3350 +- if (u->gc_candidate)
3351 ++ if (u->gc_maybe_cycle)
3352 + list_move_tail(&u->link, &gc_candidates);
3353 + }
3354 +
3355 +@@ -267,6 +276,7 @@ void unix_gc(void)
3356 + struct unix_sock *next;
3357 + struct sk_buff_head hitlist;
3358 + struct list_head cursor;
3359 ++ LIST_HEAD(not_cycle_list);
3360 +
3361 + spin_lock(&unix_gc_lock);
3362 +
3363 +@@ -282,10 +292,14 @@ void unix_gc(void)
3364 + *
3365 + * Holding unix_gc_lock will protect these candidates from
3366 + * being detached, and hence from gaining an external
3367 +- * reference. This also means, that since there are no
3368 +- * possible receivers, the receive queues of these sockets are
3369 +- * static during the GC, even though the dequeue is done
3370 +- * before the detach without atomicity guarantees.
3371 ++ * reference. Since there are no possible receivers, all
3372 ++ * buffers currently on the candidates' queues stay there
3373 ++ * during the garbage collection.
3374 ++ *
3375 ++ * We also know that no new candidate can be added onto the
3376 ++ * receive queues. Other, non candidate sockets _can_ be
3377 ++ * added to queue, so we must make sure only to touch
3378 ++ * candidates.
3379 + */
3380 + list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
3381 + int total_refs;
3382 +@@ -299,6 +313,7 @@ void unix_gc(void)
3383 + if (total_refs == inflight_refs) {
3384 + list_move_tail(&u->link, &gc_candidates);
3385 + u->gc_candidate = 1;
3386 ++ u->gc_maybe_cycle = 1;
3387 + }
3388 + }
3389 +
3390 +@@ -325,14 +340,24 @@ void unix_gc(void)
3391 + list_move(&cursor, &u->link);
3392 +
3393 + if (atomic_read(&u->inflight) > 0) {
3394 +- list_move_tail(&u->link, &gc_inflight_list);
3395 +- u->gc_candidate = 0;
3396 ++ list_move_tail(&u->link, &not_cycle_list);
3397 ++ u->gc_maybe_cycle = 0;
3398 + scan_children(&u->sk, inc_inflight_move_tail, NULL);
3399 + }
3400 + }
3401 + list_del(&cursor);
3402 +
3403 + /*
3404 ++ * not_cycle_list contains those sockets which do not make up a
3405 ++ * cycle. Restore these to the inflight list.
3406 ++ */
3407 ++ while (!list_empty(&not_cycle_list)) {
3408 ++ u = list_entry(not_cycle_list.next, struct unix_sock, link);
3409 ++ u->gc_candidate = 0;
3410 ++ list_move_tail(&u->link, &gc_inflight_list);
3411 ++ }
3412 ++
3413 ++ /*
3414 + * Now gc_candidates contains only garbage. Restore original
3415 + * inflight counters for these as well, and remove the skbuffs
3416 + * which are creating the cycle(s).
3417
3418 Added: hardened/2.6/tags/2.6.25-13/1413_block-fix-nr_phys_segments-miscalculation-bug.patch
3419 ===================================================================
3420 --- hardened/2.6/tags/2.6.25-13/1413_block-fix-nr_phys_segments-miscalculation-bug.patch (rev 0)
3421 +++ hardened/2.6/tags/2.6.25-13/1413_block-fix-nr_phys_segments-miscalculation-bug.patch 2009-01-20 21:27:53 UTC (rev 1478)
3422 @@ -0,0 +1,126 @@
3423 +Added-By: Gordon Malm <gengor@g.o>
3424 +
3425 +---
3426 +
3427 +From knikanth@××××.de Thu Nov 13 14:07:47 2008
3428 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3429 +Date: Wed, 12 Nov 2008 11:33:54 +0530
3430 +Subject: block: fix nr_phys_segments miscalculation bug
3431 +To: Greg KH <greg@×××××.com>
3432 +Cc: stable@××××××.org, FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3433 +Message-ID: <200811121133.55404.knikanth@××××.de>
3434 +Content-Disposition: inline
3435 +
3436 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3437 +
3438 +commit 8677142710516d986d932d6f1fba7be8382c1fec upstream
3439 +backported by Nikanth Karthikesan <knikanth@××××.de> to the 2.6.27.y tree.
3440 +
3441 +block: fix nr_phys_segments miscalculation bug
3442 +
3443 +This fixes the bug reported by Nikanth Karthikesan <knikanth@××××.de>:
3444 +
3445 +http://lkml.org/lkml/2008/10/2/203
3446 +
3447 +The root cause of the bug is that blk_phys_contig_segment
3448 +miscalculates q->max_segment_size.
3449 +
3450 +blk_phys_contig_segment checks:
3451 +
3452 +req->biotail->bi_size + next_req->bio->bi_size > q->max_segment_size
3453 +
3454 +But blk_recalc_rq_segments might expect that req->biotail and the
3455 +previous bio in the req are supposed be merged into one
3456 +segment. blk_recalc_rq_segments might also expect that next_req->bio
3457 +and the next bio in the next_req are supposed be merged into one
3458 +segment. In such case, we merge two requests that can't be merged
3459 +here. Later, blk_rq_map_sg gives more segments than it should.
3460 +
3461 +We need to keep track of segment size in blk_recalc_rq_segments and
3462 +use it to see if two requests can be merged. This patch implements it
3463 +in the similar way that we used to do for hw merging (virtual
3464 +merging).
3465 +
3466 +Signed-off-by: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3467 +Signed-off-by: Jens Axboe <jens.axboe@××××××.com>
3468 +Cc: Nikanth Karthikesan <knikanth@××××.de>
3469 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3470 +
3471 +---
3472 + block/blk-merge.c | 19 +++++++++++++++++--
3473 + include/linux/bio.h | 7 +++++++
3474 + 2 files changed, 24 insertions(+), 2 deletions(-)
3475 +
3476 +--- a/block/blk-merge.c
3477 ++++ b/block/blk-merge.c
3478 +@@ -95,6 +95,9 @@ new_hw_segment:
3479 + nr_hw_segs++;
3480 + }
3481 +
3482 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
3483 ++ rq->bio->bi_seg_front_size = seg_size;
3484 ++
3485 + nr_phys_segs++;
3486 + bvprv = bv;
3487 + seg_size = bv->bv_len;
3488 +@@ -106,6 +109,10 @@ new_hw_segment:
3489 + rq->bio->bi_hw_front_size = hw_seg_size;
3490 + if (hw_seg_size > rq->biotail->bi_hw_back_size)
3491 + rq->biotail->bi_hw_back_size = hw_seg_size;
3492 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
3493 ++ rq->bio->bi_seg_front_size = seg_size;
3494 ++ if (seg_size > rq->biotail->bi_seg_back_size)
3495 ++ rq->biotail->bi_seg_back_size = seg_size;
3496 + rq->nr_phys_segments = nr_phys_segs;
3497 + rq->nr_hw_segments = nr_hw_segs;
3498 + }
3499 +@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struc
3500 +
3501 + if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
3502 + return 0;
3503 +- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
3504 ++ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
3505 ++ q->max_segment_size)
3506 + return 0;
3507 +
3508 + /*
3509 +@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct r
3510 + {
3511 + int total_phys_segments;
3512 + int total_hw_segments;
3513 ++ unsigned int seg_size =
3514 ++ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
3515 +
3516 + /*
3517 + * First check if the either of the requests are re-queued
3518 +@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct r
3519 + return 0;
3520 +
3521 + total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
3522 +- if (blk_phys_contig_segment(q, req->biotail, next->bio))
3523 ++ if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
3524 ++ if (req->nr_phys_segments == 1)
3525 ++ req->bio->bi_seg_front_size = seg_size;
3526 ++ if (next->nr_phys_segments == 1)
3527 ++ next->biotail->bi_seg_back_size = seg_size;
3528 + total_phys_segments--;
3529 ++ }
3530 +
3531 + if (total_phys_segments > q->max_phys_segments)
3532 + return 0;
3533 +--- a/include/linux/bio.h
3534 ++++ b/include/linux/bio.h
3535 +@@ -98,6 +98,13 @@ struct bio {
3536 + unsigned int bi_size; /* residual I/O count */
3537 +
3538 + /*
3539 ++ * To keep track of the max segment size, we account for the
3540 ++ * sizes of the first and last mergeable segments in this bio.
3541 ++ */
3542 ++ unsigned int bi_seg_front_size;
3543 ++ unsigned int bi_seg_back_size;
3544 ++
3545 ++ /*
3546 + * To keep track of the max hw size, we account for the
3547 + * sizes of the first and last virtually mergeable segments
3548 + * in this bio
3549
3550 Added: hardened/2.6/tags/2.6.25-13/1414_dm-raid1-flush-workqueue-before-destruction.patch
3551 ===================================================================
3552 --- hardened/2.6/tags/2.6.25-13/1414_dm-raid1-flush-workqueue-before-destruction.patch (rev 0)
3553 +++ hardened/2.6/tags/2.6.25-13/1414_dm-raid1-flush-workqueue-before-destruction.patch 2009-01-20 21:27:53 UTC (rev 1478)
3554 @@ -0,0 +1,36 @@
3555 +Added-By: Gordon Malm <gengor@g.o>
3556 +
3557 +Note: Backported to 2.6.25. Original message included below.
3558 +
3559 +---
3560 +
3561 +From 18776c7316545482a02bfaa2629a2aa1afc48357 Mon Sep 17 00:00:00 2001
3562 +From: Mikulas Patocka <mpatocka@××××××.com>
3563 +Date: Thu, 13 Nov 2008 23:38:52 +0000
3564 +Subject: dm raid1: flush workqueue before destruction
3565 +
3566 +From: Mikulas Patocka <mpatocka@××××××.com>
3567 +
3568 +commit 18776c7316545482a02bfaa2629a2aa1afc48357 upstream.
3569 +
3570 +We queue work on keventd queue --- so this queue must be flushed in the
3571 +destructor. Otherwise, keventd could access mirror_set after it was freed.
3572 +
3573 +Signed-off-by: Mikulas Patocka <mpatocka@××××××.com>
3574 +Signed-off-by: Alasdair G Kergon <agk@××××××.com>
3575 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3576 +
3577 +---
3578 + drivers/md/dm-raid1.c | 1 +
3579 + 1 file changed, 1 insertion(+)
3580 +
3581 +--- a/drivers/md/dm-raid1.c
3582 ++++ b/drivers/md/dm-raid1.c
3583 +@@ -1590,6 +1590,7 @@ static void mirror_dtr(struct dm_target
3584 + struct mirror_set *ms = (struct mirror_set *) ti->private;
3585 +
3586 + flush_workqueue(ms->kmirrord_wq);
3587 ++ flush_scheduled_work();
3588 + kcopyd_client_destroy(ms->kcopyd_client);
3589 + destroy_workqueue(ms->kmirrord_wq);
3590 + free_context(ms, ti, ms->nr_mirrors);
3591
3592 Added: hardened/2.6/tags/2.6.25-13/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch
3593 ===================================================================
3594 --- hardened/2.6/tags/2.6.25-13/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch (rev 0)
3595 +++ hardened/2.6/tags/2.6.25-13/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch 2009-01-20 21:27:53 UTC (rev 1478)
3596 @@ -0,0 +1,104 @@
3597 +Added-By: Gordon Malm <gengor@g.o>
3598 +
3599 +Note: Backported to earlier kernels. Original message included below.
3600 +
3601 +---
3602 +
3603 +From b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 Mon Sep 17 00:00:00 2001
3604 +From: Eric Dumazet <dada1@×××××××××.com>
3605 +Date: Mon, 10 Nov 2008 21:43:08 -0800
3606 +Subject: net: fix /proc/net/snmp as memory corruptor
3607 +
3608 +From: Eric Dumazet <dada1@×××××××××.com>
3609 +
3610 +commit b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 upstream.
3611 +
3612 +icmpmsg_put() can happily corrupt kernel memory, using a static
3613 +table and forgetting to reset an array index in a loop.
3614 +
3615 +Remove the static array since its not safe without proper locking.
3616 +
3617 +Signed-off-by: Alexey Dobriyan <adobriyan@×××××.com>
3618 +Signed-off-by: Eric Dumazet <dada1@×××××××××.com>
3619 +Signed-off-by: David S. Miller <davem@×××××××××.net>
3620 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3621 +
3622 +---
3623 + net/ipv4/proc.c | 58 ++++++++++++++++++++++++++++----------------------------
3624 + 1 file changed, 30 insertions(+), 28 deletions(-)
3625 +
3626 +--- a/net/ipv4/proc.c
3627 ++++ b/net/ipv4/proc.c
3628 +@@ -262,42 +262,44 @@ static const struct snmp_mib snmp4_net_l
3629 + SNMP_MIB_SENTINEL
3630 + };
3631 +
3632 +-static void icmpmsg_put(struct seq_file *seq)
3633 ++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
3634 ++ unsigned short *type, int count)
3635 + {
3636 +-#define PERLINE 16
3637 +-
3638 +- int j, i, count;
3639 +- static int out[PERLINE];
3640 +-
3641 +- count = 0;
3642 +- for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
3643 +-
3644 +- if (snmp_fold_field((void **) icmpmsg_statistics, i))
3645 +- out[count++] = i;
3646 +- if (count < PERLINE)
3647 +- continue;
3648 ++ int j;
3649 +
3650 +- seq_printf(seq, "\nIcmpMsg:");
3651 +- for (j = 0; j < PERLINE; ++j)
3652 +- seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In",
3653 +- i & 0xff);
3654 +- seq_printf(seq, "\nIcmpMsg: ");
3655 +- for (j = 0; j < PERLINE; ++j)
3656 +- seq_printf(seq, " %lu",
3657 +- snmp_fold_field((void **) icmpmsg_statistics,
3658 +- out[j]));
3659 +- seq_putc(seq, '\n');
3660 +- }
3661 + if (count) {
3662 + seq_printf(seq, "\nIcmpMsg:");
3663 + for (j = 0; j < count; ++j)
3664 +- seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" :
3665 +- "In", out[j] & 0xff);
3666 ++ seq_printf(seq, " %sType%u",
3667 ++ type[j] & 0x100 ? "Out" : "In",
3668 ++ type[j] & 0xff);
3669 + seq_printf(seq, "\nIcmpMsg:");
3670 + for (j = 0; j < count; ++j)
3671 +- seq_printf(seq, " %lu", snmp_fold_field((void **)
3672 +- icmpmsg_statistics, out[j]));
3673 ++ seq_printf(seq, " %lu", vals[j]);
3674 ++ }
3675 ++}
3676 ++
3677 ++static void icmpmsg_put(struct seq_file *seq)
3678 ++{
3679 ++#define PERLINE 16
3680 ++
3681 ++ int i, count;
3682 ++ unsigned short type[PERLINE];
3683 ++ unsigned long vals[PERLINE], val;
3684 ++
3685 ++ count = 0;
3686 ++ for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
3687 ++ val = snmp_fold_field((void **) icmpmsg_statistics, i);
3688 ++ if (val) {
3689 ++ type[count] = i;
3690 ++ vals[count++] = val;
3691 ++ }
3692 ++ if (count == PERLINE) {
3693 ++ icmpmsg_put_line(seq, vals, type, count);
3694 ++ count = 0;
3695 ++ }
3696 + }
3697 ++ icmpmsg_put_line(seq, vals, type, count);
3698 +
3699 + #undef PERLINE
3700 + }
3701
3702 Added: hardened/2.6/tags/2.6.25-13/1416_touch_mnt_namespace-when-the-mount-flags-change.patch
3703 ===================================================================
3704 --- hardened/2.6/tags/2.6.25-13/1416_touch_mnt_namespace-when-the-mount-flags-change.patch (rev 0)
3705 +++ hardened/2.6/tags/2.6.25-13/1416_touch_mnt_namespace-when-the-mount-flags-change.patch 2009-01-20 21:27:53 UTC (rev 1478)
3706 @@ -0,0 +1,43 @@
3707 +Added-By: Gordon Malm <gengor@g.o>
3708 +
3709 +---
3710 +
3711 +From 0e55a7cca4b66f625d67b292f80b6a976e77c51b Mon Sep 17 00:00:00 2001
3712 +From: Dan Williams <dan.j.williams@×××××.com>
3713 +Date: Fri, 26 Sep 2008 19:01:20 -0700
3714 +Subject: touch_mnt_namespace when the mount flags change
3715 +
3716 +From: Dan Williams <dan.j.williams@×××××.com>
3717 +
3718 +commit 0e55a7cca4b66f625d67b292f80b6a976e77c51b upstream
3719 +
3720 +Daemons that need to be launched while the rootfs is read-only can now
3721 +poll /proc/mounts to be notified when their O_RDWR requests may no
3722 +longer end in EROFS.
3723 +
3724 +Cc: Kay Sievers <kay.sievers@××××.org>
3725 +Cc: Neil Brown <neilb@××××.de>
3726 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
3727 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3728 +
3729 +---
3730 + fs/namespace.c | 7 ++++++-
3731 + 1 file changed, 6 insertions(+), 1 deletion(-)
3732 +
3733 +--- a/fs/namespace.c
3734 ++++ b/fs/namespace.c
3735 +@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct na
3736 + if (!err)
3737 + nd->path.mnt->mnt_flags = mnt_flags;
3738 + up_write(&sb->s_umount);
3739 +- if (!err)
3740 ++ if (!err) {
3741 + security_sb_post_remount(nd->path.mnt, flags, data);
3742 ++
3743 ++ spin_lock(&vfsmount_lock);
3744 ++ touch_mnt_namespace(nd->path.mnt->mnt_ns);
3745 ++ spin_unlock(&vfsmount_lock);
3746 ++ }
3747 + return err;
3748 + }
3749 +
3750
3751 Added: hardened/2.6/tags/2.6.25-13/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch
3752 ===================================================================
3753 --- hardened/2.6/tags/2.6.25-13/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch (rev 0)
3754 +++ hardened/2.6/tags/2.6.25-13/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch 2009-01-20 21:27:53 UTC (rev 1478)
3755 @@ -0,0 +1,54 @@
3756 +Added-By: Gordon Malm <gengor@g.o>
3757 +
3758 +---
3759 +
3760 +From: David Brownell <david-b@×××××××.net>
3761 +Date: Thu, 6 Mar 2008 07:37:52 +0000 (-0800)
3762 +Subject: USB: ehci: remove obsolete workaround for bogus IRQs
3763 +X-Git-Tag: v2.6.26-rc1~1061^2~74
3764 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=d1b1842c393cf322712b669ec887397b89ed2312
3765 +
3766 +USB: ehci: remove obsolete workaround for bogus IRQs
3767 +
3768 +It was pointed out that we found and fixed the cause of the "bogus"
3769 +fatal IRQ reports some time ago ... this patch removes the code
3770 +which was working around that bug ("status" got clobbered), and a
3771 +comment which needlessly confused folk reading this code.
3772 +
3773 +This also includes a minor cleanup to the code which fixed that bug.
3774 +
3775 +Signed-off-by: David Brownell <dbrownell@×××××××××××××××××.net>
3776 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3777 +---
3778 +
3779 +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
3780 +index 40f7391..8c3e860 100644
3781 +--- a/drivers/usb/host/ehci-hcd.c
3782 ++++ b/drivers/usb/host/ehci-hcd.c
3783 +@@ -686,6 +686,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
3784 + /* remote wakeup [4.3.1] */
3785 + if (status & STS_PCD) {
3786 + unsigned i = HCS_N_PORTS (ehci->hcs_params);
3787 ++
3788 ++ /* kick root hub later */
3789 + pcd_status = status;
3790 +
3791 + /* resume root hub? */
3792 +@@ -714,8 +716,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
3793 +
3794 + /* PCI errors [4.15.2.4] */
3795 + if (unlikely ((status & STS_FATAL) != 0)) {
3796 +- /* bogus "fatal" IRQs appear on some chips... why? */
3797 +- status = ehci_readl(ehci, &ehci->regs->status);
3798 + dbg_cmd (ehci, "fatal", ehci_readl(ehci,
3799 + &ehci->regs->command));
3800 + dbg_status (ehci, "fatal", status);
3801 +@@ -734,7 +734,7 @@ dead:
3802 + if (bh)
3803 + ehci_work (ehci);
3804 + spin_unlock (&ehci->lock);
3805 +- if (pcd_status & STS_PCD)
3806 ++ if (pcd_status)
3807 + usb_hcd_poll_rh_status(hcd);
3808 + return IRQ_HANDLED;
3809 + }
3810
3811 Added: hardened/2.6/tags/2.6.25-13/1418_usb-ehci-fix-handling-of-dead-controllers.patch
3812 ===================================================================
3813 --- hardened/2.6/tags/2.6.25-13/1418_usb-ehci-fix-handling-of-dead-controllers.patch (rev 0)
3814 +++ hardened/2.6/tags/2.6.25-13/1418_usb-ehci-fix-handling-of-dead-controllers.patch 2009-01-20 21:27:53 UTC (rev 1478)
3815 @@ -0,0 +1,93 @@
3816 +Added-By: Gordon Malm <gengor@g.o>
3817 +
3818 +---
3819 +
3820 +From 67b2e029743a52670d77864723b4d0d40f7733b5 Mon Sep 17 00:00:00 2001
3821 +From: Alan Stern <stern@×××××××××××××××.edu>
3822 +Date: Wed, 12 Nov 2008 17:04:53 -0500
3823 +Subject: USB: EHCI: fix handling of dead controllers
3824 +
3825 +From: Alan Stern <stern@×××××××××××××××.edu>
3826 +
3827 +commit 67b2e029743a52670d77864723b4d0d40f7733b5 upstream.
3828 +
3829 +This patch (as1165) makes a few small changes in the logic used by
3830 +ehci-hcd when it encounters a controller error:
3831 +
3832 + Instead of printing out the masked status, it prints the
3833 + original status as read directly from the hardware.
3834 +
3835 + It doesn't check for the STS_HALT status bit before taking
3836 + action. The mere fact that the STS_FATAL bit is set means
3837 + that something bad has happened and the controller needs to
3838 + be reset. With the old code this test could never succeed
3839 + because the STS_HALT bit was masked out from the status.
3840 +
3841 +I anticipate that this will prevent the occasional "irq X: nobody cared"
3842 +problem people encounter when their EHCI controllers die.
3843 +
3844 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
3845 +Cc: David Brownell <david-b@×××××××.net>
3846 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3847 +
3848 +---
3849 + drivers/usb/host/ehci-hcd.c | 25 ++++++++++++-------------
3850 + 1 file changed, 12 insertions(+), 13 deletions(-)
3851 +
3852 +--- a/drivers/usb/host/ehci-hcd.c
3853 ++++ b/drivers/usb/host/ehci-hcd.c
3854 +@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd
3855 + static irqreturn_t ehci_irq (struct usb_hcd *hcd)
3856 + {
3857 + struct ehci_hcd *ehci = hcd_to_ehci (hcd);
3858 +- u32 status, pcd_status = 0, cmd;
3859 ++ u32 status, masked_status, pcd_status = 0, cmd;
3860 + int bh;
3861 +
3862 + spin_lock (&ehci->lock);
3863 +@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_
3864 + goto dead;
3865 + }
3866 +
3867 +- status &= INTR_MASK;
3868 +- if (!status) { /* irq sharing? */
3869 ++ masked_status = status & INTR_MASK;
3870 ++ if (!masked_status) { /* irq sharing? */
3871 + spin_unlock(&ehci->lock);
3872 + return IRQ_NONE;
3873 + }
3874 +
3875 + /* clear (just) interrupts */
3876 +- ehci_writel(ehci, status, &ehci->regs->status);
3877 ++ ehci_writel(ehci, masked_status, &ehci->regs->status);
3878 + cmd = ehci_readl(ehci, &ehci->regs->command);
3879 + bh = 0;
3880 +
3881 +@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_
3882 +
3883 + /* PCI errors [4.15.2.4] */
3884 + if (unlikely ((status & STS_FATAL) != 0)) {
3885 ++ ehci_err(ehci, "fatal error\n");
3886 + dbg_cmd (ehci, "fatal", ehci_readl(ehci,
3887 + &ehci->regs->command));
3888 + dbg_status (ehci, "fatal", status);
3889 +- if (status & STS_HALT) {
3890 +- ehci_err (ehci, "fatal error\n");
3891 ++ ehci_halt(ehci);
3892 + dead:
3893 +- ehci_reset (ehci);
3894 +- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
3895 +- /* generic layer kills/unlinks all urbs, then
3896 +- * uses ehci_stop to clean up the rest
3897 +- */
3898 +- bh = 1;
3899 +- }
3900 ++ ehci_reset(ehci);
3901 ++ ehci_writel(ehci, 0, &ehci->regs->configured_flag);
3902 ++ /* generic layer kills/unlinks all urbs, then
3903 ++ * uses ehci_stop to clean up the rest
3904 ++ */
3905 ++ bh = 1;
3906 + }
3907 +
3908 + if (bh)
3909
3910 Added: hardened/2.6/tags/2.6.25-13/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
3911 ===================================================================
3912 --- hardened/2.6/tags/2.6.25-13/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch (rev 0)
3913 +++ hardened/2.6/tags/2.6.25-13/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch 2009-01-20 21:27:53 UTC (rev 1478)
3914 @@ -0,0 +1,75 @@
3915 +Added-By: Gordon Malm <gengor@g.o>
3916 +
3917 +Note: Backported to kernel 2.6.25. Original message included below.
3918 +
3919 +---
3920 +
3921 +From 352d026338378b1f13f044e33c1047da6e470056 Mon Sep 17 00:00:00 2001
3922 +From: Alan Stern <stern@×××××××××××××××.edu>
3923 +Date: Wed, 29 Oct 2008 15:16:58 -0400
3924 +Subject: USB: don't register endpoints for interfaces that are going away
3925 +
3926 +From: Alan Stern <stern@×××××××××××××××.edu>
3927 +
3928 +commit 352d026338378b1f13f044e33c1047da6e470056 upstream.
3929 +
3930 +This patch (as1155) fixes a bug in usbcore. When interfaces are
3931 +deleted, either because the device was disconnected or because of a
3932 +configuration change, the extra attribute files and child endpoint
3933 +devices may get left behind. This is because the core removes them
3934 +before calling device_del(). But during device_del(), after the
3935 +driver is unbound the core will reinstall altsetting 0 and recreate
3936 +those extra attributes and children.
3937 +
3938 +The patch prevents this by adding a flag to record when the interface
3939 +is in the midst of being unregistered. When the flag is set, the
3940 +attribute files and child devices will not be created.
3941 +
3942 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
3943 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3944 +
3945 +---
3946 + drivers/usb/core/message.c | 1 +
3947 + drivers/usb/core/sysfs.c | 2 +-
3948 + include/linux/usb.h | 2 ++
3949 + 3 files changed, 4 insertions(+), 1 deletion(-)
3950 +
3951 +--- a/drivers/usb/core/message.c
3952 ++++ b/drivers/usb/core/message.c
3953 +@@ -1089,6 +1089,7 @@ void usb_disable_device(struct usb_devic
3954 + continue;
3955 + dev_dbg(&dev->dev, "unregistering interface %s\n",
3956 + interface->dev.bus_id);
3957 ++ interface->unregistering = 1;
3958 + usb_remove_sysfs_intf_files(interface);
3959 + device_del(&interface->dev);
3960 + }
3961 +--- a/drivers/usb/core/sysfs.c
3962 ++++ b/drivers/usb/core/sysfs.c
3963 +@@ -784,7 +784,7 @@ int usb_create_sysfs_intf_files(struct u
3964 + struct usb_host_interface *alt = intf->cur_altsetting;
3965 + int retval;
3966 +
3967 +- if (intf->sysfs_files_created)
3968 ++ if (intf->sysfs_files_created || intf->unregistering)
3969 + return 0;
3970 + retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
3971 + if (retval)
3972 +--- a/include/linux/usb.h
3973 ++++ b/include/linux/usb.h
3974 +@@ -107,6 +107,7 @@ enum usb_interface_condition {
3975 + * (in probe()), bound to a driver, or unbinding (in disconnect())
3976 + * @is_active: flag set when the interface is bound and not suspended.
3977 + * @sysfs_files_created: sysfs attributes exist
3978 ++ * @unregistering: flag set when the interface is being unregistered
3979 + * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
3980 + * capability during autosuspend.
3981 + * @dev: driver model's view of this device
3982 +@@ -158,6 +159,7 @@ struct usb_interface {
3983 + enum usb_interface_condition condition; /* state of binding */
3984 + unsigned is_active:1; /* the interface is not suspended */
3985 + unsigned sysfs_files_created:1; /* the sysfs attributes exist */
3986 ++ unsigned unregistering:1; /* unregistration is in progress */
3987 + unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
3988 +
3989 + struct device dev; /* interface specific device info */
3990
3991 Added: hardened/2.6/tags/2.6.25-13/1420_usb-ehci-fix-divide-by-zero-bug.patch
3992 ===================================================================
3993 --- hardened/2.6/tags/2.6.25-13/1420_usb-ehci-fix-divide-by-zero-bug.patch (rev 0)
3994 +++ hardened/2.6/tags/2.6.25-13/1420_usb-ehci-fix-divide-by-zero-bug.patch 2009-01-20 21:27:53 UTC (rev 1478)
3995 @@ -0,0 +1,46 @@
3996 +Added-By: Gordon Malm <gengor@g.o>
3997 +
3998 +---
3999 +
4000 +From 372dd6e8ed924e876f3beb598721e813ad7fa323 Mon Sep 17 00:00:00 2001
4001 +From: Alan Stern <stern@×××××××××××××××.edu>
4002 +Date: Wed, 12 Nov 2008 17:02:57 -0500
4003 +Subject: USB: EHCI: fix divide-by-zero bug
4004 +
4005 +From: Alan Stern <stern@×××××××××××××××.edu>
4006 +
4007 +commit 372dd6e8ed924e876f3beb598721e813ad7fa323 upstream.
4008 +
4009 +This patch (as1164) fixes a bug in the EHCI scheduler. The interval
4010 +value it uses is already in linear format, not logarithmically coded.
4011 +The existing code can sometimes crash the system by trying to divide
4012 +by zero.
4013 +
4014 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
4015 +Cc: David Brownell <david-b@×××××××.net>
4016 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4017 +
4018 +---
4019 + drivers/usb/host/ehci-sched.c | 4 ++--
4020 + 1 file changed, 2 insertions(+), 2 deletions(-)
4021 +
4022 +--- a/drivers/usb/host/ehci-sched.c
4023 ++++ b/drivers/usb/host/ehci-sched.c
4024 +@@ -918,7 +918,7 @@ iso_stream_init (
4025 + */
4026 + stream->usecs = HS_USECS_ISO (maxp);
4027 + bandwidth = stream->usecs * 8;
4028 +- bandwidth /= 1 << (interval - 1);
4029 ++ bandwidth /= interval;
4030 +
4031 + } else {
4032 + u32 addr;
4033 +@@ -951,7 +951,7 @@ iso_stream_init (
4034 + } else
4035 + stream->raw_mask = smask_out [hs_transfers - 1];
4036 + bandwidth = stream->usecs + stream->c_usecs;
4037 +- bandwidth /= 1 << (interval + 2);
4038 ++ bandwidth /= interval << 3;
4039 +
4040 + /* stream->splits gets created from raw_mask later */
4041 + stream->address = cpu_to_hc32(ehci, addr);
4042
4043 Added: hardened/2.6/tags/2.6.25-13/1421_usb-fix-ps3-usb-shutdown-problems.patch
4044 ===================================================================
4045 --- hardened/2.6/tags/2.6.25-13/1421_usb-fix-ps3-usb-shutdown-problems.patch (rev 0)
4046 +++ hardened/2.6/tags/2.6.25-13/1421_usb-fix-ps3-usb-shutdown-problems.patch 2009-01-20 21:27:53 UTC (rev 1478)
4047 @@ -0,0 +1,64 @@
4048 +Added-By: Gordon Malm <gengor@g.o>
4049 +
4050 +---
4051 +
4052 +From ddcb01ff9bf49c4dbbb058423559f7bc90b89374 Mon Sep 17 00:00:00 2001
4053 +From: Geoff Levand <geoffrey.levand@×××××××.com>
4054 +Date: Fri, 31 Oct 2008 13:52:54 -0700
4055 +Subject: USB: Fix PS3 USB shutdown problems
4056 +
4057 +From: Geoff Levand <geoffrey.levand@×××××××.com>
4058 +
4059 +commit ddcb01ff9bf49c4dbbb058423559f7bc90b89374 upstream.
4060 +
4061 +Add ehci_shutdown() or ohci_shutdown() calls to the USB
4062 +PS3 bus glue. ehci_shutdown() and ohci_shutdown() do some
4063 +controller specific cleanups not done by usb_remove_hcd().
4064 +
4065 +Fixes errors on shutdown or reboot similar to these:
4066 +
4067 + ps3-ehci-driver sb_07: HC died; cleaning up
4068 + irq 51: nobody cared (try booting with the "irqpoll" option)
4069 +
4070 +Related bugzilla reports:
4071 +
4072 + http://bugzilla.kernel.org/show_bug.cgi?id=11819
4073 + http://bugzilla.terrasoftsolutions.com/show_bug.cgi?id=317
4074 +
4075 +Signed-off-by: Geoff Levand <geoffrey.levand@×××××××.com>
4076 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4077 +
4078 +---
4079 + drivers/usb/host/ehci-ps3.c | 1 +
4080 + drivers/usb/host/ohci-ps3.c | 3 ++-
4081 + 2 files changed, 3 insertions(+), 1 deletion(-)
4082 +
4083 +--- a/drivers/usb/host/ehci-ps3.c
4084 ++++ b/drivers/usb/host/ehci-ps3.c
4085 +@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_sy
4086 +
4087 + tmp = hcd->irq;
4088 +
4089 ++ ehci_shutdown(hcd);
4090 + usb_remove_hcd(hcd);
4091 +
4092 + ps3_system_bus_set_driver_data(dev, NULL);
4093 +--- a/drivers/usb/host/ohci-ps3.c
4094 ++++ b/drivers/usb/host/ohci-ps3.c
4095 +@@ -192,7 +192,7 @@ fail_start:
4096 + return result;
4097 + }
4098 +
4099 +-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
4100 ++static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
4101 + {
4102 + unsigned int tmp;
4103 + struct usb_hcd *hcd =
4104 +@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_s
4105 +
4106 + tmp = hcd->irq;
4107 +
4108 ++ ohci_shutdown(hcd);
4109 + usb_remove_hcd(hcd);
4110 +
4111 + ps3_system_bus_set_driver_data(dev, NULL);
4112
4113 Added: hardened/2.6/tags/2.6.25-13/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
4114 ===================================================================
4115 --- hardened/2.6/tags/2.6.25-13/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch (rev 0)
4116 +++ hardened/2.6/tags/2.6.25-13/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch 2009-01-20 21:27:53 UTC (rev 1478)
4117 @@ -0,0 +1,135 @@
4118 +Added-By: Gordon Malm <gengor@g.o>
4119 +
4120 +---
4121 +
4122 +From 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 Mon Sep 17 00:00:00 2001
4123 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
4124 +Date: Fri, 14 Nov 2008 10:46:59 -0300
4125 +Subject: V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble
4126 +
4127 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
4128 +
4129 +commit 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 upstream.
4130 +
4131 +This bug were supposed to be fixed by 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1,
4132 +where a call to NULL happens.
4133 +
4134 +Not all tvaudio chips allow controlling bass/treble. So, the driver
4135 +has a table with a flag to indicate if the chip does support it.
4136 +
4137 +Unfortunately, the handling of this logic were broken for a very long
4138 +time (probably since the first module version). Due to that, an OOPS
4139 +were generated for devices that don't support bass/treble.
4140 +
4141 +This were the resulting OOPS message before the patch, with debug messages
4142 +enabled:
4143 +
4144 +tvaudio' 1-005b: VIDIOC_S_CTRL
4145 +BUG: unable to handle kernel NULL pointer dereference at 00000000
4146 +IP: [<00000000>]
4147 +*pde = 22fda067 *pte = 00000000
4148 +Oops: 0000 [#1] SMP
4149 +Modules linked in: snd_hda_intel snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
4150 +snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_hwdep snd soundcore tuner_simple tuner_types tea5767 tuner
4151 +tvaudio bttv bridgebnep rfcomm l2cap bluetooth it87 hwmon_vid hwmon fuse sunrpc ipt_REJECT
4152 +nf_conntrack_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack
4153 +ip6table_filter ip6_tables x_tables ipv6 dm_mirrordm_multipath dm_mod configfs videodev v4l1_compat
4154 +ir_common 8139cp compat_ioctl32 v4l2_common 8139too videobuf_dma_sg videobuf_core mii btcx_risc tveeprom
4155 +i915 button snd_page_alloc serio_raw drm pcspkr i2c_algo_bit i2c_i801 i2c_core iTCO_wdt
4156 +iTCO_vendor_support sr_mod cdrom sg ata_generic pata_acpi ata_piix libata sd_mod scsi_mod ext3 jbdmbcache
4157 +uhci_hcd ohci_hcd ehci_hcd [last unloaded: soundcore]
4158 +
4159 +Pid: 15413, comm: qv4l2 Not tainted (2.6.25.14-108.fc9.i686 #1)
4160 +EIP: 0060:[<00000000>] EFLAGS: 00210246 CPU: 0
4161 +EIP is at 0x0
4162 +EAX: 00008000 EBX: ebd21600 ECX: e2fd9ec4 EDX: 00200046
4163 +ESI: f8c0f0c4 EDI: f8c0f0c4 EBP: e2fd9d50 ESP: e2fd9d2c
4164 + DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
4165 +Process qv4l2 (pid: 15413, ti=e2fd9000 task=ebe44000 task.ti=e2fd9000)
4166 +Stack: f8c0c6ae e2ff2a00 00000d00 e2fd9ec4 ebc4e000 e2fd9d5c f8c0c448 00000000
4167 + f899c12a e2fd9d5c f899c154 e2fd9d68 e2fd9d80 c0560185 e2fd9d88 f8f3e1d8
4168 + f8f3e1dc ebc4e034 f8f3e18c e2fd9ec4 00000000 e2fd9d90 f899c286 c008561c
4169 +Call Trace:
4170 + [<f8c0c6ae>] ? chip_command+0x266/0x4b6 [tvaudio]
4171 + [<f8c0c448>] ? chip_command+0x0/0x4b6 [tvaudio]
4172 + [<f899c12a>] ? i2c_cmd+0x0/0x2f [i2c_core]
4173 + [<f899c154>] ? i2c_cmd+0x2a/0x2f [i2c_core]
4174 + [<c0560185>] ? device_for_each_child+0x21/0x49
4175 + [<f899c286>] ? i2c_clients_command+0x1c/0x1e [i2c_core]
4176 + [<f8f283d8>] ? bttv_call_i2c_clients+0x14/0x16 [bttv]
4177 + [<f8f23601>] ? bttv_s_ctrl+0x1bc/0x313 [bttv]
4178 + [<f8f23445>] ? bttv_s_ctrl+0x0/0x313 [bttv]
4179 + [<f8b6096d>] ? __video_do_ioctl+0x1f84/0x3726 [videodev]
4180 + [<c05abb4e>] ? sock_aio_write+0x100/0x10d
4181 + [<c041b23e>] ? kmap_atomic_prot+0x1dd/0x1df
4182 + [<c043a0c9>] ? enqueue_hrtimer+0xc2/0xcd
4183 + [<c04f4fa4>] ? copy_from_user+0x39/0x121
4184 + [<f8b622b9>] ? __video_ioctl2+0x1aa/0x24a [videodev]
4185 + [<c04054fd>] ? do_notify_resume+0x768/0x795
4186 + [<c043c0f7>] ? getnstimeofday+0x34/0xd1
4187 + [<c0437b77>] ? autoremove_wake_function+0x0/0x33
4188 + [<f8b62368>] ? video_ioctl2+0xf/0x13 [videodev]
4189 + [<c048c6f0>] ? vfs_ioctl+0x50/0x69
4190 + [<c048c942>] ? do_vfs_ioctl+0x239/0x24c
4191 + [<c048c995>] ? sys_ioctl+0x40/0x5b
4192 + [<c0405bf2>] ? syscall_call+0x7/0xb
4193 + [<c0620000>] ? cpuid4_cache_sysfs_exit+0x3d/0x69
4194 + =======================
4195 +Code: Bad EIP value.
4196 +EIP: [<00000000>] 0x0 SS:ESP 0068:e2fd9d2c
4197 +
4198 +Signed-off-by: Mauro Carvalho Chehab <mchehab@××××××.com>
4199 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4200 +
4201 +---
4202 + drivers/media/video/tvaudio.c | 15 +++++++--------
4203 + 1 file changed, 7 insertions(+), 8 deletions(-)
4204 +
4205 +--- a/drivers/media/video/tvaudio.c
4206 ++++ b/drivers/media/video/tvaudio.c
4207 +@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPS
4208 + return 0;
4209 + }
4210 + case V4L2_CID_AUDIO_BASS:
4211 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4212 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4213 + break;
4214 + ctrl->value = chip->bass;
4215 + return 0;
4216 + case V4L2_CID_AUDIO_TREBLE:
4217 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4218 +- return -EINVAL;
4219 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4220 ++ break;
4221 + ctrl->value = chip->treble;
4222 + return 0;
4223 + }
4224 +@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPS
4225 + return 0;
4226 + }
4227 + case V4L2_CID_AUDIO_BASS:
4228 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4229 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4230 + break;
4231 + chip->bass = ctrl->value;
4232 + chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
4233 +
4234 + return 0;
4235 + case V4L2_CID_AUDIO_TREBLE:
4236 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4237 +- return -EINVAL;
4238 +-
4239 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4240 ++ break;
4241 + chip->treble = ctrl->value;
4242 + chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
4243 +
4244 +@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_clien
4245 + break;
4246 + case V4L2_CID_AUDIO_BASS:
4247 + case V4L2_CID_AUDIO_TREBLE:
4248 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4249 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4250 + return -EINVAL;
4251 + break;
4252 + default:
4253
4254 Added: hardened/2.6/tags/2.6.25-13/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch
4255 ===================================================================
4256 --- hardened/2.6/tags/2.6.25-13/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch (rev 0)
4257 +++ hardened/2.6/tags/2.6.25-13/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch 2009-01-20 21:27:53 UTC (rev 1478)
4258 @@ -0,0 +1,105 @@
4259 +Added-By: Gordon Malm <gengor@g.o>
4260 +
4261 +---
4262 +
4263 +From 5f23b734963ec7eaa3ebcd9050da0c9b7d143dd3 Mon Sep 17 00:00:00 2001
4264 +From: dann frazier <dannf@××.com>
4265 +Date: Wed, 26 Nov 2008 15:32:27 -0800
4266 +Subject: net: Fix soft lockups/OOM issues w/ unix garbage collector (CVE-2008-5300)
4267 +
4268 +From: dann frazier <dannf@××.com>
4269 +
4270 +commit 5f23b734963ec7eaa3ebcd9050da0c9b7d143dd3 upstream.
4271 +
4272 +This is an implementation of David Miller's suggested fix in:
4273 + https://bugzilla.redhat.com/show_bug.cgi?id=470201
4274 +
4275 +It has been updated to use wait_event() instead of
4276 +wait_event_interruptible().
4277 +
4278 +Paraphrasing the description from the above report, it makes sendmsg()
4279 +block while UNIX garbage collection is in progress. This avoids a
4280 +situation where child processes continue to queue new FDs over a
4281 +AF_UNIX socket to a parent which is in the exit path and running
4282 +garbage collection on these FDs. This contention can result in soft
4283 +lockups and oom-killing of unrelated processes.
4284 +
4285 +Signed-off-by: dann frazier <dannf@××.com>
4286 +Signed-off-by: David S. Miller <davem@×××××××××.net>
4287 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4288 +---
4289 +
4290 +--- a/include/net/af_unix.h
4291 ++++ b/include/net/af_unix.h
4292 +@@ -9,6 +9,7 @@
4293 + extern void unix_inflight(struct file *fp);
4294 + extern void unix_notinflight(struct file *fp);
4295 + extern void unix_gc(void);
4296 ++extern void wait_for_unix_gc(void);
4297 +
4298 + #define UNIX_HASH_SIZE 256
4299 +
4300 +--- a/net/unix/af_unix.c
4301 ++++ b/net/unix/af_unix.c
4302 +@@ -1341,6 +1341,7 @@ static int unix_dgram_sendmsg(struct kio
4303 +
4304 + if (NULL == siocb->scm)
4305 + siocb->scm = &tmp_scm;
4306 ++ wait_for_unix_gc();
4307 + err = scm_send(sock, msg, siocb->scm);
4308 + if (err < 0)
4309 + return err;
4310 +@@ -1491,6 +1492,7 @@ static int unix_stream_sendmsg(struct ki
4311 +
4312 + if (NULL == siocb->scm)
4313 + siocb->scm = &tmp_scm;
4314 ++ wait_for_unix_gc();
4315 + err = scm_send(sock, msg, siocb->scm);
4316 + if (err < 0)
4317 + return err;
4318 +--- a/net/unix/garbage.c
4319 ++++ b/net/unix/garbage.c
4320 +@@ -80,6 +80,7 @@
4321 + #include <linux/file.h>
4322 + #include <linux/proc_fs.h>
4323 + #include <linux/mutex.h>
4324 ++#include <linux/wait.h>
4325 +
4326 + #include <net/sock.h>
4327 + #include <net/af_unix.h>
4328 +@@ -91,6 +92,7 @@
4329 + static LIST_HEAD(gc_inflight_list);
4330 + static LIST_HEAD(gc_candidates);
4331 + static DEFINE_SPINLOCK(unix_gc_lock);
4332 ++static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
4333 +
4334 + unsigned int unix_tot_inflight;
4335 +
4336 +@@ -266,12 +268,16 @@ static void inc_inflight_move_tail(struc
4337 + list_move_tail(&u->link, &gc_candidates);
4338 + }
4339 +
4340 +-/* The external entry point: unix_gc() */
4341 ++static bool gc_in_progress = false;
4342 +
4343 +-void unix_gc(void)
4344 ++void wait_for_unix_gc(void)
4345 + {
4346 +- static bool gc_in_progress = false;
4347 ++ wait_event(unix_gc_wait, gc_in_progress == false);
4348 ++}
4349 +
4350 ++/* The external entry point: unix_gc() */
4351 ++void unix_gc(void)
4352 ++{
4353 + struct unix_sock *u;
4354 + struct unix_sock *next;
4355 + struct sk_buff_head hitlist;
4356 +@@ -376,6 +382,7 @@ void unix_gc(void)
4357 + /* All candidates should have been detached by now. */
4358 + BUG_ON(!list_empty(&gc_candidates));
4359 + gc_in_progress = false;
4360 ++ wake_up(&unix_gc_wait);
4361 +
4362 + out:
4363 + spin_unlock(&unix_gc_lock);
4364
4365 Added: hardened/2.6/tags/2.6.25-13/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
4366 ===================================================================
4367 --- hardened/2.6/tags/2.6.25-13/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch (rev 0)
4368 +++ hardened/2.6/tags/2.6.25-13/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch 2009-01-20 21:27:53 UTC (rev 1478)
4369 @@ -0,0 +1,45 @@
4370 +Added-By: Gordon Malm <gengor@g.o>
4371 +
4372 +---
4373 +
4374 +From 17b24b3c97498935a2ef9777370b1151dfed3f6f Mon Sep 17 00:00:00 2001
4375 +From: Chas Williams <chas@××××××××××××.mil>
4376 +Date: Thu, 4 Dec 2008 14:58:13 -0800
4377 +Subject: ATM: CVE-2008-5079: duplicate listen() on socket corrupts the vcc table
4378 +
4379 +From: Chas Williams <chas@××××××××××××.mil>
4380 +
4381 +commit 17b24b3c97498935a2ef9777370b1151dfed3f6f upstream.
4382 +
4383 +As reported by Hugo Dias that it is possible to cause a local denial
4384 +of service attack by calling the svc_listen function twice on the same
4385 +socket and reading /proc/net/atm/*vc
4386 +
4387 +Signed-off-by: Chas Williams <chas@××××××××××××.mil>
4388 +Signed-off-by: David S. Miller <davem@×××××××××.net>
4389 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4390 +
4391 +---
4392 +
4393 +--- a/net/atm/svc.c
4394 ++++ b/net/atm/svc.c
4395 +@@ -293,7 +293,10 @@ static int svc_listen(struct socket *soc
4396 + error = -EINVAL;
4397 + goto out;
4398 + }
4399 +- vcc_insert_socket(sk);
4400 ++ if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
4401 ++ error = -EADDRINUSE;
4402 ++ goto out;
4403 ++ }
4404 + set_bit(ATM_VF_WAITING, &vcc->flags);
4405 + prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
4406 + sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
4407 +@@ -307,6 +310,7 @@ static int svc_listen(struct socket *soc
4408 + goto out;
4409 + }
4410 + set_bit(ATM_VF_LISTEN,&vcc->flags);
4411 ++ vcc_insert_socket(sk);
4412 + sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
4413 + error = -sk->sk_err;
4414 + out:
4415
4416 Added: hardened/2.6/tags/2.6.25-13/1425_enforce-a-minimum-sg_io-timeout.patch
4417 ===================================================================
4418 --- hardened/2.6/tags/2.6.25-13/1425_enforce-a-minimum-sg_io-timeout.patch (rev 0)
4419 +++ hardened/2.6/tags/2.6.25-13/1425_enforce-a-minimum-sg_io-timeout.patch 2009-01-20 21:27:53 UTC (rev 1478)
4420 @@ -0,0 +1,64 @@
4421 +Added-By: Gordon Malm <gengor@g.o>
4422 +
4423 +---
4424 +
4425 +From f2f1fa78a155524b849edf359e42a3001ea652c0 Mon Sep 17 00:00:00 2001
4426 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
4427 +Date: Fri, 5 Dec 2008 14:49:18 -0800
4428 +Subject: Enforce a minimum SG_IO timeout
4429 +
4430 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
4431 +
4432 +commit f2f1fa78a155524b849edf359e42a3001ea652c0 upstream.
4433 +
4434 +There's no point in having too short SG_IO timeouts, since if the
4435 +command does end up timing out, we'll end up through the reset sequence
4436 +that is several seconds long in order to abort the command that timed
4437 +out.
4438 +
4439 +As a result, shorter timeouts than a few seconds simply do not make
4440 +sense, as the recovery would be longer than the timeout itself.
4441 +
4442 +Add a BLK_MIN_SG_TIMEOUT to match the existign BLK_DEFAULT_SG_TIMEOUT.
4443 +
4444 +Suggested-by: Alan Cox <alan@××××××××××××××××.uk>
4445 +Acked-by: Tejun Heo <tj@××××××.org>
4446 +Acked-by: Jens Axboe <jens.axboe@××××××.com>
4447 +Cc: Jeff Garzik <jeff@××××××.org>
4448 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4449 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4450 +
4451 +---
4452 +
4453 +--- a/block/bsg.c
4454 ++++ b/block/bsg.c
4455 +@@ -202,6 +202,8 @@ static int blk_fill_sgv4_hdr_rq(struct r
4456 + rq->timeout = q->sg_timeout;
4457 + if (!rq->timeout)
4458 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
4459 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
4460 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
4461 +
4462 + return 0;
4463 + }
4464 +--- a/block/scsi_ioctl.c
4465 ++++ b/block/scsi_ioctl.c
4466 +@@ -208,6 +208,8 @@ static int blk_fill_sghdr_rq(struct requ
4467 + rq->timeout = q->sg_timeout;
4468 + if (!rq->timeout)
4469 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
4470 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
4471 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
4472 +
4473 + return 0;
4474 + }
4475 +--- a/include/linux/blkdev.h
4476 ++++ b/include/linux/blkdev.h
4477 +@@ -623,6 +623,7 @@ extern unsigned long blk_max_low_pfn, bl
4478 + * default timeout for SG_IO if none specified
4479 + */
4480 + #define BLK_DEFAULT_SG_TIMEOUT (60 * HZ)
4481 ++#define BLK_MIN_SG_TIMEOUT (7 * HZ)
4482 +
4483 + #ifdef CONFIG_BOUNCE
4484 + extern int init_emergency_isa_pool(void);
4485
4486 Added: hardened/2.6/tags/2.6.25-13/1503_hfsplus-check-read_mapping_page-return-value.patch
4487 ===================================================================
4488 --- hardened/2.6/tags/2.6.25-13/1503_hfsplus-check-read_mapping_page-return-value.patch (rev 0)
4489 +++ hardened/2.6/tags/2.6.25-13/1503_hfsplus-check-read_mapping_page-return-value.patch 2009-01-20 21:27:53 UTC (rev 1478)
4490 @@ -0,0 +1,110 @@
4491 +Added-By: Gordon Malm <gengor@g.o>
4492 +
4493 +---
4494 +
4495 +From 649f1ee6c705aab644035a7998d7b574193a598a Mon Sep 17 00:00:00 2001
4496 +From: Eric Sesterhenn <snakebyte@×××.de>
4497 +Date: Wed, 15 Oct 2008 22:04:10 -0700
4498 +Subject: hfsplus: check read_mapping_page() return value
4499 +
4500 +From: Eric Sesterhenn <snakebyte@×××.de>
4501 +
4502 +While testing more corrupted images with hfsplus, i came across
4503 +one which triggered the following bug:
4504 +
4505 +[15840.675016] BUG: unable to handle kernel paging request at fffffffb
4506 +[15840.675016] IP: [<c0116a4f>] kmap+0x15/0x56
4507 +[15840.675016] *pde = 00008067 *pte = 00000000
4508 +[15840.675016] Oops: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
4509 +[15840.675016] Modules linked in:
4510 +[15840.675016]
4511 +[15840.675016] Pid: 11575, comm: ln Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #29)
4512 +[15840.675016] EIP: 0060:[<c0116a4f>] EFLAGS: 00010202 CPU: 0
4513 +[15840.675016] EIP is at kmap+0x15/0x56
4514 +[15840.675016] EAX: 00000246 EBX: fffffffb ECX: 00000000 EDX: cab919c0
4515 +[15840.675016] ESI: 000007dd EDI: cab0bcf4 EBP: cab0bc98 ESP: cab0bc94
4516 +[15840.675016] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
4517 +[15840.675016] Process ln (pid: 11575, ti=cab0b000 task=cab919c0 task.ti=cab0b000)
4518 +[15840.675016] Stack: 00000000 cab0bcdc c0231cfb 00000000 cab0bce0 00000800 ca9290c0 fffffffb
4519 +[15840.675016] cab145d0 cab919c0 cab15998 22222222 22222222 22222222 00000001 cab15960
4520 +[15840.675016] 000007dd cab0bcf4 cab0bd04 c022cb3a cab0bcf4 cab15a6c ca9290c0 00000000
4521 +[15840.675016] Call Trace:
4522 +[15840.675016] [<c0231cfb>] ? hfsplus_block_allocate+0x6f/0x2d3
4523 +[15840.675016] [<c022cb3a>] ? hfsplus_file_extend+0xc4/0x1db
4524 +[15840.675016] [<c022ce41>] ? hfsplus_get_block+0x8c/0x19d
4525 +[15840.675016] [<c06adde4>] ? sub_preempt_count+0x9d/0xab
4526 +[15840.675016] [<c019ece6>] ? __block_prepare_write+0x147/0x311
4527 +[15840.675016] [<c0161934>] ? __grab_cache_page+0x52/0x73
4528 +[15840.675016] [<c019ef4f>] ? block_write_begin+0x79/0xd5
4529 +[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
4530 +[15840.675016] [<c019f22a>] ? cont_write_begin+0x27f/0x2af
4531 +[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
4532 +[15840.675016] [<c0139ebe>] ? tick_program_event+0x28/0x4c
4533 +[15840.675016] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4534 +[15840.675016] [<c022b723>] ? hfsplus_write_begin+0x2d/0x32
4535 +[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
4536 +[15840.675016] [<c0161988>] ? pagecache_write_begin+0x33/0x107
4537 +[15840.675016] [<c01879e5>] ? __page_symlink+0x3c/0xae
4538 +[15840.675016] [<c019ad34>] ? __mark_inode_dirty+0x12f/0x137
4539 +[15840.675016] [<c0187a70>] ? page_symlink+0x19/0x1e
4540 +[15840.675016] [<c022e6eb>] ? hfsplus_symlink+0x41/0xa6
4541 +[15840.675016] [<c01886a9>] ? vfs_symlink+0x99/0x101
4542 +[15840.675016] [<c018a2f6>] ? sys_symlinkat+0x6b/0xad
4543 +[15840.675016] [<c018a348>] ? sys_symlink+0x10/0x12
4544 +[15840.675016] [<c01038bd>] ? sysenter_do_call+0x12/0x31
4545 +[15840.675016] =======================
4546 +[15840.675016] Code: 00 00 75 10 83 3d 88 2f ec c0 02 75 07 89 d0 e8 12 56 05 00 5d c3 55 ba 06 00 00 00 89 e5 53 89 c3 b8 3d eb 7e c0 e8 16 74 00 00 <8b> 03 c1 e8 1e 69 c0 d8 02 00 00 05 b8 69 8e c0 2b 80 c4 02 00
4547 +[15840.675016] EIP: [<c0116a4f>] kmap+0x15/0x56 SS:ESP 0068:cab0bc94
4548 +[15840.675016] ---[ end trace 4fea40dad6b70e5f ]---
4549 +
4550 +This happens because the return value of read_mapping_page() is passed on
4551 +to kmap unchecked. The bug is triggered after the first
4552 +read_mapping_page() in hfsplus_block_allocate(), this patch fixes all
4553 +three usages in this functions but leaves the ones further down in the
4554 +file unchanged.
4555 +
4556 +Signed-off-by: Eric Sesterhenn <snakebyte@×××.de>
4557 +Cc: Roman Zippel <zippel@××××××××××.org>
4558 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
4559 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4560 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4561 +
4562 +---
4563 + fs/hfsplus/bitmap.c | 12 ++++++++++++
4564 + 1 file changed, 12 insertions(+)
4565 +
4566 +--- a/fs/hfsplus/bitmap.c
4567 ++++ b/fs/hfsplus/bitmap.c
4568 +@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_
4569 + mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
4570 + mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
4571 + page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
4572 ++ if (IS_ERR(page)) {
4573 ++ start = size;
4574 ++ goto out;
4575 ++ }
4576 + pptr = kmap(page);
4577 + curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
4578 + i = offset % 32;
4579 +@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_
4580 + break;
4581 + page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
4582 + NULL);
4583 ++ if (IS_ERR(page)) {
4584 ++ start = size;
4585 ++ goto out;
4586 ++ }
4587 + curr = pptr = kmap(page);
4588 + if ((size ^ offset) / PAGE_CACHE_BITS)
4589 + end = pptr + PAGE_CACHE_BITS / 32;
4590 +@@ -120,6 +128,10 @@ found:
4591 + offset += PAGE_CACHE_BITS;
4592 + page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
4593 + NULL);
4594 ++ if (IS_ERR(page)) {
4595 ++ start = size;
4596 ++ goto out;
4597 ++ }
4598 + pptr = kmap(page);
4599 + curr = pptr;
4600 + end = pptr + PAGE_CACHE_BITS / 32;
4601
4602 Added: hardened/2.6/tags/2.6.25-13/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch
4603 ===================================================================
4604 --- hardened/2.6/tags/2.6.25-13/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch (rev 0)
4605 +++ hardened/2.6/tags/2.6.25-13/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch 2009-01-20 21:27:53 UTC (rev 1478)
4606 @@ -0,0 +1,129 @@
4607 +Added-By: Gordon Malm <gengor@g.o>
4608 +
4609 +---
4610 +
4611 +From efc7ffcb4237f8cb9938909041c4ed38f6e1bf40 Mon Sep 17 00:00:00 2001
4612 +From: Eric Sesterhenn <snakebyte@×××.de>
4613 +Date: Wed, 15 Oct 2008 22:04:08 -0700
4614 +Subject: hfsplus: fix Buffer overflow with a corrupted image
4615 +
4616 +From: Eric Sesterhenn <snakebyte@×××.de>
4617 +
4618 +commit efc7ffcb4237f8cb9938909041c4ed38f6e1bf40 upstream
4619 +
4620 +When an hfsplus image gets corrupted it might happen that the catalog
4621 +namelength field gets b0rked. If we mount such an image the memcpy() in
4622 +hfsplus_cat_build_key_uni() writes more than the 255 that fit in the name
4623 +field. Depending on the size of the overwritten data, we either only get
4624 +memory corruption or also trigger an oops like this:
4625 +
4626 +[ 221.628020] BUG: unable to handle kernel paging request at c82b0000
4627 +[ 221.629066] IP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151
4628 +[ 221.629066] *pde = 0ea29163 *pte = 082b0160
4629 +[ 221.629066] Oops: 0002 [#1] PREEMPT DEBUG_PAGEALLOC
4630 +[ 221.629066] Modules linked in:
4631 +[ 221.629066]
4632 +[ 221.629066] Pid: 4845, comm: mount Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #28)
4633 +[ 221.629066] EIP: 0060:[<c022d4b1>] EFLAGS: 00010206 CPU: 0
4634 +[ 221.629066] EIP is at hfsplus_find_cat+0x10d/0x151
4635 +[ 221.629066] EAX: 00000029 EBX: 00016210 ECX: 000042c2 EDX: 00000002
4636 +[ 221.629066] ESI: c82d70ca EDI: c82b0000 EBP: c82d1bcc ESP: c82d199c
4637 +[ 221.629066] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
4638 +[ 221.629066] Process mount (pid: 4845, ti=c82d1000 task=c8224060 task.ti=c82d1000)
4639 +[ 221.629066] Stack: c080b3c4 c82aa8f8 c82d19c2 00016210 c080b3be c82d1bd4 c82aa8f0 00000300
4640 +[ 221.629066] 01000000 750008b1 74006e00 74006900 65006c00 c82d6400 c013bd35 c8224060
4641 +[ 221.629066] 00000036 00000046 c82d19f0 00000082 c8224548 c8224060 00000036 c0d653cc
4642 +[ 221.629066] Call Trace:
4643 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4644 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4645 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4646 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4647 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4648 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4649 +[ 221.629066] [<c01302d2>] ? __kernel_text_address+0x1b/0x27
4650 +[ 221.629066] [<c010487a>] ? dump_trace+0xca/0xd6
4651 +[ 221.629066] [<c0109e32>] ? save_stack_address+0x0/0x2c
4652 +[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
4653 +[ 221.629066] [<c013b571>] ? save_trace+0x37/0x8d
4654 +[ 221.629066] [<c013b62e>] ? add_lock_to_list+0x67/0x8d
4655 +[ 221.629066] [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
4656 +[ 221.629066] [<c013553d>] ? down+0xc/0x2f
4657 +[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
4658 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4659 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4660 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4661 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4662 +[ 221.629066] [<c013da5d>] ? mark_held_locks+0x43/0x5a
4663 +[ 221.629066] [<c013dc3a>] ? trace_hardirqs_on+0xb/0xd
4664 +[ 221.629066] [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
4665 +[ 221.629066] [<c06abec8>] ? _spin_unlock_irqrestore+0x42/0x58
4666 +[ 221.629066] [<c013555c>] ? down+0x2b/0x2f
4667 +[ 221.629066] [<c022aa68>] ? hfsplus_iget+0xa0/0x154
4668 +[ 221.629066] [<c022b0b9>] ? hfsplus_fill_super+0x280/0x447
4669 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4670 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4671 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4672 +[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
4673 +[ 221.629066] [<c041c9e4>] ? string+0x2b/0x74
4674 +[ 221.629066] [<c041cd16>] ? vsnprintf+0x2e9/0x512
4675 +[ 221.629066] [<c010487a>] ? dump_trace+0xca/0xd6
4676 +[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
4677 +[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
4678 +[ 221.629066] [<c013b571>] ? save_trace+0x37/0x8d
4679 +[ 221.629066] [<c013b62e>] ? add_lock_to_list+0x67/0x8d
4680 +[ 221.629066] [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
4681 +[ 221.629066] [<c01354d3>] ? up+0xc/0x2f
4682 +[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
4683 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4684 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4685 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4686 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4687 +[ 221.629066] [<c041cfb7>] ? snprintf+0x1b/0x1d
4688 +[ 221.629066] [<c01ba466>] ? disk_name+0x25/0x67
4689 +[ 221.629066] [<c0183960>] ? get_sb_bdev+0xcd/0x10b
4690 +[ 221.629066] [<c016ad92>] ? kstrdup+0x2a/0x4c
4691 +[ 221.629066] [<c022a7b3>] ? hfsplus_get_sb+0x13/0x15
4692 +[ 221.629066] [<c022ae39>] ? hfsplus_fill_super+0x0/0x447
4693 +[ 221.629066] [<c0183583>] ? vfs_kern_mount+0x3b/0x76
4694 +[ 221.629066] [<c0183602>] ? do_kern_mount+0x32/0xba
4695 +[ 221.629066] [<c01960d4>] ? do_new_mount+0x46/0x74
4696 +[ 221.629066] [<c0196277>] ? do_mount+0x175/0x193
4697 +[ 221.629066] [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
4698 +[ 221.629066] [<c01663b2>] ? __get_free_pages+0x1e/0x24
4699 +[ 221.629066] [<c06ac07b>] ? lock_kernel+0x19/0x8c
4700 +[ 221.629066] [<c01962e6>] ? sys_mount+0x51/0x9b
4701 +[ 221.629066] [<c01962f9>] ? sys_mount+0x64/0x9b
4702 +[ 221.629066] [<c01038bd>] ? sysenter_do_call+0x12/0x31
4703 +[ 221.629066] =======================
4704 +[ 221.629066] Code: 89 c2 c1 e2 08 c1 e8 08 09 c2 8b 85 e8 fd ff ff 66 89 50 06 89 c7 53 83 c7 08 56 57 68 c4 b3 80 c0 e8 8c 5c ef ff 89 d9 c1 e9 02 <f3> a5 89 d9 83 e1 03 74 02 f3 a4 83 c3 06 8b 95 e8 fd ff ff 0f
4705 +[ 221.629066] EIP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151 SS:ESP 0068:c82d199c
4706 +[ 221.629066] ---[ end trace e417a1d67f0d0066 ]---
4707 +
4708 +Since hfsplus_cat_build_key_uni() returns void and only has one callsite,
4709 +the check is performed at the callsite.
4710 +
4711 +Signed-off-by: Eric Sesterhenn <snakebyte@×××.de>
4712 +Reviewed-by: Pekka Enberg <penberg@×××××××××××.fi>
4713 +Cc: Roman Zippel <zippel@××××××××××.org>
4714 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
4715 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4716 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4717 +
4718 +---
4719 + fs/hfsplus/catalog.c | 5 +++++
4720 + 1 file changed, 5 insertions(+)
4721 +
4722 +--- a/fs/hfsplus/catalog.c
4723 ++++ b/fs/hfsplus/catalog.c
4724 +@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block
4725 + return -EIO;
4726 + }
4727 +
4728 ++ if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
4729 ++ printk(KERN_ERR "hfs: catalog name length corrupted\n");
4730 ++ return -EIO;
4731 ++ }
4732 ++
4733 + hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
4734 + &tmp.thread.nodeName);
4735 + return hfs_brec_find(fd);
4736
4737 Added: hardened/2.6/tags/2.6.25-13/1505_hfs-fix-namelength-memory-corruption.patch
4738 ===================================================================
4739 --- hardened/2.6/tags/2.6.25-13/1505_hfs-fix-namelength-memory-corruption.patch (rev 0)
4740 +++ hardened/2.6/tags/2.6.25-13/1505_hfs-fix-namelength-memory-corruption.patch 2009-01-20 21:27:53 UTC (rev 1478)
4741 @@ -0,0 +1,41 @@
4742 +Added-By: Gordon Malm <gengor@g.o>
4743 +
4744 +---
4745 +
4746 +From d38b7aa7fc3371b52d036748028db50b585ade2e Mon Sep 17 00:00:00 2001
4747 +From: Eric Sesterhenn <snakebyte@×××.de>
4748 +Date: Wed, 15 Oct 2008 22:04:11 -0700
4749 +Subject: hfs: fix namelength memory corruption (CVE-2008-5025)
4750 +
4751 +From: Eric Sesterhenn <snakebyte@×××.de>
4752 +
4753 +commit d38b7aa7fc3371b52d036748028db50b585ade2e upstream
4754 +
4755 +Fix a stack corruption caused by a corrupted hfs filesystem. If the
4756 +catalog name length is corrupted the memcpy overwrites the catalog btree
4757 +structure. Since the field is limited to HFS_NAMELEN bytes in the
4758 +structure and the file format, we throw an error if it is too long.
4759 +
4760 +Cc: Roman Zippel <zippel@××××××××××.org>
4761 +Signed-off-by: Eric Sesterhenn <snakebyte@×××.de>
4762 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
4763 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4764 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4765 +
4766 +---
4767 + fs/hfs/catalog.c | 4 ++++
4768 + 1 file changed, 4 insertions(+)
4769 +
4770 +--- a/fs/hfs/catalog.c
4771 ++++ b/fs/hfs/catalog.c
4772 +@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block
4773 +
4774 + fd->search_key->cat.ParID = rec.thread.ParID;
4775 + len = fd->search_key->cat.CName.len = rec.thread.CName.len;
4776 ++ if (len > HFS_NAMELEN) {
4777 ++ printk(KERN_ERR "hfs: bad catalog namelength\n");
4778 ++ return -EIO;
4779 ++ }
4780 + memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
4781 + return hfs_brec_find(fd);
4782 + }
4783
4784 Added: hardened/2.6/tags/2.6.25-13/1506_inotify-fix-watch-removal-or-umount-races.patch
4785 ===================================================================
4786 --- hardened/2.6/tags/2.6.25-13/1506_inotify-fix-watch-removal-or-umount-races.patch (rev 0)
4787 +++ hardened/2.6/tags/2.6.25-13/1506_inotify-fix-watch-removal-or-umount-races.patch 2009-01-20 21:27:53 UTC (rev 1478)
4788 @@ -0,0 +1,565 @@
4789 +Added-By: Gordon Malm <gengor@g.o>
4790 +
4791 +Note: Modified slightly to eliminate patch fuzz.
4792 +
4793 +---
4794 +
4795 +From: Al Viro <viro@×××××××××××××××.uk>
4796 +Date: Sat, 15 Nov 2008 01:15:43 +0000 (+0000)
4797 +Subject: Fix inotify watch removal/umount races
4798 +X-Git-Tag: v2.6.28-rc5~1
4799 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8f7b0ba1c853919b85b54774775f567f30006107
4800 +
4801 +Fix inotify watch removal/umount races
4802 +
4803 +Inotify watch removals suck violently.
4804 +
4805 +To kick the watch out we need (in this order) inode->inotify_mutex and
4806 +ih->mutex. That's fine if we have a hold on inode; however, for all
4807 +other cases we need to make damn sure we don't race with umount. We can
4808 +*NOT* just grab a reference to a watch - inotify_unmount_inodes() will
4809 +happily sail past it and we'll end with reference to inode potentially
4810 +outliving its superblock.
4811 +
4812 +Ideally we just want to grab an active reference to superblock if we
4813 +can; that will make sure we won't go into inotify_umount_inodes() until
4814 +we are done. Cleanup is just deactivate_super().
4815 +
4816 +However, that leaves a messy case - what if we *are* racing with
4817 +umount() and active references to superblock can't be acquired anymore?
4818 +We can bump ->s_count, grab ->s_umount, which will almost certainly wait
4819 +until the superblock is shut down and the watch in question is pining
4820 +for fjords. That's fine, but there is a problem - we might have hit the
4821 +window between ->s_active getting to 0 / ->s_count - below S_BIAS (i.e.
4822 +the moment when superblock is past the point of no return and is heading
4823 +for shutdown) and the moment when deactivate_super() acquires
4824 +->s_umount.
4825 +
4826 +We could just do drop_super() yield() and retry, but that's rather
4827 +antisocial and this stuff is luser-triggerable. OTOH, having grabbed
4828 +->s_umount and having found that we'd got there first (i.e. that
4829 +->s_root is non-NULL) we know that we won't race with
4830 +inotify_umount_inodes().
4831 +
4832 +So we could grab a reference to watch and do the rest as above, just
4833 +with drop_super() instead of deactivate_super(), right? Wrong. We had
4834 +to drop ih->mutex before we could grab ->s_umount. So the watch
4835 +could've been gone already.
4836 +
4837 +That still can be dealt with - we need to save watch->wd, do idr_find()
4838 +and compare its result with our pointer. If they match, we either have
4839 +the damn thing still alive or we'd lost not one but two races at once,
4840 +the watch had been killed and a new one got created with the same ->wd
4841 +at the same address. That couldn't have happened in inotify_destroy(),
4842 +but inotify_rm_wd() could run into that. Still, "new one got created"
4843 +is not a problem - we have every right to kill it or leave it alone,
4844 +whatever's more convenient.
4845 +
4846 +So we can use idr_find(...) == watch && watch->inode->i_sb == sb as
4847 +"grab it and kill it" check. If it's been our original watch, we are
4848 +fine, if it's a newcomer - nevermind, just pretend that we'd won the
4849 +race and kill the fscker anyway; we are safe since we know that its
4850 +superblock won't be going away.
4851 +
4852 +And yes, this is far beyond mere "not very pretty"; so's the entire
4853 +concept of inotify to start with.
4854 +
4855 +Signed-off-by: Al Viro <viro@×××××××××××××××.uk>
4856 +Acked-by: Greg KH <greg@×××××.com>
4857 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4858 +---
4859 +
4860 +--- a/fs/inotify.c
4861 ++++ b/fs/inotify.c
4862 +@@ -106,6 +106,20 @@ void get_inotify_watch(struct inotify_wa
4863 + }
4864 + EXPORT_SYMBOL_GPL(get_inotify_watch);
4865 +
4866 ++int pin_inotify_watch(struct inotify_watch *watch)
4867 ++{
4868 ++ struct super_block *sb = watch->inode->i_sb;
4869 ++ spin_lock(&sb_lock);
4870 ++ if (sb->s_count >= S_BIAS) {
4871 ++ atomic_inc(&sb->s_active);
4872 ++ spin_unlock(&sb_lock);
4873 ++ atomic_inc(&watch->count);
4874 ++ return 1;
4875 ++ }
4876 ++ spin_unlock(&sb_lock);
4877 ++ return 0;
4878 ++}
4879 ++
4880 + /**
4881 + * put_inotify_watch - decrements the ref count on a given watch. cleans up
4882 + * watch references if the count reaches zero. inotify_watch is freed by
4883 +@@ -124,6 +138,13 @@ void put_inotify_watch(struct inotify_wa
4884 + }
4885 + EXPORT_SYMBOL_GPL(put_inotify_watch);
4886 +
4887 ++void unpin_inotify_watch(struct inotify_watch *watch)
4888 ++{
4889 ++ struct super_block *sb = watch->inode->i_sb;
4890 ++ put_inotify_watch(watch);
4891 ++ deactivate_super(sb);
4892 ++}
4893 ++
4894 + /*
4895 + * inotify_handle_get_wd - returns the next WD for use by the given handle
4896 + *
4897 +@@ -479,6 +500,112 @@ void inotify_init_watch(struct inotify_w
4898 + }
4899 + EXPORT_SYMBOL_GPL(inotify_init_watch);
4900 +
4901 ++/*
4902 ++ * Watch removals suck violently. To kick the watch out we need (in this
4903 ++ * order) inode->inotify_mutex and ih->mutex. That's fine if we have
4904 ++ * a hold on inode; however, for all other cases we need to make damn sure
4905 ++ * we don't race with umount. We can *NOT* just grab a reference to a
4906 ++ * watch - inotify_unmount_inodes() will happily sail past it and we'll end
4907 ++ * with reference to inode potentially outliving its superblock. Ideally
4908 ++ * we just want to grab an active reference to superblock if we can; that
4909 ++ * will make sure we won't go into inotify_umount_inodes() until we are
4910 ++ * done. Cleanup is just deactivate_super(). However, that leaves a messy
4911 ++ * case - what if we *are* racing with umount() and active references to
4912 ++ * superblock can't be acquired anymore? We can bump ->s_count, grab
4913 ++ * ->s_umount, which will almost certainly wait until the superblock is shut
4914 ++ * down and the watch in question is pining for fjords. That's fine, but
4915 ++ * there is a problem - we might have hit the window between ->s_active
4916 ++ * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock
4917 ++ * is past the point of no return and is heading for shutdown) and the
4918 ++ * moment when deactivate_super() acquires ->s_umount. We could just do
4919 ++ * drop_super() yield() and retry, but that's rather antisocial and this
4920 ++ * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having
4921 ++ * found that we'd got there first (i.e. that ->s_root is non-NULL) we know
4922 ++ * that we won't race with inotify_umount_inodes(). So we could grab a
4923 ++ * reference to watch and do the rest as above, just with drop_super() instead
4924 ++ * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we
4925 ++ * could grab ->s_umount. So the watch could've been gone already.
4926 ++ *
4927 ++ * That still can be dealt with - we need to save watch->wd, do idr_find()
4928 ++ * and compare its result with our pointer. If they match, we either have
4929 ++ * the damn thing still alive or we'd lost not one but two races at once,
4930 ++ * the watch had been killed and a new one got created with the same ->wd
4931 ++ * at the same address. That couldn't have happened in inotify_destroy(),
4932 ++ * but inotify_rm_wd() could run into that. Still, "new one got created"
4933 ++ * is not a problem - we have every right to kill it or leave it alone,
4934 ++ * whatever's more convenient.
4935 ++ *
4936 ++ * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as
4937 ++ * "grab it and kill it" check. If it's been our original watch, we are
4938 ++ * fine, if it's a newcomer - nevermind, just pretend that we'd won the
4939 ++ * race and kill the fscker anyway; we are safe since we know that its
4940 ++ * superblock won't be going away.
4941 ++ *
4942 ++ * And yes, this is far beyond mere "not very pretty"; so's the entire
4943 ++ * concept of inotify to start with.
4944 ++ */
4945 ++
4946 ++/**
4947 ++ * pin_to_kill - pin the watch down for removal
4948 ++ * @ih: inotify handle
4949 ++ * @watch: watch to kill
4950 ++ *
4951 ++ * Called with ih->mutex held, drops it. Possible return values:
4952 ++ * 0 - nothing to do, it has died
4953 ++ * 1 - remove it, drop the reference and deactivate_super()
4954 ++ * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid
4955 ++ * that variant, since it involved a lot of PITA, but that's the best that
4956 ++ * could've been done.
4957 ++ */
4958 ++static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch)
4959 ++{
4960 ++ struct super_block *sb = watch->inode->i_sb;
4961 ++ s32 wd = watch->wd;
4962 ++
4963 ++ spin_lock(&sb_lock);
4964 ++ if (sb->s_count >= S_BIAS) {
4965 ++ atomic_inc(&sb->s_active);
4966 ++ spin_unlock(&sb_lock);
4967 ++ get_inotify_watch(watch);
4968 ++ mutex_unlock(&ih->mutex);
4969 ++ return 1; /* the best outcome */
4970 ++ }
4971 ++ sb->s_count++;
4972 ++ spin_unlock(&sb_lock);
4973 ++ mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */
4974 ++ down_read(&sb->s_umount);
4975 ++ if (likely(!sb->s_root)) {
4976 ++ /* fs is already shut down; the watch is dead */
4977 ++ drop_super(sb);
4978 ++ return 0;
4979 ++ }
4980 ++ /* raced with the final deactivate_super() */
4981 ++ mutex_lock(&ih->mutex);
4982 ++ if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) {
4983 ++ /* the watch is dead */
4984 ++ mutex_unlock(&ih->mutex);
4985 ++ drop_super(sb);
4986 ++ return 0;
4987 ++ }
4988 ++ /* still alive or freed and reused with the same sb and wd; kill */
4989 ++ get_inotify_watch(watch);
4990 ++ mutex_unlock(&ih->mutex);
4991 ++ return 2;
4992 ++}
4993 ++
4994 ++static void unpin_and_kill(struct inotify_watch *watch, int how)
4995 ++{
4996 ++ struct super_block *sb = watch->inode->i_sb;
4997 ++ put_inotify_watch(watch);
4998 ++ switch (how) {
4999 ++ case 1:
5000 ++ deactivate_super(sb);
5001 ++ break;
5002 ++ case 2:
5003 ++ drop_super(sb);
5004 ++ }
5005 ++}
5006 ++
5007 + /**
5008 + * inotify_destroy - clean up and destroy an inotify instance
5009 + * @ih: inotify handle
5010 +@@ -490,11 +617,15 @@ void inotify_destroy(struct inotify_hand
5011 + * pretty. We cannot do a simple iteration over the list, because we
5012 + * do not know the inode until we iterate to the watch. But we need to
5013 + * hold inode->inotify_mutex before ih->mutex. The following works.
5014 ++ *
5015 ++ * AV: it had to become even uglier to start working ;-/
5016 + */
5017 + while (1) {
5018 + struct inotify_watch *watch;
5019 + struct list_head *watches;
5020 ++ struct super_block *sb;
5021 + struct inode *inode;
5022 ++ int how;
5023 +
5024 + mutex_lock(&ih->mutex);
5025 + watches = &ih->watches;
5026 +@@ -503,8 +634,10 @@ void inotify_destroy(struct inotify_hand
5027 + break;
5028 + }
5029 + watch = list_first_entry(watches, struct inotify_watch, h_list);
5030 +- get_inotify_watch(watch);
5031 +- mutex_unlock(&ih->mutex);
5032 ++ sb = watch->inode->i_sb;
5033 ++ how = pin_to_kill(ih, watch);
5034 ++ if (!how)
5035 ++ continue;
5036 +
5037 + inode = watch->inode;
5038 + mutex_lock(&inode->inotify_mutex);
5039 +@@ -518,7 +651,7 @@ void inotify_destroy(struct inotify_hand
5040 +
5041 + mutex_unlock(&ih->mutex);
5042 + mutex_unlock(&inode->inotify_mutex);
5043 +- put_inotify_watch(watch);
5044 ++ unpin_and_kill(watch, how);
5045 + }
5046 +
5047 + /* free this handle: the put matching the get in inotify_init() */
5048 +@@ -719,7 +852,9 @@ void inotify_evict_watch(struct inotify_
5049 + int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
5050 + {
5051 + struct inotify_watch *watch;
5052 ++ struct super_block *sb;
5053 + struct inode *inode;
5054 ++ int how;
5055 +
5056 + mutex_lock(&ih->mutex);
5057 + watch = idr_find(&ih->idr, wd);
5058 +@@ -727,9 +862,12 @@ int inotify_rm_wd(struct inotify_handle
5059 + mutex_unlock(&ih->mutex);
5060 + return -EINVAL;
5061 + }
5062 +- get_inotify_watch(watch);
5063 ++ sb = watch->inode->i_sb;
5064 ++ how = pin_to_kill(ih, watch);
5065 ++ if (!how)
5066 ++ return 0;
5067 ++
5068 + inode = watch->inode;
5069 +- mutex_unlock(&ih->mutex);
5070 +
5071 + mutex_lock(&inode->inotify_mutex);
5072 + mutex_lock(&ih->mutex);
5073 +@@ -740,7 +878,7 @@ int inotify_rm_wd(struct inotify_handle
5074 +
5075 + mutex_unlock(&ih->mutex);
5076 + mutex_unlock(&inode->inotify_mutex);
5077 +- put_inotify_watch(watch);
5078 ++ unpin_and_kill(watch, how);
5079 +
5080 + return 0;
5081 + }
5082 +--- a/include/linux/inotify.h
5083 ++++ b/include/linux/inotify.h
5084 +@@ -128,6 +128,8 @@ extern void inotify_remove_watch_locked(
5085 + struct inotify_watch *);
5086 + extern void get_inotify_watch(struct inotify_watch *);
5087 + extern void put_inotify_watch(struct inotify_watch *);
5088 ++extern int pin_inotify_watch(struct inotify_watch *);
5089 ++extern void unpin_inotify_watch(struct inotify_watch *);
5090 +
5091 + #else
5092 +
5093 +@@ -222,6 +224,15 @@ static inline void put_inotify_watch(str
5094 + {
5095 + }
5096 +
5097 ++extern inline int pin_inotify_watch(struct inotify_watch *watch)
5098 ++{
5099 ++ return 0;
5100 ++}
5101 ++
5102 ++extern inline void unpin_inotify_watch(struct inotify_watch *watch)
5103 ++{
5104 ++}
5105 ++
5106 + #endif /* CONFIG_INOTIFY */
5107 +
5108 + #endif /* __KERNEL __ */
5109 +--- a/kernel/audit_tree.c
5110 ++++ b/kernel/audit_tree.c
5111 +@@ -24,6 +24,7 @@ struct audit_chunk {
5112 + struct list_head trees; /* with root here */
5113 + int dead;
5114 + int count;
5115 ++ atomic_long_t refs;
5116 + struct rcu_head head;
5117 + struct node {
5118 + struct list_head list;
5119 +@@ -56,7 +57,8 @@ static LIST_HEAD(prune_list);
5120 + * tree is refcounted; one reference for "some rules on rules_list refer to
5121 + * it", one for each chunk with pointer to it.
5122 + *
5123 +- * chunk is refcounted by embedded inotify_watch.
5124 ++ * chunk is refcounted by embedded inotify_watch + .refs (non-zero refcount
5125 ++ * of watch contributes 1 to .refs).
5126 + *
5127 + * node.index allows to get from node.list to containing chunk.
5128 + * MSB of that sucker is stolen to mark taggings that we might have to
5129 +@@ -121,6 +123,7 @@ static struct audit_chunk *alloc_chunk(i
5130 + INIT_LIST_HEAD(&chunk->hash);
5131 + INIT_LIST_HEAD(&chunk->trees);
5132 + chunk->count = count;
5133 ++ atomic_long_set(&chunk->refs, 1);
5134 + for (i = 0; i < count; i++) {
5135 + INIT_LIST_HEAD(&chunk->owners[i].list);
5136 + chunk->owners[i].index = i;
5137 +@@ -129,9 +132,8 @@ static struct audit_chunk *alloc_chunk(i
5138 + return chunk;
5139 + }
5140 +
5141 +-static void __free_chunk(struct rcu_head *rcu)
5142 ++static void free_chunk(struct audit_chunk *chunk)
5143 + {
5144 +- struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
5145 + int i;
5146 +
5147 + for (i = 0; i < chunk->count; i++) {
5148 +@@ -141,14 +143,16 @@ static void __free_chunk(struct rcu_head
5149 + kfree(chunk);
5150 + }
5151 +
5152 +-static inline void free_chunk(struct audit_chunk *chunk)
5153 ++void audit_put_chunk(struct audit_chunk *chunk)
5154 + {
5155 +- call_rcu(&chunk->head, __free_chunk);
5156 ++ if (atomic_long_dec_and_test(&chunk->refs))
5157 ++ free_chunk(chunk);
5158 + }
5159 +
5160 +-void audit_put_chunk(struct audit_chunk *chunk)
5161 ++static void __put_chunk(struct rcu_head *rcu)
5162 + {
5163 +- put_inotify_watch(&chunk->watch);
5164 ++ struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
5165 ++ audit_put_chunk(chunk);
5166 + }
5167 +
5168 + enum {HASH_SIZE = 128};
5169 +@@ -177,7 +181,7 @@ struct audit_chunk *audit_tree_lookup(co
5170 + list_for_each_rcu(pos, list) {
5171 + struct audit_chunk *p = container_of(pos, struct audit_chunk, hash);
5172 + if (p->watch.inode == inode) {
5173 +- get_inotify_watch(&p->watch);
5174 ++ atomic_long_inc(&p->refs);
5175 + return p;
5176 + }
5177 + }
5178 +@@ -195,17 +199,49 @@ int audit_tree_match(struct audit_chunk
5179 +
5180 + /* tagging and untagging inodes with trees */
5181 +
5182 +-static void untag_chunk(struct audit_chunk *chunk, struct node *p)
5183 ++static struct audit_chunk *find_chunk(struct node *p)
5184 ++{
5185 ++ int index = p->index & ~(1U<<31);
5186 ++ p -= index;
5187 ++ return container_of(p, struct audit_chunk, owners[0]);
5188 ++}
5189 ++
5190 ++static void untag_chunk(struct node *p)
5191 + {
5192 ++ struct audit_chunk *chunk = find_chunk(p);
5193 + struct audit_chunk *new;
5194 + struct audit_tree *owner;
5195 + int size = chunk->count - 1;
5196 + int i, j;
5197 +
5198 ++ if (!pin_inotify_watch(&chunk->watch)) {
5199 ++ /*
5200 ++ * Filesystem is shutting down; all watches are getting
5201 ++ * evicted, just take it off the node list for this
5202 ++ * tree and let the eviction logics take care of the
5203 ++ * rest.
5204 ++ */
5205 ++ owner = p->owner;
5206 ++ if (owner->root == chunk) {
5207 ++ list_del_init(&owner->same_root);
5208 ++ owner->root = NULL;
5209 ++ }
5210 ++ list_del_init(&p->list);
5211 ++ p->owner = NULL;
5212 ++ put_tree(owner);
5213 ++ return;
5214 ++ }
5215 ++
5216 ++ spin_unlock(&hash_lock);
5217 ++
5218 ++ /*
5219 ++ * pin_inotify_watch() succeeded, so the watch won't go away
5220 ++ * from under us.
5221 ++ */
5222 + mutex_lock(&chunk->watch.inode->inotify_mutex);
5223 + if (chunk->dead) {
5224 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5225 +- return;
5226 ++ goto out;
5227 + }
5228 +
5229 + owner = p->owner;
5230 +@@ -222,7 +258,7 @@ static void untag_chunk(struct audit_chu
5231 + inotify_evict_watch(&chunk->watch);
5232 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5233 + put_inotify_watch(&chunk->watch);
5234 +- return;
5235 ++ goto out;
5236 + }
5237 +
5238 + new = alloc_chunk(size);
5239 +@@ -264,7 +300,7 @@ static void untag_chunk(struct audit_chu
5240 + inotify_evict_watch(&chunk->watch);
5241 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5242 + put_inotify_watch(&chunk->watch);
5243 +- return;
5244 ++ goto out;
5245 +
5246 + Fallback:
5247 + // do the best we can
5248 +@@ -278,6 +314,9 @@ Fallback:
5249 + put_tree(owner);
5250 + spin_unlock(&hash_lock);
5251 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5252 ++out:
5253 ++ unpin_inotify_watch(&chunk->watch);
5254 ++ spin_lock(&hash_lock);
5255 + }
5256 +
5257 + static int create_chunk(struct inode *inode, struct audit_tree *tree)
5258 +@@ -388,13 +427,6 @@ static int tag_chunk(struct inode *inode
5259 + return 0;
5260 + }
5261 +
5262 +-static struct audit_chunk *find_chunk(struct node *p)
5263 +-{
5264 +- int index = p->index & ~(1U<<31);
5265 +- p -= index;
5266 +- return container_of(p, struct audit_chunk, owners[0]);
5267 +-}
5268 +-
5269 + static void kill_rules(struct audit_tree *tree)
5270 + {
5271 + struct audit_krule *rule, *next;
5272 +@@ -432,17 +464,10 @@ static void prune_one(struct audit_tree
5273 + spin_lock(&hash_lock);
5274 + while (!list_empty(&victim->chunks)) {
5275 + struct node *p;
5276 +- struct audit_chunk *chunk;
5277 +
5278 + p = list_entry(victim->chunks.next, struct node, list);
5279 +- chunk = find_chunk(p);
5280 +- get_inotify_watch(&chunk->watch);
5281 +- spin_unlock(&hash_lock);
5282 +-
5283 +- untag_chunk(chunk, p);
5284 +
5285 +- put_inotify_watch(&chunk->watch);
5286 +- spin_lock(&hash_lock);
5287 ++ untag_chunk(p);
5288 + }
5289 + spin_unlock(&hash_lock);
5290 + put_tree(victim);
5291 +@@ -470,7 +495,6 @@ static void trim_marked(struct audit_tre
5292 +
5293 + while (!list_empty(&tree->chunks)) {
5294 + struct node *node;
5295 +- struct audit_chunk *chunk;
5296 +
5297 + node = list_entry(tree->chunks.next, struct node, list);
5298 +
5299 +@@ -478,14 +502,7 @@ static void trim_marked(struct audit_tre
5300 + if (!(node->index & (1U<<31)))
5301 + break;
5302 +
5303 +- chunk = find_chunk(node);
5304 +- get_inotify_watch(&chunk->watch);
5305 +- spin_unlock(&hash_lock);
5306 +-
5307 +- untag_chunk(chunk, node);
5308 +-
5309 +- put_inotify_watch(&chunk->watch);
5310 +- spin_lock(&hash_lock);
5311 ++ untag_chunk(node);
5312 + }
5313 + if (!tree->root && !tree->goner) {
5314 + tree->goner = 1;
5315 +@@ -879,7 +896,7 @@ static void handle_event(struct inotify_
5316 + static void destroy_watch(struct inotify_watch *watch)
5317 + {
5318 + struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
5319 +- free_chunk(chunk);
5320 ++ call_rcu(&chunk->head, __put_chunk);
5321 + }
5322 +
5323 + static const struct inotify_operations rtree_inotify_ops = {
5324 +--- a/kernel/auditfilter.c
5325 ++++ b/kernel/auditfilter.c
5326 +@@ -1085,8 +1085,8 @@ static void audit_inotify_unregister(str
5327 + list_for_each_entry_safe(p, n, in_list, ilist) {
5328 + list_del(&p->ilist);
5329 + inotify_rm_watch(audit_ih, &p->wdata);
5330 +- /* the put matching the get in audit_do_del_rule() */
5331 +- put_inotify_watch(&p->wdata);
5332 ++ /* the unpin matching the pin in audit_do_del_rule() */
5333 ++ unpin_inotify_watch(&p->wdata);
5334 + }
5335 + }
5336 +
5337 +@@ -1380,9 +1380,13 @@ static inline int audit_del_rule(struct
5338 + /* Put parent on the inotify un-registration
5339 + * list. Grab a reference before releasing
5340 + * audit_filter_mutex, to be released in
5341 +- * audit_inotify_unregister(). */
5342 +- list_add(&parent->ilist, &inotify_list);
5343 +- get_inotify_watch(&parent->wdata);
5344 ++ * audit_inotify_unregister().
5345 ++ * If filesystem is going away, just leave
5346 ++ * the sucker alone, eviction will take
5347 ++ * care of it.
5348 ++ */
5349 ++ if (pin_inotify_watch(&parent->wdata))
5350 ++ list_add(&parent->ilist, &inotify_list);
5351 + }
5352 + }
5353 + }
5354
5355 Added: hardened/2.6/tags/2.6.25-13/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
5356 ===================================================================
5357 --- hardened/2.6/tags/2.6.25-13/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch (rev 0)
5358 +++ hardened/2.6/tags/2.6.25-13/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch 2009-01-20 21:27:53 UTC (rev 1478)
5359 @@ -0,0 +1,80 @@
5360 +Added-By: Gordon Malm <gengor@g.o>
5361 +
5362 +Note: Re-diffed to eliminate failed hunks.
5363 +
5364 +---
5365 +
5366 +From: Wei Yongjun <yjwei@××××××××××.com>
5367 +Date: Fri, 26 Dec 2008 00:58:11 +0000 (-0800)
5368 +Subject: sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
5369 +X-Git-Tag: v2.6.29-rc1~581^2~75
5370 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9fcb95a105758b81ef0131cd18e2db5149f13e95
5371 +
5372 +sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
5373 +
5374 +If FWD-TSN chunk is received with bad stream ID, the sctp will not do the
5375 +validity check, this may cause memory overflow when overwrite the TSN of
5376 +the stream ID.
5377 +
5378 +The FORWARD-TSN chunk is like this:
5379 +
5380 +FORWARD-TSN chunk
5381 + Type = 192
5382 + Flags = 0
5383 + Length = 172
5384 + NewTSN = 99
5385 + Stream = 10000
5386 + StreamSequence = 0xFFFF
5387 +
5388 +This patch fix this problem by discard the chunk if stream ID is not
5389 +less than MIS.
5390 +
5391 +Signed-off-by: Wei Yongjun <yjwei@××××××××××.com>
5392 +Signed-off-by: Vlad Yasevich <vladislav.yasevich@××.com>
5393 +Signed-off-by: David S. Miller <davem@×××××××××.net>
5394 +---
5395 +
5396 +--- a/net/sctp/sm_statefuns.c
5397 ++++ b/net/sctp/sm_statefuns.c
5398 +@@ -3641,6 +3641,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
5399 + {
5400 + struct sctp_chunk *chunk = arg;
5401 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
5402 ++ struct sctp_fwdtsn_skip *skip;
5403 + __u16 len;
5404 + __u32 tsn;
5405 +
5406 +@@ -3670,6 +3671,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
5407 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
5408 + goto discard_noforce;
5409 +
5410 ++ /* Silently discard the chunk if stream-id is not valid */
5411 ++ sctp_walk_fwdtsn(skip, chunk) {
5412 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
5413 ++ goto discard_noforce;
5414 ++ }
5415 ++
5416 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
5417 + if (len > sizeof(struct sctp_fwdtsn_hdr))
5418 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
5419 +@@ -3701,6 +3708,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
5420 + {
5421 + struct sctp_chunk *chunk = arg;
5422 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
5423 ++ struct sctp_fwdtsn_skip *skip;
5424 + __u16 len;
5425 + __u32 tsn;
5426 +
5427 +@@ -3730,6 +3738,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
5428 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
5429 + goto gen_shutdown;
5430 +
5431 ++ /* Silently discard the chunk if stream-id is not valid */
5432 ++ sctp_walk_fwdtsn(skip, chunk) {
5433 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
5434 ++ goto gen_shutdown;
5435 ++ }
5436 ++
5437 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
5438 + if (len > sizeof(struct sctp_fwdtsn_hdr))
5439 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
5440
5441 Added: hardened/2.6/tags/2.6.25-13/1800_sched-disable-hrtick.patch
5442 ===================================================================
5443 --- hardened/2.6/tags/2.6.25-13/1800_sched-disable-hrtick.patch (rev 0)
5444 +++ hardened/2.6/tags/2.6.25-13/1800_sched-disable-hrtick.patch 2009-01-20 21:27:53 UTC (rev 1478)
5445 @@ -0,0 +1,17 @@
5446 +From: Kerin Millar <kerframil@×××××.com>
5447 +
5448 +This is a backport to 2.6.25 of commit 612f39d5e7baeb0518cfe50d53e37e14c0ca1475
5449 +from Ingo Molnar, which disables hrtick (high-resolution preemption ticks). For
5450 +further information, please refer to Gentoo Bug #247453.
5451 +
5452 +--- a/kernel/sched.c 2008-04-17 03:49:44.000000000 +0100
5453 ++++ b/kernel/sched.c 2008-11-18 20:30:33.000000000 +0000
5454 +@@ -602,7 +602,7 @@
5455 + SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 |
5456 + SCHED_FEAT_WAKEUP_PREEMPT * 1 |
5457 + SCHED_FEAT_START_DEBIT * 1 |
5458 +- SCHED_FEAT_HRTICK * 1 |
5459 ++ SCHED_FEAT_HRTICK * 0 |
5460 + SCHED_FEAT_DOUBLE_TICK * 0;
5461 +
5462 + #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
5463
5464 Added: hardened/2.6/tags/2.6.25-13/4420_grsec-2.1.12-2.6.25.16-200808201644.patch
5465 ===================================================================
5466 --- hardened/2.6/tags/2.6.25-13/4420_grsec-2.1.12-2.6.25.16-200808201644.patch (rev 0)
5467 +++ hardened/2.6/tags/2.6.25-13/4420_grsec-2.1.12-2.6.25.16-200808201644.patch 2009-01-20 21:27:53 UTC (rev 1478)
5468 @@ -0,0 +1,35914 @@
5469 +diff -urNp a/Documentation/dontdiff b/Documentation/dontdiff
5470 +--- a/Documentation/dontdiff 2008-08-20 11:16:13.000000000 -0700
5471 ++++ b/Documentation/dontdiff 2008-08-20 18:36:57.000000000 -0700
5472 +@@ -3,6 +3,7 @@
5473 + *.bin
5474 + *.cpio
5475 + *.css
5476 ++*.dbg
5477 + *.dvi
5478 + *.eps
5479 + *.gif
5480 +@@ -55,6 +56,7 @@ ChangeSet
5481 + Image
5482 + Kerntypes
5483 + MODS.txt
5484 ++Module.markers
5485 + Module.symvers
5486 + PENDING
5487 + SCCS
5488 +@@ -89,6 +91,7 @@ config_data.gz*
5489 + conmakehash
5490 + consolemap_deftbl.c*
5491 + crc32table.h*
5492 ++cpustr.h
5493 + cscope.*
5494 + defkeymap.c*
5495 + devlist.h*
5496 +@@ -137,11 +140,13 @@ miboot*
5497 + mk_elfconfig
5498 + mkboot
5499 + mkbugboot
5500 ++mkcpustr
5501 + mkdep
5502 + mkprep
5503 + mktables
5504 + mktree
5505 + modpost
5506 ++modules.order
5507 + modversions.h*
5508 + offset.h
5509 + offsets.h
5510 +@@ -172,20 +177,24 @@ sm_tbl*
5511 + split-include
5512 + tags
5513 + tftpboot.img
5514 ++timeconst.h
5515 + times.h*
5516 + tkparse
5517 + trix_boot.h
5518 + utsrelease.h*
5519 +-vdso.lds
5520 ++vdso*.lds
5521 + version.h*
5522 + vmlinux
5523 + vmlinux-*
5524 + vmlinux.aout
5525 +-vmlinux*.lds*
5526 ++vmlinux.bin.all
5527 ++vmlinux*.lds
5528 ++vmlinux.relocs
5529 + vmlinux*.scr
5530 +-vsyscall.lds
5531 ++vsyscall*.lds
5532 + wanxlfw.inc
5533 + uImage
5534 + unifdef
5535 ++utsrelease.h
5536 + zImage*
5537 + zconf.hash.c
5538 +diff -urNp a/Makefile b/Makefile
5539 +--- a/Makefile 2008-08-20 11:16:13.000000000 -0700
5540 ++++ b/Makefile 2008-08-20 18:36:57.000000000 -0700
5541 +@@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
5542 +
5543 + HOSTCC = gcc
5544 + HOSTCXX = g++
5545 +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
5546 ++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
5547 + HOSTCXXFLAGS = -O2
5548 +
5549 + # Decide whether to build built-in, modular, or both.
5550 +@@ -603,7 +603,7 @@ export mod_strip_cmd
5551 +
5552 +
5553 + ifeq ($(KBUILD_EXTMOD),)
5554 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
5555 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
5556 +
5557 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
5558 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
5559 +diff -urNp a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
5560 +--- a/arch/alpha/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
5561 ++++ b/arch/alpha/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
5562 +@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
5563 +
5564 + /* The small sections were sorted to the end of the segment.
5565 + The following should definitely cover them. */
5566 +- gp = (u64)me->module_core + me->core_size - 0x8000;
5567 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
5568 + got = sechdrs[me->arch.gotsecindex].sh_addr;
5569 +
5570 + for (i = 0; i < n; i++) {
5571 +diff -urNp a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
5572 +--- a/arch/alpha/kernel/osf_sys.c 2008-08-20 11:16:13.000000000 -0700
5573 ++++ b/arch/alpha/kernel/osf_sys.c 2008-08-20 18:36:57.000000000 -0700
5574 +@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
5575 + merely specific addresses, but regions of memory -- perhaps
5576 + this feature should be incorporated into all ports? */
5577 +
5578 ++#ifdef CONFIG_PAX_RANDMMAP
5579 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5580 ++#endif
5581 ++
5582 + if (addr) {
5583 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
5584 + if (addr != (unsigned long) -ENOMEM)
5585 +@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
5586 + }
5587 +
5588 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
5589 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
5590 +- len, limit);
5591 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
5592 ++
5593 + if (addr != (unsigned long) -ENOMEM)
5594 + return addr;
5595 +
5596 +diff -urNp a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
5597 +--- a/arch/alpha/kernel/ptrace.c 2008-08-20 11:16:13.000000000 -0700
5598 ++++ b/arch/alpha/kernel/ptrace.c 2008-08-20 18:36:57.000000000 -0700
5599 +@@ -15,6 +15,7 @@
5600 + #include <linux/slab.h>
5601 + #include <linux/security.h>
5602 + #include <linux/signal.h>
5603 ++#include <linux/grsecurity.h>
5604 +
5605 + #include <asm/uaccess.h>
5606 + #include <asm/pgtable.h>
5607 +@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
5608 + size_t copied;
5609 + long ret;
5610 +
5611 ++ if (gr_handle_ptrace(child, request))
5612 ++ return -EPERM;
5613 ++
5614 + switch (request) {
5615 + /* When I and D space are separate, these will need to be fixed. */
5616 + case PTRACE_PEEKTEXT: /* read word at location addr. */
5617 +diff -urNp a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
5618 +--- a/arch/alpha/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
5619 ++++ b/arch/alpha/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
5620 +@@ -23,6 +23,7 @@
5621 + #include <linux/smp.h>
5622 + #include <linux/interrupt.h>
5623 + #include <linux/module.h>
5624 ++#include <linux/binfmts.h>
5625 +
5626 + #include <asm/system.h>
5627 + #include <asm/uaccess.h>
5628 +@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
5629 + __reload_thread(pcb);
5630 + }
5631 +
5632 ++#ifdef CONFIG_PAX_PAGEEXEC
5633 ++/*
5634 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
5635 ++ *
5636 ++ * returns 1 when task should be killed
5637 ++ * 2 when patched PLT trampoline was detected
5638 ++ * 3 when unpatched PLT trampoline was detected
5639 ++ */
5640 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
5641 ++{
5642 ++
5643 ++#ifdef CONFIG_PAX_EMUPLT
5644 ++ int err;
5645 ++
5646 ++ do { /* PaX: patched PLT emulation #1 */
5647 ++ unsigned int ldah, ldq, jmp;
5648 ++
5649 ++ err = get_user(ldah, (unsigned int *)regs->pc);
5650 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
5651 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
5652 ++
5653 ++ if (err)
5654 ++ break;
5655 ++
5656 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
5657 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
5658 ++ jmp == 0x6BFB0000U)
5659 ++ {
5660 ++ unsigned long r27, addr;
5661 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
5662 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
5663 ++
5664 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
5665 ++ err = get_user(r27, (unsigned long *)addr);
5666 ++ if (err)
5667 ++ break;
5668 ++
5669 ++ regs->r27 = r27;
5670 ++ regs->pc = r27;
5671 ++ return 2;
5672 ++ }
5673 ++ } while (0);
5674 ++
5675 ++ do { /* PaX: patched PLT emulation #2 */
5676 ++ unsigned int ldah, lda, br;
5677 ++
5678 ++ err = get_user(ldah, (unsigned int *)regs->pc);
5679 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
5680 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
5681 ++
5682 ++ if (err)
5683 ++ break;
5684 ++
5685 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
5686 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
5687 ++ (br & 0xFFE00000U) == 0xC3E00000U)
5688 ++ {
5689 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
5690 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
5691 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
5692 ++
5693 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
5694 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
5695 ++ return 2;
5696 ++ }
5697 ++ } while (0);
5698 ++
5699 ++ do { /* PaX: unpatched PLT emulation */
5700 ++ unsigned int br;
5701 ++
5702 ++ err = get_user(br, (unsigned int *)regs->pc);
5703 ++
5704 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
5705 ++ unsigned int br2, ldq, nop, jmp;
5706 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
5707 ++
5708 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
5709 ++ err = get_user(br2, (unsigned int *)addr);
5710 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
5711 ++ err |= get_user(nop, (unsigned int *)(addr+8));
5712 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
5713 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
5714 ++
5715 ++ if (err)
5716 ++ break;
5717 ++
5718 ++ if (br2 == 0xC3600000U &&
5719 ++ ldq == 0xA77B000CU &&
5720 ++ nop == 0x47FF041FU &&
5721 ++ jmp == 0x6B7B0000U)
5722 ++ {
5723 ++ regs->r28 = regs->pc+4;
5724 ++ regs->r27 = addr+16;
5725 ++ regs->pc = resolver;
5726 ++ return 3;
5727 ++ }
5728 ++ }
5729 ++ } while (0);
5730 ++#endif
5731 ++
5732 ++ return 1;
5733 ++}
5734 ++
5735 ++void pax_report_insns(void *pc, void *sp)
5736 ++{
5737 ++ unsigned long i;
5738 ++
5739 ++ printk(KERN_ERR "PAX: bytes at PC: ");
5740 ++ for (i = 0; i < 5; i++) {
5741 ++ unsigned int c;
5742 ++ if (get_user(c, (unsigned int *)pc+i))
5743 ++ printk(KERN_CONT "???????? ");
5744 ++ else
5745 ++ printk(KERN_CONT "%08x ", c);
5746 ++ }
5747 ++ printk("\n");
5748 ++}
5749 ++#endif
5750 +
5751 + /*
5752 + * This routine handles page faults. It determines the address,
5753 +@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
5754 + good_area:
5755 + si_code = SEGV_ACCERR;
5756 + if (cause < 0) {
5757 +- if (!(vma->vm_flags & VM_EXEC))
5758 ++ if (!(vma->vm_flags & VM_EXEC)) {
5759 ++
5760 ++#ifdef CONFIG_PAX_PAGEEXEC
5761 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
5762 ++ goto bad_area;
5763 ++
5764 ++ up_read(&mm->mmap_sem);
5765 ++ switch (pax_handle_fetch_fault(regs)) {
5766 ++
5767 ++#ifdef CONFIG_PAX_EMUPLT
5768 ++ case 2:
5769 ++ case 3:
5770 ++ return;
5771 ++#endif
5772 ++
5773 ++ }
5774 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
5775 ++ do_group_exit(SIGKILL);
5776 ++#else
5777 + goto bad_area;
5778 ++#endif
5779 ++
5780 ++ }
5781 + } else if (!cause) {
5782 + /* Allow reads even for write-only mappings */
5783 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
5784 +diff -urNp a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
5785 +--- a/arch/arm/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
5786 ++++ b/arch/arm/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
5787 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
5788 + if (len > TASK_SIZE)
5789 + return -ENOMEM;
5790 +
5791 ++#ifdef CONFIG_PAX_RANDMMAP
5792 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5793 ++#endif
5794 ++
5795 + if (addr) {
5796 + if (do_align)
5797 + addr = COLOUR_ALIGN(addr, pgoff);
5798 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
5799 + return addr;
5800 + }
5801 + if (len > mm->cached_hole_size) {
5802 +- start_addr = addr = mm->free_area_cache;
5803 ++ start_addr = addr = mm->free_area_cache;
5804 + } else {
5805 +- start_addr = addr = TASK_UNMAPPED_BASE;
5806 +- mm->cached_hole_size = 0;
5807 ++ start_addr = addr = mm->mmap_base;
5808 ++ mm->cached_hole_size = 0;
5809 + }
5810 +
5811 + full_search:
5812 +@@ -91,8 +95,8 @@ full_search:
5813 + * Start a new search - just in case we missed
5814 + * some holes.
5815 + */
5816 +- if (start_addr != TASK_UNMAPPED_BASE) {
5817 +- start_addr = addr = TASK_UNMAPPED_BASE;
5818 ++ if (start_addr != mm->mmap_base) {
5819 ++ start_addr = addr = mm->mmap_base;
5820 + mm->cached_hole_size = 0;
5821 + goto full_search;
5822 + }
5823 +diff -urNp a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
5824 +--- a/arch/avr32/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
5825 ++++ b/arch/avr32/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
5826 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
5827 +
5828 + int exception_trace = 1;
5829 +
5830 ++#ifdef CONFIG_PAX_PAGEEXEC
5831 ++void pax_report_insns(void *pc, void *sp)
5832 ++{
5833 ++ unsigned long i;
5834 ++
5835 ++ printk(KERN_ERR "PAX: bytes at PC: ");
5836 ++ for (i = 0; i < 20; i++) {
5837 ++ unsigned char c;
5838 ++ if (get_user(c, (unsigned char *)pc+i))
5839 ++ printk(KERN_CONT "???????? ");
5840 ++ else
5841 ++ printk(KERN_CONT "%02x ", c);
5842 ++ }
5843 ++ printk("\n");
5844 ++}
5845 ++#endif
5846 ++
5847 + /*
5848 + * This routine handles page faults. It determines the address and the
5849 + * problem, and then passes it off to one of the appropriate routines.
5850 +@@ -157,6 +174,16 @@ bad_area:
5851 + up_read(&mm->mmap_sem);
5852 +
5853 + if (user_mode(regs)) {
5854 ++
5855 ++#ifdef CONFIG_PAX_PAGEEXEC
5856 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5857 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
5858 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
5859 ++ do_group_exit(SIGKILL);
5860 ++ }
5861 ++ }
5862 ++#endif
5863 ++
5864 + if (exception_trace && printk_ratelimit())
5865 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
5866 + "sp %08lx ecr %lu\n",
5867 +diff -urNp a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
5868 +--- a/arch/ia64/ia32/binfmt_elf32.c 2008-08-20 11:16:13.000000000 -0700
5869 ++++ b/arch/ia64/ia32/binfmt_elf32.c 2008-08-20 18:36:57.000000000 -0700
5870 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
5871 +
5872 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
5873 +
5874 ++#ifdef CONFIG_PAX_ASLR
5875 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
5876 ++
5877 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
5878 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
5879 ++#endif
5880 ++
5881 + /* Ugly but avoids duplication */
5882 + #include "../../../fs/binfmt_elf.c"
5883 +
5884 +diff -urNp a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
5885 +--- a/arch/ia64/ia32/ia32priv.h 2008-08-20 11:16:13.000000000 -0700
5886 ++++ b/arch/ia64/ia32/ia32priv.h 2008-08-20 18:36:57.000000000 -0700
5887 +@@ -303,7 +303,14 @@ struct old_linux32_dirent {
5888 + #define ELF_DATA ELFDATA2LSB
5889 + #define ELF_ARCH EM_386
5890 +
5891 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
5892 ++#ifdef CONFIG_PAX_RANDUSTACK
5893 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
5894 ++#else
5895 ++#define __IA32_DELTA_STACK 0UL
5896 ++#endif
5897 ++
5898 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
5899 ++
5900 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
5901 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
5902 +
5903 +diff -urNp a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
5904 +--- a/arch/ia64/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
5905 ++++ b/arch/ia64/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
5906 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
5907 + void
5908 + module_free (struct module *mod, void *module_region)
5909 + {
5910 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
5911 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
5912 + unw_remove_unwind_table(mod->arch.init_unw_table);
5913 + mod->arch.init_unw_table = NULL;
5914 + }
5915 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
5916 + }
5917 +
5918 + static inline int
5919 ++in_init_rx (const struct module *mod, uint64_t addr)
5920 ++{
5921 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
5922 ++}
5923 ++
5924 ++static inline int
5925 ++in_init_rw (const struct module *mod, uint64_t addr)
5926 ++{
5927 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
5928 ++}
5929 ++
5930 ++static inline int
5931 + in_init (const struct module *mod, uint64_t addr)
5932 + {
5933 +- return addr - (uint64_t) mod->module_init < mod->init_size;
5934 ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
5935 ++}
5936 ++
5937 ++static inline int
5938 ++in_core_rx (const struct module *mod, uint64_t addr)
5939 ++{
5940 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
5941 ++}
5942 ++
5943 ++static inline int
5944 ++in_core_rw (const struct module *mod, uint64_t addr)
5945 ++{
5946 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
5947 + }
5948 +
5949 + static inline int
5950 + in_core (const struct module *mod, uint64_t addr)
5951 + {
5952 +- return addr - (uint64_t) mod->module_core < mod->core_size;
5953 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
5954 + }
5955 +
5956 + static inline int
5957 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
5958 + break;
5959 +
5960 + case RV_BDREL:
5961 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
5962 ++ if (in_init_rx(mod, val))
5963 ++ val -= (uint64_t) mod->module_init_rx;
5964 ++ else if (in_init_rw(mod, val))
5965 ++ val -= (uint64_t) mod->module_init_rw;
5966 ++ else if (in_core_rx(mod, val))
5967 ++ val -= (uint64_t) mod->module_core_rx;
5968 ++ else if (in_core_rw(mod, val))
5969 ++ val -= (uint64_t) mod->module_core_rw;
5970 + break;
5971 +
5972 + case RV_LTV:
5973 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
5974 + * addresses have been selected...
5975 + */
5976 + uint64_t gp;
5977 +- if (mod->core_size > MAX_LTOFF)
5978 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
5979 + /*
5980 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
5981 + * at the end of the module.
5982 + */
5983 +- gp = mod->core_size - MAX_LTOFF / 2;
5984 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
5985 + else
5986 +- gp = mod->core_size / 2;
5987 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
5988 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
5989 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
5990 + mod->arch.gp = gp;
5991 + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
5992 + }
5993 +diff -urNp a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
5994 +--- a/arch/ia64/kernel/sys_ia64.c 2008-08-20 11:16:13.000000000 -0700
5995 ++++ b/arch/ia64/kernel/sys_ia64.c 2008-08-20 18:36:57.000000000 -0700
5996 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
5997 + if (REGION_NUMBER(addr) == RGN_HPAGE)
5998 + addr = 0;
5999 + #endif
6000 ++
6001 ++#ifdef CONFIG_PAX_RANDMMAP
6002 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
6003 ++ addr = mm->free_area_cache;
6004 ++ else
6005 ++#endif
6006 ++
6007 + if (!addr)
6008 + addr = mm->free_area_cache;
6009 +
6010 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
6011 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6012 + /* At this point: (!vma || addr < vma->vm_end). */
6013 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
6014 +- if (start_addr != TASK_UNMAPPED_BASE) {
6015 ++ if (start_addr != mm->mmap_base) {
6016 + /* Start a new search --- just in case we missed some holes. */
6017 +- addr = TASK_UNMAPPED_BASE;
6018 ++ addr = mm->mmap_base;
6019 + goto full_search;
6020 + }
6021 + return -ENOMEM;
6022 +diff -urNp a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
6023 +--- a/arch/ia64/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6024 ++++ b/arch/ia64/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6025 +@@ -10,6 +10,7 @@
6026 + #include <linux/interrupt.h>
6027 + #include <linux/kprobes.h>
6028 + #include <linux/kdebug.h>
6029 ++#include <linux/binfmts.h>
6030 +
6031 + #include <asm/pgtable.h>
6032 + #include <asm/processor.h>
6033 +@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
6034 + return pte_present(pte);
6035 + }
6036 +
6037 ++#ifdef CONFIG_PAX_PAGEEXEC
6038 ++void pax_report_insns(void *pc, void *sp)
6039 ++{
6040 ++ unsigned long i;
6041 ++
6042 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6043 ++ for (i = 0; i < 8; i++) {
6044 ++ unsigned int c;
6045 ++ if (get_user(c, (unsigned int *)pc+i))
6046 ++ printk(KERN_CONT "???????? ");
6047 ++ else
6048 ++ printk(KERN_CONT "%08x ", c);
6049 ++ }
6050 ++ printk("\n");
6051 ++}
6052 ++#endif
6053 ++
6054 + void __kprobes
6055 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
6056 + {
6057 +@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
6058 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
6059 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
6060 +
6061 +- if ((vma->vm_flags & mask) != mask)
6062 ++ if ((vma->vm_flags & mask) != mask) {
6063 ++
6064 ++#ifdef CONFIG_PAX_PAGEEXEC
6065 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
6066 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
6067 ++ goto bad_area;
6068 ++
6069 ++ up_read(&mm->mmap_sem);
6070 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
6071 ++ do_group_exit(SIGKILL);
6072 ++ }
6073 ++#endif
6074 ++
6075 + goto bad_area;
6076 +
6077 ++ }
6078 ++
6079 + survive:
6080 + /*
6081 + * If for any reason at all we couldn't handle the fault, make
6082 +diff -urNp a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
6083 +--- a/arch/ia64/mm/init.c 2008-08-20 11:16:13.000000000 -0700
6084 ++++ b/arch/ia64/mm/init.c 2008-08-20 18:36:57.000000000 -0700
6085 +@@ -128,6 +128,19 @@ ia64_init_addr_space (void)
6086 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
6087 + vma->vm_end = vma->vm_start + PAGE_SIZE;
6088 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
6089 ++
6090 ++#ifdef CONFIG_PAX_PAGEEXEC
6091 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
6092 ++ vma->vm_flags &= ~VM_EXEC;
6093 ++
6094 ++#ifdef CONFIG_PAX_MPROTECT
6095 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
6096 ++ vma->vm_flags &= ~VM_MAYEXEC;
6097 ++#endif
6098 ++
6099 ++ }
6100 ++#endif
6101 ++
6102 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
6103 + down_write(&current->mm->mmap_sem);
6104 + if (insert_vm_struct(current->mm, vma)) {
6105 +diff -urNp a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
6106 +--- a/arch/mips/kernel/binfmt_elfn32.c 2008-08-20 11:16:13.000000000 -0700
6107 ++++ b/arch/mips/kernel/binfmt_elfn32.c 2008-08-20 18:36:57.000000000 -0700
6108 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6109 + #undef ELF_ET_DYN_BASE
6110 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6111 +
6112 ++#ifdef CONFIG_PAX_ASLR
6113 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6114 ++
6115 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6116 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6117 ++#endif
6118 ++
6119 + #include <asm/processor.h>
6120 + #include <linux/module.h>
6121 + #include <linux/elfcore.h>
6122 +diff -urNp a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
6123 +--- a/arch/mips/kernel/binfmt_elfo32.c 2008-08-20 11:16:13.000000000 -0700
6124 ++++ b/arch/mips/kernel/binfmt_elfo32.c 2008-08-20 18:36:57.000000000 -0700
6125 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6126 + #undef ELF_ET_DYN_BASE
6127 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6128 +
6129 ++#ifdef CONFIG_PAX_ASLR
6130 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6131 ++
6132 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6133 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6134 ++#endif
6135 ++
6136 + #include <asm/processor.h>
6137 + #include <linux/module.h>
6138 + #include <linux/elfcore.h>
6139 +diff -urNp a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
6140 +--- a/arch/mips/kernel/syscall.c 2008-08-20 11:16:13.000000000 -0700
6141 ++++ b/arch/mips/kernel/syscall.c 2008-08-20 18:36:57.000000000 -0700
6142 +@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
6143 + do_color_align = 0;
6144 + if (filp || (flags & MAP_SHARED))
6145 + do_color_align = 1;
6146 ++
6147 ++#ifdef CONFIG_PAX_RANDMMAP
6148 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6149 ++#endif
6150 ++
6151 + if (addr) {
6152 + if (do_color_align)
6153 + addr = COLOUR_ALIGN(addr, pgoff);
6154 +@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
6155 + (!vmm || addr + len <= vmm->vm_start))
6156 + return addr;
6157 + }
6158 +- addr = TASK_UNMAPPED_BASE;
6159 ++ addr = current->mm->mmap_base;
6160 + if (do_color_align)
6161 + addr = COLOUR_ALIGN(addr, pgoff);
6162 + else
6163 +diff -urNp a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
6164 +--- a/arch/mips/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6165 ++++ b/arch/mips/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6166 +@@ -26,6 +26,23 @@
6167 + #include <asm/ptrace.h>
6168 + #include <asm/highmem.h> /* For VMALLOC_END */
6169 +
6170 ++#ifdef CONFIG_PAX_PAGEEXEC
6171 ++void pax_report_insns(void *pc)
6172 ++{
6173 ++ unsigned long i;
6174 ++
6175 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6176 ++ for (i = 0; i < 5; i++) {
6177 ++ unsigned int c;
6178 ++ if (get_user(c, (unsigned int *)pc+i))
6179 ++ printk(KERN_CONT "???????? ");
6180 ++ else
6181 ++ printk(KERN_CONT "%08x ", c);
6182 ++ }
6183 ++ printk("\n");
6184 ++}
6185 ++#endif
6186 ++
6187 + /*
6188 + * This routine handles page faults. It determines the address,
6189 + * and the problem, and then passes it off to one of the appropriate
6190 +diff -urNp a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
6191 +--- a/arch/parisc/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
6192 ++++ b/arch/parisc/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
6193 +@@ -73,16 +73,38 @@
6194 +
6195 + /* three functions to determine where in the module core
6196 + * or init pieces the location is */
6197 ++static inline int in_init_rx(struct module *me, void *loc)
6198 ++{
6199 ++ return (loc >= me->module_init_rx &&
6200 ++ loc < (me->module_init_rx + me->init_size_rx));
6201 ++}
6202 ++
6203 ++static inline int in_init_rw(struct module *me, void *loc)
6204 ++{
6205 ++ return (loc >= me->module_init_rw &&
6206 ++ loc < (me->module_init_rw + me->init_size_rw));
6207 ++}
6208 ++
6209 + static inline int in_init(struct module *me, void *loc)
6210 + {
6211 +- return (loc >= me->module_init &&
6212 +- loc <= (me->module_init + me->init_size));
6213 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
6214 ++}
6215 ++
6216 ++static inline int in_core_rx(struct module *me, void *loc)
6217 ++{
6218 ++ return (loc >= me->module_core_rx &&
6219 ++ loc < (me->module_core_rx + me->core_size_rx));
6220 ++}
6221 ++
6222 ++static inline int in_core_rw(struct module *me, void *loc)
6223 ++{
6224 ++ return (loc >= me->module_core_rw &&
6225 ++ loc < (me->module_core_rw + me->core_size_rw));
6226 + }
6227 +
6228 + static inline int in_core(struct module *me, void *loc)
6229 + {
6230 +- return (loc >= me->module_core &&
6231 +- loc <= (me->module_core + me->core_size));
6232 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
6233 + }
6234 +
6235 + static inline int in_local(struct module *me, void *loc)
6236 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
6237 + }
6238 +
6239 + /* align things a bit */
6240 +- me->core_size = ALIGN(me->core_size, 16);
6241 +- me->arch.got_offset = me->core_size;
6242 +- me->core_size += gots * sizeof(struct got_entry);
6243 +-
6244 +- me->core_size = ALIGN(me->core_size, 16);
6245 +- me->arch.fdesc_offset = me->core_size;
6246 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
6247 +-
6248 +- me->core_size = ALIGN(me->core_size, 16);
6249 +- me->arch.stub_offset = me->core_size;
6250 +- me->core_size += stubs * sizeof(struct stub_entry);
6251 +-
6252 +- me->init_size = ALIGN(me->init_size, 16);
6253 +- me->arch.init_stub_offset = me->init_size;
6254 +- me->init_size += init_stubs * sizeof(struct stub_entry);
6255 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
6256 ++ me->arch.got_offset = me->core_size_rw;
6257 ++ me->core_size_rw += gots * sizeof(struct got_entry);
6258 ++
6259 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
6260 ++ me->arch.fdesc_offset = me->core_size_rw;
6261 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
6262 ++
6263 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
6264 ++ me->arch.stub_offset = me->core_size_rx;
6265 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
6266 ++
6267 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
6268 ++ me->arch.init_stub_offset = me->init_size_rx;
6269 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
6270 +
6271 + me->arch.got_max = gots;
6272 + me->arch.fdesc_max = fdescs;
6273 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
6274 +
6275 + BUG_ON(value == 0);
6276 +
6277 +- got = me->module_core + me->arch.got_offset;
6278 ++ got = me->module_core_rw + me->arch.got_offset;
6279 + for (i = 0; got[i].addr; i++)
6280 + if (got[i].addr == value)
6281 + goto out;
6282 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
6283 + #ifdef CONFIG_64BIT
6284 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
6285 + {
6286 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
6287 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
6288 +
6289 + if (!value) {
6290 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
6291 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
6292 +
6293 + /* Create new one */
6294 + fdesc->addr = value;
6295 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6296 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6297 + return (Elf_Addr)fdesc;
6298 + }
6299 + #endif /* CONFIG_64BIT */
6300 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
6301 + if(init_section) {
6302 + i = me->arch.init_stub_count++;
6303 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
6304 +- stub = me->module_init + me->arch.init_stub_offset +
6305 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
6306 + i * sizeof(struct stub_entry);
6307 + } else {
6308 + i = me->arch.stub_count++;
6309 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
6310 +- stub = me->module_core + me->arch.stub_offset +
6311 ++ stub = me->module_core_rx + me->arch.stub_offset +
6312 + i * sizeof(struct stub_entry);
6313 + }
6314 +
6315 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
6316 +
6317 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
6318 + end = table + sechdrs[me->arch.unwind_section].sh_size;
6319 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6320 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6321 +
6322 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
6323 + me->arch.unwind_section, table, end, gp);
6324 +diff -urNp a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
6325 +--- a/arch/parisc/kernel/sys_parisc.c 2008-08-20 11:16:13.000000000 -0700
6326 ++++ b/arch/parisc/kernel/sys_parisc.c 2008-08-20 18:36:57.000000000 -0700
6327 +@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
6328 + if (flags & MAP_FIXED)
6329 + return addr;
6330 + if (!addr)
6331 +- addr = TASK_UNMAPPED_BASE;
6332 ++ addr = current->mm->mmap_base;
6333 +
6334 + if (filp) {
6335 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
6336 +diff -urNp a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
6337 +--- a/arch/parisc/kernel/traps.c 2008-08-20 11:16:13.000000000 -0700
6338 ++++ b/arch/parisc/kernel/traps.c 2008-08-20 18:36:57.000000000 -0700
6339 +@@ -732,9 +732,7 @@ void handle_interruption(int code, struc
6340 +
6341 + down_read(&current->mm->mmap_sem);
6342 + vma = find_vma(current->mm,regs->iaoq[0]);
6343 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
6344 +- && (vma->vm_flags & VM_EXEC)) {
6345 +-
6346 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
6347 + fault_address = regs->iaoq[0];
6348 + fault_space = regs->iasq[0];
6349 +
6350 +diff -urNp a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
6351 +--- a/arch/parisc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6352 ++++ b/arch/parisc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6353 +@@ -16,6 +16,8 @@
6354 + #include <linux/sched.h>
6355 + #include <linux/interrupt.h>
6356 + #include <linux/module.h>
6357 ++#include <linux/unistd.h>
6358 ++#include <linux/binfmts.h>
6359 +
6360 + #include <asm/uaccess.h>
6361 + #include <asm/traps.h>
6362 +@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
6363 + static unsigned long
6364 + parisc_acctyp(unsigned long code, unsigned int inst)
6365 + {
6366 +- if (code == 6 || code == 16)
6367 ++ if (code == 6 || code == 7 || code == 16)
6368 + return VM_EXEC;
6369 +
6370 + switch (inst & 0xf0000000) {
6371 +@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
6372 + }
6373 + #endif
6374 +
6375 ++#ifdef CONFIG_PAX_PAGEEXEC
6376 ++/*
6377 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
6378 ++ *
6379 ++ * returns 1 when task should be killed
6380 ++ * 2 when rt_sigreturn trampoline was detected
6381 ++ * 3 when unpatched PLT trampoline was detected
6382 ++ */
6383 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
6384 ++{
6385 ++
6386 ++#ifdef CONFIG_PAX_EMUPLT
6387 ++ int err;
6388 ++
6389 ++ do { /* PaX: unpatched PLT emulation */
6390 ++ unsigned int bl, depwi;
6391 ++
6392 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
6393 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
6394 ++
6395 ++ if (err)
6396 ++ break;
6397 ++
6398 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
6399 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
6400 ++
6401 ++ err = get_user(ldw, (unsigned int *)addr);
6402 ++ err |= get_user(bv, (unsigned int *)(addr+4));
6403 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
6404 ++
6405 ++ if (err)
6406 ++ break;
6407 ++
6408 ++ if (ldw == 0x0E801096U &&
6409 ++ bv == 0xEAC0C000U &&
6410 ++ ldw2 == 0x0E881095U)
6411 ++ {
6412 ++ unsigned int resolver, map;
6413 ++
6414 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
6415 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
6416 ++ if (err)
6417 ++ break;
6418 ++
6419 ++ regs->gr[20] = instruction_pointer(regs)+8;
6420 ++ regs->gr[21] = map;
6421 ++ regs->gr[22] = resolver;
6422 ++ regs->iaoq[0] = resolver | 3UL;
6423 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
6424 ++ return 3;
6425 ++ }
6426 ++ }
6427 ++ } while (0);
6428 ++#endif
6429 ++
6430 ++#ifdef CONFIG_PAX_EMUTRAMP
6431 ++
6432 ++#ifndef CONFIG_PAX_EMUSIGRT
6433 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6434 ++ return 1;
6435 ++#endif
6436 ++
6437 ++ do { /* PaX: rt_sigreturn emulation */
6438 ++ unsigned int ldi1, ldi2, bel, nop;
6439 ++
6440 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
6441 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
6442 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
6443 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
6444 ++
6445 ++ if (err)
6446 ++ break;
6447 ++
6448 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
6449 ++ ldi2 == 0x3414015AU &&
6450 ++ bel == 0xE4008200U &&
6451 ++ nop == 0x08000240U)
6452 ++ {
6453 ++ regs->gr[25] = (ldi1 & 2) >> 1;
6454 ++ regs->gr[20] = __NR_rt_sigreturn;
6455 ++ regs->gr[31] = regs->iaoq[1] + 16;
6456 ++ regs->sr[0] = regs->iasq[1];
6457 ++ regs->iaoq[0] = 0x100UL;
6458 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
6459 ++ regs->iasq[0] = regs->sr[2];
6460 ++ regs->iasq[1] = regs->sr[2];
6461 ++ return 2;
6462 ++ }
6463 ++ } while (0);
6464 ++#endif
6465 ++
6466 ++ return 1;
6467 ++}
6468 ++
6469 ++void pax_report_insns(void *pc, void *sp)
6470 ++{
6471 ++ unsigned long i;
6472 ++
6473 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6474 ++ for (i = 0; i < 5; i++) {
6475 ++ unsigned int c;
6476 ++ if (get_user(c, (unsigned int *)pc+i))
6477 ++ printk(KERN_CONT "???????? ");
6478 ++ else
6479 ++ printk(KERN_CONT "%08x ", c);
6480 ++ }
6481 ++ printk("\n");
6482 ++}
6483 ++#endif
6484 ++
6485 + void do_page_fault(struct pt_regs *regs, unsigned long code,
6486 + unsigned long address)
6487 + {
6488 +@@ -165,8 +277,33 @@ good_area:
6489 +
6490 + acc_type = parisc_acctyp(code,regs->iir);
6491 +
6492 +- if ((vma->vm_flags & acc_type) != acc_type)
6493 ++ if ((vma->vm_flags & acc_type) != acc_type) {
6494 ++
6495 ++#ifdef CONFIG_PAX_PAGEEXEC
6496 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
6497 ++ (address & ~3UL) == instruction_pointer(regs))
6498 ++ {
6499 ++ up_read(&mm->mmap_sem);
6500 ++ switch (pax_handle_fetch_fault(regs)) {
6501 ++
6502 ++#ifdef CONFIG_PAX_EMUPLT
6503 ++ case 3:
6504 ++ return;
6505 ++#endif
6506 ++
6507 ++#ifdef CONFIG_PAX_EMUTRAMP
6508 ++ case 2:
6509 ++ return;
6510 ++#endif
6511 ++
6512 ++ }
6513 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
6514 ++ do_group_exit(SIGKILL);
6515 ++ }
6516 ++#endif
6517 ++
6518 + goto bad_area;
6519 ++ }
6520 +
6521 + /*
6522 + * If for any reason at all we couldn't handle the fault, make
6523 +diff -urNp a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
6524 +--- a/arch/powerpc/kernel/module_32.c 2008-08-20 11:16:13.000000000 -0700
6525 ++++ b/arch/powerpc/kernel/module_32.c 2008-08-20 18:36:57.000000000 -0700
6526 +@@ -175,7 +175,7 @@ int module_frob_arch_sections(Elf32_Ehdr
6527 + me->arch.core_plt_section = i;
6528 + }
6529 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
6530 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
6531 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
6532 + return -ENOEXEC;
6533 + }
6534 +
6535 +@@ -216,11 +216,16 @@ static uint32_t do_plt_call(void *locati
6536 +
6537 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
6538 + /* Init, or core PLT? */
6539 +- if (location >= mod->module_core
6540 +- && location < mod->module_core + mod->core_size)
6541 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
6542 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
6543 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
6544 +- else
6545 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
6546 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
6547 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
6548 ++ else {
6549 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
6550 ++ return ~0UL;
6551 ++ }
6552 +
6553 + /* Find this entry, or if that fails, the next avail. entry */
6554 + while (entry->jump[0]) {
6555 +diff -urNp a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
6556 +--- a/arch/powerpc/kernel/signal_32.c 2008-08-20 11:16:13.000000000 -0700
6557 ++++ b/arch/powerpc/kernel/signal_32.c 2008-08-20 18:36:57.000000000 -0700
6558 +@@ -730,7 +730,7 @@ int handle_rt_signal32(unsigned long sig
6559 + /* Save user registers on the stack */
6560 + frame = &rt_sf->uc.uc_mcontext;
6561 + addr = frame;
6562 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
6563 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
6564 + if (save_user_regs(regs, frame, 0))
6565 + goto badframe;
6566 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
6567 +diff -urNp a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
6568 +--- a/arch/powerpc/kernel/signal_64.c 2008-08-20 11:16:13.000000000 -0700
6569 ++++ b/arch/powerpc/kernel/signal_64.c 2008-08-20 18:36:57.000000000 -0700
6570 +@@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
6571 + current->thread.fpscr.val = 0;
6572 +
6573 + /* Set up to return from userspace. */
6574 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
6575 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
6576 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
6577 + } else {
6578 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
6579 +diff -urNp a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
6580 +--- a/arch/powerpc/kernel/vdso.c 2008-08-20 11:16:13.000000000 -0700
6581 ++++ b/arch/powerpc/kernel/vdso.c 2008-08-20 18:36:57.000000000 -0700
6582 +@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
6583 + vdso_base = VDSO32_MBASE;
6584 + #endif
6585 +
6586 +- current->mm->context.vdso_base = 0;
6587 ++ current->mm->context.vdso_base = ~0UL;
6588 +
6589 + /* vDSO has a problem and was disabled, just don't "enable" it for the
6590 + * process
6591 +@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
6592 + */
6593 + down_write(&mm->mmap_sem);
6594 + vdso_base = get_unmapped_area(NULL, vdso_base,
6595 +- vdso_pages << PAGE_SHIFT, 0, 0);
6596 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
6597 + if (IS_ERR_VALUE(vdso_base)) {
6598 + rc = vdso_base;
6599 + goto fail_mmapsem;
6600 +diff -urNp a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
6601 +--- a/arch/powerpc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6602 ++++ b/arch/powerpc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6603 +@@ -29,6 +29,12 @@
6604 + #include <linux/module.h>
6605 + #include <linux/kprobes.h>
6606 + #include <linux/kdebug.h>
6607 ++#include <linux/binfmts.h>
6608 ++#include <linux/slab.h>
6609 ++#include <linux/pagemap.h>
6610 ++#include <linux/compiler.h>
6611 ++#include <linux/binfmts.h>
6612 ++#include <linux/unistd.h>
6613 +
6614 + #include <asm/page.h>
6615 + #include <asm/pgtable.h>
6616 +@@ -62,6 +68,366 @@ static inline int notify_page_fault(stru
6617 + }
6618 + #endif
6619 +
6620 ++#ifdef CONFIG_PAX_EMUSIGRT
6621 ++void pax_syscall_close(struct vm_area_struct *vma)
6622 ++{
6623 ++ vma->vm_mm->call_syscall = 0UL;
6624 ++}
6625 ++
6626 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6627 ++{
6628 ++ struct page *page;
6629 ++ unsigned int *kaddr;
6630 ++
6631 ++ page = alloc_page(GFP_HIGHUSER);
6632 ++ if (!page)
6633 ++ return NOPAGE_OOM;
6634 ++
6635 ++ kaddr = kmap(page);
6636 ++ memset(kaddr, 0, PAGE_SIZE);
6637 ++ kaddr[0] = 0x44000002U; /* sc */
6638 ++ __flush_dcache_icache(kaddr);
6639 ++ kunmap(page);
6640 ++ if (type)
6641 ++ *type = VM_FAULT_MAJOR;
6642 ++ return page;
6643 ++}
6644 ++
6645 ++static struct vm_operations_struct pax_vm_ops = {
6646 ++ .close = pax_syscall_close,
6647 ++ .nopage = pax_syscall_nopage,
6648 ++};
6649 ++
6650 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6651 ++{
6652 ++ int ret;
6653 ++
6654 ++ vma->vm_mm = current->mm;
6655 ++ vma->vm_start = addr;
6656 ++ vma->vm_end = addr + PAGE_SIZE;
6657 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6658 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
6659 ++ vma->vm_ops = &pax_vm_ops;
6660 ++
6661 ++ ret = insert_vm_struct(current->mm, vma);
6662 ++ if (ret)
6663 ++ return ret;
6664 ++
6665 ++ ++current->mm->total_vm;
6666 ++ return 0;
6667 ++}
6668 ++#endif
6669 ++
6670 ++#ifdef CONFIG_PAX_PAGEEXEC
6671 ++/*
6672 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
6673 ++ *
6674 ++ * returns 1 when task should be killed
6675 ++ * 2 when patched GOT trampoline was detected
6676 ++ * 3 when patched PLT trampoline was detected
6677 ++ * 4 when unpatched PLT trampoline was detected
6678 ++ * 5 when sigreturn trampoline was detected
6679 ++ * 6 when rt_sigreturn trampoline was detected
6680 ++ */
6681 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
6682 ++{
6683 ++
6684 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6685 ++ int err;
6686 ++#endif
6687 ++
6688 ++#ifdef CONFIG_PAX_EMUPLT
6689 ++ do { /* PaX: patched GOT emulation */
6690 ++ unsigned int blrl;
6691 ++
6692 ++ err = get_user(blrl, (unsigned int *)regs->nip);
6693 ++
6694 ++ if (!err && blrl == 0x4E800021U) {
6695 ++ unsigned long temp = regs->nip;
6696 ++
6697 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
6698 ++ regs->link = temp + 4UL;
6699 ++ return 2;
6700 ++ }
6701 ++ } while (0);
6702 ++
6703 ++ do { /* PaX: patched PLT emulation #1 */
6704 ++ unsigned int b;
6705 ++
6706 ++ err = get_user(b, (unsigned int *)regs->nip);
6707 ++
6708 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
6709 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
6710 ++ return 3;
6711 ++ }
6712 ++ } while (0);
6713 ++
6714 ++ do { /* PaX: unpatched PLT emulation #1 */
6715 ++ unsigned int li, b;
6716 ++
6717 ++ err = get_user(li, (unsigned int *)regs->nip);
6718 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
6719 ++
6720 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6721 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6722 ++ unsigned long addr = b | 0xFC000000UL;
6723 ++
6724 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6725 ++ err = get_user(rlwinm, (unsigned int *)addr);
6726 ++ err |= get_user(add, (unsigned int *)(addr+4));
6727 ++ err |= get_user(li2, (unsigned int *)(addr+8));
6728 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
6729 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
6730 ++ err |= get_user(li3, (unsigned int *)(addr+20));
6731 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
6732 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
6733 ++
6734 ++ if (err)
6735 ++ break;
6736 ++
6737 ++ if (rlwinm == 0x556C083CU &&
6738 ++ add == 0x7D6C5A14U &&
6739 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
6740 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6741 ++ mtctr == 0x7D8903A6U &&
6742 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
6743 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6744 ++ bctr == 0x4E800420U)
6745 ++ {
6746 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6747 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6748 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6749 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6750 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
6751 ++ regs->nip = regs->ctr;
6752 ++ return 4;
6753 ++ }
6754 ++ }
6755 ++ } while (0);
6756 ++
6757 ++#if 0
6758 ++ do { /* PaX: unpatched PLT emulation #2 */
6759 ++ unsigned int lis, lwzu, b, bctr;
6760 ++
6761 ++ err = get_user(lis, (unsigned int *)regs->nip);
6762 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
6763 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
6764 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
6765 ++
6766 ++ if (err)
6767 ++ break;
6768 ++
6769 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
6770 ++ (lwzu & 0xU) == 0xU &&
6771 ++ (b & 0xFC000003U) == 0x48000000U &&
6772 ++ bctr == 0x4E800420U)
6773 ++ {
6774 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6775 ++ unsigned long addr = b | 0xFC000000UL;
6776 ++
6777 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6778 ++ err = get_user(addis, (unsigned int *)addr);
6779 ++ err |= get_user(addi, (unsigned int *)(addr+4));
6780 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
6781 ++ err |= get_user(add, (unsigned int *)(addr+12));
6782 ++ err |= get_user(li2, (unsigned int *)(addr+16));
6783 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
6784 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
6785 ++ err |= get_user(li3, (unsigned int *)(addr+28));
6786 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
6787 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
6788 ++
6789 ++ if (err)
6790 ++ break;
6791 ++
6792 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6793 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
6794 ++ rlwinm == 0x556C083CU &&
6795 ++ add == 0x7D6C5A14U &&
6796 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
6797 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6798 ++ mtctr == 0x7D8903A6U &&
6799 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
6800 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6801 ++ bctr == 0x4E800420U)
6802 ++ {
6803 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6804 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6805 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6806 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6807 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
6808 ++ regs->nip = regs->ctr;
6809 ++ return 4;
6810 ++ }
6811 ++ }
6812 ++ } while (0);
6813 ++#endif
6814 ++
6815 ++ do { /* PaX: unpatched PLT emulation #3 */
6816 ++ unsigned int li, b;
6817 ++
6818 ++ err = get_user(li, (unsigned int *)regs->nip);
6819 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
6820 ++
6821 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6822 ++ unsigned int addis, lwz, mtctr, bctr;
6823 ++ unsigned long addr = b | 0xFC000000UL;
6824 ++
6825 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6826 ++ err = get_user(addis, (unsigned int *)addr);
6827 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
6828 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
6829 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
6830 ++
6831 ++ if (err)
6832 ++ break;
6833 ++
6834 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6835 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
6836 ++ mtctr == 0x7D6903A6U &&
6837 ++ bctr == 0x4E800420U)
6838 ++ {
6839 ++ unsigned int r11;
6840 ++
6841 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6842 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6843 ++
6844 ++ err = get_user(r11, (unsigned int *)addr);
6845 ++ if (err)
6846 ++ break;
6847 ++
6848 ++ regs->gpr[PT_R11] = r11;
6849 ++ regs->ctr = r11;
6850 ++ regs->nip = r11;
6851 ++ return 4;
6852 ++ }
6853 ++ }
6854 ++ } while (0);
6855 ++#endif
6856 ++
6857 ++#ifdef CONFIG_PAX_EMUSIGRT
6858 ++ do { /* PaX: sigreturn emulation */
6859 ++ unsigned int li, sc;
6860 ++
6861 ++ err = get_user(li, (unsigned int *)regs->nip);
6862 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
6863 ++
6864 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
6865 ++ struct vm_area_struct *vma;
6866 ++ unsigned long call_syscall;
6867 ++
6868 ++ down_read(&current->mm->mmap_sem);
6869 ++ call_syscall = current->mm->call_syscall;
6870 ++ up_read(&current->mm->mmap_sem);
6871 ++ if (likely(call_syscall))
6872 ++ goto emulate;
6873 ++
6874 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
6875 ++
6876 ++ down_write(&current->mm->mmap_sem);
6877 ++ if (current->mm->call_syscall) {
6878 ++ call_syscall = current->mm->call_syscall;
6879 ++ up_write(&current->mm->mmap_sem);
6880 ++ if (vma)
6881 ++ kmem_cache_free(vm_area_cachep, vma);
6882 ++ goto emulate;
6883 ++ }
6884 ++
6885 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6886 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
6887 ++ up_write(&current->mm->mmap_sem);
6888 ++ if (vma)
6889 ++ kmem_cache_free(vm_area_cachep, vma);
6890 ++ return 1;
6891 ++ }
6892 ++
6893 ++ if (pax_insert_vma(vma, call_syscall)) {
6894 ++ up_write(&current->mm->mmap_sem);
6895 ++ kmem_cache_free(vm_area_cachep, vma);
6896 ++ return 1;
6897 ++ }
6898 ++
6899 ++ current->mm->call_syscall = call_syscall;
6900 ++ up_write(&current->mm->mmap_sem);
6901 ++
6902 ++emulate:
6903 ++ regs->gpr[PT_R0] = __NR_sigreturn;
6904 ++ regs->nip = call_syscall;
6905 ++ return 5;
6906 ++ }
6907 ++ } while (0);
6908 ++
6909 ++ do { /* PaX: rt_sigreturn emulation */
6910 ++ unsigned int li, sc;
6911 ++
6912 ++ err = get_user(li, (unsigned int *)regs->nip);
6913 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
6914 ++
6915 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6916 ++ struct vm_area_struct *vma;
6917 ++ unsigned int call_syscall;
6918 ++
6919 ++ down_read(&current->mm->mmap_sem);
6920 ++ call_syscall = current->mm->call_syscall;
6921 ++ up_read(&current->mm->mmap_sem);
6922 ++ if (likely(call_syscall))
6923 ++ goto rt_emulate;
6924 ++
6925 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
6926 ++
6927 ++ down_write(&current->mm->mmap_sem);
6928 ++ if (current->mm->call_syscall) {
6929 ++ call_syscall = current->mm->call_syscall;
6930 ++ up_write(&current->mm->mmap_sem);
6931 ++ if (vma)
6932 ++ kmem_cache_free(vm_area_cachep, vma);
6933 ++ goto rt_emulate;
6934 ++ }
6935 ++
6936 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6937 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
6938 ++ up_write(&current->mm->mmap_sem);
6939 ++ if (vma)
6940 ++ kmem_cache_free(vm_area_cachep, vma);
6941 ++ return 1;
6942 ++ }
6943 ++
6944 ++ if (pax_insert_vma(vma, call_syscall)) {
6945 ++ up_write(&current->mm->mmap_sem);
6946 ++ kmem_cache_free(vm_area_cachep, vma);
6947 ++ return 1;
6948 ++ }
6949 ++
6950 ++ current->mm->call_syscall = call_syscall;
6951 ++ up_write(&current->mm->mmap_sem);
6952 ++
6953 ++rt_emulate:
6954 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
6955 ++ regs->nip = call_syscall;
6956 ++ return 6;
6957 ++ }
6958 ++ } while (0);
6959 ++#endif
6960 ++
6961 ++ return 1;
6962 ++}
6963 ++
6964 ++void pax_report_insns(void *pc, void *sp)
6965 ++{
6966 ++ unsigned long i;
6967 ++
6968 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6969 ++ for (i = 0; i < 5; i++) {
6970 ++ unsigned int c;
6971 ++ if (get_user(c, (unsigned int *)pc+i))
6972 ++ printk(KERN_CONT "???????? ");
6973 ++ else
6974 ++ printk(KERN_CONT "%08x ", c);
6975 ++ }
6976 ++ printk("\n");
6977 ++}
6978 ++#endif
6979 ++
6980 + /*
6981 + * Check whether the instruction at regs->nip is a store using
6982 + * an update addressing form which will update r1.
6983 +@@ -157,7 +523,7 @@ int __kprobes do_page_fault(struct pt_re
6984 + * indicate errors in DSISR but can validly be set in SRR1.
6985 + */
6986 + if (trap == 0x400)
6987 +- error_code &= 0x48200000;
6988 ++ error_code &= 0x58200000;
6989 + else
6990 + is_write = error_code & DSISR_ISSTORE;
6991 + #else
6992 +@@ -355,6 +721,37 @@ bad_area:
6993 + bad_area_nosemaphore:
6994 + /* User mode accesses cause a SIGSEGV */
6995 + if (user_mode(regs)) {
6996 ++
6997 ++#ifdef CONFIG_PAX_PAGEEXEC
6998 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6999 ++#ifdef CONFIG_PPC64
7000 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
7001 ++#else
7002 ++ if (is_exec && regs->nip == address) {
7003 ++#endif
7004 ++ switch (pax_handle_fetch_fault(regs)) {
7005 ++
7006 ++#ifdef CONFIG_PAX_EMUPLT
7007 ++ case 2:
7008 ++ case 3:
7009 ++ case 4:
7010 ++ return 0;
7011 ++#endif
7012 ++
7013 ++#ifdef CONFIG_PAX_EMUSIGRT
7014 ++ case 5:
7015 ++ case 6:
7016 ++ return 0;
7017 ++#endif
7018 ++
7019 ++ }
7020 ++
7021 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
7022 ++ do_group_exit(SIGKILL);
7023 ++ }
7024 ++ }
7025 ++#endif
7026 ++
7027 + _exception(SIGSEGV, regs, code, address);
7028 + return 0;
7029 + }
7030 +diff -urNp a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
7031 +--- a/arch/powerpc/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
7032 ++++ b/arch/powerpc/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
7033 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
7034 + */
7035 + if (mmap_is_legacy()) {
7036 + mm->mmap_base = TASK_UNMAPPED_BASE;
7037 ++
7038 ++#ifdef CONFIG_PAX_RANDMMAP
7039 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7040 ++ mm->mmap_base += mm->delta_mmap;
7041 ++#endif
7042 ++
7043 + mm->get_unmapped_area = arch_get_unmapped_area;
7044 + mm->unmap_area = arch_unmap_area;
7045 + } else {
7046 + mm->mmap_base = mmap_base();
7047 ++
7048 ++#ifdef CONFIG_PAX_RANDMMAP
7049 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7050 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7051 ++#endif
7052 ++
7053 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7054 + mm->unmap_area = arch_unmap_area_topdown;
7055 + }
7056 +diff -urNp a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
7057 +--- a/arch/ppc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
7058 ++++ b/arch/ppc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
7059 +@@ -25,6 +25,11 @@
7060 + #include <linux/interrupt.h>
7061 + #include <linux/highmem.h>
7062 + #include <linux/module.h>
7063 ++#include <linux/slab.h>
7064 ++#include <linux/pagemap.h>
7065 ++#include <linux/compiler.h>
7066 ++#include <linux/binfmts.h>
7067 ++#include <linux/unistd.h>
7068 +
7069 + #include <asm/page.h>
7070 + #include <asm/pgtable.h>
7071 +@@ -48,6 +53,366 @@ unsigned long pte_misses; /* updated by
7072 + unsigned long pte_errors; /* updated by do_page_fault() */
7073 + unsigned int probingmem;
7074 +
7075 ++#ifdef CONFIG_PAX_EMUSIGRT
7076 ++void pax_syscall_close(struct vm_area_struct *vma)
7077 ++{
7078 ++ vma->vm_mm->call_syscall = 0UL;
7079 ++}
7080 ++
7081 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7082 ++{
7083 ++ struct page *page;
7084 ++ unsigned int *kaddr;
7085 ++
7086 ++ page = alloc_page(GFP_HIGHUSER);
7087 ++ if (!page)
7088 ++ return NOPAGE_OOM;
7089 ++
7090 ++ kaddr = kmap(page);
7091 ++ memset(kaddr, 0, PAGE_SIZE);
7092 ++ kaddr[0] = 0x44000002U; /* sc */
7093 ++ __flush_dcache_icache(kaddr);
7094 ++ kunmap(page);
7095 ++ if (type)
7096 ++ *type = VM_FAULT_MAJOR;
7097 ++ return page;
7098 ++}
7099 ++
7100 ++static struct vm_operations_struct pax_vm_ops = {
7101 ++ .close = pax_syscall_close,
7102 ++ .nopage = pax_syscall_nopage,
7103 ++};
7104 ++
7105 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7106 ++{
7107 ++ int ret;
7108 ++
7109 ++ vma->vm_mm = current->mm;
7110 ++ vma->vm_start = addr;
7111 ++ vma->vm_end = addr + PAGE_SIZE;
7112 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7113 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
7114 ++ vma->vm_ops = &pax_vm_ops;
7115 ++
7116 ++ ret = insert_vm_struct(current->mm, vma);
7117 ++ if (ret)
7118 ++ return ret;
7119 ++
7120 ++ ++current->mm->total_vm;
7121 ++ return 0;
7122 ++}
7123 ++#endif
7124 ++
7125 ++#ifdef CONFIG_PAX_PAGEEXEC
7126 ++/*
7127 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
7128 ++ *
7129 ++ * returns 1 when task should be killed
7130 ++ * 2 when patched GOT trampoline was detected
7131 ++ * 3 when patched PLT trampoline was detected
7132 ++ * 4 when unpatched PLT trampoline was detected
7133 ++ * 5 when sigreturn trampoline was detected
7134 ++ * 6 when rt_sigreturn trampoline was detected
7135 ++ */
7136 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
7137 ++{
7138 ++
7139 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7140 ++ int err;
7141 ++#endif
7142 ++
7143 ++#ifdef CONFIG_PAX_EMUPLT
7144 ++ do { /* PaX: patched GOT emulation */
7145 ++ unsigned int blrl;
7146 ++
7147 ++ err = get_user(blrl, (unsigned int *)regs->nip);
7148 ++
7149 ++ if (!err && blrl == 0x4E800021U) {
7150 ++ unsigned long temp = regs->nip;
7151 ++
7152 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
7153 ++ regs->link = temp + 4UL;
7154 ++ return 2;
7155 ++ }
7156 ++ } while (0);
7157 ++
7158 ++ do { /* PaX: patched PLT emulation #1 */
7159 ++ unsigned int b;
7160 ++
7161 ++ err = get_user(b, (unsigned int *)regs->nip);
7162 ++
7163 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
7164 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
7165 ++ return 3;
7166 ++ }
7167 ++ } while (0);
7168 ++
7169 ++ do { /* PaX: unpatched PLT emulation #1 */
7170 ++ unsigned int li, b;
7171 ++
7172 ++ err = get_user(li, (unsigned int *)regs->nip);
7173 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
7174 ++
7175 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7176 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7177 ++ unsigned long addr = b | 0xFC000000UL;
7178 ++
7179 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7180 ++ err = get_user(rlwinm, (unsigned int *)addr);
7181 ++ err |= get_user(add, (unsigned int *)(addr+4));
7182 ++ err |= get_user(li2, (unsigned int *)(addr+8));
7183 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
7184 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
7185 ++ err |= get_user(li3, (unsigned int *)(addr+20));
7186 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
7187 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
7188 ++
7189 ++ if (err)
7190 ++ break;
7191 ++
7192 ++ if (rlwinm == 0x556C083CU &&
7193 ++ add == 0x7D6C5A14U &&
7194 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
7195 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7196 ++ mtctr == 0x7D8903A6U &&
7197 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
7198 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7199 ++ bctr == 0x4E800420U)
7200 ++ {
7201 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7202 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7203 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7204 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7205 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
7206 ++ regs->nip = regs->ctr;
7207 ++ return 4;
7208 ++ }
7209 ++ }
7210 ++ } while (0);
7211 ++
7212 ++#if 0
7213 ++ do { /* PaX: unpatched PLT emulation #2 */
7214 ++ unsigned int lis, lwzu, b, bctr;
7215 ++
7216 ++ err = get_user(lis, (unsigned int *)regs->nip);
7217 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
7218 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
7219 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
7220 ++
7221 ++ if (err)
7222 ++ break;
7223 ++
7224 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
7225 ++ (lwzu & 0xU) == 0xU &&
7226 ++ (b & 0xFC000003U) == 0x48000000U &&
7227 ++ bctr == 0x4E800420U)
7228 ++ {
7229 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7230 ++ unsigned long addr = b | 0xFC000000UL;
7231 ++
7232 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7233 ++ err = get_user(addis, (unsigned int *)addr);
7234 ++ err |= get_user(addi, (unsigned int *)(addr+4));
7235 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
7236 ++ err |= get_user(add, (unsigned int *)(addr+12));
7237 ++ err |= get_user(li2, (unsigned int *)(addr+16));
7238 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
7239 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
7240 ++ err |= get_user(li3, (unsigned int *)(addr+28));
7241 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
7242 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
7243 ++
7244 ++ if (err)
7245 ++ break;
7246 ++
7247 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7248 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
7249 ++ rlwinm == 0x556C083CU &&
7250 ++ add == 0x7D6C5A14U &&
7251 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
7252 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7253 ++ mtctr == 0x7D8903A6U &&
7254 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
7255 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7256 ++ bctr == 0x4E800420U)
7257 ++ {
7258 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7259 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7260 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7261 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7262 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
7263 ++ regs->nip = regs->ctr;
7264 ++ return 4;
7265 ++ }
7266 ++ }
7267 ++ } while (0);
7268 ++#endif
7269 ++
7270 ++ do { /* PaX: unpatched PLT emulation #3 */
7271 ++ unsigned int li, b;
7272 ++
7273 ++ err = get_user(li, (unsigned int *)regs->nip);
7274 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
7275 ++
7276 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7277 ++ unsigned int addis, lwz, mtctr, bctr;
7278 ++ unsigned long addr = b | 0xFC000000UL;
7279 ++
7280 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7281 ++ err = get_user(addis, (unsigned int *)addr);
7282 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
7283 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
7284 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
7285 ++
7286 ++ if (err)
7287 ++ break;
7288 ++
7289 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7290 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
7291 ++ mtctr == 0x7D6903A6U &&
7292 ++ bctr == 0x4E800420U)
7293 ++ {
7294 ++ unsigned int r11;
7295 ++
7296 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7297 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7298 ++
7299 ++ err = get_user(r11, (unsigned int *)addr);
7300 ++ if (err)
7301 ++ break;
7302 ++
7303 ++ regs->gpr[PT_R11] = r11;
7304 ++ regs->ctr = r11;
7305 ++ regs->nip = r11;
7306 ++ return 4;
7307 ++ }
7308 ++ }
7309 ++ } while (0);
7310 ++#endif
7311 ++
7312 ++#ifdef CONFIG_PAX_EMUSIGRT
7313 ++ do { /* PaX: sigreturn emulation */
7314 ++ unsigned int li, sc;
7315 ++
7316 ++ err = get_user(li, (unsigned int *)regs->nip);
7317 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
7318 ++
7319 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
7320 ++ struct vm_area_struct *vma;
7321 ++ unsigned long call_syscall;
7322 ++
7323 ++ down_read(&current->mm->mmap_sem);
7324 ++ call_syscall = current->mm->call_syscall;
7325 ++ up_read(&current->mm->mmap_sem);
7326 ++ if (likely(call_syscall))
7327 ++ goto emulate;
7328 ++
7329 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
7330 ++
7331 ++ down_write(&current->mm->mmap_sem);
7332 ++ if (current->mm->call_syscall) {
7333 ++ call_syscall = current->mm->call_syscall;
7334 ++ up_write(&current->mm->mmap_sem);
7335 ++ if (vma)
7336 ++ kmem_cache_free(vm_area_cachep, vma);
7337 ++ goto emulate;
7338 ++ }
7339 ++
7340 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7341 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
7342 ++ up_write(&current->mm->mmap_sem);
7343 ++ if (vma)
7344 ++ kmem_cache_free(vm_area_cachep, vma);
7345 ++ return 1;
7346 ++ }
7347 ++
7348 ++ if (pax_insert_vma(vma, call_syscall)) {
7349 ++ up_write(&current->mm->mmap_sem);
7350 ++ kmem_cache_free(vm_area_cachep, vma);
7351 ++ return 1;
7352 ++ }
7353 ++
7354 ++ current->mm->call_syscall = call_syscall;
7355 ++ up_write(&current->mm->mmap_sem);
7356 ++
7357 ++emulate:
7358 ++ regs->gpr[PT_R0] = __NR_sigreturn;
7359 ++ regs->nip = call_syscall;
7360 ++ return 5;
7361 ++ }
7362 ++ } while (0);
7363 ++
7364 ++ do { /* PaX: rt_sigreturn emulation */
7365 ++ unsigned int li, sc;
7366 ++
7367 ++ err = get_user(li, (unsigned int *)regs->nip);
7368 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
7369 ++
7370 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
7371 ++ struct vm_area_struct *vma;
7372 ++ unsigned int call_syscall;
7373 ++
7374 ++ down_read(&current->mm->mmap_sem);
7375 ++ call_syscall = current->mm->call_syscall;
7376 ++ up_read(&current->mm->mmap_sem);
7377 ++ if (likely(call_syscall))
7378 ++ goto rt_emulate;
7379 ++
7380 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
7381 ++
7382 ++ down_write(&current->mm->mmap_sem);
7383 ++ if (current->mm->call_syscall) {
7384 ++ call_syscall = current->mm->call_syscall;
7385 ++ up_write(&current->mm->mmap_sem);
7386 ++ if (vma)
7387 ++ kmem_cache_free(vm_area_cachep, vma);
7388 ++ goto rt_emulate;
7389 ++ }
7390 ++
7391 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7392 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
7393 ++ up_write(&current->mm->mmap_sem);
7394 ++ if (vma)
7395 ++ kmem_cache_free(vm_area_cachep, vma);
7396 ++ return 1;
7397 ++ }
7398 ++
7399 ++ if (pax_insert_vma(vma, call_syscall)) {
7400 ++ up_write(&current->mm->mmap_sem);
7401 ++ kmem_cache_free(vm_area_cachep, vma);
7402 ++ return 1;
7403 ++ }
7404 ++
7405 ++ current->mm->call_syscall = call_syscall;
7406 ++ up_write(&current->mm->mmap_sem);
7407 ++
7408 ++rt_emulate:
7409 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
7410 ++ regs->nip = call_syscall;
7411 ++ return 6;
7412 ++ }
7413 ++ } while (0);
7414 ++#endif
7415 ++
7416 ++ return 1;
7417 ++}
7418 ++
7419 ++void pax_report_insns(void *pc, void *sp)
7420 ++{
7421 ++ unsigned long i;
7422 ++
7423 ++ printk(KERN_ERR "PAX: bytes at PC: ");
7424 ++ for (i = 0; i < 5; i++) {
7425 ++ unsigned int c;
7426 ++ if (get_user(c, (unsigned int *)pc+i))
7427 ++ printk(KERN_CONT "???????? ");
7428 ++ else
7429 ++ printk(KERN_CONT "%08x ", c);
7430 ++ }
7431 ++ printk("\n");
7432 ++}
7433 ++#endif
7434 ++
7435 + /*
7436 + * Check whether the instruction at regs->nip is a store using
7437 + * an update addressing form which will update r1.
7438 +@@ -109,7 +474,7 @@ int do_page_fault(struct pt_regs *regs,
7439 + * indicate errors in DSISR but can validly be set in SRR1.
7440 + */
7441 + if (TRAP(regs) == 0x400)
7442 +- error_code &= 0x48200000;
7443 ++ error_code &= 0x58200000;
7444 + else
7445 + is_write = error_code & 0x02000000;
7446 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
7447 +@@ -204,15 +569,14 @@ good_area:
7448 + pte_t *ptep;
7449 + pmd_t *pmdp;
7450 +
7451 +-#if 0
7452 ++#if 1
7453 + /* It would be nice to actually enforce the VM execute
7454 + permission on CPUs which can do so, but far too
7455 + much stuff in userspace doesn't get the permissions
7456 + right, so we let any page be executed for now. */
7457 + if (! (vma->vm_flags & VM_EXEC))
7458 + goto bad_area;
7459 +-#endif
7460 +-
7461 ++#else
7462 + /* Since 4xx/Book-E supports per-page execute permission,
7463 + * we lazily flush dcache to icache. */
7464 + ptep = NULL;
7465 +@@ -235,6 +599,7 @@ good_area:
7466 + pte_unmap_unlock(ptep, ptl);
7467 + }
7468 + #endif
7469 ++#endif
7470 + /* a read */
7471 + } else {
7472 + /* protection fault */
7473 +@@ -278,6 +643,33 @@ bad_area:
7474 +
7475 + /* User mode accesses cause a SIGSEGV */
7476 + if (user_mode(regs)) {
7477 ++
7478 ++#ifdef CONFIG_PAX_PAGEEXEC
7479 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
7480 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
7481 ++ switch (pax_handle_fetch_fault(regs)) {
7482 ++
7483 ++#ifdef CONFIG_PAX_EMUPLT
7484 ++ case 2:
7485 ++ case 3:
7486 ++ case 4:
7487 ++ return 0;
7488 ++#endif
7489 ++
7490 ++#ifdef CONFIG_PAX_EMUSIGRT
7491 ++ case 5:
7492 ++ case 6:
7493 ++ return 0;
7494 ++#endif
7495 ++
7496 ++ }
7497 ++
7498 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
7499 ++ do_group_exit(SIGKILL);
7500 ++ }
7501 ++ }
7502 ++#endif
7503 ++
7504 + _exception(SIGSEGV, regs, code, address);
7505 + return 0;
7506 + }
7507 +diff -urNp a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
7508 +--- a/arch/s390/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
7509 ++++ b/arch/s390/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
7510 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
7511 +
7512 + /* Increase core size by size of got & plt and set start
7513 + offsets for got and plt. */
7514 +- me->core_size = ALIGN(me->core_size, 4);
7515 +- me->arch.got_offset = me->core_size;
7516 +- me->core_size += me->arch.got_size;
7517 +- me->arch.plt_offset = me->core_size;
7518 +- me->core_size += me->arch.plt_size;
7519 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
7520 ++ me->arch.got_offset = me->core_size_rw;
7521 ++ me->core_size_rw += me->arch.got_size;
7522 ++ me->arch.plt_offset = me->core_size_rx;
7523 ++ me->core_size_rx += me->arch.plt_size;
7524 + return 0;
7525 + }
7526 +
7527 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7528 + if (info->got_initialized == 0) {
7529 + Elf_Addr *gotent;
7530 +
7531 +- gotent = me->module_core + me->arch.got_offset +
7532 ++ gotent = me->module_core_rw + me->arch.got_offset +
7533 + info->got_offset;
7534 + *gotent = val;
7535 + info->got_initialized = 1;
7536 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7537 + else if (r_type == R_390_GOTENT ||
7538 + r_type == R_390_GOTPLTENT)
7539 + *(unsigned int *) loc =
7540 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
7541 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
7542 + else if (r_type == R_390_GOT64 ||
7543 + r_type == R_390_GOTPLT64)
7544 + *(unsigned long *) loc = val;
7545 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7546 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
7547 + if (info->plt_initialized == 0) {
7548 + unsigned int *ip;
7549 +- ip = me->module_core + me->arch.plt_offset +
7550 ++ ip = me->module_core_rx + me->arch.plt_offset +
7551 + info->plt_offset;
7552 + #ifndef CONFIG_64BIT
7553 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
7554 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7555 + val = me->arch.plt_offset - me->arch.got_offset +
7556 + info->plt_offset + rela->r_addend;
7557 + else
7558 +- val = (Elf_Addr) me->module_core +
7559 ++ val = (Elf_Addr) me->module_core_rx +
7560 + me->arch.plt_offset + info->plt_offset +
7561 + rela->r_addend - loc;
7562 + if (r_type == R_390_PLT16DBL)
7563 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7564 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
7565 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
7566 + val = val + rela->r_addend -
7567 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
7568 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
7569 + if (r_type == R_390_GOTOFF16)
7570 + *(unsigned short *) loc = val;
7571 + else if (r_type == R_390_GOTOFF32)
7572 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7573 + break;
7574 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
7575 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
7576 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
7577 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
7578 + rela->r_addend - loc;
7579 + if (r_type == R_390_GOTPC)
7580 + *(unsigned int *) loc = val;
7581 +diff -urNp a/arch/sparc/Makefile b/arch/sparc/Makefile
7582 +--- a/arch/sparc/Makefile 2008-08-20 11:16:13.000000000 -0700
7583 ++++ b/arch/sparc/Makefile 2008-08-20 18:36:57.000000000 -0700
7584 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
7585 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
7586 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
7587 + CORE_Y := $(core-y)
7588 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
7589 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
7590 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
7591 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
7592 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
7593 +diff -urNp a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
7594 +--- a/arch/sparc/kernel/sys_sparc.c 2008-08-20 11:16:13.000000000 -0700
7595 ++++ b/arch/sparc/kernel/sys_sparc.c 2008-08-20 18:36:57.000000000 -0700
7596 +@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
7597 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
7598 + return -ENOMEM;
7599 + if (!addr)
7600 +- addr = TASK_UNMAPPED_BASE;
7601 ++ addr = current->mm->mmap_base;
7602 +
7603 + if (flags & MAP_SHARED)
7604 + addr = COLOUR_ALIGN(addr);
7605 +diff -urNp a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
7606 +--- a/arch/sparc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
7607 ++++ b/arch/sparc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
7608 +@@ -21,6 +21,10 @@
7609 + #include <linux/interrupt.h>
7610 + #include <linux/module.h>
7611 + #include <linux/kdebug.h>
7612 ++#include <linux/slab.h>
7613 ++#include <linux/pagemap.h>
7614 ++#include <linux/compiler.h>
7615 ++#include <linux/binfmts.h>
7616 +
7617 + #include <asm/system.h>
7618 + #include <asm/page.h>
7619 +@@ -216,6 +220,253 @@ static unsigned long compute_si_addr(str
7620 + return safe_compute_effective_address(regs, insn);
7621 + }
7622 +
7623 ++#ifdef CONFIG_PAX_PAGEEXEC
7624 ++void pax_emuplt_close(struct vm_area_struct *vma)
7625 ++{
7626 ++ vma->vm_mm->call_dl_resolve = 0UL;
7627 ++}
7628 ++
7629 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7630 ++{
7631 ++ struct page *page;
7632 ++ unsigned int *kaddr;
7633 ++
7634 ++ page = alloc_page(GFP_HIGHUSER);
7635 ++ if (!page)
7636 ++ return NOPAGE_OOM;
7637 ++
7638 ++ kaddr = kmap(page);
7639 ++ memset(kaddr, 0, PAGE_SIZE);
7640 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
7641 ++ flush_dcache_page(page);
7642 ++ kunmap(page);
7643 ++ if (type)
7644 ++ *type = VM_FAULT_MAJOR;
7645 ++
7646 ++ return page;
7647 ++}
7648 ++
7649 ++static struct vm_operations_struct pax_vm_ops = {
7650 ++ .close = pax_emuplt_close,
7651 ++ .nopage = pax_emuplt_nopage,
7652 ++};
7653 ++
7654 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7655 ++{
7656 ++ int ret;
7657 ++
7658 ++ vma->vm_mm = current->mm;
7659 ++ vma->vm_start = addr;
7660 ++ vma->vm_end = addr + PAGE_SIZE;
7661 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7662 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
7663 ++ vma->vm_ops = &pax_vm_ops;
7664 ++
7665 ++ ret = insert_vm_struct(current->mm, vma);
7666 ++ if (ret)
7667 ++ return ret;
7668 ++
7669 ++ ++current->mm->total_vm;
7670 ++ return 0;
7671 ++}
7672 ++
7673 ++/*
7674 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
7675 ++ *
7676 ++ * returns 1 when task should be killed
7677 ++ * 2 when patched PLT trampoline was detected
7678 ++ * 3 when unpatched PLT trampoline was detected
7679 ++ */
7680 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
7681 ++{
7682 ++
7683 ++#ifdef CONFIG_PAX_EMUPLT
7684 ++ int err;
7685 ++
7686 ++ do { /* PaX: patched PLT emulation #1 */
7687 ++ unsigned int sethi1, sethi2, jmpl;
7688 ++
7689 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
7690 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
7691 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
7692 ++
7693 ++ if (err)
7694 ++ break;
7695 ++
7696 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7697 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
7698 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
7699 ++ {
7700 ++ unsigned int addr;
7701 ++
7702 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
7703 ++ addr = regs->u_regs[UREG_G1];
7704 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7705 ++ regs->pc = addr;
7706 ++ regs->npc = addr+4;
7707 ++ return 2;
7708 ++ }
7709 ++ } while (0);
7710 ++
7711 ++ { /* PaX: patched PLT emulation #2 */
7712 ++ unsigned int ba;
7713 ++
7714 ++ err = get_user(ba, (unsigned int *)regs->pc);
7715 ++
7716 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
7717 ++ unsigned int addr;
7718 ++
7719 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7720 ++ regs->pc = addr;
7721 ++ regs->npc = addr+4;
7722 ++ return 2;
7723 ++ }
7724 ++ }
7725 ++
7726 ++ do { /* PaX: patched PLT emulation #3 */
7727 ++ unsigned int sethi, jmpl, nop;
7728 ++
7729 ++ err = get_user(sethi, (unsigned int *)regs->pc);
7730 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
7731 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
7732 ++
7733 ++ if (err)
7734 ++ break;
7735 ++
7736 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
7737 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
7738 ++ nop == 0x01000000U)
7739 ++ {
7740 ++ unsigned int addr;
7741 ++
7742 ++ addr = (sethi & 0x003FFFFFU) << 10;
7743 ++ regs->u_regs[UREG_G1] = addr;
7744 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7745 ++ regs->pc = addr;
7746 ++ regs->npc = addr+4;
7747 ++ return 2;
7748 ++ }
7749 ++ } while (0);
7750 ++
7751 ++ do { /* PaX: unpatched PLT emulation step 1 */
7752 ++ unsigned int sethi, ba, nop;
7753 ++
7754 ++ err = get_user(sethi, (unsigned int *)regs->pc);
7755 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
7756 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
7757 ++
7758 ++ if (err)
7759 ++ break;
7760 ++
7761 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
7762 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
7763 ++ nop == 0x01000000U)
7764 ++ {
7765 ++ unsigned int addr, save, call;
7766 ++
7767 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
7768 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7769 ++ else
7770 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
7771 ++
7772 ++ err = get_user(save, (unsigned int *)addr);
7773 ++ err |= get_user(call, (unsigned int *)(addr+4));
7774 ++ err |= get_user(nop, (unsigned int *)(addr+8));
7775 ++ if (err)
7776 ++ break;
7777 ++
7778 ++ if (save == 0x9DE3BFA8U &&
7779 ++ (call & 0xC0000000U) == 0x40000000U &&
7780 ++ nop == 0x01000000U)
7781 ++ {
7782 ++ struct vm_area_struct *vma;
7783 ++ unsigned long call_dl_resolve;
7784 ++
7785 ++ down_read(&current->mm->mmap_sem);
7786 ++ call_dl_resolve = current->mm->call_dl_resolve;
7787 ++ up_read(&current->mm->mmap_sem);
7788 ++ if (likely(call_dl_resolve))
7789 ++ goto emulate;
7790 ++
7791 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
7792 ++
7793 ++ down_write(&current->mm->mmap_sem);
7794 ++ if (current->mm->call_dl_resolve) {
7795 ++ call_dl_resolve = current->mm->call_dl_resolve;
7796 ++ up_write(&current->mm->mmap_sem);
7797 ++ if (vma)
7798 ++ kmem_cache_free(vm_area_cachep, vma);
7799 ++ goto emulate;
7800 ++ }
7801 ++
7802 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7803 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7804 ++ up_write(&current->mm->mmap_sem);
7805 ++ if (vma)
7806 ++ kmem_cache_free(vm_area_cachep, vma);
7807 ++ return 1;
7808 ++ }
7809 ++
7810 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
7811 ++ up_write(&current->mm->mmap_sem);
7812 ++ kmem_cache_free(vm_area_cachep, vma);
7813 ++ return 1;
7814 ++ }
7815 ++
7816 ++ current->mm->call_dl_resolve = call_dl_resolve;
7817 ++ up_write(&current->mm->mmap_sem);
7818 ++
7819 ++emulate:
7820 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7821 ++ regs->pc = call_dl_resolve;
7822 ++ regs->npc = addr+4;
7823 ++ return 3;
7824 ++ }
7825 ++ }
7826 ++ } while (0);
7827 ++
7828 ++ do { /* PaX: unpatched PLT emulation step 2 */
7829 ++ unsigned int save, call, nop;
7830 ++
7831 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
7832 ++ err |= get_user(call, (unsigned int *)regs->pc);
7833 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
7834 ++ if (err)
7835 ++ break;
7836 ++
7837 ++ if (save == 0x9DE3BFA8U &&
7838 ++ (call & 0xC0000000U) == 0x40000000U &&
7839 ++ nop == 0x01000000U)
7840 ++ {
7841 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
7842 ++
7843 ++ regs->u_regs[UREG_RETPC] = regs->pc;
7844 ++ regs->pc = dl_resolve;
7845 ++ regs->npc = dl_resolve+4;
7846 ++ return 3;
7847 ++ }
7848 ++ } while (0);
7849 ++#endif
7850 ++
7851 ++ return 1;
7852 ++}
7853 ++
7854 ++void pax_report_insns(void *pc, void *sp)
7855 ++{
7856 ++ unsigned long i;
7857 ++
7858 ++ printk(KERN_ERR "PAX: bytes at PC: ");
7859 ++ for (i = 0; i < 5; i++) {
7860 ++ unsigned int c;
7861 ++ if (get_user(c, (unsigned int *)pc+i))
7862 ++ printk(KERN_CONT "???????? ");
7863 ++ else
7864 ++ printk(KERN_CONT "%08x ", c);
7865 ++ }
7866 ++ printk("\n");
7867 ++}
7868 ++#endif
7869 ++
7870 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
7871 + unsigned long address)
7872 + {
7873 +@@ -280,6 +531,24 @@ good_area:
7874 + if(!(vma->vm_flags & VM_WRITE))
7875 + goto bad_area;
7876 + } else {
7877 ++
7878 ++#ifdef CONFIG_PAX_PAGEEXEC
7879 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
7880 ++ up_read(&mm->mmap_sem);
7881 ++ switch (pax_handle_fetch_fault(regs)) {
7882 ++
7883 ++#ifdef CONFIG_PAX_EMUPLT
7884 ++ case 2:
7885 ++ case 3:
7886 ++ return;
7887 ++#endif
7888 ++
7889 ++ }
7890 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
7891 ++ do_group_exit(SIGKILL);
7892 ++ }
7893 ++#endif
7894 ++
7895 + /* Allow reads even for write-only mappings */
7896 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
7897 + goto bad_area;
7898 +diff -urNp a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
7899 +--- a/arch/sparc/mm/init.c 2008-08-20 11:16:13.000000000 -0700
7900 ++++ b/arch/sparc/mm/init.c 2008-08-20 18:36:57.000000000 -0700
7901 +@@ -311,6 +311,9 @@ extern void device_scan(void);
7902 + pgprot_t PAGE_SHARED __read_mostly;
7903 + EXPORT_SYMBOL(PAGE_SHARED);
7904 +
7905 ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
7906 ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
7907 ++
7908 + void __init paging_init(void)
7909 + {
7910 + switch(sparc_cpu_model) {
7911 +@@ -336,17 +339,17 @@ void __init paging_init(void)
7912 +
7913 + /* Initialize the protection map with non-constant, MMU dependent values. */
7914 + protection_map[0] = PAGE_NONE;
7915 +- protection_map[1] = PAGE_READONLY;
7916 +- protection_map[2] = PAGE_COPY;
7917 +- protection_map[3] = PAGE_COPY;
7918 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
7919 ++ protection_map[2] = PAGE_COPY_NOEXEC;
7920 ++ protection_map[3] = PAGE_COPY_NOEXEC;
7921 + protection_map[4] = PAGE_READONLY;
7922 + protection_map[5] = PAGE_READONLY;
7923 + protection_map[6] = PAGE_COPY;
7924 + protection_map[7] = PAGE_COPY;
7925 + protection_map[8] = PAGE_NONE;
7926 +- protection_map[9] = PAGE_READONLY;
7927 +- protection_map[10] = PAGE_SHARED;
7928 +- protection_map[11] = PAGE_SHARED;
7929 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
7930 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
7931 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
7932 + protection_map[12] = PAGE_READONLY;
7933 + protection_map[13] = PAGE_READONLY;
7934 + protection_map[14] = PAGE_SHARED;
7935 +diff -urNp a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
7936 +--- a/arch/sparc/mm/srmmu.c 2008-08-20 11:16:13.000000000 -0700
7937 ++++ b/arch/sparc/mm/srmmu.c 2008-08-20 18:36:57.000000000 -0700
7938 +@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
7939 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
7940 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
7941 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
7942 ++
7943 ++#ifdef CONFIG_PAX_PAGEEXEC
7944 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
7945 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
7946 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
7947 ++#endif
7948 ++
7949 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
7950 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
7951 +
7952 +diff -urNp a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
7953 +--- a/arch/sparc64/kernel/Makefile 2008-08-20 11:16:13.000000000 -0700
7954 ++++ b/arch/sparc64/kernel/Makefile 2008-08-20 18:36:57.000000000 -0700
7955 +@@ -3,7 +3,7 @@
7956 + #
7957 +
7958 + EXTRA_AFLAGS := -ansi
7959 +-EXTRA_CFLAGS := -Werror
7960 ++#EXTRA_CFLAGS := -Werror
7961 +
7962 + extra-y := head.o init_task.o vmlinux.lds
7963 +
7964 +diff -urNp a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
7965 +--- a/arch/sparc64/kernel/sys_sparc.c 2008-08-20 11:16:13.000000000 -0700
7966 ++++ b/arch/sparc64/kernel/sys_sparc.c 2008-08-20 18:36:57.000000000 -0700
7967 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
7968 + /* We do not accept a shared mapping if it would violate
7969 + * cache aliasing constraints.
7970 + */
7971 +- if ((flags & MAP_SHARED) &&
7972 ++ if ((filp || (flags & MAP_SHARED)) &&
7973 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
7974 + return -EINVAL;
7975 + return addr;
7976 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
7977 + if (filp || (flags & MAP_SHARED))
7978 + do_color_align = 1;
7979 +
7980 ++#ifdef CONFIG_PAX_RANDMMAP
7981 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7982 ++#endif
7983 ++
7984 + if (addr) {
7985 + if (do_color_align)
7986 + addr = COLOUR_ALIGN(addr, pgoff);
7987 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
7988 + }
7989 +
7990 + if (len > mm->cached_hole_size) {
7991 +- start_addr = addr = mm->free_area_cache;
7992 ++ start_addr = addr = mm->free_area_cache;
7993 + } else {
7994 +- start_addr = addr = TASK_UNMAPPED_BASE;
7995 ++ start_addr = addr = mm->mmap_base;
7996 + mm->cached_hole_size = 0;
7997 + }
7998 +
7999 +@@ -174,8 +178,8 @@ full_search:
8000 + vma = find_vma(mm, VA_EXCLUDE_END);
8001 + }
8002 + if (unlikely(task_size < addr)) {
8003 +- if (start_addr != TASK_UNMAPPED_BASE) {
8004 +- start_addr = addr = TASK_UNMAPPED_BASE;
8005 ++ if (start_addr != mm->mmap_base) {
8006 ++ start_addr = addr = mm->mmap_base;
8007 + mm->cached_hole_size = 0;
8008 + goto full_search;
8009 + }
8010 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
8011 + /* We do not accept a shared mapping if it would violate
8012 + * cache aliasing constraints.
8013 + */
8014 +- if ((flags & MAP_SHARED) &&
8015 ++ if ((filp || (flags & MAP_SHARED)) &&
8016 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
8017 + return -EINVAL;
8018 + return addr;
8019 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
8020 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
8021 + sysctl_legacy_va_layout) {
8022 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
8023 ++
8024 ++#ifdef CONFIG_PAX_RANDMMAP
8025 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
8026 ++ mm->mmap_base += mm->delta_mmap;
8027 ++#endif
8028 ++
8029 + mm->get_unmapped_area = arch_get_unmapped_area;
8030 + mm->unmap_area = arch_unmap_area;
8031 + } else {
8032 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
8033 + gap = (task_size / 6 * 5);
8034 +
8035 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
8036 ++
8037 ++#ifdef CONFIG_PAX_RANDMMAP
8038 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
8039 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8040 ++#endif
8041 ++
8042 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8043 + mm->unmap_area = arch_unmap_area_topdown;
8044 + }
8045 +diff -urNp a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
8046 +--- a/arch/sparc64/mm/Makefile 2008-08-20 11:16:13.000000000 -0700
8047 ++++ b/arch/sparc64/mm/Makefile 2008-08-20 18:36:57.000000000 -0700
8048 +@@ -3,7 +3,7 @@
8049 + #
8050 +
8051 + EXTRA_AFLAGS := -ansi
8052 +-EXTRA_CFLAGS := -Werror
8053 ++#EXTRA_CFLAGS := -Werror
8054 +
8055 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
8056 +
8057 +diff -urNp a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
8058 +--- a/arch/sparc64/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
8059 ++++ b/arch/sparc64/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
8060 +@@ -20,6 +20,10 @@
8061 + #include <linux/kprobes.h>
8062 + #include <linux/kallsyms.h>
8063 + #include <linux/kdebug.h>
8064 ++#include <linux/slab.h>
8065 ++#include <linux/pagemap.h>
8066 ++#include <linux/compiler.h>
8067 ++#include <linux/binfmts.h>
8068 +
8069 + #include <asm/page.h>
8070 + #include <asm/pgtable.h>
8071 +@@ -262,6 +266,370 @@ cannot_handle:
8072 + unhandled_fault (address, current, regs);
8073 + }
8074 +
8075 ++#ifdef CONFIG_PAX_PAGEEXEC
8076 ++#ifdef CONFIG_PAX_EMUPLT
8077 ++static void pax_emuplt_close(struct vm_area_struct *vma)
8078 ++{
8079 ++ vma->vm_mm->call_dl_resolve = 0UL;
8080 ++}
8081 ++
8082 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8083 ++{
8084 ++ struct page *page;
8085 ++ unsigned int *kaddr;
8086 ++
8087 ++ page = alloc_page(GFP_HIGHUSER);
8088 ++ if (!page)
8089 ++ return NOPAGE_OOM;
8090 ++
8091 ++ kaddr = kmap(page);
8092 ++ memset(kaddr, 0, PAGE_SIZE);
8093 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
8094 ++ flush_dcache_page(page);
8095 ++ kunmap(page);
8096 ++ if (type)
8097 ++ *type = VM_FAULT_MAJOR;
8098 ++ return page;
8099 ++}
8100 ++
8101 ++static struct vm_operations_struct pax_vm_ops = {
8102 ++ .close = pax_emuplt_close,
8103 ++ .nopage = pax_emuplt_nopage,
8104 ++};
8105 ++
8106 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8107 ++{
8108 ++ int ret;
8109 ++
8110 ++ vma->vm_mm = current->mm;
8111 ++ vma->vm_start = addr;
8112 ++ vma->vm_end = addr + PAGE_SIZE;
8113 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8114 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8115 ++ vma->vm_ops = &pax_vm_ops;
8116 ++
8117 ++ ret = insert_vm_struct(current->mm, vma);
8118 ++ if (ret)
8119 ++ return ret;
8120 ++
8121 ++ ++current->mm->total_vm;
8122 ++ return 0;
8123 ++}
8124 ++#endif
8125 ++
8126 ++/*
8127 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
8128 ++ *
8129 ++ * returns 1 when task should be killed
8130 ++ * 2 when patched PLT trampoline was detected
8131 ++ * 3 when unpatched PLT trampoline was detected
8132 ++ */
8133 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
8134 ++{
8135 ++
8136 ++#ifdef CONFIG_PAX_EMUPLT
8137 ++ int err;
8138 ++
8139 ++ do { /* PaX: patched PLT emulation #1 */
8140 ++ unsigned int sethi1, sethi2, jmpl;
8141 ++
8142 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
8143 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
8144 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
8145 ++
8146 ++ if (err)
8147 ++ break;
8148 ++
8149 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8150 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
8151 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
8152 ++ {
8153 ++ unsigned long addr;
8154 ++
8155 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
8156 ++ addr = regs->u_regs[UREG_G1];
8157 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8158 ++ regs->tpc = addr;
8159 ++ regs->tnpc = addr+4;
8160 ++ return 2;
8161 ++ }
8162 ++ } while (0);
8163 ++
8164 ++ { /* PaX: patched PLT emulation #2 */
8165 ++ unsigned int ba;
8166 ++
8167 ++ err = get_user(ba, (unsigned int *)regs->tpc);
8168 ++
8169 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
8170 ++ unsigned long addr;
8171 ++
8172 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8173 ++ regs->tpc = addr;
8174 ++ regs->tnpc = addr+4;
8175 ++ return 2;
8176 ++ }
8177 ++ }
8178 ++
8179 ++ do { /* PaX: patched PLT emulation #3 */
8180 ++ unsigned int sethi, jmpl, nop;
8181 ++
8182 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
8183 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
8184 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
8185 ++
8186 ++ if (err)
8187 ++ break;
8188 ++
8189 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8190 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
8191 ++ nop == 0x01000000U)
8192 ++ {
8193 ++ unsigned long addr;
8194 ++
8195 ++ addr = (sethi & 0x003FFFFFU) << 10;
8196 ++ regs->u_regs[UREG_G1] = addr;
8197 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8198 ++ regs->tpc = addr;
8199 ++ regs->tnpc = addr+4;
8200 ++ return 2;
8201 ++ }
8202 ++ } while (0);
8203 ++
8204 ++ do { /* PaX: patched PLT emulation #4 */
8205 ++ unsigned int mov1, call, mov2;
8206 ++
8207 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
8208 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
8209 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
8210 ++
8211 ++ if (err)
8212 ++ break;
8213 ++
8214 ++ if (mov1 == 0x8210000FU &&
8215 ++ (call & 0xC0000000U) == 0x40000000U &&
8216 ++ mov2 == 0x9E100001U)
8217 ++ {
8218 ++ unsigned long addr;
8219 ++
8220 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
8221 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8222 ++ regs->tpc = addr;
8223 ++ regs->tnpc = addr+4;
8224 ++ return 2;
8225 ++ }
8226 ++ } while (0);
8227 ++
8228 ++ do { /* PaX: patched PLT emulation #5 */
8229 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
8230 ++
8231 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
8232 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
8233 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
8234 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
8235 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
8236 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
8237 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
8238 ++
8239 ++ if (err)
8240 ++ break;
8241 ++
8242 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8243 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8244 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
8245 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
8246 ++ sllx == 0x83287020 &&
8247 ++ jmpl == 0x81C04005U &&
8248 ++ nop == 0x01000000U)
8249 ++ {
8250 ++ unsigned long addr;
8251 ++
8252 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
8253 ++ regs->u_regs[UREG_G1] <<= 32;
8254 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
8255 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8256 ++ regs->tpc = addr;
8257 ++ regs->tnpc = addr+4;
8258 ++ return 2;
8259 ++ }
8260 ++ } while (0);
8261 ++
8262 ++ do { /* PaX: patched PLT emulation #6 */
8263 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
8264 ++
8265 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
8266 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
8267 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
8268 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
8269 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
8270 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
8271 ++
8272 ++ if (err)
8273 ++ break;
8274 ++
8275 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8276 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8277 ++ sllx == 0x83287020 &&
8278 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
8279 ++ jmpl == 0x81C04005U &&
8280 ++ nop == 0x01000000U)
8281 ++ {
8282 ++ unsigned long addr;
8283 ++
8284 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
8285 ++ regs->u_regs[UREG_G1] <<= 32;
8286 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
8287 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8288 ++ regs->tpc = addr;
8289 ++ regs->tnpc = addr+4;
8290 ++ return 2;
8291 ++ }
8292 ++ } while (0);
8293 ++
8294 ++ do { /* PaX: patched PLT emulation #7 */
8295 ++ unsigned int sethi, ba, nop;
8296 ++
8297 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
8298 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
8299 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
8300 ++
8301 ++ if (err)
8302 ++ break;
8303 ++
8304 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8305 ++ (ba & 0xFFF00000U) == 0x30600000U &&
8306 ++ nop == 0x01000000U)
8307 ++ {
8308 ++ unsigned long addr;
8309 ++
8310 ++ addr = (sethi & 0x003FFFFFU) << 10;
8311 ++ regs->u_regs[UREG_G1] = addr;
8312 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8313 ++ regs->tpc = addr;
8314 ++ regs->tnpc = addr+4;
8315 ++ return 2;
8316 ++ }
8317 ++ } while (0);
8318 ++
8319 ++ do { /* PaX: unpatched PLT emulation step 1 */
8320 ++ unsigned int sethi, ba, nop;
8321 ++
8322 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
8323 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
8324 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
8325 ++
8326 ++ if (err)
8327 ++ break;
8328 ++
8329 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8330 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
8331 ++ nop == 0x01000000U)
8332 ++ {
8333 ++ unsigned long addr;
8334 ++ unsigned int save, call;
8335 ++
8336 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
8337 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8338 ++ else
8339 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8340 ++
8341 ++ err = get_user(save, (unsigned int *)addr);
8342 ++ err |= get_user(call, (unsigned int *)(addr+4));
8343 ++ err |= get_user(nop, (unsigned int *)(addr+8));
8344 ++ if (err)
8345 ++ break;
8346 ++
8347 ++ if (save == 0x9DE3BFA8U &&
8348 ++ (call & 0xC0000000U) == 0x40000000U &&
8349 ++ nop == 0x01000000U)
8350 ++ {
8351 ++ struct vm_area_struct *vma;
8352 ++ unsigned long call_dl_resolve;
8353 ++
8354 ++ down_read(&current->mm->mmap_sem);
8355 ++ call_dl_resolve = current->mm->call_dl_resolve;
8356 ++ up_read(&current->mm->mmap_sem);
8357 ++ if (likely(call_dl_resolve))
8358 ++ goto emulate;
8359 ++
8360 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
8361 ++
8362 ++ down_write(&current->mm->mmap_sem);
8363 ++ if (current->mm->call_dl_resolve) {
8364 ++ call_dl_resolve = current->mm->call_dl_resolve;
8365 ++ up_write(&current->mm->mmap_sem);
8366 ++ if (vma)
8367 ++ kmem_cache_free(vm_area_cachep, vma);
8368 ++ goto emulate;
8369 ++ }
8370 ++
8371 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8372 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
8373 ++ up_write(&current->mm->mmap_sem);
8374 ++ if (vma)
8375 ++ kmem_cache_free(vm_area_cachep, vma);
8376 ++ return 1;
8377 ++ }
8378 ++
8379 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
8380 ++ up_write(&current->mm->mmap_sem);
8381 ++ kmem_cache_free(vm_area_cachep, vma);
8382 ++ return 1;
8383 ++ }
8384 ++
8385 ++ current->mm->call_dl_resolve = call_dl_resolve;
8386 ++ up_write(&current->mm->mmap_sem);
8387 ++
8388 ++emulate:
8389 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
8390 ++ regs->tpc = call_dl_resolve;
8391 ++ regs->tnpc = addr+4;
8392 ++ return 3;
8393 ++ }
8394 ++ }
8395 ++ } while (0);
8396 ++
8397 ++ do { /* PaX: unpatched PLT emulation step 2 */
8398 ++ unsigned int save, call, nop;
8399 ++
8400 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
8401 ++ err |= get_user(call, (unsigned int *)regs->tpc);
8402 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
8403 ++ if (err)
8404 ++ break;
8405 ++
8406 ++ if (save == 0x9DE3BFA8U &&
8407 ++ (call & 0xC0000000U) == 0x40000000U &&
8408 ++ nop == 0x01000000U)
8409 ++ {
8410 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8411 ++
8412 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
8413 ++ regs->tpc = dl_resolve;
8414 ++ regs->tnpc = dl_resolve+4;
8415 ++ return 3;
8416 ++ }
8417 ++ } while (0);
8418 ++#endif
8419 ++
8420 ++ return 1;
8421 ++}
8422 ++
8423 ++void pax_report_insns(void *pc, void *sp)
8424 ++{
8425 ++ unsigned long i;
8426 ++
8427 ++ printk(KERN_ERR "PAX: bytes at PC: ");
8428 ++ for (i = 0; i < 5; i++) {
8429 ++ unsigned int c;
8430 ++ if (get_user(c, (unsigned int *)pc+i))
8431 ++ printk(KERN_CONT "???????? ");
8432 ++ else
8433 ++ printk(KERN_CONT "%08x ", c);
8434 ++ }
8435 ++ printk("\n");
8436 ++}
8437 ++#endif
8438 ++
8439 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
8440 + {
8441 + struct mm_struct *mm = current->mm;
8442 +@@ -303,8 +671,10 @@ asmlinkage void __kprobes do_sparc64_fau
8443 + goto intr_or_no_mm;
8444 +
8445 + if (test_thread_flag(TIF_32BIT)) {
8446 +- if (!(regs->tstate & TSTATE_PRIV))
8447 ++ if (!(regs->tstate & TSTATE_PRIV)) {
8448 + regs->tpc &= 0xffffffff;
8449 ++ regs->tnpc &= 0xffffffff;
8450 ++ }
8451 + address &= 0xffffffff;
8452 + }
8453 +
8454 +@@ -321,6 +691,29 @@ asmlinkage void __kprobes do_sparc64_fau
8455 + if (!vma)
8456 + goto bad_area;
8457 +
8458 ++#ifdef CONFIG_PAX_PAGEEXEC
8459 ++ /* PaX: detect ITLB misses on non-exec pages */
8460 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
8461 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
8462 ++ {
8463 ++ if (address != regs->tpc)
8464 ++ goto good_area;
8465 ++
8466 ++ up_read(&mm->mmap_sem);
8467 ++ switch (pax_handle_fetch_fault(regs)) {
8468 ++
8469 ++#ifdef CONFIG_PAX_EMUPLT
8470 ++ case 2:
8471 ++ case 3:
8472 ++ return;
8473 ++#endif
8474 ++
8475 ++ }
8476 ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
8477 ++ do_group_exit(SIGKILL);
8478 ++ }
8479 ++#endif
8480 ++
8481 + /* Pure DTLB misses do not tell us whether the fault causing
8482 + * load/store/atomic was a write or not, it only says that there
8483 + * was no match. So in such a case we (carefully) read the
8484 +diff -urNp a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c
8485 +--- a/arch/v850/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
8486 ++++ b/arch/v850/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
8487 +@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
8488 + tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
8489 +
8490 + /* Init, or core PLT? */
8491 +- if (location >= mod->module_core
8492 +- && location < mod->module_core + mod->core_size)
8493 ++ if (location >= mod->module_core_rx
8494 ++ && location < mod->module_core_rx + mod->core_size_rx)
8495 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
8496 + else
8497 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
8498 +diff -urNp a/arch/x86/Kconfig b/arch/x86/Kconfig
8499 +--- a/arch/x86/Kconfig 2008-08-20 11:16:13.000000000 -0700
8500 ++++ b/arch/x86/Kconfig 2008-08-20 18:36:57.000000000 -0700
8501 +@@ -819,7 +819,7 @@ config PAGE_OFFSET
8502 + hex
8503 + default 0xB0000000 if VMSPLIT_3G_OPT
8504 + default 0x80000000 if VMSPLIT_2G
8505 +- default 0x78000000 if VMSPLIT_2G_OPT
8506 ++ default 0x70000000 if VMSPLIT_2G_OPT
8507 + default 0x40000000 if VMSPLIT_1G
8508 + default 0xC0000000
8509 + depends on X86_32
8510 +@@ -1113,8 +1113,7 @@ config CRASH_DUMP
8511 + config PHYSICAL_START
8512 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
8513 + default "0x1000000" if X86_NUMAQ
8514 +- default "0x200000" if X86_64
8515 +- default "0x100000"
8516 ++ default "0x200000"
8517 + help
8518 + This gives the physical address where the kernel is loaded.
8519 +
8520 +@@ -1206,9 +1205,9 @@ config HOTPLUG_CPU
8521 + suspend.
8522 +
8523 + config COMPAT_VDSO
8524 +- def_bool y
8525 ++ def_bool n
8526 + prompt "Compat VDSO support"
8527 +- depends on X86_32 || IA32_EMULATION
8528 ++ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
8529 + help
8530 + Map the 32-bit VDSO to the predictable old-style address too.
8531 + ---help---
8532 +@@ -1395,7 +1394,7 @@ config PCI
8533 + choice
8534 + prompt "PCI access mode"
8535 + depends on X86_32 && PCI && !X86_VISWS
8536 +- default PCI_GOANY
8537 ++ default PCI_GODIRECT
8538 + ---help---
8539 + On PCI systems, the BIOS can be used to detect the PCI devices and
8540 + determine their configuration. However, some old PCI motherboards
8541 +diff -urNp a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
8542 +--- a/arch/x86/Kconfig.cpu 2008-08-20 11:16:13.000000000 -0700
8543 ++++ b/arch/x86/Kconfig.cpu 2008-08-20 18:36:57.000000000 -0700
8544 +@@ -335,7 +335,7 @@ config X86_PPRO_FENCE
8545 +
8546 + config X86_F00F_BUG
8547 + def_bool y
8548 +- depends on M586MMX || M586TSC || M586 || M486 || M386
8549 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
8550 +
8551 + config X86_WP_WORKS_OK
8552 + def_bool y
8553 +@@ -355,7 +355,7 @@ config X86_POPAD_OK
8554 +
8555 + config X86_ALIGNMENT_16
8556 + def_bool y
8557 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
8558 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
8559 +
8560 + config X86_GOOD_APIC
8561 + def_bool y
8562 +@@ -398,7 +398,7 @@ config X86_TSC
8563 + # generates cmov.
8564 + config X86_CMOV
8565 + def_bool y
8566 +- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
8567 ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
8568 +
8569 + config X86_MINIMUM_CPU_FAMILY
8570 + int
8571 +diff -urNp a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
8572 +--- a/arch/x86/Kconfig.debug 2008-08-20 11:16:13.000000000 -0700
8573 ++++ b/arch/x86/Kconfig.debug 2008-08-20 18:36:57.000000000 -0700
8574 +@@ -57,7 +57,7 @@ config DEBUG_PER_CPU_MAPS
8575 + config DEBUG_RODATA
8576 + bool "Write protect kernel read-only data structures"
8577 + default y
8578 +- depends on DEBUG_KERNEL
8579 ++ depends on DEBUG_KERNEL && BROKEN
8580 + help
8581 + Mark the kernel read-only data as write-protected in the pagetables,
8582 + in order to catch accidental (and incorrect) writes to such const
8583 +diff -urNp a/arch/x86/boot/bitops.h b/arch/x86/boot/bitops.h
8584 +--- a/arch/x86/boot/bitops.h 2008-08-20 11:16:13.000000000 -0700
8585 ++++ b/arch/x86/boot/bitops.h 2008-08-20 18:36:57.000000000 -0700
8586 +@@ -28,7 +28,7 @@ static inline int variable_test_bit(int
8587 + u8 v;
8588 + const u32 *p = (const u32 *)addr;
8589 +
8590 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
8591 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
8592 + return v;
8593 + }
8594 +
8595 +@@ -39,7 +39,7 @@ static inline int variable_test_bit(int
8596 +
8597 + static inline void set_bit(int nr, void *addr)
8598 + {
8599 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
8600 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
8601 + }
8602 +
8603 + #endif /* BOOT_BITOPS_H */
8604 +diff -urNp a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
8605 +--- a/arch/x86/boot/boot.h 2008-08-20 11:16:13.000000000 -0700
8606 ++++ b/arch/x86/boot/boot.h 2008-08-20 18:36:57.000000000 -0700
8607 +@@ -80,7 +80,7 @@ static inline void io_delay(void)
8608 + static inline u16 ds(void)
8609 + {
8610 + u16 seg;
8611 +- asm("movw %%ds,%0" : "=rm" (seg));
8612 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
8613 + return seg;
8614 + }
8615 +
8616 +@@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
8617 + static inline int memcmp(const void *s1, const void *s2, size_t len)
8618 + {
8619 + u8 diff;
8620 +- asm("repe; cmpsb; setnz %0"
8621 ++ asm volatile("repe; cmpsb; setnz %0"
8622 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
8623 + return diff;
8624 + }
8625 +diff -urNp a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
8626 +--- a/arch/x86/boot/compressed/head_32.S 2008-08-20 11:16:13.000000000 -0700
8627 ++++ b/arch/x86/boot/compressed/head_32.S 2008-08-20 18:36:57.000000000 -0700
8628 +@@ -70,7 +70,7 @@ startup_32:
8629 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
8630 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
8631 + #else
8632 +- movl $LOAD_PHYSICAL_ADDR, %ebx
8633 ++ movl $____LOAD_PHYSICAL_ADDR, %ebx
8634 + #endif
8635 +
8636 + /* Replace the compressed data size with the uncompressed size */
8637 +@@ -105,7 +105,7 @@ startup_32:
8638 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
8639 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
8640 + #else
8641 +- movl $LOAD_PHYSICAL_ADDR, %ebp
8642 ++ movl $____LOAD_PHYSICAL_ADDR, %ebp
8643 + #endif
8644 +
8645 + /*
8646 +@@ -159,16 +159,15 @@ relocated:
8647 + * and where it was actually loaded.
8648 + */
8649 + movl %ebp, %ebx
8650 +- subl $LOAD_PHYSICAL_ADDR, %ebx
8651 ++ subl $____LOAD_PHYSICAL_ADDR, %ebx
8652 + jz 2f /* Nothing to be done if loaded at compiled addr. */
8653 + /*
8654 + * Process relocations.
8655 + */
8656 +
8657 + 1: subl $4, %edi
8658 +- movl 0(%edi), %ecx
8659 +- testl %ecx, %ecx
8660 +- jz 2f
8661 ++ movl (%edi), %ecx
8662 ++ jecxz 2f
8663 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
8664 + jmp 1b
8665 + 2:
8666 +diff -urNp a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
8667 +--- a/arch/x86/boot/compressed/misc.c 2008-08-20 11:16:13.000000000 -0700
8668 ++++ b/arch/x86/boot/compressed/misc.c 2008-08-20 18:36:57.000000000 -0700
8669 +@@ -122,7 +122,8 @@ typedef unsigned char uch;
8670 + typedef unsigned short ush;
8671 + typedef unsigned long ulg;
8672 +
8673 +-#define WSIZE 0x80000000 /* Window size must be at least 32k,
8674 ++#define WSIZE 0x80000000
8675 ++ /* Window size must be at least 32k,
8676 + * and a power of two
8677 + * We don't actually have a window just
8678 + * a huge output buffer so I report
8679 +@@ -400,7 +401,7 @@ asmlinkage void decompress_kernel(void *
8680 + if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
8681 + error("Destination address too large");
8682 + #ifndef CONFIG_RELOCATABLE
8683 +- if ((u32)output != LOAD_PHYSICAL_ADDR)
8684 ++ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
8685 + error("Wrong destination address");
8686 + #endif
8687 + #endif
8688 +diff -urNp a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
8689 +--- a/arch/x86/boot/compressed/relocs.c 2008-08-20 11:16:13.000000000 -0700
8690 ++++ b/arch/x86/boot/compressed/relocs.c 2008-08-20 18:36:57.000000000 -0700
8691 +@@ -10,9 +10,13 @@
8692 + #define USE_BSD
8693 + #include <endian.h>
8694 +
8695 ++#include "../../../../include/linux/autoconf.h"
8696 ++
8697 ++#define MAX_PHDRS 100
8698 + #define MAX_SHDRS 100
8699 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
8700 + static Elf32_Ehdr ehdr;
8701 ++static Elf32_Phdr phdr[MAX_PHDRS];
8702 + static Elf32_Shdr shdr[MAX_SHDRS];
8703 + static Elf32_Sym *symtab[MAX_SHDRS];
8704 + static Elf32_Rel *reltab[MAX_SHDRS];
8705 +@@ -241,6 +245,34 @@ static void read_ehdr(FILE *fp)
8706 + }
8707 + }
8708 +
8709 ++static void read_phdrs(FILE *fp)
8710 ++{
8711 ++ int i;
8712 ++ if (ehdr.e_phnum > MAX_PHDRS) {
8713 ++ die("%d program headers supported: %d\n",
8714 ++ ehdr.e_phnum, MAX_PHDRS);
8715 ++ }
8716 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
8717 ++ die("Seek to %d failed: %s\n",
8718 ++ ehdr.e_phoff, strerror(errno));
8719 ++ }
8720 ++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
8721 ++ die("Cannot read ELF program headers: %s\n",
8722 ++ strerror(errno));
8723 ++ }
8724 ++ for(i = 0; i < ehdr.e_phnum; i++) {
8725 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
8726 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
8727 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
8728 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
8729 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
8730 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
8731 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
8732 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
8733 ++ }
8734 ++
8735 ++}
8736 ++
8737 + static void read_shdrs(FILE *fp)
8738 + {
8739 + int i;
8740 +@@ -327,6 +359,8 @@ static void read_symtabs(FILE *fp)
8741 + static void read_relocs(FILE *fp)
8742 + {
8743 + int i,j;
8744 ++ uint32_t base;
8745 ++
8746 + for(i = 0; i < ehdr.e_shnum; i++) {
8747 + if (shdr[i].sh_type != SHT_REL) {
8748 + continue;
8749 +@@ -344,8 +378,17 @@ static void read_relocs(FILE *fp)
8750 + die("Cannot read symbol table: %s\n",
8751 + strerror(errno));
8752 + }
8753 ++ base = 0;
8754 ++ for (j = 0; j < ehdr.e_phnum; j++) {
8755 ++ if (phdr[j].p_type != PT_LOAD )
8756 ++ continue;
8757 ++ 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)
8758 ++ continue;
8759 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
8760 ++ break;
8761 ++ }
8762 + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
8763 +- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
8764 ++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
8765 + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
8766 + }
8767 + }
8768 +@@ -482,6 +525,23 @@ static void walk_relocs(void (*visit)(El
8769 + if (sym->st_shndx == SHN_ABS) {
8770 + continue;
8771 + }
8772 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
8773 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
8774 ++ continue;
8775 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
8776 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
8777 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
8778 ++ continue;
8779 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
8780 ++ continue;
8781 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
8782 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
8783 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
8784 ++ continue;
8785 ++ }
8786 ++ if (!strcmp(sec_name(sym->st_shndx), ".text"))
8787 ++ continue;
8788 ++#endif
8789 + if (r_type == R_386_PC32) {
8790 + /* PC relative relocations don't need to be adjusted */
8791 + }
8792 +@@ -609,6 +669,7 @@ int main(int argc, char **argv)
8793 + fname, strerror(errno));
8794 + }
8795 + read_ehdr(fp);
8796 ++ read_phdrs(fp);
8797 + read_shdrs(fp);
8798 + read_strtabs(fp);
8799 + read_symtabs(fp);
8800 +diff -urNp a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
8801 +--- a/arch/x86/boot/cpucheck.c 2008-08-20 11:16:13.000000000 -0700
8802 ++++ b/arch/x86/boot/cpucheck.c 2008-08-20 18:36:57.000000000 -0700
8803 +@@ -78,7 +78,7 @@ static int has_fpu(void)
8804 + u16 fcw = -1, fsw = -1;
8805 + u32 cr0;
8806 +
8807 +- asm("movl %%cr0,%0" : "=r" (cr0));
8808 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
8809 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
8810 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
8811 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
8812 +@@ -94,7 +94,7 @@ static int has_eflag(u32 mask)
8813 + {
8814 + u32 f0, f1;
8815 +
8816 +- asm("pushfl ; "
8817 ++ asm volatile("pushfl ; "
8818 + "pushfl ; "
8819 + "popl %0 ; "
8820 + "movl %0,%1 ; "
8821 +@@ -119,7 +119,7 @@ static void get_flags(void)
8822 + set_bit(X86_FEATURE_FPU, cpu.flags);
8823 +
8824 + if (has_eflag(X86_EFLAGS_ID)) {
8825 +- asm("cpuid"
8826 ++ asm volatile("cpuid"
8827 + : "=a" (max_intel_level),
8828 + "=b" (cpu_vendor[0]),
8829 + "=d" (cpu_vendor[1]),
8830 +@@ -128,7 +128,7 @@ static void get_flags(void)
8831 +
8832 + if (max_intel_level >= 0x00000001 &&
8833 + max_intel_level <= 0x0000ffff) {
8834 +- asm("cpuid"
8835 ++ asm volatile("cpuid"
8836 + : "=a" (tfms),
8837 + "=c" (cpu.flags[4]),
8838 + "=d" (cpu.flags[0])
8839 +@@ -140,7 +140,7 @@ static void get_flags(void)
8840 + cpu.model += ((tfms >> 16) & 0xf) << 4;
8841 + }
8842 +
8843 +- asm("cpuid"
8844 ++ asm volatile("cpuid"
8845 + : "=a" (max_amd_level)
8846 + : "a" (0x80000000)
8847 + : "ebx", "ecx", "edx");
8848 +@@ -148,7 +148,7 @@ static void get_flags(void)
8849 + if (max_amd_level >= 0x80000001 &&
8850 + max_amd_level <= 0x8000ffff) {
8851 + u32 eax = 0x80000001;
8852 +- asm("cpuid"
8853 ++ asm volatile("cpuid"
8854 + : "+a" (eax),
8855 + "=c" (cpu.flags[6]),
8856 + "=d" (cpu.flags[1])
8857 +@@ -207,9 +207,9 @@ int check_cpu(int *cpu_level_ptr, int *r
8858 + u32 ecx = MSR_K7_HWCR;
8859 + u32 eax, edx;
8860 +
8861 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8862 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8863 + eax &= ~(1 << 15);
8864 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8865 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8866 +
8867 + get_flags(); /* Make sure it really did something */
8868 + err = check_flags();
8869 +@@ -222,9 +222,9 @@ int check_cpu(int *cpu_level_ptr, int *r
8870 + u32 ecx = MSR_VIA_FCR;
8871 + u32 eax, edx;
8872 +
8873 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8874 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8875 + eax |= (1<<1)|(1<<7);
8876 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8877 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8878 +
8879 + set_bit(X86_FEATURE_CX8, cpu.flags);
8880 + err = check_flags();
8881 +@@ -235,12 +235,12 @@ int check_cpu(int *cpu_level_ptr, int *r
8882 + u32 eax, edx;
8883 + u32 level = 1;
8884 +
8885 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8886 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
8887 +- asm("cpuid"
8888 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8889 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
8890 ++ asm volatile("cpuid"
8891 + : "+a" (level), "=d" (cpu.flags[0])
8892 + : : "ecx", "ebx");
8893 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8894 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8895 +
8896 + err = check_flags();
8897 + }
8898 +diff -urNp a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c
8899 +--- a/arch/x86/boot/edd.c 2008-08-20 11:16:13.000000000 -0700
8900 ++++ b/arch/x86/boot/edd.c 2008-08-20 18:36:57.000000000 -0700
8901 +@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
8902 + ax = 0x4100;
8903 + bx = EDDMAGIC1;
8904 + dx = devno;
8905 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
8906 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
8907 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
8908 + : : "esi", "edi");
8909 +
8910 +@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
8911 + ei->params.length = sizeof(ei->params);
8912 + ax = 0x4800;
8913 + dx = devno;
8914 +- asm("pushfl; int $0x13; popfl"
8915 ++ asm volatile("pushfl; int $0x13; popfl"
8916 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
8917 + : "S" (&ei->params)
8918 + : "ebx", "ecx", "edi");
8919 +@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
8920 + ax = 0x0800;
8921 + dx = devno;
8922 + di = 0;
8923 +- asm("pushw %%es; "
8924 ++ asm volatile("pushw %%es; "
8925 + "movw %%di,%%es; "
8926 + "pushfl; stc; int $0x13; setc %%al; popfl; "
8927 + "popw %%es"
8928 +diff -urNp a/arch/x86/boot/main.c b/arch/x86/boot/main.c
8929 +--- a/arch/x86/boot/main.c 2008-08-20 11:16:13.000000000 -0700
8930 ++++ b/arch/x86/boot/main.c 2008-08-20 18:38:51.000000000 -0700
8931 +@@ -79,7 +79,7 @@ static void query_ist(void)
8932 + if (cpu.level < 6)
8933 + return;
8934 +
8935 +- asm("int $0x15"
8936 ++ asm volatile("int $0x15"
8937 + : "=a" (boot_params.ist_info.signature),
8938 + "=b" (boot_params.ist_info.command),
8939 + "=c" (boot_params.ist_info.event),
8940 +diff -urNp a/arch/x86/boot/mca.c b/arch/x86/boot/mca.c
8941 +--- a/arch/x86/boot/mca.c 2008-08-20 11:16:13.000000000 -0700
8942 ++++ b/arch/x86/boot/mca.c 2008-08-20 18:36:57.000000000 -0700
8943 +@@ -21,7 +21,7 @@ int query_mca(void)
8944 + u8 err;
8945 + u16 es, bx, len;
8946 +
8947 +- asm("pushw %%es ; "
8948 ++ asm volatile("pushw %%es ; "
8949 + "int $0x15 ; "
8950 + "setc %0 ; "
8951 + "movw %%es, %1 ; "
8952 +diff -urNp a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
8953 +--- a/arch/x86/boot/memory.c 2008-08-20 11:16:13.000000000 -0700
8954 ++++ b/arch/x86/boot/memory.c 2008-08-20 18:36:57.000000000 -0700
8955 +@@ -32,7 +32,7 @@ static int detect_memory_e820(void)
8956 + /* Important: %edx is clobbered by some BIOSes,
8957 + so it must be either used for the error output
8958 + or explicitly marked clobbered. */
8959 +- asm("int $0x15; setc %0"
8960 ++ asm volatile("int $0x15; setc %0"
8961 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
8962 + "=m" (*desc)
8963 + : "D" (desc), "d" (SMAP), "a" (0xe820));
8964 +@@ -67,7 +67,7 @@ static int detect_memory_e801(void)
8965 +
8966 + bx = cx = dx = 0;
8967 + ax = 0xe801;
8968 +- asm("stc; int $0x15; setc %0"
8969 ++ asm volatile("stc; int $0x15; setc %0"
8970 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
8971 +
8972 + if (err)
8973 +@@ -97,7 +97,7 @@ static int detect_memory_88(void)
8974 + u8 err;
8975 +
8976 + ax = 0x8800;
8977 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
8978 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
8979 +
8980 + boot_params.screen_info.ext_mem_k = ax;
8981 +
8982 +diff -urNp a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
8983 +--- a/arch/x86/boot/video-vesa.c 2008-08-20 11:16:13.000000000 -0700
8984 ++++ b/arch/x86/boot/video-vesa.c 2008-08-20 18:36:57.000000000 -0700
8985 +@@ -39,7 +39,7 @@ static int vesa_probe(void)
8986 +
8987 + ax = 0x4f00;
8988 + di = (size_t)&vginfo;
8989 +- asm(INT10
8990 ++ asm volatile(INT10
8991 + : "+a" (ax), "+D" (di), "=m" (vginfo)
8992 + : : "ebx", "ecx", "edx", "esi");
8993 +
8994 +@@ -66,7 +66,7 @@ static int vesa_probe(void)
8995 + ax = 0x4f01;
8996 + cx = mode;
8997 + di = (size_t)&vminfo;
8998 +- asm(INT10
8999 ++ asm volatile(INT10
9000 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
9001 + : : "ebx", "edx", "esi");
9002 +
9003 +@@ -121,7 +121,7 @@ static int vesa_set_mode(struct mode_inf
9004 + ax = 0x4f01;
9005 + cx = vesa_mode;
9006 + di = (size_t)&vminfo;
9007 +- asm(INT10
9008 ++ asm volatile(INT10
9009 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
9010 + : : "ebx", "edx", "esi");
9011 +
9012 +@@ -199,19 +199,20 @@ static void vesa_dac_set_8bits(void)
9013 + /* Save the VESA protected mode info */
9014 + static void vesa_store_pm_info(void)
9015 + {
9016 +- u16 ax, bx, di, es;
9017 ++ u16 ax, bx, cx, di, es;
9018 +
9019 + ax = 0x4f0a;
9020 +- bx = di = 0;
9021 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
9022 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
9023 +- : : "ecx", "esi");
9024 ++ bx = cx = di = 0;
9025 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
9026 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
9027 ++ : : "esi");
9028 +
9029 + if (ax != 0x004f)
9030 + return;
9031 +
9032 + boot_params.screen_info.vesapm_seg = es;
9033 + boot_params.screen_info.vesapm_off = di;
9034 ++ boot_params.screen_info.vesapm_size = cx;
9035 + }
9036 +
9037 + /*
9038 +@@ -265,7 +266,7 @@ void vesa_store_edid(void)
9039 + /* Note: The VBE DDC spec is different from the main VESA spec;
9040 + we genuinely have to assume all registers are destroyed here. */
9041 +
9042 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
9043 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
9044 + : "+a" (ax), "+b" (bx)
9045 + : "c" (cx), "D" (di)
9046 + : "esi");
9047 +@@ -281,7 +282,7 @@ void vesa_store_edid(void)
9048 + cx = 0; /* Controller 0 */
9049 + dx = 0; /* EDID block number */
9050 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
9051 +- asm(INT10
9052 ++ asm volatile(INT10
9053 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
9054 + : "c" (cx), "D" (di)
9055 + : "esi");
9056 +diff -urNp a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
9057 +--- a/arch/x86/boot/video-vga.c 2008-08-20 11:16:13.000000000 -0700
9058 ++++ b/arch/x86/boot/video-vga.c 2008-08-20 18:36:57.000000000 -0700
9059 +@@ -225,7 +225,7 @@ static int vga_probe(void)
9060 + };
9061 + u8 vga_flag;
9062 +
9063 +- asm(INT10
9064 ++ asm volatile(INT10
9065 + : "=b" (boot_params.screen_info.orig_video_ega_bx)
9066 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
9067 + : "ecx", "edx", "esi", "edi");
9068 +@@ -233,7 +233,7 @@ static int vga_probe(void)
9069 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
9070 + if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
9071 + /* EGA/VGA */
9072 +- asm(INT10
9073 ++ asm volatile(INT10
9074 + : "=a" (vga_flag)
9075 + : "a" (0x1a00)
9076 + : "ebx", "ecx", "edx", "esi", "edi");
9077 +diff -urNp a/arch/x86/boot/video.c b/arch/x86/boot/video.c
9078 +--- a/arch/x86/boot/video.c 2008-08-20 11:16:13.000000000 -0700
9079 ++++ b/arch/x86/boot/video.c 2008-08-20 18:36:57.000000000 -0700
9080 +@@ -40,7 +40,7 @@ static void store_cursor_position(void)
9081 +
9082 + ax = 0x0300;
9083 + bx = 0;
9084 +- asm(INT10
9085 ++ asm volatile(INT10
9086 + : "=d" (curpos), "+a" (ax), "+b" (bx)
9087 + : : "ecx", "esi", "edi");
9088 +
9089 +@@ -55,7 +55,7 @@ static void store_video_mode(void)
9090 + /* N.B.: the saving of the video page here is a bit silly,
9091 + since we pretty much assume page 0 everywhere. */
9092 + ax = 0x0f00;
9093 +- asm(INT10
9094 ++ asm volatile(INT10
9095 + : "+a" (ax), "=b" (page)
9096 + : : "ecx", "edx", "esi", "edi");
9097 +
9098 +diff -urNp a/arch/x86/boot/voyager.c b/arch/x86/boot/voyager.c
9099 +--- a/arch/x86/boot/voyager.c 2008-08-20 11:16:13.000000000 -0700
9100 ++++ b/arch/x86/boot/voyager.c 2008-08-20 18:36:57.000000000 -0700
9101 +@@ -25,7 +25,7 @@ int query_voyager(void)
9102 +
9103 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
9104 +
9105 +- asm("pushw %%es ; "
9106 ++ asm volatile("pushw %%es ; "
9107 + "int $0x15 ; "
9108 + "setc %0 ; "
9109 + "movw %%es, %1 ; "
9110 +diff -urNp a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
9111 +--- a/arch/x86/ia32/ia32_signal.c 2008-08-20 11:16:13.000000000 -0700
9112 ++++ b/arch/x86/ia32/ia32_signal.c 2008-08-20 18:36:57.000000000 -0700
9113 +@@ -536,6 +536,7 @@ int ia32_setup_rt_frame(int sig, struct
9114 + __NR_ia32_rt_sigreturn,
9115 + 0x80cd,
9116 + 0,
9117 ++ 0
9118 + };
9119 +
9120 + frame = get_sigframe(ka, regs, sizeof(*frame));
9121 +diff -urNp a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
9122 +--- a/arch/x86/kernel/acpi/boot.c 2008-08-20 11:16:13.000000000 -0700
9123 ++++ b/arch/x86/kernel/acpi/boot.c 2008-08-20 18:36:57.000000000 -0700
9124 +@@ -1119,7 +1119,7 @@ static struct dmi_system_id __initdata a
9125 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
9126 + },
9127 + },
9128 +- {}
9129 ++ { NULL, NULL, {{0, NULL}}, NULL}
9130 + };
9131 +
9132 + #endif /* __i386__ */
9133 +diff -urNp a/arch/x86/kernel/acpi/sleep_32.c b/arch/x86/kernel/acpi/sleep_32.c
9134 +--- a/arch/x86/kernel/acpi/sleep_32.c 2008-08-20 11:16:13.000000000 -0700
9135 ++++ b/arch/x86/kernel/acpi/sleep_32.c 2008-08-20 18:36:57.000000000 -0700
9136 +@@ -28,7 +28,7 @@ static __initdata struct dmi_system_id a
9137 + DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
9138 + },
9139 + },
9140 +- {}
9141 ++ { NULL, NULL, {{0, NULL}}, NULL}
9142 + };
9143 +
9144 + static int __init acpisleep_dmi_init(void)
9145 +diff -urNp a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
9146 +--- a/arch/x86/kernel/acpi/wakeup_32.S 2008-08-20 11:16:13.000000000 -0700
9147 ++++ b/arch/x86/kernel/acpi/wakeup_32.S 2008-08-20 18:36:57.000000000 -0700
9148 +@@ -2,6 +2,7 @@
9149 + #include <linux/linkage.h>
9150 + #include <asm/segment.h>
9151 + #include <asm/page.h>
9152 ++#include <asm/msr-index.h>
9153 +
9154 + #
9155 + # wakeup_code runs in real mode, and at unknown address (determined at run-time).
9156 +@@ -79,7 +80,7 @@ wakeup_code:
9157 + # restore efer setting
9158 + movl real_save_efer_edx - wakeup_code, %edx
9159 + movl real_save_efer_eax - wakeup_code, %eax
9160 +- mov $0xc0000080, %ecx
9161 ++ mov $MSR_EFER, %ecx
9162 + wrmsr
9163 + 4:
9164 + # make sure %cr4 is set correctly (features, etc)
9165 +@@ -196,13 +197,11 @@ wakeup_pmode_return:
9166 + # and restore the stack ... but you need gdt for this to work
9167 + movl saved_context_esp, %esp
9168 +
9169 +- movl %cs:saved_magic, %eax
9170 +- cmpl $0x12345678, %eax
9171 ++ cmpl $0x12345678, saved_magic
9172 + jne bogus_magic
9173 +
9174 + # jump to place where we left off
9175 +- movl saved_eip,%eax
9176 +- jmp *%eax
9177 ++ jmp *(saved_eip)
9178 +
9179 + bogus_magic:
9180 + jmp bogus_magic
9181 +@@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
9182 + # save efer setting
9183 + pushl %eax
9184 + movl %eax, %ebx
9185 +- mov $0xc0000080, %ecx
9186 ++ mov $MSR_EFER, %ecx
9187 + rdmsr
9188 + movl %edx, real_save_efer_edx - wakeup_start (%ebx)
9189 + movl %eax, real_save_efer_eax - wakeup_start (%ebx)
9190 +diff -urNp a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
9191 +--- a/arch/x86/kernel/alternative.c 2008-08-20 11:16:13.000000000 -0700
9192 ++++ b/arch/x86/kernel/alternative.c 2008-08-20 18:36:57.000000000 -0700
9193 +@@ -403,7 +403,7 @@ void apply_paravirt(struct paravirt_patc
9194 +
9195 + BUG_ON(p->len > MAX_PATCH_LEN);
9196 + /* prep the buffer with the original instructions */
9197 +- memcpy(insnbuf, p->instr, p->len);
9198 ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
9199 + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
9200 + (unsigned long)p->instr, p->len);
9201 +
9202 +@@ -485,7 +485,19 @@ void __init alternative_instructions(voi
9203 + */
9204 + void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
9205 + {
9206 +- memcpy(addr, opcode, len);
9207 ++
9208 ++#ifdef CONFIG_PAX_KERNEXEC
9209 ++ unsigned long cr0;
9210 ++
9211 ++ pax_open_kernel(cr0);
9212 ++#endif
9213 ++
9214 ++ memcpy(ktla_ktva(addr), opcode, len);
9215 ++
9216 ++#ifdef CONFIG_PAX_KERNEXEC
9217 ++ pax_close_kernel(cr0);
9218 ++#endif
9219 ++
9220 + sync_core();
9221 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
9222 + that causes hangs on some VIA CPUs. */
9223 +diff -urNp a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
9224 +--- a/arch/x86/kernel/apm_32.c 2008-08-20 11:16:13.000000000 -0700
9225 ++++ b/arch/x86/kernel/apm_32.c 2008-08-20 18:36:57.000000000 -0700
9226 +@@ -406,7 +406,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
9227 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
9228 + static struct apm_user *user_list;
9229 + static DEFINE_SPINLOCK(user_list_lock);
9230 +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
9231 ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
9232 +
9233 + static const char driver_version[] = "1.16ac"; /* no spaces */
9234 +
9235 +@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
9236 + struct desc_struct save_desc_40;
9237 + struct desc_struct *gdt;
9238 +
9239 ++#ifdef CONFIG_PAX_KERNEXEC
9240 ++ unsigned long cr0;
9241 ++#endif
9242 ++
9243 + cpus = apm_save_cpus();
9244 +
9245 + cpu = get_cpu();
9246 + gdt = get_cpu_gdt_table(cpu);
9247 + save_desc_40 = gdt[0x40 / 8];
9248 ++
9249 ++#ifdef CONFIG_PAX_KERNEXEC
9250 ++ pax_open_kernel(cr0);
9251 ++#endif
9252 ++
9253 + gdt[0x40 / 8] = bad_bios_desc;
9254 +
9255 ++#ifdef CONFIG_PAX_KERNEXEC
9256 ++ pax_close_kernel(cr0);
9257 ++#endif
9258 ++
9259 + apm_irq_save(flags);
9260 + APM_DO_SAVE_SEGS;
9261 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
9262 + APM_DO_RESTORE_SEGS;
9263 + apm_irq_restore(flags);
9264 ++
9265 ++#ifdef CONFIG_PAX_KERNEXEC
9266 ++ pax_open_kernel(cr0);
9267 ++#endif
9268 ++
9269 + gdt[0x40 / 8] = save_desc_40;
9270 ++
9271 ++#ifdef CONFIG_PAX_KERNEXEC
9272 ++ pax_close_kernel(cr0);
9273 ++#endif
9274 ++
9275 + put_cpu();
9276 + apm_restore_cpus(cpus);
9277 +
9278 +@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
9279 + struct desc_struct save_desc_40;
9280 + struct desc_struct *gdt;
9281 +
9282 ++#ifdef CONFIG_PAX_KERNEXEC
9283 ++ unsigned long cr0;
9284 ++#endif
9285 ++
9286 + cpus = apm_save_cpus();
9287 +
9288 + cpu = get_cpu();
9289 + gdt = get_cpu_gdt_table(cpu);
9290 + save_desc_40 = gdt[0x40 / 8];
9291 ++
9292 ++#ifdef CONFIG_PAX_KERNEXEC
9293 ++ pax_open_kernel(cr0);
9294 ++#endif
9295 ++
9296 + gdt[0x40 / 8] = bad_bios_desc;
9297 +
9298 ++#ifdef CONFIG_PAX_KERNEXEC
9299 ++ pax_close_kernel(cr0);
9300 ++#endif
9301 ++
9302 + apm_irq_save(flags);
9303 + APM_DO_SAVE_SEGS;
9304 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
9305 + APM_DO_RESTORE_SEGS;
9306 + apm_irq_restore(flags);
9307 ++
9308 ++#ifdef CONFIG_PAX_KERNEXEC
9309 ++ pax_open_kernel(cr0);
9310 ++#endif
9311 ++
9312 + gdt[0x40 / 8] = save_desc_40;
9313 ++
9314 ++#ifdef CONFIG_PAX_KERNEXEC
9315 ++ pax_close_kernel(cr0);
9316 ++#endif
9317 ++
9318 + put_cpu();
9319 + apm_restore_cpus(cpus);
9320 + return error;
9321 +@@ -925,7 +971,7 @@ recalc:
9322 +
9323 + static void apm_power_off(void)
9324 + {
9325 +- unsigned char po_bios_call[] = {
9326 ++ const unsigned char po_bios_call[] = {
9327 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
9328 + 0x8e, 0xd0, /* movw ax,ss */
9329 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
9330 +@@ -1881,7 +1927,10 @@ static const struct file_operations apm_
9331 + static struct miscdevice apm_device = {
9332 + APM_MINOR_DEV,
9333 + "apm_bios",
9334 +- &apm_bios_fops
9335 ++ &apm_bios_fops,
9336 ++ {NULL, NULL},
9337 ++ NULL,
9338 ++ NULL
9339 + };
9340 +
9341 +
9342 +@@ -2202,7 +2251,7 @@ static struct dmi_system_id __initdata a
9343 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
9344 + },
9345 +
9346 +- { }
9347 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
9348 + };
9349 +
9350 + /*
9351 +@@ -2221,6 +2270,10 @@ static int __init apm_init(void)
9352 + struct desc_struct *gdt;
9353 + int err;
9354 +
9355 ++#ifdef CONFIG_PAX_KERNEXEC
9356 ++ unsigned long cr0;
9357 ++#endif
9358 ++
9359 + dmi_check_system(apm_dmi_table);
9360 +
9361 + if (apm_info.bios.version == 0 || paravirt_enabled()) {
9362 +@@ -2294,9 +2347,18 @@ static int __init apm_init(void)
9363 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
9364 + * even though they are called in protected mode.
9365 + */
9366 ++
9367 ++#ifdef CONFIG_PAX_KERNEXEC
9368 ++ pax_open_kernel(cr0);
9369 ++#endif
9370 ++
9371 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
9372 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
9373 +
9374 ++#ifdef CONFIG_PAX_KERNEXEC
9375 ++ pax_close_kernel(cr0);
9376 ++#endif
9377 ++
9378 + /*
9379 + * Set up the long jump entry point to the APM BIOS, which is called
9380 + * from inline assembly.
9381 +@@ -2315,6 +2377,11 @@ static int __init apm_init(void)
9382 + * code to that CPU.
9383 + */
9384 + gdt = get_cpu_gdt_table(0);
9385 ++
9386 ++#ifdef CONFIG_PAX_KERNEXEC
9387 ++ pax_open_kernel(cr0);
9388 ++#endif
9389 ++
9390 + set_base(gdt[APM_CS >> 3],
9391 + __va((unsigned long)apm_info.bios.cseg << 4));
9392 + set_base(gdt[APM_CS_16 >> 3],
9393 +@@ -2322,6 +2389,10 @@ static int __init apm_init(void)
9394 + set_base(gdt[APM_DS >> 3],
9395 + __va((unsigned long)apm_info.bios.dseg << 4));
9396 +
9397 ++#ifdef CONFIG_PAX_KERNEXEC
9398 ++ pax_close_kernel(cr0);
9399 ++#endif
9400 ++
9401 + apm_proc = create_proc_entry("apm", 0, NULL);
9402 + if (apm_proc)
9403 + apm_proc->proc_fops = &apm_file_ops;
9404 +diff -urNp a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
9405 +--- a/arch/x86/kernel/asm-offsets_32.c 2008-08-20 11:16:13.000000000 -0700
9406 ++++ b/arch/x86/kernel/asm-offsets_32.c 2008-08-20 18:36:57.000000000 -0700
9407 +@@ -107,6 +107,7 @@ void foo(void)
9408 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
9409 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
9410 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
9411 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
9412 +
9413 + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
9414 +
9415 +@@ -120,6 +121,7 @@ void foo(void)
9416 + OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
9417 + OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
9418 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
9419 ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
9420 + #endif
9421 +
9422 + #ifdef CONFIG_XEN
9423 +diff -urNp a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
9424 +--- a/arch/x86/kernel/asm-offsets_64.c 2008-08-20 11:16:13.000000000 -0700
9425 ++++ b/arch/x86/kernel/asm-offsets_64.c 2008-08-20 18:36:57.000000000 -0700
9426 +@@ -124,6 +124,7 @@ int main(void)
9427 + ENTRY(cr8);
9428 + BLANK();
9429 + #undef ENTRY
9430 ++ DEFINE(TSS_size, sizeof(struct tss_struct));
9431 + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
9432 + BLANK();
9433 + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
9434 +diff -urNp a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
9435 +--- a/arch/x86/kernel/cpu/common.c 2008-08-20 11:16:13.000000000 -0700
9436 ++++ b/arch/x86/kernel/cpu/common.c 2008-08-20 18:36:57.000000000 -0700
9437 +@@ -4,7 +4,6 @@
9438 + #include <linux/smp.h>
9439 + #include <linux/module.h>
9440 + #include <linux/percpu.h>
9441 +-#include <linux/bootmem.h>
9442 + #include <asm/semaphore.h>
9443 + #include <asm/processor.h>
9444 + #include <asm/i387.h>
9445 +@@ -21,42 +20,6 @@
9446 +
9447 + #include "cpu.h"
9448 +
9449 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
9450 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
9451 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
9452 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
9453 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
9454 +- /*
9455 +- * Segments used for calling PnP BIOS have byte granularity.
9456 +- * They code segments and data segments have fixed 64k limits,
9457 +- * the transfer segment sizes are set at run time.
9458 +- */
9459 +- /* 32-bit code */
9460 +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
9461 +- /* 16-bit code */
9462 +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
9463 +- /* 16-bit data */
9464 +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
9465 +- /* 16-bit data */
9466 +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
9467 +- /* 16-bit data */
9468 +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
9469 +- /*
9470 +- * The APM segments have byte granularity and their bases
9471 +- * are set at run time. All have 64k limits.
9472 +- */
9473 +- /* 32-bit code */
9474 +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
9475 +- /* 16-bit code */
9476 +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
9477 +- /* data */
9478 +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
9479 +-
9480 +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
9481 +- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
9482 +-} };
9483 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
9484 +-
9485 + __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
9486 +
9487 + static int cachesize_override __cpuinitdata = -1;
9488 +@@ -478,6 +441,10 @@ void __cpuinit identify_cpu(struct cpuin
9489 + * we do "generic changes."
9490 + */
9491 +
9492 ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
9493 ++ setup_clear_cpu_cap(X86_FEATURE_SEP);
9494 ++#endif
9495 ++
9496 + /* If the model name is still unset, do table lookup. */
9497 + if ( !c->x86_model_id[0] ) {
9498 + char *p;
9499 +@@ -614,7 +581,7 @@ static __init int setup_disablecpuid(cha
9500 + }
9501 + __setup("clearcpuid=", setup_disablecpuid);
9502 +
9503 +-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
9504 ++cpumask_t cpu_initialized = CPU_MASK_NONE;
9505 +
9506 + /* This is hacky. :)
9507 + * We're emulating future behavior.
9508 +@@ -650,7 +617,7 @@ void switch_to_new_gdt(void)
9509 + {
9510 + struct desc_ptr gdt_descr;
9511 +
9512 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
9513 ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
9514 + gdt_descr.size = GDT_SIZE - 1;
9515 + load_gdt(&gdt_descr);
9516 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
9517 +@@ -666,7 +633,7 @@ void __cpuinit cpu_init(void)
9518 + {
9519 + int cpu = smp_processor_id();
9520 + struct task_struct *curr = current;
9521 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
9522 ++ struct tss_struct *t = init_tss + cpu;
9523 + struct thread_struct *thread = &curr->thread;
9524 +
9525 + if (cpu_test_and_set(cpu, cpu_initialized)) {
9526 +@@ -721,7 +688,7 @@ void __cpuinit cpu_init(void)
9527 + }
9528 +
9529 + #ifdef CONFIG_HOTPLUG_CPU
9530 +-void __cpuinit cpu_uninit(void)
9531 ++void cpu_uninit(void)
9532 + {
9533 + int cpu = raw_smp_processor_id();
9534 + cpu_clear(cpu, cpu_initialized);
9535 +diff -urNp a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
9536 +--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-08-20 11:16:13.000000000 -0700
9537 ++++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-08-20 18:36:57.000000000 -0700
9538 +@@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
9539 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
9540 + },
9541 + },
9542 +- { }
9543 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
9544 + };
9545 + #endif
9546 +
9547 +diff -urNp a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
9548 +--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-08-20 11:16:13.000000000 -0700
9549 ++++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-08-20 18:36:57.000000000 -0700
9550 +@@ -223,7 +223,7 @@ static struct cpu_model models[] =
9551 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
9552 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
9553 +
9554 +- { NULL, }
9555 ++ { NULL, NULL, 0, NULL}
9556 + };
9557 + #undef _BANIAS
9558 + #undef BANIAS
9559 +diff -urNp a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
9560 +--- a/arch/x86/kernel/cpu/intel.c 2008-08-20 11:16:13.000000000 -0700
9561 ++++ b/arch/x86/kernel/cpu/intel.c 2008-08-20 18:36:57.000000000 -0700
9562 +@@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
9563 + * Update the IDT descriptor and reload the IDT so that
9564 + * it uses the read-only mapped virtual address.
9565 + */
9566 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
9567 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
9568 + load_idt(&idt_descr);
9569 + }
9570 + #endif
9571 +diff -urNp a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
9572 +--- a/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-08-20 11:16:13.000000000 -0700
9573 ++++ b/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-08-20 18:36:57.000000000 -0700
9574 +@@ -670,6 +670,7 @@ static struct miscdevice mce_log_device
9575 + MISC_MCELOG_MINOR,
9576 + "mcelog",
9577 + &mce_chrdev_ops,
9578 ++ {NULL, NULL}, NULL, NULL
9579 + };
9580 +
9581 + static unsigned long old_cr4 __initdata;
9582 +diff -urNp a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
9583 +--- a/arch/x86/kernel/cpu/mtrr/generic.c 2008-08-20 11:16:13.000000000 -0700
9584 ++++ b/arch/x86/kernel/cpu/mtrr/generic.c 2008-08-20 18:36:57.000000000 -0700
9585 +@@ -30,11 +30,11 @@ static struct fixed_range_block fixed_ra
9586 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
9587 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
9588 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
9589 +- {}
9590 ++ { 0, 0 }
9591 + };
9592 +
9593 + static unsigned long smp_changes_mask;
9594 +-static struct mtrr_state mtrr_state = {};
9595 ++static struct mtrr_state mtrr_state;
9596 +
9597 + #undef MODULE_PARAM_PREFIX
9598 + #define MODULE_PARAM_PREFIX "mtrr."
9599 +diff -urNp a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
9600 +--- a/arch/x86/kernel/crash.c 2008-08-20 11:16:13.000000000 -0700
9601 ++++ b/arch/x86/kernel/crash.c 2008-08-20 18:36:57.000000000 -0700
9602 +@@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not
9603 + local_irq_disable();
9604 +
9605 + #ifdef CONFIG_X86_32
9606 +- if (!user_mode_vm(regs)) {
9607 ++ if (!user_mode(regs)) {
9608 + crash_fixup_ss_esp(&fixed_regs, regs);
9609 + regs = &fixed_regs;
9610 + }
9611 +diff -urNp a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
9612 +--- a/arch/x86/kernel/doublefault_32.c 2008-08-20 11:16:13.000000000 -0700
9613 ++++ b/arch/x86/kernel/doublefault_32.c 2008-08-20 18:36:57.000000000 -0700
9614 +@@ -11,7 +11,7 @@
9615 +
9616 + #define DOUBLEFAULT_STACKSIZE (1024)
9617 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
9618 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
9619 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
9620 +
9621 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
9622 +
9623 +@@ -21,7 +21,7 @@ static void doublefault_fn(void)
9624 + unsigned long gdt, tss;
9625 +
9626 + store_gdt(&gdt_desc);
9627 +- gdt = gdt_desc.address;
9628 ++ gdt = (unsigned long)gdt_desc.address;
9629 +
9630 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
9631 +
9632 +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
9633 + /* 0x2 bit is always set */
9634 + .flags = X86_EFLAGS_SF | 0x2,
9635 + .sp = STACK_START,
9636 +- .es = __USER_DS,
9637 ++ .es = __KERNEL_DS,
9638 + .cs = __KERNEL_CS,
9639 + .ss = __KERNEL_DS,
9640 +- .ds = __USER_DS,
9641 ++ .ds = __KERNEL_DS,
9642 + .fs = __KERNEL_PERCPU,
9643 +
9644 + .__cr3 = __pa(swapper_pg_dir)
9645 +diff -urNp a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
9646 +--- a/arch/x86/kernel/efi_32.c 2008-08-20 11:16:13.000000000 -0700
9647 ++++ b/arch/x86/kernel/efi_32.c 2008-08-20 18:36:57.000000000 -0700
9648 +@@ -38,70 +38,37 @@
9649 + */
9650 +
9651 + static unsigned long efi_rt_eflags;
9652 +-static pgd_t efi_bak_pg_dir_pointer[2];
9653 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
9654 +
9655 +-void efi_call_phys_prelog(void)
9656 ++void __init efi_call_phys_prelog(void)
9657 + {
9658 +- unsigned long cr4;
9659 +- unsigned long temp;
9660 + struct desc_ptr gdt_descr;
9661 +
9662 + local_irq_save(efi_rt_eflags);
9663 +
9664 +- /*
9665 +- * If I don't have PSE, I should just duplicate two entries in page
9666 +- * directory. If I have PSE, I just need to duplicate one entry in
9667 +- * page directory.
9668 +- */
9669 +- cr4 = read_cr4();
9670 +-
9671 +- if (cr4 & X86_CR4_PSE) {
9672 +- efi_bak_pg_dir_pointer[0].pgd =
9673 +- swapper_pg_dir[pgd_index(0)].pgd;
9674 +- swapper_pg_dir[0].pgd =
9675 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
9676 +- } else {
9677 +- efi_bak_pg_dir_pointer[0].pgd =
9678 +- swapper_pg_dir[pgd_index(0)].pgd;
9679 +- efi_bak_pg_dir_pointer[1].pgd =
9680 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
9681 +- swapper_pg_dir[pgd_index(0)].pgd =
9682 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
9683 +- temp = PAGE_OFFSET + 0x400000;
9684 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
9685 +- swapper_pg_dir[pgd_index(temp)].pgd;
9686 +- }
9687 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
9688 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
9689 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
9690 +
9691 + /*
9692 + * After the lock is released, the original page table is restored.
9693 + */
9694 + __flush_tlb_all();
9695 +
9696 +- gdt_descr.address = __pa(get_cpu_gdt_table(0));
9697 ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
9698 + gdt_descr.size = GDT_SIZE - 1;
9699 + load_gdt(&gdt_descr);
9700 + }
9701 +
9702 +-void efi_call_phys_epilog(void)
9703 ++void __init efi_call_phys_epilog(void)
9704 + {
9705 +- unsigned long cr4;
9706 + struct desc_ptr gdt_descr;
9707 +
9708 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
9709 ++ gdt_descr.address = get_cpu_gdt_table(0);
9710 + gdt_descr.size = GDT_SIZE - 1;
9711 + load_gdt(&gdt_descr);
9712 +
9713 +- cr4 = read_cr4();
9714 +-
9715 +- if (cr4 & X86_CR4_PSE) {
9716 +- swapper_pg_dir[pgd_index(0)].pgd =
9717 +- efi_bak_pg_dir_pointer[0].pgd;
9718 +- } else {
9719 +- swapper_pg_dir[pgd_index(0)].pgd =
9720 +- efi_bak_pg_dir_pointer[0].pgd;
9721 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
9722 +- efi_bak_pg_dir_pointer[1].pgd;
9723 +- }
9724 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
9725 +
9726 + /*
9727 + * After the lock is released, the original page table is restored.
9728 +diff -urNp a/arch/x86/kernel/efi_stub_32.S b/arch/x86/kernel/efi_stub_32.S
9729 +--- a/arch/x86/kernel/efi_stub_32.S 2008-08-20 11:16:13.000000000 -0700
9730 ++++ b/arch/x86/kernel/efi_stub_32.S 2008-08-20 18:36:57.000000000 -0700
9731 +@@ -6,6 +6,7 @@
9732 + */
9733 +
9734 + #include <linux/linkage.h>
9735 ++#include <linux/init.h>
9736 + #include <asm/page.h>
9737 +
9738 + /*
9739 +@@ -20,7 +21,7 @@
9740 + * service functions will comply with gcc calling convention, too.
9741 + */
9742 +
9743 +-.text
9744 ++__INIT
9745 + ENTRY(efi_call_phys)
9746 + /*
9747 + * 0. The function can only be called in Linux kernel. So CS has been
9748 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
9749 + * The mapping of lower virtual memory has been created in prelog and
9750 + * epilog.
9751 + */
9752 +- movl $1f, %edx
9753 +- subl $__PAGE_OFFSET, %edx
9754 +- jmp *%edx
9755 ++ jmp 1f-__PAGE_OFFSET
9756 + 1:
9757 +
9758 + /*
9759 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
9760 + * parameter 2, ..., param n. To make things easy, we save the return
9761 + * address of efi_call_phys in a global variable.
9762 + */
9763 +- popl %edx
9764 +- movl %edx, saved_return_addr
9765 +- /* get the function pointer into ECX*/
9766 +- popl %ecx
9767 +- movl %ecx, efi_rt_function_ptr
9768 +- movl $2f, %edx
9769 +- subl $__PAGE_OFFSET, %edx
9770 +- pushl %edx
9771 ++ popl (saved_return_addr)
9772 ++ popl (efi_rt_function_ptr)
9773 +
9774 + /*
9775 + * 3. Clear PG bit in %CR0.
9776 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
9777 + /*
9778 + * 5. Call the physical function.
9779 + */
9780 +- jmp *%ecx
9781 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
9782 +
9783 +-2:
9784 + /*
9785 + * 6. After EFI runtime service returns, control will return to
9786 + * following instruction. We'd better readjust stack pointer first.
9787 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
9788 + movl %cr0, %edx
9789 + orl $0x80000000, %edx
9790 + movl %edx, %cr0
9791 +- jmp 1f
9792 +-1:
9793 ++
9794 + /*
9795 + * 8. Now restore the virtual mode from flat mode by
9796 + * adding EIP with PAGE_OFFSET.
9797 + */
9798 +- movl $1f, %edx
9799 +- jmp *%edx
9800 ++ jmp 1f+__PAGE_OFFSET
9801 + 1:
9802 +
9803 + /*
9804 + * 9. Balance the stack. And because EAX contain the return value,
9805 + * we'd better not clobber it.
9806 + */
9807 +- leal efi_rt_function_ptr, %edx
9808 +- movl (%edx), %ecx
9809 +- pushl %ecx
9810 ++ pushl (efi_rt_function_ptr)
9811 +
9812 + /*
9813 +- * 10. Push the saved return address onto the stack and return.
9814 ++ * 10. Return to the saved return address.
9815 + */
9816 +- leal saved_return_addr, %edx
9817 +- movl (%edx), %ecx
9818 +- pushl %ecx
9819 +- ret
9820 ++ jmpl *(saved_return_addr)
9821 + .previous
9822 +
9823 +-.data
9824 ++__INITDATA
9825 + saved_return_addr:
9826 + .long 0
9827 + efi_rt_function_ptr:
9828 +diff -urNp a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
9829 +--- a/arch/x86/kernel/entry_32.S 2008-08-20 11:16:13.000000000 -0700
9830 ++++ b/arch/x86/kernel/entry_32.S 2008-08-20 18:36:57.000000000 -0700
9831 +@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
9832 + #define resume_userspace_sig resume_userspace
9833 + #endif
9834 +
9835 +-#define SAVE_ALL \
9836 ++#define __SAVE_ALL(_DS) \
9837 + cld; \
9838 + pushl %fs; \
9839 + CFI_ADJUST_CFA_OFFSET 4;\
9840 +@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
9841 + pushl %ebx; \
9842 + CFI_ADJUST_CFA_OFFSET 4;\
9843 + CFI_REL_OFFSET ebx, 0;\
9844 +- movl $(__USER_DS), %edx; \
9845 ++ movl $(_DS), %edx; \
9846 + movl %edx, %ds; \
9847 + movl %edx, %es; \
9848 + movl $(__KERNEL_PERCPU), %edx; \
9849 + movl %edx, %fs
9850 +
9851 ++#ifdef CONFIG_PAX_KERNEXEC
9852 ++#define SAVE_ALL \
9853 ++ __SAVE_ALL(__KERNEL_DS); \
9854 ++ GET_CR0_INTO_EDX; \
9855 ++ movl %edx, %esi; \
9856 ++ orl $X86_CR0_WP, %edx; \
9857 ++ xorl %edx, %esi; \
9858 ++ SET_CR0_FROM_EDX
9859 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
9860 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
9861 ++#else
9862 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
9863 ++#endif
9864 ++
9865 + #define RESTORE_INT_REGS \
9866 + popl %ebx; \
9867 + CFI_ADJUST_CFA_OFFSET -4;\
9868 +@@ -225,6 +239,11 @@ ENTRY(ret_from_fork)
9869 + CFI_ADJUST_CFA_OFFSET 4
9870 + popfl
9871 + CFI_ADJUST_CFA_OFFSET -4
9872 ++
9873 ++#ifdef CONFIG_PAX_KERNEXEC
9874 ++ xorl %esi, %esi
9875 ++#endif
9876 ++
9877 + jmp syscall_exit
9878 + CFI_ENDPROC
9879 + END(ret_from_fork)
9880 +@@ -248,7 +267,17 @@ check_userspace:
9881 + movb PT_CS(%esp), %al
9882 + andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
9883 + cmpl $USER_RPL, %eax
9884 ++
9885 ++#ifdef CONFIG_PAX_KERNEXEC
9886 ++ jae resume_userspace
9887 ++
9888 ++ GET_CR0_INTO_EDX
9889 ++ xorl %esi, %edx
9890 ++ SET_CR0_FROM_EDX
9891 ++ jmp resume_kernel
9892 ++#else
9893 + jb resume_kernel # not returning to v8086 or userspace
9894 ++#endif
9895 +
9896 + ENTRY(resume_userspace)
9897 + LOCKDEP_SYS_EXIT
9898 +@@ -308,10 +337,9 @@ sysenter_past_esp:
9899 + /*CFI_REL_OFFSET cs, 0*/
9900 + /*
9901 + * Push current_thread_info()->sysenter_return to the stack.
9902 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
9903 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
9904 + */
9905 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
9906 ++ GET_THREAD_INFO(%ebp)
9907 ++ pushl TI_sysenter_return(%ebp)
9908 + CFI_ADJUST_CFA_OFFSET 4
9909 + CFI_REL_OFFSET eip, 0
9910 +
9911 +@@ -319,9 +347,17 @@ sysenter_past_esp:
9912 + * Load the potential sixth argument from user stack.
9913 + * Careful about security.
9914 + */
9915 ++ movl 12(%esp),%ebp
9916 ++
9917 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
9918 ++ mov 16(%esp),%ds
9919 ++1: movl %ds:(%ebp),%ebp
9920 ++#else
9921 + cmpl $__PAGE_OFFSET-3,%ebp
9922 + jae syscall_fault
9923 + 1: movl (%ebp),%ebp
9924 ++#endif
9925 ++
9926 + .section __ex_table,"a"
9927 + .align 4
9928 + .long 1b,syscall_fault
9929 +@@ -345,20 +381,37 @@ sysenter_past_esp:
9930 + movl TI_flags(%ebp), %ecx
9931 + testw $_TIF_ALLWORK_MASK, %cx
9932 + jne syscall_exit_work
9933 ++
9934 ++#ifdef CONFIG_PAX_RANDKSTACK
9935 ++ pushl %eax
9936 ++ CFI_ADJUST_CFA_OFFSET 4
9937 ++ call pax_randomize_kstack
9938 ++ popl %eax
9939 ++ CFI_ADJUST_CFA_OFFSET -4
9940 ++#endif
9941 ++
9942 + /* if something modifies registers it must also disable sysexit */
9943 + movl PT_EIP(%esp), %edx
9944 + movl PT_OLDESP(%esp), %ecx
9945 + xorl %ebp,%ebp
9946 + TRACE_IRQS_ON
9947 + 1: mov PT_FS(%esp), %fs
9948 ++2: mov PT_DS(%esp), %ds
9949 ++3: mov PT_ES(%esp), %es
9950 + ENABLE_INTERRUPTS_SYSCALL_RET
9951 + CFI_ENDPROC
9952 + .pushsection .fixup,"ax"
9953 +-2: movl $0,PT_FS(%esp)
9954 ++4: movl $0,PT_FS(%esp)
9955 ++ jmp 1b
9956 ++5: movl $0,PT_DS(%esp)
9957 ++ jmp 1b
9958 ++6: movl $0,PT_ES(%esp)
9959 + jmp 1b
9960 + .section __ex_table,"a"
9961 + .align 4
9962 +- .long 1b,2b
9963 ++ .long 1b,4b
9964 ++ .long 2b,5b
9965 ++ .long 3b,6b
9966 + .popsection
9967 + ENDPROC(ia32_sysenter_target)
9968 +
9969 +@@ -392,6 +445,10 @@ no_singlestep:
9970 + testw $_TIF_ALLWORK_MASK, %cx # current->work
9971 + jne syscall_exit_work
9972 +
9973 ++#ifdef CONFIG_PAX_RANDKSTACK
9974 ++ call pax_randomize_kstack
9975 ++#endif
9976 ++
9977 + restore_all:
9978 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
9979 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
9980 +@@ -485,25 +542,19 @@ work_resched:
9981 +
9982 + work_notifysig: # deal with pending signals and
9983 + # notify-resume requests
9984 ++ movl %esp, %eax
9985 + #ifdef CONFIG_VM86
9986 + testl $VM_MASK, PT_EFLAGS(%esp)
9987 +- movl %esp, %eax
9988 +- jne work_notifysig_v86 # returning to kernel-space or
9989 ++ jz 1f # returning to kernel-space or
9990 + # vm86-space
9991 +- xorl %edx, %edx
9992 +- call do_notify_resume
9993 +- jmp resume_userspace_sig
9994 +
9995 +- ALIGN
9996 +-work_notifysig_v86:
9997 + pushl %ecx # save ti_flags for do_notify_resume
9998 + CFI_ADJUST_CFA_OFFSET 4
9999 + call save_v86_state # %eax contains pt_regs pointer
10000 + popl %ecx
10001 + CFI_ADJUST_CFA_OFFSET -4
10002 + movl %eax, %esp
10003 +-#else
10004 +- movl %esp, %eax
10005 ++1:
10006 + #endif
10007 + xorl %edx, %edx
10008 + call do_notify_resume
10009 +@@ -557,17 +608,24 @@ syscall_badsys:
10010 + END(syscall_badsys)
10011 + CFI_ENDPROC
10012 +
10013 +-#define FIXUP_ESPFIX_STACK \
10014 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
10015 +- PER_CPU(gdt_page, %ebx); \
10016 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
10017 +- addl %esp, %eax; \
10018 +- pushl $__KERNEL_DS; \
10019 +- CFI_ADJUST_CFA_OFFSET 4; \
10020 +- pushl %eax; \
10021 +- CFI_ADJUST_CFA_OFFSET 4; \
10022 +- lss (%esp), %esp; \
10023 ++.macro FIXUP_ESPFIX_STACK
10024 ++ /* since we are on a wrong stack, we cant make it a C code :( */
10025 ++#ifdef CONFIG_SMP
10026 ++ movl PER_CPU_VAR(cpu_number), %ebx;
10027 ++ shll $PAGE_SHIFT_asm, %ebx;
10028 ++ addl $cpu_gdt_table, %ebx;
10029 ++#else
10030 ++ movl $cpu_gdt_table, %ebx;
10031 ++#endif
10032 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
10033 ++ addl %esp, %eax;
10034 ++ pushl $__KERNEL_DS;
10035 ++ CFI_ADJUST_CFA_OFFSET 4;
10036 ++ pushl %eax;
10037 ++ CFI_ADJUST_CFA_OFFSET 4;
10038 ++ lss (%esp), %esp;
10039 + CFI_ADJUST_CFA_OFFSET -8;
10040 ++.endm
10041 + #define UNWIND_ESPFIX_STACK \
10042 + movl %ss, %eax; \
10043 + /* see if on espfix stack */ \
10044 +@@ -584,7 +642,7 @@ END(syscall_badsys)
10045 + * Build the entry stubs and pointer table with
10046 + * some assembler magic.
10047 + */
10048 +-.section .rodata,"a"
10049 ++.section .rodata,"a",@progbits
10050 + ENTRY(interrupt)
10051 + .text
10052 +
10053 +@@ -684,12 +742,21 @@ error_code:
10054 + popl %ecx
10055 + CFI_ADJUST_CFA_OFFSET -4
10056 + /*CFI_REGISTER es, ecx*/
10057 ++
10058 ++#ifdef CONFIG_PAX_KERNEXEC
10059 ++ GET_CR0_INTO_EDX
10060 ++ movl %edx, %esi
10061 ++ orl $X86_CR0_WP, %edx
10062 ++ xorl %edx, %esi
10063 ++ SET_CR0_FROM_EDX
10064 ++#endif
10065 ++
10066 + movl PT_FS(%esp), %edi # get the function address
10067 + movl PT_ORIG_EAX(%esp), %edx # get the error code
10068 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
10069 + mov %ecx, PT_FS(%esp)
10070 + /*CFI_REL_OFFSET fs, ES*/
10071 +- movl $(__USER_DS), %ecx
10072 ++ movl $(__KERNEL_DS), %ecx
10073 + movl %ecx, %ds
10074 + movl %ecx, %es
10075 + movl %esp,%eax # pt_regs pointer
10076 +@@ -823,6 +890,13 @@ nmi_stack_correct:
10077 + xorl %edx,%edx # zero error code
10078 + movl %esp,%eax # pt_regs pointer
10079 + call do_nmi
10080 ++
10081 ++#ifdef CONFIG_PAX_KERNEXEC
10082 ++ GET_CR0_INTO_EDX
10083 ++ xorl %esi, %edx
10084 ++ SET_CR0_FROM_EDX
10085 ++#endif
10086 ++
10087 + jmp restore_nocheck_notrace
10088 + CFI_ENDPROC
10089 +
10090 +@@ -863,6 +937,13 @@ nmi_espfix_stack:
10091 + FIXUP_ESPFIX_STACK # %eax == %esp
10092 + xorl %edx,%edx # zero error code
10093 + call do_nmi
10094 ++
10095 ++#ifdef CONFIG_PAX_KERNEXEC
10096 ++ GET_CR0_INTO_EDX
10097 ++ xorl %esi, %edx
10098 ++ SET_CR0_FROM_EDX
10099 ++#endif
10100 ++
10101 + RESTORE_REGS
10102 + lss 12+4(%esp), %esp # back to espfix stack
10103 + CFI_ADJUST_CFA_OFFSET -24
10104 +@@ -1107,7 +1188,6 @@ ENDPROC(xen_failsafe_callback)
10105 +
10106 + #endif /* CONFIG_XEN */
10107 +
10108 +-.section .rodata,"a"
10109 + #include "syscall_table_32.S"
10110 +
10111 + syscall_table_size=(.-sys_call_table)
10112 +diff -urNp a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
10113 +--- a/arch/x86/kernel/entry_64.S 2008-08-20 11:16:13.000000000 -0700
10114 ++++ b/arch/x86/kernel/entry_64.S 2008-08-20 18:36:57.000000000 -0700
10115 +@@ -769,17 +769,18 @@ END(spurious_interrupt)
10116 + xorl %ebx,%ebx
10117 + 1:
10118 + .if \ist
10119 +- movq %gs:pda_data_offset, %rbp
10120 ++ imul $TSS_size, %gs:pda_cpunumber, %ebp
10121 ++ lea init_tss(%rbp), %rbp
10122 + .endif
10123 + movq %rsp,%rdi
10124 + movq ORIG_RAX(%rsp),%rsi
10125 + movq $-1,ORIG_RAX(%rsp)
10126 + .if \ist
10127 +- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
10128 ++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
10129 + .endif
10130 + call \sym
10131 + .if \ist
10132 +- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
10133 ++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
10134 + .endif
10135 + DISABLE_INTERRUPTS(CLBR_NONE)
10136 + .if \irqtrace
10137 +diff -urNp a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
10138 +--- a/arch/x86/kernel/head64.c 2008-08-20 11:16:13.000000000 -0700
10139 ++++ b/arch/x86/kernel/head64.c 2008-08-20 18:36:57.000000000 -0700
10140 +@@ -88,6 +88,11 @@ void __init x86_64_start_kernel(char * r
10141 + /* Make NULL pointers segfault */
10142 + zap_identity_mappings();
10143 +
10144 ++ for (i = 0; i < NR_CPUS; i++)
10145 ++ cpu_pda(i) = &boot_cpu_pda[i];
10146 ++
10147 ++ pda_init(0);
10148 ++
10149 + /* Cleanup the over mapped high alias */
10150 + cleanup_highmap();
10151 +
10152 +@@ -102,10 +107,6 @@ void __init x86_64_start_kernel(char * r
10153 +
10154 + early_printk("Kernel alive\n");
10155 +
10156 +- for (i = 0; i < NR_CPUS; i++)
10157 +- cpu_pda(i) = &boot_cpu_pda[i];
10158 +-
10159 +- pda_init(0);
10160 + copy_bootdata(__va(real_mode_data));
10161 +
10162 + reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
10163 +diff -urNp a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
10164 +--- a/arch/x86/kernel/head_32.S 2008-08-20 11:16:13.000000000 -0700
10165 ++++ b/arch/x86/kernel/head_32.S 2008-08-20 18:36:57.000000000 -0700
10166 +@@ -20,6 +20,7 @@
10167 + #include <asm/asm-offsets.h>
10168 + #include <asm/setup.h>
10169 + #include <asm/processor-flags.h>
10170 ++#include <asm/msr-index.h>
10171 +
10172 + /* Physical address */
10173 + #define pa(X) ((X) - __PAGE_OFFSET)
10174 +@@ -65,17 +66,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
10175 + LOW_PAGES = LOW_PAGES + 0x1000000
10176 + #endif
10177 +
10178 +-#if PTRS_PER_PMD > 1
10179 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
10180 +-#else
10181 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
10182 +-#endif
10183 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
10184 + BOOTBITMAP_SIZE = LOW_PAGES / 8
10185 + ALLOCATOR_SLOP = 4
10186 +
10187 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
10188 +
10189 + /*
10190 ++ * Real beginning of normal "text" segment
10191 ++ */
10192 ++ENTRY(stext)
10193 ++ENTRY(_stext)
10194 ++
10195 ++.section .text.startup,"ax",@progbits
10196 ++ ljmp $(__BOOT_CS),$phys_startup_32
10197 ++
10198 ++/*
10199 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
10200 + * %esi points to the real-mode code as a 32-bit pointer.
10201 + * CS and DS must be 4 GB flat segments, but we don't depend on
10202 +@@ -83,6 +89,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
10203 + * can.
10204 + */
10205 + .section .text.head,"ax",@progbits
10206 ++
10207 ++#ifdef CONFIG_PAX_KERNEXEC
10208 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
10209 ++.fill 4096,1,0xcc
10210 ++#endif
10211 ++
10212 + ENTRY(startup_32)
10213 + /* test KEEP_SEGMENTS flag to see if the bootloader is asking
10214 + us to not reload segments */
10215 +@@ -100,6 +112,43 @@ ENTRY(startup_32)
10216 + movl %eax,%gs
10217 + 2:
10218 +
10219 ++ movl $__per_cpu_start,%eax
10220 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
10221 ++ rorl $16,%eax
10222 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
10223 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
10224 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
10225 ++ subl $__per_cpu_start,%eax
10226 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
10227 ++
10228 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
10229 ++ /* check for VMware */
10230 ++ movl $0x564d5868,%eax
10231 ++ xorl %ebx,%ebx
10232 ++ movl $0xa,%ecx
10233 ++ movl $0x5658,%edx
10234 ++ in (%dx),%eax
10235 ++ cmpl $0x564d5868,%ebx
10236 ++ jz 1f
10237 ++
10238 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
10239 ++ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
10240 ++1:
10241 ++#endif
10242 ++
10243 ++#ifdef CONFIG_PAX_KERNEXEC
10244 ++ movl $KERNEL_TEXT_OFFSET,%eax
10245 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
10246 ++ rorl $16,%eax
10247 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
10248 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
10249 ++
10250 ++ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
10251 ++ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
10252 ++ rorl $16,%eax
10253 ++ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
10254 ++#endif
10255 ++
10256 + /*
10257 + * Clear BSS first so that there are no surprises...
10258 + */
10259 +@@ -143,9 +192,7 @@ ENTRY(startup_32)
10260 + cmpl $num_subarch_entries, %eax
10261 + jae bad_subarch
10262 +
10263 +- movl pa(subarch_entries)(,%eax,4), %eax
10264 +- subl $__PAGE_OFFSET, %eax
10265 +- jmp *%eax
10266 ++ jmp *pa(subarch_entries)(,%eax,4)
10267 +
10268 + bad_subarch:
10269 + WEAK(lguest_entry)
10270 +@@ -157,9 +204,9 @@ WEAK(xen_entry)
10271 + __INITDATA
10272 +
10273 + subarch_entries:
10274 +- .long default_entry /* normal x86/PC */
10275 +- .long lguest_entry /* lguest hypervisor */
10276 +- .long xen_entry /* Xen hypervisor */
10277 ++ .long pa(default_entry) /* normal x86/PC */
10278 ++ .long pa(lguest_entry) /* lguest hypervisor */
10279 ++ .long pa(xen_entry) /* Xen hypervisor */
10280 + num_subarch_entries = (. - subarch_entries) / 4
10281 + .previous
10282 + #endif /* CONFIG_PARAVIRT */
10283 +@@ -173,7 +220,7 @@ num_subarch_entries = (. - subarch_entri
10284 + *
10285 + * Note that the stack is not yet set up!
10286 + */
10287 +-#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
10288 ++#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
10289 + #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
10290 + #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
10291 +
10292 +@@ -222,8 +269,7 @@ default_entry:
10293 + movl %edi,pa(init_pg_tables_end)
10294 +
10295 + /* Do early initialization of the fixmap area */
10296 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
10297 +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
10298 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
10299 + #else /* Not PAE */
10300 +
10301 + page_pde_offset = (__PAGE_OFFSET >> 20);
10302 +@@ -252,8 +298,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
10303 + movl %edi,pa(init_pg_tables_end)
10304 +
10305 + /* Do early initialization of the fixmap area */
10306 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
10307 +- movl %eax,pa(swapper_pg_dir+0xffc)
10308 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
10309 + #endif
10310 + jmp 3f
10311 + /*
10312 +@@ -317,13 +362,16 @@ ENTRY(startup_32_smp)
10313 + jnc 6f
10314 +
10315 + /* Setup EFER (Extended Feature Enable Register) */
10316 +- movl $0xc0000080, %ecx
10317 ++ movl $MSR_EFER, %ecx
10318 + rdmsr
10319 +
10320 + btsl $11, %eax
10321 + /* Make changes effective */
10322 + wrmsr
10323 +
10324 ++ btsl $63-32,pa(__supported_pte_mask+4)
10325 ++ movl $1,pa(nx_enabled)
10326 ++
10327 + 6:
10328 +
10329 + /*
10330 +@@ -349,9 +397,7 @@ ENTRY(startup_32_smp)
10331 +
10332 + #ifdef CONFIG_SMP
10333 + cmpb $0, ready
10334 +- jz 1f /* Initial CPU cleans BSS */
10335 +- jmp checkCPUtype
10336 +-1:
10337 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
10338 + #endif /* CONFIG_SMP */
10339 +
10340 + /*
10341 +@@ -428,12 +474,12 @@ is386: movl $2,%ecx # set MP
10342 + ljmp $(__KERNEL_CS),$1f
10343 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
10344 + movl %eax,%ss # after changing gdt.
10345 +- movl %eax,%fs # gets reset once there's real percpu
10346 +-
10347 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
10348 + movl %eax,%ds
10349 + movl %eax,%es
10350 +
10351 ++ movl $(__KERNEL_PERCPU), %eax
10352 ++ movl %eax,%fs # set this cpu's percpu
10353 ++
10354 + xorl %eax,%eax # Clear GS and LDT
10355 + movl %eax,%gs
10356 + lldt %ax
10357 +@@ -444,11 +490,7 @@ is386: movl $2,%ecx # set MP
10358 + movb ready, %cl
10359 + movb $1, ready
10360 + cmpb $0,%cl # the first CPU calls start_kernel
10361 +- je 1f
10362 +- movl $(__KERNEL_PERCPU), %eax
10363 +- movl %eax,%fs # set this cpu's percpu
10364 +- jmp initialize_secondary # all other CPUs call initialize_secondary
10365 +-1:
10366 ++ jne initialize_secondary # all other CPUs call initialize_secondary
10367 + #endif /* CONFIG_SMP */
10368 + jmp start_kernel
10369 +
10370 +@@ -534,15 +576,15 @@ early_page_fault:
10371 + jmp early_fault
10372 +
10373 + early_fault:
10374 +- cld
10375 + #ifdef CONFIG_PRINTK
10376 ++ cmpl $2,%ss:early_recursion_flag
10377 ++ je hlt_loop
10378 ++ incl %ss:early_recursion_flag
10379 ++ cld
10380 + pusha
10381 + movl $(__KERNEL_DS),%eax
10382 + movl %eax,%ds
10383 + movl %eax,%es
10384 +- cmpl $2,early_recursion_flag
10385 +- je hlt_loop
10386 +- incl early_recursion_flag
10387 + movl %cr2,%eax
10388 + pushl %eax
10389 + pushl %edx /* trapno */
10390 +@@ -552,8 +594,8 @@ early_fault:
10391 + #else
10392 + call printk
10393 + #endif
10394 +-#endif
10395 + call dump_stack
10396 ++#endif
10397 + hlt_loop:
10398 + hlt
10399 + jmp hlt_loop
10400 +@@ -561,8 +603,11 @@ hlt_loop:
10401 + /* This is the default interrupt "handler" :-) */
10402 + ALIGN
10403 + ignore_int:
10404 +- cld
10405 + #ifdef CONFIG_PRINTK
10406 ++ cmpl $2,%ss:early_recursion_flag
10407 ++ je hlt_loop
10408 ++ incl %ss:early_recursion_flag
10409 ++ cld
10410 + pushl %eax
10411 + pushl %ecx
10412 + pushl %edx
10413 +@@ -571,9 +616,6 @@ ignore_int:
10414 + movl $(__KERNEL_DS),%eax
10415 + movl %eax,%ds
10416 + movl %eax,%es
10417 +- cmpl $2,early_recursion_flag
10418 +- je hlt_loop
10419 +- incl early_recursion_flag
10420 + pushl 16(%esp)
10421 + pushl 24(%esp)
10422 + pushl 32(%esp)
10423 +@@ -593,36 +635,41 @@ ignore_int:
10424 + #endif
10425 + iret
10426 +
10427 +-.section .text
10428 +-/*
10429 +- * Real beginning of normal "text" segment
10430 +- */
10431 +-ENTRY(stext)
10432 +-ENTRY(_stext)
10433 +-
10434 + /*
10435 + * BSS section
10436 + */
10437 +-.section ".bss.page_aligned","wa"
10438 +- .align PAGE_SIZE_asm
10439 + #ifdef CONFIG_X86_PAE
10440 ++.section .swapper_pg_pmd,"a",@progbits
10441 + swapper_pg_pmd:
10442 + .fill 1024*KPMDS,4,0
10443 + #else
10444 ++.section .swapper_pg_dir,"a",@progbits
10445 + ENTRY(swapper_pg_dir)
10446 + .fill 1024,4,0
10447 + #endif
10448 + swapper_pg_fixmap:
10449 + .fill 1024,4,0
10450 ++
10451 ++.section .empty_zero_page,"a",@progbits
10452 + ENTRY(empty_zero_page)
10453 + .fill 4096,1,0
10454 ++
10455 ++/*
10456 ++ * The IDT has to be page-aligned to simplify the Pentium
10457 ++ * F0 0F bug workaround.. We have a special link segment
10458 ++ * for this.
10459 ++ */
10460 ++.section .idt,"a",@progbits
10461 ++ENTRY(idt_table)
10462 ++ .fill 256,8,0
10463 ++
10464 + /*
10465 + * This starts the data section.
10466 + */
10467 ++.data
10468 ++
10469 + #ifdef CONFIG_X86_PAE
10470 +-.section ".data.page_aligned","wa"
10471 +- /* Page-aligned for the benefit of paravirt? */
10472 +- .align PAGE_SIZE_asm
10473 ++.section .swapper_pg_dir,"a",@progbits
10474 + ENTRY(swapper_pg_dir)
10475 + .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
10476 + # if KPMDS == 3
10477 +@@ -645,11 +692,12 @@ ENTRY(swapper_pg_dir)
10478 +
10479 + .data
10480 + ENTRY(stack_start)
10481 +- .long init_thread_union+THREAD_SIZE
10482 ++ .long init_thread_union+THREAD_SIZE-8
10483 + .long __BOOT_DS
10484 +
10485 + ready: .byte 0
10486 +
10487 ++.section .rodata,"a",@progbits
10488 + early_recursion_flag:
10489 + .long 0
10490 +
10491 +@@ -695,7 +743,7 @@ idt_descr:
10492 + .word 0 # 32 bit align gdt_desc.address
10493 + ENTRY(early_gdt_descr)
10494 + .word GDT_ENTRIES*8-1
10495 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
10496 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
10497 +
10498 + /*
10499 + * The boot_gdt must mirror the equivalent in setup.S and is
10500 +@@ -704,5 +752,61 @@ ENTRY(early_gdt_descr)
10501 + .align L1_CACHE_BYTES
10502 + ENTRY(boot_gdt)
10503 + .fill GDT_ENTRY_BOOT_CS,8,0
10504 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
10505 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
10506 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
10507 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
10508 ++
10509 ++ .align PAGE_SIZE_asm
10510 ++ENTRY(cpu_gdt_table)
10511 ++ .quad 0x0000000000000000 /* NULL descriptor */
10512 ++ .quad 0x0000000000000000 /* 0x0b reserved */
10513 ++ .quad 0x0000000000000000 /* 0x13 reserved */
10514 ++ .quad 0x0000000000000000 /* 0x1b reserved */
10515 ++ .quad 0x0000000000000000 /* 0x20 unused */
10516 ++ .quad 0x0000000000000000 /* 0x28 unused */
10517 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
10518 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
10519 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
10520 ++ .quad 0x0000000000000000 /* 0x4b reserved */
10521 ++ .quad 0x0000000000000000 /* 0x53 reserved */
10522 ++ .quad 0x0000000000000000 /* 0x5b reserved */
10523 ++
10524 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
10525 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
10526 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
10527 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
10528 ++
10529 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
10530 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
10531 ++
10532 ++ /*
10533 ++ * Segments used for calling PnP BIOS have byte granularity.
10534 ++ * The code segments and data segments have fixed 64k limits,
10535 ++ * the transfer segment sizes are set at run time.
10536 ++ */
10537 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
10538 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
10539 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
10540 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
10541 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
10542 ++
10543 ++ /*
10544 ++ * The APM segments have byte granularity and their bases
10545 ++ * are set at run time. All have 64k limits.
10546 ++ */
10547 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
10548 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
10549 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
10550 ++
10551 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
10552 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
10553 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
10554 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
10555 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
10556 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
10557 ++
10558 ++ /* Be sure this is zeroed to avoid false validations in Xen */
10559 ++ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
10560 ++
10561 ++#ifdef CONFIG_SMP
10562 ++ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
10563 ++#endif
10564 +diff -urNp a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
10565 +--- a/arch/x86/kernel/head_64.S 2008-08-20 11:16:13.000000000 -0700
10566 ++++ b/arch/x86/kernel/head_64.S 2008-08-20 18:36:57.000000000 -0700
10567 +@@ -185,6 +185,10 @@ ENTRY(secondary_startup_64)
10568 + btl $20,%edi /* No Execute supported? */
10569 + jnc 1f
10570 + btsl $_EFER_NX, %eax
10571 ++ movq $(init_level4_pgt), %rdi
10572 ++ addq phys_base(%rip), %rdi
10573 ++ btsq $_PAGE_BIT_NX, 8*258(%rdi)
10574 ++ btsq $_PAGE_BIT_NX, 8*388(%rdi)
10575 + 1: wrmsr /* Make changes effective */
10576 +
10577 + /* Setup cr0 */
10578 +@@ -254,6 +258,9 @@ ENTRY(secondary_startup_64)
10579 + pushq %rax # target address in negative space
10580 + lretq
10581 +
10582 ++bad_address:
10583 ++ jmp bad_address
10584 ++
10585 + /* SMP bootup changes these two */
10586 + __REFDATA
10587 + .align 8
10588 +@@ -264,9 +271,7 @@ ENTRY(secondary_startup_64)
10589 + ENTRY(init_rsp)
10590 + .quad init_thread_union+THREAD_SIZE-8
10591 +
10592 +-bad_address:
10593 +- jmp bad_address
10594 +-
10595 ++ __INIT
10596 + #ifdef CONFIG_EARLY_PRINTK
10597 + .macro early_idt_tramp first, last
10598 + .ifgt \last-\first
10599 +@@ -319,15 +324,18 @@ ENTRY(early_idt_handler)
10600 + jmp 1b
10601 +
10602 + #ifdef CONFIG_EARLY_PRINTK
10603 ++ __INITDATA
10604 + early_recursion_flag:
10605 + .long 0
10606 +
10607 ++ .section .rodata,"a",@progbits
10608 + early_idt_msg:
10609 + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
10610 + early_idt_ripmsg:
10611 + .asciz "RIP %s\n"
10612 + #endif /* CONFIG_EARLY_PRINTK */
10613 +
10614 ++ .section .rodata,"a",@progbits
10615 + .balign PAGE_SIZE
10616 +
10617 + #define NEXT_PAGE(name) \
10618 +@@ -352,7 +360,9 @@ NEXT_PAGE(init_level4_pgt)
10619 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10620 + .fill 257,8,0
10621 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10622 +- .fill 252,8,0
10623 ++ .fill 129,8,0
10624 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
10625 ++ .fill 122,8,0
10626 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
10627 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
10628 +
10629 +@@ -360,6 +370,9 @@ NEXT_PAGE(level3_ident_pgt)
10630 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10631 + .fill 511,8,0
10632 +
10633 ++NEXT_PAGE(level3_vmalloc_pgt)
10634 ++ .fill 512,8,0
10635 ++
10636 + NEXT_PAGE(level3_kernel_pgt)
10637 + .fill 510,8,0
10638 + /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
10639 +@@ -401,19 +414,12 @@ NEXT_PAGE(level2_spare_pgt)
10640 + #undef PMDS
10641 + #undef NEXT_PAGE
10642 +
10643 +- .data
10644 + .align 16
10645 + .globl cpu_gdt_descr
10646 + cpu_gdt_descr:
10647 +- .word gdt_end-cpu_gdt_table-1
10648 ++ .word GDT_SIZE-1
10649 + gdt:
10650 + .quad cpu_gdt_table
10651 +-#ifdef CONFIG_SMP
10652 +- .rept NR_CPUS-1
10653 +- .word 0
10654 +- .quad 0
10655 +- .endr
10656 +-#endif
10657 +
10658 + ENTRY(phys_base)
10659 + /* This must match the first entry in level2_kernel_pgt */
10660 +@@ -423,8 +429,7 @@ ENTRY(phys_base)
10661 + * IRET will check the segment types kkeil 2000/10/28
10662 + * Also sysret mandates a special GDT layout
10663 + */
10664 +-
10665 +- .section .data.page_aligned, "aw"
10666 ++
10667 + .align PAGE_SIZE
10668 +
10669 + /* The TLS descriptors are currently at a different place compared to i386.
10670 +@@ -443,15 +448,15 @@ ENTRY(cpu_gdt_table)
10671 + .quad 0,0 /* LDT */
10672 + .quad 0,0,0 /* three TLS descriptors */
10673 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
10674 +-gdt_end:
10675 + /* asm/segment.h:GDT_ENTRIES must match this */
10676 + /* This should be a multiple of the cache line size */
10677 +- /* GDTs of other CPUs are now dynamically allocated */
10678 +
10679 + /* zero the remaining page */
10680 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
10681 ++#ifdef CONFIG_SMP
10682 ++ .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
10683 ++#endif
10684 +
10685 +- .section .bss, "aw", @nobits
10686 + .align L1_CACHE_BYTES
10687 + ENTRY(idt_table)
10688 + .skip 256 * 16
10689 +diff -urNp a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
10690 +--- a/arch/x86/kernel/hpet.c 2008-08-20 11:16:13.000000000 -0700
10691 ++++ b/arch/x86/kernel/hpet.c 2008-08-20 18:36:57.000000000 -0700
10692 +@@ -138,7 +138,7 @@ static void hpet_reserve_platform_timers
10693 + hd.hd_irq[1] = HPET_LEGACY_RTC;
10694 +
10695 + for (i = 2; i < nrtimers; timer++, i++)
10696 +- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
10697 ++ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
10698 + Tn_INT_ROUTE_CNF_SHIFT;
10699 +
10700 + hpet_alloc(&hd);
10701 +diff -urNp a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
10702 +--- a/arch/x86/kernel/i386_ksyms_32.c 2008-08-20 11:16:13.000000000 -0700
10703 ++++ b/arch/x86/kernel/i386_ksyms_32.c 2008-08-20 18:36:57.000000000 -0700
10704 +@@ -4,12 +4,16 @@
10705 + #include <asm/desc.h>
10706 + #include <asm/pgtable.h>
10707 +
10708 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
10709 ++
10710 + EXPORT_SYMBOL(__down_failed);
10711 + EXPORT_SYMBOL(__down_failed_interruptible);
10712 + EXPORT_SYMBOL(__down_failed_trylock);
10713 + EXPORT_SYMBOL(__up_wakeup);
10714 + /* Networking helper routines. */
10715 + EXPORT_SYMBOL(csum_partial_copy_generic);
10716 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
10717 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
10718 +
10719 + EXPORT_SYMBOL(__get_user_1);
10720 + EXPORT_SYMBOL(__get_user_2);
10721 +@@ -24,3 +28,7 @@ EXPORT_SYMBOL(strstr);
10722 +
10723 + EXPORT_SYMBOL(csum_partial);
10724 + EXPORT_SYMBOL(empty_zero_page);
10725 ++
10726 ++#ifdef CONFIG_PAX_KERNEXEC
10727 ++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
10728 ++#endif
10729 +diff -urNp a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c
10730 +--- a/arch/x86/kernel/init_task.c 2008-08-20 11:16:13.000000000 -0700
10731 ++++ b/arch/x86/kernel/init_task.c 2008-08-20 18:36:57.000000000 -0700
10732 +@@ -43,5 +43,5 @@ EXPORT_SYMBOL(init_task);
10733 + * section. Since TSS's are completely CPU-local, we want them
10734 + * on exact cacheline boundaries, to eliminate cacheline ping-pong.
10735 + */
10736 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
10737 +-
10738 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
10739 ++EXPORT_SYMBOL(init_tss);
10740 +diff -urNp a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
10741 +--- a/arch/x86/kernel/ioport.c 2008-08-20 11:16:13.000000000 -0700
10742 ++++ b/arch/x86/kernel/ioport.c 2008-08-20 18:36:57.000000000 -0700
10743 +@@ -14,6 +14,7 @@
10744 + #include <linux/slab.h>
10745 + #include <linux/thread_info.h>
10746 + #include <linux/syscalls.h>
10747 ++#include <linux/grsecurity.h>
10748 +
10749 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
10750 + static void set_bitmap(unsigned long *bitmap, unsigned int base,
10751 +@@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
10752 +
10753 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
10754 + return -EINVAL;
10755 ++#ifdef CONFIG_GRKERNSEC_IO
10756 ++ if (turn_on) {
10757 ++ gr_handle_ioperm();
10758 ++ return -EPERM;
10759 ++ }
10760 ++#endif
10761 + if (turn_on && !capable(CAP_SYS_RAWIO))
10762 + return -EPERM;
10763 +
10764 +@@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
10765 + * because the ->io_bitmap_max value must match the bitmap
10766 + * contents:
10767 + */
10768 +- tss = &per_cpu(init_tss, get_cpu());
10769 ++ tss = init_tss + get_cpu();
10770 +
10771 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
10772 +
10773 +@@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
10774 + return -EINVAL;
10775 + /* Trying to gain more privileges? */
10776 + if (level > old) {
10777 ++#ifdef CONFIG_GRKERNSEC_IO
10778 ++ gr_handle_iopl();
10779 ++ return -EPERM;
10780 ++#else
10781 + if (!capable(CAP_SYS_RAWIO))
10782 + return -EPERM;
10783 ++#endif
10784 + }
10785 + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
10786 +
10787 +diff -urNp a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
10788 +--- a/arch/x86/kernel/irq_32.c 2008-08-20 11:16:13.000000000 -0700
10789 ++++ b/arch/x86/kernel/irq_32.c 2008-08-20 18:36:57.000000000 -0700
10790 +@@ -115,7 +115,7 @@ unsigned int do_IRQ(struct pt_regs *regs
10791 + int arg1, arg2, bx;
10792 +
10793 + /* build the stack frame on the IRQ stack */
10794 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
10795 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
10796 + irqctx->tinfo.task = curctx->tinfo.task;
10797 + irqctx->tinfo.previous_esp = current_stack_pointer;
10798 +
10799 +@@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
10800 + irqctx->tinfo.previous_esp = current_stack_pointer;
10801 +
10802 + /* build the stack frame on the softirq stack */
10803 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
10804 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
10805 +
10806 + asm volatile(
10807 + " xchgl %%ebx,%%esp \n"
10808 +diff -urNp a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
10809 +--- a/arch/x86/kernel/kprobes.c 2008-08-20 11:16:13.000000000 -0700
10810 ++++ b/arch/x86/kernel/kprobes.c 2008-08-20 18:36:57.000000000 -0700
10811 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
10812 + char op;
10813 + s32 raddr;
10814 + } __attribute__((packed)) * jop;
10815 +- jop = (struct __arch_jmp_op *)from;
10816 ++
10817 ++#ifdef CONFIG_PAX_KERNEXEC
10818 ++ unsigned long cr0;
10819 ++#endif
10820 ++
10821 ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
10822 ++
10823 ++#ifdef CONFIG_PAX_KERNEXEC
10824 ++ pax_open_kernel(cr0);
10825 ++#endif
10826 ++
10827 + jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
10828 + jop->op = RELATIVEJUMP_INSTRUCTION;
10829 ++
10830 ++#ifdef CONFIG_PAX_KERNEXEC
10831 ++ pax_close_kernel(cr0);
10832 ++#endif
10833 ++
10834 + }
10835 +
10836 + /*
10837 +@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
10838 +
10839 + static void __kprobes arch_copy_kprobe(struct kprobe *p)
10840 + {
10841 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
10842 ++
10843 ++#ifdef CONFIG_PAX_KERNEXEC
10844 ++ unsigned long cr0;
10845 ++#endif
10846 ++
10847 ++#ifdef CONFIG_PAX_KERNEXEC
10848 ++ pax_open_kernel(cr0);
10849 ++#endif
10850 ++
10851 ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
10852 ++
10853 ++#ifdef CONFIG_PAX_KERNEXEC
10854 ++ pax_close_kernel(cr0);
10855 ++#endif
10856 +
10857 + fix_riprel(p);
10858 +
10859 +- if (can_boost(p->addr))
10860 ++ if (can_boost(ktla_ktva(p->addr)))
10861 + p->ainsn.boostable = 0;
10862 + else
10863 + p->ainsn.boostable = -1;
10864 +
10865 +- p->opcode = *p->addr;
10866 ++ p->opcode = *(ktla_ktva(p->addr));
10867 + }
10868 +
10869 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
10870 +@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
10871 + if (p->opcode == BREAKPOINT_INSTRUCTION)
10872 + regs->ip = (unsigned long)p->addr;
10873 + else
10874 +- regs->ip = (unsigned long)p->ainsn.insn;
10875 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
10876 + }
10877 +
10878 + /* Called with kretprobe_lock held */
10879 +@@ -450,7 +478,7 @@ static void __kprobes setup_singlestep(s
10880 + if (p->ainsn.boostable == 1 && !p->post_handler) {
10881 + /* Boost up -- we can execute copied instructions directly */
10882 + reset_current_kprobe();
10883 +- regs->ip = (unsigned long)p->ainsn.insn;
10884 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
10885 + preempt_enable_no_resched();
10886 + return;
10887 + }
10888 +@@ -772,7 +800,7 @@ static void __kprobes resume_execution(s
10889 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
10890 + {
10891 + unsigned long *tos = stack_addr(regs);
10892 +- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
10893 ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
10894 + unsigned long orig_ip = (unsigned long)p->addr;
10895 + kprobe_opcode_t *insn = p->ainsn.insn;
10896 +
10897 +@@ -956,7 +984,7 @@ int __kprobes kprobe_exceptions_notify(s
10898 + struct die_args *args = data;
10899 + int ret = NOTIFY_DONE;
10900 +
10901 +- if (args->regs && user_mode_vm(args->regs))
10902 ++ if (args->regs && user_mode(args->regs))
10903 + return ret;
10904 +
10905 + switch (val) {
10906 +diff -urNp a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
10907 +--- a/arch/x86/kernel/ldt.c 2008-08-20 11:16:13.000000000 -0700
10908 ++++ b/arch/x86/kernel/ldt.c 2008-08-20 18:36:57.000000000 -0700
10909 +@@ -65,7 +65,7 @@ static int alloc_ldt(mm_context_t *pc, i
10910 + cpumask_t mask;
10911 +
10912 + preempt_disable();
10913 +- load_LDT(pc);
10914 ++ load_LDT_nolock(pc);
10915 + mask = cpumask_of_cpu(smp_processor_id());
10916 + if (!cpus_equal(current->mm->cpu_vm_mask, mask))
10917 + smp_call_function(flush_ldt, NULL, 1, 1);
10918 +@@ -110,6 +110,24 @@ int init_new_context(struct task_struct
10919 + retval = copy_ldt(&mm->context, &old_mm->context);
10920 + mutex_unlock(&old_mm->context.lock);
10921 + }
10922 ++
10923 ++ if (tsk == current) {
10924 ++ mm->context.vdso = ~0UL;
10925 ++
10926 ++#ifdef CONFIG_X86_32
10927 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10928 ++ mm->context.user_cs_base = 0UL;
10929 ++ mm->context.user_cs_limit = ~0UL;
10930 ++
10931 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
10932 ++ cpus_clear(mm->context.cpu_user_cs_mask);
10933 ++#endif
10934 ++
10935 ++#endif
10936 ++#endif
10937 ++
10938 ++ }
10939 ++
10940 + return retval;
10941 + }
10942 +
10943 +@@ -223,6 +241,13 @@ static int write_ldt(void __user *ptr, u
10944 + }
10945 + }
10946 +
10947 ++#ifdef CONFIG_PAX_SEGMEXEC
10948 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
10949 ++ error = -EINVAL;
10950 ++ goto out_unlock;
10951 ++ }
10952 ++#endif
10953 ++
10954 + fill_ldt(&ldt, &ldt_info);
10955 + if (oldmode)
10956 + ldt.avl = 0;
10957 +diff -urNp a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
10958 +--- a/arch/x86/kernel/machine_kexec_32.c 2008-08-20 11:16:13.000000000 -0700
10959 ++++ b/arch/x86/kernel/machine_kexec_32.c 2008-08-20 18:36:57.000000000 -0700
10960 +@@ -30,7 +30,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
10961 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
10962 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
10963 +
10964 +-static void set_idt(void *newidt, __u16 limit)
10965 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
10966 + {
10967 + struct desc_ptr curidt;
10968 +
10969 +@@ -42,7 +42,7 @@ static void set_idt(void *newidt, __u16
10970 + };
10971 +
10972 +
10973 +-static void set_gdt(void *newgdt, __u16 limit)
10974 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
10975 + {
10976 + struct desc_ptr curgdt;
10977 +
10978 +@@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
10979 + local_irq_disable();
10980 +
10981 + control_page = page_address(image->control_code_page);
10982 +- memcpy(control_page, relocate_kernel, PAGE_SIZE);
10983 ++ memcpy(control_page, ktla_ktva(relocate_kernel), PAGE_SIZE);
10984 +
10985 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
10986 +- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
10987 ++ page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
10988 + page_list[PA_PGD] = __pa(kexec_pgd);
10989 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
10990 + #ifdef CONFIG_X86_PAE
10991 +diff -urNp a/arch/x86/kernel/module_32.c b/arch/x86/kernel/module_32.c
10992 +--- a/arch/x86/kernel/module_32.c 2008-08-20 11:16:13.000000000 -0700
10993 ++++ b/arch/x86/kernel/module_32.c 2008-08-20 18:36:57.000000000 -0700
10994 +@@ -23,6 +23,8 @@
10995 + #include <linux/kernel.h>
10996 + #include <linux/bug.h>
10997 +
10998 ++#include <asm/desc.h>
10999 ++
11000 + #if 0
11001 + #define DEBUGP printk
11002 + #else
11003 +@@ -33,9 +35,31 @@ void *module_alloc(unsigned long size)
11004 + {
11005 + if (size == 0)
11006 + return NULL;
11007 ++
11008 ++#ifdef CONFIG_PAX_KERNEXEC
11009 ++ return vmalloc(size);
11010 ++#else
11011 + return vmalloc_exec(size);
11012 ++#endif
11013 ++
11014 + }
11015 +
11016 ++#ifdef CONFIG_PAX_KERNEXEC
11017 ++void *module_alloc_exec(unsigned long size)
11018 ++{
11019 ++ struct vm_struct *area;
11020 ++
11021 ++ if (size == 0)
11022 ++ return NULL;
11023 ++
11024 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
11025 ++ if (area)
11026 ++ return area->addr;
11027 ++
11028 ++ return NULL;
11029 ++}
11030 ++EXPORT_SYMBOL(module_alloc_exec);
11031 ++#endif
11032 +
11033 + /* Free memory returned from module_alloc */
11034 + void module_free(struct module *mod, void *module_region)
11035 +@@ -45,6 +69,45 @@ void module_free(struct module *mod, voi
11036 + table entries. */
11037 + }
11038 +
11039 ++#ifdef CONFIG_PAX_KERNEXEC
11040 ++void module_free_exec(struct module *mod, void *module_region)
11041 ++{
11042 ++ struct vm_struct **p, *tmp;
11043 ++
11044 ++ if (!module_region)
11045 ++ return;
11046 ++
11047 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
11048 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
11049 ++ WARN_ON(1);
11050 ++ return;
11051 ++ }
11052 ++
11053 ++ write_lock(&vmlist_lock);
11054 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
11055 ++ if (tmp->addr == module_region)
11056 ++ break;
11057 ++
11058 ++ if (tmp) {
11059 ++ unsigned long cr0;
11060 ++
11061 ++ pax_open_kernel(cr0);
11062 ++ memset(tmp->addr, 0xCC, tmp->size);
11063 ++ pax_close_kernel(cr0);
11064 ++
11065 ++ *p = tmp->next;
11066 ++ kfree(tmp);
11067 ++ }
11068 ++ write_unlock(&vmlist_lock);
11069 ++
11070 ++ if (!tmp) {
11071 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
11072 ++ module_region);
11073 ++ WARN_ON(1);
11074 ++ }
11075 ++}
11076 ++#endif
11077 ++
11078 + /* We don't need anything special. */
11079 + int module_frob_arch_sections(Elf_Ehdr *hdr,
11080 + Elf_Shdr *sechdrs,
11081 +@@ -63,14 +126,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
11082 + unsigned int i;
11083 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
11084 + Elf32_Sym *sym;
11085 +- uint32_t *location;
11086 ++ uint32_t *plocation, location;
11087 ++
11088 ++#ifdef CONFIG_PAX_KERNEXEC
11089 ++ unsigned long cr0;
11090 ++#endif
11091 +
11092 + DEBUGP("Applying relocate section %u to %u\n", relsec,
11093 + sechdrs[relsec].sh_info);
11094 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
11095 + /* This is where to make the change */
11096 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
11097 +- + rel[i].r_offset;
11098 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
11099 ++ location = (uint32_t)plocation;
11100 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
11101 ++ plocation = ktla_ktva((void *)plocation);
11102 + /* This is the symbol it is referring to. Note that all
11103 + undefined symbols have been resolved. */
11104 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
11105 +@@ -78,12 +147,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
11106 +
11107 + switch (ELF32_R_TYPE(rel[i].r_info)) {
11108 + case R_386_32:
11109 ++
11110 ++#ifdef CONFIG_PAX_KERNEXEC
11111 ++ pax_open_kernel(cr0);
11112 ++#endif
11113 ++
11114 + /* We add the value into the location given */
11115 +- *location += sym->st_value;
11116 ++ *plocation += sym->st_value;
11117 ++
11118 ++#ifdef CONFIG_PAX_KERNEXEC
11119 ++ pax_close_kernel(cr0);
11120 ++#endif
11121 ++
11122 + break;
11123 + case R_386_PC32:
11124 ++
11125 ++#ifdef CONFIG_PAX_KERNEXEC
11126 ++ pax_open_kernel(cr0);
11127 ++#endif
11128 ++
11129 + /* Add the value, subtract its postition */
11130 +- *location += sym->st_value - (uint32_t)location;
11131 ++ *plocation += sym->st_value - location;
11132 ++
11133 ++#ifdef CONFIG_PAX_KERNEXEC
11134 ++ pax_close_kernel(cr0);
11135 ++#endif
11136 ++
11137 + break;
11138 + default:
11139 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
11140 +diff -urNp a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module_64.c
11141 +--- a/arch/x86/kernel/module_64.c 2008-08-20 11:16:13.000000000 -0700
11142 ++++ b/arch/x86/kernel/module_64.c 2008-08-20 18:36:57.000000000 -0700
11143 +@@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
11144 + table entries. */
11145 + }
11146 +
11147 +-void *module_alloc(unsigned long size)
11148 ++static void *__module_alloc(unsigned long size, pgprot_t prot)
11149 + {
11150 + struct vm_struct *area;
11151 +
11152 +@@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
11153 + if (!area)
11154 + return NULL;
11155 +
11156 +- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
11157 ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
11158 ++}
11159 ++
11160 ++#ifdef CONFIG_PAX_KERNEXEC
11161 ++void *module_alloc(unsigned long size)
11162 ++{
11163 ++ return __module_alloc(size, PAGE_KERNEL);
11164 ++}
11165 ++
11166 ++void module_free_exec(struct module *mod, void *module_region)
11167 ++{
11168 ++ module_free(mod, module_region);
11169 ++}
11170 ++
11171 ++void *module_alloc_exec(unsigned long size)
11172 ++{
11173 ++ return __module_alloc(size, PAGE_KERNEL_RX);
11174 + }
11175 ++#else
11176 ++void *module_alloc(unsigned long size)
11177 ++{
11178 ++ return __module_alloc(size, PAGE_KERNEL_EXEC);
11179 ++}
11180 ++#endif
11181 ++
11182 + #endif
11183 +
11184 + /* We don't need anything special. */
11185 +@@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
11186 + Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
11187 + Elf64_Sym *sym;
11188 + void *loc;
11189 +- u64 val;
11190 ++ u64 val;
11191 ++
11192 ++#ifdef CONFIG_PAX_KERNEXEC
11193 ++ unsigned long cr0;
11194 ++#endif
11195 +
11196 + DEBUGP("Applying relocate section %u to %u\n", relsec,
11197 + sechdrs[relsec].sh_info);
11198 +@@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
11199 + case R_X86_64_NONE:
11200 + break;
11201 + case R_X86_64_64:
11202 ++
11203 ++#ifdef CONFIG_PAX_KERNEXEC
11204 ++ pax_open_kernel(cr0);
11205 ++#endif
11206 ++
11207 + *(u64 *)loc = val;
11208 ++
11209 ++#ifdef CONFIG_PAX_KERNEXEC
11210 ++ pax_close_kernel(cr0);
11211 ++#endif
11212 ++
11213 + break;
11214 + case R_X86_64_32:
11215 ++
11216 ++#ifdef CONFIG_PAX_KERNEXEC
11217 ++ pax_open_kernel(cr0);
11218 ++#endif
11219 ++
11220 + *(u32 *)loc = val;
11221 ++
11222 ++#ifdef CONFIG_PAX_KERNEXEC
11223 ++ pax_close_kernel(cr0);
11224 ++#endif
11225 ++
11226 + if (val != *(u32 *)loc)
11227 + goto overflow;
11228 + break;
11229 + case R_X86_64_32S:
11230 ++
11231 ++#ifdef CONFIG_PAX_KERNEXEC
11232 ++ pax_open_kernel(cr0);
11233 ++#endif
11234 ++
11235 + *(s32 *)loc = val;
11236 ++
11237 ++#ifdef CONFIG_PAX_KERNEXEC
11238 ++ pax_close_kernel(cr0);
11239 ++#endif
11240 ++
11241 + if ((s64)val != *(s32 *)loc)
11242 + goto overflow;
11243 + break;
11244 + case R_X86_64_PC32:
11245 + val -= (u64)loc;
11246 ++
11247 ++#ifdef CONFIG_PAX_KERNEXEC
11248 ++ pax_open_kernel(cr0);
11249 ++#endif
11250 ++
11251 + *(u32 *)loc = val;
11252 ++
11253 ++#ifdef CONFIG_PAX_KERNEXEC
11254 ++ pax_close_kernel(cr0);
11255 ++#endif
11256 ++
11257 + #if 0
11258 + if ((s64)val != *(s32 *)loc)
11259 + goto overflow;
11260 +diff -urNp a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
11261 +--- a/arch/x86/kernel/paravirt.c 2008-08-20 11:16:13.000000000 -0700
11262 ++++ b/arch/x86/kernel/paravirt.c 2008-08-20 18:36:57.000000000 -0700
11263 +@@ -42,7 +42,7 @@ void _paravirt_nop(void)
11264 + {
11265 + }
11266 +
11267 +-static void __init default_banner(void)
11268 ++static void default_banner(void)
11269 + {
11270 + printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
11271 + pv_info.name);
11272 +@@ -159,7 +159,7 @@ unsigned paravirt_patch_insns(void *insn
11273 + if (insn_len > len || start == NULL)
11274 + insn_len = len;
11275 + else
11276 +- memcpy(insnbuf, start, insn_len);
11277 ++ memcpy(insnbuf, ktla_ktva(start), insn_len);
11278 +
11279 + return insn_len;
11280 + }
11281 +@@ -277,21 +277,21 @@ enum paravirt_lazy_mode paravirt_get_laz
11282 + return __get_cpu_var(paravirt_lazy_mode);
11283 + }
11284 +
11285 +-struct pv_info pv_info = {
11286 ++struct pv_info pv_info __read_only = {
11287 + .name = "bare hardware",
11288 + .paravirt_enabled = 0,
11289 + .kernel_rpl = 0,
11290 + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
11291 + };
11292 +
11293 +-struct pv_init_ops pv_init_ops = {
11294 ++struct pv_init_ops pv_init_ops __read_only = {
11295 + .patch = native_patch,
11296 + .banner = default_banner,
11297 + .arch_setup = paravirt_nop,
11298 + .memory_setup = machine_specific_memory_setup,
11299 + };
11300 +
11301 +-struct pv_time_ops pv_time_ops = {
11302 ++struct pv_time_ops pv_time_ops __read_only = {
11303 + .time_init = hpet_time_init,
11304 + .get_wallclock = native_get_wallclock,
11305 + .set_wallclock = native_set_wallclock,
11306 +@@ -299,7 +299,7 @@ struct pv_time_ops pv_time_ops = {
11307 + .get_cpu_khz = native_calculate_cpu_khz,
11308 + };
11309 +
11310 +-struct pv_irq_ops pv_irq_ops = {
11311 ++struct pv_irq_ops pv_irq_ops __read_only = {
11312 + .init_IRQ = native_init_IRQ,
11313 + .save_fl = native_save_fl,
11314 + .restore_fl = native_restore_fl,
11315 +@@ -309,7 +309,7 @@ struct pv_irq_ops pv_irq_ops = {
11316 + .halt = native_halt,
11317 + };
11318 +
11319 +-struct pv_cpu_ops pv_cpu_ops = {
11320 ++struct pv_cpu_ops pv_cpu_ops __read_only = {
11321 + .cpuid = native_cpuid,
11322 + .get_debugreg = native_get_debugreg,
11323 + .set_debugreg = native_set_debugreg,
11324 +@@ -355,7 +355,7 @@ struct pv_cpu_ops pv_cpu_ops = {
11325 + },
11326 + };
11327 +
11328 +-struct pv_apic_ops pv_apic_ops = {
11329 ++struct pv_apic_ops pv_apic_ops __read_only = {
11330 + #ifdef CONFIG_X86_LOCAL_APIC
11331 + .apic_write = native_apic_write,
11332 + .apic_write_atomic = native_apic_write_atomic,
11333 +@@ -366,7 +366,7 @@ struct pv_apic_ops pv_apic_ops = {
11334 + #endif
11335 + };
11336 +
11337 +-struct pv_mmu_ops pv_mmu_ops = {
11338 ++struct pv_mmu_ops pv_mmu_ops __read_only = {
11339 + #ifndef CONFIG_X86_64
11340 + .pagetable_setup_start = native_pagetable_setup_start,
11341 + .pagetable_setup_done = native_pagetable_setup_done,
11342 +diff -urNp a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
11343 +--- a/arch/x86/kernel/process_32.c 2008-08-20 11:16:13.000000000 -0700
11344 ++++ b/arch/x86/kernel/process_32.c 2008-08-20 18:36:57.000000000 -0700
11345 +@@ -66,8 +66,10 @@ EXPORT_SYMBOL(boot_option_idle_override)
11346 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
11347 + EXPORT_PER_CPU_SYMBOL(current_task);
11348 +
11349 ++#ifdef CONFIG_SMP
11350 + DEFINE_PER_CPU(int, cpu_number);
11351 + EXPORT_PER_CPU_SYMBOL(cpu_number);
11352 ++#endif
11353 +
11354 + /*
11355 + * Return saved PC of a blocked thread.
11356 +@@ -75,6 +77,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
11357 + unsigned long thread_saved_pc(struct task_struct *tsk)
11358 + {
11359 + return ((unsigned long *)tsk->thread.sp)[3];
11360 ++//XXX return tsk->thread.eip;
11361 + }
11362 +
11363 + /*
11364 +@@ -333,7 +336,7 @@ void __show_registers(struct pt_regs *re
11365 + unsigned long sp;
11366 + unsigned short ss, gs;
11367 +
11368 +- if (user_mode_vm(regs)) {
11369 ++ if (user_mode(regs)) {
11370 + sp = regs->sp;
11371 + ss = regs->ss & 0xffff;
11372 + savesegment(gs, gs);
11373 +@@ -411,8 +414,8 @@ int kernel_thread(int (*fn)(void *), voi
11374 + regs.bx = (unsigned long) fn;
11375 + regs.dx = (unsigned long) arg;
11376 +
11377 +- regs.ds = __USER_DS;
11378 +- regs.es = __USER_DS;
11379 ++ regs.ds = __KERNEL_DS;
11380 ++ regs.es = __KERNEL_DS;
11381 + regs.fs = __KERNEL_PERCPU;
11382 + regs.orig_ax = -1;
11383 + regs.ip = (unsigned long) kernel_thread_helper;
11384 +@@ -434,7 +437,7 @@ void exit_thread(void)
11385 + struct task_struct *tsk = current;
11386 + struct thread_struct *t = &tsk->thread;
11387 + int cpu = get_cpu();
11388 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11389 ++ struct tss_struct *tss = init_tss + cpu;
11390 +
11391 + kfree(t->io_bitmap_ptr);
11392 + t->io_bitmap_ptr = NULL;
11393 +@@ -455,6 +458,7 @@ void flush_thread(void)
11394 + {
11395 + struct task_struct *tsk = current;
11396 +
11397 ++ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
11398 + tsk->thread.debugreg0 = 0;
11399 + tsk->thread.debugreg1 = 0;
11400 + tsk->thread.debugreg2 = 0;
11401 +@@ -493,7 +497,7 @@ int copy_thread(int nr, unsigned long cl
11402 + struct task_struct *tsk;
11403 + int err;
11404 +
11405 +- childregs = task_pt_regs(p);
11406 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
11407 + *childregs = *regs;
11408 + childregs->ax = 0;
11409 + childregs->sp = sp;
11410 +@@ -522,6 +526,7 @@ int copy_thread(int nr, unsigned long cl
11411 + * Set a new TLS for the child thread?
11412 + */
11413 + if (clone_flags & CLONE_SETTLS)
11414 ++//XXX needs set_fs()?
11415 + err = do_set_thread_area(p, -1,
11416 + (struct user_desc __user *)childregs->si, 0);
11417 +
11418 +@@ -668,7 +673,7 @@ struct task_struct * __switch_to(struct
11419 + struct thread_struct *prev = &prev_p->thread,
11420 + *next = &next_p->thread;
11421 + int cpu = smp_processor_id();
11422 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11423 ++ struct tss_struct *tss = init_tss + cpu;
11424 +
11425 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
11426 +
11427 +@@ -696,6 +701,11 @@ struct task_struct * __switch_to(struct
11428 + */
11429 + savesegment(gs, prev->gs);
11430 +
11431 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
11432 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
11433 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
11434 ++#endif
11435 ++
11436 + /*
11437 + * Load the per-thread Thread-Local Storage descriptor.
11438 + */
11439 +@@ -834,15 +844,27 @@ unsigned long get_wchan(struct task_stru
11440 + return 0;
11441 + }
11442 +
11443 +-unsigned long arch_align_stack(unsigned long sp)
11444 ++#ifdef CONFIG_PAX_RANDKSTACK
11445 ++asmlinkage void pax_randomize_kstack(void)
11446 + {
11447 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
11448 +- sp -= get_random_int() % 8192;
11449 +- return sp & ~0xf;
11450 +-}
11451 ++ struct thread_struct *thread = &current->thread;
11452 ++ unsigned long time;
11453 +
11454 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
11455 +-{
11456 +- unsigned long range_end = mm->brk + 0x02000000;
11457 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
11458 ++ if (!randomize_va_space)
11459 ++ return;
11460 ++
11461 ++ rdtscl(time);
11462 ++
11463 ++ /* P4 seems to return a 0 LSB, ignore it */
11464 ++#ifdef CONFIG_MPENTIUM4
11465 ++ time &= 0x1EUL;
11466 ++ time <<= 2;
11467 ++#else
11468 ++ time &= 0xFUL;
11469 ++ time <<= 3;
11470 ++#endif
11471 ++
11472 ++ thread->sp0 ^= time;
11473 ++ load_sp0(init_tss + smp_processor_id(), thread);
11474 + }
11475 ++#endif
11476 +diff -urNp a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
11477 +--- a/arch/x86/kernel/process_64.c 2008-08-20 11:16:13.000000000 -0700
11478 ++++ b/arch/x86/kernel/process_64.c 2008-08-20 18:36:57.000000000 -0700
11479 +@@ -166,6 +166,8 @@ static inline void play_dead(void)
11480 + void cpu_idle(void)
11481 + {
11482 + current_thread_info()->status |= TS_POLLING;
11483 ++ current->stack_canary = pax_get_random_long();
11484 ++ write_pda(stack_canary, current->stack_canary);
11485 + /* endless idle loop with no priority at all */
11486 + while (1) {
11487 + tick_nohz_stop_sched_tick();
11488 +@@ -397,7 +399,7 @@ void exit_thread(void)
11489 + struct thread_struct *t = &me->thread;
11490 +
11491 + if (me->thread.io_bitmap_ptr) {
11492 +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
11493 ++ struct tss_struct *tss = init_tss + get_cpu();
11494 +
11495 + kfree(t->io_bitmap_ptr);
11496 + t->io_bitmap_ptr = NULL;
11497 +@@ -621,7 +623,7 @@ __switch_to(struct task_struct *prev_p,
11498 + struct thread_struct *prev = &prev_p->thread,
11499 + *next = &next_p->thread;
11500 + int cpu = smp_processor_id();
11501 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11502 ++ struct tss_struct *tss = init_tss + cpu;
11503 +
11504 + /* we're going to use this soon, after a few expensive things */
11505 + if (next_p->fpu_counter>5)
11506 +@@ -696,7 +698,6 @@ __switch_to(struct task_struct *prev_p,
11507 + write_pda(kernelstack,
11508 + (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
11509 + #ifdef CONFIG_CC_STACKPROTECTOR
11510 +- write_pda(stack_canary, next_p->stack_canary);
11511 + /*
11512 + * Build time only check to make sure the stack_canary is at
11513 + * offset 40 in the pda; this is a gcc ABI requirement
11514 +@@ -910,16 +911,3 @@ long sys_arch_prctl(int code, unsigned l
11515 + {
11516 + return do_arch_prctl(current, code, addr);
11517 + }
11518 +-
11519 +-unsigned long arch_align_stack(unsigned long sp)
11520 +-{
11521 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
11522 +- sp -= get_random_int() % 8192;
11523 +- return sp & ~0xf;
11524 +-}
11525 +-
11526 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
11527 +-{
11528 +- unsigned long range_end = mm->brk + 0x02000000;
11529 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
11530 +-}
11531 +diff -urNp a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
11532 +--- a/arch/x86/kernel/ptrace.c 2008-08-20 11:16:13.000000000 -0700
11533 ++++ b/arch/x86/kernel/ptrace.c 2008-08-20 18:36:57.000000000 -0700
11534 +@@ -1457,7 +1457,7 @@ void send_sigtrap(struct task_struct *ts
11535 + info.si_code = TRAP_BRKPT;
11536 +
11537 + /* User-mode ip? */
11538 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
11539 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
11540 +
11541 + /* Send us the fake SIGTRAP */
11542 + force_sig_info(SIGTRAP, &info, tsk);
11543 +diff -urNp a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
11544 +--- a/arch/x86/kernel/reboot.c 2008-08-20 11:16:13.000000000 -0700
11545 ++++ b/arch/x86/kernel/reboot.c 2008-08-20 18:36:57.000000000 -0700
11546 +@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
11547 + EXPORT_SYMBOL(pm_power_off);
11548 +
11549 + static long no_idt[3];
11550 +-static int reboot_mode;
11551 ++static unsigned short reboot_mode;
11552 + enum reboot_type reboot_type = BOOT_KBD;
11553 + int reboot_force;
11554 +
11555 +@@ -186,7 +186,7 @@ static struct dmi_system_id __initdata r
11556 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
11557 + },
11558 + },
11559 +- { }
11560 ++ { NULL, NULL, {{0, NULL}}, NULL}
11561 + };
11562 +
11563 + static int __init reboot_init(void)
11564 +@@ -202,15 +202,15 @@ core_initcall(reboot_init);
11565 + controller to pulse the CPU reset line, which is more thorough, but
11566 + doesn't work with at least one type of 486 motherboard. It is easy
11567 + to stop this code working; hence the copious comments. */
11568 +-static unsigned long long
11569 +-real_mode_gdt_entries [3] =
11570 ++static struct desc_struct
11571 ++real_mode_gdt_entries [3] __read_only =
11572 + {
11573 +- 0x0000000000000000ULL, /* Null descriptor */
11574 +- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
11575 +- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
11576 ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
11577 ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
11578 ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
11579 + };
11580 +
11581 +-static struct desc_ptr
11582 ++static const struct desc_ptr
11583 + real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
11584 + real_mode_idt = { 0x3ff, 0 };
11585 +
11586 +@@ -232,7 +232,7 @@ real_mode_idt = { 0x3ff, 0 };
11587 +
11588 + More could be done here to set up the registers as if a CPU reset had
11589 + occurred; hopefully real BIOSs don't assume much. */
11590 +-static unsigned char real_mode_switch [] =
11591 ++static const unsigned char real_mode_switch [] =
11592 + {
11593 + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
11594 + 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
11595 +@@ -246,7 +246,7 @@ static unsigned char real_mode_switch []
11596 + 0x24, 0x10, /* f: andb $0x10,al */
11597 + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
11598 + };
11599 +-static unsigned char jump_to_bios [] =
11600 ++static const unsigned char jump_to_bios [] =
11601 + {
11602 + 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
11603 + };
11604 +@@ -256,7 +256,7 @@ static unsigned char jump_to_bios [] =
11605 + * specified by the code and length parameters.
11606 + * We assume that length will aways be less that 100!
11607 + */
11608 +-void machine_real_restart(unsigned char *code, int length)
11609 ++void machine_real_restart(const unsigned char *code, unsigned int length)
11610 + {
11611 + local_irq_disable();
11612 +
11613 +@@ -276,8 +276,8 @@ void machine_real_restart(unsigned char
11614 + /* Remap the kernel at virtual address zero, as well as offset zero
11615 + from the kernel segment. This assumes the kernel segment starts at
11616 + virtual address PAGE_OFFSET. */
11617 +- memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
11618 +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
11619 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
11620 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
11621 +
11622 + /*
11623 + * Use `swapper_pg_dir' as our page directory.
11624 +@@ -289,16 +289,15 @@ void machine_real_restart(unsigned char
11625 + boot)". This seems like a fairly standard thing that gets set by
11626 + REBOOT.COM programs, and the previous reset routine did this
11627 + too. */
11628 +- *((unsigned short *)0x472) = reboot_mode;
11629 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
11630 +
11631 + /* For the switch to real mode, copy some code to low memory. It has
11632 + to be in the first 64k because it is running in 16-bit mode, and it
11633 + has to have the same physical and virtual address, because it turns
11634 + off paging. Copy it near the end of the first page, out of the way
11635 + of BIOS variables. */
11636 +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
11637 +- real_mode_switch, sizeof (real_mode_switch));
11638 +- memcpy((void *)(0x1000 - 100), code, length);
11639 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
11640 ++ memcpy(__va(0x1000 - 100), code, length);
11641 +
11642 + /* Set up the IDT for real mode. */
11643 + load_idt(&real_mode_idt);
11644 +diff -urNp a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
11645 +--- a/arch/x86/kernel/setup64.c 2008-08-20 11:16:13.000000000 -0700
11646 ++++ b/arch/x86/kernel/setup64.c 2008-08-20 18:36:57.000000000 -0700
11647 +@@ -36,15 +36,13 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
11648 + EXPORT_SYMBOL(_cpu_pda);
11649 + struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
11650 +
11651 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
11652 ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
11653 +
11654 + char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
11655 +
11656 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
11657 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
11658 +
11659 +-static int do_not_nx __cpuinitdata = 0;
11660 +-
11661 + /* noexec=on|off
11662 + Control non executable mappings for 64bit processes.
11663 +
11664 +@@ -57,16 +55,14 @@ static int __init nonx_setup(char *str)
11665 + return -EINVAL;
11666 + if (!strncmp(str, "on", 2)) {
11667 + __supported_pte_mask |= _PAGE_NX;
11668 +- do_not_nx = 0;
11669 + } else if (!strncmp(str, "off", 3)) {
11670 +- do_not_nx = 1;
11671 + __supported_pte_mask &= ~_PAGE_NX;
11672 + }
11673 + return 0;
11674 + }
11675 + early_param("noexec", nonx_setup);
11676 +
11677 +-int force_personality32 = 0;
11678 ++int force_personality32;
11679 +
11680 + /* noexec32=on|off
11681 + Control non executable heap for 32bit processes.
11682 +@@ -226,7 +222,7 @@ void __cpuinit check_efer(void)
11683 + unsigned long efer;
11684 +
11685 + rdmsrl(MSR_EFER, efer);
11686 +- if (!(efer & EFER_NX) || do_not_nx) {
11687 ++ if (!(efer & EFER_NX)) {
11688 + __supported_pte_mask &= ~_PAGE_NX;
11689 + }
11690 + }
11691 +@@ -249,12 +245,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
11692 + void __cpuinit cpu_init (void)
11693 + {
11694 + int cpu = stack_smp_processor_id();
11695 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
11696 ++ struct tss_struct *t = init_tss + cpu;
11697 + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
11698 + unsigned long v;
11699 + char *estacks = NULL;
11700 + struct task_struct *me;
11701 + int i;
11702 ++ struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)get_cpu_gdt_table(cpu)};
11703 +
11704 + /* CPU 0 is initialised in head64.c */
11705 + if (cpu != 0) {
11706 +@@ -272,14 +269,12 @@ void __cpuinit cpu_init (void)
11707 + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
11708 +
11709 + /*
11710 +- * Initialize the per-CPU GDT with the boot GDT,
11711 +- * and set up the GDT descriptor:
11712 ++ * Initialize the per-CPU GDT with the boot GDT:
11713 + */
11714 + if (cpu)
11715 +- memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
11716 ++ memcpy(get_cpu_gdt_table(cpu), get_cpu_gdt_table(0), GDT_SIZE);
11717 +
11718 +- cpu_gdt_descr[cpu].size = GDT_SIZE;
11719 +- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
11720 ++ load_gdt(&cpu_gdt_descr);
11721 + load_idt((const struct desc_ptr *)&idt_descr);
11722 +
11723 + memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
11724 +diff -urNp a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
11725 +--- a/arch/x86/kernel/setup_32.c 2008-08-20 11:16:13.000000000 -0700
11726 ++++ b/arch/x86/kernel/setup_32.c 2008-08-20 18:36:57.000000000 -0700
11727 +@@ -64,6 +64,7 @@
11728 + #include <setup_arch.h>
11729 + #include <bios_ebda.h>
11730 + #include <asm/cacheflush.h>
11731 ++#include <asm/boot.h>
11732 +
11733 + /* This value is set up by the early boot code to point to the value
11734 + immediately after the boot time page tables. It contains a *physical*
11735 +@@ -613,8 +614,8 @@ void __init setup_bootmem_allocator(void
11736 + * the (very unlikely) case of us accidentally initializing the
11737 + * bootmem allocator with an invalid RAM area.
11738 + */
11739 +- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
11740 +- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
11741 ++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
11742 ++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR,
11743 + BOOTMEM_DEFAULT);
11744 +
11745 + /*
11746 +@@ -743,14 +744,14 @@ void __init setup_arch(char **cmdline_p)
11747 +
11748 + if (!boot_params.hdr.root_flags)
11749 + root_mountflags &= ~MS_RDONLY;
11750 +- init_mm.start_code = (unsigned long) _text;
11751 +- init_mm.end_code = (unsigned long) _etext;
11752 ++ init_mm.start_code = ktla_ktva((unsigned long) _text);
11753 ++ init_mm.end_code = ktla_ktva((unsigned long) _etext);
11754 + init_mm.end_data = (unsigned long) _edata;
11755 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
11756 +
11757 +- code_resource.start = virt_to_phys(_text);
11758 +- code_resource.end = virt_to_phys(_etext)-1;
11759 +- data_resource.start = virt_to_phys(_etext);
11760 ++ code_resource.start = virt_to_phys(ktla_ktva(_text));
11761 ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
11762 ++ data_resource.start = virt_to_phys(_data);
11763 + data_resource.end = virt_to_phys(_edata)-1;
11764 + bss_resource.start = virt_to_phys(&__bss_start);
11765 + bss_resource.end = virt_to_phys(&__bss_stop)-1;
11766 +diff -urNp a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
11767 +--- a/arch/x86/kernel/signal_32.c 2008-08-20 11:16:13.000000000 -0700
11768 ++++ b/arch/x86/kernel/signal_32.c 2008-08-20 18:36:57.000000000 -0700
11769 +@@ -366,9 +366,9 @@ static int setup_frame(int sig, struct k
11770 + }
11771 +
11772 + if (current->binfmt->hasvdso)
11773 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
11774 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
11775 + else
11776 +- restorer = &frame->retcode;
11777 ++ restorer = (void __user *)&frame->retcode;
11778 + if (ka->sa.sa_flags & SA_RESTORER)
11779 + restorer = ka->sa.sa_restorer;
11780 +
11781 +@@ -463,7 +463,7 @@ static int setup_rt_frame(int sig, struc
11782 + goto give_sigsegv;
11783 +
11784 + /* Set up to return from userspace. */
11785 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
11786 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
11787 + if (ka->sa.sa_flags & SA_RESTORER)
11788 + restorer = ka->sa.sa_restorer;
11789 + err |= __put_user(restorer, &frame->pretcode);
11790 +@@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *re
11791 + * before reaching here, so testing against kernel
11792 + * CS suffices.
11793 + */
11794 +- if (!user_mode(regs))
11795 ++ if (!user_mode_novm(regs))
11796 + return;
11797 +
11798 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
11799 +diff -urNp a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
11800 +--- a/arch/x86/kernel/signal_64.c 2008-08-20 11:16:13.000000000 -0700
11801 ++++ b/arch/x86/kernel/signal_64.c 2008-08-20 18:36:57.000000000 -0700
11802 +@@ -252,8 +252,8 @@ static int setup_rt_frame(int sig, struc
11803 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
11804 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
11805 + if (sizeof(*set) == 16) {
11806 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
11807 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
11808 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
11809 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
11810 + } else
11811 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
11812 +
11813 +diff -urNp a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
11814 +--- a/arch/x86/kernel/smp_32.c 2008-08-20 11:16:13.000000000 -0700
11815 ++++ b/arch/x86/kernel/smp_32.c 2008-08-20 18:36:57.000000000 -0700
11816 +@@ -104,7 +104,7 @@
11817 + * about nothing of note with C stepping upwards.
11818 + */
11819 +
11820 +-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
11821 ++DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
11822 +
11823 + /*
11824 + * the following functions deal with sending IPIs between CPUs.
11825 +diff -urNp a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
11826 +--- a/arch/x86/kernel/smpboot_32.c 2008-08-20 11:16:13.000000000 -0700
11827 ++++ b/arch/x86/kernel/smpboot_32.c 2008-08-20 18:36:57.000000000 -0700
11828 +@@ -768,6 +768,10 @@ static int __cpuinit do_boot_cpu(int api
11829 + unsigned long start_eip;
11830 + unsigned short nmi_high = 0, nmi_low = 0;
11831 +
11832 ++#ifdef CONFIG_PAX_KERNEXEC
11833 ++ unsigned long cr0;
11834 ++#endif
11835 ++
11836 + /*
11837 + * Save current MTRR state in case it was changed since early boot
11838 + * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
11839 +@@ -784,8 +788,17 @@ static int __cpuinit do_boot_cpu(int api
11840 +
11841 + init_gdt(cpu);
11842 + per_cpu(current_task, cpu) = idle;
11843 ++
11844 ++#ifdef CONFIG_PAX_KERNEXEC
11845 ++ pax_open_kernel(cr0);
11846 ++#endif
11847 ++
11848 + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
11849 +
11850 ++#ifdef CONFIG_PAX_KERNEXEC
11851 ++ pax_close_kernel(cr0);
11852 ++#endif
11853 ++
11854 + idle->thread.ip = (unsigned long) start_secondary;
11855 + /* start_eip had better be page-aligned! */
11856 + start_eip = setup_trampoline();
11857 +diff -urNp a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
11858 +--- a/arch/x86/kernel/smpboot_64.c 2008-08-20 11:16:13.000000000 -0700
11859 ++++ b/arch/x86/kernel/smpboot_64.c 2008-08-20 18:36:57.000000000 -0700
11860 +@@ -559,13 +559,6 @@ static int __cpuinit do_boot_cpu(int cpu
11861 + };
11862 + INIT_WORK(&c_idle.work, do_fork_idle);
11863 +
11864 +- /* allocate memory for gdts of secondary cpus. Hotplug is considered */
11865 +- if (!cpu_gdt_descr[cpu].address &&
11866 +- !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
11867 +- printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
11868 +- return -1;
11869 +- }
11870 +-
11871 + /* Allocate node local memory for AP pdas */
11872 + if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
11873 + struct x8664_pda *newpda, *pda;
11874 +@@ -624,7 +617,7 @@ do_rest:
11875 + start_rip = setup_trampoline();
11876 +
11877 + init_rsp = c_idle.idle->thread.sp;
11878 +- load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
11879 ++ load_sp0(init_tss + cpu, &c_idle.idle->thread);
11880 + initial_code = start_secondary;
11881 + clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
11882 +
11883 +diff -urNp a/arch/x86/kernel/smpcommon_32.c b/arch/x86/kernel/smpcommon_32.c
11884 +--- a/arch/x86/kernel/smpcommon_32.c 2008-08-20 11:16:13.000000000 -0700
11885 ++++ b/arch/x86/kernel/smpcommon_32.c 2008-08-20 18:36:57.000000000 -0700
11886 +@@ -3,8 +3,9 @@
11887 + */
11888 + #include <linux/module.h>
11889 + #include <asm/smp.h>
11890 ++#include <asm/sections.h>
11891 +
11892 +-DEFINE_PER_CPU(unsigned long, this_cpu_off);
11893 ++DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
11894 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
11895 +
11896 + /* Initialize the CPU's GDT. This is either the boot CPU doing itself
11897 +@@ -12,15 +13,32 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
11898 + secondary which will soon come up. */
11899 + __cpuinit void init_gdt(int cpu)
11900 + {
11901 +- struct desc_struct *gdt = get_cpu_gdt_table(cpu);
11902 ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
11903 ++ unsigned long base, limit;
11904 +
11905 +- pack_descriptor(&gdt[GDT_ENTRY_PERCPU],
11906 +- __per_cpu_offset[cpu], 0xFFFFF,
11907 +- 0x2 | DESCTYPE_S, 0x8);
11908 ++#ifdef CONFIG_PAX_KERNEXEC
11909 ++ unsigned long cr0;
11910 +
11911 +- gdt[GDT_ENTRY_PERCPU].s = 1;
11912 ++ pax_open_kernel(cr0);
11913 ++#endif
11914 +
11915 +- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
11916 ++ if (cpu)
11917 ++ memcpy(gdt, get_cpu_gdt_table(0), GDT_SIZE);
11918 ++
11919 ++#ifdef CONFIG_PAX_KERNEXEC
11920 ++ pax_close_kernel(cr0);
11921 ++#endif
11922 ++
11923 ++ base = __per_cpu_offset[cpu] + (unsigned long)__per_cpu_start;
11924 ++ limit = PERCPU_ENOUGH_ROOM - 1;
11925 ++ if (limit < 64*1024)
11926 ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
11927 ++ else
11928 ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
11929 ++
11930 ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
11931 ++
11932 ++ per_cpu(this_cpu_off, cpu) = base;
11933 + per_cpu(cpu_number, cpu) = cpu;
11934 + }
11935 +
11936 +diff -urNp a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
11937 +--- a/arch/x86/kernel/step.c 2008-08-20 11:16:13.000000000 -0700
11938 ++++ b/arch/x86/kernel/step.c 2008-08-20 18:36:57.000000000 -0700
11939 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
11940 + * and APM bios ones we just ignore here.
11941 + */
11942 + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
11943 +- u32 *desc;
11944 ++ struct desc_struct *desc;
11945 + unsigned long base;
11946 +
11947 +- seg &= ~7UL;
11948 ++ seg >>= 3;
11949 +
11950 + mutex_lock(&child->mm->context.lock);
11951 +- if (unlikely((seg >> 3) >= child->mm->context.size))
11952 +- addr = -1L; /* bogus selector, access would fault */
11953 ++ if (unlikely(seg >= child->mm->context.size))
11954 ++ addr = -EINVAL;
11955 + else {
11956 +- desc = child->mm->context.ldt + seg;
11957 +- base = ((desc[0] >> 16) |
11958 +- ((desc[1] & 0xff) << 16) |
11959 +- (desc[1] & 0xff000000));
11960 ++ desc = &child->mm->context.ldt[seg];
11961 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
11962 +
11963 + /* 16-bit code segment? */
11964 +- if (!((desc[1] >> 22) & 1))
11965 ++ if (!((desc->b >> 22) & 1))
11966 + addr &= 0xffff;
11967 + addr += base;
11968 + }
11969 +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
11970 + unsigned char opcode[15];
11971 + unsigned long addr = convert_ip_to_linear(child, regs);
11972 +
11973 ++ if (addr == -EINVAL)
11974 ++ return 0;
11975 ++
11976 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
11977 + for (i = 0; i < copied; i++) {
11978 + switch (opcode[i]) {
11979 +diff -urNp a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
11980 +--- a/arch/x86/kernel/sys_i386_32.c 2008-08-20 11:16:13.000000000 -0700
11981 ++++ b/arch/x86/kernel/sys_i386_32.c 2008-08-20 18:36:57.000000000 -0700
11982 +@@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __
11983 + return error;
11984 + }
11985 +
11986 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
11987 ++{
11988 ++ unsigned long pax_task_size = TASK_SIZE;
11989 ++
11990 ++#ifdef CONFIG_PAX_SEGMEXEC
11991 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
11992 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
11993 ++#endif
11994 ++
11995 ++ if (len > pax_task_size || addr > pax_task_size - len)
11996 ++ return -EINVAL;
11997 ++
11998 ++ return 0;
11999 ++}
12000 ++
12001 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
12002 + unsigned long prot, unsigned long flags,
12003 + unsigned long fd, unsigned long pgoff)
12004 +@@ -98,6 +113,205 @@ out:
12005 + return err;
12006 + }
12007 +
12008 ++unsigned long
12009 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
12010 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
12011 ++{
12012 ++ struct mm_struct *mm = current->mm;
12013 ++ struct vm_area_struct *vma;
12014 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
12015 ++
12016 ++#ifdef CONFIG_PAX_SEGMEXEC
12017 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12018 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12019 ++#endif
12020 ++
12021 ++ if (len > pax_task_size)
12022 ++ return -ENOMEM;
12023 ++
12024 ++ if (flags & MAP_FIXED)
12025 ++ return addr;
12026 ++
12027 ++#ifdef CONFIG_PAX_RANDMMAP
12028 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
12029 ++#endif
12030 ++
12031 ++ if (addr) {
12032 ++ addr = PAGE_ALIGN(addr);
12033 ++ vma = find_vma(mm, addr);
12034 ++ if (pax_task_size - len >= addr &&
12035 ++ (!vma || addr + len <= vma->vm_start))
12036 ++ return addr;
12037 ++ }
12038 ++ if (len > mm->cached_hole_size) {
12039 ++ start_addr = addr = mm->free_area_cache;
12040 ++ } else {
12041 ++ start_addr = addr = mm->mmap_base;
12042 ++ mm->cached_hole_size = 0;
12043 ++ }
12044 ++
12045 ++#ifdef CONFIG_PAX_PAGEEXEC
12046 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
12047 ++ start_addr = 0x00110000UL;
12048 ++
12049 ++#ifdef CONFIG_PAX_RANDMMAP
12050 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12051 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
12052 ++#endif
12053 ++
12054 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
12055 ++ start_addr = addr = mm->mmap_base;
12056 ++ else
12057 ++ addr = start_addr;
12058 ++ }
12059 ++#endif
12060 ++
12061 ++full_search:
12062 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
12063 ++ /* At this point: (!vma || addr < vma->vm_end). */
12064 ++ if (pax_task_size - len < addr) {
12065 ++ /*
12066 ++ * Start a new search - just in case we missed
12067 ++ * some holes.
12068 ++ */
12069 ++ if (start_addr != mm->mmap_base) {
12070 ++ start_addr = addr = mm->mmap_base;
12071 ++ mm->cached_hole_size = 0;
12072 ++ goto full_search;
12073 ++ }
12074 ++ return -ENOMEM;
12075 ++ }
12076 ++ if (!vma || addr + len <= vma->vm_start) {
12077 ++ /*
12078 ++ * Remember the place where we stopped the search:
12079 ++ */
12080 ++ mm->free_area_cache = addr + len;
12081 ++ return addr;
12082 ++ }
12083 ++ if (addr + mm->cached_hole_size < vma->vm_start)
12084 ++ mm->cached_hole_size = vma->vm_start - addr;
12085 ++ addr = vma->vm_end;
12086 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
12087 ++ start_addr = addr = mm->mmap_base;
12088 ++ mm->cached_hole_size = 0;
12089 ++ goto full_search;
12090 ++ }
12091 ++ }
12092 ++}
12093 ++
12094 ++unsigned long
12095 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
12096 ++ const unsigned long len, const unsigned long pgoff,
12097 ++ const unsigned long flags)
12098 ++{
12099 ++ struct vm_area_struct *vma;
12100 ++ struct mm_struct *mm = current->mm;
12101 ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
12102 ++
12103 ++#ifdef CONFIG_PAX_SEGMEXEC
12104 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12105 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12106 ++#endif
12107 ++
12108 ++ /* requested length too big for entire address space */
12109 ++ if (len > pax_task_size)
12110 ++ return -ENOMEM;
12111 ++
12112 ++ if (flags & MAP_FIXED)
12113 ++ return addr;
12114 ++
12115 ++#ifdef CONFIG_PAX_PAGEEXEC
12116 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
12117 ++ goto bottomup;
12118 ++#endif
12119 ++
12120 ++#ifdef CONFIG_PAX_RANDMMAP
12121 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
12122 ++#endif
12123 ++
12124 ++ /* requesting a specific address */
12125 ++ if (addr) {
12126 ++ addr = PAGE_ALIGN(addr);
12127 ++ vma = find_vma(mm, addr);
12128 ++ if (pax_task_size - len >= addr &&
12129 ++ (!vma || addr + len <= vma->vm_start))
12130 ++ return addr;
12131 ++ }
12132 ++
12133 ++ /* check if free_area_cache is useful for us */
12134 ++ if (len <= mm->cached_hole_size) {
12135 ++ mm->cached_hole_size = 0;
12136 ++ mm->free_area_cache = mm->mmap_base;
12137 ++ }
12138 ++
12139 ++ /* either no address requested or can't fit in requested address hole */
12140 ++ addr = mm->free_area_cache;
12141 ++
12142 ++ /* make sure it can fit in the remaining address space */
12143 ++ if (addr > len) {
12144 ++ vma = find_vma(mm, addr-len);
12145 ++ if (!vma || addr <= vma->vm_start)
12146 ++ /* remember the address as a hint for next time */
12147 ++ return (mm->free_area_cache = addr-len);
12148 ++ }
12149 ++
12150 ++ if (mm->mmap_base < len)
12151 ++ goto bottomup;
12152 ++
12153 ++ addr = mm->mmap_base-len;
12154 ++
12155 ++ do {
12156 ++ /*
12157 ++ * Lookup failure means no vma is above this address,
12158 ++ * else if new region fits below vma->vm_start,
12159 ++ * return with success:
12160 ++ */
12161 ++ vma = find_vma(mm, addr);
12162 ++ if (!vma || addr+len <= vma->vm_start)
12163 ++ /* remember the address as a hint for next time */
12164 ++ return (mm->free_area_cache = addr);
12165 ++
12166 ++ /* remember the largest hole we saw so far */
12167 ++ if (addr + mm->cached_hole_size < vma->vm_start)
12168 ++ mm->cached_hole_size = vma->vm_start - addr;
12169 ++
12170 ++ /* try just below the current vma->vm_start */
12171 ++ addr = vma->vm_start-len;
12172 ++ } while (len < vma->vm_start);
12173 ++
12174 ++bottomup:
12175 ++ /*
12176 ++ * A failed mmap() very likely causes application failure,
12177 ++ * so fall back to the bottom-up function here. This scenario
12178 ++ * can happen with large stack limits and large mmap()
12179 ++ * allocations.
12180 ++ */
12181 ++
12182 ++#ifdef CONFIG_PAX_SEGMEXEC
12183 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12184 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
12185 ++ else
12186 ++#endif
12187 ++
12188 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12189 ++
12190 ++#ifdef CONFIG_PAX_RANDMMAP
12191 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12192 ++ mm->mmap_base += mm->delta_mmap;
12193 ++#endif
12194 ++
12195 ++ mm->free_area_cache = mm->mmap_base;
12196 ++ mm->cached_hole_size = ~0UL;
12197 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
12198 ++ /*
12199 ++ * Restore the topdown base:
12200 ++ */
12201 ++ mm->mmap_base = base;
12202 ++ mm->free_area_cache = base;
12203 ++ mm->cached_hole_size = ~0UL;
12204 ++
12205 ++ return addr;
12206 ++}
12207 +
12208 + struct sel_arg_struct {
12209 + unsigned long n;
12210 +diff -urNp a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
12211 +--- a/arch/x86/kernel/sys_x86_64.c 2008-08-20 11:16:13.000000000 -0700
12212 ++++ b/arch/x86/kernel/sys_x86_64.c 2008-08-20 18:36:57.000000000 -0700
12213 +@@ -62,8 +62,8 @@ out:
12214 + return error;
12215 + }
12216 +
12217 +-static void find_start_end(unsigned long flags, unsigned long *begin,
12218 +- unsigned long *end)
12219 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
12220 ++ unsigned long *begin, unsigned long *end)
12221 + {
12222 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
12223 + unsigned long new_begin;
12224 +@@ -82,7 +82,7 @@ static void find_start_end(unsigned long
12225 + *begin = new_begin;
12226 + }
12227 + } else {
12228 +- *begin = TASK_UNMAPPED_BASE;
12229 ++ *begin = mm->mmap_base;
12230 + *end = TASK_SIZE;
12231 + }
12232 + }
12233 +@@ -99,11 +99,15 @@ arch_get_unmapped_area(struct file *filp
12234 + if (flags & MAP_FIXED)
12235 + return addr;
12236 +
12237 +- find_start_end(flags, &begin, &end);
12238 ++ find_start_end(mm, flags, &begin, &end);
12239 +
12240 + if (len > end)
12241 + return -ENOMEM;
12242 +
12243 ++#ifdef CONFIG_PAX_RANDMMAP
12244 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
12245 ++#endif
12246 ++
12247 + if (addr) {
12248 + addr = PAGE_ALIGN(addr);
12249 + vma = find_vma(mm, addr);
12250 +@@ -158,7 +162,7 @@ arch_get_unmapped_area_topdown(struct fi
12251 + {
12252 + struct vm_area_struct *vma;
12253 + struct mm_struct *mm = current->mm;
12254 +- unsigned long addr = addr0;
12255 ++ unsigned long base = mm->mmap_base, addr = addr0;
12256 +
12257 + /* requested length too big for entire address space */
12258 + if (len > TASK_SIZE)
12259 +@@ -171,6 +175,10 @@ arch_get_unmapped_area_topdown(struct fi
12260 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
12261 + goto bottomup;
12262 +
12263 ++#ifdef CONFIG_PAX_RANDMMAP
12264 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
12265 ++#endif
12266 ++
12267 + /* requesting a specific address */
12268 + if (addr) {
12269 + addr = PAGE_ALIGN(addr);
12270 +@@ -228,13 +236,21 @@ bottomup:
12271 + * can happen with large stack limits and large mmap()
12272 + * allocations.
12273 + */
12274 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12275 ++
12276 ++#ifdef CONFIG_PAX_RANDMMAP
12277 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12278 ++ mm->mmap_base += mm->delta_mmap;
12279 ++#endif
12280 ++
12281 ++ mm->free_area_cache = mm->mmap_base;
12282 + mm->cached_hole_size = ~0UL;
12283 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
12284 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
12285 + /*
12286 + * Restore the topdown base:
12287 + */
12288 +- mm->free_area_cache = mm->mmap_base;
12289 ++ mm->mmap_base = base;
12290 ++ mm->free_area_cache = base;
12291 + mm->cached_hole_size = ~0UL;
12292 +
12293 + return addr;
12294 +diff -urNp a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
12295 +--- a/arch/x86/kernel/syscall_table_32.S 2008-08-20 11:16:13.000000000 -0700
12296 ++++ b/arch/x86/kernel/syscall_table_32.S 2008-08-20 18:36:57.000000000 -0700
12297 +@@ -1,3 +1,4 @@
12298 ++.section .rodata,"a",@progbits
12299 + ENTRY(sys_call_table)
12300 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
12301 + .long sys_exit
12302 +diff -urNp a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
12303 +--- a/arch/x86/kernel/time_32.c 2008-08-20 11:16:13.000000000 -0700
12304 ++++ b/arch/x86/kernel/time_32.c 2008-08-20 18:36:57.000000000 -0700
12305 +@@ -52,20 +52,30 @@ unsigned long profile_pc(struct pt_regs
12306 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
12307 + in_lock_functions(pc)) {
12308 + #ifdef CONFIG_FRAME_POINTER
12309 +- return *(unsigned long *)(regs->bp + 4);
12310 ++ return ktla_ktva(*(unsigned long *)(regs->bp + 4));
12311 + #else
12312 + unsigned long *sp = (unsigned long *)&regs->sp;
12313 +
12314 + /* Return address is either directly at stack pointer
12315 + or above a saved flags. Eflags has bits 22-31 zero,
12316 + kernel addresses don't. */
12317 ++
12318 ++#ifdef CONFIG_PAX_KERNEXEC
12319 ++ return ktla_ktva(sp[0]);
12320 ++#else
12321 + if (sp[0] >> 22)
12322 + return sp[0];
12323 + if (sp[1] >> 22)
12324 + return sp[1];
12325 + #endif
12326 ++
12327 ++#endif
12328 + }
12329 + #endif
12330 ++
12331 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
12332 ++ pc = ktla_ktva(pc);
12333 ++
12334 + return pc;
12335 + }
12336 + EXPORT_SYMBOL(profile_pc);
12337 +diff -urNp a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
12338 +--- a/arch/x86/kernel/tls.c 2008-08-20 11:16:13.000000000 -0700
12339 ++++ b/arch/x86/kernel/tls.c 2008-08-20 18:36:57.000000000 -0700
12340 +@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
12341 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
12342 + return -EINVAL;
12343 +
12344 ++#ifdef CONFIG_PAX_SEGMEXEC
12345 ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
12346 ++ return -EINVAL;
12347 ++#endif
12348 ++
12349 + set_tls_desc(p, idx, &info, 1);
12350 +
12351 + return 0;
12352 +diff -urNp a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
12353 +--- a/arch/x86/kernel/traps_32.c 2008-08-20 11:16:13.000000000 -0700
12354 ++++ b/arch/x86/kernel/traps_32.c 2008-08-20 18:36:57.000000000 -0700
12355 +@@ -29,6 +29,7 @@
12356 + #include <linux/uaccess.h>
12357 + #include <linux/nmi.h>
12358 + #include <linux/bug.h>
12359 ++#include <linux/binfmts.h>
12360 +
12361 + #ifdef CONFIG_EISA
12362 + #include <linux/ioport.h>
12363 +@@ -71,14 +72,6 @@ asmlinkage int system_call(void);
12364 + /* Do we ignore FPU interrupts ? */
12365 + char ignore_fpu_irq = 0;
12366 +
12367 +-/*
12368 +- * The IDT has to be page-aligned to simplify the Pentium
12369 +- * F0 0F bug workaround.. We have a special link segment
12370 +- * for this.
12371 +- */
12372 +-gate_desc idt_table[256]
12373 +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
12374 +-
12375 + asmlinkage void divide_error(void);
12376 + asmlinkage void debug(void);
12377 + asmlinkage void nmi(void);
12378 +@@ -330,22 +323,23 @@ void show_registers(struct pt_regs *regs
12379 + * When in-kernel, we also print out the stack and code at the
12380 + * time of the fault..
12381 + */
12382 +- if (!user_mode_vm(regs)) {
12383 ++ if (!user_mode(regs)) {
12384 + u8 *ip;
12385 + unsigned int code_prologue = code_bytes * 43 / 64;
12386 + unsigned int code_len = code_bytes;
12387 + unsigned char c;
12388 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
12389 +
12390 + printk("\n" KERN_EMERG "Stack: ");
12391 + show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
12392 +
12393 + printk(KERN_EMERG "Code: ");
12394 +
12395 +- ip = (u8 *)regs->ip - code_prologue;
12396 ++ ip = (u8 *)regs->ip - code_prologue + cs_base;
12397 + if (ip < (u8 *)PAGE_OFFSET ||
12398 + probe_kernel_address(ip, c)) {
12399 + /* try starting at EIP */
12400 +- ip = (u8 *)regs->ip;
12401 ++ ip = (u8 *)regs->ip + cs_base;
12402 + code_len = code_len - code_prologue + 1;
12403 + }
12404 + for (i = 0; i < code_len; i++, ip++) {
12405 +@@ -354,7 +348,7 @@ void show_registers(struct pt_regs *regs
12406 + printk(" Bad EIP value.");
12407 + break;
12408 + }
12409 +- if (ip == (u8 *)regs->ip)
12410 ++ if (ip == (u8 *)regs->ip + cs_base)
12411 + printk("<%02x> ", c);
12412 + else
12413 + printk("%02x ", c);
12414 +@@ -367,6 +361,7 @@ int is_valid_bugaddr(unsigned long ip)
12415 + {
12416 + unsigned short ud2;
12417 +
12418 ++ ip = ktla_ktva(ip);
12419 + if (ip < PAGE_OFFSET)
12420 + return 0;
12421 + if (probe_kernel_address((unsigned short *)ip, ud2))
12422 +@@ -476,7 +471,7 @@ void die(const char * str, struct pt_reg
12423 +
12424 + static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
12425 + {
12426 +- if (!user_mode_vm(regs))
12427 ++ if (!user_mode(regs))
12428 + die(str, regs, err);
12429 + }
12430 +
12431 +@@ -492,7 +487,7 @@ static void __kprobes do_trap(int trapnr
12432 + goto trap_signal;
12433 + }
12434 +
12435 +- if (!user_mode(regs))
12436 ++ if (!user_mode_novm(regs))
12437 + goto kernel_trap;
12438 +
12439 + trap_signal: {
12440 +@@ -598,7 +593,7 @@ void __kprobes do_general_protection(str
12441 + long error_code)
12442 + {
12443 + int cpu = get_cpu();
12444 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
12445 ++ struct tss_struct *tss = &init_tss[cpu];
12446 + struct thread_struct *thread = &current->thread;
12447 +
12448 + /*
12449 +@@ -631,9 +626,25 @@ void __kprobes do_general_protection(str
12450 + if (regs->flags & VM_MASK)
12451 + goto gp_in_vm86;
12452 +
12453 +- if (!user_mode(regs))
12454 ++ if (!user_mode_novm(regs))
12455 + goto gp_in_kernel;
12456 +
12457 ++#ifdef CONFIG_PAX_PAGEEXEC
12458 ++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
12459 ++ struct mm_struct *mm = current->mm;
12460 ++ unsigned long limit;
12461 ++
12462 ++ down_write(&mm->mmap_sem);
12463 ++ limit = mm->context.user_cs_limit;
12464 ++ if (limit < TASK_SIZE) {
12465 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
12466 ++ up_write(&mm->mmap_sem);
12467 ++ return;
12468 ++ }
12469 ++ up_write(&mm->mmap_sem);
12470 ++ }
12471 ++#endif
12472 ++
12473 + current->thread.error_code = error_code;
12474 + current->thread.trap_no = 13;
12475 + if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
12476 +@@ -661,6 +672,13 @@ gp_in_kernel:
12477 + if (notify_die(DIE_GPF, "general protection fault", regs,
12478 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
12479 + return;
12480 ++
12481 ++#ifdef CONFIG_PAX_KERNEXEC
12482 ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
12483 ++ die("PAX: suspicious general protection fault", regs, error_code);
12484 ++ else
12485 ++#endif
12486 ++
12487 + die("general protection fault", regs, error_code);
12488 + }
12489 + }
12490 +@@ -750,7 +768,7 @@ void __kprobes die_nmi(struct pt_regs *r
12491 + /* If we are in kernel we are probably nested up pretty bad
12492 + * and might aswell get out now while we still can.
12493 + */
12494 +- if (!user_mode_vm(regs)) {
12495 ++ if (!user_mode(regs)) {
12496 + current->thread.trap_no = 2;
12497 + crash_kexec(regs);
12498 + }
12499 +@@ -907,7 +925,7 @@ void __kprobes do_debug(struct pt_regs *
12500 + * check for kernel mode by just checking the CPL
12501 + * of CS.
12502 + */
12503 +- if (!user_mode(regs))
12504 ++ if (!user_mode_novm(regs))
12505 + goto clear_TF_reenable;
12506 + }
12507 +
12508 +@@ -1085,18 +1103,14 @@ void do_spurious_interrupt_bug(struct pt
12509 + unsigned long patch_espfix_desc(unsigned long uesp,
12510 + unsigned long kesp)
12511 + {
12512 +- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
12513 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
12514 + unsigned long new_kesp = kesp - base;
12515 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
12516 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
12517 ++ struct desc_struct ss;
12518 ++
12519 + /* Set up base for espfix segment */
12520 +- desc &= 0x00f0ff0000000000ULL;
12521 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
12522 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
12523 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
12524 +- (lim_pages & 0xffff);
12525 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
12526 ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
12527 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
12528 + return new_kesp;
12529 + }
12530 +
12531 +diff -urNp a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
12532 +--- a/arch/x86/kernel/tsc_32.c 2008-08-20 11:16:13.000000000 -0700
12533 ++++ b/arch/x86/kernel/tsc_32.c 2008-08-20 18:36:57.000000000 -0700
12534 +@@ -338,7 +338,7 @@ static struct dmi_system_id __initdata b
12535 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
12536 + },
12537 + },
12538 +- {}
12539 ++ { NULL, NULL, {{0, NULL}}, NULL}
12540 + };
12541 +
12542 + /*
12543 +diff -urNp a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
12544 +--- a/arch/x86/kernel/vm86_32.c 2008-08-20 11:16:13.000000000 -0700
12545 ++++ b/arch/x86/kernel/vm86_32.c 2008-08-20 18:36:57.000000000 -0700
12546 +@@ -145,7 +145,7 @@ struct pt_regs * save_v86_state(struct k
12547 + do_exit(SIGSEGV);
12548 + }
12549 +
12550 +- tss = &per_cpu(init_tss, get_cpu());
12551 ++ tss = init_tss + get_cpu();
12552 + current->thread.sp0 = current->thread.saved_sp0;
12553 + current->thread.sysenter_cs = __KERNEL_CS;
12554 + load_sp0(tss, &current->thread);
12555 +@@ -321,7 +321,7 @@ static void do_sys_vm86(struct kernel_vm
12556 + tsk->thread.saved_fs = info->regs32->fs;
12557 + savesegment(gs, tsk->thread.saved_gs);
12558 +
12559 +- tss = &per_cpu(init_tss, get_cpu());
12560 ++ tss = init_tss + get_cpu();
12561 + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
12562 + if (cpu_has_sep)
12563 + tsk->thread.sysenter_cs = 0;
12564 +diff -urNp a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
12565 +--- a/arch/x86/kernel/vmi_32.c 2008-08-20 11:16:13.000000000 -0700
12566 ++++ b/arch/x86/kernel/vmi_32.c 2008-08-20 18:36:57.000000000 -0700
12567 +@@ -101,18 +101,43 @@ static unsigned patch_internal(int call,
12568 + {
12569 + u64 reloc;
12570 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
12571 ++
12572 ++#ifdef CONFIG_PAX_KERNEXEC
12573 ++ unsigned long cr0;
12574 ++#endif
12575 ++
12576 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
12577 + switch(rel->type) {
12578 + case VMI_RELOCATION_CALL_REL:
12579 + BUG_ON(len < 5);
12580 ++
12581 ++#ifdef CONFIG_PAX_KERNEXEC
12582 ++ pax_open_kernel(cr0);
12583 ++#endif
12584 ++
12585 + *(char *)insnbuf = MNEM_CALL;
12586 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
12587 ++
12588 ++#ifdef CONFIG_PAX_KERNEXEC
12589 ++ pax_close_kernel(cr0);
12590 ++#endif
12591 ++
12592 + return 5;
12593 +
12594 + case VMI_RELOCATION_JUMP_REL:
12595 + BUG_ON(len < 5);
12596 ++
12597 ++#ifdef CONFIG_PAX_KERNEXEC
12598 ++ pax_open_kernel(cr0);
12599 ++#endif
12600 ++
12601 + *(char *)insnbuf = MNEM_JMP;
12602 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
12603 ++
12604 ++#ifdef CONFIG_PAX_KERNEXEC
12605 ++ pax_close_kernel(cr0);
12606 ++#endif
12607 ++
12608 + return 5;
12609 +
12610 + case VMI_RELOCATION_NOP:
12611 +@@ -515,14 +540,14 @@ static void vmi_set_pud(pud_t *pudp, pud
12612 +
12613 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
12614 + {
12615 +- const pte_t pte = { .pte = 0 };
12616 ++ const pte_t pte = __pte(0ULL);
12617 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
12618 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
12619 + }
12620 +
12621 + static void vmi_pmd_clear(pmd_t *pmd)
12622 + {
12623 +- const pte_t pte = { .pte = 0 };
12624 ++ const pte_t pte = __pte(0ULL);
12625 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
12626 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
12627 + }
12628 +@@ -551,8 +576,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
12629 + ap.ss = __KERNEL_DS;
12630 + ap.esp = (unsigned long) start_esp;
12631 +
12632 +- ap.ds = __USER_DS;
12633 +- ap.es = __USER_DS;
12634 ++ ap.ds = __KERNEL_DS;
12635 ++ ap.es = __KERNEL_DS;
12636 + ap.fs = __KERNEL_PERCPU;
12637 + ap.gs = 0;
12638 +
12639 +@@ -747,12 +772,20 @@ static inline int __init activate_vmi(vo
12640 + u64 reloc;
12641 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
12642 +
12643 ++#ifdef CONFIG_PAX_KERNEXEC
12644 ++ unsigned long cr0;
12645 ++#endif
12646 ++
12647 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
12648 + printk(KERN_ERR "VMI ROM failed to initialize!");
12649 + return 0;
12650 + }
12651 + savesegment(cs, kernel_cs);
12652 +
12653 ++#ifdef CONFIG_PAX_KERNEXEC
12654 ++ pax_open_kernel(cr0);
12655 ++#endif
12656 ++
12657 + pv_info.paravirt_enabled = 1;
12658 + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
12659 + pv_info.name = "vmi";
12660 +@@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
12661 +
12662 + para_fill(pv_irq_ops.safe_halt, Halt);
12663 +
12664 ++#ifdef CONFIG_PAX_KERNEXEC
12665 ++ pax_close_kernel(cr0);
12666 ++#endif
12667 ++
12668 + /*
12669 + * Alternative instruction rewriting doesn't happen soon enough
12670 + * to convert VMI_IRET to a call instead of a jump; so we have
12671 +diff -urNp a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
12672 +--- a/arch/x86/kernel/vmlinux_32.lds.S 2008-08-20 11:16:13.000000000 -0700
12673 ++++ b/arch/x86/kernel/vmlinux_32.lds.S 2008-08-20 18:36:57.000000000 -0700
12674 +@@ -15,6 +15,20 @@
12675 + #include <asm/page.h>
12676 + #include <asm/cache.h>
12677 + #include <asm/boot.h>
12678 ++#include <asm/segment.h>
12679 ++
12680 ++#ifdef CONFIG_X86_PAE
12681 ++#define PMD_SHIFT 21
12682 ++#else
12683 ++#define PMD_SHIFT 22
12684 ++#endif
12685 ++#define PMD_SIZE (1 << PMD_SHIFT)
12686 ++
12687 ++#ifdef CONFIG_PAX_KERNEXEC
12688 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
12689 ++#else
12690 ++#define __KERNEL_TEXT_OFFSET 0
12691 ++#endif
12692 +
12693 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
12694 + OUTPUT_ARCH(i386)
12695 +@@ -22,90 +36,23 @@ ENTRY(phys_startup_32)
12696 + jiffies = jiffies_64;
12697 +
12698 + PHDRS {
12699 +- text PT_LOAD FLAGS(5); /* R_E */
12700 +- data PT_LOAD FLAGS(7); /* RWE */
12701 +- note PT_NOTE FLAGS(0); /* ___ */
12702 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
12703 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
12704 ++ inittext PT_LOAD FLAGS(5); /* R_E */
12705 ++ text PT_LOAD FLAGS(5); /* R_E */
12706 ++ rodata PT_LOAD FLAGS(4); /* R__ */
12707 ++ data PT_LOAD FLAGS(6); /* RW_ */
12708 ++ note PT_NOTE FLAGS(0); /* ___ */
12709 + }
12710 + SECTIONS
12711 + {
12712 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
12713 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
12714 +-
12715 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
12716 +- _text = .; /* Text and read-only data */
12717 +- *(.text.head)
12718 +- } :text = 0x9090
12719 +-
12720 +- /* read-only */
12721 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
12722 +- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
12723 +- *(.text.page_aligned)
12724 +- TEXT_TEXT
12725 +- SCHED_TEXT
12726 +- LOCK_TEXT
12727 +- KPROBES_TEXT
12728 +- *(.fixup)
12729 +- *(.gnu.warning)
12730 +- _etext = .; /* End of text section */
12731 +- } :text = 0x9090
12732 +-
12733 +- . = ALIGN(16); /* Exception table */
12734 +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
12735 +- __start___ex_table = .;
12736 +- *(__ex_table)
12737 +- __stop___ex_table = .;
12738 +- }
12739 +-
12740 +- NOTES :text :note
12741 +-
12742 +- BUG_TABLE :text
12743 +-
12744 +- . = ALIGN(4);
12745 +- .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
12746 +- __tracedata_start = .;
12747 +- *(.tracedata)
12748 +- __tracedata_end = .;
12749 +- }
12750 ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
12751 +
12752 +- RODATA
12753 +-
12754 +- /* writeable */
12755 +- . = ALIGN(PAGE_SIZE);
12756 +- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
12757 +- DATA_DATA
12758 +- CONSTRUCTORS
12759 +- } :data
12760 +-
12761 +- . = ALIGN(PAGE_SIZE);
12762 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
12763 +- __nosave_begin = .;
12764 +- *(.data.nosave)
12765 +- . = ALIGN(PAGE_SIZE);
12766 +- __nosave_end = .;
12767 +- }
12768 +-
12769 +- . = ALIGN(PAGE_SIZE);
12770 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
12771 +- *(.data.page_aligned)
12772 +- *(.data.idt)
12773 +- }
12774 +-
12775 +- . = ALIGN(32);
12776 +- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
12777 +- *(.data.cacheline_aligned)
12778 +- }
12779 +-
12780 +- /* rarely changed data like cpu maps */
12781 +- . = ALIGN(32);
12782 +- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
12783 +- *(.data.read_mostly)
12784 +- _edata = .; /* End of data section */
12785 +- }
12786 +-
12787 +- . = ALIGN(THREAD_SIZE); /* init_task */
12788 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
12789 +- *(.data.init_task)
12790 +- }
12791 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
12792 ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
12793 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
12794 ++ *(.text.startup)
12795 ++ } :initdata
12796 +
12797 + /* might get freed after init */
12798 + . = ALIGN(PAGE_SIZE);
12799 +@@ -123,14 +70,8 @@ SECTIONS
12800 + . = ALIGN(PAGE_SIZE);
12801 +
12802 + /* will be freed after init */
12803 +- . = ALIGN(PAGE_SIZE); /* Init code and data */
12804 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
12805 +- __init_begin = .;
12806 +- _sinittext = .;
12807 +- INIT_TEXT
12808 +- _einittext = .;
12809 +- }
12810 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
12811 ++ __init_begin = .;
12812 + INIT_DATA
12813 + }
12814 + . = ALIGN(16);
12815 +@@ -165,11 +106,6 @@ SECTIONS
12816 + *(.parainstructions)
12817 + __parainstructions_end = .;
12818 + }
12819 +- /* .exit.text is discard at runtime, not link time, to deal with references
12820 +- from .altinstructions and .eh_frame */
12821 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
12822 +- EXIT_TEXT
12823 +- }
12824 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
12825 + EXIT_DATA
12826 + }
12827 +@@ -182,17 +118,144 @@ SECTIONS
12828 + }
12829 + #endif
12830 + . = ALIGN(PAGE_SIZE);
12831 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
12832 +- __per_cpu_start = .;
12833 ++ per_cpu_start = .;
12834 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
12835 ++ __per_cpu_start = . + per_cpu_start;
12836 ++ LONG(0)
12837 + *(.data.percpu)
12838 + *(.data.percpu.shared_aligned)
12839 +- __per_cpu_end = .;
12840 +- }
12841 ++ __per_cpu_end = . + per_cpu_start;
12842 ++ } :percpu
12843 ++ . += per_cpu_start;
12844 + . = ALIGN(PAGE_SIZE);
12845 + /* freed after init ends here */
12846 +
12847 ++ . = ALIGN(PAGE_SIZE); /* Init code and data */
12848 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12849 ++ _sinittext = .;
12850 ++ INIT_TEXT
12851 ++ _einittext = .;
12852 ++ } :inittext
12853 ++
12854 ++ /* .exit.text is discard at runtime, not link time, to deal with references
12855 ++ from .altinstructions and .eh_frame */
12856 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12857 ++ EXIT_TEXT
12858 ++ }
12859 ++
12860 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12861 ++ BYTE(0)
12862 ++ . = ALIGN(2*PMD_SIZE) - 1;
12863 ++ }
12864 ++
12865 ++ /* freed after init ends here */
12866 ++
12867 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12868 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
12869 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
12870 ++ _text = .; /* Text and read-only data */
12871 ++ *(.text.head)
12872 ++ } :text = 0x9090
12873 ++
12874 ++ /* read-only */
12875 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12876 ++ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
12877 ++ *(.text.page_aligned)
12878 ++ TEXT_TEXT
12879 ++ SCHED_TEXT
12880 ++ LOCK_TEXT
12881 ++ KPROBES_TEXT
12882 ++ *(.fixup)
12883 ++ *(.gnu.warning)
12884 ++ _etext = .; /* End of text section */
12885 ++ } :text = 0x9090
12886 ++
12887 ++ . += __KERNEL_TEXT_OFFSET;
12888 ++ . = ALIGN(4096); /* Exception table */
12889 ++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
12890 ++ __start___ex_table = .;
12891 ++ *(__ex_table)
12892 ++ __stop___ex_table = .;
12893 ++ } :rodata
12894 ++
12895 ++ NOTES :rodata :note
12896 ++
12897 ++ BUG_TABLE :rodata
12898 ++
12899 ++ . = ALIGN(4);
12900 ++ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
12901 ++ __tracedata_start = .;
12902 ++ *(.tracedata)
12903 ++ __tracedata_end = .;
12904 ++ }
12905 ++
12906 ++ RO_DATA(PAGE_SIZE)
12907 ++
12908 ++ . = ALIGN(PAGE_SIZE);
12909 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
12910 ++ *(.idt)
12911 ++ . = ALIGN(PAGE_SIZE);
12912 ++ *(.empty_zero_page)
12913 ++ *(.swapper_pg_pmd)
12914 ++ *(.swapper_pg_dir)
12915 ++ }
12916 ++
12917 ++#ifdef CONFIG_PAX_KERNEXEC
12918 ++
12919 ++#ifdef CONFIG_MODULES
12920 ++ . = ALIGN(PAGE_SIZE);
12921 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
12922 ++ MODULES_VADDR = .;
12923 ++ BYTE(0)
12924 ++ . += (6 * 1024 * 1024);
12925 ++ . = ALIGN( PMD_SIZE) - 1;
12926 ++ MODULES_END = .;
12927 ++ }
12928 ++#else
12929 ++ . = ALIGN(PMD_SIZE) - 1;
12930 ++#endif
12931 ++
12932 ++#endif
12933 ++
12934 ++ /* writeable */
12935 ++ . = ALIGN(PAGE_SIZE);
12936 ++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
12937 ++ _data = .;
12938 ++ DATA_DATA
12939 ++ CONSTRUCTORS
12940 ++ } :data
12941 ++
12942 ++ . = ALIGN(PAGE_SIZE);
12943 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
12944 ++ __nosave_begin = .;
12945 ++ *(.data.nosave)
12946 ++ . = ALIGN(PAGE_SIZE);
12947 ++ __nosave_end = .;
12948 ++ }
12949 ++
12950 ++ . = ALIGN(PAGE_SIZE);
12951 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
12952 ++ *(.data.page_aligned)
12953 ++ }
12954 ++
12955 ++ . = ALIGN(32);
12956 ++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
12957 ++ *(.data.cacheline_aligned)
12958 ++ }
12959 ++
12960 ++ /* rarely changed data like cpu maps */
12961 ++ . = ALIGN(32);
12962 ++ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
12963 ++ *(.data.read_mostly)
12964 ++ _edata = .; /* End of data section */
12965 ++ }
12966 ++
12967 ++ . = ALIGN(THREAD_SIZE); /* init_task */
12968 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
12969 ++ *(.data.init_task)
12970 ++ }
12971 ++
12972 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
12973 +- __init_end = .;
12974 + __bss_start = .; /* BSS */
12975 + *(.bss.page_aligned)
12976 + *(.bss)
12977 +diff -urNp a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
12978 +--- a/arch/x86/kernel/vmlinux_64.lds.S 2008-08-20 11:16:13.000000000 -0700
12979 ++++ b/arch/x86/kernel/vmlinux_64.lds.S 2008-08-20 18:36:57.000000000 -0700
12980 +@@ -16,8 +16,8 @@ jiffies_64 = jiffies;
12981 + _proxy_pda = 1;
12982 + PHDRS {
12983 + text PT_LOAD FLAGS(5); /* R_E */
12984 +- data PT_LOAD FLAGS(7); /* RWE */
12985 +- user PT_LOAD FLAGS(7); /* RWE */
12986 ++ data PT_LOAD FLAGS(6); /* RW_ */
12987 ++ user PT_LOAD FLAGS(7); /* RWX */
12988 + data.init PT_LOAD FLAGS(7); /* RWE */
12989 + note PT_NOTE FLAGS(4); /* R__ */
12990 + }
12991 +@@ -51,7 +51,7 @@ SECTIONS
12992 +
12993 + BUG_TABLE :text
12994 +
12995 +- RODATA
12996 ++ RO_DATA(PAGE_SIZE)
12997 +
12998 + . = ALIGN(4);
12999 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
13000 +@@ -60,15 +60,18 @@ SECTIONS
13001 + __tracedata_end = .;
13002 + }
13003 +
13004 ++#ifdef CONFIG_PAX_KERNEXEC
13005 ++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
13006 ++#else
13007 + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
13008 ++#endif
13009 + /* Data */
13010 ++ _data = .;
13011 + .data : AT(ADDR(.data) - LOAD_OFFSET) {
13012 + DATA_DATA
13013 + CONSTRUCTORS
13014 + } :data
13015 +
13016 +- _edata = .; /* End of data section */
13017 +-
13018 + . = ALIGN(PAGE_SIZE);
13019 + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
13020 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
13021 +@@ -79,9 +82,27 @@ SECTIONS
13022 + *(.data.read_mostly)
13023 + }
13024 +
13025 ++ . = ALIGN(THREAD_SIZE); /* init_task */
13026 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
13027 ++ *(.data.init_task)
13028 ++ }
13029 ++
13030 ++ . = ALIGN(PAGE_SIZE);
13031 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
13032 ++ *(.data.page_aligned)
13033 ++ }
13034 ++
13035 ++ . = ALIGN(PAGE_SIZE);
13036 ++ __nosave_begin = .;
13037 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
13038 ++ . = ALIGN(PAGE_SIZE);
13039 ++ __nosave_end = .;
13040 ++
13041 ++ _edata = .; /* End of data section */
13042 ++
13043 + #define VSYSCALL_ADDR (-10*1024*1024)
13044 +-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
13045 +-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
13046 ++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
13047 ++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
13048 +
13049 + #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
13050 + #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
13051 +@@ -129,23 +150,13 @@ SECTIONS
13052 + #undef VVIRT_OFFSET
13053 + #undef VVIRT
13054 +
13055 +- . = ALIGN(THREAD_SIZE); /* init_task */
13056 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
13057 +- *(.data.init_task)
13058 +- }:data.init
13059 +-
13060 +- . = ALIGN(PAGE_SIZE);
13061 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
13062 +- *(.data.page_aligned)
13063 +- }
13064 +-
13065 + /* might get freed after init */
13066 + . = ALIGN(PAGE_SIZE);
13067 + __smp_alt_begin = .;
13068 + __smp_locks = .;
13069 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
13070 + *(.smp_locks)
13071 +- }
13072 ++ } :data.init
13073 + __smp_locks_end = .;
13074 + . = ALIGN(PAGE_SIZE);
13075 + __smp_alt_end = .;
13076 +@@ -222,12 +233,6 @@ SECTIONS
13077 + . = ALIGN(PAGE_SIZE);
13078 + __init_end = .;
13079 +
13080 +- . = ALIGN(PAGE_SIZE);
13081 +- __nosave_begin = .;
13082 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
13083 +- . = ALIGN(PAGE_SIZE);
13084 +- __nosave_end = .;
13085 +-
13086 + __bss_start = .; /* BSS */
13087 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
13088 + *(.bss.page_aligned)
13089 +@@ -235,6 +240,7 @@ SECTIONS
13090 + }
13091 + __bss_stop = .;
13092 +
13093 ++ . = ALIGN(2*1024*1024);
13094 + _end = . ;
13095 +
13096 + /* Sections to be discarded */
13097 +diff -urNp a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
13098 +--- a/arch/x86/kernel/vsyscall_64.c 2008-08-20 11:16:13.000000000 -0700
13099 ++++ b/arch/x86/kernel/vsyscall_64.c 2008-08-20 18:36:57.000000000 -0700
13100 +@@ -235,13 +235,13 @@ static ctl_table kernel_table2[] = {
13101 + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
13102 + .mode = 0644,
13103 + .proc_handler = vsyscall_sysctl_change },
13104 +- {}
13105 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
13106 + };
13107 +
13108 + static ctl_table kernel_root_table2[] = {
13109 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
13110 + .child = kernel_table2 },
13111 +- {}
13112 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
13113 + };
13114 + #endif
13115 +
13116 +@@ -251,6 +251,11 @@ static void __cpuinit vsyscall_set_cpu(i
13117 + {
13118 + unsigned long *d;
13119 + unsigned long node = 0;
13120 ++
13121 ++#ifdef CONFIG_PAX_KERNEXEC
13122 ++ unsigned long cr0;
13123 ++#endif
13124 ++
13125 + #ifdef CONFIG_NUMA
13126 + node = cpu_to_node(cpu);
13127 + #endif
13128 +@@ -261,10 +266,20 @@ static void __cpuinit vsyscall_set_cpu(i
13129 + in user space in vgetcpu.
13130 + 12 bits for the CPU and 8 bits for the node. */
13131 + d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU);
13132 ++
13133 ++#ifdef CONFIG_PAX_KERNEXEC
13134 ++ pax_open_kernel(cr0);
13135 ++#endif
13136 ++
13137 + *d = 0x0f40000000000ULL;
13138 + *d |= cpu;
13139 + *d |= (node & 0xf) << 12;
13140 + *d |= (node >> 4) << 48;
13141 ++
13142 ++#ifdef CONFIG_PAX_KERNEXEC
13143 ++ pax_close_kernel(cr0);
13144 ++#endif
13145 ++
13146 + }
13147 +
13148 + static void __cpuinit cpu_vsyscall_init(void *arg)
13149 +diff -urNp a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
13150 +--- a/arch/x86/kernel/x8664_ksyms_64.c 2008-08-20 11:16:13.000000000 -0700
13151 ++++ b/arch/x86/kernel/x8664_ksyms_64.c 2008-08-20 18:36:57.000000000 -0700
13152 +@@ -54,8 +54,3 @@ EXPORT_SYMBOL(init_level4_pgt);
13153 + EXPORT_SYMBOL(load_gs_index);
13154 +
13155 + EXPORT_SYMBOL(_proxy_pda);
13156 +-
13157 +-#ifdef CONFIG_PARAVIRT
13158 +-/* Virtualized guests may want to use it */
13159 +-EXPORT_SYMBOL_GPL(cpu_gdt_descr);
13160 +-#endif
13161 +diff -urNp a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
13162 +--- a/arch/x86/kvm/svm.c 2008-08-20 11:16:13.000000000 -0700
13163 ++++ b/arch/x86/kvm/svm.c 2008-08-20 18:36:57.000000000 -0700
13164 +@@ -1329,7 +1329,19 @@ static void reload_tss(struct kvm_vcpu *
13165 + int cpu = raw_smp_processor_id();
13166 +
13167 + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
13168 ++
13169 ++#ifdef CONFIG_PAX_KERNEXEC
13170 ++ unsigned long cr0;
13171 ++
13172 ++ pax_open_kernel(cr0);
13173 ++#endif
13174 ++
13175 + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
13176 ++
13177 ++#ifdef CONFIG_PAX_KERNEXEC
13178 ++ pax_close_kernel(cr0);
13179 ++#endif
13180 ++
13181 + load_TR_desc();
13182 + }
13183 +
13184 +diff -urNp a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
13185 +--- a/arch/x86/kvm/vmx.c 2008-08-20 11:16:13.000000000 -0700
13186 ++++ b/arch/x86/kvm/vmx.c 2008-08-20 18:36:57.000000000 -0700
13187 +@@ -355,9 +355,23 @@ static void reload_tss(void)
13188 + struct descriptor_table gdt;
13189 + struct segment_descriptor *descs;
13190 +
13191 ++#ifdef CONFIG_PAX_KERNEXEC
13192 ++ unsigned long cr0;
13193 ++#endif
13194 ++
13195 + get_gdt(&gdt);
13196 + descs = (void *)gdt.base;
13197 ++
13198 ++#ifdef CONFIG_PAX_KERNEXEC
13199 ++ pax_open_kernel(cr0);
13200 ++#endif
13201 ++
13202 + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
13203 ++
13204 ++#ifdef CONFIG_PAX_KERNEXEC
13205 ++ pax_close_kernel(cr0);
13206 ++#endif
13207 ++
13208 + load_TR_desc();
13209 + }
13210 +
13211 +@@ -2464,7 +2478,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
13212 + vcpu->arch.interrupt_window_open =
13213 + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
13214 +
13215 +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
13216 ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
13217 + vmx->launched = 1;
13218 +
13219 + intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
13220 +diff -urNp a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
13221 +--- a/arch/x86/kvm/x86.c 2008-08-20 11:16:13.000000000 -0700
13222 ++++ b/arch/x86/kvm/x86.c 2008-08-20 18:36:57.000000000 -0700
13223 +@@ -52,33 +52,33 @@ static int kvm_dev_ioctl_get_supported_c
13224 + struct kvm_x86_ops *kvm_x86_ops;
13225 +
13226 + struct kvm_stats_debugfs_item debugfs_entries[] = {
13227 +- { "pf_fixed", VCPU_STAT(pf_fixed) },
13228 +- { "pf_guest", VCPU_STAT(pf_guest) },
13229 +- { "tlb_flush", VCPU_STAT(tlb_flush) },
13230 +- { "invlpg", VCPU_STAT(invlpg) },
13231 +- { "exits", VCPU_STAT(exits) },
13232 +- { "io_exits", VCPU_STAT(io_exits) },
13233 +- { "mmio_exits", VCPU_STAT(mmio_exits) },
13234 +- { "signal_exits", VCPU_STAT(signal_exits) },
13235 +- { "irq_window", VCPU_STAT(irq_window_exits) },
13236 +- { "halt_exits", VCPU_STAT(halt_exits) },
13237 +- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
13238 +- { "request_irq", VCPU_STAT(request_irq_exits) },
13239 +- { "irq_exits", VCPU_STAT(irq_exits) },
13240 +- { "host_state_reload", VCPU_STAT(host_state_reload) },
13241 +- { "efer_reload", VCPU_STAT(efer_reload) },
13242 +- { "fpu_reload", VCPU_STAT(fpu_reload) },
13243 +- { "insn_emulation", VCPU_STAT(insn_emulation) },
13244 +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
13245 +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
13246 +- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
13247 +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
13248 +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
13249 +- { "mmu_flooded", VM_STAT(mmu_flooded) },
13250 +- { "mmu_recycled", VM_STAT(mmu_recycled) },
13251 +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
13252 +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
13253 +- { NULL }
13254 ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
13255 ++ { "pf_guest", VCPU_STAT(pf_guest), NULL },
13256 ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
13257 ++ { "invlpg", VCPU_STAT(invlpg), NULL },
13258 ++ { "exits", VCPU_STAT(exits), NULL },
13259 ++ { "io_exits", VCPU_STAT(io_exits), NULL },
13260 ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
13261 ++ { "signal_exits", VCPU_STAT(signal_exits), NULL },
13262 ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
13263 ++ { "halt_exits", VCPU_STAT(halt_exits), NULL },
13264 ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
13265 ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
13266 ++ { "irq_exits", VCPU_STAT(irq_exits), NULL },
13267 ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
13268 ++ { "efer_reload", VCPU_STAT(efer_reload), NULL },
13269 ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
13270 ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
13271 ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
13272 ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
13273 ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
13274 ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
13275 ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
13276 ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
13277 ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
13278 ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
13279 ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
13280 ++ { NULL, 0, KVM_STAT_VM, NULL }
13281 + };
13282 +
13283 +
13284 +@@ -1065,7 +1065,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
13285 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
13286 + struct kvm_interrupt *irq)
13287 + {
13288 +- if (irq->irq < 0 || irq->irq >= 256)
13289 ++ if (irq->irq >= 256)
13290 + return -EINVAL;
13291 + if (irqchip_in_kernel(vcpu->kvm))
13292 + return -ENXIO;
13293 +diff -urNp a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S
13294 +--- a/arch/x86/lib/checksum_32.S 2008-08-20 11:16:13.000000000 -0700
13295 ++++ b/arch/x86/lib/checksum_32.S 2008-08-20 18:36:57.000000000 -0700
13296 +@@ -28,7 +28,8 @@
13297 + #include <linux/linkage.h>
13298 + #include <asm/dwarf2.h>
13299 + #include <asm/errno.h>
13300 +-
13301 ++#include <asm/segment.h>
13302 ++
13303 + /*
13304 + * computes a partial checksum, e.g. for TCP/UDP fragments
13305 + */
13306 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
13307 +
13308 + #define ARGBASE 16
13309 + #define FP 12
13310 +-
13311 +-ENTRY(csum_partial_copy_generic)
13312 ++
13313 ++ENTRY(csum_partial_copy_generic_to_user)
13314 + CFI_STARTPROC
13315 ++ pushl $(__USER_DS)
13316 ++ CFI_ADJUST_CFA_OFFSET 4
13317 ++ popl %es
13318 ++ CFI_ADJUST_CFA_OFFSET -4
13319 ++ jmp csum_partial_copy_generic
13320 ++
13321 ++ENTRY(csum_partial_copy_generic_from_user)
13322 ++ pushl $(__USER_DS)
13323 ++ CFI_ADJUST_CFA_OFFSET 4
13324 ++ popl %ds
13325 ++ CFI_ADJUST_CFA_OFFSET -4
13326 ++
13327 ++ENTRY(csum_partial_copy_generic)
13328 + subl $4,%esp
13329 + CFI_ADJUST_CFA_OFFSET 4
13330 + pushl %edi
13331 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
13332 + jmp 4f
13333 + SRC(1: movw (%esi), %bx )
13334 + addl $2, %esi
13335 +-DST( movw %bx, (%edi) )
13336 ++DST( movw %bx, %es:(%edi) )
13337 + addl $2, %edi
13338 + addw %bx, %ax
13339 + adcl $0, %eax
13340 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
13341 + SRC(1: movl (%esi), %ebx )
13342 + SRC( movl 4(%esi), %edx )
13343 + adcl %ebx, %eax
13344 +-DST( movl %ebx, (%edi) )
13345 ++DST( movl %ebx, %es:(%edi) )
13346 + adcl %edx, %eax
13347 +-DST( movl %edx, 4(%edi) )
13348 ++DST( movl %edx, %es:4(%edi) )
13349 +
13350 + SRC( movl 8(%esi), %ebx )
13351 + SRC( movl 12(%esi), %edx )
13352 + adcl %ebx, %eax
13353 +-DST( movl %ebx, 8(%edi) )
13354 ++DST( movl %ebx, %es:8(%edi) )
13355 + adcl %edx, %eax
13356 +-DST( movl %edx, 12(%edi) )
13357 ++DST( movl %edx, %es:12(%edi) )
13358 +
13359 + SRC( movl 16(%esi), %ebx )
13360 + SRC( movl 20(%esi), %edx )
13361 + adcl %ebx, %eax
13362 +-DST( movl %ebx, 16(%edi) )
13363 ++DST( movl %ebx, %es:16(%edi) )
13364 + adcl %edx, %eax
13365 +-DST( movl %edx, 20(%edi) )
13366 ++DST( movl %edx, %es:20(%edi) )
13367 +
13368 + SRC( movl 24(%esi), %ebx )
13369 + SRC( movl 28(%esi), %edx )
13370 + adcl %ebx, %eax
13371 +-DST( movl %ebx, 24(%edi) )
13372 ++DST( movl %ebx, %es:24(%edi) )
13373 + adcl %edx, %eax
13374 +-DST( movl %edx, 28(%edi) )
13375 ++DST( movl %edx, %es:28(%edi) )
13376 +
13377 + lea 32(%esi), %esi
13378 + lea 32(%edi), %edi
13379 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
13380 + shrl $2, %edx # This clears CF
13381 + SRC(3: movl (%esi), %ebx )
13382 + adcl %ebx, %eax
13383 +-DST( movl %ebx, (%edi) )
13384 ++DST( movl %ebx, %es:(%edi) )
13385 + lea 4(%esi), %esi
13386 + lea 4(%edi), %edi
13387 + dec %edx
13388 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
13389 + jb 5f
13390 + SRC( movw (%esi), %cx )
13391 + leal 2(%esi), %esi
13392 +-DST( movw %cx, (%edi) )
13393 ++DST( movw %cx, %es:(%edi) )
13394 + leal 2(%edi), %edi
13395 + je 6f
13396 + shll $16,%ecx
13397 + SRC(5: movb (%esi), %cl )
13398 +-DST( movb %cl, (%edi) )
13399 ++DST( movb %cl, %es:(%edi) )
13400 + 6: addl %ecx, %eax
13401 + adcl $0, %eax
13402 + 7:
13403 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
13404 +
13405 + 6001:
13406 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
13407 +- movl $-EFAULT, (%ebx)
13408 ++ movl $-EFAULT, %ss:(%ebx)
13409 +
13410 + # zero the complete destination - computing the rest
13411 + # is too much work
13412 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
13413 +
13414 + 6002:
13415 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
13416 +- movl $-EFAULT,(%ebx)
13417 ++ movl $-EFAULT,%ss:(%ebx)
13418 + jmp 5000b
13419 +
13420 + .previous
13421 +
13422 ++ pushl %ss
13423 ++ CFI_ADJUST_CFA_OFFSET 4
13424 ++ popl %ds
13425 ++ CFI_ADJUST_CFA_OFFSET -4
13426 ++ pushl %ss
13427 ++ CFI_ADJUST_CFA_OFFSET 4
13428 ++ popl %es
13429 ++ CFI_ADJUST_CFA_OFFSET -4
13430 + popl %ebx
13431 + CFI_ADJUST_CFA_OFFSET -4
13432 + CFI_RESTORE ebx
13433 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
13434 + CFI_ADJUST_CFA_OFFSET -4
13435 + ret
13436 + CFI_ENDPROC
13437 +-ENDPROC(csum_partial_copy_generic)
13438 ++ENDPROC(csum_partial_copy_generic_to_user)
13439 +
13440 + #else
13441 +
13442 + /* Version for PentiumII/PPro */
13443 +
13444 + #define ROUND1(x) \
13445 ++ nop; nop; nop; \
13446 + SRC(movl x(%esi), %ebx ) ; \
13447 + addl %ebx, %eax ; \
13448 +- DST(movl %ebx, x(%edi) ) ;
13449 ++ DST(movl %ebx, %es:x(%edi)) ;
13450 +
13451 + #define ROUND(x) \
13452 ++ nop; nop; nop; \
13453 + SRC(movl x(%esi), %ebx ) ; \
13454 + adcl %ebx, %eax ; \
13455 +- DST(movl %ebx, x(%edi) ) ;
13456 ++ DST(movl %ebx, %es:x(%edi)) ;
13457 +
13458 + #define ARGBASE 12
13459 +-
13460 +-ENTRY(csum_partial_copy_generic)
13461 ++
13462 ++ENTRY(csum_partial_copy_generic_to_user)
13463 + CFI_STARTPROC
13464 ++ pushl $(__USER_DS)
13465 ++ CFI_ADJUST_CFA_OFFSET 4
13466 ++ popl %es
13467 ++ CFI_ADJUST_CFA_OFFSET -4
13468 ++ jmp csum_partial_copy_generic
13469 ++
13470 ++ENTRY(csum_partial_copy_generic_from_user)
13471 ++ pushl $(__USER_DS)
13472 ++ CFI_ADJUST_CFA_OFFSET 4
13473 ++ popl %ds
13474 ++ CFI_ADJUST_CFA_OFFSET -4
13475 ++
13476 ++ENTRY(csum_partial_copy_generic)
13477 + pushl %ebx
13478 + CFI_ADJUST_CFA_OFFSET 4
13479 + CFI_REL_OFFSET ebx, 0
13480 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
13481 + subl %ebx, %edi
13482 + lea -1(%esi),%edx
13483 + andl $-32,%edx
13484 +- lea 3f(%ebx,%ebx), %ebx
13485 ++ lea 3f(%ebx,%ebx,2), %ebx
13486 + testl %esi, %esi
13487 + jmp *%ebx
13488 + 1: addl $64,%esi
13489 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
13490 + jb 5f
13491 + SRC( movw (%esi), %dx )
13492 + leal 2(%esi), %esi
13493 +-DST( movw %dx, (%edi) )
13494 ++DST( movw %dx, %es:(%edi) )
13495 + leal 2(%edi), %edi
13496 + je 6f
13497 + shll $16,%edx
13498 + 5:
13499 + SRC( movb (%esi), %dl )
13500 +-DST( movb %dl, (%edi) )
13501 ++DST( movb %dl, %es:(%edi) )
13502 + 6: addl %edx, %eax
13503 + adcl $0, %eax
13504 + 7:
13505 + .section .fixup, "ax"
13506 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
13507 +- movl $-EFAULT, (%ebx)
13508 ++ movl $-EFAULT, %ss:(%ebx)
13509 + # zero the complete destination (computing the rest is too much work)
13510 + movl ARGBASE+8(%esp),%edi # dst
13511 + movl ARGBASE+12(%esp),%ecx # len
13512 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
13513 + rep; stosb
13514 + jmp 7b
13515 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
13516 +- movl $-EFAULT, (%ebx)
13517 ++ movl $-EFAULT, %ss:(%ebx)
13518 + jmp 7b
13519 + .previous
13520 +
13521 ++ pushl %ss
13522 ++ CFI_ADJUST_CFA_OFFSET 4
13523 ++ popl %ds
13524 ++ CFI_ADJUST_CFA_OFFSET -4
13525 ++ pushl %ss
13526 ++ CFI_ADJUST_CFA_OFFSET 4
13527 ++ popl %es
13528 ++ CFI_ADJUST_CFA_OFFSET -4
13529 + popl %esi
13530 + CFI_ADJUST_CFA_OFFSET -4
13531 + CFI_RESTORE esi
13532 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
13533 + CFI_RESTORE ebx
13534 + ret
13535 + CFI_ENDPROC
13536 +-ENDPROC(csum_partial_copy_generic)
13537 ++ENDPROC(csum_partial_copy_generic_to_user)
13538 +
13539 + #undef ROUND
13540 + #undef ROUND1
13541 +diff -urNp a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S
13542 +--- a/arch/x86/lib/clear_page_64.S 2008-08-20 11:16:13.000000000 -0700
13543 ++++ b/arch/x86/lib/clear_page_64.S 2008-08-20 18:36:57.000000000 -0700
13544 +@@ -44,7 +44,7 @@ ENDPROC(clear_page)
13545 +
13546 + #include <asm/cpufeature.h>
13547 +
13548 +- .section .altinstr_replacement,"ax"
13549 ++ .section .altinstr_replacement,"a"
13550 + 1: .byte 0xeb /* jmp <disp8> */
13551 + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
13552 + 2:
13553 +diff -urNp a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
13554 +--- a/arch/x86/lib/copy_page_64.S 2008-08-20 11:16:13.000000000 -0700
13555 ++++ b/arch/x86/lib/copy_page_64.S 2008-08-20 18:36:57.000000000 -0700
13556 +@@ -104,7 +104,7 @@ ENDPROC(copy_page)
13557 +
13558 + #include <asm/cpufeature.h>
13559 +
13560 +- .section .altinstr_replacement,"ax"
13561 ++ .section .altinstr_replacement,"a"
13562 + 1: .byte 0xeb /* jmp <disp8> */
13563 + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
13564 + 2:
13565 +diff -urNp a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
13566 +--- a/arch/x86/lib/copy_user_64.S 2008-08-20 11:16:13.000000000 -0700
13567 ++++ b/arch/x86/lib/copy_user_64.S 2008-08-20 18:36:57.000000000 -0700
13568 +@@ -19,7 +19,7 @@
13569 + .byte 0xe9 /* 32bit jump */
13570 + .long \orig-1f /* by default jump to orig */
13571 + 1:
13572 +- .section .altinstr_replacement,"ax"
13573 ++ .section .altinstr_replacement,"a"
13574 + 2: .byte 0xe9 /* near jump with 32bit immediate */
13575 + .long \alt-1b /* offset */ /* or alternatively to alt */
13576 + .previous
13577 +@@ -76,6 +76,8 @@ ENDPROC(copy_from_user)
13578 + /* must zero dest */
13579 + bad_from_user:
13580 + CFI_STARTPROC
13581 ++ testl %edx,%edx
13582 ++ js bad_to_user
13583 + movl %edx,%ecx
13584 + xorl %eax,%eax
13585 + rep
13586 +diff -urNp a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S
13587 +--- a/arch/x86/lib/getuser_32.S 2008-08-20 11:16:13.000000000 -0700
13588 ++++ b/arch/x86/lib/getuser_32.S 2008-08-20 18:36:57.000000000 -0700
13589 +@@ -11,7 +11,7 @@
13590 + #include <linux/linkage.h>
13591 + #include <asm/dwarf2.h>
13592 + #include <asm/thread_info.h>
13593 +-
13594 ++#include <asm/segment.h>
13595 +
13596 + /*
13597 + * __get_user_X
13598 +@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
13599 + GET_THREAD_INFO(%edx)
13600 + cmpl TI_addr_limit(%edx),%eax
13601 + jae bad_get_user
13602 ++ pushl $(__USER_DS)
13603 ++ popl %ds
13604 + 1: movzbl (%eax),%edx
13605 ++ pushl %ss
13606 ++ pop %ds
13607 + xorl %eax,%eax
13608 + ret
13609 + CFI_ENDPROC
13610 +@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
13611 + GET_THREAD_INFO(%edx)
13612 + cmpl TI_addr_limit(%edx),%eax
13613 + jae bad_get_user
13614 ++ pushl $(__USER_DS)
13615 ++ popl %ds
13616 + 2: movzwl -1(%eax),%edx
13617 ++ pushl %ss
13618 ++ pop %ds
13619 + xorl %eax,%eax
13620 + ret
13621 + CFI_ENDPROC
13622 +@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
13623 + GET_THREAD_INFO(%edx)
13624 + cmpl TI_addr_limit(%edx),%eax
13625 + jae bad_get_user
13626 ++ pushl $(__USER_DS)
13627 ++ popl %ds
13628 + 3: movl -3(%eax),%edx
13629 ++ pushl %ss
13630 ++ pop %ds
13631 + xorl %eax,%eax
13632 + ret
13633 + CFI_ENDPROC
13634 +@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
13635 +
13636 + bad_get_user:
13637 + CFI_STARTPROC
13638 ++ pushl %ss
13639 ++ pop %ds
13640 + xorl %edx,%edx
13641 + movl $-14,%eax
13642 + ret
13643 +diff -urNp a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
13644 +--- a/arch/x86/lib/memcpy_64.S 2008-08-20 11:16:13.000000000 -0700
13645 ++++ b/arch/x86/lib/memcpy_64.S 2008-08-20 18:36:57.000000000 -0700
13646 +@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
13647 + /* Some CPUs run faster using the string copy instructions.
13648 + It is also a lot simpler. Use this when possible */
13649 +
13650 +- .section .altinstr_replacement,"ax"
13651 ++ .section .altinstr_replacement,"a"
13652 + 1: .byte 0xeb /* jmp <disp8> */
13653 + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
13654 + 2:
13655 +diff -urNp a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
13656 +--- a/arch/x86/lib/memset_64.S 2008-08-20 11:16:13.000000000 -0700
13657 ++++ b/arch/x86/lib/memset_64.S 2008-08-20 18:36:57.000000000 -0700
13658 +@@ -118,7 +118,7 @@ ENDPROC(__memset)
13659 +
13660 + #include <asm/cpufeature.h>
13661 +
13662 +- .section .altinstr_replacement,"ax"
13663 ++ .section .altinstr_replacement,"a"
13664 + 1: .byte 0xeb /* jmp <disp8> */
13665 + .byte (memset_c - memset) - (2f - 1b) /* offset */
13666 + 2:
13667 +diff -urNp a/arch/x86/lib/mmx_32.c b/arch/x86/lib/mmx_32.c
13668 +--- a/arch/x86/lib/mmx_32.c 2008-08-20 11:16:13.000000000 -0700
13669 ++++ b/arch/x86/lib/mmx_32.c 2008-08-20 18:36:57.000000000 -0700
13670 +@@ -31,6 +31,7 @@ void *_mmx_memcpy(void *to, const void *
13671 + {
13672 + void *p;
13673 + int i;
13674 ++ unsigned long cr0;
13675 +
13676 + if (unlikely(in_interrupt()))
13677 + return __memcpy(to, from, len);
13678 +@@ -41,46 +42,74 @@ void *_mmx_memcpy(void *to, const void *
13679 + kernel_fpu_begin();
13680 +
13681 + __asm__ __volatile__ (
13682 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
13683 +- " prefetch 64(%0)\n"
13684 +- " prefetch 128(%0)\n"
13685 +- " prefetch 192(%0)\n"
13686 +- " prefetch 256(%0)\n"
13687 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
13688 ++ " prefetch 64(%1)\n"
13689 ++ " prefetch 128(%1)\n"
13690 ++ " prefetch 192(%1)\n"
13691 ++ " prefetch 256(%1)\n"
13692 + "2: \n"
13693 + ".section .fixup, \"ax\"\n"
13694 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13695 ++ "3: \n"
13696 ++
13697 ++#ifdef CONFIG_PAX_KERNEXEC
13698 ++ " movl %%cr0, %0\n"
13699 ++ " movl %0, %%eax\n"
13700 ++ " andl $0xFFFEFFFF, %%eax\n"
13701 ++ " movl %%eax, %%cr0\n"
13702 ++#endif
13703 ++
13704 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13705 ++
13706 ++#ifdef CONFIG_PAX_KERNEXEC
13707 ++ " movl %0, %%cr0\n"
13708 ++#endif
13709 ++
13710 + " jmp 2b\n"
13711 + ".previous\n"
13712 + _ASM_EXTABLE(1b,3b)
13713 +- : : "r" (from) );
13714 ++ : "=&r" (cr0) : "r" (from) : "ax");
13715 +
13716 +
13717 + for(; i>5; i--)
13718 + {
13719 + __asm__ __volatile__ (
13720 +- "1: prefetch 320(%0)\n"
13721 +- "2: movq (%0), %%mm0\n"
13722 +- " movq 8(%0), %%mm1\n"
13723 +- " movq 16(%0), %%mm2\n"
13724 +- " movq 24(%0), %%mm3\n"
13725 +- " movq %%mm0, (%1)\n"
13726 +- " movq %%mm1, 8(%1)\n"
13727 +- " movq %%mm2, 16(%1)\n"
13728 +- " movq %%mm3, 24(%1)\n"
13729 +- " movq 32(%0), %%mm0\n"
13730 +- " movq 40(%0), %%mm1\n"
13731 +- " movq 48(%0), %%mm2\n"
13732 +- " movq 56(%0), %%mm3\n"
13733 +- " movq %%mm0, 32(%1)\n"
13734 +- " movq %%mm1, 40(%1)\n"
13735 +- " movq %%mm2, 48(%1)\n"
13736 +- " movq %%mm3, 56(%1)\n"
13737 ++ "1: prefetch 320(%1)\n"
13738 ++ "2: movq (%1), %%mm0\n"
13739 ++ " movq 8(%1), %%mm1\n"
13740 ++ " movq 16(%1), %%mm2\n"
13741 ++ " movq 24(%1), %%mm3\n"
13742 ++ " movq %%mm0, (%2)\n"
13743 ++ " movq %%mm1, 8(%2)\n"
13744 ++ " movq %%mm2, 16(%2)\n"
13745 ++ " movq %%mm3, 24(%2)\n"
13746 ++ " movq 32(%1), %%mm0\n"
13747 ++ " movq 40(%1), %%mm1\n"
13748 ++ " movq 48(%1), %%mm2\n"
13749 ++ " movq 56(%1), %%mm3\n"
13750 ++ " movq %%mm0, 32(%2)\n"
13751 ++ " movq %%mm1, 40(%2)\n"
13752 ++ " movq %%mm2, 48(%2)\n"
13753 ++ " movq %%mm3, 56(%2)\n"
13754 + ".section .fixup, \"ax\"\n"
13755 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13756 ++ "3:\n"
13757 ++
13758 ++#ifdef CONFIG_PAX_KERNEXEC
13759 ++ " movl %%cr0, %0\n"
13760 ++ " movl %0, %%eax\n"
13761 ++ " andl $0xFFFEFFFF, %%eax\n"
13762 ++ " movl %%eax, %%cr0\n"
13763 ++#endif
13764 ++
13765 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13766 ++
13767 ++#ifdef CONFIG_PAX_KERNEXEC
13768 ++ " movl %0, %%cr0\n"
13769 ++#endif
13770 ++
13771 + " jmp 2b\n"
13772 + ".previous\n"
13773 + _ASM_EXTABLE(1b,3b)
13774 +- : : "r" (from), "r" (to) : "memory");
13775 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13776 + from+=64;
13777 + to+=64;
13778 + }
13779 +@@ -159,6 +188,7 @@ static void fast_clear_page(void *page)
13780 + static void fast_copy_page(void *to, void *from)
13781 + {
13782 + int i;
13783 ++ unsigned long cr0;
13784 +
13785 + kernel_fpu_begin();
13786 +
13787 +@@ -166,45 +196,73 @@ static void fast_copy_page(void *to, voi
13788 + * but that is for later. -AV
13789 + */
13790 + __asm__ __volatile__ (
13791 +- "1: prefetch (%0)\n"
13792 +- " prefetch 64(%0)\n"
13793 +- " prefetch 128(%0)\n"
13794 +- " prefetch 192(%0)\n"
13795 +- " prefetch 256(%0)\n"
13796 ++ "1: prefetch (%1)\n"
13797 ++ " prefetch 64(%1)\n"
13798 ++ " prefetch 128(%1)\n"
13799 ++ " prefetch 192(%1)\n"
13800 ++ " prefetch 256(%1)\n"
13801 + "2: \n"
13802 + ".section .fixup, \"ax\"\n"
13803 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13804 ++ "3: \n"
13805 ++
13806 ++#ifdef CONFIG_PAX_KERNEXEC
13807 ++ " movl %%cr0, %0\n"
13808 ++ " movl %0, %%eax\n"
13809 ++ " andl $0xFFFEFFFF, %%eax\n"
13810 ++ " movl %%eax, %%cr0\n"
13811 ++#endif
13812 ++
13813 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13814 ++
13815 ++#ifdef CONFIG_PAX_KERNEXEC
13816 ++ " movl %0, %%cr0\n"
13817 ++#endif
13818 ++
13819 + " jmp 2b\n"
13820 + ".previous\n"
13821 + _ASM_EXTABLE(1b,3b)
13822 +- : : "r" (from) );
13823 ++ : "=&r" (cr0) : "r" (from) : "ax");
13824 +
13825 + for(i=0; i<(4096-320)/64; i++)
13826 + {
13827 + __asm__ __volatile__ (
13828 +- "1: prefetch 320(%0)\n"
13829 +- "2: movq (%0), %%mm0\n"
13830 +- " movntq %%mm0, (%1)\n"
13831 +- " movq 8(%0), %%mm1\n"
13832 +- " movntq %%mm1, 8(%1)\n"
13833 +- " movq 16(%0), %%mm2\n"
13834 +- " movntq %%mm2, 16(%1)\n"
13835 +- " movq 24(%0), %%mm3\n"
13836 +- " movntq %%mm3, 24(%1)\n"
13837 +- " movq 32(%0), %%mm4\n"
13838 +- " movntq %%mm4, 32(%1)\n"
13839 +- " movq 40(%0), %%mm5\n"
13840 +- " movntq %%mm5, 40(%1)\n"
13841 +- " movq 48(%0), %%mm6\n"
13842 +- " movntq %%mm6, 48(%1)\n"
13843 +- " movq 56(%0), %%mm7\n"
13844 +- " movntq %%mm7, 56(%1)\n"
13845 ++ "1: prefetch 320(%1)\n"
13846 ++ "2: movq (%1), %%mm0\n"
13847 ++ " movntq %%mm0, (%2)\n"
13848 ++ " movq 8(%1), %%mm1\n"
13849 ++ " movntq %%mm1, 8(%2)\n"
13850 ++ " movq 16(%1), %%mm2\n"
13851 ++ " movntq %%mm2, 16(%2)\n"
13852 ++ " movq 24(%1), %%mm3\n"
13853 ++ " movntq %%mm3, 24(%2)\n"
13854 ++ " movq 32(%1), %%mm4\n"
13855 ++ " movntq %%mm4, 32(%2)\n"
13856 ++ " movq 40(%1), %%mm5\n"
13857 ++ " movntq %%mm5, 40(%2)\n"
13858 ++ " movq 48(%1), %%mm6\n"
13859 ++ " movntq %%mm6, 48(%2)\n"
13860 ++ " movq 56(%1), %%mm7\n"
13861 ++ " movntq %%mm7, 56(%2)\n"
13862 + ".section .fixup, \"ax\"\n"
13863 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13864 ++ "3:\n"
13865 ++
13866 ++#ifdef CONFIG_PAX_KERNEXEC
13867 ++ " movl %%cr0, %0\n"
13868 ++ " movl %0, %%eax\n"
13869 ++ " andl $0xFFFEFFFF, %%eax\n"
13870 ++ " movl %%eax, %%cr0\n"
13871 ++#endif
13872 ++
13873 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13874 ++
13875 ++#ifdef CONFIG_PAX_KERNEXEC
13876 ++ " movl %0, %%cr0\n"
13877 ++#endif
13878 ++
13879 + " jmp 2b\n"
13880 + ".previous\n"
13881 + _ASM_EXTABLE(1b,3b)
13882 +- : : "r" (from), "r" (to) : "memory");
13883 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13884 + from+=64;
13885 + to+=64;
13886 + }
13887 +@@ -285,50 +343,78 @@ static void fast_clear_page(void *page)
13888 + static void fast_copy_page(void *to, void *from)
13889 + {
13890 + int i;
13891 +-
13892 +-
13893 ++ unsigned long cr0;
13894 ++
13895 + kernel_fpu_begin();
13896 +
13897 + __asm__ __volatile__ (
13898 +- "1: prefetch (%0)\n"
13899 +- " prefetch 64(%0)\n"
13900 +- " prefetch 128(%0)\n"
13901 +- " prefetch 192(%0)\n"
13902 +- " prefetch 256(%0)\n"
13903 ++ "1: prefetch (%1)\n"
13904 ++ " prefetch 64(%1)\n"
13905 ++ " prefetch 128(%1)\n"
13906 ++ " prefetch 192(%1)\n"
13907 ++ " prefetch 256(%1)\n"
13908 + "2: \n"
13909 + ".section .fixup, \"ax\"\n"
13910 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13911 ++ "3: \n"
13912 ++
13913 ++#ifdef CONFIG_PAX_KERNEXEC
13914 ++ " movl %%cr0, %0\n"
13915 ++ " movl %0, %%eax\n"
13916 ++ " andl $0xFFFEFFFF, %%eax\n"
13917 ++ " movl %%eax, %%cr0\n"
13918 ++#endif
13919 ++
13920 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13921 ++
13922 ++#ifdef CONFIG_PAX_KERNEXEC
13923 ++ " movl %0, %%cr0\n"
13924 ++#endif
13925 ++
13926 + " jmp 2b\n"
13927 + ".previous\n"
13928 + _ASM_EXTABLE(1b,3b)
13929 +- : : "r" (from) );
13930 ++ : "=&r" (cr0) : "r" (from) : "ax");
13931 +
13932 + for(i=0; i<4096/64; i++)
13933 + {
13934 + __asm__ __volatile__ (
13935 +- "1: prefetch 320(%0)\n"
13936 +- "2: movq (%0), %%mm0\n"
13937 +- " movq 8(%0), %%mm1\n"
13938 +- " movq 16(%0), %%mm2\n"
13939 +- " movq 24(%0), %%mm3\n"
13940 +- " movq %%mm0, (%1)\n"
13941 +- " movq %%mm1, 8(%1)\n"
13942 +- " movq %%mm2, 16(%1)\n"
13943 +- " movq %%mm3, 24(%1)\n"
13944 +- " movq 32(%0), %%mm0\n"
13945 +- " movq 40(%0), %%mm1\n"
13946 +- " movq 48(%0), %%mm2\n"
13947 +- " movq 56(%0), %%mm3\n"
13948 +- " movq %%mm0, 32(%1)\n"
13949 +- " movq %%mm1, 40(%1)\n"
13950 +- " movq %%mm2, 48(%1)\n"
13951 +- " movq %%mm3, 56(%1)\n"
13952 ++ "1: prefetch 320(%1)\n"
13953 ++ "2: movq (%1), %%mm0\n"
13954 ++ " movq 8(%1), %%mm1\n"
13955 ++ " movq 16(%1), %%mm2\n"
13956 ++ " movq 24(%1), %%mm3\n"
13957 ++ " movq %%mm0, (%2)\n"
13958 ++ " movq %%mm1, 8(%2)\n"
13959 ++ " movq %%mm2, 16(%2)\n"
13960 ++ " movq %%mm3, 24(%2)\n"
13961 ++ " movq 32(%1), %%mm0\n"
13962 ++ " movq 40(%1), %%mm1\n"
13963 ++ " movq 48(%1), %%mm2\n"
13964 ++ " movq 56(%1), %%mm3\n"
13965 ++ " movq %%mm0, 32(%2)\n"
13966 ++ " movq %%mm1, 40(%2)\n"
13967 ++ " movq %%mm2, 48(%2)\n"
13968 ++ " movq %%mm3, 56(%2)\n"
13969 + ".section .fixup, \"ax\"\n"
13970 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13971 ++ "3:\n"
13972 ++
13973 ++#ifdef CONFIG_PAX_KERNEXEC
13974 ++ " movl %%cr0, %0\n"
13975 ++ " movl %0, %%eax\n"
13976 ++ " andl $0xFFFEFFFF, %%eax\n"
13977 ++ " movl %%eax, %%cr0\n"
13978 ++#endif
13979 ++
13980 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13981 ++
13982 ++#ifdef CONFIG_PAX_KERNEXEC
13983 ++ " movl %0, %%cr0\n"
13984 ++#endif
13985 ++
13986 + " jmp 2b\n"
13987 + ".previous\n"
13988 + _ASM_EXTABLE(1b,3b)
13989 +- : : "r" (from), "r" (to) : "memory");
13990 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13991 + from+=64;
13992 + to+=64;
13993 + }
13994 +diff -urNp a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser_32.S
13995 +--- a/arch/x86/lib/putuser_32.S 2008-08-20 11:16:13.000000000 -0700
13996 ++++ b/arch/x86/lib/putuser_32.S 2008-08-20 18:36:57.000000000 -0700
13997 +@@ -11,7 +11,7 @@
13998 + #include <linux/linkage.h>
13999 + #include <asm/dwarf2.h>
14000 + #include <asm/thread_info.h>
14001 +-
14002 ++#include <asm/segment.h>
14003 +
14004 + /*
14005 + * __put_user_X
14006 +@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
14007 + ENTER
14008 + cmpl TI_addr_limit(%ebx),%ecx
14009 + jae bad_put_user
14010 ++ pushl $(__USER_DS)
14011 ++ popl %ds
14012 + 1: movb %al,(%ecx)
14013 ++ pushl %ss
14014 ++ popl %ds
14015 + xorl %eax,%eax
14016 + EXIT
14017 + ENDPROC(__put_user_1)
14018 +@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
14019 + subl $1,%ebx
14020 + cmpl %ebx,%ecx
14021 + jae bad_put_user
14022 ++ pushl $(__USER_DS)
14023 ++ popl %ds
14024 + 2: movw %ax,(%ecx)
14025 ++ pushl %ss
14026 ++ popl %ds
14027 + xorl %eax,%eax
14028 + EXIT
14029 + ENDPROC(__put_user_2)
14030 +@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
14031 + subl $3,%ebx
14032 + cmpl %ebx,%ecx
14033 + jae bad_put_user
14034 ++ pushl $(__USER_DS)
14035 ++ popl %ds
14036 + 3: movl %eax,(%ecx)
14037 ++ pushl %ss
14038 ++ popl %ds
14039 + xorl %eax,%eax
14040 + EXIT
14041 + ENDPROC(__put_user_4)
14042 +@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
14043 + subl $7,%ebx
14044 + cmpl %ebx,%ecx
14045 + jae bad_put_user
14046 ++ pushl $(__USER_DS)
14047 ++ popl %ds
14048 + 4: movl %eax,(%ecx)
14049 + 5: movl %edx,4(%ecx)
14050 ++ pushl %ss
14051 ++ popl %ds
14052 + xorl %eax,%eax
14053 + EXIT
14054 + ENDPROC(__put_user_8)
14055 +@@ -85,6 +101,10 @@ bad_put_user:
14056 + CFI_DEF_CFA esp, 2*4
14057 + CFI_OFFSET eip, -1*4
14058 + CFI_OFFSET ebx, -2*4
14059 ++ pushl %ss
14060 ++ CFI_ADJUST_CFA_OFFSET 4
14061 ++ popl %ds
14062 ++ CFI_ADJUST_CFA_OFFSET -4
14063 + movl $-14,%eax
14064 + EXIT
14065 + END(bad_put_user)
14066 +diff -urNp a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
14067 +--- a/arch/x86/lib/usercopy_32.c 2008-08-20 11:16:13.000000000 -0700
14068 ++++ b/arch/x86/lib/usercopy_32.c 2008-08-20 18:36:57.000000000 -0700
14069 +@@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
14070 + * Copy a null terminated string from userspace.
14071 + */
14072 +
14073 +-#define __do_strncpy_from_user(dst,src,count,res) \
14074 +-do { \
14075 +- int __d0, __d1, __d2; \
14076 +- might_sleep(); \
14077 +- __asm__ __volatile__( \
14078 +- " testl %1,%1\n" \
14079 +- " jz 2f\n" \
14080 +- "0: lodsb\n" \
14081 +- " stosb\n" \
14082 +- " testb %%al,%%al\n" \
14083 +- " jz 1f\n" \
14084 +- " decl %1\n" \
14085 +- " jnz 0b\n" \
14086 +- "1: subl %1,%0\n" \
14087 +- "2:\n" \
14088 +- ".section .fixup,\"ax\"\n" \
14089 +- "3: movl %5,%0\n" \
14090 +- " jmp 2b\n" \
14091 +- ".previous\n" \
14092 +- _ASM_EXTABLE(0b,3b) \
14093 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
14094 +- "=&D" (__d2) \
14095 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
14096 +- : "memory"); \
14097 +-} while (0)
14098 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
14099 ++{
14100 ++ int __d0, __d1, __d2;
14101 ++ long res = -EFAULT;
14102 ++
14103 ++ might_sleep();
14104 ++ __asm__ __volatile__(
14105 ++ " movw %w10,%%ds\n"
14106 ++ " testl %1,%1\n"
14107 ++ " jz 2f\n"
14108 ++ "0: lodsb\n"
14109 ++ " stosb\n"
14110 ++ " testb %%al,%%al\n"
14111 ++ " jz 1f\n"
14112 ++ " decl %1\n"
14113 ++ " jnz 0b\n"
14114 ++ "1: subl %1,%0\n"
14115 ++ "2:\n"
14116 ++ " pushl %%ss\n"
14117 ++ " popl %%ds\n"
14118 ++ ".section .fixup,\"ax\"\n"
14119 ++ "3: movl %5,%0\n"
14120 ++ " jmp 2b\n"
14121 ++ ".previous\n"
14122 ++ _ASM_EXTABLE(0b,3b)
14123 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
14124 ++ "=&D" (__d2)
14125 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
14126 ++ "r"(__USER_DS)
14127 ++ : "memory");
14128 ++ return res;
14129 ++}
14130 +
14131 + /**
14132 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
14133 +@@ -78,9 +85,7 @@ do { \
14134 + long
14135 + __strncpy_from_user(char *dst, const char __user *src, long count)
14136 + {
14137 +- long res;
14138 +- __do_strncpy_from_user(dst, src, count, res);
14139 +- return res;
14140 ++ return __do_strncpy_from_user(dst, src, count);
14141 + }
14142 + EXPORT_SYMBOL(__strncpy_from_user);
14143 +
14144 +@@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
14145 + {
14146 + long res = -EFAULT;
14147 + if (access_ok(VERIFY_READ, src, 1))
14148 +- __do_strncpy_from_user(dst, src, count, res);
14149 ++ res = __do_strncpy_from_user(dst, src, count);
14150 + return res;
14151 + }
14152 + EXPORT_SYMBOL(strncpy_from_user);
14153 +@@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
14154 + * Zero Userspace
14155 + */
14156 +
14157 +-#define __do_clear_user(addr,size) \
14158 +-do { \
14159 +- int __d0; \
14160 +- might_sleep(); \
14161 +- __asm__ __volatile__( \
14162 +- "0: rep; stosl\n" \
14163 +- " movl %2,%0\n" \
14164 +- "1: rep; stosb\n" \
14165 +- "2:\n" \
14166 +- ".section .fixup,\"ax\"\n" \
14167 +- "3: lea 0(%2,%0,4),%0\n" \
14168 +- " jmp 2b\n" \
14169 +- ".previous\n" \
14170 +- _ASM_EXTABLE(0b,3b) \
14171 +- _ASM_EXTABLE(1b,2b) \
14172 +- : "=&c"(size), "=&D" (__d0) \
14173 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
14174 +-} while (0)
14175 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
14176 ++{
14177 ++ int __d0;
14178 ++
14179 ++ might_sleep();
14180 ++ __asm__ __volatile__(
14181 ++ " movw %w6,%%es\n"
14182 ++ "0: rep; stosl\n"
14183 ++ " movl %2,%0\n"
14184 ++ "1: rep; stosb\n"
14185 ++ "2:\n"
14186 ++ " pushl %%ss\n"
14187 ++ " popl %%es\n"
14188 ++ ".section .fixup,\"ax\"\n"
14189 ++ "3: lea 0(%2,%0,4),%0\n"
14190 ++ " jmp 2b\n"
14191 ++ ".previous\n"
14192 ++ _ASM_EXTABLE(0b,3b)
14193 ++ _ASM_EXTABLE(1b,2b)
14194 ++ : "=&c"(size), "=&D" (__d0)
14195 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
14196 ++ "r"(__USER_DS));
14197 ++ return size;
14198 ++}
14199 +
14200 + /**
14201 + * clear_user: - Zero a block of memory in user space.
14202 +@@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
14203 + {
14204 + might_sleep();
14205 + if (access_ok(VERIFY_WRITE, to, n))
14206 +- __do_clear_user(to, n);
14207 ++ n = __do_clear_user(to, n);
14208 + return n;
14209 + }
14210 + EXPORT_SYMBOL(clear_user);
14211 +@@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
14212 + unsigned long
14213 + __clear_user(void __user *to, unsigned long n)
14214 + {
14215 +- __do_clear_user(to, n);
14216 +- return n;
14217 ++ return __do_clear_user(to, n);
14218 + }
14219 + EXPORT_SYMBOL(__clear_user);
14220 +
14221 +@@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
14222 + might_sleep();
14223 +
14224 + __asm__ __volatile__(
14225 ++ " movw %w8,%%es\n"
14226 + " testl %0, %0\n"
14227 + " jz 3f\n"
14228 +- " andl %0,%%ecx\n"
14229 ++ " movl %0,%%ecx\n"
14230 + "0: repne; scasb\n"
14231 + " setne %%al\n"
14232 + " subl %%ecx,%0\n"
14233 + " addl %0,%%eax\n"
14234 + "1:\n"
14235 ++ " pushl %%ss\n"
14236 ++ " popl %%es\n"
14237 + ".section .fixup,\"ax\"\n"
14238 + "2: xorl %%eax,%%eax\n"
14239 + " jmp 1b\n"
14240 +@@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
14241 + " .long 0b,2b\n"
14242 + ".previous"
14243 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
14244 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
14245 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
14246 + :"cc");
14247 + return res & mask;
14248 + }
14249 +@@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
14250 +
14251 + #ifdef CONFIG_X86_INTEL_USERCOPY
14252 + static unsigned long
14253 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
14254 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
14255 + {
14256 + int d0, d1;
14257 + __asm__ __volatile__(
14258 ++ " movw %w6, %%es\n"
14259 + " .align 2,0x90\n"
14260 + "1: movl 32(%4), %%eax\n"
14261 + " cmpl $67, %0\n"
14262 +@@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
14263 + " .align 2,0x90\n"
14264 + "3: movl 0(%4), %%eax\n"
14265 + "4: movl 4(%4), %%edx\n"
14266 +- "5: movl %%eax, 0(%3)\n"
14267 +- "6: movl %%edx, 4(%3)\n"
14268 ++ "5: movl %%eax, %%es:0(%3)\n"
14269 ++ "6: movl %%edx, %%es:4(%3)\n"
14270 + "7: movl 8(%4), %%eax\n"
14271 + "8: movl 12(%4),%%edx\n"
14272 +- "9: movl %%eax, 8(%3)\n"
14273 +- "10: movl %%edx, 12(%3)\n"
14274 ++ "9: movl %%eax, %%es:8(%3)\n"
14275 ++ "10: movl %%edx, %%es:12(%3)\n"
14276 + "11: movl 16(%4), %%eax\n"
14277 + "12: movl 20(%4), %%edx\n"
14278 +- "13: movl %%eax, 16(%3)\n"
14279 +- "14: movl %%edx, 20(%3)\n"
14280 ++ "13: movl %%eax, %%es:16(%3)\n"
14281 ++ "14: movl %%edx, %%es:20(%3)\n"
14282 + "15: movl 24(%4), %%eax\n"
14283 + "16: movl 28(%4), %%edx\n"
14284 +- "17: movl %%eax, 24(%3)\n"
14285 +- "18: movl %%edx, 28(%3)\n"
14286 ++ "17: movl %%eax, %%es:24(%3)\n"
14287 ++ "18: movl %%edx, %%es:28(%3)\n"
14288 + "19: movl 32(%4), %%eax\n"
14289 + "20: movl 36(%4), %%edx\n"
14290 +- "21: movl %%eax, 32(%3)\n"
14291 +- "22: movl %%edx, 36(%3)\n"
14292 ++ "21: movl %%eax, %%es:32(%3)\n"
14293 ++ "22: movl %%edx, %%es:36(%3)\n"
14294 + "23: movl 40(%4), %%eax\n"
14295 + "24: movl 44(%4), %%edx\n"
14296 +- "25: movl %%eax, 40(%3)\n"
14297 +- "26: movl %%edx, 44(%3)\n"
14298 ++ "25: movl %%eax, %%es:40(%3)\n"
14299 ++ "26: movl %%edx, %%es:44(%3)\n"
14300 + "27: movl 48(%4), %%eax\n"
14301 + "28: movl 52(%4), %%edx\n"
14302 +- "29: movl %%eax, 48(%3)\n"
14303 +- "30: movl %%edx, 52(%3)\n"
14304 ++ "29: movl %%eax, %%es:48(%3)\n"
14305 ++ "30: movl %%edx, %%es:52(%3)\n"
14306 + "31: movl 56(%4), %%eax\n"
14307 + "32: movl 60(%4), %%edx\n"
14308 +- "33: movl %%eax, 56(%3)\n"
14309 +- "34: movl %%edx, 60(%3)\n"
14310 ++ "33: movl %%eax, %%es:56(%3)\n"
14311 ++ "34: movl %%edx, %%es:60(%3)\n"
14312 + " addl $-64, %0\n"
14313 + " addl $64, %4\n"
14314 + " addl $64, %3\n"
14315 +@@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
14316 + "36: movl %%eax, %0\n"
14317 + "37: rep; movsb\n"
14318 + "100:\n"
14319 ++ " pushl %%ss\n"
14320 ++ " popl %%es\n"
14321 + ".section .fixup,\"ax\"\n"
14322 + "101: lea 0(%%eax,%0,4),%0\n"
14323 + " jmp 100b\n"
14324 +@@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
14325 + " .long 99b,101b\n"
14326 + ".previous"
14327 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14328 +- : "1"(to), "2"(from), "0"(size)
14329 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14330 ++ : "eax", "edx", "memory");
14331 ++ return size;
14332 ++}
14333 ++
14334 ++static unsigned long
14335 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
14336 ++{
14337 ++ int d0, d1;
14338 ++ __asm__ __volatile__(
14339 ++ " movw %w6, %%ds\n"
14340 ++ " .align 2,0x90\n"
14341 ++ "1: movl 32(%4), %%eax\n"
14342 ++ " cmpl $67, %0\n"
14343 ++ " jbe 3f\n"
14344 ++ "2: movl 64(%4), %%eax\n"
14345 ++ " .align 2,0x90\n"
14346 ++ "3: movl 0(%4), %%eax\n"
14347 ++ "4: movl 4(%4), %%edx\n"
14348 ++ "5: movl %%eax, %%es:0(%3)\n"
14349 ++ "6: movl %%edx, %%es:4(%3)\n"
14350 ++ "7: movl 8(%4), %%eax\n"
14351 ++ "8: movl 12(%4),%%edx\n"
14352 ++ "9: movl %%eax, %%es:8(%3)\n"
14353 ++ "10: movl %%edx, %%es:12(%3)\n"
14354 ++ "11: movl 16(%4), %%eax\n"
14355 ++ "12: movl 20(%4), %%edx\n"
14356 ++ "13: movl %%eax, %%es:16(%3)\n"
14357 ++ "14: movl %%edx, %%es:20(%3)\n"
14358 ++ "15: movl 24(%4), %%eax\n"
14359 ++ "16: movl 28(%4), %%edx\n"
14360 ++ "17: movl %%eax, %%es:24(%3)\n"
14361 ++ "18: movl %%edx, %%es:28(%3)\n"
14362 ++ "19: movl 32(%4), %%eax\n"
14363 ++ "20: movl 36(%4), %%edx\n"
14364 ++ "21: movl %%eax, %%es:32(%3)\n"
14365 ++ "22: movl %%edx, %%es:36(%3)\n"
14366 ++ "23: movl 40(%4), %%eax\n"
14367 ++ "24: movl 44(%4), %%edx\n"
14368 ++ "25: movl %%eax, %%es:40(%3)\n"
14369 ++ "26: movl %%edx, %%es:44(%3)\n"
14370 ++ "27: movl 48(%4), %%eax\n"
14371 ++ "28: movl 52(%4), %%edx\n"
14372 ++ "29: movl %%eax, %%es:48(%3)\n"
14373 ++ "30: movl %%edx, %%es:52(%3)\n"
14374 ++ "31: movl 56(%4), %%eax\n"
14375 ++ "32: movl 60(%4), %%edx\n"
14376 ++ "33: movl %%eax, %%es:56(%3)\n"
14377 ++ "34: movl %%edx, %%es:60(%3)\n"
14378 ++ " addl $-64, %0\n"
14379 ++ " addl $64, %4\n"
14380 ++ " addl $64, %3\n"
14381 ++ " cmpl $63, %0\n"
14382 ++ " ja 1b\n"
14383 ++ "35: movl %0, %%eax\n"
14384 ++ " shrl $2, %0\n"
14385 ++ " andl $3, %%eax\n"
14386 ++ " cld\n"
14387 ++ "99: rep; movsl\n"
14388 ++ "36: movl %%eax, %0\n"
14389 ++ "37: rep; movsb\n"
14390 ++ "100:\n"
14391 ++ " pushl %%ss\n"
14392 ++ " popl %%ds\n"
14393 ++ ".section .fixup,\"ax\"\n"
14394 ++ "101: lea 0(%%eax,%0,4),%0\n"
14395 ++ " jmp 100b\n"
14396 ++ ".previous\n"
14397 ++ ".section __ex_table,\"a\"\n"
14398 ++ " .align 4\n"
14399 ++ " .long 1b,100b\n"
14400 ++ " .long 2b,100b\n"
14401 ++ " .long 3b,100b\n"
14402 ++ " .long 4b,100b\n"
14403 ++ " .long 5b,100b\n"
14404 ++ " .long 6b,100b\n"
14405 ++ " .long 7b,100b\n"
14406 ++ " .long 8b,100b\n"
14407 ++ " .long 9b,100b\n"
14408 ++ " .long 10b,100b\n"
14409 ++ " .long 11b,100b\n"
14410 ++ " .long 12b,100b\n"
14411 ++ " .long 13b,100b\n"
14412 ++ " .long 14b,100b\n"
14413 ++ " .long 15b,100b\n"
14414 ++ " .long 16b,100b\n"
14415 ++ " .long 17b,100b\n"
14416 ++ " .long 18b,100b\n"
14417 ++ " .long 19b,100b\n"
14418 ++ " .long 20b,100b\n"
14419 ++ " .long 21b,100b\n"
14420 ++ " .long 22b,100b\n"
14421 ++ " .long 23b,100b\n"
14422 ++ " .long 24b,100b\n"
14423 ++ " .long 25b,100b\n"
14424 ++ " .long 26b,100b\n"
14425 ++ " .long 27b,100b\n"
14426 ++ " .long 28b,100b\n"
14427 ++ " .long 29b,100b\n"
14428 ++ " .long 30b,100b\n"
14429 ++ " .long 31b,100b\n"
14430 ++ " .long 32b,100b\n"
14431 ++ " .long 33b,100b\n"
14432 ++ " .long 34b,100b\n"
14433 ++ " .long 35b,100b\n"
14434 ++ " .long 36b,100b\n"
14435 ++ " .long 37b,100b\n"
14436 ++ " .long 99b,101b\n"
14437 ++ ".previous"
14438 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
14439 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14440 + : "eax", "edx", "memory");
14441 + return size;
14442 + }
14443 +@@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
14444 + {
14445 + int d0, d1;
14446 + __asm__ __volatile__(
14447 ++ " movw %w6, %%ds\n"
14448 + " .align 2,0x90\n"
14449 + "0: movl 32(%4), %%eax\n"
14450 + " cmpl $67, %0\n"
14451 +@@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
14452 + " .align 2,0x90\n"
14453 + "2: movl 0(%4), %%eax\n"
14454 + "21: movl 4(%4), %%edx\n"
14455 +- " movl %%eax, 0(%3)\n"
14456 +- " movl %%edx, 4(%3)\n"
14457 ++ " movl %%eax, %%es:0(%3)\n"
14458 ++ " movl %%edx, %%es:4(%3)\n"
14459 + "3: movl 8(%4), %%eax\n"
14460 + "31: movl 12(%4),%%edx\n"
14461 +- " movl %%eax, 8(%3)\n"
14462 +- " movl %%edx, 12(%3)\n"
14463 ++ " movl %%eax, %%es:8(%3)\n"
14464 ++ " movl %%edx, %%es:12(%3)\n"
14465 + "4: movl 16(%4), %%eax\n"
14466 + "41: movl 20(%4), %%edx\n"
14467 +- " movl %%eax, 16(%3)\n"
14468 +- " movl %%edx, 20(%3)\n"
14469 ++ " movl %%eax, %%es:16(%3)\n"
14470 ++ " movl %%edx, %%es:20(%3)\n"
14471 + "10: movl 24(%4), %%eax\n"
14472 + "51: movl 28(%4), %%edx\n"
14473 +- " movl %%eax, 24(%3)\n"
14474 +- " movl %%edx, 28(%3)\n"
14475 ++ " movl %%eax, %%es:24(%3)\n"
14476 ++ " movl %%edx, %%es:28(%3)\n"
14477 + "11: movl 32(%4), %%eax\n"
14478 + "61: movl 36(%4), %%edx\n"
14479 +- " movl %%eax, 32(%3)\n"
14480 +- " movl %%edx, 36(%3)\n"
14481 ++ " movl %%eax, %%es:32(%3)\n"
14482 ++ " movl %%edx, %%es:36(%3)\n"
14483 + "12: movl 40(%4), %%eax\n"
14484 + "71: movl 44(%4), %%edx\n"
14485 +- " movl %%eax, 40(%3)\n"
14486 +- " movl %%edx, 44(%3)\n"
14487 ++ " movl %%eax, %%es:40(%3)\n"
14488 ++ " movl %%edx, %%es:44(%3)\n"
14489 + "13: movl 48(%4), %%eax\n"
14490 + "81: movl 52(%4), %%edx\n"
14491 +- " movl %%eax, 48(%3)\n"
14492 +- " movl %%edx, 52(%3)\n"
14493 ++ " movl %%eax, %%es:48(%3)\n"
14494 ++ " movl %%edx, %%es:52(%3)\n"
14495 + "14: movl 56(%4), %%eax\n"
14496 + "91: movl 60(%4), %%edx\n"
14497 +- " movl %%eax, 56(%3)\n"
14498 +- " movl %%edx, 60(%3)\n"
14499 ++ " movl %%eax, %%es:56(%3)\n"
14500 ++ " movl %%edx, %%es:60(%3)\n"
14501 + " addl $-64, %0\n"
14502 + " addl $64, %4\n"
14503 + " addl $64, %3\n"
14504 +@@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
14505 + " movl %%eax,%0\n"
14506 + "7: rep; movsb\n"
14507 + "8:\n"
14508 ++ " pushl %%ss\n"
14509 ++ " popl %%ds\n"
14510 + ".section .fixup,\"ax\"\n"
14511 + "9: lea 0(%%eax,%0,4),%0\n"
14512 + "16: pushl %0\n"
14513 +@@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
14514 + " .long 7b,16b\n"
14515 + ".previous"
14516 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14517 +- : "1"(to), "2"(from), "0"(size)
14518 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14519 + : "eax", "edx", "memory");
14520 + return size;
14521 + }
14522 +@@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
14523 + int d0, d1;
14524 +
14525 + __asm__ __volatile__(
14526 ++ " movw %w6, %%ds\n"
14527 + " .align 2,0x90\n"
14528 + "0: movl 32(%4), %%eax\n"
14529 + " cmpl $67, %0\n"
14530 +@@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
14531 + " .align 2,0x90\n"
14532 + "2: movl 0(%4), %%eax\n"
14533 + "21: movl 4(%4), %%edx\n"
14534 +- " movnti %%eax, 0(%3)\n"
14535 +- " movnti %%edx, 4(%3)\n"
14536 ++ " movnti %%eax, %%es:0(%3)\n"
14537 ++ " movnti %%edx, %%es:4(%3)\n"
14538 + "3: movl 8(%4), %%eax\n"
14539 + "31: movl 12(%4),%%edx\n"
14540 +- " movnti %%eax, 8(%3)\n"
14541 +- " movnti %%edx, 12(%3)\n"
14542 ++ " movnti %%eax, %%es:8(%3)\n"
14543 ++ " movnti %%edx, %%es:12(%3)\n"
14544 + "4: movl 16(%4), %%eax\n"
14545 + "41: movl 20(%4), %%edx\n"
14546 +- " movnti %%eax, 16(%3)\n"
14547 +- " movnti %%edx, 20(%3)\n"
14548 ++ " movnti %%eax, %%es:16(%3)\n"
14549 ++ " movnti %%edx, %%es:20(%3)\n"
14550 + "10: movl 24(%4), %%eax\n"
14551 + "51: movl 28(%4), %%edx\n"
14552 +- " movnti %%eax, 24(%3)\n"
14553 +- " movnti %%edx, 28(%3)\n"
14554 ++ " movnti %%eax, %%es:24(%3)\n"
14555 ++ " movnti %%edx, %%es:28(%3)\n"
14556 + "11: movl 32(%4), %%eax\n"
14557 + "61: movl 36(%4), %%edx\n"
14558 +- " movnti %%eax, 32(%3)\n"
14559 +- " movnti %%edx, 36(%3)\n"
14560 ++ " movnti %%eax, %%es:32(%3)\n"
14561 ++ " movnti %%edx, %%es:36(%3)\n"
14562 + "12: movl 40(%4), %%eax\n"
14563 + "71: movl 44(%4), %%edx\n"
14564 +- " movnti %%eax, 40(%3)\n"
14565 +- " movnti %%edx, 44(%3)\n"
14566 ++ " movnti %%eax, %%es:40(%3)\n"
14567 ++ " movnti %%edx, %%es:44(%3)\n"
14568 + "13: movl 48(%4), %%eax\n"
14569 + "81: movl 52(%4), %%edx\n"
14570 +- " movnti %%eax, 48(%3)\n"
14571 +- " movnti %%edx, 52(%3)\n"
14572 ++ " movnti %%eax, %%es:48(%3)\n"
14573 ++ " movnti %%edx, %%es:52(%3)\n"
14574 + "14: movl 56(%4), %%eax\n"
14575 + "91: movl 60(%4), %%edx\n"
14576 +- " movnti %%eax, 56(%3)\n"
14577 +- " movnti %%edx, 60(%3)\n"
14578 ++ " movnti %%eax, %%es:56(%3)\n"
14579 ++ " movnti %%edx, %%es:60(%3)\n"
14580 + " addl $-64, %0\n"
14581 + " addl $64, %4\n"
14582 + " addl $64, %3\n"
14583 +@@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
14584 + " movl %%eax,%0\n"
14585 + "7: rep; movsb\n"
14586 + "8:\n"
14587 ++ " pushl %%ss\n"
14588 ++ " popl %%ds\n"
14589 + ".section .fixup,\"ax\"\n"
14590 + "9: lea 0(%%eax,%0,4),%0\n"
14591 + "16: pushl %0\n"
14592 +@@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
14593 + " .long 7b,16b\n"
14594 + ".previous"
14595 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14596 +- : "1"(to), "2"(from), "0"(size)
14597 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14598 + : "eax", "edx", "memory");
14599 + return size;
14600 + }
14601 +@@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
14602 + int d0, d1;
14603 +
14604 + __asm__ __volatile__(
14605 ++ " movw %w6, %%ds\n"
14606 + " .align 2,0x90\n"
14607 + "0: movl 32(%4), %%eax\n"
14608 + " cmpl $67, %0\n"
14609 +@@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
14610 + " .align 2,0x90\n"
14611 + "2: movl 0(%4), %%eax\n"
14612 + "21: movl 4(%4), %%edx\n"
14613 +- " movnti %%eax, 0(%3)\n"
14614 +- " movnti %%edx, 4(%3)\n"
14615 ++ " movnti %%eax, %%es:0(%3)\n"
14616 ++ " movnti %%edx, %%es:4(%3)\n"
14617 + "3: movl 8(%4), %%eax\n"
14618 + "31: movl 12(%4),%%edx\n"
14619 +- " movnti %%eax, 8(%3)\n"
14620 +- " movnti %%edx, 12(%3)\n"
14621 ++ " movnti %%eax, %%es:8(%3)\n"
14622 ++ " movnti %%edx, %%es:12(%3)\n"
14623 + "4: movl 16(%4), %%eax\n"
14624 + "41: movl 20(%4), %%edx\n"
14625 +- " movnti %%eax, 16(%3)\n"
14626 +- " movnti %%edx, 20(%3)\n"
14627 ++ " movnti %%eax, %%es:16(%3)\n"
14628 ++ " movnti %%edx, %%es:20(%3)\n"
14629 + "10: movl 24(%4), %%eax\n"
14630 + "51: movl 28(%4), %%edx\n"
14631 +- " movnti %%eax, 24(%3)\n"
14632 +- " movnti %%edx, 28(%3)\n"
14633 ++ " movnti %%eax, %%es:24(%3)\n"
14634 ++ " movnti %%edx, %%es:28(%3)\n"
14635 + "11: movl 32(%4), %%eax\n"
14636 + "61: movl 36(%4), %%edx\n"
14637 +- " movnti %%eax, 32(%3)\n"
14638 +- " movnti %%edx, 36(%3)\n"
14639 ++ " movnti %%eax, %%es:32(%3)\n"
14640 ++ " movnti %%edx, %%es:36(%3)\n"
14641 + "12: movl 40(%4), %%eax\n"
14642 + "71: movl 44(%4), %%edx\n"
14643 +- " movnti %%eax, 40(%3)\n"
14644 +- " movnti %%edx, 44(%3)\n"
14645 ++ " movnti %%eax, %%es:40(%3)\n"
14646 ++ " movnti %%edx, %%es:44(%3)\n"
14647 + "13: movl 48(%4), %%eax\n"
14648 + "81: movl 52(%4), %%edx\n"
14649 +- " movnti %%eax, 48(%3)\n"
14650 +- " movnti %%edx, 52(%3)\n"
14651 ++ " movnti %%eax, %%es:48(%3)\n"
14652 ++ " movnti %%edx, %%es:52(%3)\n"
14653 + "14: movl 56(%4), %%eax\n"
14654 + "91: movl 60(%4), %%edx\n"
14655 +- " movnti %%eax, 56(%3)\n"
14656 +- " movnti %%edx, 60(%3)\n"
14657 ++ " movnti %%eax, %%es:56(%3)\n"
14658 ++ " movnti %%edx, %%es:60(%3)\n"
14659 + " addl $-64, %0\n"
14660 + " addl $64, %4\n"
14661 + " addl $64, %3\n"
14662 +@@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
14663 + " movl %%eax,%0\n"
14664 + "7: rep; movsb\n"
14665 + "8:\n"
14666 ++ " pushl %%ss\n"
14667 ++ " popl %%ds\n"
14668 + ".section .fixup,\"ax\"\n"
14669 + "9: lea 0(%%eax,%0,4),%0\n"
14670 + "16: jmp 8b\n"
14671 +@@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
14672 + " .long 7b,16b\n"
14673 + ".previous"
14674 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14675 +- : "1"(to), "2"(from), "0"(size)
14676 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14677 + : "eax", "edx", "memory");
14678 + return size;
14679 + }
14680 +@@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
14681 + */
14682 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
14683 + unsigned long size);
14684 +-unsigned long __copy_user_intel(void __user *to, const void *from,
14685 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
14686 ++ unsigned long size);
14687 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
14688 + unsigned long size);
14689 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
14690 + const void __user *from, unsigned long size);
14691 + #endif /* CONFIG_X86_INTEL_USERCOPY */
14692 +
14693 + /* Generic arbitrary sized copy. */
14694 +-#define __copy_user(to,from,size) \
14695 +-do { \
14696 +- int __d0, __d1, __d2; \
14697 +- __asm__ __volatile__( \
14698 +- " cmp $7,%0\n" \
14699 +- " jbe 1f\n" \
14700 +- " movl %1,%0\n" \
14701 +- " negl %0\n" \
14702 +- " andl $7,%0\n" \
14703 +- " subl %0,%3\n" \
14704 +- "4: rep; movsb\n" \
14705 +- " movl %3,%0\n" \
14706 +- " shrl $2,%0\n" \
14707 +- " andl $3,%3\n" \
14708 +- " .align 2,0x90\n" \
14709 +- "0: rep; movsl\n" \
14710 +- " movl %3,%0\n" \
14711 +- "1: rep; movsb\n" \
14712 +- "2:\n" \
14713 +- ".section .fixup,\"ax\"\n" \
14714 +- "5: addl %3,%0\n" \
14715 +- " jmp 2b\n" \
14716 +- "3: lea 0(%3,%0,4),%0\n" \
14717 +- " jmp 2b\n" \
14718 +- ".previous\n" \
14719 +- ".section __ex_table,\"a\"\n" \
14720 +- " .align 4\n" \
14721 +- " .long 4b,5b\n" \
14722 +- " .long 0b,3b\n" \
14723 +- " .long 1b,2b\n" \
14724 +- ".previous" \
14725 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
14726 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
14727 +- : "memory"); \
14728 +-} while (0)
14729 +-
14730 +-#define __copy_user_zeroing(to,from,size) \
14731 +-do { \
14732 +- int __d0, __d1, __d2; \
14733 +- __asm__ __volatile__( \
14734 +- " cmp $7,%0\n" \
14735 +- " jbe 1f\n" \
14736 +- " movl %1,%0\n" \
14737 +- " negl %0\n" \
14738 +- " andl $7,%0\n" \
14739 +- " subl %0,%3\n" \
14740 +- "4: rep; movsb\n" \
14741 +- " movl %3,%0\n" \
14742 +- " shrl $2,%0\n" \
14743 +- " andl $3,%3\n" \
14744 +- " .align 2,0x90\n" \
14745 +- "0: rep; movsl\n" \
14746 +- " movl %3,%0\n" \
14747 +- "1: rep; movsb\n" \
14748 +- "2:\n" \
14749 +- ".section .fixup,\"ax\"\n" \
14750 +- "5: addl %3,%0\n" \
14751 +- " jmp 6f\n" \
14752 +- "3: lea 0(%3,%0,4),%0\n" \
14753 +- "6: pushl %0\n" \
14754 +- " pushl %%eax\n" \
14755 +- " xorl %%eax,%%eax\n" \
14756 +- " rep; stosb\n" \
14757 +- " popl %%eax\n" \
14758 +- " popl %0\n" \
14759 +- " jmp 2b\n" \
14760 +- ".previous\n" \
14761 +- ".section __ex_table,\"a\"\n" \
14762 +- " .align 4\n" \
14763 +- " .long 4b,5b\n" \
14764 +- " .long 0b,3b\n" \
14765 +- " .long 1b,6b\n" \
14766 +- ".previous" \
14767 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
14768 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
14769 +- : "memory"); \
14770 +-} while (0)
14771 ++static unsigned long
14772 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
14773 ++{
14774 ++ int __d0, __d1, __d2;
14775 ++
14776 ++ __asm__ __volatile__(
14777 ++ " movw %w8,%%es\n"
14778 ++ " cmp $7,%0\n"
14779 ++ " jbe 1f\n"
14780 ++ " movl %1,%0\n"
14781 ++ " negl %0\n"
14782 ++ " andl $7,%0\n"
14783 ++ " subl %0,%3\n"
14784 ++ "4: rep; movsb\n"
14785 ++ " movl %3,%0\n"
14786 ++ " shrl $2,%0\n"
14787 ++ " andl $3,%3\n"
14788 ++ " .align 2,0x90\n"
14789 ++ "0: rep; movsl\n"
14790 ++ " movl %3,%0\n"
14791 ++ "1: rep; movsb\n"
14792 ++ "2:\n"
14793 ++ " pushl %%ss\n"
14794 ++ " popl %%es\n"
14795 ++ ".section .fixup,\"ax\"\n"
14796 ++ "5: addl %3,%0\n"
14797 ++ " jmp 2b\n"
14798 ++ "3: lea 0(%3,%0,4),%0\n"
14799 ++ " jmp 2b\n"
14800 ++ ".previous\n"
14801 ++ ".section __ex_table,\"a\"\n"
14802 ++ " .align 4\n"
14803 ++ " .long 4b,5b\n"
14804 ++ " .long 0b,3b\n"
14805 ++ " .long 1b,2b\n"
14806 ++ ".previous"
14807 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14808 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14809 ++ : "memory");
14810 ++ return size;
14811 ++}
14812 ++
14813 ++static unsigned long
14814 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
14815 ++{
14816 ++ int __d0, __d1, __d2;
14817 ++
14818 ++ __asm__ __volatile__(
14819 ++ " movw %w8,%%ds\n"
14820 ++ " cmp $7,%0\n"
14821 ++ " jbe 1f\n"
14822 ++ " movl %1,%0\n"
14823 ++ " negl %0\n"
14824 ++ " andl $7,%0\n"
14825 ++ " subl %0,%3\n"
14826 ++ "4: rep; movsb\n"
14827 ++ " movl %3,%0\n"
14828 ++ " shrl $2,%0\n"
14829 ++ " andl $3,%3\n"
14830 ++ " .align 2,0x90\n"
14831 ++ "0: rep; movsl\n"
14832 ++ " movl %3,%0\n"
14833 ++ "1: rep; movsb\n"
14834 ++ "2:\n"
14835 ++ " pushl %%ss\n"
14836 ++ " popl %%ds\n"
14837 ++ ".section .fixup,\"ax\"\n"
14838 ++ "5: addl %3,%0\n"
14839 ++ " jmp 2b\n"
14840 ++ "3: lea 0(%3,%0,4),%0\n"
14841 ++ " jmp 2b\n"
14842 ++ ".previous\n"
14843 ++ ".section __ex_table,\"a\"\n"
14844 ++ " .align 4\n"
14845 ++ " .long 4b,5b\n"
14846 ++ " .long 0b,3b\n"
14847 ++ " .long 1b,2b\n"
14848 ++ ".previous"
14849 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14850 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14851 ++ : "memory");
14852 ++ return size;
14853 ++}
14854 ++
14855 ++static unsigned long
14856 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
14857 ++{
14858 ++ int __d0, __d1, __d2;
14859 ++
14860 ++ __asm__ __volatile__(
14861 ++ " movw %w8,%%ds\n"
14862 ++ " cmp $7,%0\n"
14863 ++ " jbe 1f\n"
14864 ++ " movl %1,%0\n"
14865 ++ " negl %0\n"
14866 ++ " andl $7,%0\n"
14867 ++ " subl %0,%3\n"
14868 ++ "4: rep; movsb\n"
14869 ++ " movl %3,%0\n"
14870 ++ " shrl $2,%0\n"
14871 ++ " andl $3,%3\n"
14872 ++ " .align 2,0x90\n"
14873 ++ "0: rep; movsl\n"
14874 ++ " movl %3,%0\n"
14875 ++ "1: rep; movsb\n"
14876 ++ "2:\n"
14877 ++ " pushl %%ss\n"
14878 ++ " popl %%ds\n"
14879 ++ ".section .fixup,\"ax\"\n"
14880 ++ "5: addl %3,%0\n"
14881 ++ " jmp 6f\n"
14882 ++ "3: lea 0(%3,%0,4),%0\n"
14883 ++ "6: pushl %0\n"
14884 ++ " pushl %%eax\n"
14885 ++ " xorl %%eax,%%eax\n"
14886 ++ " rep; stosb\n"
14887 ++ " popl %%eax\n"
14888 ++ " popl %0\n"
14889 ++ " jmp 2b\n"
14890 ++ ".previous\n"
14891 ++ ".section __ex_table,\"a\"\n"
14892 ++ " .align 4\n"
14893 ++ " .long 4b,5b\n"
14894 ++ " .long 0b,3b\n"
14895 ++ " .long 1b,6b\n"
14896 ++ ".previous"
14897 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14898 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14899 ++ : "memory");
14900 ++ return size;
14901 ++}
14902 +
14903 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
14904 + unsigned long n)
14905 +@@ -768,9 +959,9 @@ survive:
14906 + }
14907 + #endif
14908 + if (movsl_is_ok(to, from, n))
14909 +- __copy_user(to, from, n);
14910 ++ n = __generic_copy_to_user(to, from, n);
14911 + else
14912 +- n = __copy_user_intel(to, from, n);
14913 ++ n = __generic_copy_to_user_intel(to, from, n);
14914 + return n;
14915 + }
14916 + EXPORT_SYMBOL(__copy_to_user_ll);
14917 +@@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
14918 + unsigned long n)
14919 + {
14920 + if (movsl_is_ok(to, from, n))
14921 +- __copy_user_zeroing(to, from, n);
14922 ++ n = __copy_user_zeroing(to, from, n);
14923 + else
14924 + n = __copy_user_zeroing_intel(to, from, n);
14925 + return n;
14926 +@@ -790,9 +981,9 @@ unsigned long __copy_from_user_ll_nozero
14927 + unsigned long n)
14928 + {
14929 + if (movsl_is_ok(to, from, n))
14930 +- __copy_user(to, from, n);
14931 ++ n = __generic_copy_from_user(to, from, n);
14932 + else
14933 +- n = __copy_user_intel((void __user *)to,
14934 ++ n = __generic_copy_from_user_intel((void __user *)to,
14935 + (const void *)from, n);
14936 + return n;
14937 + }
14938 +@@ -803,11 +994,11 @@ unsigned long __copy_from_user_ll_nocach
14939 + {
14940 + #ifdef CONFIG_X86_INTEL_USERCOPY
14941 + if ( n > 64 && cpu_has_xmm2)
14942 +- n = __copy_user_zeroing_intel_nocache(to, from, n);
14943 ++ n = __copy_user_zeroing_intel_nocache(to, from, n);
14944 + else
14945 +- __copy_user_zeroing(to, from, n);
14946 ++ n = __copy_user_zeroing(to, from, n);
14947 + #else
14948 +- __copy_user_zeroing(to, from, n);
14949 ++ n = __copy_user_zeroing(to, from, n);
14950 + #endif
14951 + return n;
14952 + }
14953 +@@ -818,11 +1009,11 @@ unsigned long __copy_from_user_ll_nocach
14954 + {
14955 + #ifdef CONFIG_X86_INTEL_USERCOPY
14956 + if ( n > 64 && cpu_has_xmm2)
14957 +- n = __copy_user_intel_nocache(to, from, n);
14958 ++ n = __copy_user_intel_nocache(to, from, n);
14959 + else
14960 +- __copy_user(to, from, n);
14961 ++ n = __generic_copy_from_user(to, from, n);
14962 + #else
14963 +- __copy_user(to, from, n);
14964 ++ n = __generic_copy_from_user(to, from, n);
14965 + #endif
14966 + return n;
14967 + }
14968 +@@ -871,8 +1062,35 @@ copy_from_user(void *to, const void __us
14969 + {
14970 + if (access_ok(VERIFY_READ, from, n))
14971 + n = __copy_from_user(to, from, n);
14972 +- else
14973 ++ else if ((long)n > 0)
14974 + memset(to, 0, n);
14975 + return n;
14976 + }
14977 + EXPORT_SYMBOL(copy_from_user);
14978 ++
14979 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
14980 ++void __set_fs(mm_segment_t x, int cpu)
14981 ++{
14982 ++ unsigned long limit = x.seg;
14983 ++ struct desc_struct d;
14984 ++
14985 ++ current_thread_info()->addr_limit = x;
14986 ++ if (likely(limit))
14987 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
14988 ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
14989 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
14990 ++}
14991 ++
14992 ++void set_fs(mm_segment_t x)
14993 ++{
14994 ++ __set_fs(x, get_cpu());
14995 ++ put_cpu_no_resched();
14996 ++}
14997 ++#else
14998 ++void set_fs(mm_segment_t x)
14999 ++{
15000 ++ current_thread_info()->addr_limit = x;
15001 ++}
15002 ++#endif
15003 ++
15004 ++EXPORT_SYMBOL(set_fs);
15005 +diff -urNp a/arch/x86/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c
15006 +--- a/arch/x86/mach-voyager/voyager_basic.c 2008-08-20 11:16:13.000000000 -0700
15007 ++++ b/arch/x86/mach-voyager/voyager_basic.c 2008-08-20 18:36:57.000000000 -0700
15008 +@@ -125,7 +125,7 @@ int __init voyager_memory_detect(int reg
15009 + __u8 cmos[4];
15010 + ClickMap_t *map;
15011 + unsigned long map_addr;
15012 +- unsigned long old;
15013 ++ pte_t old;
15014 +
15015 + if (region >= CLICK_ENTRIES) {
15016 + printk("Voyager: Illegal ClickMap region %d\n", region);
15017 +@@ -140,7 +140,7 @@ int __init voyager_memory_detect(int reg
15018 +
15019 + /* steal page 0 for this */
15020 + old = pg0[0];
15021 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
15022 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
15023 + local_flush_tlb();
15024 + /* now clear everything out but page 0 */
15025 + map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
15026 +diff -urNp a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
15027 +--- a/arch/x86/mach-voyager/voyager_smp.c 2008-08-20 11:16:13.000000000 -0700
15028 ++++ b/arch/x86/mach-voyager/voyager_smp.c 2008-08-20 18:36:57.000000000 -0700
15029 +@@ -540,6 +540,10 @@ static void __init do_boot_cpu(__u8 cpu)
15030 + __u32 *hijack_vector;
15031 + __u32 start_phys_address = setup_trampoline();
15032 +
15033 ++#ifdef CONFIG_PAX_KERNEXEC
15034 ++ unsigned long cr0;
15035 ++#endif
15036 ++
15037 + /* There's a clever trick to this: The linux trampoline is
15038 + * compiled to begin at absolute location zero, so make the
15039 + * address zero but have the data segment selector compensate
15040 +@@ -559,7 +563,17 @@ static void __init do_boot_cpu(__u8 cpu)
15041 +
15042 + init_gdt(cpu);
15043 + per_cpu(current_task, cpu) = idle;
15044 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
15045 ++
15046 ++#ifdef CONFIG_PAX_KERNEXEC
15047 ++ pax_open_kernel(cr0);
15048 ++#endif
15049 ++
15050 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
15051 ++
15052 ++#ifdef CONFIG_PAX_KERNEXEC
15053 ++ pax_close_kernel(cr0);
15054 ++#endif
15055 ++
15056 + irq_ctx_init(cpu);
15057 +
15058 + /* Note: Don't modify initial ss override */
15059 +@@ -1242,7 +1256,7 @@ void smp_local_timer_interrupt(void)
15060 + per_cpu(prof_counter, cpu);
15061 + }
15062 +
15063 +- update_process_times(user_mode_vm(get_irq_regs()));
15064 ++ update_process_times(user_mode(get_irq_regs()));
15065 + }
15066 +
15067 + if (((1 << cpu) & voyager_extended_vic_processors) == 0)
15068 +diff -urNp a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
15069 +--- a/arch/x86/mm/extable.c 2008-08-20 11:16:13.000000000 -0700
15070 ++++ b/arch/x86/mm/extable.c 2008-08-20 18:36:57.000000000 -0700
15071 +@@ -1,14 +1,62 @@
15072 + #include <linux/module.h>
15073 + #include <linux/spinlock.h>
15074 ++#include <linux/sort.h>
15075 + #include <asm/uaccess.h>
15076 +
15077 ++/*
15078 ++ * The exception table needs to be sorted so that the binary
15079 ++ * search that we use to find entries in it works properly.
15080 ++ * This is used both for the kernel exception table and for
15081 ++ * the exception tables of modules that get loaded.
15082 ++ */
15083 ++static int cmp_ex(const void *a, const void *b)
15084 ++{
15085 ++ const struct exception_table_entry *x = a, *y = b;
15086 ++
15087 ++ /* avoid overflow */
15088 ++ if (x->insn > y->insn)
15089 ++ return 1;
15090 ++ if (x->insn < y->insn)
15091 ++ return -1;
15092 ++ return 0;
15093 ++}
15094 ++
15095 ++static void swap_ex(void *a, void *b, int size)
15096 ++{
15097 ++ struct exception_table_entry t, *x = a, *y = b;
15098 ++
15099 ++#ifdef CONFIG_PAX_KERNEXEC
15100 ++ unsigned long cr0;
15101 ++#endif
15102 ++
15103 ++ t = *x;
15104 ++
15105 ++#ifdef CONFIG_PAX_KERNEXEC
15106 ++ pax_open_kernel(cr0);
15107 ++#endif
15108 ++
15109 ++ *x = *y;
15110 ++ *y = t;
15111 ++
15112 ++#ifdef CONFIG_PAX_KERNEXEC
15113 ++ pax_close_kernel(cr0);
15114 ++#endif
15115 ++
15116 ++}
15117 ++
15118 ++void sort_extable(struct exception_table_entry *start,
15119 ++ struct exception_table_entry *finish)
15120 ++{
15121 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
15122 ++ cmp_ex, swap_ex);
15123 ++}
15124 +
15125 + int fixup_exception(struct pt_regs *regs)
15126 + {
15127 + const struct exception_table_entry *fixup;
15128 +
15129 + #ifdef CONFIG_PNPBIOS
15130 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
15131 ++ if (unlikely(!(regs->flags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->cs))) {
15132 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
15133 + extern u32 pnp_bios_is_utter_crap;
15134 + pnp_bios_is_utter_crap = 1;
15135 +diff -urNp a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
15136 +--- a/arch/x86/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
15137 ++++ b/arch/x86/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
15138 +@@ -25,6 +25,9 @@
15139 + #include <linux/kprobes.h>
15140 + #include <linux/uaccess.h>
15141 + #include <linux/kdebug.h>
15142 ++#include <linux/unistd.h>
15143 ++#include <linux/compiler.h>
15144 ++#include <linux/binfmts.h>
15145 +
15146 + #include <asm/system.h>
15147 + #include <asm/desc.h>
15148 +@@ -34,6 +37,7 @@
15149 + #include <asm/tlbflush.h>
15150 + #include <asm/proto.h>
15151 + #include <asm-generic/sections.h>
15152 ++#include <asm/tlbflush.h>
15153 +
15154 + /*
15155 + * Page fault error code bits
15156 +@@ -55,11 +59,7 @@ static inline int notify_page_fault(stru
15157 + int ret = 0;
15158 +
15159 + /* kprobe_running() needs smp_processor_id() */
15160 +-#ifdef CONFIG_X86_32
15161 +- if (!user_mode_vm(regs)) {
15162 +-#else
15163 + if (!user_mode(regs)) {
15164 +-#endif
15165 + preempt_disable();
15166 + if (kprobe_running() && kprobe_fault_handler(regs, 14))
15167 + ret = 1;
15168 +@@ -257,6 +257,30 @@ bad:
15169 + #endif
15170 + }
15171 +
15172 ++#ifdef CONFIG_PAX_EMUTRAMP
15173 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
15174 ++#endif
15175 ++
15176 ++#ifdef CONFIG_PAX_PAGEEXEC
15177 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
15178 ++{
15179 ++ pgd_t *pgd;
15180 ++ pud_t *pud;
15181 ++ pmd_t *pmd;
15182 ++
15183 ++ pgd = pgd_offset(mm, address);
15184 ++ if (!pgd_present(*pgd))
15185 ++ return NULL;
15186 ++ pud = pud_offset(pgd, address);
15187 ++ if (!pud_present(*pud))
15188 ++ return NULL;
15189 ++ pmd = pmd_offset(pud, address);
15190 ++ if (!pmd_present(*pmd))
15191 ++ return NULL;
15192 ++ return pmd;
15193 ++}
15194 ++#endif
15195 ++
15196 + #ifdef CONFIG_X86_32
15197 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
15198 + {
15199 +@@ -343,7 +367,7 @@ static int is_errata93(struct pt_regs *r
15200 + static int is_errata100(struct pt_regs *regs, unsigned long address)
15201 + {
15202 + #ifdef CONFIG_X86_64
15203 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
15204 ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
15205 + (address >> 32))
15206 + return 1;
15207 + #endif
15208 +@@ -380,17 +404,32 @@ static void show_fault_oops(struct pt_re
15209 + #endif
15210 +
15211 + #ifdef CONFIG_X86_PAE
15212 +- if (error_code & PF_INSTR) {
15213 ++ if (nx_enabled && (error_code & PF_INSTR)) {
15214 + unsigned int level;
15215 + pte_t *pte = lookup_address(address, &level);
15216 +
15217 + if (pte && pte_present(*pte) && !pte_exec(*pte))
15218 + printk(KERN_CRIT "kernel tried to execute "
15219 + "NX-protected page - exploit attempt? "
15220 +- "(uid: %d)\n", current->uid);
15221 ++ "(uid: %d, task: %s, pid: %d)\n",
15222 ++ current->uid, current->comm, task_pid_nr(current));
15223 + }
15224 + #endif
15225 +
15226 ++#ifdef CONFIG_PAX_KERNEXEC
15227 ++#ifdef CONFIG_MODULES
15228 ++ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
15229 ++#else
15230 ++ if (init_mm.start_code <= address && address < init_mm.end_code)
15231 ++#endif
15232 ++ if (current->signal->curr_ip)
15233 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
15234 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
15235 ++ else
15236 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
15237 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
15238 ++#endif
15239 ++
15240 + printk(KERN_ALERT "BUG: unable to handle kernel ");
15241 + if (address < PAGE_SIZE)
15242 + printk(KERN_CONT "NULL pointer dereference");
15243 +@@ -578,13 +617,22 @@ void __kprobes do_page_fault(struct pt_r
15244 + struct task_struct *tsk;
15245 + struct mm_struct *mm;
15246 + struct vm_area_struct *vma;
15247 +- unsigned long address;
15248 + int write, si_code;
15249 + int fault;
15250 + #ifdef CONFIG_X86_64
15251 + unsigned long flags;
15252 + #endif
15253 +
15254 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
15255 ++ pte_t *pte;
15256 ++ pmd_t *pmd;
15257 ++ spinlock_t *ptl;
15258 ++ unsigned char pte_mask;
15259 ++#endif
15260 ++
15261 ++ /* get the address */
15262 ++ const unsigned long address = read_cr2();
15263 ++
15264 + /*
15265 + * We can fault from pretty much anywhere, with unknown IRQ state.
15266 + */
15267 +@@ -594,9 +642,6 @@ void __kprobes do_page_fault(struct pt_r
15268 + mm = tsk->mm;
15269 + prefetchw(&mm->mmap_sem);
15270 +
15271 +- /* get the address */
15272 +- address = read_cr2();
15273 +-
15274 + si_code = SEGV_MAPERR;
15275 +
15276 + if (notify_page_fault(regs))
15277 +@@ -647,7 +692,7 @@ void __kprobes do_page_fault(struct pt_r
15278 + * atomic region then we must not take the fault.
15279 + */
15280 + if (in_atomic() || !mm)
15281 +- goto bad_area_nosemaphore;
15282 ++ goto bad_area_nopax;
15283 + #else /* CONFIG_X86_64 */
15284 + if (likely(regs->flags & X86_EFLAGS_IF))
15285 + local_irq_enable();
15286 +@@ -660,13 +705,13 @@ void __kprobes do_page_fault(struct pt_r
15287 + * atomic region then we must not take the fault.
15288 + */
15289 + if (unlikely(in_atomic() || !mm))
15290 +- goto bad_area_nosemaphore;
15291 ++ goto bad_area_nopax;
15292 +
15293 + /*
15294 + * User-mode registers count as a user access even for any
15295 + * potential system fault or CPU buglet.
15296 + */
15297 +- if (user_mode_vm(regs))
15298 ++ if (user_mode(regs))
15299 + error_code |= PF_USER;
15300 + again:
15301 + #endif
15302 +@@ -688,10 +733,104 @@ again:
15303 + if (!down_read_trylock(&mm->mmap_sem)) {
15304 + if ((error_code & PF_USER) == 0 &&
15305 + !search_exception_tables(regs->ip))
15306 +- goto bad_area_nosemaphore;
15307 ++ goto bad_area_nopax;
15308 + down_read(&mm->mmap_sem);
15309 + }
15310 +
15311 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
15312 ++ if (nx_enabled || (error_code & 5) != 5 || (regs->flags & X86_EFLAGS_VM) ||
15313 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
15314 ++ goto not_pax_fault;
15315 ++
15316 ++ /* PaX: it's our fault, let's handle it if we can */
15317 ++
15318 ++ /* PaX: take a look at read faults before acquiring any locks */
15319 ++ if (unlikely(!(error_code & 2) && (regs->ip == address))) {
15320 ++ /* instruction fetch attempt from a protected page in user mode */
15321 ++ up_read(&mm->mmap_sem);
15322 ++
15323 ++#ifdef CONFIG_PAX_EMUTRAMP
15324 ++ switch (pax_handle_fetch_fault(regs)) {
15325 ++ case 2:
15326 ++ return;
15327 ++ }
15328 ++#endif
15329 ++
15330 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
15331 ++ do_group_exit(SIGKILL);
15332 ++ }
15333 ++
15334 ++ pmd = pax_get_pmd(mm, address);
15335 ++ if (unlikely(!pmd))
15336 ++ goto not_pax_fault;
15337 ++
15338 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
15339 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
15340 ++ pte_unmap_unlock(pte, ptl);
15341 ++ goto not_pax_fault;
15342 ++ }
15343 ++
15344 ++ if (unlikely((error_code & 2) && !pte_write(*pte))) {
15345 ++ /* write attempt to a protected page in user mode */
15346 ++ pte_unmap_unlock(pte, ptl);
15347 ++ goto not_pax_fault;
15348 ++ }
15349 ++
15350 ++#ifdef CONFIG_SMP
15351 ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
15352 ++#else
15353 ++ if (likely(address > get_limit(regs->cs)))
15354 ++#endif
15355 ++ {
15356 ++ set_pte(pte, pte_mkread(*pte));
15357 ++ __flush_tlb_one(address);
15358 ++ pte_unmap_unlock(pte, ptl);
15359 ++ up_read(&mm->mmap_sem);
15360 ++ return;
15361 ++ }
15362 ++
15363 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
15364 ++
15365 ++ /*
15366 ++ * PaX: fill DTLB with user rights and retry
15367 ++ */
15368 ++ __asm__ __volatile__ (
15369 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
15370 ++ "movw %w4,%%es\n"
15371 ++#endif
15372 ++ "orb %2,(%1)\n"
15373 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
15374 ++/*
15375 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
15376 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
15377 ++ * page fault when examined during a TLB load attempt. this is true not only
15378 ++ * for PTEs holding a non-present entry but also present entries that will
15379 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
15380 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
15381 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
15382 ++
15383 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
15384 ++ * fast path of the page fault handler and can get rid of tracing since we
15385 ++ * can no longer flush unintended entries.
15386 ++ */
15387 ++ "invlpg (%0)\n"
15388 ++#endif
15389 ++ "testb $0,%%es:(%0)\n"
15390 ++ "xorb %3,(%1)\n"
15391 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
15392 ++ "pushl %%ss\n"
15393 ++ "popl %%es\n"
15394 ++#endif
15395 ++ :
15396 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
15397 ++ : "memory", "cc");
15398 ++ pte_unmap_unlock(pte, ptl);
15399 ++ up_read(&mm->mmap_sem);
15400 ++ return;
15401 ++
15402 ++not_pax_fault:
15403 ++#endif
15404 ++
15405 + vma = find_vma(mm, address);
15406 + if (!vma)
15407 + goto bad_area;
15408 +@@ -709,6 +848,12 @@ again:
15409 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
15410 + goto bad_area;
15411 + }
15412 ++
15413 ++#ifdef CONFIG_PAX_SEGMEXEC
15414 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
15415 ++ goto bad_area;
15416 ++#endif
15417 ++
15418 + if (expand_stack(vma, address))
15419 + goto bad_area;
15420 + /*
15421 +@@ -718,6 +863,8 @@ again:
15422 + good_area:
15423 + si_code = SEGV_ACCERR;
15424 + write = 0;
15425 ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
15426 ++ goto bad_area;
15427 + switch (error_code & (PF_PROT|PF_WRITE)) {
15428 + default: /* 3: write, present */
15429 + /* fall through */
15430 +@@ -775,6 +922,49 @@ bad_area:
15431 + up_read(&mm->mmap_sem);
15432 +
15433 + bad_area_nosemaphore:
15434 ++
15435 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15436 ++ if (mm && (error_code & 4) && !(regs->flags & X86_EFLAGS_VM)) {
15437 ++ /*
15438 ++ * It's possible to have interrupts off here.
15439 ++ */
15440 ++ local_irq_enable();
15441 ++
15442 ++#ifdef CONFIG_PAX_PAGEEXEC
15443 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
15444 ++ ((nx_enabled && ((error_code & PF_INSTR) || !(error_code & (PF_PROT | PF_WRITE))) && (regs->ip == address)))) {
15445 ++
15446 ++#ifdef CONFIG_PAX_EMUTRAMP
15447 ++ switch (pax_handle_fetch_fault(regs)) {
15448 ++ case 2:
15449 ++ return;
15450 ++ }
15451 ++#endif
15452 ++
15453 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
15454 ++ do_group_exit(SIGKILL);
15455 ++ }
15456 ++#endif
15457 ++
15458 ++#ifdef CONFIG_PAX_SEGMEXEC
15459 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
15460 ++
15461 ++#ifdef CONFIG_PAX_EMUTRAMP
15462 ++ switch (pax_handle_fetch_fault(regs)) {
15463 ++ case 2:
15464 ++ return;
15465 ++ }
15466 ++#endif
15467 ++
15468 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
15469 ++ do_group_exit(SIGKILL);
15470 ++ }
15471 ++#endif
15472 ++
15473 ++ }
15474 ++#endif
15475 ++
15476 ++bad_area_nopax:
15477 + /* User mode accesses just cause a SIGSEGV */
15478 + if (error_code & PF_USER) {
15479 + /*
15480 +@@ -857,7 +1047,7 @@ no_context:
15481 + #ifdef CONFIG_X86_32
15482 + die("Oops", regs, error_code);
15483 + bust_spinlocks(0);
15484 +- do_exit(SIGKILL);
15485 ++ do_group_exit(SIGKILL);
15486 + #else
15487 + if (__die("Oops", regs, error_code))
15488 + regs = NULL;
15489 +@@ -871,17 +1061,17 @@ no_context:
15490 + * us unable to handle the page fault gracefully.
15491 + */
15492 + out_of_memory:
15493 +- up_read(&mm->mmap_sem);
15494 + if (is_global_init(tsk)) {
15495 + yield();
15496 + #ifdef CONFIG_X86_32
15497 +- down_read(&mm->mmap_sem);
15498 + goto survive;
15499 + #else
15500 ++ up_read(&mm->mmap_sem);
15501 + goto again;
15502 + #endif
15503 + }
15504 +
15505 ++ up_read(&mm->mmap_sem);
15506 + printk("VM: killing process %s\n", tsk->comm);
15507 + if (error_code & PF_USER)
15508 + do_group_exit(SIGKILL);
15509 +@@ -982,3 +1172,174 @@ void vmalloc_sync_all(void)
15510 + (__START_KERNEL & PGDIR_MASK)));
15511 + #endif
15512 + }
15513 ++
15514 ++#ifdef CONFIG_PAX_EMUTRAMP
15515 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
15516 ++{
15517 ++ int err;
15518 ++
15519 ++ do { /* PaX: gcc trampoline emulation #1 */
15520 ++ unsigned char mov1, mov2;
15521 ++ unsigned short jmp;
15522 ++ unsigned int addr1, addr2;
15523 ++
15524 ++#ifdef CONFIG_X86_64
15525 ++ if ((regs->ip + 11) >> 32)
15526 ++ break;
15527 ++#endif
15528 ++
15529 ++ err = get_user(mov1, (unsigned char __user *)regs->ip);
15530 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
15531 ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
15532 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
15533 ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
15534 ++
15535 ++ if (err)
15536 ++ break;
15537 ++
15538 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
15539 ++ regs->cx = addr1;
15540 ++ regs->ax = addr2;
15541 ++ regs->ip = addr2;
15542 ++ return 2;
15543 ++ }
15544 ++ } while (0);
15545 ++
15546 ++ do { /* PaX: gcc trampoline emulation #2 */
15547 ++ unsigned char mov, jmp;
15548 ++ unsigned int addr1, addr2;
15549 ++
15550 ++#ifdef CONFIG_X86_64
15551 ++ if ((regs->ip + 9) >> 32)
15552 ++ break;
15553 ++#endif
15554 ++
15555 ++ err = get_user(mov, (unsigned char __user *)regs->ip);
15556 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
15557 ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
15558 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
15559 ++
15560 ++ if (err)
15561 ++ break;
15562 ++
15563 ++ if (mov == 0xB9 && jmp == 0xE9) {
15564 ++ regs->cx = addr1;
15565 ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
15566 ++ return 2;
15567 ++ }
15568 ++ } while (0);
15569 ++
15570 ++ return 1; /* PaX in action */
15571 ++}
15572 ++
15573 ++#ifdef CONFIG_X86_64
15574 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
15575 ++{
15576 ++ int err;
15577 ++
15578 ++ do { /* PaX: gcc trampoline emulation #1 */
15579 ++ unsigned short mov1, mov2, jmp1;
15580 ++ unsigned char jmp2;
15581 ++ unsigned int addr1;
15582 ++ unsigned long addr2;
15583 ++
15584 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
15585 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
15586 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
15587 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
15588 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
15589 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
15590 ++
15591 ++ if (err)
15592 ++ break;
15593 ++
15594 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
15595 ++ regs->r11 = addr1;
15596 ++ regs->r10 = addr2;
15597 ++ regs->ip = addr1;
15598 ++ return 2;
15599 ++ }
15600 ++ } while (0);
15601 ++
15602 ++ do { /* PaX: gcc trampoline emulation #2 */
15603 ++ unsigned short mov1, mov2, jmp1;
15604 ++ unsigned char jmp2;
15605 ++ unsigned long addr1, addr2;
15606 ++
15607 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
15608 ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
15609 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
15610 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
15611 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
15612 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
15613 ++
15614 ++ if (err)
15615 ++ break;
15616 ++
15617 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
15618 ++ regs->r11 = addr1;
15619 ++ regs->r10 = addr2;
15620 ++ regs->ip = addr1;
15621 ++ return 2;
15622 ++ }
15623 ++ } while (0);
15624 ++
15625 ++ return 1; /* PaX in action */
15626 ++}
15627 ++#endif
15628 ++
15629 ++/*
15630 ++ * PaX: decide what to do with offenders (regs->ip = fault address)
15631 ++ *
15632 ++ * returns 1 when task should be killed
15633 ++ * 2 when gcc trampoline was detected
15634 ++ */
15635 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
15636 ++{
15637 ++ if (regs->flags & X86_EFLAGS_VM)
15638 ++ return 1;
15639 ++
15640 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
15641 ++ return 1;
15642 ++
15643 ++#ifdef CONFIG_X86_32
15644 ++ return pax_handle_fetch_fault_32(regs);
15645 ++#else
15646 ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
15647 ++ return pax_handle_fetch_fault_32(regs);
15648 ++ else
15649 ++ return pax_handle_fetch_fault_64(regs);
15650 ++#endif
15651 ++}
15652 ++#endif
15653 ++
15654 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15655 ++void pax_report_insns(void *pc, void *sp)
15656 ++{
15657 ++ long i;
15658 ++
15659 ++ printk(KERN_ERR "PAX: bytes at PC: ");
15660 ++ for (i = 0; i < 20; i++) {
15661 ++ unsigned char c;
15662 ++ if (get_user(c, (unsigned char __user *)pc+i))
15663 ++ printk(KERN_CONT "?? ");
15664 ++ else
15665 ++ printk(KERN_CONT "%02x ", c);
15666 ++ }
15667 ++ printk("\n");
15668 ++
15669 ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
15670 ++ for (i = -1; i < 80 / sizeof(long); i++) {
15671 ++ unsigned long c;
15672 ++ if (get_user(c, (unsigned long __user *)sp+i))
15673 ++#ifdef CONFIG_X86_32
15674 ++ printk(KERN_CONT "???????? ");
15675 ++#else
15676 ++ printk(KERN_CONT "???????????????? ");
15677 ++#endif
15678 ++ else
15679 ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
15680 ++ }
15681 ++ printk("\n");
15682 ++}
15683 ++#endif
15684 +diff -urNp a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
15685 +--- a/arch/x86/mm/highmem_32.c 2008-08-20 11:16:13.000000000 -0700
15686 ++++ b/arch/x86/mm/highmem_32.c 2008-08-20 18:36:57.000000000 -0700
15687 +@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
15688 + enum fixed_addresses idx;
15689 + unsigned long vaddr;
15690 +
15691 ++#ifdef CONFIG_PAX_KERNEXEC
15692 ++ unsigned long cr0;
15693 ++#endif
15694 ++
15695 + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
15696 + pagefault_disable();
15697 +
15698 +@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
15699 + idx = type + KM_TYPE_NR*smp_processor_id();
15700 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15701 + BUG_ON(!pte_none(*(kmap_pte-idx)));
15702 ++
15703 ++#ifdef CONFIG_PAX_KERNEXEC
15704 ++ pax_open_kernel(cr0);
15705 ++#endif
15706 ++
15707 + set_pte(kmap_pte-idx, mk_pte(page, prot));
15708 ++
15709 ++#ifdef CONFIG_PAX_KERNEXEC
15710 ++ pax_close_kernel(cr0);
15711 ++#endif
15712 ++
15713 + arch_flush_lazy_mmu_mode();
15714 +
15715 + return (void *)vaddr;
15716 +@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
15717 + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
15718 + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
15719 +
15720 ++#ifdef CONFIG_PAX_KERNEXEC
15721 ++ unsigned long cr0;
15722 ++#endif
15723 ++
15724 + /*
15725 + * Force other mappings to Oops if they'll try to access this pte
15726 + * without first remap it. Keeping stale mappings around is a bad idea
15727 + * also, in case the page changes cacheability attributes or becomes
15728 + * a protected page in a hypervisor.
15729 + */
15730 +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
15731 ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
15732 ++
15733 ++#ifdef CONFIG_PAX_KERNEXEC
15734 ++ pax_open_kernel(cr0);
15735 ++#endif
15736 ++
15737 + kpte_clear_flush(kmap_pte-idx, vaddr);
15738 +- else {
15739 ++
15740 ++#ifdef CONFIG_PAX_KERNEXEC
15741 ++ pax_close_kernel(cr0);
15742 ++#endif
15743 ++
15744 ++ } else {
15745 + #ifdef CONFIG_DEBUG_HIGHMEM
15746 + BUG_ON(vaddr < PAGE_OFFSET);
15747 + BUG_ON(vaddr >= (unsigned long)high_memory);
15748 +@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
15749 + enum fixed_addresses idx;
15750 + unsigned long vaddr;
15751 +
15752 ++#ifdef CONFIG_PAX_KERNEXEC
15753 ++ unsigned long cr0;
15754 ++#endif
15755 ++
15756 + pagefault_disable();
15757 +
15758 + idx = type + KM_TYPE_NR*smp_processor_id();
15759 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15760 ++
15761 ++#ifdef CONFIG_PAX_KERNEXEC
15762 ++ pax_open_kernel(cr0);
15763 ++#endif
15764 ++
15765 + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
15766 ++
15767 ++#ifdef CONFIG_PAX_KERNEXEC
15768 ++ pax_close_kernel(cr0);
15769 ++#endif
15770 ++
15771 + arch_flush_lazy_mmu_mode();
15772 +
15773 + return (void*) vaddr;
15774 +diff -urNp a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
15775 +--- a/arch/x86/mm/hugetlbpage.c 2008-08-20 11:16:13.000000000 -0700
15776 ++++ b/arch/x86/mm/hugetlbpage.c 2008-08-20 18:36:57.000000000 -0700
15777 +@@ -230,13 +230,18 @@ static unsigned long hugetlb_get_unmappe
15778 + {
15779 + struct mm_struct *mm = current->mm;
15780 + struct vm_area_struct *vma;
15781 +- unsigned long start_addr;
15782 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
15783 ++
15784 ++#ifdef CONFIG_PAX_SEGMEXEC
15785 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15786 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
15787 ++#endif
15788 +
15789 + if (len > mm->cached_hole_size) {
15790 +- start_addr = mm->free_area_cache;
15791 ++ start_addr = mm->free_area_cache;
15792 + } else {
15793 +- start_addr = TASK_UNMAPPED_BASE;
15794 +- mm->cached_hole_size = 0;
15795 ++ start_addr = mm->mmap_base;
15796 ++ mm->cached_hole_size = 0;
15797 + }
15798 +
15799 + full_search:
15800 +@@ -244,13 +249,13 @@ full_search:
15801 +
15802 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
15803 + /* At this point: (!vma || addr < vma->vm_end). */
15804 +- if (TASK_SIZE - len < addr) {
15805 ++ if (pax_task_size - len < addr) {
15806 + /*
15807 + * Start a new search - just in case we missed
15808 + * some holes.
15809 + */
15810 +- if (start_addr != TASK_UNMAPPED_BASE) {
15811 +- start_addr = TASK_UNMAPPED_BASE;
15812 ++ if (start_addr != mm->mmap_base) {
15813 ++ start_addr = mm->mmap_base;
15814 + mm->cached_hole_size = 0;
15815 + goto full_search;
15816 + }
15817 +@@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
15818 + {
15819 + struct mm_struct *mm = current->mm;
15820 + struct vm_area_struct *vma, *prev_vma;
15821 +- unsigned long base = mm->mmap_base, addr = addr0;
15822 ++ unsigned long base = mm->mmap_base, addr;
15823 + unsigned long largest_hole = mm->cached_hole_size;
15824 +- int first_time = 1;
15825 +
15826 + /* don't allow allocations above current base */
15827 + if (mm->free_area_cache > base)
15828 +@@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
15829 + largest_hole = 0;
15830 + mm->free_area_cache = base;
15831 + }
15832 +-try_again:
15833 ++
15834 + /* make sure it can fit in the remaining address space */
15835 + if (mm->free_area_cache < len)
15836 + goto fail;
15837 +@@ -326,22 +330,26 @@ try_again:
15838 +
15839 + fail:
15840 + /*
15841 +- * if hint left us with no space for the requested
15842 +- * mapping then try again:
15843 +- */
15844 +- if (first_time) {
15845 +- mm->free_area_cache = base;
15846 +- largest_hole = 0;
15847 +- first_time = 0;
15848 +- goto try_again;
15849 +- }
15850 +- /*
15851 + * A failed mmap() very likely causes application failure,
15852 + * so fall back to the bottom-up function here. This scenario
15853 + * can happen with large stack limits and large mmap()
15854 + * allocations.
15855 + */
15856 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
15857 ++
15858 ++#ifdef CONFIG_PAX_SEGMEXEC
15859 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15860 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
15861 ++ else
15862 ++#endif
15863 ++
15864 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
15865 ++
15866 ++#ifdef CONFIG_PAX_RANDMMAP
15867 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
15868 ++ mm->mmap_base += mm->delta_mmap;
15869 ++#endif
15870 ++
15871 ++ mm->free_area_cache = mm->mmap_base;
15872 + mm->cached_hole_size = ~0UL;
15873 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
15874 + len, pgoff, flags);
15875 +@@ -349,6 +357,7 @@ fail:
15876 + /*
15877 + * Restore the topdown base:
15878 + */
15879 ++ mm->mmap_base = base;
15880 + mm->free_area_cache = base;
15881 + mm->cached_hole_size = ~0UL;
15882 +
15883 +@@ -361,10 +370,17 @@ hugetlb_get_unmapped_area(struct file *f
15884 + {
15885 + struct mm_struct *mm = current->mm;
15886 + struct vm_area_struct *vma;
15887 ++ unsigned long pax_task_size = TASK_SIZE;
15888 +
15889 + if (len & ~HPAGE_MASK)
15890 + return -EINVAL;
15891 +- if (len > TASK_SIZE)
15892 ++
15893 ++#ifdef CONFIG_PAX_SEGMEXEC
15894 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15895 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
15896 ++#endif
15897 ++
15898 ++ if (len > pax_task_size)
15899 + return -ENOMEM;
15900 +
15901 + if (flags & MAP_FIXED) {
15902 +@@ -376,7 +392,7 @@ hugetlb_get_unmapped_area(struct file *f
15903 + if (addr) {
15904 + addr = ALIGN(addr, HPAGE_SIZE);
15905 + vma = find_vma(mm, addr);
15906 +- if (TASK_SIZE - len >= addr &&
15907 ++ if (pax_task_size - len >= addr &&
15908 + (!vma || addr + len <= vma->vm_start))
15909 + return addr;
15910 + }
15911 +diff -urNp a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
15912 +--- a/arch/x86/mm/init_32.c 2008-08-20 11:16:13.000000000 -0700
15913 ++++ b/arch/x86/mm/init_32.c 2008-08-20 18:36:57.000000000 -0700
15914 +@@ -48,6 +48,7 @@
15915 + #include <asm/paravirt.h>
15916 + #include <asm/setup.h>
15917 + #include <asm/cacheflush.h>
15918 ++#include <asm/desc.h>
15919 +
15920 + unsigned int __VMALLOC_RESERVE = 128 << 20;
15921 +
15922 +@@ -57,32 +58,6 @@ unsigned long highstart_pfn, highend_pfn
15923 + static noinline int do_test_wp_bit(void);
15924 +
15925 + /*
15926 +- * Creates a middle page table and puts a pointer to it in the
15927 +- * given global directory entry. This only returns the gd entry
15928 +- * in non-PAE compilation mode, since the middle layer is folded.
15929 +- */
15930 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
15931 +-{
15932 +- pud_t *pud;
15933 +- pmd_t *pmd_table;
15934 +-
15935 +-#ifdef CONFIG_X86_PAE
15936 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
15937 +- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
15938 +-
15939 +- paravirt_alloc_pd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
15940 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
15941 +- pud = pud_offset(pgd, 0);
15942 +- BUG_ON(pmd_table != pmd_offset(pud, 0));
15943 +- }
15944 +-#endif
15945 +- pud = pud_offset(pgd, 0);
15946 +- pmd_table = pmd_offset(pud, 0);
15947 +-
15948 +- return pmd_table;
15949 +-}
15950 +-
15951 +-/*
15952 + * Create a page table and place a pointer to it in a middle page
15953 + * directory entry:
15954 + */
15955 +@@ -100,7 +75,11 @@ static pte_t * __init one_page_table_ini
15956 + }
15957 +
15958 + paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
15959 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15960 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
15961 ++#else
15962 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
15963 ++#endif
15964 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
15965 + }
15966 +
15967 +@@ -122,6 +101,7 @@ page_table_range_init(unsigned long star
15968 + int pgd_idx, pmd_idx;
15969 + unsigned long vaddr;
15970 + pgd_t *pgd;
15971 ++ pud_t *pud;
15972 + pmd_t *pmd;
15973 +
15974 + vaddr = start;
15975 +@@ -130,8 +110,13 @@ page_table_range_init(unsigned long star
15976 + pgd = pgd_base + pgd_idx;
15977 +
15978 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
15979 +- pmd = one_md_table_init(pgd);
15980 +- pmd = pmd + pmd_index(vaddr);
15981 ++ pud = pud_offset(pgd, vaddr);
15982 ++ pmd = pmd_offset(pud, vaddr);
15983 ++
15984 ++#ifdef CONFIG_X86_PAE
15985 ++ paravirt_alloc_pd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
15986 ++#endif
15987 ++
15988 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
15989 + pmd++, pmd_idx++) {
15990 + one_page_table_init(pmd);
15991 +@@ -142,11 +127,23 @@ page_table_range_init(unsigned long star
15992 + }
15993 + }
15994 +
15995 +-static inline int is_kernel_text(unsigned long addr)
15996 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
15997 + {
15998 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
15999 +- return 1;
16000 +- return 0;
16001 ++ unsigned long etext;
16002 ++
16003 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
16004 ++ etext = ktva_ktla((unsigned long)&MODULES_END);
16005 ++#else
16006 ++ etext = (unsigned long)&_etext;
16007 ++#endif
16008 ++
16009 ++ if ((start > ktla_ktva(etext) ||
16010 ++ end <= ktla_ktva((unsigned long)_stext)) &&
16011 ++ (start > ktla_ktva((unsigned long)_einittext) ||
16012 ++ end <= ktla_ktva((unsigned long)_sinittext)) &&
16013 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
16014 ++ return 0;
16015 ++ return 1;
16016 + }
16017 +
16018 + /*
16019 +@@ -156,9 +153,10 @@ static inline int is_kernel_text(unsigne
16020 + */
16021 + static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
16022 + {
16023 +- int pgd_idx, pmd_idx, pte_ofs;
16024 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
16025 + unsigned long pfn;
16026 + pgd_t *pgd;
16027 ++ pud_t *pud;
16028 + pmd_t *pmd;
16029 + pte_t *pte;
16030 +
16031 +@@ -166,29 +164,27 @@ static void __init kernel_physical_mappi
16032 + pgd = pgd_base + pgd_idx;
16033 + pfn = 0;
16034 +
16035 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
16036 +- pmd = one_md_table_init(pgd);
16037 +- if (pfn >= max_low_pfn)
16038 +- continue;
16039 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
16040 ++ pud = pud_offset(pgd, 0);
16041 ++ pmd = pmd_offset(pud, 0);
16042 ++
16043 ++#ifdef CONFIG_X86_PAE
16044 ++ paravirt_alloc_pd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
16045 ++#endif
16046 +
16047 + for (pmd_idx = 0;
16048 + pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
16049 + pmd++, pmd_idx++) {
16050 +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
16051 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
16052 +
16053 + /*
16054 + * Map with big pages if possible, otherwise
16055 + * create normal page tables:
16056 + */
16057 +- if (cpu_has_pse) {
16058 +- unsigned int addr2;
16059 ++ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
16060 + pgprot_t prot = PAGE_KERNEL_LARGE;
16061 +
16062 +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
16063 +- PAGE_OFFSET + PAGE_SIZE-1;
16064 +-
16065 +- if (is_kernel_text(addr) ||
16066 +- is_kernel_text(addr2))
16067 ++ if (is_kernel_text(address, address + PMD_SIZE))
16068 + prot = PAGE_KERNEL_LARGE_EXEC;
16069 +
16070 + set_pmd(pmd, pfn_pmd(pfn, prot));
16071 +@@ -200,10 +196,10 @@ static void __init kernel_physical_mappi
16072 +
16073 + for (pte_ofs = 0;
16074 + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
16075 +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
16076 ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
16077 + pgprot_t prot = PAGE_KERNEL;
16078 +
16079 +- if (is_kernel_text(addr))
16080 ++ if (is_kernel_text(address, address + PAGE_SIZE))
16081 + prot = PAGE_KERNEL_EXEC;
16082 +
16083 + set_pte(pte, pfn_pte(pfn, prot));
16084 +@@ -323,10 +319,10 @@ static void __init set_highmem_pages_ini
16085 + # define set_highmem_pages_init(bad_ppro) do { } while (0)
16086 + #endif /* CONFIG_HIGHMEM */
16087 +
16088 +-pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
16089 ++pteval_t __PAGE_KERNEL __read_only = _PAGE_KERNEL;
16090 + EXPORT_SYMBOL(__PAGE_KERNEL);
16091 +
16092 +-pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
16093 ++pteval_t __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
16094 +
16095 + void __init native_pagetable_setup_start(pgd_t *base)
16096 + {
16097 +@@ -348,7 +344,7 @@ void __init native_pagetable_setup_start
16098 +
16099 + pud = pud_offset(pgd, va);
16100 + pmd = pmd_offset(pud, va);
16101 +- if (!pmd_present(*pmd))
16102 ++ if (!pmd_present(*pmd) || pmd_huge(*pmd))
16103 + break;
16104 +
16105 + pte = pte_offset_kernel(pmd, va);
16106 +@@ -424,12 +420,12 @@ static void __init pagetable_init(void)
16107 + * ACPI suspend needs this for resume, because things like the intel-agp
16108 + * driver might have split up a kernel 4MB mapping.
16109 + */
16110 +-char swsusp_pg_dir[PAGE_SIZE]
16111 ++pgd_t swsusp_pg_dir[PTRS_PER_PGD]
16112 + __attribute__ ((aligned(PAGE_SIZE)));
16113 +
16114 + static inline void save_pg_dir(void)
16115 + {
16116 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
16117 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
16118 + }
16119 + #else /* !CONFIG_ACPI_SLEEP */
16120 + static inline void save_pg_dir(void)
16121 +@@ -461,13 +457,11 @@ void zap_low_mappings(void)
16122 +
16123 + int nx_enabled;
16124 +
16125 +-pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
16126 ++pteval_t __supported_pte_mask __read_only = ~_PAGE_NX;
16127 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
16128 +
16129 + #ifdef CONFIG_X86_PAE
16130 +
16131 +-static int disable_nx __initdata;
16132 +-
16133 + /*
16134 + * noexec = on|off
16135 + *
16136 +@@ -476,40 +470,33 @@ static int disable_nx __initdata;
16137 + * on Enable
16138 + * off Disable
16139 + */
16140 ++#if !defined(CONFIG_PAX_PAGEEXEC)
16141 + static int __init noexec_setup(char *str)
16142 + {
16143 + if (!str || !strcmp(str, "on")) {
16144 +- if (cpu_has_nx) {
16145 +- __supported_pte_mask |= _PAGE_NX;
16146 +- disable_nx = 0;
16147 +- }
16148 ++ if (cpu_has_nx)
16149 ++ nx_enabled = 1;
16150 + } else {
16151 +- if (!strcmp(str, "off")) {
16152 +- disable_nx = 1;
16153 +- __supported_pte_mask &= ~_PAGE_NX;
16154 +- } else {
16155 ++ if (!strcmp(str, "off"))
16156 ++ nx_enabled = 0;
16157 ++ else
16158 + return -EINVAL;
16159 +- }
16160 + }
16161 +
16162 + return 0;
16163 + }
16164 + early_param("noexec", noexec_setup);
16165 ++#endif
16166 +
16167 + static void __init set_nx(void)
16168 + {
16169 +- unsigned int v[4], l, h;
16170 +-
16171 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
16172 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
16173 ++ if (!nx_enabled && cpu_has_nx) {
16174 ++ unsigned l, h;
16175 +
16176 +- if ((v[3] & (1 << 20)) && !disable_nx) {
16177 +- rdmsr(MSR_EFER, l, h);
16178 +- l |= EFER_NX;
16179 +- wrmsr(MSR_EFER, l, h);
16180 +- nx_enabled = 1;
16181 +- __supported_pte_mask |= _PAGE_NX;
16182 +- }
16183 ++ __supported_pte_mask &= ~_PAGE_NX;
16184 ++ rdmsr(MSR_EFER, l, h);
16185 ++ l &= ~EFER_NX;
16186 ++ wrmsr(MSR_EFER, l, h);
16187 + }
16188 + }
16189 + #endif
16190 +@@ -601,7 +588,7 @@ void __init mem_init(void)
16191 + set_highmem_pages_init(bad_ppro);
16192 +
16193 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
16194 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
16195 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
16196 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
16197 +
16198 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
16199 +@@ -648,10 +635,10 @@ void __init mem_init(void)
16200 + ((unsigned long)&__init_end -
16201 + (unsigned long)&__init_begin) >> 10,
16202 +
16203 +- (unsigned long)&_etext, (unsigned long)&_edata,
16204 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
16205 ++ (unsigned long)&_data, (unsigned long)&_edata,
16206 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
16207 +
16208 +- (unsigned long)&_text, (unsigned long)&_etext,
16209 ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
16210 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
16211 +
16212 + #ifdef CONFIG_HIGHMEM
16213 +@@ -794,6 +781,46 @@ void free_init_pages(char *what, unsigne
16214 +
16215 + void free_initmem(void)
16216 + {
16217 ++
16218 ++#ifdef CONFIG_PAX_KERNEXEC
16219 ++ /* PaX: limit KERNEL_CS to actual size */
16220 ++ unsigned long addr, limit;
16221 ++ struct desc_struct d;
16222 ++ int cpu;
16223 ++ pgd_t *pgd;
16224 ++ pud_t *pud;
16225 ++ pmd_t *pmd;
16226 ++
16227 ++#ifdef CONFIG_MODULES
16228 ++ limit = ktva_ktla((unsigned long)&MODULES_END);
16229 ++#else
16230 ++ limit = (unsigned long)&_etext;
16231 ++#endif
16232 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
16233 ++
16234 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
16235 ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
16236 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
16237 ++ }
16238 ++
16239 ++ /* PaX: make KERNEL_CS read-only */
16240 ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
16241 ++ pgd = pgd_offset_k(addr);
16242 ++ pud = pud_offset(pgd, addr);
16243 ++ pmd = pmd_offset(pud, addr);
16244 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
16245 ++ }
16246 ++#ifdef CONFIG_X86_PAE
16247 ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
16248 ++ pgd = pgd_offset_k(addr);
16249 ++ pud = pud_offset(pgd, addr);
16250 ++ pmd = pmd_offset(pud, addr);
16251 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
16252 ++ }
16253 ++#endif
16254 ++ flush_tlb_all();
16255 ++#endif
16256 ++
16257 + free_init_pages("unused kernel memory",
16258 + (unsigned long)(&__init_begin),
16259 + (unsigned long)(&__init_end));
16260 +diff -urNp a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
16261 +--- a/arch/x86/mm/init_64.c 2008-08-20 11:16:13.000000000 -0700
16262 ++++ b/arch/x86/mm/init_64.c 2008-08-20 18:36:57.000000000 -0700
16263 +@@ -129,6 +129,10 @@ set_pte_phys(unsigned long vaddr, unsign
16264 + pmd_t *pmd;
16265 + pte_t *pte, new_pte;
16266 +
16267 ++#ifdef CONFIG_PAX_KERNEXEC
16268 ++ unsigned long cr0;
16269 ++#endif
16270 ++
16271 + pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
16272 +
16273 + pgd = pgd_offset_k(vaddr);
16274 +@@ -140,7 +144,7 @@ set_pte_phys(unsigned long vaddr, unsign
16275 + pud = pud_offset(pgd, vaddr);
16276 + if (pud_none(*pud)) {
16277 + pmd = (pmd_t *) spp_getpage();
16278 +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
16279 ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
16280 + if (pmd != pmd_offset(pud, 0)) {
16281 + printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
16282 + pmd, pmd_offset(pud, 0));
16283 +@@ -150,7 +154,7 @@ set_pte_phys(unsigned long vaddr, unsign
16284 + pmd = pmd_offset(pud, vaddr);
16285 + if (pmd_none(*pmd)) {
16286 + pte = (pte_t *) spp_getpage();
16287 +- set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
16288 ++ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
16289 + if (pte != pte_offset_kernel(pmd, 0)) {
16290 + printk(KERN_ERR "PAGETABLE BUG #02!\n");
16291 + return;
16292 +@@ -162,8 +166,17 @@ set_pte_phys(unsigned long vaddr, unsign
16293 + if (!pte_none(*pte) &&
16294 + pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
16295 + pte_ERROR(*pte);
16296 ++
16297 ++#ifdef CONFIG_PAX_KERNEXEC
16298 ++ pax_open_kernel(cr0);
16299 ++#endif
16300 ++
16301 + set_pte(pte, new_pte);
16302 +
16303 ++#ifdef CONFIG_PAX_KERNEXEC
16304 ++ pax_close_kernel(cr0);
16305 ++#endif
16306 ++
16307 + /*
16308 + * It's enough to flush this one mapping.
16309 + * (PGE mappings get flushed as well)
16310 +@@ -585,6 +598,39 @@ void free_init_pages(char *what, unsigne
16311 +
16312 + void free_initmem(void)
16313 + {
16314 ++
16315 ++#ifdef CONFIG_PAX_KERNEXEC
16316 ++ unsigned long addr, end;
16317 ++ pgd_t *pgd;
16318 ++ pud_t *pud;
16319 ++ pmd_t *pmd;
16320 ++
16321 ++ /* PaX: make kernel code/rodata read-only, rest non-executable */
16322 ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
16323 ++ pgd = pgd_offset_k(addr);
16324 ++ pud = pud_offset(pgd, addr);
16325 ++ pmd = pmd_offset(pud, addr);
16326 ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
16327 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
16328 ++ else
16329 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
16330 ++ }
16331 ++
16332 ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
16333 ++ end = addr + KERNEL_IMAGE_SIZE;
16334 ++ for (; addr < end; addr += PMD_SIZE) {
16335 ++ pgd = pgd_offset_k(addr);
16336 ++ pud = pud_offset(pgd, addr);
16337 ++ pmd = pmd_offset(pud, addr);
16338 ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
16339 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
16340 ++ else
16341 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
16342 ++ }
16343 ++
16344 ++ flush_tlb_all();
16345 ++#endif
16346 ++
16347 + free_init_pages("unused kernel memory",
16348 + (unsigned long)(&__init_begin),
16349 + (unsigned long)(&__init_end));
16350 +@@ -753,7 +799,7 @@ int in_gate_area_no_task(unsigned long a
16351 +
16352 + const char *arch_vma_name(struct vm_area_struct *vma)
16353 + {
16354 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
16355 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
16356 + return "[vdso]";
16357 + if (vma == &gate_vma)
16358 + return "[vsyscall]";
16359 +diff -urNp a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
16360 +--- a/arch/x86/mm/ioremap.c 2008-08-20 11:16:13.000000000 -0700
16361 ++++ b/arch/x86/mm/ioremap.c 2008-08-20 18:36:57.000000000 -0700
16362 +@@ -149,6 +149,8 @@ static void __iomem *__ioremap(resource_
16363 + break;
16364 + }
16365 +
16366 ++ prot = canon_pgprot(prot);
16367 ++
16368 + /*
16369 + * Mappings have to be page-aligned
16370 + */
16371 +diff -urNp a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
16372 +--- a/arch/x86/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
16373 ++++ b/arch/x86/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
16374 +@@ -36,7 +36,7 @@
16375 + * Leave an at least ~128 MB hole.
16376 + */
16377 + #define MIN_GAP (128*1024*1024)
16378 +-#define MAX_GAP (TASK_SIZE/6*5)
16379 ++#define MAX_GAP (pax_task_size/6*5)
16380 +
16381 + /*
16382 + * True on X86_32 or when emulating IA32 on X86_64
16383 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
16384 + return rnd << PAGE_SHIFT;
16385 + }
16386 +
16387 +-static unsigned long mmap_base(void)
16388 ++static unsigned long mmap_base(struct mm_struct *mm)
16389 + {
16390 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
16391 ++ unsigned long pax_task_size = TASK_SIZE;
16392 ++
16393 ++#ifdef CONFIG_PAX_SEGMEXEC
16394 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
16395 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16396 ++#endif
16397 +
16398 + if (gap < MIN_GAP)
16399 + gap = MIN_GAP;
16400 + else if (gap > MAX_GAP)
16401 + gap = MAX_GAP;
16402 +
16403 +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
16404 ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
16405 + }
16406 +
16407 + /*
16408 + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
16409 + * does, but not when emulating X86_32
16410 + */
16411 +-static unsigned long mmap_legacy_base(void)
16412 ++static unsigned long mmap_legacy_base(struct mm_struct *mm)
16413 + {
16414 +- if (mmap_is_ia32())
16415 ++ if (mmap_is_ia32()) {
16416 ++
16417 ++#ifdef CONFIG_PAX_SEGMEXEC
16418 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
16419 ++ return SEGMEXEC_TASK_UNMAPPED_BASE;
16420 ++ else
16421 ++#endif
16422 ++
16423 + return TASK_UNMAPPED_BASE;
16424 +- else
16425 ++ } else
16426 + return TASK_UNMAPPED_BASE + mmap_rnd();
16427 + }
16428 +
16429 +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
16430 + void arch_pick_mmap_layout(struct mm_struct *mm)
16431 + {
16432 + if (mmap_is_legacy()) {
16433 +- mm->mmap_base = mmap_legacy_base();
16434 ++ mm->mmap_base = mmap_legacy_base(mm);
16435 ++
16436 ++#ifdef CONFIG_PAX_RANDMMAP
16437 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16438 ++ mm->mmap_base += mm->delta_mmap;
16439 ++#endif
16440 ++
16441 + mm->get_unmapped_area = arch_get_unmapped_area;
16442 + mm->unmap_area = arch_unmap_area;
16443 + } else {
16444 +- mm->mmap_base = mmap_base();
16445 ++ mm->mmap_base = mmap_base(mm);
16446 ++
16447 ++#ifdef CONFIG_PAX_RANDMMAP
16448 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16449 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
16450 ++#endif
16451 ++
16452 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
16453 + mm->unmap_area = arch_unmap_area_topdown;
16454 + }
16455 +diff -urNp a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
16456 +--- a/arch/x86/mm/numa_64.c 2008-08-20 11:16:13.000000000 -0700
16457 ++++ b/arch/x86/mm/numa_64.c 2008-08-20 18:36:57.000000000 -0700
16458 +@@ -21,7 +21,7 @@
16459 + #include <asm/k8.h>
16460 +
16461 + #ifndef Dprintk
16462 +-#define Dprintk(x...)
16463 ++#define Dprintk(x...) do {} while (0)
16464 + #endif
16465 +
16466 + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
16467 +diff -urNp a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
16468 +--- a/arch/x86/mm/pageattr.c 2008-08-20 11:16:13.000000000 -0700
16469 ++++ b/arch/x86/mm/pageattr.c 2008-08-20 18:36:57.000000000 -0700
16470 +@@ -17,6 +17,7 @@
16471 + #include <asm/uaccess.h>
16472 + #include <asm/pgalloc.h>
16473 + #include <asm/proto.h>
16474 ++#include <asm/desc.h>
16475 +
16476 + /*
16477 + * The current flushing context - we pass it instead of 5 arguments:
16478 +@@ -168,7 +169,7 @@ static inline pgprot_t static_protection
16479 + * Does not cover __inittext since that is gone later on. On
16480 + * 64bit we do not enforce !NX on the low mapping
16481 + */
16482 +- if (within(address, (unsigned long)_text, (unsigned long)_etext))
16483 ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
16484 + pgprot_val(forbidden) |= _PAGE_NX;
16485 +
16486 + /*
16487 +@@ -229,8 +230,20 @@ pte_t *lookup_address(unsigned long addr
16488 + */
16489 + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
16490 + {
16491 ++
16492 ++#ifdef CONFIG_PAX_KERNEXEC
16493 ++ unsigned long cr0;
16494 ++
16495 ++ pax_open_kernel(cr0);
16496 ++#endif
16497 ++
16498 + /* change init_mm */
16499 + set_pte_atomic(kpte, pte);
16500 ++
16501 ++#ifdef CONFIG_PAX_KERNEXEC
16502 ++ pax_close_kernel(cr0);
16503 ++#endif
16504 ++
16505 + #ifdef CONFIG_X86_32
16506 + if (!SHARED_KERNEL_PMD) {
16507 + struct page *page;
16508 +diff -urNp a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
16509 +--- a/arch/x86/mm/pgtable_32.c 2008-08-20 11:16:13.000000000 -0700
16510 ++++ b/arch/x86/mm/pgtable_32.c 2008-08-20 18:36:57.000000000 -0700
16511 +@@ -83,6 +83,10 @@ static void set_pte_pfn(unsigned long va
16512 + pmd_t *pmd;
16513 + pte_t *pte;
16514 +
16515 ++#ifdef CONFIG_PAX_KERNEXEC
16516 ++ unsigned long cr0;
16517 ++#endif
16518 ++
16519 + pgd = swapper_pg_dir + pgd_index(vaddr);
16520 + if (pgd_none(*pgd)) {
16521 + BUG();
16522 +@@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
16523 + return;
16524 + }
16525 + pte = pte_offset_kernel(pmd, vaddr);
16526 ++
16527 ++#ifdef CONFIG_PAX_KERNEXEC
16528 ++ pax_open_kernel(cr0);
16529 ++#endif
16530 ++
16531 + if (pgprot_val(flags))
16532 + set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
16533 + else
16534 + pte_clear(&init_mm, vaddr, pte);
16535 +
16536 ++#ifdef CONFIG_PAX_KERNEXEC
16537 ++ pax_close_kernel(cr0);
16538 ++#endif
16539 ++
16540 + /*
16541 + * It's enough to flush this one mapping.
16542 + * (PGE mappings get flushed as well)
16543 +diff -urNp a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
16544 +--- a/arch/x86/oprofile/backtrace.c 2008-08-20 11:16:13.000000000 -0700
16545 ++++ b/arch/x86/oprofile/backtrace.c 2008-08-20 18:36:57.000000000 -0700
16546 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data
16547 + unsigned int *depth = data;
16548 +
16549 + if ((*depth)--)
16550 +- oprofile_add_trace(addr);
16551 ++ oprofile_add_trace(ktla_ktva(addr));
16552 + }
16553 +
16554 + static struct stacktrace_ops backtrace_ops = {
16555 +@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
16556 + struct frame_head *head = (struct frame_head *)frame_pointer(regs);
16557 + unsigned long stack = kernel_trap_sp(regs);
16558 +
16559 +- if (!user_mode_vm(regs)) {
16560 ++ if (!user_mode(regs)) {
16561 + if (depth)
16562 + dump_trace(NULL, regs, (unsigned long *)stack, 0,
16563 + &backtrace_ops, &depth);
16564 +diff -urNp a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
16565 +--- a/arch/x86/oprofile/op_model_p4.c 2008-08-20 11:16:13.000000000 -0700
16566 ++++ b/arch/x86/oprofile/op_model_p4.c 2008-08-20 18:36:57.000000000 -0700
16567 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
16568 + #endif
16569 + }
16570 +
16571 +-static int inline addr_increment(void)
16572 ++static inline int addr_increment(void)
16573 + {
16574 + #ifdef CONFIG_SMP
16575 + return smp_num_siblings == 2 ? 2 : 1;
16576 +diff -urNp a/arch/x86/pci/common.c b/arch/x86/pci/common.c
16577 +--- a/arch/x86/pci/common.c 2008-08-20 11:16:13.000000000 -0700
16578 ++++ b/arch/x86/pci/common.c 2008-08-20 18:36:57.000000000 -0700
16579 +@@ -352,7 +352,7 @@ static struct dmi_system_id __devinitdat
16580 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
16581 + },
16582 + },
16583 +- {}
16584 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
16585 + };
16586 +
16587 + void __init dmi_check_pciprobe(void)
16588 +diff -urNp a/arch/x86/pci/early.c b/arch/x86/pci/early.c
16589 +--- a/arch/x86/pci/early.c 2008-08-20 11:16:13.000000000 -0700
16590 ++++ b/arch/x86/pci/early.c 2008-08-20 18:36:57.000000000 -0700
16591 +@@ -7,7 +7,7 @@
16592 + /* Direct PCI access. This is used for PCI accesses in early boot before
16593 + the PCI subsystem works. */
16594 +
16595 +-#define PDprintk(x...)
16596 ++#define PDprintk(x...) do {} while (0)
16597 +
16598 + u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
16599 + {
16600 +diff -urNp a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
16601 +--- a/arch/x86/pci/fixup.c 2008-08-20 11:16:13.000000000 -0700
16602 ++++ b/arch/x86/pci/fixup.c 2008-08-20 18:36:57.000000000 -0700
16603 +@@ -364,7 +364,7 @@ static struct dmi_system_id __devinitdat
16604 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
16605 + },
16606 + },
16607 +- {}
16608 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
16609 + };
16610 +
16611 + /*
16612 +@@ -435,7 +435,7 @@ static struct dmi_system_id __devinitdat
16613 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
16614 + },
16615 + },
16616 +- { }
16617 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
16618 + };
16619 +
16620 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
16621 +diff -urNp a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
16622 +--- a/arch/x86/pci/irq.c 2008-08-20 11:16:13.000000000 -0700
16623 ++++ b/arch/x86/pci/irq.c 2008-08-20 18:36:57.000000000 -0700
16624 +@@ -540,7 +540,7 @@ static __init int intel_router_probe(str
16625 + static struct pci_device_id __initdata pirq_440gx[] = {
16626 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
16627 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
16628 +- { },
16629 ++ { PCI_DEVICE(0, 0) }
16630 + };
16631 +
16632 + /* 440GX has a proprietary PIRQ router -- don't use it */
16633 +@@ -1106,7 +1106,7 @@ static struct dmi_system_id __initdata p
16634 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
16635 + },
16636 + },
16637 +- { }
16638 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
16639 + };
16640 +
16641 + static int __init pcibios_irq_init(void)
16642 +diff -urNp a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
16643 +--- a/arch/x86/pci/pcbios.c 2008-08-20 11:16:13.000000000 -0700
16644 ++++ b/arch/x86/pci/pcbios.c 2008-08-20 18:36:57.000000000 -0700
16645 +@@ -57,50 +57,120 @@ union bios32 {
16646 + static struct {
16647 + unsigned long address;
16648 + unsigned short segment;
16649 +-} bios32_indirect = { 0, __KERNEL_CS };
16650 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
16651 +
16652 + /*
16653 + * Returns the entry point for the given service, NULL on error
16654 + */
16655 +
16656 +-static unsigned long bios32_service(unsigned long service)
16657 ++static unsigned long __devinit bios32_service(unsigned long service)
16658 + {
16659 + unsigned char return_code; /* %al */
16660 + unsigned long address; /* %ebx */
16661 + unsigned long length; /* %ecx */
16662 + unsigned long entry; /* %edx */
16663 + unsigned long flags;
16664 ++ struct desc_struct d, *gdt;
16665 ++
16666 ++#ifdef CONFIG_PAX_KERNEXEC
16667 ++ unsigned long cr0;
16668 ++#endif
16669 +
16670 + local_irq_save(flags);
16671 +- __asm__("lcall *(%%edi); cld"
16672 ++
16673 ++ gdt = get_cpu_gdt_table(smp_processor_id());
16674 ++
16675 ++#ifdef CONFIG_PAX_KERNEXEC
16676 ++ pax_open_kernel(cr0);
16677 ++#endif
16678 ++
16679 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
16680 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
16681 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
16682 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
16683 ++
16684 ++#ifdef CONFIG_PAX_KERNEXEC
16685 ++ pax_close_kernel(cr0);
16686 ++#endif
16687 ++
16688 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
16689 + : "=a" (return_code),
16690 + "=b" (address),
16691 + "=c" (length),
16692 + "=d" (entry)
16693 + : "0" (service),
16694 + "1" (0),
16695 +- "D" (&bios32_indirect));
16696 ++ "D" (&bios32_indirect),
16697 ++ "r"(__PCIBIOS_DS)
16698 ++ : "memory");
16699 ++
16700 ++#ifdef CONFIG_PAX_KERNEXEC
16701 ++ pax_open_kernel(cr0);
16702 ++#endif
16703 ++
16704 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
16705 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
16706 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
16707 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
16708 ++
16709 ++#ifdef CONFIG_PAX_KERNEXEC
16710 ++ pax_close_kernel(cr0);
16711 ++#endif
16712 ++
16713 + local_irq_restore(flags);
16714 +
16715 + switch (return_code) {
16716 +- case 0:
16717 +- return address + entry;
16718 +- case 0x80: /* Not present */
16719 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
16720 +- return 0;
16721 +- default: /* Shouldn't happen */
16722 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
16723 +- service, return_code);
16724 ++ case 0: {
16725 ++ int cpu;
16726 ++ unsigned char flags;
16727 ++
16728 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
16729 ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
16730 ++ printk(KERN_WARNING "bios32_service: not valid\n");
16731 + return 0;
16732 ++ }
16733 ++ address = address + PAGE_OFFSET;
16734 ++ length += 16UL; /* some BIOSs underreport this... */
16735 ++ flags = 4;
16736 ++ if (length >= 64*1024*1024) {
16737 ++ length >>= PAGE_SHIFT;
16738 ++ flags |= 8;
16739 ++ }
16740 ++
16741 ++#ifdef CONFIG_PAX_KERNEXEC
16742 ++ pax_open_kernel(cr0);
16743 ++#endif
16744 ++
16745 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
16746 ++ gdt = get_cpu_gdt_table(cpu);
16747 ++ pack_descriptor(&d, address, length, 0x9b, flags);
16748 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
16749 ++ pack_descriptor(&d, address, length, 0x93, flags);
16750 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
16751 ++ }
16752 ++
16753 ++#ifdef CONFIG_PAX_KERNEXEC
16754 ++ pax_close_kernel(cr0);
16755 ++#endif
16756 ++
16757 ++ return entry;
16758 ++ }
16759 ++ case 0x80: /* Not present */
16760 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
16761 ++ return 0;
16762 ++ default: /* Shouldn't happen */
16763 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
16764 ++ service, return_code);
16765 ++ return 0;
16766 + }
16767 + }
16768 +
16769 + static struct {
16770 + unsigned long address;
16771 + unsigned short segment;
16772 +-} pci_indirect = { 0, __KERNEL_CS };
16773 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
16774 +
16775 +-static int pci_bios_present;
16776 ++static int pci_bios_present __read_only;
16777 +
16778 + static int __devinit check_pcibios(void)
16779 + {
16780 +@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
16781 + unsigned long flags, pcibios_entry;
16782 +
16783 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
16784 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
16785 ++ pci_indirect.address = pcibios_entry;
16786 +
16787 + local_irq_save(flags);
16788 +- __asm__(
16789 +- "lcall *(%%edi); cld\n\t"
16790 ++ __asm__("movw %w6, %%ds\n\t"
16791 ++ "lcall *%%ss:(%%edi); cld\n\t"
16792 ++ "push %%ss\n\t"
16793 ++ "pop %%ds\n\t"
16794 + "jc 1f\n\t"
16795 + "xor %%ah, %%ah\n"
16796 + "1:"
16797 +@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
16798 + "=b" (ebx),
16799 + "=c" (ecx)
16800 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
16801 +- "D" (&pci_indirect)
16802 ++ "D" (&pci_indirect),
16803 ++ "r" (__PCIBIOS_DS)
16804 + : "memory");
16805 + local_irq_restore(flags);
16806 +
16807 +@@ -158,7 +231,10 @@ static int __devinit pci_bios_find_devic
16808 + unsigned short bx;
16809 + unsigned short ret;
16810 +
16811 +- __asm__("lcall *(%%edi); cld\n\t"
16812 ++ __asm__("movw %w7, %%ds\n\t"
16813 ++ "lcall *%%ss:(%%edi); cld\n\t"
16814 ++ "push %%ss\n\t"
16815 ++ "pop %%ds\n\t"
16816 + "jc 1f\n\t"
16817 + "xor %%ah, %%ah\n"
16818 + "1:"
16819 +@@ -168,7 +244,8 @@ static int __devinit pci_bios_find_devic
16820 + "c" (device_id),
16821 + "d" (vendor),
16822 + "S" ((int) index),
16823 +- "D" (&pci_indirect));
16824 ++ "D" (&pci_indirect),
16825 ++ "r" (__PCIBIOS_DS));
16826 + *bus = (bx >> 8) & 0xff;
16827 + *device_fn = bx & 0xff;
16828 + return (int) (ret & 0xff00) >> 8;
16829 +@@ -188,7 +265,10 @@ static int pci_bios_read(unsigned int se
16830 +
16831 + switch (len) {
16832 + case 1:
16833 +- __asm__("lcall *(%%esi); cld\n\t"
16834 ++ __asm__("movw %w6, %%ds\n\t"
16835 ++ "lcall *%%ss:(%%esi); cld\n\t"
16836 ++ "push %%ss\n\t"
16837 ++ "pop %%ds\n\t"
16838 + "jc 1f\n\t"
16839 + "xor %%ah, %%ah\n"
16840 + "1:"
16841 +@@ -197,7 +277,8 @@ static int pci_bios_read(unsigned int se
16842 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
16843 + "b" (bx),
16844 + "D" ((long)reg),
16845 +- "S" (&pci_indirect));
16846 ++ "S" (&pci_indirect),
16847 ++ "r" (__PCIBIOS_DS));
16848 + /*
16849 + * Zero-extend the result beyond 8 bits, do not trust the
16850 + * BIOS having done it:
16851 +@@ -205,7 +286,10 @@ static int pci_bios_read(unsigned int se
16852 + *value &= 0xff;
16853 + break;
16854 + case 2:
16855 +- __asm__("lcall *(%%esi); cld\n\t"
16856 ++ __asm__("movw %w6, %%ds\n\t"
16857 ++ "lcall *%%ss:(%%esi); cld\n\t"
16858 ++ "push %%ss\n\t"
16859 ++ "pop %%ds\n\t"
16860 + "jc 1f\n\t"
16861 + "xor %%ah, %%ah\n"
16862 + "1:"
16863 +@@ -214,7 +298,8 @@ static int pci_bios_read(unsigned int se
16864 + : "1" (PCIBIOS_READ_CONFIG_WORD),
16865 + "b" (bx),
16866 + "D" ((long)reg),
16867 +- "S" (&pci_indirect));
16868 ++ "S" (&pci_indirect),
16869 ++ "r" (__PCIBIOS_DS));
16870 + /*
16871 + * Zero-extend the result beyond 16 bits, do not trust the
16872 + * BIOS having done it:
16873 +@@ -222,7 +307,10 @@ static int pci_bios_read(unsigned int se
16874 + *value &= 0xffff;
16875 + break;
16876 + case 4:
16877 +- __asm__("lcall *(%%esi); cld\n\t"
16878 ++ __asm__("movw %w6, %%ds\n\t"
16879 ++ "lcall *%%ss:(%%esi); cld\n\t"
16880 ++ "push %%ss\n\t"
16881 ++ "pop %%ds\n\t"
16882 + "jc 1f\n\t"
16883 + "xor %%ah, %%ah\n"
16884 + "1:"
16885 +@@ -231,7 +319,8 @@ static int pci_bios_read(unsigned int se
16886 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
16887 + "b" (bx),
16888 + "D" ((long)reg),
16889 +- "S" (&pci_indirect));
16890 ++ "S" (&pci_indirect),
16891 ++ "r" (__PCIBIOS_DS));
16892 + break;
16893 + }
16894 +
16895 +@@ -254,7 +343,10 @@ static int pci_bios_write(unsigned int s
16896 +
16897 + switch (len) {
16898 + case 1:
16899 +- __asm__("lcall *(%%esi); cld\n\t"
16900 ++ __asm__("movw %w6, %%ds\n\t"
16901 ++ "lcall *%%ss:(%%esi); cld\n\t"
16902 ++ "push %%ss\n\t"
16903 ++ "pop %%ds\n\t"
16904 + "jc 1f\n\t"
16905 + "xor %%ah, %%ah\n"
16906 + "1:"
16907 +@@ -263,10 +355,14 @@ static int pci_bios_write(unsigned int s
16908 + "c" (value),
16909 + "b" (bx),
16910 + "D" ((long)reg),
16911 +- "S" (&pci_indirect));
16912 ++ "S" (&pci_indirect),
16913 ++ "r" (__PCIBIOS_DS));
16914 + break;
16915 + case 2:
16916 +- __asm__("lcall *(%%esi); cld\n\t"
16917 ++ __asm__("movw %w6, %%ds\n\t"
16918 ++ "lcall *%%ss:(%%esi); cld\n\t"
16919 ++ "push %%ss\n\t"
16920 ++ "pop %%ds\n\t"
16921 + "jc 1f\n\t"
16922 + "xor %%ah, %%ah\n"
16923 + "1:"
16924 +@@ -275,10 +371,14 @@ static int pci_bios_write(unsigned int s
16925 + "c" (value),
16926 + "b" (bx),
16927 + "D" ((long)reg),
16928 +- "S" (&pci_indirect));
16929 ++ "S" (&pci_indirect),
16930 ++ "r" (__PCIBIOS_DS));
16931 + break;
16932 + case 4:
16933 +- __asm__("lcall *(%%esi); cld\n\t"
16934 ++ __asm__("movw %w6, %%ds\n\t"
16935 ++ "lcall *%%ss:(%%esi); cld\n\t"
16936 ++ "push %%ss\n\t"
16937 ++ "pop %%ds\n\t"
16938 + "jc 1f\n\t"
16939 + "xor %%ah, %%ah\n"
16940 + "1:"
16941 +@@ -287,7 +387,8 @@ static int pci_bios_write(unsigned int s
16942 + "c" (value),
16943 + "b" (bx),
16944 + "D" ((long)reg),
16945 +- "S" (&pci_indirect));
16946 ++ "S" (&pci_indirect),
16947 ++ "r" (__PCIBIOS_DS));
16948 + break;
16949 + }
16950 +
16951 +@@ -440,10 +541,13 @@ struct irq_routing_table * pcibios_get_i
16952 +
16953 + DBG("PCI: Fetching IRQ routing table... ");
16954 + __asm__("push %%es\n\t"
16955 ++ "movw %w8, %%ds\n\t"
16956 + "push %%ds\n\t"
16957 + "pop %%es\n\t"
16958 +- "lcall *(%%esi); cld\n\t"
16959 ++ "lcall *%%ss:(%%esi); cld\n\t"
16960 + "pop %%es\n\t"
16961 ++ "push %%ss\n\t"
16962 ++ "pop %%ds\n"
16963 + "jc 1f\n\t"
16964 + "xor %%ah, %%ah\n"
16965 + "1:"
16966 +@@ -454,7 +558,8 @@ struct irq_routing_table * pcibios_get_i
16967 + "1" (0),
16968 + "D" ((long) &opt),
16969 + "S" (&pci_indirect),
16970 +- "m" (opt)
16971 ++ "m" (opt),
16972 ++ "r" (__PCIBIOS_DS)
16973 + : "memory");
16974 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
16975 + if (ret & 0xff00)
16976 +@@ -478,7 +583,10 @@ int pcibios_set_irq_routing(struct pci_d
16977 + {
16978 + int ret;
16979 +
16980 +- __asm__("lcall *(%%esi); cld\n\t"
16981 ++ __asm__("movw %w5, %%ds\n\t"
16982 ++ "lcall *%%ss:(%%esi); cld\n\t"
16983 ++ "push %%ss\n\t"
16984 ++ "pop %%ds\n"
16985 + "jc 1f\n\t"
16986 + "xor %%ah, %%ah\n"
16987 + "1:"
16988 +@@ -486,7 +594,8 @@ int pcibios_set_irq_routing(struct pci_d
16989 + : "0" (PCIBIOS_SET_PCI_HW_INT),
16990 + "b" ((dev->bus->number << 8) | dev->devfn),
16991 + "c" ((irq << 8) | (pin + 10)),
16992 +- "S" (&pci_indirect));
16993 ++ "S" (&pci_indirect),
16994 ++ "r" (__PCIBIOS_DS));
16995 + return !(ret & 0xff00);
16996 + }
16997 + EXPORT_SYMBOL(pcibios_set_irq_routing);
16998 +diff -urNp a/arch/x86/power/cpu_32.c b/arch/x86/power/cpu_32.c
16999 +--- a/arch/x86/power/cpu_32.c 2008-08-20 11:16:13.000000000 -0700
17000 ++++ b/arch/x86/power/cpu_32.c 2008-08-20 18:36:57.000000000 -0700
17001 +@@ -64,7 +64,7 @@ static void do_fpu_end(void)
17002 + static void fix_processor_context(void)
17003 + {
17004 + int cpu = smp_processor_id();
17005 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
17006 ++ struct tss_struct *t = init_tss + cpu;
17007 +
17008 + set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
17009 +
17010 +diff -urNp a/arch/x86/power/cpu_64.c b/arch/x86/power/cpu_64.c
17011 +--- a/arch/x86/power/cpu_64.c 2008-08-20 11:16:13.000000000 -0700
17012 ++++ b/arch/x86/power/cpu_64.c 2008-08-20 18:36:57.000000000 -0700
17013 +@@ -136,7 +136,11 @@ void restore_processor_state(void)
17014 + static void fix_processor_context(void)
17015 + {
17016 + int cpu = smp_processor_id();
17017 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
17018 ++ struct tss_struct *t = init_tss + cpu;
17019 ++
17020 ++#ifdef CONFIG_PAX_KERNEXEC
17021 ++ unsigned long cr0;
17022 ++#endif
17023 +
17024 + /*
17025 + * This just modifies memory; should not be necessary. But... This
17026 +@@ -145,8 +149,16 @@ static void fix_processor_context(void)
17027 + */
17028 + set_tss_desc(cpu, t);
17029 +
17030 ++#ifdef CONFIG_PAX_KERNEXEC
17031 ++ pax_open_kernel(cr0);
17032 ++#endif
17033 ++
17034 + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
17035 +
17036 ++#ifdef CONFIG_PAX_KERNEXEC
17037 ++ pax_close_kernel(cr0);
17038 ++#endif
17039 ++
17040 + syscall_init(); /* This sets MSR_*STAR and related */
17041 + load_TR_desc(); /* This does ltr */
17042 + load_LDT(&current->active_mm->context); /* This does lldt */
17043 +diff -urNp a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
17044 +--- a/arch/x86/vdso/vdso32-setup.c 2008-08-20 11:16:13.000000000 -0700
17045 ++++ b/arch/x86/vdso/vdso32-setup.c 2008-08-20 18:36:57.000000000 -0700
17046 +@@ -235,7 +235,7 @@ static inline void map_compat_vdso(int m
17047 + void enable_sep_cpu(void)
17048 + {
17049 + int cpu = get_cpu();
17050 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
17051 ++ struct tss_struct *tss = init_tss + cpu;
17052 +
17053 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
17054 + put_cpu();
17055 +@@ -258,7 +258,7 @@ static int __init gate_vma_init(void)
17056 + gate_vma.vm_start = FIXADDR_USER_START;
17057 + gate_vma.vm_end = FIXADDR_USER_END;
17058 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
17059 +- gate_vma.vm_page_prot = __P101;
17060 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
17061 + /*
17062 + * Make sure the vDSO gets into every core dump.
17063 + * Dumping its contents makes post-mortem fully interpretable later
17064 +@@ -336,7 +336,7 @@ int arch_setup_additional_pages(struct l
17065 + if (compat)
17066 + addr = VDSO_HIGH_BASE;
17067 + else {
17068 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
17069 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
17070 + if (IS_ERR_VALUE(addr)) {
17071 + ret = addr;
17072 + goto up_fail;
17073 +@@ -363,7 +363,7 @@ int arch_setup_additional_pages(struct l
17074 + goto up_fail;
17075 + }
17076 +
17077 +- current->mm->context.vdso = (void *)addr;
17078 ++ current->mm->context.vdso = addr;
17079 + current_thread_info()->sysenter_return =
17080 + VDSO32_SYMBOL(addr, SYSENTER_RETURN);
17081 +
17082 +@@ -389,7 +389,7 @@ static ctl_table abi_table2[] = {
17083 + .mode = 0644,
17084 + .proc_handler = proc_dointvec
17085 + },
17086 +- {}
17087 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
17088 + };
17089 +
17090 + static ctl_table abi_root_table2[] = {
17091 +@@ -399,7 +399,7 @@ static ctl_table abi_root_table2[] = {
17092 + .mode = 0555,
17093 + .child = abi_table2
17094 + },
17095 +- {}
17096 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
17097 + };
17098 +
17099 + static __init int ia32_binfmt_init(void)
17100 +@@ -414,8 +414,14 @@ __initcall(ia32_binfmt_init);
17101 +
17102 + const char *arch_vma_name(struct vm_area_struct *vma)
17103 + {
17104 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
17105 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
17106 + return "[vdso]";
17107 ++
17108 ++#ifdef CONFIG_PAX_SEGMEXEC
17109 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
17110 ++ return "[vdso]";
17111 ++#endif
17112 ++
17113 + return NULL;
17114 + }
17115 +
17116 +@@ -424,7 +430,7 @@ struct vm_area_struct *get_gate_vma(stru
17117 + struct mm_struct *mm = tsk->mm;
17118 +
17119 + /* Check to see if this task was created in compat vdso mode */
17120 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
17121 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
17122 + return &gate_vma;
17123 + return NULL;
17124 + }
17125 +diff -urNp a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
17126 +--- a/arch/x86/vdso/vma.c 2008-08-20 11:16:13.000000000 -0700
17127 ++++ b/arch/x86/vdso/vma.c 2008-08-20 18:36:57.000000000 -0700
17128 +@@ -122,7 +122,7 @@ int arch_setup_additional_pages(struct l
17129 + if (ret)
17130 + goto up_fail;
17131 +
17132 +- current->mm->context.vdso = (void *)addr;
17133 ++ current->mm->context.vdso = addr;
17134 + up_fail:
17135 + up_write(&mm->mmap_sem);
17136 + return ret;
17137 +diff -urNp a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
17138 +--- a/arch/x86/xen/enlighten.c 2008-08-20 11:16:13.000000000 -0700
17139 ++++ b/arch/x86/xen/enlighten.c 2008-08-20 18:36:57.000000000 -0700
17140 +@@ -293,7 +293,7 @@ static void xen_set_ldt(const void *addr
17141 + static void xen_load_gdt(const struct desc_ptr *dtr)
17142 + {
17143 + unsigned long *frames;
17144 +- unsigned long va = dtr->address;
17145 ++ unsigned long va = (unsigned long)dtr->address;
17146 + unsigned int size = dtr->size + 1;
17147 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
17148 + int f;
17149 +@@ -308,7 +308,7 @@ static void xen_load_gdt(const struct de
17150 + mcs = xen_mc_entry(sizeof(*frames) * pages);
17151 + frames = mcs.args;
17152 +
17153 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
17154 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
17155 + frames[f] = virt_to_mfn(va);
17156 + make_lowmem_page_readonly((void *)va);
17157 + }
17158 +@@ -401,7 +401,7 @@ static void xen_write_idt_entry(gate_des
17159 +
17160 + preempt_disable();
17161 +
17162 +- start = __get_cpu_var(idt_desc).address;
17163 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
17164 + end = start + __get_cpu_var(idt_desc).size + 1;
17165 +
17166 + xen_mc_flush();
17167 +diff -urNp a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
17168 +--- a/arch/x86/xen/smp.c 2008-08-20 11:16:13.000000000 -0700
17169 ++++ b/arch/x86/xen/smp.c 2008-08-20 18:36:57.000000000 -0700
17170 +@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
17171 +
17172 + /* We've switched to the "real" per-cpu gdt, so make sure the
17173 + old memory can be recycled */
17174 +- make_lowmem_page_readwrite(&per_cpu__gdt_page);
17175 ++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
17176 +
17177 + for_each_possible_cpu(cpu) {
17178 + cpus_clear(per_cpu(cpu_sibling_map, cpu));
17179 +@@ -208,7 +208,7 @@ static __cpuinit int
17180 + cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
17181 + {
17182 + struct vcpu_guest_context *ctxt;
17183 +- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
17184 ++ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
17185 +
17186 + if (cpu_test_and_set(cpu, cpu_initialized_map))
17187 + return 0;
17188 +@@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
17189 + return -ENOMEM;
17190 +
17191 + ctxt->flags = VGCF_IN_KERNEL;
17192 +- ctxt->user_regs.ds = __USER_DS;
17193 +- ctxt->user_regs.es = __USER_DS;
17194 ++ ctxt->user_regs.ds = __KERNEL_DS;
17195 ++ ctxt->user_regs.es = __KERNEL_DS;
17196 + ctxt->user_regs.fs = __KERNEL_PERCPU;
17197 + ctxt->user_regs.gs = 0;
17198 + ctxt->user_regs.ss = __KERNEL_DS;
17199 +@@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu,
17200 +
17201 + ctxt->ldt_ents = 0;
17202 +
17203 +- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
17204 +- make_lowmem_page_readonly(gdt->gdt);
17205 ++ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
17206 ++ make_lowmem_page_readonly(gdt);
17207 +
17208 +- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
17209 +- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
17210 ++ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
17211 ++ ctxt->gdt_ents = GDT_ENTRIES;
17212 +
17213 + ctxt->user_regs.cs = __KERNEL_CS;
17214 + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
17215 +diff -urNp a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
17216 +--- a/crypto/async_tx/async_tx.c 2008-08-20 11:16:13.000000000 -0700
17217 ++++ b/crypto/async_tx/async_tx.c 2008-08-20 18:36:57.000000000 -0700
17218 +@@ -341,8 +341,8 @@ async_tx_init(void)
17219 + err:
17220 + printk(KERN_ERR "async_tx: initialization failure\n");
17221 +
17222 +- while (--cap >= 0)
17223 +- free_percpu(channel_table[cap]);
17224 ++ while (cap)
17225 ++ free_percpu(channel_table[--cap]);
17226 +
17227 + return 1;
17228 + }
17229 +diff -urNp a/crypto/lrw.c b/crypto/lrw.c
17230 +--- a/crypto/lrw.c 2008-08-20 11:16:13.000000000 -0700
17231 ++++ b/crypto/lrw.c 2008-08-20 18:36:57.000000000 -0700
17232 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
17233 + struct priv *ctx = crypto_tfm_ctx(parent);
17234 + struct crypto_cipher *child = ctx->child;
17235 + int err, i;
17236 +- be128 tmp = { 0 };
17237 ++ be128 tmp = { 0, 0 };
17238 + int bsize = crypto_cipher_blocksize(child);
17239 +
17240 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
17241 +diff -urNp a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
17242 +--- a/drivers/acpi/blacklist.c 2008-08-20 11:16:13.000000000 -0700
17243 ++++ b/drivers/acpi/blacklist.c 2008-08-20 18:36:57.000000000 -0700
17244 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
17245 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
17246 + "Incorrect _ADR", 1},
17247 +
17248 +- {""}
17249 ++ {"", "", 0, 0, 0, all_versions, 0}
17250 + };
17251 +
17252 + #if CONFIG_ACPI_BLACKLIST_YEAR
17253 +diff -urNp a/drivers/acpi/osl.c b/drivers/acpi/osl.c
17254 +--- a/drivers/acpi/osl.c 2008-08-20 11:16:13.000000000 -0700
17255 ++++ b/drivers/acpi/osl.c 2008-08-20 18:36:57.000000000 -0700
17256 +@@ -489,6 +489,8 @@ acpi_os_read_memory(acpi_physical_addres
17257 + void __iomem *virt_addr;
17258 +
17259 + virt_addr = ioremap(phys_addr, width);
17260 ++ if (!virt_addr)
17261 ++ return AE_NO_MEMORY;
17262 + if (!value)
17263 + value = &dummy;
17264 +
17265 +@@ -517,6 +519,8 @@ acpi_os_write_memory(acpi_physical_addre
17266 + void __iomem *virt_addr;
17267 +
17268 + virt_addr = ioremap(phys_addr, width);
17269 ++ if (!virt_addr)
17270 ++ return AE_NO_MEMORY;
17271 +
17272 + switch (width) {
17273 + case 8:
17274 +diff -urNp a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
17275 +--- a/drivers/acpi/processor_core.c 2008-08-20 11:16:13.000000000 -0700
17276 ++++ b/drivers/acpi/processor_core.c 2008-08-20 18:36:57.000000000 -0700
17277 +@@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star
17278 + return 0;
17279 + }
17280 +
17281 +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
17282 ++ BUG_ON(pr->id >= nr_cpu_ids);
17283 +
17284 + /*
17285 + * Buggy BIOS check
17286 +diff -urNp a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
17287 +--- a/drivers/acpi/processor_idle.c 2008-08-20 11:16:13.000000000 -0700
17288 ++++ b/drivers/acpi/processor_idle.c 2008-08-20 18:36:57.000000000 -0700
17289 +@@ -181,7 +181,7 @@ static struct dmi_system_id __cpuinitdat
17290 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
17291 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
17292 + (void *)2},
17293 +- {},
17294 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
17295 + };
17296 +
17297 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
17298 +diff -urNp a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
17299 +--- a/drivers/acpi/sleep/main.c 2008-08-20 11:16:13.000000000 -0700
17300 ++++ b/drivers/acpi/sleep/main.c 2008-08-20 18:36:57.000000000 -0700
17301 +@@ -250,7 +250,7 @@ static struct dmi_system_id __initdata a
17302 + .ident = "Toshiba Satellite 4030cdt",
17303 + .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
17304 + },
17305 +- {},
17306 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
17307 + };
17308 + #endif /* CONFIG_SUSPEND */
17309 +
17310 +diff -urNp a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
17311 +--- a/drivers/acpi/tables/tbfadt.c 2008-08-20 11:16:13.000000000 -0700
17312 ++++ b/drivers/acpi/tables/tbfadt.c 2008-08-20 18:36:57.000000000 -0700
17313 +@@ -48,7 +48,7 @@
17314 + ACPI_MODULE_NAME("tbfadt")
17315 +
17316 + /* Local prototypes */
17317 +-static void inline
17318 ++static inline void
17319 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
17320 + u8 bit_width, u64 address);
17321 +
17322 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
17323 + *
17324 + ******************************************************************************/
17325 +
17326 +-static void inline
17327 ++static inline void
17328 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
17329 + u8 bit_width, u64 address)
17330 + {
17331 +diff -urNp a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
17332 +--- a/drivers/acpi/tables/tbxface.c 2008-08-20 11:16:13.000000000 -0700
17333 ++++ b/drivers/acpi/tables/tbxface.c 2008-08-20 18:36:57.000000000 -0700
17334 +@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac
17335 + acpi_tb_print_table_header(0, table);
17336 +
17337 + if (no_auto_ssdt == 0) {
17338 +- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
17339 ++ printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
17340 + }
17341 + }
17342 +
17343 +diff -urNp a/drivers/ata/ahci.c b/drivers/ata/ahci.c
17344 +--- a/drivers/ata/ahci.c 2008-08-20 11:16:13.000000000 -0700
17345 ++++ b/drivers/ata/ahci.c 2008-08-20 18:36:57.000000000 -0700
17346 +@@ -598,7 +598,7 @@ static const struct pci_device_id ahci_p
17347 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
17348 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
17349 +
17350 +- { } /* terminate list */
17351 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17352 + };
17353 +
17354 +
17355 +diff -urNp a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
17356 +--- a/drivers/ata/ata_piix.c 2008-08-20 11:16:13.000000000 -0700
17357 ++++ b/drivers/ata/ata_piix.c 2008-08-20 18:36:57.000000000 -0700
17358 +@@ -276,7 +276,7 @@ static const struct pci_device_id piix_p
17359 + /* SATA Controller IDE (ICH10) */
17360 + { 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
17361 +
17362 +- { } /* terminate list */
17363 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17364 + };
17365 +
17366 + static struct pci_driver piix_pci_driver = {
17367 +@@ -723,7 +723,7 @@ static const struct ich_laptop ich_lapto
17368 + { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
17369 + { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
17370 + /* end marker */
17371 +- { 0, }
17372 ++ { 0, 0, 0 }
17373 + };
17374 +
17375 + /**
17376 +@@ -1307,7 +1307,7 @@ static int piix_broken_suspend(void)
17377 + },
17378 + },
17379 +
17380 +- { } /* terminate list */
17381 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
17382 + };
17383 + static const char *oemstrs[] = {
17384 + "Tecra M3,",
17385 +diff -urNp a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
17386 +--- a/drivers/ata/libata-core.c 2008-08-20 11:16:13.000000000 -0700
17387 ++++ b/drivers/ata/libata-core.c 2008-08-20 18:36:57.000000000 -0700
17388 +@@ -725,7 +725,7 @@ static const struct ata_xfer_ent {
17389 + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
17390 + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
17391 + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
17392 +- { -1, },
17393 ++ { -1, 0, 0 }
17394 + };
17395 +
17396 + /**
17397 +@@ -3043,7 +3043,7 @@ static const struct ata_timing ata_timin
17398 + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
17399 + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
17400 +
17401 +- { 0xFF }
17402 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
17403 + };
17404 +
17405 + #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
17406 +@@ -4465,7 +4465,7 @@ static const struct ata_blacklist_entry
17407 + { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
17408 +
17409 + /* End Marker */
17410 +- { }
17411 ++ { NULL, NULL, 0 }
17412 + };
17413 +
17414 + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
17415 +diff -urNp a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
17416 +--- a/drivers/char/agp/frontend.c 2008-08-20 11:16:13.000000000 -0700
17417 ++++ b/drivers/char/agp/frontend.c 2008-08-20 18:36:57.000000000 -0700
17418 +@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
17419 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
17420 + return -EFAULT;
17421 +
17422 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
17423 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
17424 + return -EFAULT;
17425 +
17426 + client = agp_find_client_by_pid(reserve.pid);
17427 +diff -urNp a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
17428 +--- a/drivers/char/agp/intel-agp.c 2008-08-20 11:16:13.000000000 -0700
17429 ++++ b/drivers/char/agp/intel-agp.c 2008-08-20 18:36:57.000000000 -0700
17430 +@@ -2254,7 +2254,7 @@ static struct pci_device_id agp_intel_pc
17431 + ID(PCI_DEVICE_ID_INTEL_Q35_HB),
17432 + ID(PCI_DEVICE_ID_INTEL_Q33_HB),
17433 + ID(PCI_DEVICE_ID_INTEL_IGD_HB),
17434 +- { }
17435 ++ { 0, 0, 0, 0, 0, 0, 0 }
17436 + };
17437 +
17438 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
17439 +diff -urNp a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
17440 +--- a/drivers/char/drm/drm_pciids.h 2008-08-20 11:16:13.000000000 -0700
17441 ++++ b/drivers/char/drm/drm_pciids.h 2008-08-20 18:36:57.000000000 -0700
17442 +@@ -348,7 +348,7 @@
17443 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17444 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17445 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17446 +- {0, 0, 0}
17447 ++ {0, 0, 0, 0, 0, 0, 0 }
17448 +
17449 + #define i830_PCI_IDS \
17450 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17451 +diff -urNp a/drivers/char/hpet.c b/drivers/char/hpet.c
17452 +--- a/drivers/char/hpet.c 2008-08-20 11:16:13.000000000 -0700
17453 ++++ b/drivers/char/hpet.c 2008-08-20 18:36:57.000000000 -0700
17454 +@@ -953,7 +953,7 @@ static struct acpi_driver hpet_acpi_driv
17455 + },
17456 + };
17457 +
17458 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
17459 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
17460 +
17461 + static int __init hpet_init(void)
17462 + {
17463 +diff -urNp a/drivers/char/keyboard.c b/drivers/char/keyboard.c
17464 +--- a/drivers/char/keyboard.c 2008-08-20 11:16:13.000000000 -0700
17465 ++++ b/drivers/char/keyboard.c 2008-08-20 18:36:57.000000000 -0700
17466 +@@ -630,6 +630,16 @@ static void k_spec(struct vc_data *vc, u
17467 + kbd->kbdmode == VC_MEDIUMRAW) &&
17468 + value != KVAL(K_SAK))
17469 + return; /* SAK is allowed even in raw mode */
17470 ++
17471 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
17472 ++ {
17473 ++ void *func = fn_handler[value];
17474 ++ if (func == fn_show_state || func == fn_show_ptregs ||
17475 ++ func == fn_show_mem)
17476 ++ return;
17477 ++ }
17478 ++#endif
17479 ++
17480 + fn_handler[value](vc);
17481 + }
17482 +
17483 +@@ -1384,7 +1394,7 @@ static const struct input_device_id kbd_
17484 + .evbit = { BIT_MASK(EV_SND) },
17485 + },
17486 +
17487 +- { }, /* Terminating entry */
17488 ++ { 0 }, /* Terminating entry */
17489 + };
17490 +
17491 + MODULE_DEVICE_TABLE(input, kbd_ids);
17492 +diff -urNp a/drivers/char/mem.c b/drivers/char/mem.c
17493 +--- a/drivers/char/mem.c 2008-08-20 11:16:13.000000000 -0700
17494 ++++ b/drivers/char/mem.c 2008-08-20 18:36:57.000000000 -0700
17495 +@@ -26,6 +26,7 @@
17496 + #include <linux/bootmem.h>
17497 + #include <linux/splice.h>
17498 + #include <linux/pfn.h>
17499 ++#include <linux/grsecurity.h>
17500 +
17501 + #include <asm/uaccess.h>
17502 + #include <asm/io.h>
17503 +@@ -34,6 +35,10 @@
17504 + # include <linux/efi.h>
17505 + #endif
17506 +
17507 ++#ifdef CONFIG_GRKERNSEC
17508 ++extern struct file_operations grsec_fops;
17509 ++#endif
17510 ++
17511 + /*
17512 + * Architectures vary in how they handle caching for addresses
17513 + * outside of main memory.
17514 +@@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
17515 + if (!valid_phys_addr_range(p, count))
17516 + return -EFAULT;
17517 +
17518 ++#ifdef CONFIG_GRKERNSEC_KMEM
17519 ++ gr_handle_mem_write();
17520 ++ return -EPERM;
17521 ++#endif
17522 ++
17523 + written = 0;
17524 +
17525 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
17526 +@@ -281,6 +291,11 @@ static int mmap_mem(struct file * file,
17527 + if (!private_mapping_ok(vma))
17528 + return -ENOSYS;
17529 +
17530 ++#ifdef CONFIG_GRKERNSEC_KMEM
17531 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
17532 ++ return -EPERM;
17533 ++#endif
17534 ++
17535 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
17536 + size,
17537 + vma->vm_page_prot);
17538 +@@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file *
17539 + ssize_t written;
17540 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
17541 +
17542 ++#ifdef CONFIG_GRKERNSEC_KMEM
17543 ++ gr_handle_kmem_write();
17544 ++ return -EPERM;
17545 ++#endif
17546 ++
17547 + if (p < (unsigned long) high_memory) {
17548 +
17549 + wrote = count;
17550 +@@ -714,6 +734,16 @@ static loff_t memory_lseek(struct file *
17551 +
17552 + static int open_port(struct inode * inode, struct file * filp)
17553 + {
17554 ++#ifdef CONFIG_GRKERNSEC_KMEM
17555 ++ gr_handle_open_port();
17556 ++ return -EPERM;
17557 ++#endif
17558 ++
17559 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17560 ++}
17561 ++
17562 ++static int open_mem(struct inode * inode, struct file * filp)
17563 ++{
17564 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17565 + }
17566 +
17567 +@@ -721,7 +751,6 @@ static int open_port(struct inode * inod
17568 + #define full_lseek null_lseek
17569 + #define write_zero write_null
17570 + #define read_full read_zero
17571 +-#define open_mem open_port
17572 + #define open_kmem open_mem
17573 + #define open_oldmem open_mem
17574 +
17575 +@@ -854,6 +883,11 @@ static int memory_open(struct inode * in
17576 + filp->f_op = &oldmem_fops;
17577 + break;
17578 + #endif
17579 ++#ifdef CONFIG_GRKERNSEC
17580 ++ case 13:
17581 ++ filp->f_op = &grsec_fops;
17582 ++ break;
17583 ++#endif
17584 + default:
17585 + return -ENXIO;
17586 + }
17587 +@@ -886,6 +920,9 @@ static const struct {
17588 + #ifdef CONFIG_CRASH_DUMP
17589 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
17590 + #endif
17591 ++#ifdef CONFIG_GRKERNSEC
17592 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
17593 ++#endif
17594 + };
17595 +
17596 + static struct class *mem_class;
17597 +diff -urNp a/drivers/char/nvram.c b/drivers/char/nvram.c
17598 +--- a/drivers/char/nvram.c 2008-08-20 11:16:13.000000000 -0700
17599 ++++ b/drivers/char/nvram.c 2008-08-20 18:36:57.000000000 -0700
17600 +@@ -430,7 +430,10 @@ static const struct file_operations nvra
17601 + static struct miscdevice nvram_dev = {
17602 + NVRAM_MINOR,
17603 + "nvram",
17604 +- &nvram_fops
17605 ++ &nvram_fops,
17606 ++ {NULL, NULL},
17607 ++ NULL,
17608 ++ NULL
17609 + };
17610 +
17611 + static int __init
17612 +diff -urNp a/drivers/char/random.c b/drivers/char/random.c
17613 +--- a/drivers/char/random.c 2008-08-20 11:16:13.000000000 -0700
17614 ++++ b/drivers/char/random.c 2008-08-20 18:36:57.000000000 -0700
17615 +@@ -248,8 +248,13 @@
17616 + /*
17617 + * Configuration information
17618 + */
17619 ++#ifdef CONFIG_GRKERNSEC_RANDNET
17620 ++#define INPUT_POOL_WORDS 512
17621 ++#define OUTPUT_POOL_WORDS 128
17622 ++#else
17623 + #define INPUT_POOL_WORDS 128
17624 + #define OUTPUT_POOL_WORDS 32
17625 ++#endif
17626 + #define SEC_XFER_SIZE 512
17627 +
17628 + /*
17629 +@@ -286,10 +291,17 @@ static struct poolinfo {
17630 + int poolwords;
17631 + int tap1, tap2, tap3, tap4, tap5;
17632 + } poolinfo_table[] = {
17633 ++#ifdef CONFIG_GRKERNSEC_RANDNET
17634 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
17635 ++ { 512, 411, 308, 208, 104, 1 },
17636 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
17637 ++ { 128, 103, 76, 51, 25, 1 },
17638 ++#else
17639 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
17640 + { 128, 103, 76, 51, 25, 1 },
17641 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
17642 + { 32, 26, 20, 14, 7, 1 },
17643 ++#endif
17644 + #if 0
17645 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
17646 + { 2048, 1638, 1231, 819, 411, 1 },
17647 +@@ -1171,7 +1183,7 @@ EXPORT_SYMBOL(generate_random_uuid);
17648 + #include <linux/sysctl.h>
17649 +
17650 + static int min_read_thresh = 8, min_write_thresh;
17651 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
17652 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
17653 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
17654 + static char sysctl_bootid[16];
17655 +
17656 +diff -urNp a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
17657 +--- a/drivers/char/tpm/tpm.c 2008-08-20 11:16:13.000000000 -0700
17658 ++++ b/drivers/char/tpm/tpm.c 2008-08-20 18:36:57.000000000 -0700
17659 +@@ -970,7 +970,7 @@ ssize_t tpm_write(struct file *file, con
17660 +
17661 + mutex_lock(&chip->buffer_mutex);
17662 +
17663 +- if (in_size > TPM_BUFSIZE)
17664 ++ if (in_size > (unsigned int)TPM_BUFSIZE)
17665 + in_size = TPM_BUFSIZE;
17666 +
17667 + if (copy_from_user
17668 +diff -urNp a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
17669 +--- a/drivers/char/vt_ioctl.c 2008-08-20 11:16:13.000000000 -0700
17670 ++++ b/drivers/char/vt_ioctl.c 2008-08-20 18:36:57.000000000 -0700
17671 +@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
17672 + case KDSKBENT:
17673 + if (!perm)
17674 + return -EPERM;
17675 ++
17676 ++#ifdef CONFIG_GRKERNSEC
17677 ++ if (!capable(CAP_SYS_TTY_CONFIG))
17678 ++ return -EPERM;
17679 ++#endif
17680 ++
17681 + if (!i && v == K_NOSUCHMAP) {
17682 + /* deallocate map */
17683 + key_map = key_maps[s];
17684 +@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
17685 + goto reterr;
17686 + }
17687 +
17688 ++#ifdef CONFIG_GRKERNSEC
17689 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
17690 ++ ret = -EPERM;
17691 ++ goto reterr;
17692 ++ }
17693 ++#endif
17694 ++
17695 + q = func_table[i];
17696 + first_free = funcbufptr + (funcbufsize - funcbufleft);
17697 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
17698 +diff -urNp a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
17699 +--- a/drivers/edac/edac_core.h 2008-08-20 11:16:13.000000000 -0700
17700 ++++ b/drivers/edac/edac_core.h 2008-08-20 18:36:57.000000000 -0700
17701 +@@ -86,11 +86,11 @@ extern int edac_debug_level;
17702 +
17703 + #else /* !CONFIG_EDAC_DEBUG */
17704 +
17705 +-#define debugf0( ... )
17706 +-#define debugf1( ... )
17707 +-#define debugf2( ... )
17708 +-#define debugf3( ... )
17709 +-#define debugf4( ... )
17710 ++#define debugf0( ... ) do {} while (0)
17711 ++#define debugf1( ... ) do {} while (0)
17712 ++#define debugf2( ... ) do {} while (0)
17713 ++#define debugf3( ... ) do {} while (0)
17714 ++#define debugf4( ... ) do {} while (0)
17715 +
17716 + #endif /* !CONFIG_EDAC_DEBUG */
17717 +
17718 +diff -urNp a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
17719 +--- a/drivers/firmware/dmi_scan.c 2008-08-20 11:16:13.000000000 -0700
17720 ++++ b/drivers/firmware/dmi_scan.c 2008-08-20 18:36:57.000000000 -0700
17721 +@@ -379,11 +379,6 @@ void __init dmi_scan_machine(void)
17722 + }
17723 + }
17724 + else {
17725 +- /*
17726 +- * no iounmap() for that ioremap(); it would be a no-op, but
17727 +- * it's so early in setup that sucker gets confused into doing
17728 +- * what it shouldn't if we actually call it.
17729 +- */
17730 + p = dmi_ioremap(0xF0000, 0x10000);
17731 + if (p == NULL)
17732 + goto out;
17733 +diff -urNp a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
17734 +--- a/drivers/hwmon/fscpos.c 2008-08-20 11:16:13.000000000 -0700
17735 ++++ b/drivers/hwmon/fscpos.c 2008-08-20 18:36:57.000000000 -0700
17736 +@@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
17737 + unsigned long v = simple_strtoul(buf, NULL, 10);
17738 +
17739 + /* Range: 0..255 */
17740 +- if (v < 0) v = 0;
17741 + if (v > 255) v = 255;
17742 +
17743 + mutex_lock(&data->update_lock);
17744 +diff -urNp a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
17745 +--- a/drivers/hwmon/k8temp.c 2008-08-20 11:16:13.000000000 -0700
17746 ++++ b/drivers/hwmon/k8temp.c 2008-08-20 18:36:57.000000000 -0700
17747 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
17748 +
17749 + static struct pci_device_id k8temp_ids[] = {
17750 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
17751 +- { 0 },
17752 ++ { 0, 0, 0, 0, 0, 0, 0 },
17753 + };
17754 +
17755 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
17756 +diff -urNp a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
17757 +--- a/drivers/hwmon/sis5595.c 2008-08-20 11:16:13.000000000 -0700
17758 ++++ b/drivers/hwmon/sis5595.c 2008-08-20 18:36:57.000000000 -0700
17759 +@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
17760 +
17761 + static struct pci_device_id sis5595_pci_ids[] = {
17762 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
17763 +- { 0, }
17764 ++ { 0, 0, 0, 0, 0, 0, 0 }
17765 + };
17766 +
17767 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
17768 +diff -urNp a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
17769 +--- a/drivers/hwmon/via686a.c 2008-08-20 11:16:13.000000000 -0700
17770 ++++ b/drivers/hwmon/via686a.c 2008-08-20 18:36:57.000000000 -0700
17771 +@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
17772 +
17773 + static struct pci_device_id via686a_pci_ids[] = {
17774 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
17775 +- { 0, }
17776 ++ { 0, 0, 0, 0, 0, 0, 0 }
17777 + };
17778 +
17779 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
17780 +diff -urNp a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
17781 +--- a/drivers/hwmon/vt8231.c 2008-08-20 11:16:13.000000000 -0700
17782 ++++ b/drivers/hwmon/vt8231.c 2008-08-20 18:36:57.000000000 -0700
17783 +@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
17784 +
17785 + static struct pci_device_id vt8231_pci_ids[] = {
17786 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
17787 +- { 0, }
17788 ++ { 0, 0, 0, 0, 0, 0, 0 }
17789 + };
17790 +
17791 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
17792 +diff -urNp a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
17793 +--- a/drivers/hwmon/w83791d.c 2008-08-20 11:16:13.000000000 -0700
17794 ++++ b/drivers/hwmon/w83791d.c 2008-08-20 18:36:57.000000000 -0700
17795 +@@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
17796 + static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
17797 + static int w83791d_detach_client(struct i2c_client *client);
17798 +
17799 +-static int w83791d_read(struct i2c_client *client, u8 register);
17800 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
17801 ++static int w83791d_read(struct i2c_client *client, u8 reg);
17802 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
17803 + static struct w83791d_data *w83791d_update_device(struct device *dev);
17804 +
17805 + #ifdef DEBUG
17806 +diff -urNp a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
17807 +--- a/drivers/i2c/busses/i2c-i801.c 2008-08-20 11:16:13.000000000 -0700
17808 ++++ b/drivers/i2c/busses/i2c-i801.c 2008-08-20 18:36:57.000000000 -0700
17809 +@@ -592,7 +592,7 @@ static struct pci_device_id i801_ids[] =
17810 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
17811 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
17812 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
17813 +- { 0, }
17814 ++ { 0, 0, 0, 0, 0, 0, 0 }
17815 + };
17816 +
17817 + MODULE_DEVICE_TABLE (pci, i801_ids);
17818 +diff -urNp a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
17819 +--- a/drivers/i2c/busses/i2c-i810.c 2008-08-20 11:16:13.000000000 -0700
17820 ++++ b/drivers/i2c/busses/i2c-i810.c 2008-08-20 18:36:57.000000000 -0700
17821 +@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
17822 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
17823 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
17824 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
17825 +- { 0, },
17826 ++ { 0, 0, 0, 0, 0, 0, 0 },
17827 + };
17828 +
17829 + MODULE_DEVICE_TABLE (pci, i810_ids);
17830 +diff -urNp a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
17831 +--- a/drivers/i2c/busses/i2c-piix4.c 2008-08-20 11:16:13.000000000 -0700
17832 ++++ b/drivers/i2c/busses/i2c-piix4.c 2008-08-20 18:36:57.000000000 -0700
17833 +@@ -133,7 +133,7 @@ static struct dmi_system_id __devinitdat
17834 + .ident = "IBM",
17835 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
17836 + },
17837 +- { },
17838 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
17839 + };
17840 +
17841 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
17842 +@@ -428,7 +428,7 @@ static struct pci_device_id piix4_ids[]
17843 + PCI_DEVICE_ID_SERVERWORKS_CSB6) },
17844 + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
17845 + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
17846 +- { 0, }
17847 ++ { 0, 0, 0, 0, 0, 0, 0 }
17848 + };
17849 +
17850 + MODULE_DEVICE_TABLE (pci, piix4_ids);
17851 +diff -urNp a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
17852 +--- a/drivers/i2c/busses/i2c-sis630.c 2008-08-20 11:16:13.000000000 -0700
17853 ++++ b/drivers/i2c/busses/i2c-sis630.c 2008-08-20 18:36:57.000000000 -0700
17854 +@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
17855 + static struct pci_device_id sis630_ids[] __devinitdata = {
17856 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
17857 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
17858 +- { 0, }
17859 ++ { 0, 0, 0, 0, 0, 0, 0 }
17860 + };
17861 +
17862 + MODULE_DEVICE_TABLE (pci, sis630_ids);
17863 +diff -urNp a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
17864 +--- a/drivers/i2c/busses/i2c-sis96x.c 2008-08-20 11:16:13.000000000 -0700
17865 ++++ b/drivers/i2c/busses/i2c-sis96x.c 2008-08-20 18:36:57.000000000 -0700
17866 +@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
17867 +
17868 + static struct pci_device_id sis96x_ids[] = {
17869 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
17870 +- { 0, }
17871 ++ { 0, 0, 0, 0, 0, 0, 0 }
17872 + };
17873 +
17874 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
17875 +diff -urNp a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
17876 +--- a/drivers/ide/ide-cd.c 2008-08-20 11:16:13.000000000 -0700
17877 ++++ b/drivers/ide/ide-cd.c 2008-08-20 18:36:57.000000000 -0700
17878 +@@ -182,8 +182,6 @@ void cdrom_analyze_sense_data(ide_drive_
17879 + sector &= ~(bio_sectors -1);
17880 + valid = (sector - failed_command->sector) << 9;
17881 +
17882 +- if (valid < 0)
17883 +- valid = 0;
17884 + if (sector < get_capacity(info->disk) &&
17885 + drive->probed_capacity - sector < 4 * 75) {
17886 + set_capacity(info->disk, sector);
17887 +diff -urNp a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
17888 +--- a/drivers/ieee1394/dv1394.c 2008-08-20 11:16:13.000000000 -0700
17889 ++++ b/drivers/ieee1394/dv1394.c 2008-08-20 18:36:57.000000000 -0700
17890 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
17891 + based upon DIF section and sequence
17892 + */
17893 +
17894 +-static void inline
17895 ++static inline void
17896 + frame_put_packet (struct frame *f, struct packet *p)
17897 + {
17898 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
17899 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
17900 + /* default SYT offset is 3 cycles */
17901 + init->syt_offset = 3;
17902 +
17903 +- if ( (init->channel > 63) || (init->channel < 0) )
17904 ++ if (init->channel > 63)
17905 + init->channel = 63;
17906 +
17907 + chan_mask = (u64)1 << init->channel;
17908 +@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
17909 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
17910 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
17911 + },
17912 +- { }
17913 ++ { 0, 0, 0, 0, 0, 0 }
17914 + };
17915 +
17916 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
17917 +diff -urNp a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
17918 +--- a/drivers/ieee1394/eth1394.c 2008-08-20 11:16:13.000000000 -0700
17919 ++++ b/drivers/ieee1394/eth1394.c 2008-08-20 18:36:57.000000000 -0700
17920 +@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
17921 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
17922 + .version = ETHER1394_GASP_VERSION,
17923 + },
17924 +- {}
17925 ++ { 0, 0, 0, 0, 0, 0 }
17926 + };
17927 +
17928 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
17929 +diff -urNp a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
17930 +--- a/drivers/ieee1394/hosts.c 2008-08-20 11:16:13.000000000 -0700
17931 ++++ b/drivers/ieee1394/hosts.c 2008-08-20 18:36:57.000000000 -0700
17932 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
17933 + }
17934 +
17935 + static struct hpsb_host_driver dummy_driver = {
17936 ++ .name = "dummy",
17937 + .transmit_packet = dummy_transmit_packet,
17938 + .devctl = dummy_devctl,
17939 + .isoctl = dummy_isoctl
17940 +diff -urNp a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
17941 +--- a/drivers/ieee1394/ohci1394.c 2008-08-20 11:16:13.000000000 -0700
17942 ++++ b/drivers/ieee1394/ohci1394.c 2008-08-20 18:36:57.000000000 -0700
17943 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
17944 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
17945 +
17946 + /* Module Parameters */
17947 +-static int phys_dma = 1;
17948 ++static int phys_dma;
17949 + module_param(phys_dma, int, 0444);
17950 +-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
17951 ++MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
17952 +
17953 + static void dma_trm_tasklet(unsigned long data);
17954 + static void dma_trm_reset(struct dma_trm_ctx *d);
17955 +@@ -3400,7 +3400,7 @@ static struct pci_device_id ohci1394_pci
17956 + .subvendor = PCI_ANY_ID,
17957 + .subdevice = PCI_ANY_ID,
17958 + },
17959 +- { 0, },
17960 ++ { 0, 0, 0, 0, 0, 0, 0 },
17961 + };
17962 +
17963 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
17964 +diff -urNp a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
17965 +--- a/drivers/ieee1394/raw1394.c 2008-08-20 11:16:13.000000000 -0700
17966 ++++ b/drivers/ieee1394/raw1394.c 2008-08-20 18:36:57.000000000 -0700
17967 +@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
17968 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
17969 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
17970 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
17971 +- {}
17972 ++ { 0, 0, 0, 0, 0, 0 }
17973 + };
17974 +
17975 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
17976 +diff -urNp a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
17977 +--- a/drivers/ieee1394/sbp2.c 2008-08-20 11:16:13.000000000 -0700
17978 ++++ b/drivers/ieee1394/sbp2.c 2008-08-20 18:36:57.000000000 -0700
17979 +@@ -283,7 +283,7 @@ static struct ieee1394_device_id sbp2_id
17980 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
17981 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
17982 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
17983 +- {}
17984 ++ { 0, 0, 0, 0, 0, 0 }
17985 + };
17986 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
17987 +
17988 +@@ -2108,7 +2108,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
17989 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
17990 + MODULE_LICENSE("GPL");
17991 +
17992 +-static int sbp2_module_init(void)
17993 ++static int __init sbp2_module_init(void)
17994 + {
17995 + int ret;
17996 +
17997 +diff -urNp a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
17998 +--- a/drivers/ieee1394/video1394.c 2008-08-20 11:16:13.000000000 -0700
17999 ++++ b/drivers/ieee1394/video1394.c 2008-08-20 18:36:57.000000000 -0700
18000 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
18001 + if (unlikely(d == NULL))
18002 + return -EFAULT;
18003 +
18004 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
18005 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
18006 + PRINT(KERN_ERR, ohci->host->id,
18007 + "Buffer %d out of range",v.buffer);
18008 + return -EINVAL;
18009 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
18010 + if (unlikely(d == NULL))
18011 + return -EFAULT;
18012 +
18013 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
18014 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
18015 + PRINT(KERN_ERR, ohci->host->id,
18016 + "Buffer %d out of range",v.buffer);
18017 + return -EINVAL;
18018 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
18019 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
18020 + if (d == NULL) return -EFAULT;
18021 +
18022 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
18023 ++ if (v.buffer>=d->num_desc - 1) {
18024 + PRINT(KERN_ERR, ohci->host->id,
18025 + "Buffer %d out of range",v.buffer);
18026 + return -EINVAL;
18027 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
18028 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
18029 + if (d == NULL) return -EFAULT;
18030 +
18031 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
18032 ++ if (v.buffer>=d->num_desc-1) {
18033 + PRINT(KERN_ERR, ohci->host->id,
18034 + "Buffer %d out of range",v.buffer);
18035 + return -EINVAL;
18036 +@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
18037 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
18038 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
18039 + },
18040 +- { }
18041 ++ { 0, 0, 0, 0, 0, 0 }
18042 + };
18043 +
18044 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
18045 +diff -urNp a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
18046 +--- a/drivers/input/keyboard/atkbd.c 2008-08-20 11:16:13.000000000 -0700
18047 ++++ b/drivers/input/keyboard/atkbd.c 2008-08-20 18:36:57.000000000 -0700
18048 +@@ -1113,7 +1113,7 @@ static struct serio_device_id atkbd_seri
18049 + .id = SERIO_ANY,
18050 + .extra = SERIO_ANY,
18051 + },
18052 +- { 0 }
18053 ++ { 0, 0, 0, 0 }
18054 + };
18055 +
18056 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
18057 +diff -urNp a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
18058 +--- a/drivers/input/mouse/lifebook.c 2008-08-20 11:16:13.000000000 -0700
18059 ++++ b/drivers/input/mouse/lifebook.c 2008-08-20 18:36:57.000000000 -0700
18060 +@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
18061 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
18062 + },
18063 + },
18064 +- { }
18065 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
18066 + };
18067 +
18068 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
18069 +diff -urNp a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
18070 +--- a/drivers/input/mouse/psmouse-base.c 2008-08-20 11:16:13.000000000 -0700
18071 ++++ b/drivers/input/mouse/psmouse-base.c 2008-08-20 18:36:57.000000000 -0700
18072 +@@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
18073 + .id = SERIO_ANY,
18074 + .extra = SERIO_ANY,
18075 + },
18076 +- { 0 }
18077 ++ { 0, 0, 0, 0 }
18078 + };
18079 +
18080 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
18081 +diff -urNp a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
18082 +--- a/drivers/input/mouse/synaptics.c 2008-08-20 11:16:13.000000000 -0700
18083 ++++ b/drivers/input/mouse/synaptics.c 2008-08-20 18:36:57.000000000 -0700
18084 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
18085 + break;
18086 + case 2:
18087 + if (SYN_MODEL_PEN(priv->model_id))
18088 +- ; /* Nothing, treat a pen as a single finger */
18089 ++ break; /* Nothing, treat a pen as a single finger */
18090 + break;
18091 + case 4 ... 15:
18092 + if (SYN_CAP_PALMDETECT(priv->capabilities))
18093 +@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
18094 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
18095 + },
18096 + },
18097 +- { }
18098 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18099 + };
18100 + #endif
18101 +
18102 +diff -urNp a/drivers/input/mousedev.c b/drivers/input/mousedev.c
18103 +--- a/drivers/input/mousedev.c 2008-08-20 11:16:13.000000000 -0700
18104 ++++ b/drivers/input/mousedev.c 2008-08-20 18:36:57.000000000 -0700
18105 +@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
18106 +
18107 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
18108 + static struct miscdevice psaux_mouse = {
18109 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
18110 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
18111 + };
18112 + static int psaux_registered;
18113 + #endif
18114 +diff -urNp a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
18115 +--- a/drivers/input/serio/i8042-x86ia64io.h 2008-08-20 11:16:13.000000000 -0700
18116 ++++ b/drivers/input/serio/i8042-x86ia64io.h 2008-08-20 18:36:57.000000000 -0700
18117 +@@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
18118 + DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
18119 + },
18120 + },
18121 +- { }
18122 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18123 + };
18124 +
18125 + /*
18126 +@@ -305,7 +305,7 @@ static struct dmi_system_id __initdata i
18127 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
18128 + },
18129 + },
18130 +- { }
18131 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18132 + };
18133 +
18134 + #ifdef CONFIG_PNP
18135 +diff -urNp a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
18136 +--- a/drivers/input/serio/serio_raw.c 2008-08-20 11:16:13.000000000 -0700
18137 ++++ b/drivers/input/serio/serio_raw.c 2008-08-20 18:36:57.000000000 -0700
18138 +@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
18139 + .id = SERIO_ANY,
18140 + .extra = SERIO_ANY,
18141 + },
18142 +- { 0 }
18143 ++ { 0, 0, 0, 0 }
18144 + };
18145 +
18146 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
18147 +diff -urNp a/drivers/md/bitmap.c b/drivers/md/bitmap.c
18148 +--- a/drivers/md/bitmap.c 2008-08-20 11:16:13.000000000 -0700
18149 ++++ b/drivers/md/bitmap.c 2008-08-20 18:36:57.000000000 -0700
18150 +@@ -57,7 +57,7 @@
18151 + # if DEBUG > 0
18152 + # define PRINTK(x...) printk(KERN_DEBUG x)
18153 + # else
18154 +-# define PRINTK(x...)
18155 ++# define PRINTK(x...) do {} while (0)
18156 + # endif
18157 + #endif
18158 +
18159 +diff -urNp a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
18160 +--- a/drivers/mtd/devices/doc2000.c 2008-08-20 11:16:13.000000000 -0700
18161 ++++ b/drivers/mtd/devices/doc2000.c 2008-08-20 18:36:57.000000000 -0700
18162 +@@ -779,7 +779,7 @@ static int doc_write(struct mtd_info *mt
18163 +
18164 + /* The ECC will not be calculated correctly if less than 512 is written */
18165 + /* DBB-
18166 +- if (len != 0x200 && eccbuf)
18167 ++ if (len != 0x200)
18168 + printk(KERN_WARNING
18169 + "ECC needs a full sector write (adr: %lx size %lx)\n",
18170 + (long) to, (long) len);
18171 +diff -urNp a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
18172 +--- a/drivers/mtd/devices/doc2001.c 2008-08-20 11:16:13.000000000 -0700
18173 ++++ b/drivers/mtd/devices/doc2001.c 2008-08-20 18:36:57.000000000 -0700
18174 +@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
18175 + /* Don't allow read past end of device */
18176 + if (from >= this->totlen)
18177 + return -EINVAL;
18178 ++ if (!len)
18179 ++ return -EINVAL;
18180 +
18181 + /* Don't allow a single read to cross a 512-byte block boundary */
18182 + if (from + len > ((from | 0x1ff) + 1))
18183 +diff -urNp a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
18184 +--- a/drivers/mtd/devices/slram.c 2008-08-20 11:16:13.000000000 -0700
18185 ++++ b/drivers/mtd/devices/slram.c 2008-08-20 18:36:57.000000000 -0700
18186 +@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
18187 + }
18188 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
18189 + devname, devstart, devlength);
18190 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
18191 ++ if (devlength % SLRAM_BLK_SZ != 0) {
18192 + E("slram: Illegal start / length parameter.\n");
18193 + return(-EINVAL);
18194 + }
18195 +diff -urNp a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
18196 +--- a/drivers/mtd/ubi/build.c 2008-08-20 11:16:13.000000000 -0700
18197 ++++ b/drivers/mtd/ubi/build.c 2008-08-20 18:36:57.000000000 -0700
18198 +@@ -1059,7 +1059,7 @@ static int __init bytes_str_to_int(const
18199 + unsigned long result;
18200 +
18201 + result = simple_strtoul(str, &endp, 0);
18202 +- if (str == endp || result < 0) {
18203 ++ if (str == endp) {
18204 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
18205 + str);
18206 + return -EINVAL;
18207 +diff -urNp a/drivers/net/eepro100.c b/drivers/net/eepro100.c
18208 +--- a/drivers/net/eepro100.c 2008-08-20 11:16:13.000000000 -0700
18209 ++++ b/drivers/net/eepro100.c 2008-08-20 18:36:57.000000000 -0700
18210 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
18211 + # define rx_align(skb) skb_reserve((skb), 2)
18212 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
18213 + #else
18214 +-# define rx_align(skb)
18215 ++# define rx_align(skb) do {} while (0)
18216 + # define RxFD_ALIGNMENT
18217 + #endif
18218 +
18219 +@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
18220 + }
18221 +
18222 + static struct pci_device_id eepro100_pci_tbl[] = {
18223 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
18224 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
18225 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
18226 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
18227 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
18228 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
18229 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
18230 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
18231 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
18232 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
18233 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
18234 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
18235 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
18236 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
18237 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
18238 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
18239 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
18240 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
18241 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
18242 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
18243 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
18244 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
18245 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
18246 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
18247 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
18248 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
18249 +- { 0,}
18250 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18251 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18252 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18253 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18254 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18255 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18256 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18257 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18258 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18259 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18260 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18261 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18262 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18263 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18264 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18265 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18266 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18267 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18268 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18269 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18270 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18271 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18272 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18273 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18274 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18275 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18276 ++ { 0, 0, 0, 0, 0, 0, 0 }
18277 + };
18278 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
18279 +
18280 +diff -urNp a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
18281 +--- a/drivers/net/irda/vlsi_ir.c 2008-08-20 11:16:13.000000000 -0700
18282 ++++ b/drivers/net/irda/vlsi_ir.c 2008-08-20 18:36:57.000000000 -0700
18283 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
18284 + /* no race - tx-ring already empty */
18285 + vlsi_set_baud(idev, iobase);
18286 + netif_wake_queue(ndev);
18287 +- }
18288 +- else
18289 +- ;
18290 ++ } else {
18291 + /* keep the speed change pending like it would
18292 + * for any len>0 packet. tx completion interrupt
18293 + * will apply it when the tx ring becomes empty.
18294 + */
18295 ++ }
18296 + spin_unlock_irqrestore(&idev->lock, flags);
18297 + dev_kfree_skb_any(skb);
18298 + return 0;
18299 +diff -urNp a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
18300 +--- a/drivers/net/pcnet32.c 2008-08-20 11:16:13.000000000 -0700
18301 ++++ b/drivers/net/pcnet32.c 2008-08-20 18:36:57.000000000 -0700
18302 +@@ -82,7 +82,7 @@ static int cards_found;
18303 + /*
18304 + * VLB I/O addresses
18305 + */
18306 +-static unsigned int pcnet32_portlist[] __initdata =
18307 ++static unsigned int pcnet32_portlist[] __devinitdata =
18308 + { 0x300, 0x320, 0x340, 0x360, 0 };
18309 +
18310 + static int pcnet32_debug = 0;
18311 +diff -urNp a/drivers/net/tg3.h b/drivers/net/tg3.h
18312 +--- a/drivers/net/tg3.h 2008-08-20 11:16:13.000000000 -0700
18313 ++++ b/drivers/net/tg3.h 2008-08-20 18:36:57.000000000 -0700
18314 +@@ -102,6 +102,7 @@
18315 + #define CHIPREV_ID_5750_A0 0x4000
18316 + #define CHIPREV_ID_5750_A1 0x4001
18317 + #define CHIPREV_ID_5750_A3 0x4003
18318 ++#define CHIPREV_ID_5750_C1 0x4201
18319 + #define CHIPREV_ID_5750_C2 0x4202
18320 + #define CHIPREV_ID_5752_A0_HW 0x5000
18321 + #define CHIPREV_ID_5752_A0 0x6000
18322 +diff -urNp a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
18323 +--- a/drivers/pci/hotplug/cpqphp_nvram.c 2008-08-20 11:16:13.000000000 -0700
18324 ++++ b/drivers/pci/hotplug/cpqphp_nvram.c 2008-08-20 18:36:57.000000000 -0700
18325 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
18326 +
18327 + void compaq_nvram_init (void __iomem *rom_start)
18328 + {
18329 ++
18330 ++#ifndef CONFIG_PAX_KERNEXEC
18331 + if (rom_start) {
18332 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
18333 + }
18334 ++#endif
18335 ++
18336 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
18337 +
18338 + /* initialize our int15 lock */
18339 +diff -urNp a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
18340 +--- a/drivers/pci/pcie/aer/aerdrv.c 2008-08-20 11:16:13.000000000 -0700
18341 ++++ b/drivers/pci/pcie/aer/aerdrv.c 2008-08-20 18:36:57.000000000 -0700
18342 +@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
18343 + .port_type = PCIE_RC_PORT,
18344 + .service_type = PCIE_PORT_SERVICE_AER,
18345 + },
18346 +- { /* end: all zeroes */ }
18347 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18348 + };
18349 +
18350 + static struct pci_error_handlers aer_error_handlers = {
18351 +diff -urNp a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
18352 +--- a/drivers/pci/pcie/aer/aerdrv_core.c 2008-08-20 11:16:13.000000000 -0700
18353 ++++ b/drivers/pci/pcie/aer/aerdrv_core.c 2008-08-20 18:36:57.000000000 -0700
18354 +@@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci
18355 + struct aer_err_source *e_src)
18356 + {
18357 + struct device *s_device;
18358 +- struct aer_err_info e_info = {0, 0, 0,};
18359 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
18360 + int i;
18361 + u16 id;
18362 +
18363 +diff -urNp a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
18364 +--- a/drivers/pci/pcie/portdrv_pci.c 2008-08-20 11:16:13.000000000 -0700
18365 ++++ b/drivers/pci/pcie/portdrv_pci.c 2008-08-20 18:36:57.000000000 -0700
18366 +@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
18367 + static const struct pci_device_id port_pci_ids[] = { {
18368 + /* handle any PCI-Express port */
18369 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
18370 +- }, { /* end: all zeroes */ }
18371 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
18372 + };
18373 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
18374 +
18375 +diff -urNp a/drivers/pci/proc.c b/drivers/pci/proc.c
18376 +--- a/drivers/pci/proc.c 2008-08-20 11:16:13.000000000 -0700
18377 ++++ b/drivers/pci/proc.c 2008-08-20 18:36:57.000000000 -0700
18378 +@@ -472,7 +472,15 @@ static int __init pci_proc_init(void)
18379 + {
18380 + struct proc_dir_entry *entry;
18381 + struct pci_dev *dev = NULL;
18382 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
18383 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
18384 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
18385 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
18386 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
18387 ++#endif
18388 ++#else
18389 + proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
18390 ++#endif
18391 + entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
18392 + if (entry)
18393 + entry->proc_fops = &proc_bus_pci_dev_operations;
18394 +diff -urNp a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
18395 +--- a/drivers/pcmcia/ti113x.h 2008-08-20 11:16:13.000000000 -0700
18396 ++++ b/drivers/pcmcia/ti113x.h 2008-08-20 18:36:57.000000000 -0700
18397 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
18398 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
18399 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
18400 +
18401 +- {}
18402 ++ { 0, 0, 0, 0, 0, 0, 0 }
18403 + };
18404 +
18405 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
18406 +diff -urNp a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
18407 +--- a/drivers/pcmcia/yenta_socket.c 2008-08-20 11:16:13.000000000 -0700
18408 ++++ b/drivers/pcmcia/yenta_socket.c 2008-08-20 18:36:57.000000000 -0700
18409 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
18410 +
18411 + /* match any cardbus bridge */
18412 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
18413 +- { /* all zeroes */ }
18414 ++ { 0, 0, 0, 0, 0, 0, 0 }
18415 + };
18416 + MODULE_DEVICE_TABLE(pci, yenta_table);
18417 +
18418 +diff -urNp a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
18419 +--- a/drivers/pnp/pnpbios/bioscalls.c 2008-08-20 11:16:13.000000000 -0700
18420 ++++ b/drivers/pnp/pnpbios/bioscalls.c 2008-08-20 18:36:57.000000000 -0700
18421 +@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
18422 + set_limit(gdt[(selname) >> 3], size); \
18423 + } while(0)
18424 +
18425 +-static struct desc_struct bad_bios_desc;
18426 ++static struct desc_struct bad_bios_desc __read_only;
18427 +
18428 + /*
18429 + * At some point we want to use this stack frame pointer to unwind
18430 +@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
18431 + struct desc_struct save_desc_40;
18432 + int cpu;
18433 +
18434 ++#ifdef CONFIG_PAX_KERNEXEC
18435 ++ unsigned long cr0;
18436 ++#endif
18437 ++
18438 + /*
18439 + * PnP BIOSes are generally not terribly re-entrant.
18440 + * Also, don't rely on them to save everything correctly.
18441 +@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
18442 +
18443 + cpu = get_cpu();
18444 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
18445 ++
18446 ++#ifdef CONFIG_PAX_KERNEXEC
18447 ++ pax_open_kernel(cr0);
18448 ++#endif
18449 ++
18450 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
18451 +
18452 ++#ifdef CONFIG_PAX_KERNEXEC
18453 ++ pax_close_kernel(cr0);
18454 ++#endif
18455 ++
18456 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
18457 + spin_lock_irqsave(&pnp_bios_lock, flags);
18458 +
18459 +@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
18460 + :"memory");
18461 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
18462 +
18463 ++#ifdef CONFIG_PAX_KERNEXEC
18464 ++ pax_open_kernel(cr0);
18465 ++#endif
18466 ++
18467 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
18468 ++
18469 ++#ifdef CONFIG_PAX_KERNEXEC
18470 ++ pax_close_kernel(cr0);
18471 ++#endif
18472 ++
18473 + put_cpu();
18474 +
18475 + /* If we get here and this is set then the PnP BIOS faulted on us. */
18476 +@@ -469,16 +491,24 @@ int pnp_bios_read_escd(char *data, u32 n
18477 + return status;
18478 + }
18479 +
18480 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
18481 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
18482 + {
18483 + int i;
18484 +
18485 ++#ifdef CONFIG_PAX_KERNEXEC
18486 ++ unsigned long cr0;
18487 ++#endif
18488 ++
18489 + spin_lock_init(&pnp_bios_lock);
18490 + pnp_bios_callpoint.offset = header->fields.pm16offset;
18491 + pnp_bios_callpoint.segment = PNP_CS16;
18492 +
18493 ++#ifdef CONFIG_PAX_KERNEXEC
18494 ++ pax_open_kernel(cr0);
18495 ++#endif
18496 ++
18497 + bad_bios_desc.a = 0;
18498 +- bad_bios_desc.b = 0x00409200;
18499 ++ bad_bios_desc.b = 0x00409300;
18500 +
18501 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
18502 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
18503 +@@ -492,4 +522,9 @@ void pnpbios_calls_init(union pnp_bios_i
18504 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
18505 + __va(header->fields.pm16dseg));
18506 + }
18507 ++
18508 ++#ifdef CONFIG_PAX_KERNEXEC
18509 ++ pax_close_kernel(cr0);
18510 ++#endif
18511 ++
18512 + }
18513 +diff -urNp a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
18514 +--- a/drivers/pnp/quirks.c 2008-08-20 11:16:13.000000000 -0700
18515 ++++ b/drivers/pnp/quirks.c 2008-08-20 18:36:57.000000000 -0700
18516 +@@ -201,7 +201,7 @@ static struct pnp_fixup pnp_fixups[] = {
18517 + {"CTL0045", quirk_sb16audio_resources},
18518 + {"PNP0c01", quirk_system_pci_resources},
18519 + {"PNP0c02", quirk_system_pci_resources},
18520 +- {""}
18521 ++ {"", NULL}
18522 + };
18523 +
18524 + void pnp_fixup_device(struct pnp_dev *dev)
18525 +diff -urNp a/drivers/pnp/resource.c b/drivers/pnp/resource.c
18526 +--- a/drivers/pnp/resource.c 2008-08-20 11:16:13.000000000 -0700
18527 ++++ b/drivers/pnp/resource.c 2008-08-20 18:36:57.000000000 -0700
18528 +@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
18529 + return 1;
18530 +
18531 + /* check if the resource is valid */
18532 +- if (*irq < 0 || *irq > 15)
18533 ++ if (*irq > 15)
18534 + return 0;
18535 +
18536 + /* check if the resource is reserved */
18537 +@@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
18538 + return 1;
18539 +
18540 + /* check if the resource is valid */
18541 +- if (*dma < 0 || *dma == 4 || *dma > 7)
18542 ++ if (*dma == 4 || *dma > 7)
18543 + return 0;
18544 +
18545 + /* check if the resource is reserved */
18546 +diff -urNp a/drivers/scsi/scsi_logging.h b/drivers/scsi/scsi_logging.h
18547 +--- a/drivers/scsi/scsi_logging.h 2008-08-20 11:16:13.000000000 -0700
18548 ++++ b/drivers/scsi/scsi_logging.h 2008-08-20 18:36:57.000000000 -0700
18549 +@@ -51,7 +51,7 @@ do { \
18550 + } while (0); \
18551 + } while (0)
18552 + #else
18553 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
18554 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
18555 + #endif /* CONFIG_SCSI_LOGGING */
18556 +
18557 + /*
18558 +diff -urNp a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
18559 +--- a/drivers/serial/8250_pci.c 2008-08-20 11:16:13.000000000 -0700
18560 ++++ b/drivers/serial/8250_pci.c 2008-08-20 18:36:57.000000000 -0700
18561 +@@ -2837,7 +2837,7 @@ static struct pci_device_id serial_pci_t
18562 + PCI_ANY_ID, PCI_ANY_ID,
18563 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
18564 + 0xffff00, pbn_default },
18565 +- { 0, }
18566 ++ { 0, 0, 0, 0, 0, 0, 0 }
18567 + };
18568 +
18569 + static struct pci_driver serial_pci_driver = {
18570 +diff -urNp a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
18571 +--- a/drivers/usb/class/cdc-acm.c 2008-08-20 11:16:13.000000000 -0700
18572 ++++ b/drivers/usb/class/cdc-acm.c 2008-08-20 18:36:57.000000000 -0700
18573 +@@ -1261,7 +1261,7 @@ static struct usb_device_id acm_ids[] =
18574 + USB_CDC_ACM_PROTO_AT_CDMA) },
18575 +
18576 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
18577 +- { }
18578 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18579 + };
18580 +
18581 + MODULE_DEVICE_TABLE (usb, acm_ids);
18582 +diff -urNp a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
18583 +--- a/drivers/usb/class/usblp.c 2008-08-20 11:16:13.000000000 -0700
18584 ++++ b/drivers/usb/class/usblp.c 2008-08-20 18:36:57.000000000 -0700
18585 +@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
18586 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
18587 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
18588 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
18589 +- { 0, 0 }
18590 ++ { 0, 0, 0 }
18591 + };
18592 +
18593 + static int usblp_wwait(struct usblp *usblp, int nonblock);
18594 +@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
18595 + { USB_INTERFACE_INFO(7, 1, 2) },
18596 + { USB_INTERFACE_INFO(7, 1, 3) },
18597 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
18598 +- { } /* Terminating entry */
18599 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
18600 + };
18601 +
18602 + MODULE_DEVICE_TABLE (usb, usblp_ids);
18603 +diff -urNp a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
18604 +--- a/drivers/usb/core/hub.c 2008-08-20 11:16:13.000000000 -0700
18605 ++++ b/drivers/usb/core/hub.c 2008-08-20 18:36:57.000000000 -0700
18606 +@@ -2909,7 +2909,7 @@ static struct usb_device_id hub_id_table
18607 + .bDeviceClass = USB_CLASS_HUB},
18608 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
18609 + .bInterfaceClass = USB_CLASS_HUB},
18610 +- { } /* Terminating entry */
18611 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
18612 + };
18613 +
18614 + MODULE_DEVICE_TABLE (usb, hub_id_table);
18615 +diff -urNp a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
18616 +--- a/drivers/usb/host/ehci-pci.c 2008-08-20 11:16:13.000000000 -0700
18617 ++++ b/drivers/usb/host/ehci-pci.c 2008-08-20 18:36:57.000000000 -0700
18618 +@@ -389,7 +389,7 @@ static const struct pci_device_id pci_id
18619 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
18620 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
18621 + },
18622 +- { /* end: all zeroes */ }
18623 ++ { 0, 0, 0, 0, 0, 0, 0 }
18624 + };
18625 + MODULE_DEVICE_TABLE(pci, pci_ids);
18626 +
18627 +diff -urNp a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
18628 +--- a/drivers/usb/host/uhci-hcd.c 2008-08-20 11:16:13.000000000 -0700
18629 ++++ b/drivers/usb/host/uhci-hcd.c 2008-08-20 18:36:57.000000000 -0700
18630 +@@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p
18631 + /* handle any USB UHCI controller */
18632 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
18633 + .driver_data = (unsigned long) &uhci_driver,
18634 +- }, { /* end: all zeroes */ }
18635 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
18636 + };
18637 +
18638 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
18639 +diff -urNp a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h
18640 +--- a/drivers/usb/storage/debug.h 2008-08-20 11:16:13.000000000 -0700
18641 ++++ b/drivers/usb/storage/debug.h 2008-08-20 18:36:57.000000000 -0700
18642 +@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
18643 + #define US_DEBUGPX(x...) printk( x )
18644 + #define US_DEBUG(x) x
18645 + #else
18646 +-#define US_DEBUGP(x...)
18647 +-#define US_DEBUGPX(x...)
18648 +-#define US_DEBUG(x)
18649 ++#define US_DEBUGP(x...) do {} while (0)
18650 ++#define US_DEBUGPX(x...) do {} while (0)
18651 ++#define US_DEBUG(x) do {} while (0)
18652 + #endif
18653 +
18654 + #endif
18655 +diff -urNp a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
18656 +--- a/drivers/usb/storage/usb.c 2008-08-20 11:16:13.000000000 -0700
18657 ++++ b/drivers/usb/storage/usb.c 2008-08-20 18:36:57.000000000 -0700
18658 +@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
18659 + #undef UNUSUAL_DEV
18660 + #undef USUAL_DEV
18661 + /* Terminating entry */
18662 +- { }
18663 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18664 + };
18665 +
18666 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
18667 +@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
18668 + # undef USUAL_DEV
18669 +
18670 + /* Terminating entry */
18671 +- { NULL }
18672 ++ { NULL, NULL, 0, 0, NULL }
18673 + };
18674 +
18675 +
18676 +diff -urNp a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
18677 +--- a/drivers/video/fbcmap.c 2008-08-20 11:16:13.000000000 -0700
18678 ++++ b/drivers/video/fbcmap.c 2008-08-20 18:36:57.000000000 -0700
18679 +@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
18680 + int rc, size = cmap->len * sizeof(u16);
18681 + struct fb_cmap umap;
18682 +
18683 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
18684 +- !info->fbops->fb_setcmap))
18685 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
18686 + return -EINVAL;
18687 +
18688 + memset(&umap, 0, sizeof(struct fb_cmap));
18689 +diff -urNp a/drivers/video/fbmem.c b/drivers/video/fbmem.c
18690 +--- a/drivers/video/fbmem.c 2008-08-20 11:16:13.000000000 -0700
18691 ++++ b/drivers/video/fbmem.c 2008-08-20 18:36:57.000000000 -0700
18692 +@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
18693 + image->dx += image->width + 8;
18694 + }
18695 + } else if (rotate == FB_ROTATE_UD) {
18696 +- for (x = 0; x < num && image->dx >= 0; x++) {
18697 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
18698 + info->fbops->fb_imageblit(info, image);
18699 + image->dx -= image->width + 8;
18700 + }
18701 +@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
18702 + image->dy += image->height + 8;
18703 + }
18704 + } else if (rotate == FB_ROTATE_CCW) {
18705 +- for (x = 0; x < num && image->dy >= 0; x++) {
18706 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
18707 + info->fbops->fb_imageblit(info, image);
18708 + image->dy -= image->height + 8;
18709 + }
18710 +@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
18711 + case FBIOPUT_CON2FBMAP:
18712 + if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
18713 + return - EFAULT;
18714 +- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
18715 ++ if (con2fb.console > MAX_NR_CONSOLES)
18716 + return -EINVAL;
18717 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
18718 ++ if (con2fb.framebuffer >= FB_MAX)
18719 + return -EINVAL;
18720 + #ifdef CONFIG_KMOD
18721 + if (!registered_fb[con2fb.framebuffer])
18722 +diff -urNp a/drivers/video/fbmon.c b/drivers/video/fbmon.c
18723 +--- a/drivers/video/fbmon.c 2008-08-20 11:16:13.000000000 -0700
18724 ++++ b/drivers/video/fbmon.c 2008-08-20 18:36:57.000000000 -0700
18725 +@@ -45,7 +45,7 @@
18726 + #ifdef DEBUG
18727 + #define DPRINTK(fmt, args...) printk(fmt,## args)
18728 + #else
18729 +-#define DPRINTK(fmt, args...)
18730 ++#define DPRINTK(fmt, args...) do {} while (0)
18731 + #endif
18732 +
18733 + #define FBMON_FIX_HEADER 1
18734 +diff -urNp a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c
18735 +--- a/drivers/video/i810/i810_accel.c 2008-08-20 11:16:13.000000000 -0700
18736 ++++ b/drivers/video/i810/i810_accel.c 2008-08-20 18:36:57.000000000 -0700
18737 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
18738 + }
18739 + }
18740 + printk("ringbuffer lockup!!!\n");
18741 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
18742 + i810_report_error(mmio);
18743 + par->dev_flags |= LOCKUP;
18744 + info->pixmap.scan_align = 1;
18745 +diff -urNp a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
18746 +--- a/drivers/video/i810/i810_main.c 2008-08-20 11:16:13.000000000 -0700
18747 ++++ b/drivers/video/i810/i810_main.c 2008-08-20 18:36:57.000000000 -0700
18748 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
18749 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
18750 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
18751 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
18752 +- { 0 },
18753 ++ { 0, 0, 0, 0, 0, 0, 0 },
18754 + };
18755 +
18756 + static struct pci_driver i810fb_driver = {
18757 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
18758 + int size = ((cursor->image.width + 7) >> 3) *
18759 + cursor->image.height;
18760 + int i;
18761 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
18762 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
18763 +
18764 + if (data == NULL)
18765 + return -ENOMEM;
18766 +diff -urNp a/drivers/video/modedb.c b/drivers/video/modedb.c
18767 +--- a/drivers/video/modedb.c 2008-08-20 11:16:13.000000000 -0700
18768 ++++ b/drivers/video/modedb.c 2008-08-20 18:36:57.000000000 -0700
18769 +@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
18770 + {
18771 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
18772 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
18773 +- 0, FB_VMODE_NONINTERLACED
18774 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18775 + }, {
18776 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
18777 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
18778 +- 0, FB_VMODE_NONINTERLACED
18779 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18780 + }, {
18781 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
18782 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
18783 +- 0, FB_VMODE_NONINTERLACED
18784 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18785 + }, {
18786 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
18787 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
18788 +- 0, FB_VMODE_INTERLACED
18789 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18790 + }, {
18791 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
18792 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
18793 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18794 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18795 + }, {
18796 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
18797 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
18798 +- 0, FB_VMODE_NONINTERLACED
18799 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18800 + }, {
18801 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
18802 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
18803 +- 0, FB_VMODE_NONINTERLACED
18804 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18805 + }, {
18806 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
18807 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
18808 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18809 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18810 + }, {
18811 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
18812 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
18813 +- 0, FB_VMODE_NONINTERLACED
18814 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18815 + }, {
18816 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
18817 + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
18818 +- 0, FB_VMODE_INTERLACED
18819 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18820 + }, {
18821 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
18822 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
18823 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18824 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18825 + }, {
18826 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
18827 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
18828 +- 0, FB_VMODE_NONINTERLACED
18829 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18830 + }, {
18831 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
18832 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
18833 +- 0, FB_VMODE_NONINTERLACED
18834 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18835 + }, {
18836 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
18837 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
18838 +- 0, FB_VMODE_NONINTERLACED
18839 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18840 + }, {
18841 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
18842 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
18843 +- 0, FB_VMODE_NONINTERLACED
18844 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18845 + }, {
18846 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
18847 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
18848 +- 0, FB_VMODE_NONINTERLACED
18849 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18850 + }, {
18851 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
18852 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
18853 +- 0, FB_VMODE_INTERLACED
18854 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18855 + }, {
18856 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
18857 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
18858 +- 0, FB_VMODE_NONINTERLACED
18859 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18860 + }, {
18861 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
18862 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
18863 +- 0, FB_VMODE_NONINTERLACED
18864 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18865 + }, {
18866 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
18867 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
18868 +- 0, FB_VMODE_NONINTERLACED
18869 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18870 + }, {
18871 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
18872 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
18873 +- 0, FB_VMODE_NONINTERLACED
18874 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18875 + }, {
18876 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
18877 + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
18878 +- 0, FB_VMODE_NONINTERLACED
18879 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18880 + }, {
18881 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
18882 + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
18883 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18884 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18885 + }, {
18886 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
18887 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
18888 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18889 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18890 + }, {
18891 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
18892 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
18893 +- 0, FB_VMODE_NONINTERLACED
18894 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18895 + }, {
18896 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
18897 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
18898 +- 0, FB_VMODE_NONINTERLACED
18899 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18900 + }, {
18901 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
18902 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
18903 +- 0, FB_VMODE_NONINTERLACED
18904 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18905 + }, {
18906 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
18907 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
18908 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18909 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18910 + }, {
18911 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
18912 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
18913 +- 0, FB_VMODE_NONINTERLACED
18914 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18915 + }, {
18916 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
18917 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
18918 +- 0, FB_VMODE_NONINTERLACED
18919 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18920 + }, {
18921 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
18922 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
18923 +- 0, FB_VMODE_NONINTERLACED
18924 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18925 + }, {
18926 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
18927 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
18928 +- 0, FB_VMODE_NONINTERLACED
18929 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18930 + }, {
18931 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
18932 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
18933 +- 0, FB_VMODE_NONINTERLACED
18934 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18935 + }, {
18936 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
18937 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
18938 +- 0, FB_VMODE_NONINTERLACED
18939 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18940 + }, {
18941 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
18942 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
18943 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18944 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18945 + }, {
18946 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
18947 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
18948 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18949 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18950 + }, {
18951 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
18952 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
18953 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18954 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18955 + }, {
18956 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
18957 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
18958 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18959 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18960 + }, {
18961 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
18962 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
18963 +- 0, FB_VMODE_NONINTERLACED
18964 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18965 + }, {
18966 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
18967 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
18968 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18969 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18970 + }, {
18971 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
18972 + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
18973 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18974 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18975 + }, {
18976 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
18977 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
18978 +- 0, FB_VMODE_NONINTERLACED
18979 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18980 + }, {
18981 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
18982 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
18983 +- 0, FB_VMODE_NONINTERLACED
18984 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18985 + }, {
18986 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
18987 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
18988 +- 0, FB_VMODE_DOUBLE
18989 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
18990 + }, {
18991 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
18992 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
18993 +- 0, FB_VMODE_DOUBLE
18994 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
18995 + }, {
18996 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
18997 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
18998 +- 0, FB_VMODE_DOUBLE
18999 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19000 + }, {
19001 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
19002 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
19003 +- 0, FB_VMODE_DOUBLE
19004 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19005 + }, {
19006 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
19007 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
19008 +- 0, FB_VMODE_DOUBLE
19009 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19010 + }, {
19011 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
19012 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
19013 +- 0, FB_VMODE_DOUBLE
19014 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19015 + }, {
19016 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
19017 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
19018 +- 0, FB_VMODE_DOUBLE
19019 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19020 + }, {
19021 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
19022 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
19023 +- 0, FB_VMODE_DOUBLE
19024 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19025 + }, {
19026 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
19027 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
19028 +- 0, FB_VMODE_DOUBLE
19029 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19030 + }, {
19031 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
19032 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
19033 +- 0, FB_VMODE_DOUBLE
19034 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19035 + }, {
19036 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
19037 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
19038 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
19039 +- FB_VMODE_NONINTERLACED
19040 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19041 + }, {
19042 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
19043 + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
19044 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19045 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19046 + }, {
19047 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
19048 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
19049 +- 0, FB_VMODE_NONINTERLACED
19050 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19051 + }, {
19052 + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
19053 + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
19054 +- 0, FB_VMODE_NONINTERLACED
19055 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19056 + },
19057 + };
19058 +
19059 +diff -urNp a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
19060 +--- a/drivers/video/uvesafb.c 2008-08-20 11:16:13.000000000 -0700
19061 ++++ b/drivers/video/uvesafb.c 2008-08-20 18:36:57.000000000 -0700
19062 +@@ -18,6 +18,7 @@
19063 + #include <linux/fb.h>
19064 + #include <linux/io.h>
19065 + #include <linux/mutex.h>
19066 ++#include <linux/moduleloader.h>
19067 + #include <video/edid.h>
19068 + #include <video/uvesafb.h>
19069 + #ifdef CONFIG_X86
19070 +@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
19071 + NULL,
19072 + };
19073 +
19074 +- return call_usermodehelper(v86d_path, argv, envp, 1);
19075 ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
19076 + }
19077 +
19078 + /*
19079 +@@ -560,18 +561,46 @@ static int __devinit uvesafb_vbe_getpmi(
19080 + {
19081 + int i, err;
19082 +
19083 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19084 ++ u8 *pmi_code;
19085 ++ unsigned long cr0;
19086 ++#endif
19087 ++
19088 + uvesafb_reset(task);
19089 + task->t.regs.eax = 0x4f0a;
19090 + task->t.regs.ebx = 0x0;
19091 + err = uvesafb_exec(task);
19092 +
19093 +- if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
19094 +- par->pmi_setpal = par->ypan = 0;
19095 +- } else {
19096 ++ par->pmi_setpal = par->ypan = 0;
19097 ++ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000)
19098 ++ return 0;
19099 ++
19100 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19101 ++ pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
19102 ++ if (pmi_code) {
19103 ++#elif !defined(CONFIG_PAX_KERNEXEC)
19104 ++ if (1) {
19105 ++#endif
19106 ++
19107 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
19108 + + task->t.regs.edi);
19109 +- par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
19110 +- par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
19111 ++
19112 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19113 ++ pax_open_kernel(cr0);
19114 ++ memcpy(pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
19115 ++ pax_close_kernel(cr0);
19116 ++#else
19117 ++ pmi_code = par->pmi_base;
19118 ++#endif
19119 ++
19120 ++ par->pmi_start = pmi_code + par->pmi_base[1];
19121 ++ par->pmi_pal = pmi_code + par->pmi_base[2];
19122 ++
19123 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19124 ++ par->pmi_start = ktva_ktla(par->pmi_start);
19125 ++ par->pmi_pal = ktva_ktla(par->pmi_pal);
19126 ++#endif
19127 ++
19128 + printk(KERN_INFO "uvesafb: protected mode interface info at "
19129 + "%04x:%04x\n",
19130 + (u16)task->t.regs.es, (u16)task->t.regs.edi);
19131 +diff -urNp a/drivers/video/vesafb.c b/drivers/video/vesafb.c
19132 +--- a/drivers/video/vesafb.c 2008-08-20 11:16:13.000000000 -0700
19133 ++++ b/drivers/video/vesafb.c 2008-08-20 18:36:57.000000000 -0700
19134 +@@ -9,6 +9,7 @@
19135 + */
19136 +
19137 + #include <linux/module.h>
19138 ++#include <linux/moduleloader.h>
19139 + #include <linux/kernel.h>
19140 + #include <linux/errno.h>
19141 + #include <linux/string.h>
19142 +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
19143 + static int vram_total __initdata; /* Set total amount of memory */
19144 + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
19145 + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
19146 +-static void (*pmi_start)(void) __read_mostly;
19147 +-static void (*pmi_pal) (void) __read_mostly;
19148 ++static void (*pmi_start)(void) __read_only;
19149 ++static void (*pmi_pal) (void) __read_only;
19150 + static int depth __read_mostly;
19151 + static int vga_compat __read_mostly;
19152 + /* --------------------------------------------------------------------- */
19153 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
19154 + unsigned int size_vmode;
19155 + unsigned int size_remap;
19156 + unsigned int size_total;
19157 ++ void *pmi_code = NULL;
19158 +
19159 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
19160 + return -ENODEV;
19161 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
19162 + size_remap = size_total;
19163 + vesafb_fix.smem_len = size_remap;
19164 +
19165 +-#ifndef __i386__
19166 +- screen_info.vesapm_seg = 0;
19167 +-#endif
19168 +-
19169 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
19170 + printk(KERN_WARNING
19171 + "vesafb: cannot reserve video memory at 0x%lx\n",
19172 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
19173 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
19174 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
19175 +
19176 ++#ifdef __i386__
19177 ++
19178 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19179 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
19180 ++ if (!pmi_code)
19181 ++#elif !defined(CONFIG_PAX_KERNEXEC)
19182 ++ if (0)
19183 ++#endif
19184 ++
19185 ++#endif
19186 ++ screen_info.vesapm_seg = 0;
19187 ++
19188 + if (screen_info.vesapm_seg) {
19189 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
19190 +- screen_info.vesapm_seg,screen_info.vesapm_off);
19191 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
19192 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
19193 + }
19194 +
19195 + if (screen_info.vesapm_seg < 0xc000)
19196 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
19197 +
19198 + if (ypan || pmi_setpal) {
19199 + unsigned short *pmi_base;
19200 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
19201 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
19202 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
19203 ++
19204 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19205 ++ unsigned long cr0;
19206 ++#endif
19207 ++
19208 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
19209 ++
19210 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19211 ++ pax_open_kernel(cr0);
19212 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
19213 ++#else
19214 ++ pmi_code = pmi_base;
19215 ++#endif
19216 ++
19217 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
19218 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
19219 ++
19220 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19221 ++ pmi_start = ktva_ktla(pmi_start);
19222 ++ pmi_pal = ktva_ktla(pmi_pal);
19223 ++ pax_close_kernel(cr0);
19224 ++#endif
19225 ++
19226 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
19227 + if (pmi_base[3]) {
19228 + printk(KERN_INFO "vesafb: pmi: ports = ");
19229 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
19230 + info->node, info->fix.id);
19231 + return 0;
19232 + err:
19233 ++
19234 ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19235 ++ module_free_exec(NULL, pmi_code);
19236 ++#endif
19237 ++
19238 + if (info->screen_base)
19239 + iounmap(info->screen_base);
19240 + framebuffer_release(info);
19241 +diff -urNp a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
19242 +--- a/fs/9p/vfs_inode.c 2008-08-20 11:16:13.000000000 -0700
19243 ++++ b/fs/9p/vfs_inode.c 2008-08-20 18:36:57.000000000 -0700
19244 +@@ -1001,7 +1001,7 @@ static void *v9fs_vfs_follow_link(struct
19245 +
19246 + static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
19247 + {
19248 +- char *s = nd_get_link(nd);
19249 ++ const char *s = nd_get_link(nd);
19250 +
19251 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
19252 + if (!IS_ERR(s))
19253 +diff -urNp a/fs/Kconfig b/fs/Kconfig
19254 +--- a/fs/Kconfig 2008-08-20 11:16:13.000000000 -0700
19255 ++++ b/fs/Kconfig 2008-08-20 18:36:57.000000000 -0700
19256 +@@ -899,7 +899,7 @@ config PROC_FS
19257 +
19258 + config PROC_KCORE
19259 + bool "/proc/kcore support" if !ARM
19260 +- depends on PROC_FS && MMU
19261 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
19262 +
19263 + config PROC_VMCORE
19264 + bool "/proc/vmcore support (EXPERIMENTAL)"
19265 +diff -urNp a/fs/aio.c b/fs/aio.c
19266 +--- a/fs/aio.c 2008-08-20 11:16:13.000000000 -0700
19267 ++++ b/fs/aio.c 2008-08-20 18:36:57.000000000 -0700
19268 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
19269 + size += sizeof(struct io_event) * nr_events;
19270 + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
19271 +
19272 +- if (nr_pages < 0)
19273 ++ if (nr_pages <= 0)
19274 + return -EINVAL;
19275 +
19276 + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
19277 +diff -urNp a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
19278 +--- a/fs/autofs4/symlink.c 2008-08-20 11:16:13.000000000 -0700
19279 ++++ b/fs/autofs4/symlink.c 2008-08-20 18:36:57.000000000 -0700
19280 +@@ -15,7 +15,7 @@
19281 + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
19282 + {
19283 + struct autofs_info *ino = autofs4_dentry_ino(dentry);
19284 +- nd_set_link(nd, (char *)ino->u.symlink);
19285 ++ nd_set_link(nd, ino->u.symlink);
19286 + return NULL;
19287 + }
19288 +
19289 +diff -urNp a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
19290 +--- a/fs/befs/linuxvfs.c 2008-08-20 11:16:13.000000000 -0700
19291 ++++ b/fs/befs/linuxvfs.c 2008-08-20 18:36:57.000000000 -0700
19292 +@@ -489,7 +489,7 @@ static void befs_put_link(struct dentry
19293 + {
19294 + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
19295 + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
19296 +- char *p = nd_get_link(nd);
19297 ++ const char *p = nd_get_link(nd);
19298 + if (!IS_ERR(p))
19299 + kfree(p);
19300 + }
19301 +diff -urNp a/fs/binfmt_aout.c b/fs/binfmt_aout.c
19302 +--- a/fs/binfmt_aout.c 2008-08-20 11:16:13.000000000 -0700
19303 ++++ b/fs/binfmt_aout.c 2008-08-20 18:36:57.000000000 -0700
19304 +@@ -24,6 +24,7 @@
19305 + #include <linux/binfmts.h>
19306 + #include <linux/personality.h>
19307 + #include <linux/init.h>
19308 ++#include <linux/grsecurity.h>
19309 +
19310 + #include <asm/system.h>
19311 + #include <asm/uaccess.h>
19312 +@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
19313 + /* If the size of the dump file exceeds the rlimit, then see what would happen
19314 + if we wrote the stack, but not the data area. */
19315 + #ifdef __sparc__
19316 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
19317 + if ((dump.u_dsize + dump.u_ssize) > limit)
19318 + dump.u_dsize = 0;
19319 + #else
19320 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
19321 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
19322 + dump.u_dsize = 0;
19323 + #endif
19324 +
19325 + /* Make sure we have enough room to write the stack and data areas. */
19326 + #ifdef __sparc__
19327 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
19328 + if (dump.u_ssize > limit)
19329 + dump.u_ssize = 0;
19330 + #else
19331 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
19332 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
19333 + dump.u_ssize = 0;
19334 + #endif
19335 +@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
19336 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
19337 + if (rlim >= RLIM_INFINITY)
19338 + rlim = ~0;
19339 ++
19340 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
19341 + if (ex.a_data + ex.a_bss > rlim)
19342 + return -ENOMEM;
19343 +
19344 +@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
19345 +
19346 + compute_creds(bprm);
19347 + current->flags &= ~PF_FORKNOEXEC;
19348 ++
19349 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19350 ++ current->mm->pax_flags = 0UL;
19351 ++#endif
19352 ++
19353 ++#ifdef CONFIG_PAX_PAGEEXEC
19354 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
19355 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
19356 ++
19357 ++#ifdef CONFIG_PAX_EMUTRAMP
19358 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
19359 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
19360 ++#endif
19361 ++
19362 ++#ifdef CONFIG_PAX_MPROTECT
19363 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
19364 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
19365 ++#endif
19366 ++
19367 ++ }
19368 ++#endif
19369 ++
19370 + #ifdef __sparc__
19371 + if (N_MAGIC(ex) == NMAGIC) {
19372 + loff_t pos = fd_offset;
19373 +@@ -417,7 +446,7 @@ static int load_aout_binary(struct linux
19374 +
19375 + down_write(&current->mm->mmap_sem);
19376 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
19377 +- PROT_READ | PROT_WRITE | PROT_EXEC,
19378 ++ PROT_READ | PROT_WRITE,
19379 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
19380 + fd_offset + ex.a_text);
19381 + up_write(&current->mm->mmap_sem);
19382 +diff -urNp a/fs/binfmt_elf.c b/fs/binfmt_elf.c
19383 +--- a/fs/binfmt_elf.c 2008-08-20 11:16:13.000000000 -0700
19384 ++++ b/fs/binfmt_elf.c 2008-08-20 18:36:57.000000000 -0700
19385 +@@ -39,10 +39,16 @@
19386 + #include <linux/random.h>
19387 + #include <linux/elf.h>
19388 + #include <linux/utsname.h>
19389 ++#include <linux/grsecurity.h>
19390 ++
19391 + #include <asm/uaccess.h>
19392 + #include <asm/param.h>
19393 + #include <asm/page.h>
19394 +
19395 ++#ifdef CONFIG_PAX_SEGMEXEC
19396 ++#include <asm/desc.h>
19397 ++#endif
19398 ++
19399 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
19400 + static int load_elf_library(struct file *);
19401 + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
19402 +@@ -85,6 +91,8 @@ static struct linux_binfmt elf_format =
19403 +
19404 + static int set_brk(unsigned long start, unsigned long end)
19405 + {
19406 ++ unsigned long e = end;
19407 ++
19408 + start = ELF_PAGEALIGN(start);
19409 + end = ELF_PAGEALIGN(end);
19410 + if (end > start) {
19411 +@@ -95,7 +103,7 @@ static int set_brk(unsigned long start,
19412 + if (BAD_ADDR(addr))
19413 + return addr;
19414 + }
19415 +- current->mm->start_brk = current->mm->brk = end;
19416 ++ current->mm->start_brk = current->mm->brk = e;
19417 + return 0;
19418 + }
19419 +
19420 +@@ -352,10 +360,10 @@ static unsigned long load_elf_interp(str
19421 + {
19422 + struct elf_phdr *elf_phdata;
19423 + struct elf_phdr *eppnt;
19424 +- unsigned long load_addr = 0;
19425 ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
19426 + int load_addr_set = 0;
19427 + unsigned long last_bss = 0, elf_bss = 0;
19428 +- unsigned long error = ~0UL;
19429 ++ unsigned long error = -EINVAL;
19430 + unsigned long total_size;
19431 + int retval, i, size;
19432 +
19433 +@@ -401,6 +409,11 @@ static unsigned long load_elf_interp(str
19434 + goto out_close;
19435 + }
19436 +
19437 ++#ifdef CONFIG_PAX_SEGMEXEC
19438 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
19439 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
19440 ++#endif
19441 ++
19442 + eppnt = elf_phdata;
19443 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
19444 + if (eppnt->p_type == PT_LOAD) {
19445 +@@ -444,8 +457,8 @@ static unsigned long load_elf_interp(str
19446 + k = load_addr + eppnt->p_vaddr;
19447 + if (BAD_ADDR(k) ||
19448 + eppnt->p_filesz > eppnt->p_memsz ||
19449 +- eppnt->p_memsz > TASK_SIZE ||
19450 +- TASK_SIZE - eppnt->p_memsz < k) {
19451 ++ eppnt->p_memsz > pax_task_size ||
19452 ++ pax_task_size - eppnt->p_memsz < k) {
19453 + error = -ENOMEM;
19454 + goto out_close;
19455 + }
19456 +@@ -499,6 +512,177 @@ out:
19457 + return error;
19458 + }
19459 +
19460 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
19461 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
19462 ++{
19463 ++ unsigned long pax_flags = 0UL;
19464 ++
19465 ++#ifdef CONFIG_PAX_PAGEEXEC
19466 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
19467 ++ pax_flags |= MF_PAX_PAGEEXEC;
19468 ++#endif
19469 ++
19470 ++#ifdef CONFIG_PAX_SEGMEXEC
19471 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
19472 ++ pax_flags |= MF_PAX_SEGMEXEC;
19473 ++#endif
19474 ++
19475 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19476 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19477 ++ if (nx_enabled)
19478 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19479 ++ else
19480 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19481 ++ }
19482 ++#endif
19483 ++
19484 ++#ifdef CONFIG_PAX_EMUTRAMP
19485 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
19486 ++ pax_flags |= MF_PAX_EMUTRAMP;
19487 ++#endif
19488 ++
19489 ++#ifdef CONFIG_PAX_MPROTECT
19490 ++ if (elf_phdata->p_flags & PF_MPROTECT)
19491 ++ pax_flags |= MF_PAX_MPROTECT;
19492 ++#endif
19493 ++
19494 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
19495 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
19496 ++ pax_flags |= MF_PAX_RANDMMAP;
19497 ++#endif
19498 ++
19499 ++ return pax_flags;
19500 ++}
19501 ++#endif
19502 ++
19503 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19504 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
19505 ++{
19506 ++ unsigned long pax_flags = 0UL;
19507 ++
19508 ++#ifdef CONFIG_PAX_PAGEEXEC
19509 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
19510 ++ pax_flags |= MF_PAX_PAGEEXEC;
19511 ++#endif
19512 ++
19513 ++#ifdef CONFIG_PAX_SEGMEXEC
19514 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
19515 ++ pax_flags |= MF_PAX_SEGMEXEC;
19516 ++#endif
19517 ++
19518 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19519 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19520 ++ if (nx_enabled)
19521 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19522 ++ else
19523 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19524 ++ }
19525 ++#endif
19526 ++
19527 ++#ifdef CONFIG_PAX_EMUTRAMP
19528 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
19529 ++ pax_flags |= MF_PAX_EMUTRAMP;
19530 ++#endif
19531 ++
19532 ++#ifdef CONFIG_PAX_MPROTECT
19533 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
19534 ++ pax_flags |= MF_PAX_MPROTECT;
19535 ++#endif
19536 ++
19537 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
19538 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
19539 ++ pax_flags |= MF_PAX_RANDMMAP;
19540 ++#endif
19541 ++
19542 ++ return pax_flags;
19543 ++}
19544 ++#endif
19545 ++
19546 ++#ifdef CONFIG_PAX_EI_PAX
19547 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
19548 ++{
19549 ++ unsigned long pax_flags = 0UL;
19550 ++
19551 ++#ifdef CONFIG_PAX_PAGEEXEC
19552 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
19553 ++ pax_flags |= MF_PAX_PAGEEXEC;
19554 ++#endif
19555 ++
19556 ++#ifdef CONFIG_PAX_SEGMEXEC
19557 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
19558 ++ pax_flags |= MF_PAX_SEGMEXEC;
19559 ++#endif
19560 ++
19561 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19562 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19563 ++ if (nx_enabled)
19564 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19565 ++ else
19566 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19567 ++ }
19568 ++#endif
19569 ++
19570 ++#ifdef CONFIG_PAX_EMUTRAMP
19571 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
19572 ++ pax_flags |= MF_PAX_EMUTRAMP;
19573 ++#endif
19574 ++
19575 ++#ifdef CONFIG_PAX_MPROTECT
19576 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
19577 ++ pax_flags |= MF_PAX_MPROTECT;
19578 ++#endif
19579 ++
19580 ++#ifdef CONFIG_PAX_ASLR
19581 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
19582 ++ pax_flags |= MF_PAX_RANDMMAP;
19583 ++#endif
19584 ++
19585 ++ return pax_flags;
19586 ++}
19587 ++#endif
19588 ++
19589 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
19590 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
19591 ++{
19592 ++ unsigned long pax_flags = 0UL;
19593 ++
19594 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19595 ++ unsigned long i;
19596 ++#endif
19597 ++
19598 ++#ifdef CONFIG_PAX_EI_PAX
19599 ++ pax_flags = pax_parse_ei_pax(elf_ex);
19600 ++#endif
19601 ++
19602 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19603 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
19604 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
19605 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
19606 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
19607 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
19608 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
19609 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
19610 ++ return -EINVAL;
19611 ++
19612 ++#ifdef CONFIG_PAX_SOFTMODE
19613 ++ if (pax_softmode)
19614 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
19615 ++ else
19616 ++#endif
19617 ++
19618 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
19619 ++ break;
19620 ++ }
19621 ++#endif
19622 ++
19623 ++ if (0 > pax_check_flags(&pax_flags))
19624 ++ return -EINVAL;
19625 ++
19626 ++ current->mm->pax_flags = pax_flags;
19627 ++ return 0;
19628 ++}
19629 ++#endif
19630 ++
19631 + /*
19632 + * These are the functions used to load ELF style executables and shared
19633 + * libraries. There is no binary dependent code anywhere else.
19634 +@@ -515,6 +699,11 @@ static unsigned long randomize_stack_top
19635 + {
19636 + unsigned int random_variable = 0;
19637 +
19638 ++#ifdef CONFIG_PAX_RANDUSTACK
19639 ++ if (randomize_va_space)
19640 ++ return stack_top - current->mm->delta_stack;
19641 ++#endif
19642 ++
19643 + if ((current->flags & PF_RANDOMIZE) &&
19644 + !(current->personality & ADDR_NO_RANDOMIZE)) {
19645 + random_variable = get_random_int() & STACK_RND_MASK;
19646 +@@ -533,7 +722,7 @@ static int load_elf_binary(struct linux_
19647 + unsigned long load_addr = 0, load_bias = 0;
19648 + int load_addr_set = 0;
19649 + char * elf_interpreter = NULL;
19650 +- unsigned long error;
19651 ++ unsigned long error = 0;
19652 + struct elf_phdr *elf_ppnt, *elf_phdata;
19653 + unsigned long elf_bss, elf_brk;
19654 + int elf_exec_fileno;
19655 +@@ -545,12 +734,12 @@ static int load_elf_binary(struct linux_
19656 + unsigned long reloc_func_desc = 0;
19657 + struct files_struct *files;
19658 + int executable_stack = EXSTACK_DEFAULT;
19659 +- unsigned long def_flags = 0;
19660 + struct {
19661 + struct elfhdr elf_ex;
19662 + struct elfhdr interp_elf_ex;
19663 + struct exec interp_ex;
19664 + } *loc;
19665 ++ unsigned long pax_task_size = TASK_SIZE;
19666 +
19667 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
19668 + if (!loc) {
19669 +@@ -736,11 +925,79 @@ static int load_elf_binary(struct linux_
19670 +
19671 + /* OK, This is the point of no return */
19672 + current->flags &= ~PF_FORKNOEXEC;
19673 +- current->mm->def_flags = def_flags;
19674 ++
19675 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19676 ++ current->mm->pax_flags = 0UL;
19677 ++#endif
19678 ++
19679 ++#ifdef CONFIG_PAX_DLRESOLVE
19680 ++ current->mm->call_dl_resolve = 0UL;
19681 ++#endif
19682 ++
19683 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19684 ++ current->mm->call_syscall = 0UL;
19685 ++#endif
19686 ++
19687 ++#ifdef CONFIG_PAX_ASLR
19688 ++ current->mm->delta_mmap = 0UL;
19689 ++ current->mm->delta_stack = 0UL;
19690 ++#endif
19691 ++
19692 ++ current->mm->def_flags = 0;
19693 ++
19694 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
19695 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
19696 ++ send_sig(SIGKILL, current, 0);
19697 ++ goto out_free_dentry;
19698 ++ }
19699 ++#endif
19700 ++
19701 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19702 ++ pax_set_initial_flags(bprm);
19703 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
19704 ++ if (pax_set_initial_flags_func)
19705 ++ (pax_set_initial_flags_func)(bprm);
19706 ++#endif
19707 ++
19708 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19709 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
19710 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
19711 ++ current->mm->def_flags |= VM_PAGEEXEC;
19712 ++ }
19713 ++#endif
19714 ++
19715 ++#ifdef CONFIG_PAX_SEGMEXEC
19716 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
19717 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
19718 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
19719 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
19720 ++ }
19721 ++#endif
19722 ++
19723 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
19724 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19725 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
19726 ++ put_cpu_no_resched();
19727 ++ }
19728 ++#endif
19729 ++
19730 ++#ifdef CONFIG_PAX_ASLR
19731 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
19732 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
19733 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
19734 ++ }
19735 ++#endif
19736 +
19737 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
19738 + may depend on the personality. */
19739 + SET_PERSONALITY(loc->elf_ex, 0);
19740 ++
19741 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19742 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
19743 ++ executable_stack = EXSTACK_DISABLE_X;
19744 ++ else
19745 ++#endif
19746 ++
19747 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
19748 + current->personality |= READ_IMPLIES_EXEC;
19749 +
19750 +@@ -821,6 +1078,20 @@ static int load_elf_binary(struct linux_
19751 + #else
19752 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
19753 + #endif
19754 ++
19755 ++#ifdef CONFIG_PAX_RANDMMAP
19756 ++ /* PaX: randomize base address at the default exe base if requested */
19757 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
19758 ++#ifdef CONFIG_SPARC64
19759 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
19760 ++#else
19761 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
19762 ++#endif
19763 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
19764 ++ elf_flags |= MAP_FIXED;
19765 ++ }
19766 ++#endif
19767 ++
19768 + }
19769 +
19770 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
19771 +@@ -853,9 +1124,9 @@ static int load_elf_binary(struct linux_
19772 + * allowed task size. Note that p_filesz must always be
19773 + * <= p_memsz so it is only necessary to check p_memsz.
19774 + */
19775 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
19776 +- elf_ppnt->p_memsz > TASK_SIZE ||
19777 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
19778 ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
19779 ++ elf_ppnt->p_memsz > pax_task_size ||
19780 ++ pax_task_size - elf_ppnt->p_memsz < k) {
19781 + /* set_brk can never work. Avoid overflows. */
19782 + send_sig(SIGKILL, current, 0);
19783 + retval = -EINVAL;
19784 +@@ -883,6 +1154,11 @@ static int load_elf_binary(struct linux_
19785 + start_data += load_bias;
19786 + end_data += load_bias;
19787 +
19788 ++#ifdef CONFIG_PAX_RANDMMAP
19789 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
19790 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
19791 ++#endif
19792 ++
19793 + /* Calling set_brk effectively mmaps the pages that we need
19794 + * for the bss and break sections. We must do this before
19795 + * mapping in the interpreter, to make sure it doesn't wind
19796 +@@ -894,9 +1170,11 @@ static int load_elf_binary(struct linux_
19797 + goto out_free_dentry;
19798 + }
19799 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
19800 +- send_sig(SIGSEGV, current, 0);
19801 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
19802 +- goto out_free_dentry;
19803 ++ /*
19804 ++ * This bss-zeroing can fail if the ELF
19805 ++ * file specifies odd protections. So
19806 ++ * we don't check the return value
19807 ++ */
19808 + }
19809 +
19810 + if (elf_interpreter) {
19811 +@@ -1142,8 +1420,10 @@ static int dump_seek(struct file *file,
19812 + unsigned long n = off;
19813 + if (n > PAGE_SIZE)
19814 + n = PAGE_SIZE;
19815 +- if (!dump_write(file, buf, n))
19816 ++ if (!dump_write(file, buf, n)) {
19817 ++ free_page((unsigned long)buf);
19818 + return 0;
19819 ++ }
19820 + off -= n;
19821 + }
19822 + free_page((unsigned long)buf);
19823 +@@ -1155,7 +1435,7 @@ static int dump_seek(struct file *file,
19824 + * Decide what to dump of a segment, part, all or none.
19825 + */
19826 + static unsigned long vma_dump_size(struct vm_area_struct *vma,
19827 +- unsigned long mm_flags)
19828 ++ unsigned long mm_flags, long signr)
19829 + {
19830 + /* The vma can be set up to tell us the answer directly. */
19831 + if (vma->vm_flags & VM_ALWAYSDUMP)
19832 +@@ -1181,7 +1461,7 @@ static unsigned long vma_dump_size(struc
19833 + if (vma->vm_file == NULL)
19834 + return 0;
19835 +
19836 +- if (FILTER(MAPPED_PRIVATE))
19837 ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
19838 + goto whole;
19839 +
19840 + /*
19841 +@@ -1267,8 +1547,11 @@ static int writenote(struct memelfnote *
19842 + #undef DUMP_WRITE
19843 +
19844 + #define DUMP_WRITE(addr, nr) \
19845 ++ do { \
19846 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
19847 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
19848 +- goto end_coredump;
19849 ++ goto end_coredump; \
19850 ++ } while (0);
19851 + #define DUMP_SEEK(off) \
19852 + if (!dump_seek(file, (off))) \
19853 + goto end_coredump;
19854 +@@ -1985,7 +2268,7 @@ static int elf_core_dump(long signr, str
19855 + phdr.p_offset = offset;
19856 + phdr.p_vaddr = vma->vm_start;
19857 + phdr.p_paddr = 0;
19858 +- phdr.p_filesz = vma_dump_size(vma, mm_flags);
19859 ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
19860 + phdr.p_memsz = vma->vm_end - vma->vm_start;
19861 + offset += phdr.p_filesz;
19862 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
19863 +@@ -2017,7 +2300,7 @@ static int elf_core_dump(long signr, str
19864 + unsigned long addr;
19865 + unsigned long end;
19866 +
19867 +- end = vma->vm_start + vma_dump_size(vma, mm_flags);
19868 ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
19869 +
19870 + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
19871 + struct page *page;
19872 +@@ -2037,6 +2320,7 @@ static int elf_core_dump(long signr, str
19873 + flush_cache_page(vma, addr,
19874 + page_to_pfn(page));
19875 + kaddr = kmap(page);
19876 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
19877 + if ((size += PAGE_SIZE) > limit ||
19878 + !dump_write(file, kaddr,
19879 + PAGE_SIZE)) {
19880 +diff -urNp a/fs/binfmt_flat.c b/fs/binfmt_flat.c
19881 +--- a/fs/binfmt_flat.c 2008-08-20 11:16:13.000000000 -0700
19882 ++++ b/fs/binfmt_flat.c 2008-08-20 18:36:57.000000000 -0700
19883 +@@ -560,7 +560,9 @@ static int load_flat_file(struct linux_b
19884 + realdatastart = (unsigned long) -ENOMEM;
19885 + printk("Unable to allocate RAM for process data, errno %d\n",
19886 + (int)-realdatastart);
19887 ++ down_write(&current->mm->mmap_sem);
19888 + do_munmap(current->mm, textpos, text_len);
19889 ++ up_write(&current->mm->mmap_sem);
19890 + ret = realdatastart;
19891 + goto err;
19892 + }
19893 +@@ -582,8 +584,10 @@ static int load_flat_file(struct linux_b
19894 + }
19895 + if (result >= (unsigned long)-4096) {
19896 + printk("Unable to read data+bss, errno %d\n", (int)-result);
19897 ++ down_write(&current->mm->mmap_sem);
19898 + do_munmap(current->mm, textpos, text_len);
19899 + do_munmap(current->mm, realdatastart, data_len + extra);
19900 ++ up_write(&current->mm->mmap_sem);
19901 + ret = result;
19902 + goto err;
19903 + }
19904 +@@ -656,8 +660,10 @@ static int load_flat_file(struct linux_b
19905 + }
19906 + if (result >= (unsigned long)-4096) {
19907 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
19908 ++ down_write(&current->mm->mmap_sem);
19909 + do_munmap(current->mm, textpos, text_len + data_len + extra +
19910 + MAX_SHARED_LIBS * sizeof(unsigned long));
19911 ++ up_write(&current->mm->mmap_sem);
19912 + ret = result;
19913 + goto err;
19914 + }
19915 +diff -urNp a/fs/binfmt_misc.c b/fs/binfmt_misc.c
19916 +--- a/fs/binfmt_misc.c 2008-08-20 11:16:13.000000000 -0700
19917 ++++ b/fs/binfmt_misc.c 2008-08-20 18:36:57.000000000 -0700
19918 +@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
19919 + struct files_struct *files = NULL;
19920 +
19921 + retval = -ENOEXEC;
19922 +- if (!enabled)
19923 ++ if (!enabled || bprm->misc)
19924 + goto _ret;
19925 +
19926 ++ bprm->misc++;
19927 ++
19928 + /* to keep locking time low, we copy the interpreter string */
19929 + read_lock(&entries_lock);
19930 + fmt = check_file(bprm);
19931 +@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
19932 + static struct tree_descr bm_files[] = {
19933 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
19934 + [3] = {"register", &bm_register_operations, S_IWUSR},
19935 +- /* last one */ {""}
19936 ++ /* last one */ {"", NULL, 0}
19937 + };
19938 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
19939 + if (!err)
19940 +diff -urNp a/fs/buffer.c b/fs/buffer.c
19941 +--- a/fs/buffer.c 2008-08-20 11:16:13.000000000 -0700
19942 ++++ b/fs/buffer.c 2008-08-20 18:36:57.000000000 -0700
19943 +@@ -41,6 +41,7 @@
19944 + #include <linux/bitops.h>
19945 + #include <linux/mpage.h>
19946 + #include <linux/bit_spinlock.h>
19947 ++#include <linux/grsecurity.h>
19948 +
19949 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
19950 +
19951 +@@ -2188,6 +2189,7 @@ int generic_cont_expand_simple(struct in
19952 +
19953 + err = -EFBIG;
19954 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
19955 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
19956 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
19957 + send_sig(SIGXFSZ, current, 0);
19958 + goto out;
19959 +diff -urNp a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h
19960 +--- a/fs/cifs/cifs_uniupr.h 2008-08-20 11:16:13.000000000 -0700
19961 ++++ b/fs/cifs/cifs_uniupr.h 2008-08-20 18:36:57.000000000 -0700
19962 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
19963 + {0x0490, 0x04cc, UniCaseRangeU0490},
19964 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
19965 + {0xff40, 0xff5a, UniCaseRangeUff40},
19966 +- {0}
19967 ++ {0, 0, NULL}
19968 + };
19969 + #endif
19970 +
19971 +diff -urNp a/fs/cifs/link.c b/fs/cifs/link.c
19972 +--- a/fs/cifs/link.c 2008-08-20 11:16:13.000000000 -0700
19973 ++++ b/fs/cifs/link.c 2008-08-20 18:36:57.000000000 -0700
19974 +@@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c
19975 +
19976 + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
19977 + {
19978 +- char *p = nd_get_link(nd);
19979 ++ const char *p = nd_get_link(nd);
19980 + if (!IS_ERR(p))
19981 + kfree(p);
19982 + }
19983 +diff -urNp a/fs/compat.c b/fs/compat.c
19984 +--- a/fs/compat.c 2008-08-20 11:16:13.000000000 -0700
19985 ++++ b/fs/compat.c 2008-08-20 18:36:57.000000000 -0700
19986 +@@ -50,6 +50,7 @@
19987 + #include <linux/poll.h>
19988 + #include <linux/mm.h>
19989 + #include <linux/eventpoll.h>
19990 ++#include <linux/grsecurity.h>
19991 +
19992 + #include <asm/uaccess.h>
19993 + #include <asm/mmu_context.h>
19994 +@@ -1293,14 +1294,12 @@ static int compat_copy_strings(int argc,
19995 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
19996 + struct page *page;
19997 +
19998 +-#ifdef CONFIG_STACK_GROWSUP
19999 + ret = expand_stack_downwards(bprm->vma, pos);
20000 + if (ret < 0) {
20001 + /* We've exceed the stack rlimit. */
20002 + ret = -E2BIG;
20003 + goto out;
20004 + }
20005 +-#endif
20006 + ret = get_user_pages(current, bprm->mm, pos,
20007 + 1, 1, 1, &page, NULL);
20008 + if (ret <= 0) {
20009 +@@ -1346,6 +1345,11 @@ int compat_do_execve(char * filename,
20010 + compat_uptr_t __user *envp,
20011 + struct pt_regs * regs)
20012 + {
20013 ++#ifdef CONFIG_GRKERNSEC
20014 ++ struct file *old_exec_file;
20015 ++ struct acl_subject_label *old_acl;
20016 ++ struct rlimit old_rlim[RLIM_NLIMITS];
20017 ++#endif
20018 + struct linux_binprm *bprm;
20019 + struct file *file;
20020 + int retval;
20021 +@@ -1366,6 +1370,14 @@ int compat_do_execve(char * filename,
20022 + bprm->filename = filename;
20023 + bprm->interp = filename;
20024 +
20025 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
20026 ++ retval = -EAGAIN;
20027 ++ if (gr_handle_nproc())
20028 ++ goto out_file;
20029 ++ retval = -EACCES;
20030 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
20031 ++ goto out_file;
20032 ++
20033 + retval = bprm_mm_init(bprm);
20034 + if (retval)
20035 + goto out_file;
20036 +@@ -1399,8 +1411,36 @@ int compat_do_execve(char * filename,
20037 + if (retval < 0)
20038 + goto out;
20039 +
20040 ++ if (!gr_tpe_allow(file)) {
20041 ++ retval = -EACCES;
20042 ++ goto out;
20043 ++ }
20044 ++
20045 ++ if (gr_check_crash_exec(file)) {
20046 ++ retval = -EACCES;
20047 ++ goto out;
20048 ++ }
20049 ++
20050 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
20051 ++
20052 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
20053 ++
20054 ++#ifdef CONFIG_GRKERNSEC
20055 ++ old_acl = current->acl;
20056 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
20057 ++ old_exec_file = current->exec_file;
20058 ++ get_file(file);
20059 ++ current->exec_file = file;
20060 ++#endif
20061 ++
20062 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
20063 ++
20064 + retval = search_binary_handler(bprm, regs);
20065 + if (retval >= 0) {
20066 ++#ifdef CONFIG_GRKERNSEC
20067 ++ if (old_exec_file)
20068 ++ fput(old_exec_file);
20069 ++#endif
20070 + /* execve success */
20071 + security_bprm_free(bprm);
20072 + acct_update_integrals(current);
20073 +@@ -1408,6 +1448,13 @@ int compat_do_execve(char * filename,
20074 + return retval;
20075 + }
20076 +
20077 ++#ifdef CONFIG_GRKERNSEC
20078 ++ current->acl = old_acl;
20079 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
20080 ++ fput(current->exec_file);
20081 ++ current->exec_file = old_exec_file;
20082 ++#endif
20083 ++
20084 + out:
20085 + if (bprm->security)
20086 + security_bprm_free(bprm);
20087 +diff -urNp a/fs/compat_ioctl.c b/fs/compat_ioctl.c
20088 +--- a/fs/compat_ioctl.c 2008-08-20 11:16:13.000000000 -0700
20089 ++++ b/fs/compat_ioctl.c 2008-08-20 18:36:57.000000000 -0700
20090 +@@ -1889,15 +1889,15 @@ struct ioctl_trans {
20091 + };
20092 +
20093 + #define HANDLE_IOCTL(cmd,handler) \
20094 +- { (cmd), (ioctl_trans_handler_t)(handler) },
20095 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
20096 +
20097 + /* pointer to compatible structure or no argument */
20098 + #define COMPATIBLE_IOCTL(cmd) \
20099 +- { (cmd), do_ioctl32_pointer },
20100 ++ { (cmd), do_ioctl32_pointer, NULL },
20101 +
20102 + /* argument is an unsigned long integer, not a pointer */
20103 + #define ULONG_IOCTL(cmd) \
20104 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
20105 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
20106 +
20107 + /* ioctl should not be warned about even if it's not implemented.
20108 + Valid reasons to use this:
20109 +diff -urNp a/fs/debugfs/inode.c b/fs/debugfs/inode.c
20110 +--- a/fs/debugfs/inode.c 2008-08-20 11:16:13.000000000 -0700
20111 ++++ b/fs/debugfs/inode.c 2008-08-20 18:36:57.000000000 -0700
20112 +@@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
20113 +
20114 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
20115 + {
20116 +- static struct tree_descr debug_files[] = {{""}};
20117 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
20118 +
20119 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
20120 + }
20121 +diff -urNp a/fs/exec.c b/fs/exec.c
20122 +--- a/fs/exec.c 2008-08-20 11:16:13.000000000 -0700
20123 ++++ b/fs/exec.c 2008-08-20 18:36:57.000000000 -0700
20124 +@@ -51,6 +51,8 @@
20125 + #include <linux/tsacct_kern.h>
20126 + #include <linux/cn_proc.h>
20127 + #include <linux/audit.h>
20128 ++#include <linux/random.h>
20129 ++#include <linux/grsecurity.h>
20130 +
20131 + #include <asm/uaccess.h>
20132 + #include <asm/mmu_context.h>
20133 +@@ -60,6 +62,11 @@
20134 + #include <linux/kmod.h>
20135 + #endif
20136 +
20137 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
20138 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
20139 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
20140 ++#endif
20141 ++
20142 + int core_uses_pid;
20143 + char core_pattern[CORENAME_MAX_SIZE] = "core";
20144 + int suid_dumpable = 0;
20145 +@@ -158,18 +165,10 @@ static struct page *get_arg_page(struct
20146 + int write)
20147 + {
20148 + struct page *page;
20149 +- int ret;
20150 +
20151 +-#ifdef CONFIG_STACK_GROWSUP
20152 +- if (write) {
20153 +- ret = expand_stack_downwards(bprm->vma, pos);
20154 +- if (ret < 0)
20155 +- return NULL;
20156 +- }
20157 +-#endif
20158 +- ret = get_user_pages(current, bprm->mm, pos,
20159 +- 1, write, 1, &page, NULL);
20160 +- if (ret <= 0)
20161 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
20162 ++ return NULL;
20163 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
20164 + return NULL;
20165 +
20166 + if (write) {
20167 +@@ -242,6 +241,11 @@ static int __bprm_mm_init(struct linux_b
20168 + vma->vm_start = vma->vm_end - PAGE_SIZE;
20169 +
20170 + vma->vm_flags = VM_STACK_FLAGS;
20171 ++
20172 ++#ifdef CONFIG_PAX_SEGMEXEC
20173 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
20174 ++#endif
20175 ++
20176 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
20177 + err = insert_vm_struct(mm, vma);
20178 + if (err) {
20179 +@@ -254,6 +258,11 @@ static int __bprm_mm_init(struct linux_b
20180 +
20181 + bprm->p = vma->vm_end - sizeof(void *);
20182 +
20183 ++#ifdef CONFIG_PAX_RANDUSTACK
20184 ++ if (randomize_va_space)
20185 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
20186 ++#endif
20187 ++
20188 + return 0;
20189 +
20190 + err:
20191 +@@ -377,7 +386,7 @@ static int count(char __user * __user *
20192 + if (!p)
20193 + break;
20194 + argv++;
20195 +- if(++i > max)
20196 ++ if (++i > max)
20197 + return -E2BIG;
20198 + cond_resched();
20199 + }
20200 +@@ -517,6 +526,10 @@ static int shift_arg_pages(struct vm_are
20201 + if (vma != find_vma(mm, new_start))
20202 + return -EFAULT;
20203 +
20204 ++#ifdef CONFIG_PAX_SEGMEXEC
20205 ++ BUG_ON(pax_find_mirror_vma(vma));
20206 ++#endif
20207 ++
20208 + /*
20209 + * cover the whole range: [new_start, old_end)
20210 + */
20211 +@@ -605,6 +618,14 @@ int setup_arg_pages(struct linux_binprm
20212 + bprm->exec -= stack_shift;
20213 +
20214 + down_write(&mm->mmap_sem);
20215 ++
20216 ++ /* Move stack pages down in memory. */
20217 ++ if (stack_shift) {
20218 ++ ret = shift_arg_pages(vma, stack_shift);
20219 ++ if (ret)
20220 ++ goto out_unlock;
20221 ++ }
20222 ++
20223 + vm_flags = VM_STACK_FLAGS;
20224 +
20225 + /*
20226 +@@ -618,21 +639,24 @@ int setup_arg_pages(struct linux_binprm
20227 + vm_flags &= ~VM_EXEC;
20228 + vm_flags |= mm->def_flags;
20229 +
20230 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20231 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
20232 ++ vm_flags &= ~VM_EXEC;
20233 ++
20234 ++#ifdef CONFIG_PAX_MPROTECT
20235 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
20236 ++ vm_flags &= ~VM_MAYEXEC;
20237 ++#endif
20238 ++
20239 ++ }
20240 ++#endif
20241 ++
20242 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
20243 + vm_flags);
20244 + if (ret)
20245 + goto out_unlock;
20246 + BUG_ON(prev != vma);
20247 +
20248 +- /* Move stack pages down in memory. */
20249 +- if (stack_shift) {
20250 +- ret = shift_arg_pages(vma, stack_shift);
20251 +- if (ret) {
20252 +- up_write(&mm->mmap_sem);
20253 +- return ret;
20254 +- }
20255 +- }
20256 +-
20257 + #ifdef CONFIG_STACK_GROWSUP
20258 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
20259 + #else
20260 +@@ -644,7 +668,7 @@ int setup_arg_pages(struct linux_binprm
20261 +
20262 + out_unlock:
20263 + up_write(&mm->mmap_sem);
20264 +- return 0;
20265 ++ return ret;
20266 + }
20267 + EXPORT_SYMBOL(setup_arg_pages);
20268 +
20269 +@@ -663,7 +687,7 @@ struct file *open_exec(const char *name)
20270 + struct inode *inode = nd.path.dentry->d_inode;
20271 + file = ERR_PTR(-EACCES);
20272 + if (S_ISREG(inode->i_mode)) {
20273 +- int err = vfs_permission(&nd, MAY_EXEC);
20274 ++ err = vfs_permission(&nd, MAY_EXEC);
20275 + file = ERR_PTR(err);
20276 + if (!err) {
20277 + file = nameidata_to_filp(&nd,
20278 +@@ -1280,6 +1304,11 @@ int do_execve(char * filename,
20279 + char __user *__user *envp,
20280 + struct pt_regs * regs)
20281 + {
20282 ++#ifdef CONFIG_GRKERNSEC
20283 ++ struct file *old_exec_file;
20284 ++ struct acl_subject_label *old_acl;
20285 ++ struct rlimit old_rlim[RLIM_NLIMITS];
20286 ++#endif
20287 + struct linux_binprm *bprm;
20288 + struct file *file;
20289 + unsigned long env_p;
20290 +@@ -1295,6 +1324,20 @@ int do_execve(char * filename,
20291 + if (IS_ERR(file))
20292 + goto out_kfree;
20293 +
20294 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
20295 ++
20296 ++ if (gr_handle_nproc()) {
20297 ++ allow_write_access(file);
20298 ++ fput(file);
20299 ++ return -EAGAIN;
20300 ++ }
20301 ++
20302 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
20303 ++ allow_write_access(file);
20304 ++ fput(file);
20305 ++ return -EACCES;
20306 ++ }
20307 ++
20308 + sched_exec();
20309 +
20310 + bprm->file = file;
20311 +@@ -1336,8 +1379,38 @@ int do_execve(char * filename,
20312 + goto out;
20313 + bprm->argv_len = env_p - bprm->p;
20314 +
20315 ++ if (!gr_tpe_allow(file)) {
20316 ++ retval = -EACCES;
20317 ++ goto out;
20318 ++ }
20319 ++
20320 ++ if (gr_check_crash_exec(file)) {
20321 ++ retval = -EACCES;
20322 ++ goto out;
20323 ++ }
20324 ++
20325 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
20326 ++
20327 ++ gr_handle_exec_args(bprm, argv);
20328 ++
20329 ++#ifdef CONFIG_GRKERNSEC
20330 ++ old_acl = current->acl;
20331 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
20332 ++ old_exec_file = current->exec_file;
20333 ++ get_file(file);
20334 ++ current->exec_file = file;
20335 ++#endif
20336 ++
20337 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
20338 ++ if (retval < 0)
20339 ++ goto out_fail;
20340 ++
20341 + retval = search_binary_handler(bprm,regs);
20342 + if (retval >= 0) {
20343 ++#ifdef CONFIG_GRKERNSEC
20344 ++ if (old_exec_file)
20345 ++ fput(old_exec_file);
20346 ++#endif
20347 + /* execve success */
20348 + free_arg_pages(bprm);
20349 + security_bprm_free(bprm);
20350 +@@ -1346,6 +1419,14 @@ int do_execve(char * filename,
20351 + return retval;
20352 + }
20353 +
20354 ++out_fail:
20355 ++#ifdef CONFIG_GRKERNSEC
20356 ++ current->acl = old_acl;
20357 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
20358 ++ fput(current->exec_file);
20359 ++ current->exec_file = old_exec_file;
20360 ++#endif
20361 ++
20362 + out:
20363 + free_arg_pages(bprm);
20364 + if (bprm->security)
20365 +@@ -1510,6 +1591,116 @@ out:
20366 + return ispipe;
20367 + }
20368 +
20369 ++int pax_check_flags(unsigned long *flags)
20370 ++{
20371 ++ int retval = 0;
20372 ++
20373 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
20374 ++ if (*flags & MF_PAX_SEGMEXEC)
20375 ++ {
20376 ++ *flags &= ~MF_PAX_SEGMEXEC;
20377 ++ retval = -EINVAL;
20378 ++ }
20379 ++#endif
20380 ++
20381 ++ if ((*flags & MF_PAX_PAGEEXEC)
20382 ++
20383 ++#ifdef CONFIG_PAX_PAGEEXEC
20384 ++ && (*flags & MF_PAX_SEGMEXEC)
20385 ++#endif
20386 ++
20387 ++ )
20388 ++ {
20389 ++ *flags &= ~MF_PAX_PAGEEXEC;
20390 ++ retval = -EINVAL;
20391 ++ }
20392 ++
20393 ++ if ((*flags & MF_PAX_MPROTECT)
20394 ++
20395 ++#ifdef CONFIG_PAX_MPROTECT
20396 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
20397 ++#endif
20398 ++
20399 ++ )
20400 ++ {
20401 ++ *flags &= ~MF_PAX_MPROTECT;
20402 ++ retval = -EINVAL;
20403 ++ }
20404 ++
20405 ++ if ((*flags & MF_PAX_EMUTRAMP)
20406 ++
20407 ++#ifdef CONFIG_PAX_EMUTRAMP
20408 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
20409 ++#endif
20410 ++
20411 ++ )
20412 ++ {
20413 ++ *flags &= ~MF_PAX_EMUTRAMP;
20414 ++ retval = -EINVAL;
20415 ++ }
20416 ++
20417 ++ return retval;
20418 ++}
20419 ++
20420 ++EXPORT_SYMBOL(pax_check_flags);
20421 ++
20422 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20423 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
20424 ++{
20425 ++ struct task_struct *tsk = current;
20426 ++ struct mm_struct *mm = current->mm;
20427 ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
20428 ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
20429 ++ char *path_exec = NULL;
20430 ++ char *path_fault = NULL;
20431 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
20432 ++
20433 ++ if (buffer_exec && buffer_fault) {
20434 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
20435 ++
20436 ++ down_read(&mm->mmap_sem);
20437 ++ vma = mm->mmap;
20438 ++ while (vma && (!vma_exec || !vma_fault)) {
20439 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
20440 ++ vma_exec = vma;
20441 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
20442 ++ vma_fault = vma;
20443 ++ vma = vma->vm_next;
20444 ++ }
20445 ++ if (vma_exec) {
20446 ++ struct path path = {vma_exec->vm_file->f_path.mnt, vma_exec->vm_file->f_path.dentry};
20447 ++ path_exec = d_path(&path, buffer_exec, PAGE_SIZE);
20448 ++ if (IS_ERR(path_exec))
20449 ++ path_exec = "<path too long>";
20450 ++ }
20451 ++ if (vma_fault) {
20452 ++ start = vma_fault->vm_start;
20453 ++ end = vma_fault->vm_end;
20454 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
20455 ++ if (vma_fault->vm_file) {
20456 ++ struct path path = {vma_fault->vm_file->f_path.mnt, vma_fault->vm_file->f_path.dentry};
20457 ++ path_fault = d_path(&path, buffer_fault, PAGE_SIZE);
20458 ++ if (IS_ERR(path_fault))
20459 ++ path_fault = "<path too long>";
20460 ++ } else
20461 ++ path_fault = "<anonymous mapping>";
20462 ++ }
20463 ++ up_read(&mm->mmap_sem);
20464 ++ }
20465 ++ if (tsk->signal->curr_ip)
20466 ++ 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);
20467 ++ else
20468 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
20469 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
20470 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
20471 ++ tsk->uid, tsk->euid, pc, sp);
20472 ++ free_page((unsigned long)buffer_exec);
20473 ++ free_page((unsigned long)buffer_fault);
20474 ++ pax_report_insns(pc, sp);
20475 ++ do_coredump(SIGKILL, SIGKILL, regs);
20476 ++}
20477 ++#endif
20478 ++
20479 + static void zap_process(struct task_struct *start)
20480 + {
20481 + struct task_struct *t;
20482 +@@ -1707,6 +1898,10 @@ int do_coredump(long signr, int exit_cod
20483 + */
20484 + clear_thread_flag(TIF_SIGPENDING);
20485 +
20486 ++ if (signr == SIGKILL || signr == SIGILL)
20487 ++ gr_handle_brute_attach(current);
20488 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
20489 ++
20490 + /*
20491 + * lock_kernel() because format_corename() is controlled by sysctl, which
20492 + * uses lock_kernel()
20493 +@@ -1727,6 +1922,8 @@ int do_coredump(long signr, int exit_cod
20494 +
20495 + if (ispipe) {
20496 + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
20497 ++ if (!helper_argv)
20498 ++ goto fail_unlock;
20499 + /* Terminate the string before the first option */
20500 + delimit = strchr(corename, ' ');
20501 + if (delimit)
20502 +diff -urNp a/fs/ext2/balloc.c b/fs/ext2/balloc.c
20503 +--- a/fs/ext2/balloc.c 2008-08-20 11:16:13.000000000 -0700
20504 ++++ b/fs/ext2/balloc.c 2008-08-20 18:36:57.000000000 -0700
20505 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
20506 +
20507 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20508 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
20509 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20510 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20511 + sbi->s_resuid != current->fsuid &&
20512 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20513 + return 0;
20514 +diff -urNp a/fs/ext3/balloc.c b/fs/ext3/balloc.c
20515 +--- a/fs/ext3/balloc.c 2008-08-20 11:16:13.000000000 -0700
20516 ++++ b/fs/ext3/balloc.c 2008-08-20 18:36:57.000000000 -0700
20517 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
20518 +
20519 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20520 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
20521 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20522 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20523 + sbi->s_resuid != current->fsuid &&
20524 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20525 + return 0;
20526 +diff -urNp a/fs/ext3/namei.c b/fs/ext3/namei.c
20527 +--- a/fs/ext3/namei.c 2008-08-20 11:16:13.000000000 -0700
20528 ++++ b/fs/ext3/namei.c 2008-08-20 18:36:57.000000000 -0700
20529 +@@ -1166,9 +1166,9 @@ static struct ext3_dir_entry_2 *do_split
20530 + u32 hash2;
20531 + struct dx_map_entry *map;
20532 + char *data1 = (*bh)->b_data, *data2;
20533 +- unsigned split, move, size, i;
20534 ++ unsigned split, move, size;
20535 + struct ext3_dir_entry_2 *de = NULL, *de2;
20536 +- int err = 0;
20537 ++ int i, err = 0;
20538 +
20539 + bh2 = ext3_append (handle, dir, &newblock, &err);
20540 + if (!(bh2)) {
20541 +diff -urNp a/fs/ext3/xattr.c b/fs/ext3/xattr.c
20542 +--- a/fs/ext3/xattr.c 2008-08-20 11:16:13.000000000 -0700
20543 ++++ b/fs/ext3/xattr.c 2008-08-20 18:36:57.000000000 -0700
20544 +@@ -89,8 +89,8 @@
20545 + printk("\n"); \
20546 + } while (0)
20547 + #else
20548 +-# define ea_idebug(f...)
20549 +-# define ea_bdebug(f...)
20550 ++# define ea_idebug(f...) do {} while (0)
20551 ++# define ea_bdebug(f...) do {} while (0)
20552 + #endif
20553 +
20554 + static void ext3_xattr_cache_insert(struct buffer_head *);
20555 +diff -urNp a/fs/ext4/balloc.c b/fs/ext4/balloc.c
20556 +--- a/fs/ext4/balloc.c 2008-08-20 11:16:13.000000000 -0700
20557 ++++ b/fs/ext4/balloc.c 2008-08-20 18:36:57.000000000 -0700
20558 +@@ -1557,7 +1557,7 @@ static int ext4_has_free_blocks(struct e
20559 +
20560 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20561 + root_blocks = ext4_r_blocks_count(sbi->s_es);
20562 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20563 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20564 + sbi->s_resuid != current->fsuid &&
20565 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20566 + return 0;
20567 +diff -urNp a/fs/ext4/namei.c b/fs/ext4/namei.c
20568 +--- a/fs/ext4/namei.c 2008-08-20 11:16:13.000000000 -0700
20569 ++++ b/fs/ext4/namei.c 2008-08-20 18:36:57.000000000 -0700
20570 +@@ -1168,9 +1168,9 @@ static struct ext4_dir_entry_2 *do_split
20571 + u32 hash2;
20572 + struct dx_map_entry *map;
20573 + char *data1 = (*bh)->b_data, *data2;
20574 +- unsigned split, move, size, i;
20575 ++ unsigned split, move, size;
20576 + struct ext4_dir_entry_2 *de = NULL, *de2;
20577 +- int err = 0;
20578 ++ int i, err = 0;
20579 +
20580 + bh2 = ext4_append (handle, dir, &newblock, &err);
20581 + if (!(bh2)) {
20582 +diff -urNp a/fs/fcntl.c b/fs/fcntl.c
20583 +--- a/fs/fcntl.c 2008-08-20 11:16:13.000000000 -0700
20584 ++++ b/fs/fcntl.c 2008-08-20 18:36:57.000000000 -0700
20585 +@@ -19,6 +19,7 @@
20586 + #include <linux/signal.h>
20587 + #include <linux/rcupdate.h>
20588 + #include <linux/pid_namespace.h>
20589 ++#include <linux/grsecurity.h>
20590 +
20591 + #include <asm/poll.h>
20592 + #include <asm/siginfo.h>
20593 +@@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
20594 + struct fdtable *fdt;
20595 +
20596 + error = -EINVAL;
20597 ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
20598 + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20599 + goto out;
20600 +
20601 +@@ -83,6 +85,7 @@ repeat:
20602 + fdt->max_fds, start);
20603 +
20604 + error = -EMFILE;
20605 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
20606 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20607 + goto out;
20608 +
20609 +@@ -144,6 +147,8 @@ asmlinkage long sys_dup2(unsigned int ol
20610 + struct files_struct * files = current->files;
20611 + struct fdtable *fdt;
20612 +
20613 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
20614 ++
20615 + spin_lock(&files->file_lock);
20616 + if (!(file = fcheck(oldfd)))
20617 + goto out_unlock;
20618 +@@ -463,7 +468,8 @@ static inline int sigio_perm(struct task
20619 + return (((fown->euid == 0) ||
20620 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
20621 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
20622 +- !security_file_send_sigiotask(p, fown, sig));
20623 ++ !security_file_send_sigiotask(p, fown, sig) &&
20624 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
20625 + }
20626 +
20627 + static void send_sigio_to_task(struct task_struct *p,
20628 +diff -urNp a/fs/fuse/control.c b/fs/fuse/control.c
20629 +--- a/fs/fuse/control.c 2008-08-20 11:16:13.000000000 -0700
20630 ++++ b/fs/fuse/control.c 2008-08-20 18:36:57.000000000 -0700
20631 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
20632 +
20633 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
20634 + {
20635 +- struct tree_descr empty_descr = {""};
20636 ++ struct tree_descr empty_descr = {"", NULL, 0};
20637 + struct fuse_conn *fc;
20638 + int err;
20639 +
20640 +diff -urNp a/fs/fuse/dir.c b/fs/fuse/dir.c
20641 +--- a/fs/fuse/dir.c 2008-08-20 11:16:13.000000000 -0700
20642 ++++ b/fs/fuse/dir.c 2008-08-20 18:36:57.000000000 -0700
20643 +@@ -1031,7 +1031,7 @@ static char *read_link(struct dentry *de
20644 + return link;
20645 + }
20646 +
20647 +-static void free_link(char *link)
20648 ++static void free_link(const char *link)
20649 + {
20650 + if (!IS_ERR(link))
20651 + free_page((unsigned long) link);
20652 +diff -urNp a/fs/hfs/inode.c b/fs/hfs/inode.c
20653 +--- a/fs/hfs/inode.c 2008-08-20 11:16:13.000000000 -0700
20654 ++++ b/fs/hfs/inode.c 2008-08-20 18:36:57.000000000 -0700
20655 +@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
20656 +
20657 + if (S_ISDIR(main_inode->i_mode)) {
20658 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
20659 +- /* panic? */;
20660 ++ {/* panic? */}
20661 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
20662 + sizeof(struct hfs_cat_dir));
20663 + if (rec.type != HFS_CDR_DIR ||
20664 +@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
20665 + sizeof(struct hfs_cat_file));
20666 + } else {
20667 + if (fd.entrylength < sizeof(struct hfs_cat_file))
20668 +- /* panic? */;
20669 ++ {/* panic? */}
20670 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
20671 + sizeof(struct hfs_cat_file));
20672 + if (rec.type != HFS_CDR_FIL ||
20673 +diff -urNp a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
20674 +--- a/fs/hfsplus/inode.c 2008-08-20 11:16:13.000000000 -0700
20675 ++++ b/fs/hfsplus/inode.c 2008-08-20 18:36:57.000000000 -0700
20676 +@@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode
20677 + struct hfsplus_cat_folder *folder = &entry.folder;
20678 +
20679 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
20680 +- /* panic? */;
20681 ++ {/* panic? */}
20682 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
20683 + sizeof(struct hfsplus_cat_folder));
20684 + hfsplus_get_perms(inode, &folder->permissions, 1);
20685 +@@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode
20686 + struct hfsplus_cat_file *file = &entry.file;
20687 +
20688 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
20689 +- /* panic? */;
20690 ++ {/* panic? */}
20691 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
20692 + sizeof(struct hfsplus_cat_file));
20693 +
20694 +@@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
20695 + struct hfsplus_cat_folder *folder = &entry.folder;
20696 +
20697 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
20698 +- /* panic? */;
20699 ++ {/* panic? */}
20700 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
20701 + sizeof(struct hfsplus_cat_folder));
20702 + /* simple node checks? */
20703 +@@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode
20704 + struct hfsplus_cat_file *file = &entry.file;
20705 +
20706 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
20707 +- /* panic? */;
20708 ++ {/* panic? */}
20709 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
20710 + sizeof(struct hfsplus_cat_file));
20711 + hfsplus_inode_write_fork(inode, &file->data_fork);
20712 +diff -urNp a/fs/jffs2/debug.h b/fs/jffs2/debug.h
20713 +--- a/fs/jffs2/debug.h 2008-08-20 11:16:13.000000000 -0700
20714 ++++ b/fs/jffs2/debug.h 2008-08-20 18:36:57.000000000 -0700
20715 +@@ -51,13 +51,13 @@
20716 + #if CONFIG_JFFS2_FS_DEBUG > 0
20717 + #define D1(x) x
20718 + #else
20719 +-#define D1(x)
20720 ++#define D1(x) do {} while (0);
20721 + #endif
20722 +
20723 + #if CONFIG_JFFS2_FS_DEBUG > 1
20724 + #define D2(x) x
20725 + #else
20726 +-#define D2(x)
20727 ++#define D2(x) do {} while (0);
20728 + #endif
20729 +
20730 + /* The prefixes of JFFS2 messages */
20731 +@@ -113,68 +113,68 @@
20732 + #ifdef JFFS2_DBG_READINODE_MESSAGES
20733 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20734 + #else
20735 +-#define dbg_readinode(fmt, ...)
20736 ++#define dbg_readinode(fmt, ...) do {} while (0)
20737 + #endif
20738 +
20739 + /* Fragtree build debugging messages */
20740 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
20741 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20742 + #else
20743 +-#define dbg_fragtree(fmt, ...)
20744 ++#define dbg_fragtree(fmt, ...) do {} while (0)
20745 + #endif
20746 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
20747 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20748 + #else
20749 +-#define dbg_fragtree2(fmt, ...)
20750 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
20751 + #endif
20752 +
20753 + /* Directory entry list manilulation debugging messages */
20754 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
20755 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20756 + #else
20757 +-#define dbg_dentlist(fmt, ...)
20758 ++#define dbg_dentlist(fmt, ...) do {} while (0)
20759 + #endif
20760 +
20761 + /* Print the messages about manipulating node_refs */
20762 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
20763 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20764 + #else
20765 +-#define dbg_noderef(fmt, ...)
20766 ++#define dbg_noderef(fmt, ...) do {} while (0)
20767 + #endif
20768 +
20769 + /* Manipulations with the list of inodes (JFFS2 inocache) */
20770 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
20771 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20772 + #else
20773 +-#define dbg_inocache(fmt, ...)
20774 ++#define dbg_inocache(fmt, ...) do {} while (0)
20775 + #endif
20776 +
20777 + /* Summary debugging messages */
20778 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
20779 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20780 + #else
20781 +-#define dbg_summary(fmt, ...)
20782 ++#define dbg_summary(fmt, ...) do {} while (0)
20783 + #endif
20784 +
20785 + /* File system build messages */
20786 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
20787 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20788 + #else
20789 +-#define dbg_fsbuild(fmt, ...)
20790 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
20791 + #endif
20792 +
20793 + /* Watch the object allocations */
20794 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
20795 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20796 + #else
20797 +-#define dbg_memalloc(fmt, ...)
20798 ++#define dbg_memalloc(fmt, ...) do {} while (0)
20799 + #endif
20800 +
20801 + /* Watch the XATTR subsystem */
20802 + #ifdef JFFS2_DBG_XATTR_MESSAGES
20803 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20804 + #else
20805 +-#define dbg_xattr(fmt, ...)
20806 ++#define dbg_xattr(fmt, ...) do {} while (0)
20807 + #endif
20808 +
20809 + /* "Sanity" checks */
20810 +diff -urNp a/fs/jffs2/erase.c b/fs/jffs2/erase.c
20811 +--- a/fs/jffs2/erase.c 2008-08-20 11:16:13.000000000 -0700
20812 ++++ b/fs/jffs2/erase.c 2008-08-20 18:36:57.000000000 -0700
20813 +@@ -425,7 +425,8 @@ static void jffs2_mark_erased_block(stru
20814 + struct jffs2_unknown_node marker = {
20815 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
20816 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
20817 +- .totlen = cpu_to_je32(c->cleanmarker_size)
20818 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
20819 ++ .hdr_crc = cpu_to_je32(0)
20820 + };
20821 +
20822 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
20823 +diff -urNp a/fs/jffs2/summary.h b/fs/jffs2/summary.h
20824 +--- a/fs/jffs2/summary.h 2008-08-20 11:16:13.000000000 -0700
20825 ++++ b/fs/jffs2/summary.h 2008-08-20 18:36:57.000000000 -0700
20826 +@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
20827 +
20828 + #define jffs2_sum_active() (0)
20829 + #define jffs2_sum_init(a) (0)
20830 +-#define jffs2_sum_exit(a)
20831 +-#define jffs2_sum_disable_collecting(a)
20832 ++#define jffs2_sum_exit(a) do {} while (0)
20833 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
20834 + #define jffs2_sum_is_disabled(a) (0)
20835 +-#define jffs2_sum_reset_collected(a)
20836 ++#define jffs2_sum_reset_collected(a) do {} while (0)
20837 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
20838 +-#define jffs2_sum_move_collected(a,b)
20839 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
20840 + #define jffs2_sum_write_sumnode(a) (0)
20841 +-#define jffs2_sum_add_padding_mem(a,b)
20842 +-#define jffs2_sum_add_inode_mem(a,b,c)
20843 +-#define jffs2_sum_add_dirent_mem(a,b,c)
20844 +-#define jffs2_sum_add_xattr_mem(a,b,c)
20845 +-#define jffs2_sum_add_xref_mem(a,b,c)
20846 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
20847 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
20848 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
20849 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
20850 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
20851 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
20852 +
20853 + #endif /* CONFIG_JFFS2_SUMMARY */
20854 +diff -urNp a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
20855 +--- a/fs/jffs2/wbuf.c 2008-08-20 11:16:13.000000000 -0700
20856 ++++ b/fs/jffs2/wbuf.c 2008-08-20 18:36:57.000000000 -0700
20857 +@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
20858 + {
20859 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
20860 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
20861 +- .totlen = constant_cpu_to_je32(8)
20862 ++ .totlen = constant_cpu_to_je32(8),
20863 ++ .hdr_crc = constant_cpu_to_je32(0)
20864 + };
20865 +
20866 + /*
20867 +diff -urNp a/fs/namei.c b/fs/namei.c
20868 +--- a/fs/namei.c 2008-08-20 11:16:13.000000000 -0700
20869 ++++ b/fs/namei.c 2008-08-20 18:36:57.000000000 -0700
20870 +@@ -30,6 +30,7 @@
20871 + #include <linux/capability.h>
20872 + #include <linux/file.h>
20873 + #include <linux/fcntl.h>
20874 ++#include <linux/grsecurity.h>
20875 + #include <asm/namei.h>
20876 + #include <asm/uaccess.h>
20877 +
20878 +@@ -670,7 +671,7 @@ static __always_inline int __do_follow_l
20879 + cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
20880 + error = PTR_ERR(cookie);
20881 + if (!IS_ERR(cookie)) {
20882 +- char *s = nd_get_link(nd);
20883 ++ const char *s = nd_get_link(nd);
20884 + error = 0;
20885 + if (s)
20886 + error = __vfs_follow_link(nd, s);
20887 +@@ -701,6 +702,13 @@ static inline int do_follow_link(struct
20888 + err = security_inode_follow_link(path->dentry, nd);
20889 + if (err)
20890 + goto loop;
20891 ++
20892 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
20893 ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
20894 ++ err = -EACCES;
20895 ++ goto loop;
20896 ++ }
20897 ++
20898 + current->link_count++;
20899 + current->total_link_count++;
20900 + nd->depth++;
20901 +@@ -1049,11 +1057,18 @@ return_reval:
20902 + break;
20903 + }
20904 + return_base:
20905 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
20906 ++ path_put(&nd->path);
20907 ++ return -ENOENT;
20908 ++ }
20909 + return 0;
20910 + out_dput:
20911 + path_put_conditional(&next, nd);
20912 + break;
20913 + }
20914 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
20915 ++ err = -ENOENT;
20916 ++
20917 + path_put(&nd->path);
20918 + return_err:
20919 + return err;
20920 +@@ -1698,9 +1713,17 @@ static int open_namei_create(struct name
20921 + int error;
20922 + struct dentry *dir = nd->path.dentry;
20923 +
20924 ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
20925 ++ error = -EACCES;
20926 ++ goto out_unlock_dput;
20927 ++ }
20928 ++
20929 + if (!IS_POSIXACL(dir->d_inode))
20930 + mode &= ~current->fs->umask;
20931 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
20932 ++ if (!error)
20933 ++ gr_handle_create(path->dentry, nd->path.mnt);
20934 ++out_unlock_dput:
20935 + mutex_unlock(&dir->d_inode->i_mutex);
20936 + dput(nd->path.dentry);
20937 + nd->path.dentry = path->dentry;
20938 +@@ -1751,6 +1774,17 @@ int open_namei(int dfd, const char *path
20939 + nd, flag);
20940 + if (error)
20941 + return error;
20942 ++
20943 ++ if (gr_handle_rawio(nd->path.dentry->d_inode)) {
20944 ++ error = -EPERM;
20945 ++ goto exit;
20946 ++ }
20947 ++
20948 ++ if (!gr_acl_handle_open(nd->path.dentry, nd->path.mnt, flag)) {
20949 ++ error = -EACCES;
20950 ++ goto exit;
20951 ++ }
20952 ++
20953 + goto ok;
20954 + }
20955 +
20956 +@@ -1800,6 +1834,23 @@ do_last:
20957 + /*
20958 + * It already exists.
20959 + */
20960 ++
20961 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
20962 ++ mutex_unlock(&dir->d_inode->i_mutex);
20963 ++ error = -EPERM;
20964 ++ goto exit_dput;
20965 ++ }
20966 ++ if (!gr_acl_handle_open(path.dentry, nd->path.mnt, flag)) {
20967 ++ mutex_unlock(&dir->d_inode->i_mutex);
20968 ++ error = -EACCES;
20969 ++ goto exit_dput;
20970 ++ }
20971 ++ if (gr_handle_fifo(path.dentry, nd->path.mnt, dir, flag, acc_mode)) {
20972 ++ mutex_unlock(&dir->d_inode->i_mutex);
20973 ++ error = -EACCES;
20974 ++ goto exit_dput;
20975 ++ }
20976 ++
20977 + mutex_unlock(&dir->d_inode->i_mutex);
20978 + audit_inode(pathname, path.dentry);
20979 +
20980 +@@ -1855,6 +1906,13 @@ do_link:
20981 + error = security_inode_follow_link(path.dentry, nd);
20982 + if (error)
20983 + goto exit_dput;
20984 ++
20985 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
20986 ++ path.dentry, nd->path.mnt)) {
20987 ++ error = -EACCES;
20988 ++ goto exit_dput;
20989 ++ }
20990 ++
20991 + error = __do_follow_link(&path, nd);
20992 + if (error) {
20993 + /* Does someone understand code flow here? Or it is only
20994 +@@ -1987,6 +2045,16 @@ asmlinkage long sys_mknodat(int dfd, con
20995 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
20996 + mode &= ~current->fs->umask;
20997 + if (!IS_ERR(dentry)) {
20998 ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
20999 ++ error = -EPERM;
21000 ++ goto out_free;
21001 ++ }
21002 ++
21003 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
21004 ++ error = -EACCES;
21005 ++ goto out_free;
21006 ++ }
21007 ++
21008 + switch (mode & S_IFMT) {
21009 + case 0: case S_IFREG:
21010 + error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
21011 +@@ -2004,6 +2072,11 @@ asmlinkage long sys_mknodat(int dfd, con
21012 + default:
21013 + error = -EINVAL;
21014 + }
21015 ++
21016 ++ if (!error)
21017 ++ gr_handle_create(dentry, nd.path.mnt);
21018 ++
21019 ++out_free:
21020 + dput(dentry);
21021 + }
21022 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21023 +@@ -2061,9 +2134,18 @@ asmlinkage long sys_mkdirat(int dfd, con
21024 + if (IS_ERR(dentry))
21025 + goto out_unlock;
21026 +
21027 ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
21028 ++ error = -EACCES;
21029 ++ goto out_unlock_dput;
21030 ++ }
21031 ++
21032 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
21033 + mode &= ~current->fs->umask;
21034 + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
21035 ++
21036 ++ if (!error)
21037 ++ gr_handle_create(dentry, nd.path.mnt);
21038 ++out_unlock_dput:
21039 + dput(dentry);
21040 + out_unlock:
21041 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21042 +@@ -2145,6 +2227,8 @@ static long do_rmdir(int dfd, const char
21043 + char * name;
21044 + struct dentry *dentry;
21045 + struct nameidata nd;
21046 ++ ino_t saved_ino = 0;
21047 ++ dev_t saved_dev = 0;
21048 +
21049 + name = getname(pathname);
21050 + if(IS_ERR(name))
21051 +@@ -2170,7 +2254,23 @@ static long do_rmdir(int dfd, const char
21052 + error = PTR_ERR(dentry);
21053 + if (IS_ERR(dentry))
21054 + goto exit2;
21055 ++
21056 ++ if (dentry->d_inode != NULL) {
21057 ++ if (dentry->d_inode->i_nlink <= 1) {
21058 ++ saved_ino = dentry->d_inode->i_ino;
21059 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
21060 ++ }
21061 ++
21062 ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
21063 ++ error = -EACCES;
21064 ++ goto dput_exit2;
21065 ++ }
21066 ++ }
21067 ++
21068 + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
21069 ++ if (!error && (saved_dev || saved_ino))
21070 ++ gr_handle_delete(saved_ino, saved_dev);
21071 ++dput_exit2:
21072 + dput(dentry);
21073 + exit2:
21074 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21075 +@@ -2230,6 +2330,8 @@ static long do_unlinkat(int dfd, const c
21076 + struct dentry *dentry;
21077 + struct nameidata nd;
21078 + struct inode *inode = NULL;
21079 ++ ino_t saved_ino = 0;
21080 ++ dev_t saved_dev = 0;
21081 +
21082 + name = getname(pathname);
21083 + if(IS_ERR(name))
21084 +@@ -2245,13 +2347,26 @@ static long do_unlinkat(int dfd, const c
21085 + dentry = lookup_hash(&nd);
21086 + error = PTR_ERR(dentry);
21087 + if (!IS_ERR(dentry)) {
21088 ++ error = 0;
21089 + /* Why not before? Because we want correct error value */
21090 + if (nd.last.name[nd.last.len])
21091 + goto slashes;
21092 + inode = dentry->d_inode;
21093 +- if (inode)
21094 ++ if (inode) {
21095 ++ if (inode->i_nlink <= 1) {
21096 ++ saved_ino = inode->i_ino;
21097 ++ saved_dev = inode->i_sb->s_dev;
21098 ++ }
21099 ++
21100 ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt))
21101 ++ error = -EACCES;
21102 ++
21103 + atomic_inc(&inode->i_count);
21104 +- error = vfs_unlink(nd.path.dentry->d_inode, dentry);
21105 ++ }
21106 ++ if (!error)
21107 ++ error = vfs_unlink(nd.path.dentry->d_inode, dentry);
21108 ++ if (!error && (saved_ino || saved_dev))
21109 ++ gr_handle_delete(saved_ino, saved_dev);
21110 + exit2:
21111 + dput(dentry);
21112 + }
21113 +@@ -2332,7 +2447,17 @@ asmlinkage long sys_symlinkat(const char
21114 + if (IS_ERR(dentry))
21115 + goto out_unlock;
21116 +
21117 ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
21118 ++ error = -EACCES;
21119 ++ goto out_dput_unlock;
21120 ++ }
21121 ++
21122 + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
21123 ++
21124 ++ if (!error)
21125 ++ gr_handle_create(dentry, nd.path.mnt);
21126 ++
21127 ++out_dput_unlock:
21128 + dput(dentry);
21129 + out_unlock:
21130 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21131 +@@ -2427,7 +2552,26 @@ asmlinkage long sys_linkat(int olddfd, c
21132 + error = PTR_ERR(new_dentry);
21133 + if (IS_ERR(new_dentry))
21134 + goto out_unlock;
21135 ++
21136 ++ if (gr_handle_hardlink(old_nd.path.dentry, old_nd.path.mnt,
21137 ++ old_nd.path.dentry->d_inode,
21138 ++ old_nd.path.dentry->d_inode->i_mode, to)) {
21139 ++ error = -EACCES;
21140 ++ goto out_unlock_dput;
21141 ++ }
21142 ++
21143 ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
21144 ++ old_nd.path.dentry, old_nd.path.mnt, to)) {
21145 ++ error = -EACCES;
21146 ++ goto out_unlock_dput;
21147 ++ }
21148 ++
21149 + error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
21150 ++
21151 ++ if (!error)
21152 ++ gr_handle_create(new_dentry, nd.path.mnt);
21153 ++
21154 ++out_unlock_dput:
21155 + dput(new_dentry);
21156 + out_unlock:
21157 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21158 +@@ -2653,8 +2797,16 @@ static int do_rename(int olddfd, const c
21159 + if (new_dentry == trap)
21160 + goto exit5;
21161 +
21162 +- error = vfs_rename(old_dir->d_inode, old_dentry,
21163 ++ error = gr_acl_handle_rename(new_dentry, newnd.path.dentry, newnd.path.mnt,
21164 ++ old_dentry, old_dir->d_inode, oldnd.path.mnt,
21165 ++ newname);
21166 ++
21167 ++ if (!error)
21168 ++ error = vfs_rename(old_dir->d_inode, old_dentry,
21169 + new_dir->d_inode, new_dentry);
21170 ++ if (!error)
21171 ++ gr_handle_rename(old_dir->d_inode, newnd.path.dentry->d_inode, old_dentry,
21172 ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
21173 + exit5:
21174 + dput(new_dentry);
21175 + exit4:
21176 +diff -urNp a/fs/namespace.c b/fs/namespace.c
21177 +--- a/fs/namespace.c 2008-08-20 11:16:13.000000000 -0700
21178 ++++ b/fs/namespace.c 2008-08-20 18:36:57.000000000 -0700
21179 +@@ -26,6 +26,7 @@
21180 + #include <linux/mount.h>
21181 + #include <linux/ramfs.h>
21182 + #include <linux/log2.h>
21183 ++#include <linux/grsecurity.h>
21184 + #include <asm/uaccess.h>
21185 + #include <asm/unistd.h>
21186 + #include "pnode.h"
21187 +@@ -644,6 +645,8 @@ static int do_umount(struct vfsmount *mn
21188 + DQUOT_OFF(sb);
21189 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
21190 + unlock_kernel();
21191 ++
21192 ++ gr_log_remount(mnt->mnt_devname, retval);
21193 + }
21194 + up_write(&sb->s_umount);
21195 + return retval;
21196 +@@ -667,6 +670,9 @@ static int do_umount(struct vfsmount *mn
21197 + security_sb_umount_busy(mnt);
21198 + up_write(&namespace_sem);
21199 + release_mounts(&umount_list);
21200 ++
21201 ++ gr_log_unmount(mnt->mnt_devname, retval);
21202 ++
21203 + return retval;
21204 + }
21205 +
21206 +@@ -1438,6 +1444,11 @@ long do_mount(char *dev_name, char *dir_
21207 + if (retval)
21208 + goto dput_out;
21209 +
21210 ++ if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
21211 ++ retval = -EPERM;
21212 ++ goto dput_out;
21213 ++ }
21214 ++
21215 + if (flags & MS_REMOUNT)
21216 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
21217 + data_page);
21218 +@@ -1452,6 +1463,9 @@ long do_mount(char *dev_name, char *dir_
21219 + dev_name, data_page);
21220 + dput_out:
21221 + path_put(&nd.path);
21222 ++
21223 ++ gr_log_mount(dev_name, dir_name, retval);
21224 ++
21225 + return retval;
21226 + }
21227 +
21228 +@@ -1681,6 +1695,9 @@ asmlinkage long sys_pivot_root(const cha
21229 + if (!capable(CAP_SYS_ADMIN))
21230 + return -EPERM;
21231 +
21232 ++ if (gr_handle_chroot_pivot())
21233 ++ return -EPERM;
21234 ++
21235 + lock_kernel();
21236 +
21237 + error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
21238 +diff -urNp a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
21239 +--- a/fs/nfs/nfs4proc.c 2008-08-20 11:16:13.000000000 -0700
21240 ++++ b/fs/nfs/nfs4proc.c 2008-08-20 18:36:57.000000000 -0700
21241 +@@ -654,7 +654,7 @@ static int _nfs4_do_open_reclaim(struct
21242 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
21243 + {
21244 + struct nfs_server *server = NFS_SERVER(state->inode);
21245 +- struct nfs4_exception exception = { };
21246 ++ struct nfs4_exception exception = {0, 0};
21247 + int err;
21248 + do {
21249 + err = _nfs4_do_open_reclaim(ctx, state);
21250 +@@ -696,7 +696,7 @@ static int _nfs4_open_delegation_recall(
21251 +
21252 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
21253 + {
21254 +- struct nfs4_exception exception = { };
21255 ++ struct nfs4_exception exception = {0, 0};
21256 + struct nfs_server *server = NFS_SERVER(state->inode);
21257 + int err;
21258 + do {
21259 +@@ -992,7 +992,7 @@ static int _nfs4_open_expired(struct nfs
21260 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
21261 + {
21262 + struct nfs_server *server = NFS_SERVER(state->inode);
21263 +- struct nfs4_exception exception = { };
21264 ++ struct nfs4_exception exception = {0, 0};
21265 + int err;
21266 +
21267 + do {
21268 +@@ -1094,7 +1094,7 @@ out_err:
21269 +
21270 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
21271 + {
21272 +- struct nfs4_exception exception = { };
21273 ++ struct nfs4_exception exception = {0, 0};
21274 + struct nfs4_state *res;
21275 + int status;
21276 +
21277 +@@ -1183,7 +1183,7 @@ static int nfs4_do_setattr(struct inode
21278 + struct iattr *sattr, struct nfs4_state *state)
21279 + {
21280 + struct nfs_server *server = NFS_SERVER(inode);
21281 +- struct nfs4_exception exception = { };
21282 ++ struct nfs4_exception exception = {0, 0};
21283 + int err;
21284 + do {
21285 + err = nfs4_handle_exception(server,
21286 +@@ -1496,7 +1496,7 @@ static int _nfs4_server_capabilities(str
21287 +
21288 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
21289 + {
21290 +- struct nfs4_exception exception = { };
21291 ++ struct nfs4_exception exception = {0, 0};
21292 + int err;
21293 + do {
21294 + err = nfs4_handle_exception(server,
21295 +@@ -1529,7 +1529,7 @@ static int _nfs4_lookup_root(struct nfs_
21296 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
21297 + struct nfs_fsinfo *info)
21298 + {
21299 +- struct nfs4_exception exception = { };
21300 ++ struct nfs4_exception exception = {0, 0};
21301 + int err;
21302 + do {
21303 + err = nfs4_handle_exception(server,
21304 +@@ -1618,7 +1618,7 @@ static int _nfs4_proc_getattr(struct nfs
21305 +
21306 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
21307 + {
21308 +- struct nfs4_exception exception = { };
21309 ++ struct nfs4_exception exception = {0, 0};
21310 + int err;
21311 + do {
21312 + err = nfs4_handle_exception(server,
21313 +@@ -1708,7 +1708,7 @@ static int nfs4_proc_lookupfh(struct nfs
21314 + struct qstr *name, struct nfs_fh *fhandle,
21315 + struct nfs_fattr *fattr)
21316 + {
21317 +- struct nfs4_exception exception = { };
21318 ++ struct nfs4_exception exception = {0, 0};
21319 + int err;
21320 + do {
21321 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
21322 +@@ -1737,7 +1737,7 @@ static int _nfs4_proc_lookup(struct inod
21323 +
21324 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
21325 + {
21326 +- struct nfs4_exception exception = { };
21327 ++ struct nfs4_exception exception = {0, 0};
21328 + int err;
21329 + do {
21330 + err = nfs4_handle_exception(NFS_SERVER(dir),
21331 +@@ -1801,7 +1801,7 @@ static int _nfs4_proc_access(struct inod
21332 +
21333 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
21334 + {
21335 +- struct nfs4_exception exception = { };
21336 ++ struct nfs4_exception exception = {0, 0};
21337 + int err;
21338 + do {
21339 + err = nfs4_handle_exception(NFS_SERVER(inode),
21340 +@@ -1856,7 +1856,7 @@ static int _nfs4_proc_readlink(struct in
21341 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
21342 + unsigned int pgbase, unsigned int pglen)
21343 + {
21344 +- struct nfs4_exception exception = { };
21345 ++ struct nfs4_exception exception = {0, 0};
21346 + int err;
21347 + do {
21348 + err = nfs4_handle_exception(NFS_SERVER(inode),
21349 +@@ -1952,7 +1952,7 @@ static int _nfs4_proc_remove(struct inod
21350 +
21351 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
21352 + {
21353 +- struct nfs4_exception exception = { };
21354 ++ struct nfs4_exception exception = {0, 0};
21355 + int err;
21356 + do {
21357 + err = nfs4_handle_exception(NFS_SERVER(dir),
21358 +@@ -2024,7 +2024,7 @@ static int _nfs4_proc_rename(struct inod
21359 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
21360 + struct inode *new_dir, struct qstr *new_name)
21361 + {
21362 +- struct nfs4_exception exception = { };
21363 ++ struct nfs4_exception exception = {0, 0};
21364 + int err;
21365 + do {
21366 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
21367 +@@ -2071,7 +2071,7 @@ static int _nfs4_proc_link(struct inode
21368 +
21369 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
21370 + {
21371 +- struct nfs4_exception exception = { };
21372 ++ struct nfs4_exception exception = {0, 0};
21373 + int err;
21374 + do {
21375 + err = nfs4_handle_exception(NFS_SERVER(inode),
21376 +@@ -2128,7 +2128,7 @@ static int _nfs4_proc_symlink(struct ino
21377 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
21378 + struct page *page, unsigned int len, struct iattr *sattr)
21379 + {
21380 +- struct nfs4_exception exception = { };
21381 ++ struct nfs4_exception exception = {0, 0};
21382 + int err;
21383 + do {
21384 + err = nfs4_handle_exception(NFS_SERVER(dir),
21385 +@@ -2181,7 +2181,7 @@ static int _nfs4_proc_mkdir(struct inode
21386 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
21387 + struct iattr *sattr)
21388 + {
21389 +- struct nfs4_exception exception = { };
21390 ++ struct nfs4_exception exception = {0, 0};
21391 + int err;
21392 + do {
21393 + err = nfs4_handle_exception(NFS_SERVER(dir),
21394 +@@ -2230,7 +2230,7 @@ static int _nfs4_proc_readdir(struct den
21395 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
21396 + u64 cookie, struct page *page, unsigned int count, int plus)
21397 + {
21398 +- struct nfs4_exception exception = { };
21399 ++ struct nfs4_exception exception = {0, 0};
21400 + int err;
21401 + do {
21402 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
21403 +@@ -2300,7 +2300,7 @@ static int _nfs4_proc_mknod(struct inode
21404 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
21405 + struct iattr *sattr, dev_t rdev)
21406 + {
21407 +- struct nfs4_exception exception = { };
21408 ++ struct nfs4_exception exception = {0, 0};
21409 + int err;
21410 + do {
21411 + err = nfs4_handle_exception(NFS_SERVER(dir),
21412 +@@ -2329,7 +2329,7 @@ static int _nfs4_proc_statfs(struct nfs_
21413 +
21414 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
21415 + {
21416 +- struct nfs4_exception exception = { };
21417 ++ struct nfs4_exception exception = {0, 0};
21418 + int err;
21419 + do {
21420 + err = nfs4_handle_exception(server,
21421 +@@ -2357,7 +2357,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
21422 +
21423 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
21424 + {
21425 +- struct nfs4_exception exception = { };
21426 ++ struct nfs4_exception exception = {0, 0};
21427 + int err;
21428 +
21429 + do {
21430 +@@ -2400,7 +2400,7 @@ static int _nfs4_proc_pathconf(struct nf
21431 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
21432 + struct nfs_pathconf *pathconf)
21433 + {
21434 +- struct nfs4_exception exception = { };
21435 ++ struct nfs4_exception exception = {0, 0};
21436 + int err;
21437 +
21438 + do {
21439 +@@ -2687,7 +2687,7 @@ out_free:
21440 +
21441 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
21442 + {
21443 +- struct nfs4_exception exception = { };
21444 ++ struct nfs4_exception exception = {0, 0};
21445 + ssize_t ret;
21446 + do {
21447 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
21448 +@@ -2744,7 +2744,7 @@ static int __nfs4_proc_set_acl(struct in
21449 +
21450 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
21451 + {
21452 +- struct nfs4_exception exception = { };
21453 ++ struct nfs4_exception exception = {0, 0};
21454 + int err;
21455 + do {
21456 + err = nfs4_handle_exception(NFS_SERVER(inode),
21457 +@@ -3036,7 +3036,7 @@ out:
21458 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
21459 + {
21460 + struct nfs_server *server = NFS_SERVER(inode);
21461 +- struct nfs4_exception exception = { };
21462 ++ struct nfs4_exception exception = {0, 0};
21463 + int err;
21464 + do {
21465 + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
21466 +@@ -3111,7 +3111,7 @@ out:
21467 +
21468 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
21469 + {
21470 +- struct nfs4_exception exception = { };
21471 ++ struct nfs4_exception exception = {0, 0};
21472 + int err;
21473 +
21474 + do {
21475 +@@ -3457,7 +3457,7 @@ static int _nfs4_do_setlk(struct nfs4_st
21476 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
21477 + {
21478 + struct nfs_server *server = NFS_SERVER(state->inode);
21479 +- struct nfs4_exception exception = { };
21480 ++ struct nfs4_exception exception = {0, 0};
21481 + int err;
21482 +
21483 + do {
21484 +@@ -3475,7 +3475,7 @@ static int nfs4_lock_reclaim(struct nfs4
21485 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
21486 + {
21487 + struct nfs_server *server = NFS_SERVER(state->inode);
21488 +- struct nfs4_exception exception = { };
21489 ++ struct nfs4_exception exception = {0, 0};
21490 + int err;
21491 +
21492 + err = nfs4_set_lock_state(state, request);
21493 +@@ -3536,7 +3536,7 @@ out:
21494 +
21495 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
21496 + {
21497 +- struct nfs4_exception exception = { };
21498 ++ struct nfs4_exception exception = {0, 0};
21499 + int err;
21500 +
21501 + do {
21502 +@@ -3586,7 +3586,7 @@ nfs4_proc_lock(struct file *filp, int cm
21503 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
21504 + {
21505 + struct nfs_server *server = NFS_SERVER(state->inode);
21506 +- struct nfs4_exception exception = { };
21507 ++ struct nfs4_exception exception = {0, 0};
21508 + int err;
21509 +
21510 + err = nfs4_set_lock_state(state, fl);
21511 +diff -urNp a/fs/nfsd/export.c b/fs/nfsd/export.c
21512 +--- a/fs/nfsd/export.c 2008-08-20 11:16:13.000000000 -0700
21513 ++++ b/fs/nfsd/export.c 2008-08-20 18:36:57.000000000 -0700
21514 +@@ -472,7 +472,7 @@ static int secinfo_parse(char **mesg, ch
21515 + * probably discover the problem when someone fails to
21516 + * authenticate.
21517 + */
21518 +- if (f->pseudoflavor < 0)
21519 ++ if ((s32)f->pseudoflavor < 0)
21520 + return -EINVAL;
21521 + err = get_int(mesg, &f->flags);
21522 + if (err)
21523 +diff -urNp a/fs/nls/nls_base.c b/fs/nls/nls_base.c
21524 +--- a/fs/nls/nls_base.c 2008-08-20 11:16:13.000000000 -0700
21525 ++++ b/fs/nls/nls_base.c 2008-08-20 18:36:57.000000000 -0700
21526 +@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
21527 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
21528 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
21529 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
21530 +- {0, /* end of table */}
21531 ++ {0, 0, 0, 0, 0, /* end of table */}
21532 + };
21533 +
21534 + int
21535 +diff -urNp a/fs/ntfs/file.c b/fs/ntfs/file.c
21536 +--- a/fs/ntfs/file.c 2008-08-20 11:16:13.000000000 -0700
21537 ++++ b/fs/ntfs/file.c 2008-08-20 18:36:57.000000000 -0700
21538 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
21539 + #endif /* NTFS_RW */
21540 + };
21541 +
21542 +-const struct file_operations ntfs_empty_file_ops = {};
21543 ++const struct file_operations ntfs_empty_file_ops;
21544 +
21545 +-const struct inode_operations ntfs_empty_inode_ops = {};
21546 ++const struct inode_operations ntfs_empty_inode_ops;
21547 +diff -urNp a/fs/open.c b/fs/open.c
21548 +--- a/fs/open.c 2008-08-20 11:16:13.000000000 -0700
21549 ++++ b/fs/open.c 2008-08-20 18:36:57.000000000 -0700
21550 +@@ -27,6 +27,7 @@
21551 + #include <linux/rcupdate.h>
21552 + #include <linux/audit.h>
21553 + #include <linux/falloc.h>
21554 ++#include <linux/grsecurity.h>
21555 +
21556 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
21557 + {
21558 +@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
21559 + if (length < 0)
21560 + return -EINVAL;
21561 +
21562 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
21563 ++ return -EACCES;
21564 ++
21565 + newattrs.ia_size = length;
21566 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
21567 + if (filp) {
21568 +@@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c
21569 + if(IS_RDONLY(nd.path.dentry->d_inode))
21570 + res = -EROFS;
21571 +
21572 ++ if (!res && !gr_acl_handle_access(nd.path.dentry, nd.path.mnt, mode))
21573 ++ res = -EACCES;
21574 ++
21575 + out_path_release:
21576 + path_put(&nd.path);
21577 + out:
21578 +@@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u
21579 + if (error)
21580 + goto dput_and_out;
21581 +
21582 ++ gr_log_chdir(nd.path.dentry, nd.path.mnt);
21583 ++
21584 + set_fs_pwd(current->fs, &nd.path);
21585 +
21586 + dput_and_out:
21587 +@@ -516,6 +525,13 @@ asmlinkage long sys_fchdir(unsigned int
21588 + goto out_putf;
21589 +
21590 + error = file_permission(file, MAY_EXEC);
21591 ++
21592 ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
21593 ++ error = -EPERM;
21594 ++
21595 ++ if (!error)
21596 ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
21597 ++
21598 + if (!error)
21599 + set_fs_pwd(current->fs, &file->f_path);
21600 + out_putf:
21601 +@@ -541,8 +557,16 @@ asmlinkage long sys_chroot(const char __
21602 + if (!capable(CAP_SYS_CHROOT))
21603 + goto dput_and_out;
21604 +
21605 ++ if (gr_handle_chroot_chroot(nd.path.dentry, nd.path.mnt))
21606 ++ goto dput_and_out;
21607 ++
21608 + set_fs_root(current->fs, &nd.path);
21609 + set_fs_altroot();
21610 ++
21611 ++ gr_handle_chroot_caps(current);
21612 ++
21613 ++ gr_handle_chroot_chdir(&nd.path);
21614 ++
21615 + error = 0;
21616 + dput_and_out:
21617 + path_put(&nd.path);
21618 +@@ -573,9 +597,22 @@ asmlinkage long sys_fchmod(unsigned int
21619 + err = -EPERM;
21620 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21621 + goto out_putf;
21622 ++
21623 ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
21624 ++ err = -EACCES;
21625 ++ goto out_putf;
21626 ++ }
21627 ++
21628 + mutex_lock(&inode->i_mutex);
21629 + if (mode == (mode_t) -1)
21630 + mode = inode->i_mode;
21631 ++
21632 ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
21633 ++ err = -EPERM;
21634 ++ mutex_unlock(&inode->i_mutex);
21635 ++ goto out_putf;
21636 ++ }
21637 ++
21638 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
21639 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
21640 + err = notify_change(dentry, &newattrs);
21641 +@@ -608,9 +645,21 @@ asmlinkage long sys_fchmodat(int dfd, co
21642 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21643 + goto dput_and_out;
21644 +
21645 ++ if (!gr_acl_handle_chmod(nd.path.dentry, nd.path.mnt, mode)) {
21646 ++ error = -EACCES;
21647 ++ goto dput_and_out;
21648 ++ };
21649 ++
21650 + mutex_lock(&inode->i_mutex);
21651 + if (mode == (mode_t) -1)
21652 + mode = inode->i_mode;
21653 ++
21654 ++ if (gr_handle_chroot_chmod(nd.path.dentry, nd.path.mnt, mode)) {
21655 ++ error = -EACCES;
21656 ++ mutex_unlock(&inode->i_mutex);
21657 ++ goto dput_and_out;
21658 ++ }
21659 ++
21660 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
21661 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
21662 + error = notify_change(nd.path.dentry, &newattrs);
21663 +@@ -627,7 +676,7 @@ asmlinkage long sys_chmod(const char __u
21664 + return sys_fchmodat(AT_FDCWD, filename, mode);
21665 + }
21666 +
21667 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
21668 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
21669 + {
21670 + struct inode * inode;
21671 + int error;
21672 +@@ -644,6 +693,12 @@ static int chown_common(struct dentry *
21673 + error = -EPERM;
21674 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21675 + goto out;
21676 ++
21677 ++ if (!gr_acl_handle_chown(dentry, mnt)) {
21678 ++ error = -EACCES;
21679 ++ goto out;
21680 ++ }
21681 ++
21682 + newattrs.ia_valid = ATTR_CTIME;
21683 + if (user != (uid_t) -1) {
21684 + newattrs.ia_valid |= ATTR_UID;
21685 +@@ -671,7 +726,7 @@ asmlinkage long sys_chown(const char __u
21686 + error = user_path_walk(filename, &nd);
21687 + if (error)
21688 + goto out;
21689 +- error = chown_common(nd.path.dentry, user, group);
21690 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
21691 + path_put(&nd.path);
21692 + out:
21693 + return error;
21694 +@@ -691,7 +746,7 @@ asmlinkage long sys_fchownat(int dfd, co
21695 + error = __user_walk_fd(dfd, filename, follow, &nd);
21696 + if (error)
21697 + goto out;
21698 +- error = chown_common(nd.path.dentry, user, group);
21699 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
21700 + path_put(&nd.path);
21701 + out:
21702 + return error;
21703 +@@ -705,7 +760,7 @@ asmlinkage long sys_lchown(const char __
21704 + error = user_path_walk_link(filename, &nd);
21705 + if (error)
21706 + goto out;
21707 +- error = chown_common(nd.path.dentry, user, group);
21708 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
21709 + path_put(&nd.path);
21710 + out:
21711 + return error;
21712 +@@ -724,7 +779,7 @@ asmlinkage long sys_fchown(unsigned int
21713 +
21714 + dentry = file->f_path.dentry;
21715 + audit_inode(NULL, dentry);
21716 +- error = chown_common(dentry, user, group);
21717 ++ error = chown_common(dentry, user, group, file->f_path.mnt);
21718 + fput(file);
21719 + out:
21720 + return error;
21721 +@@ -948,6 +1003,7 @@ repeat:
21722 + * N.B. For clone tasks sharing a files structure, this test
21723 + * will limit the total number of files that can be opened.
21724 + */
21725 ++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
21726 + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
21727 + goto out;
21728 +
21729 +diff -urNp a/fs/partitions/efi.c b/fs/partitions/efi.c
21730 +--- a/fs/partitions/efi.c 2008-08-20 11:16:13.000000000 -0700
21731 ++++ b/fs/partitions/efi.c 2008-08-20 18:36:57.000000000 -0700
21732 +@@ -99,7 +99,7 @@
21733 + #ifdef EFI_DEBUG
21734 + #define Dprintk(x...) printk(KERN_DEBUG x)
21735 + #else
21736 +-#define Dprintk(x...)
21737 ++#define Dprintk(x...) do {} while (0)
21738 + #endif
21739 +
21740 + /* This allows a kernel command line option 'gpt' to override
21741 +diff -urNp a/fs/pipe.c b/fs/pipe.c
21742 +--- a/fs/pipe.c 2008-08-20 11:16:13.000000000 -0700
21743 ++++ b/fs/pipe.c 2008-08-20 18:36:57.000000000 -0700
21744 +@@ -885,7 +885,7 @@ void free_pipe_info(struct inode *inode)
21745 + inode->i_pipe = NULL;
21746 + }
21747 +
21748 +-static struct vfsmount *pipe_mnt __read_mostly;
21749 ++struct vfsmount *pipe_mnt __read_mostly;
21750 + static int pipefs_delete_dentry(struct dentry *dentry)
21751 + {
21752 + /*
21753 +diff -urNp a/fs/proc/array.c b/fs/proc/array.c
21754 +--- a/fs/proc/array.c 2008-08-20 11:16:13.000000000 -0700
21755 ++++ b/fs/proc/array.c 2008-08-20 18:36:57.000000000 -0700
21756 +@@ -308,6 +308,21 @@ static inline void task_context_switch_c
21757 + p->nivcsw);
21758 + }
21759 +
21760 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21761 ++static inline void task_pax(struct seq_file *m, struct task_struct *p)
21762 ++{
21763 ++ if (p->mm)
21764 ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
21765 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
21766 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
21767 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
21768 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
21769 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
21770 ++ else
21771 ++ seq_printf(m, "PaX:\t-----\n");
21772 ++}
21773 ++#endif
21774 ++
21775 + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
21776 + struct pid *pid, struct task_struct *task)
21777 + {
21778 +@@ -327,6 +342,11 @@ int proc_pid_status(struct seq_file *m,
21779 + task_show_regs(m, task);
21780 + #endif
21781 + task_context_switch_counts(m, task);
21782 ++
21783 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21784 ++ task_pax(m, task);
21785 ++#endif
21786 ++
21787 + return 0;
21788 + }
21789 +
21790 +@@ -389,6 +409,12 @@ static cputime_t task_gtime(struct task_
21791 + return p->gtime;
21792 + }
21793 +
21794 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21795 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
21796 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
21797 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
21798 ++#endif
21799 ++
21800 + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
21801 + struct pid *pid, struct task_struct *task, int whole)
21802 + {
21803 +@@ -481,6 +507,19 @@ static int do_task_stat(struct seq_file
21804 + gtime = task_gtime(task);
21805 + }
21806 +
21807 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21808 ++ if (PAX_RAND_FLAGS(mm)) {
21809 ++ eip = 0;
21810 ++ esp = 0;
21811 ++ wchan = 0;
21812 ++ }
21813 ++#endif
21814 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
21815 ++ wchan = 0;
21816 ++ eip =0;
21817 ++ esp =0;
21818 ++#endif
21819 ++
21820 + /* scale priority and nice values from timeslices to -20..20 */
21821 + /* to make it look like a "normal" Unix priority/nice value */
21822 + priority = task_prio(task);
21823 +@@ -521,9 +560,15 @@ static int do_task_stat(struct seq_file
21824 + vsize,
21825 + mm ? get_mm_rss(mm) : 0,
21826 + rsslim,
21827 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21828 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
21829 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
21830 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
21831 ++#else
21832 + mm ? mm->start_code : 0,
21833 + mm ? mm->end_code : 0,
21834 + mm ? mm->start_stack : 0,
21835 ++#endif
21836 + esp,
21837 + eip,
21838 + /* The signal information here is obsolete.
21839 +@@ -576,3 +621,10 @@ int proc_pid_statm(struct seq_file *m, s
21840 +
21841 + return 0;
21842 + }
21843 ++
21844 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
21845 ++int proc_pid_ipaddr(struct task_struct *task, char *buffer)
21846 ++{
21847 ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
21848 ++}
21849 ++#endif
21850 +diff -urNp a/fs/proc/base.c b/fs/proc/base.c
21851 +--- a/fs/proc/base.c 2008-08-20 11:16:13.000000000 -0700
21852 ++++ b/fs/proc/base.c 2008-08-20 18:36:57.000000000 -0700
21853 +@@ -76,6 +76,8 @@
21854 + #include <linux/oom.h>
21855 + #include <linux/elf.h>
21856 + #include <linux/pid_namespace.h>
21857 ++#include <linux/grsecurity.h>
21858 ++
21859 + #include "internal.h"
21860 +
21861 + /* NOTE:
21862 +@@ -145,7 +147,7 @@ static unsigned int pid_entry_count_dirs
21863 + return count;
21864 + }
21865 +
21866 +-int maps_protect;
21867 ++int maps_protect = 1;
21868 + EXPORT_SYMBOL(maps_protect);
21869 +
21870 + static struct fs_struct *get_fs_struct(struct task_struct *task)
21871 +@@ -219,7 +221,7 @@ static int proc_root_link(struct inode *
21872 + (task->parent == current && \
21873 + (task->ptrace & PT_PTRACED) && \
21874 + (task_is_stopped_or_traced(task)) && \
21875 +- security_ptrace(current,task) == 0))
21876 ++ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
21877 +
21878 + struct mm_struct *mm_for_maps(struct task_struct *task)
21879 + {
21880 +@@ -284,9 +286,9 @@ static int proc_pid_auxv(struct task_str
21881 + struct mm_struct *mm = get_task_mm(task);
21882 + if (mm) {
21883 + unsigned int nwords = 0;
21884 +- do
21885 ++ do {
21886 + nwords += 2;
21887 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
21888 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
21889 + res = nwords * sizeof(mm->saved_auxv[0]);
21890 + if (res > PAGE_SIZE)
21891 + res = PAGE_SIZE;
21892 +@@ -734,7 +736,7 @@ static ssize_t mem_read(struct file * fi
21893 + if (!task)
21894 + goto out_no_task;
21895 +
21896 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
21897 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
21898 + goto out;
21899 +
21900 + ret = -ENOMEM;
21901 +@@ -804,7 +806,7 @@ static ssize_t mem_write(struct file * f
21902 + if (!task)
21903 + goto out_no_task;
21904 +
21905 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
21906 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
21907 + goto out;
21908 +
21909 + copied = -ENOMEM;
21910 +@@ -1307,7 +1309,11 @@ static struct inode *proc_pid_make_inode
21911 + inode->i_gid = 0;
21912 + if (task_dumpable(task)) {
21913 + inode->i_uid = task->euid;
21914 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21915 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
21916 ++#else
21917 + inode->i_gid = task->egid;
21918 ++#endif
21919 + }
21920 + security_task_to_inode(task, inode);
21921 +
21922 +@@ -1323,17 +1329,45 @@ static int pid_getattr(struct vfsmount *
21923 + {
21924 + struct inode *inode = dentry->d_inode;
21925 + struct task_struct *task;
21926 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21927 ++ struct task_struct *tmp = current;
21928 ++#endif
21929 ++
21930 + generic_fillattr(inode, stat);
21931 +
21932 + rcu_read_lock();
21933 + stat->uid = 0;
21934 + stat->gid = 0;
21935 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
21936 +- if (task) {
21937 ++
21938 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
21939 ++ rcu_read_unlock();
21940 ++ return -ENOENT;
21941 ++ }
21942 ++
21943 ++
21944 ++ if (task
21945 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21946 ++ && (!tmp->uid || (tmp->uid == task->uid)
21947 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21948 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
21949 ++#endif
21950 ++ )
21951 ++#endif
21952 ++ ) {
21953 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
21954 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
21955 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
21956 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21957 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
21958 ++#endif
21959 + task_dumpable(task)) {
21960 + stat->uid = task->euid;
21961 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21962 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
21963 ++#else
21964 + stat->gid = task->egid;
21965 ++#endif
21966 + }
21967 + }
21968 + rcu_read_unlock();
21969 +@@ -1361,11 +1395,21 @@ static int pid_revalidate(struct dentry
21970 + {
21971 + struct inode *inode = dentry->d_inode;
21972 + struct task_struct *task = get_proc_task(inode);
21973 ++
21974 + if (task) {
21975 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
21976 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
21977 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
21978 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21979 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
21980 ++#endif
21981 + task_dumpable(task)) {
21982 + inode->i_uid = task->euid;
21983 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21984 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
21985 ++#else
21986 + inode->i_gid = task->egid;
21987 ++#endif
21988 + } else {
21989 + inode->i_uid = 0;
21990 + inode->i_gid = 0;
21991 +@@ -1736,12 +1780,22 @@ static int proc_fd_permission(struct ino
21992 + struct nameidata *nd)
21993 + {
21994 + int rv;
21995 ++ struct task_struct *task;
21996 +
21997 + rv = generic_permission(inode, mask, NULL);
21998 +- if (rv == 0)
21999 +- return 0;
22000 ++
22001 + if (task_pid(current) == proc_pid(inode))
22002 + rv = 0;
22003 ++
22004 ++ task = get_proc_task(inode);
22005 ++ if (task == NULL)
22006 ++ return rv;
22007 ++
22008 ++ if (gr_acl_handle_procpidmem(task))
22009 ++ rv = -EACCES;
22010 ++
22011 ++ put_task_struct(task);
22012 ++
22013 + return rv;
22014 + }
22015 +
22016 +@@ -1852,6 +1906,9 @@ static struct dentry *proc_pident_lookup
22017 + if (!task)
22018 + goto out_no_task;
22019 +
22020 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22021 ++ goto out;
22022 ++
22023 + /*
22024 + * Yes, it does not scale. And it should not. Don't add
22025 + * new entries into /proc/<tgid>/ without very good reasons.
22026 +@@ -1896,6 +1953,9 @@ static int proc_pident_readdir(struct fi
22027 + if (!task)
22028 + goto out_no_task;
22029 +
22030 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22031 ++ goto out;
22032 ++
22033 + ret = 0;
22034 + i = filp->f_pos;
22035 + switch (i) {
22036 +@@ -2258,6 +2318,9 @@ static struct dentry *proc_base_lookup(s
22037 + if (p > last)
22038 + goto out;
22039 +
22040 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22041 ++ goto out;
22042 ++
22043 + error = proc_base_instantiate(dir, dentry, task, p);
22044 +
22045 + out:
22046 +@@ -2369,6 +2432,9 @@ static const struct pid_entry tgid_base_
22047 + #ifdef CONFIG_TASK_IO_ACCOUNTING
22048 + INF("io", S_IRUGO, pid_io_accounting),
22049 + #endif
22050 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
22051 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
22052 ++#endif
22053 + };
22054 +
22055 + static int proc_tgid_base_readdir(struct file * filp,
22056 +@@ -2498,7 +2564,14 @@ static struct dentry *proc_pid_instantia
22057 + if (!inode)
22058 + goto out;
22059 +
22060 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22061 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
22062 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22063 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22064 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
22065 ++#else
22066 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
22067 ++#endif
22068 + inode->i_op = &proc_tgid_base_inode_operations;
22069 + inode->i_fop = &proc_tgid_base_operations;
22070 + inode->i_flags|=S_IMMUTABLE;
22071 +@@ -2540,7 +2613,11 @@ struct dentry *proc_pid_lookup(struct in
22072 + if (!task)
22073 + goto out;
22074 +
22075 ++ if (gr_check_hidden_task(task))
22076 ++ goto out_put_task;
22077 ++
22078 + result = proc_pid_instantiate(dir, dentry, task, NULL);
22079 ++out_put_task:
22080 + put_task_struct(task);
22081 + out:
22082 + return result;
22083 +@@ -2605,6 +2682,9 @@ int proc_pid_readdir(struct file * filp,
22084 + {
22085 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
22086 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
22087 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22088 ++ struct task_struct *tmp = current;
22089 ++#endif
22090 + struct tgid_iter iter;
22091 + struct pid_namespace *ns;
22092 +
22093 +@@ -2623,6 +2703,17 @@ int proc_pid_readdir(struct file * filp,
22094 + for (iter = next_tgid(ns, iter);
22095 + iter.task;
22096 + iter.tgid += 1, iter = next_tgid(ns, iter)) {
22097 ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
22098 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22099 ++ || (tmp->uid && (iter.task->uid != tmp->uid)
22100 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22101 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
22102 ++#endif
22103 ++ )
22104 ++#endif
22105 ++ )
22106 ++ continue;
22107 ++
22108 + filp->f_pos = iter.tgid + TGID_OFFSET;
22109 + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
22110 + put_task_struct(iter.task);
22111 +diff -urNp a/fs/proc/inode.c b/fs/proc/inode.c
22112 +--- a/fs/proc/inode.c 2008-08-20 11:16:13.000000000 -0700
22113 ++++ b/fs/proc/inode.c 2008-08-20 18:36:57.000000000 -0700
22114 +@@ -406,7 +406,11 @@ struct inode *proc_get_inode(struct supe
22115 + if (de->mode) {
22116 + inode->i_mode = de->mode;
22117 + inode->i_uid = de->uid;
22118 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22119 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22120 ++#else
22121 + inode->i_gid = de->gid;
22122 ++#endif
22123 + }
22124 + if (de->size)
22125 + inode->i_size = de->size;
22126 +diff -urNp a/fs/proc/internal.h b/fs/proc/internal.h
22127 +--- a/fs/proc/internal.h 2008-08-20 11:16:13.000000000 -0700
22128 ++++ b/fs/proc/internal.h 2008-08-20 18:36:57.000000000 -0700
22129 +@@ -57,6 +57,9 @@ extern int proc_pid_status(struct seq_fi
22130 + struct pid *pid, struct task_struct *task);
22131 + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
22132 + struct pid *pid, struct task_struct *task);
22133 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
22134 ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
22135 ++#endif
22136 + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
22137 +
22138 + extern const struct file_operations proc_maps_operations;
22139 +diff -urNp a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
22140 +--- a/fs/proc/proc_misc.c 2008-08-20 11:16:13.000000000 -0700
22141 ++++ b/fs/proc/proc_misc.c 2008-08-20 18:36:57.000000000 -0700
22142 +@@ -822,6 +822,8 @@ void create_seq_entry(char *name, mode_t
22143 +
22144 + void __init proc_misc_init(void)
22145 + {
22146 ++ int gr_mode = 0;
22147 ++
22148 + static struct {
22149 + char *name;
22150 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
22151 +@@ -837,13 +839,24 @@ void __init proc_misc_init(void)
22152 + {"stram", stram_read_proc},
22153 + #endif
22154 + {"filesystems", filesystems_read_proc},
22155 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
22156 + {"cmdline", cmdline_read_proc},
22157 ++#endif
22158 + {"execdomains", execdomains_read_proc},
22159 + {NULL,}
22160 + };
22161 + for (p = simple_ones; p->name; p++)
22162 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
22163 +
22164 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22165 ++ gr_mode = S_IRUSR;
22166 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22167 ++ gr_mode = S_IRUSR | S_IRGRP;
22168 ++#endif
22169 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22170 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
22171 ++#endif
22172 ++
22173 + proc_symlink("mounts", NULL, "self/mounts");
22174 +
22175 + /* And now for trickier ones */
22176 +@@ -856,7 +869,11 @@ void __init proc_misc_init(void)
22177 + }
22178 + #endif
22179 + create_seq_entry("locks", 0, &proc_locks_operations);
22180 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22181 ++ create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
22182 ++#else
22183 + create_seq_entry("devices", 0, &proc_devinfo_operations);
22184 ++#endif
22185 + create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
22186 + #ifdef CONFIG_BLOCK
22187 + create_seq_entry("partitions", 0, &proc_partitions_operations);
22188 +@@ -864,7 +881,11 @@ void __init proc_misc_init(void)
22189 + create_seq_entry("stat", 0, &proc_stat_operations);
22190 + create_seq_entry("interrupts", 0, &proc_interrupts_operations);
22191 + #ifdef CONFIG_SLABINFO
22192 ++#ifdef CONFIG_GRKRENSEC_PROC_ADD
22193 ++ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
22194 ++#else
22195 + create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
22196 ++#endif
22197 + #ifdef CONFIG_DEBUG_SLAB_LEAK
22198 + create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
22199 + #endif
22200 +@@ -882,7 +903,7 @@ void __init proc_misc_init(void)
22201 + #ifdef CONFIG_SCHEDSTATS
22202 + create_seq_entry("schedstat", 0, &proc_schedstat_operations);
22203 + #endif
22204 +-#ifdef CONFIG_PROC_KCORE
22205 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
22206 + proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
22207 + if (proc_root_kcore) {
22208 + proc_root_kcore->proc_fops = &proc_kcore_operations;
22209 +diff -urNp a/fs/proc/proc_net.c b/fs/proc/proc_net.c
22210 +--- a/fs/proc/proc_net.c 2008-08-20 11:16:13.000000000 -0700
22211 ++++ b/fs/proc/proc_net.c 2008-08-20 18:36:57.000000000 -0700
22212 +@@ -69,6 +69,14 @@ static struct net *get_proc_task_net(str
22213 + struct nsproxy *ns;
22214 + struct net *net = NULL;
22215 +
22216 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22217 ++ if (current->fsuid)
22218 ++ return net;
22219 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22220 ++ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
22221 ++ return net;
22222 ++#endif
22223 ++
22224 + rcu_read_lock();
22225 + task = pid_task(proc_pid(dir), PIDTYPE_PID);
22226 + if (task != NULL) {
22227 +diff -urNp a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
22228 +--- a/fs/proc/proc_sysctl.c 2008-08-20 11:16:13.000000000 -0700
22229 ++++ b/fs/proc/proc_sysctl.c 2008-08-20 18:36:57.000000000 -0700
22230 +@@ -7,6 +7,8 @@
22231 + #include <linux/security.h>
22232 + #include "internal.h"
22233 +
22234 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
22235 ++
22236 + static struct dentry_operations proc_sys_dentry_operations;
22237 + static const struct file_operations proc_sys_file_operations;
22238 + static const struct inode_operations proc_sys_inode_operations;
22239 +@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
22240 + if (!table)
22241 + goto out;
22242 +
22243 ++ if (gr_handle_sysctl(table, 001))
22244 ++ goto out;
22245 ++
22246 + err = ERR_PTR(-ENOMEM);
22247 + inode = proc_sys_make_inode(dir, table);
22248 + if (!inode)
22249 +@@ -360,6 +365,9 @@ static int proc_sys_readdir(struct file
22250 + if (pos < filp->f_pos)
22251 + continue;
22252 +
22253 ++ if (gr_handle_sysctl(table, 0))
22254 ++ continue;
22255 ++
22256 + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
22257 + goto out;
22258 + filp->f_pos = pos + 1;
22259 +@@ -422,6 +430,30 @@ out:
22260 + return error;
22261 + }
22262 +
22263 ++/* Eric Biederman is to blame */
22264 ++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
22265 ++{
22266 ++ int error = 0;
22267 ++ struct ctl_table_header *head;
22268 ++ struct ctl_table *table;
22269 ++
22270 ++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
22271 ++ /* Has the sysctl entry disappeared on us? */
22272 ++ if (!table)
22273 ++ goto out;
22274 ++
22275 ++ if (gr_handle_sysctl(table, 001)) {
22276 ++ error = -ENOENT;
22277 ++ goto out;
22278 ++ }
22279 ++
22280 ++out:
22281 ++ sysctl_head_finish(head);
22282 ++
22283 ++ generic_fillattr(dentry->d_inode, stat);
22284 ++
22285 ++ return error;
22286 ++}
22287 + static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
22288 + {
22289 + struct inode *inode = dentry->d_inode;
22290 +@@ -450,6 +482,7 @@ static const struct inode_operations pro
22291 + .lookup = proc_sys_lookup,
22292 + .permission = proc_sys_permission,
22293 + .setattr = proc_sys_setattr,
22294 ++ .getattr = proc_sys_getattr,
22295 + };
22296 +
22297 + static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
22298 +diff -urNp a/fs/proc/root.c b/fs/proc/root.c
22299 +--- a/fs/proc/root.c 2008-08-20 11:16:13.000000000 -0700
22300 ++++ b/fs/proc/root.c 2008-08-20 18:36:57.000000000 -0700
22301 +@@ -137,7 +137,15 @@ void __init proc_root_init(void)
22302 + #ifdef CONFIG_PROC_DEVICETREE
22303 + proc_device_tree_init();
22304 + #endif
22305 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22306 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22307 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
22308 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22309 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
22310 ++#endif
22311 ++#else
22312 + proc_bus = proc_mkdir("bus", NULL);
22313 ++#endif
22314 + proc_sys_init();
22315 + }
22316 +
22317 +diff -urNp a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
22318 +--- a/fs/proc/task_mmu.c 2008-08-20 11:16:13.000000000 -0700
22319 ++++ b/fs/proc/task_mmu.c 2008-08-20 18:36:57.000000000 -0700
22320 +@@ -48,15 +48,26 @@ void task_mem(struct seq_file *m, struct
22321 + "VmStk:\t%8lu kB\n"
22322 + "VmExe:\t%8lu kB\n"
22323 + "VmLib:\t%8lu kB\n"
22324 +- "VmPTE:\t%8lu kB\n",
22325 +- hiwater_vm << (PAGE_SHIFT-10),
22326 ++ "VmPTE:\t%8lu kB\n"
22327 ++
22328 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22329 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
22330 ++#endif
22331 ++
22332 ++ ,hiwater_vm << (PAGE_SHIFT-10),
22333 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
22334 + mm->locked_vm << (PAGE_SHIFT-10),
22335 + hiwater_rss << (PAGE_SHIFT-10),
22336 + total_rss << (PAGE_SHIFT-10),
22337 + data << (PAGE_SHIFT-10),
22338 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
22339 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
22340 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
22341 ++
22342 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22343 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
22344 ++#endif
22345 ++
22346 ++ );
22347 + }
22348 +
22349 + unsigned long task_vsize(struct mm_struct *mm)
22350 +@@ -234,6 +245,12 @@ static int do_maps_open(struct inode *in
22351 + return ret;
22352 + }
22353 +
22354 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22355 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
22356 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
22357 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
22358 ++#endif
22359 ++
22360 + static int show_map(struct seq_file *m, void *v)
22361 + {
22362 + struct proc_maps_private *priv = m->private;
22363 +@@ -256,13 +273,22 @@ static int show_map(struct seq_file *m,
22364 + }
22365 +
22366 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
22367 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22368 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
22369 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
22370 ++#else
22371 + vma->vm_start,
22372 + vma->vm_end,
22373 ++#endif
22374 + flags & VM_READ ? 'r' : '-',
22375 + flags & VM_WRITE ? 'w' : '-',
22376 + flags & VM_EXEC ? 'x' : '-',
22377 + flags & VM_MAYSHARE ? 's' : 'p',
22378 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22379 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
22380 ++#else
22381 + vma->vm_pgoff << PAGE_SHIFT,
22382 ++#endif
22383 + MAJOR(dev), MINOR(dev), ino, &len);
22384 +
22385 + /*
22386 +@@ -276,11 +302,11 @@ static int show_map(struct seq_file *m,
22387 + const char *name = arch_vma_name(vma);
22388 + if (!name) {
22389 + if (mm) {
22390 +- if (vma->vm_start <= mm->start_brk &&
22391 +- vma->vm_end >= mm->brk) {
22392 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
22393 + name = "[heap]";
22394 +- } else if (vma->vm_start <= mm->start_stack &&
22395 +- vma->vm_end >= mm->start_stack) {
22396 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
22397 ++ (vma->vm_start <= mm->start_stack &&
22398 ++ vma->vm_end >= mm->start_stack)) {
22399 + name = "[stack]";
22400 + }
22401 + } else {
22402 +@@ -404,10 +430,17 @@ static int show_smap(struct seq_file *m,
22403 + int ret;
22404 +
22405 + memset(&mss, 0, sizeof mss);
22406 +- mss.vma = vma;
22407 +- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
22408 +- walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end,
22409 +- &smaps_walk, &mss);
22410 ++
22411 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22412 ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
22413 ++#endif
22414 ++ mss.vma = vma;
22415 ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
22416 ++ walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end,
22417 ++ &smaps_walk, &mss);
22418 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22419 ++ }
22420 ++#endif
22421 +
22422 + ret = show_map(m, v);
22423 + if (ret)
22424 +@@ -422,7 +455,11 @@ static int show_smap(struct seq_file *m,
22425 + "Private_Clean: %8lu kB\n"
22426 + "Private_Dirty: %8lu kB\n"
22427 + "Referenced: %8lu kB\n",
22428 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22429 ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
22430 ++#else
22431 + (vma->vm_end - vma->vm_start) >> 10,
22432 ++#endif
22433 + mss.resident >> 10,
22434 + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
22435 + mss.shared_clean >> 10,
22436 +diff -urNp a/fs/readdir.c b/fs/readdir.c
22437 +--- a/fs/readdir.c 2008-08-20 11:16:13.000000000 -0700
22438 ++++ b/fs/readdir.c 2008-08-20 18:36:57.000000000 -0700
22439 +@@ -16,6 +16,8 @@
22440 + #include <linux/security.h>
22441 + #include <linux/syscalls.h>
22442 + #include <linux/unistd.h>
22443 ++#include <linux/namei.h>
22444 ++#include <linux/grsecurity.h>
22445 +
22446 + #include <asm/uaccess.h>
22447 +
22448 +@@ -67,6 +69,7 @@ struct old_linux_dirent {
22449 +
22450 + struct readdir_callback {
22451 + struct old_linux_dirent __user * dirent;
22452 ++ struct file * file;
22453 + int result;
22454 + };
22455 +
22456 +@@ -82,6 +85,10 @@ static int fillonedir(void * __buf, cons
22457 + d_ino = ino;
22458 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
22459 + return -EOVERFLOW;
22460 ++
22461 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22462 ++ return 0;
22463 ++
22464 + buf->result++;
22465 + dirent = buf->dirent;
22466 + if (!access_ok(VERIFY_WRITE, dirent,
22467 +@@ -113,6 +120,7 @@ asmlinkage long old_readdir(unsigned int
22468 +
22469 + buf.result = 0;
22470 + buf.dirent = dirent;
22471 ++ buf.file = file;
22472 +
22473 + error = vfs_readdir(file, fillonedir, &buf);
22474 + if (error >= 0)
22475 +@@ -139,6 +147,7 @@ struct linux_dirent {
22476 + struct getdents_callback {
22477 + struct linux_dirent __user * current_dir;
22478 + struct linux_dirent __user * previous;
22479 ++ struct file * file;
22480 + int count;
22481 + int error;
22482 + };
22483 +@@ -157,6 +166,10 @@ static int filldir(void * __buf, const c
22484 + d_ino = ino;
22485 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
22486 + return -EOVERFLOW;
22487 ++
22488 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22489 ++ return 0;
22490 ++
22491 + dirent = buf->previous;
22492 + if (dirent) {
22493 + if (__put_user(offset, &dirent->d_off))
22494 +@@ -203,6 +216,7 @@ asmlinkage long sys_getdents(unsigned in
22495 + buf.previous = NULL;
22496 + buf.count = count;
22497 + buf.error = 0;
22498 ++ buf.file = file;
22499 +
22500 + error = vfs_readdir(file, filldir, &buf);
22501 + if (error < 0)
22502 +@@ -225,6 +239,7 @@ out:
22503 + struct getdents_callback64 {
22504 + struct linux_dirent64 __user * current_dir;
22505 + struct linux_dirent64 __user * previous;
22506 ++ struct file *file;
22507 + int count;
22508 + int error;
22509 + };
22510 +@@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
22511 + buf->error = -EINVAL; /* only used if we fail.. */
22512 + if (reclen > buf->count)
22513 + return -EINVAL;
22514 ++
22515 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22516 ++ return 0;
22517 ++
22518 + dirent = buf->previous;
22519 + if (dirent) {
22520 + if (__put_user(offset, &dirent->d_off))
22521 +@@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
22522 +
22523 + buf.current_dir = dirent;
22524 + buf.previous = NULL;
22525 ++ buf.file = file;
22526 + buf.count = count;
22527 + buf.error = 0;
22528 +
22529 +diff -urNp a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
22530 +--- a/fs/smbfs/symlink.c 2008-08-20 11:16:13.000000000 -0700
22531 ++++ b/fs/smbfs/symlink.c 2008-08-20 18:36:57.000000000 -0700
22532 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
22533 +
22534 + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
22535 + {
22536 +- char *s = nd_get_link(nd);
22537 ++ const char *s = nd_get_link(nd);
22538 + if (!IS_ERR(s))
22539 + __putname(s);
22540 + }
22541 +diff -urNp a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
22542 +--- a/fs/sysfs/symlink.c 2008-08-20 11:16:13.000000000 -0700
22543 ++++ b/fs/sysfs/symlink.c 2008-08-20 18:36:57.000000000 -0700
22544 +@@ -168,7 +168,7 @@ static void *sysfs_follow_link(struct de
22545 +
22546 + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
22547 + {
22548 +- char *page = nd_get_link(nd);
22549 ++ const char *page = nd_get_link(nd);
22550 + if (!IS_ERR(page))
22551 + free_page((unsigned long)page);
22552 + }
22553 +diff -urNp a/fs/udf/balloc.c b/fs/udf/balloc.c
22554 +--- a/fs/udf/balloc.c 2008-08-20 11:16:13.000000000 -0700
22555 ++++ b/fs/udf/balloc.c 2008-08-20 18:36:57.000000000 -0700
22556 +@@ -170,9 +170,7 @@ static void udf_bitmap_free_blocks(struc
22557 + unsigned long overflow;
22558 +
22559 + mutex_lock(&sbi->s_alloc_mutex);
22560 +- if (bloc.logicalBlockNum < 0 ||
22561 +- (bloc.logicalBlockNum + count) >
22562 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22563 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22564 + udf_debug("%d < %d || %d + %d > %d\n",
22565 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
22566 + sbi->s_partmaps[bloc.partitionReferenceNum].
22567 +@@ -240,7 +238,7 @@ static int udf_bitmap_prealloc_blocks(st
22568 +
22569 + mutex_lock(&sbi->s_alloc_mutex);
22570 + part_len = sbi->s_partmaps[partition].s_partition_len;
22571 +- if (first_block < 0 || first_block >= part_len)
22572 ++ if (first_block >= part_len)
22573 + goto out;
22574 +
22575 + if (first_block + block_count > part_len)
22576 +@@ -301,7 +299,7 @@ static int udf_bitmap_new_block(struct s
22577 + mutex_lock(&sbi->s_alloc_mutex);
22578 +
22579 + repeat:
22580 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
22581 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
22582 + goal = 0;
22583 +
22584 + nr_groups = bitmap->s_nr_groups;
22585 +@@ -439,9 +437,7 @@ static void udf_table_free_blocks(struct
22586 + struct udf_inode_info *iinfo;
22587 +
22588 + mutex_lock(&sbi->s_alloc_mutex);
22589 +- if (bloc.logicalBlockNum < 0 ||
22590 +- (bloc.logicalBlockNum + count) >
22591 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22592 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22593 + udf_debug("%d < %d || %d + %d > %d\n",
22594 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
22595 + sbi->s_partmaps[bloc.partitionReferenceNum].
22596 +@@ -676,8 +672,7 @@ static int udf_table_prealloc_blocks(str
22597 + int8_t etype = -1;
22598 + struct udf_inode_info *iinfo;
22599 +
22600 +- if (first_block < 0 ||
22601 +- first_block >= sbi->s_partmaps[partition].s_partition_len)
22602 ++ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
22603 + return 0;
22604 +
22605 + iinfo = UDF_I(table);
22606 +@@ -755,7 +750,7 @@ static int udf_table_new_block(struct su
22607 + return newblock;
22608 +
22609 + mutex_lock(&sbi->s_alloc_mutex);
22610 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
22611 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
22612 + goal = 0;
22613 +
22614 + /* We search for the closest matching block to goal. If we find
22615 +diff -urNp a/fs/udf/inode.c b/fs/udf/inode.c
22616 +--- a/fs/udf/inode.c 2008-08-20 11:16:13.000000000 -0700
22617 ++++ b/fs/udf/inode.c 2008-08-20 18:36:57.000000000 -0700
22618 +@@ -323,9 +323,6 @@ static int udf_get_block(struct inode *i
22619 +
22620 + lock_kernel();
22621 +
22622 +- if (block < 0)
22623 +- goto abort_negative;
22624 +-
22625 + iinfo = UDF_I(inode);
22626 + if (block == iinfo->i_next_alloc_block + 1) {
22627 + iinfo->i_next_alloc_block++;
22628 +@@ -347,10 +344,6 @@ static int udf_get_block(struct inode *i
22629 + abort:
22630 + unlock_kernel();
22631 + return err;
22632 +-
22633 +-abort_negative:
22634 +- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
22635 +- goto abort;
22636 + }
22637 +
22638 + static struct buffer_head *udf_getblk(struct inode *inode, long block,
22639 +diff -urNp a/fs/ufs/inode.c b/fs/ufs/inode.c
22640 +--- a/fs/ufs/inode.c 2008-08-20 11:16:13.000000000 -0700
22641 ++++ b/fs/ufs/inode.c 2008-08-20 18:36:57.000000000 -0700
22642 +@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
22643 +
22644 +
22645 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
22646 +- if (i_block < 0) {
22647 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
22648 +- } else if (i_block < direct_blocks) {
22649 ++ if (i_block < direct_blocks) {
22650 + offsets[n++] = i_block;
22651 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
22652 + offsets[n++] = UFS_IND_BLOCK;
22653 +@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
22654 + lock_kernel();
22655 +
22656 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
22657 +- if (fragment < 0)
22658 +- goto abort_negative;
22659 + if (fragment >
22660 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
22661 + << uspi->s_fpbshift))
22662 +@@ -504,10 +500,6 @@ abort:
22663 + unlock_kernel();
22664 + return err;
22665 +
22666 +-abort_negative:
22667 +- ufs_warning(sb, "ufs_get_block", "block < 0");
22668 +- goto abort;
22669 +-
22670 + abort_too_big:
22671 + ufs_warning(sb, "ufs_get_block", "block > big");
22672 + goto abort;
22673 +diff -urNp a/fs/utimes.c b/fs/utimes.c
22674 +--- a/fs/utimes.c 2008-08-20 11:16:13.000000000 -0700
22675 ++++ b/fs/utimes.c 2008-08-20 18:36:57.000000000 -0700
22676 +@@ -7,6 +7,7 @@
22677 + #include <linux/stat.h>
22678 + #include <linux/utime.h>
22679 + #include <linux/syscalls.h>
22680 ++#include <linux/grsecurity.h>
22681 + #include <asm/uaccess.h>
22682 + #include <asm/unistd.h>
22683 +
22684 +@@ -61,6 +62,7 @@ long do_utimes(int dfd, char __user *fil
22685 + int error;
22686 + struct nameidata nd;
22687 + struct dentry *dentry;
22688 ++ struct vfsmount *mnt;
22689 + struct inode *inode;
22690 + struct iattr newattrs;
22691 + struct file *f = NULL;
22692 +@@ -84,12 +86,14 @@ long do_utimes(int dfd, char __user *fil
22693 + if (!f)
22694 + goto out;
22695 + dentry = f->f_path.dentry;
22696 ++ mnt = f->f_path.mnt;
22697 + } else {
22698 + error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
22699 + if (error)
22700 + goto out;
22701 +
22702 + dentry = nd.path.dentry;
22703 ++ mnt = nd.path.mnt;
22704 + }
22705 +
22706 + inode = dentry->d_inode;
22707 +@@ -144,6 +148,12 @@ long do_utimes(int dfd, char __user *fil
22708 + }
22709 + }
22710 + }
22711 ++
22712 ++ if (!gr_acl_handle_utime(dentry, mnt)) {
22713 ++ error = -EACCES;
22714 ++ goto dput_and_out;
22715 ++ }
22716 ++
22717 + mutex_lock(&inode->i_mutex);
22718 + error = notify_change(dentry, &newattrs);
22719 + mutex_unlock(&inode->i_mutex);
22720 +diff -urNp a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
22721 +--- a/fs/xfs/linux-2.6/xfs_iops.c 2008-08-20 11:16:13.000000000 -0700
22722 ++++ b/fs/xfs/linux-2.6/xfs_iops.c 2008-08-20 18:36:57.000000000 -0700
22723 +@@ -547,7 +547,7 @@ xfs_vn_put_link(
22724 + struct nameidata *nd,
22725 + void *p)
22726 + {
22727 +- char *s = nd_get_link(nd);
22728 ++ const char *s = nd_get_link(nd);
22729 +
22730 + if (!IS_ERR(s))
22731 + kfree(s);
22732 +diff -urNp a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
22733 +--- a/fs/xfs/xfs_bmap.c 2008-08-20 11:16:13.000000000 -0700
22734 ++++ b/fs/xfs/xfs_bmap.c 2008-08-20 18:36:57.000000000 -0700
22735 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
22736 + int nmap,
22737 + int ret_nmap);
22738 + #else
22739 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
22740 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
22741 + #endif /* DEBUG */
22742 +
22743 + #if defined(XFS_RW_TRACE)
22744 +diff -urNp a/grsecurity/Kconfig b/grsecurity/Kconfig
22745 +--- a/grsecurity/Kconfig 1969-12-31 16:00:00.000000000 -0800
22746 ++++ b/grsecurity/Kconfig 2008-08-20 18:36:57.000000000 -0700
22747 +@@ -0,0 +1,861 @@
22748 ++#
22749 ++# grecurity configuration
22750 ++#
22751 ++
22752 ++menu "Grsecurity"
22753 ++
22754 ++config GRKERNSEC
22755 ++ bool "Grsecurity"
22756 ++ select CRYPTO
22757 ++ select CRYPTO_SHA256
22758 ++ select SECURITY
22759 ++ select SECURITY_CAPABILITIES
22760 ++ help
22761 ++ If you say Y here, you will be able to configure many features
22762 ++ that will enhance the security of your system. It is highly
22763 ++ recommended that you say Y here and read through the help
22764 ++ for each option so that you fully understand the features and
22765 ++ can evaluate their usefulness for your machine.
22766 ++
22767 ++choice
22768 ++ prompt "Security Level"
22769 ++ depends on GRKERNSEC
22770 ++ default GRKERNSEC_CUSTOM
22771 ++
22772 ++config GRKERNSEC_LOW
22773 ++ bool "Low"
22774 ++ select GRKERNSEC_LINK
22775 ++ select GRKERNSEC_FIFO
22776 ++ select GRKERNSEC_EXECVE
22777 ++ select GRKERNSEC_RANDNET
22778 ++ select GRKERNSEC_DMESG
22779 ++ select GRKERNSEC_CHROOT_CHDIR
22780 ++ select GRKERNSEC_MODSTOP if (MODULES)
22781 ++
22782 ++ help
22783 ++ If you choose this option, several of the grsecurity options will
22784 ++ be enabled that will give you greater protection against a number
22785 ++ of attacks, while assuring that none of your software will have any
22786 ++ conflicts with the additional security measures. If you run a lot
22787 ++ of unusual software, or you are having problems with the higher
22788 ++ security levels, you should say Y here. With this option, the
22789 ++ following features are enabled:
22790 ++
22791 ++ - Linking restrictions
22792 ++ - FIFO restrictions
22793 ++ - Enforcing RLIMIT_NPROC on execve
22794 ++ - Restricted dmesg
22795 ++ - Enforced chdir("/") on chroot
22796 ++ - Runtime module disabling
22797 ++
22798 ++config GRKERNSEC_MEDIUM
22799 ++ bool "Medium"
22800 ++ select PAX
22801 ++ select PAX_EI_PAX
22802 ++ select PAX_PT_PAX_FLAGS
22803 ++ select PAX_HAVE_ACL_FLAGS
22804 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22805 ++ select GRKERNSEC_CHROOT_SYSCTL
22806 ++ select GRKERNSEC_LINK
22807 ++ select GRKERNSEC_FIFO
22808 ++ select GRKERNSEC_EXECVE
22809 ++ select GRKERNSEC_DMESG
22810 ++ select GRKERNSEC_RANDNET
22811 ++ select GRKERNSEC_FORKFAIL
22812 ++ select GRKERNSEC_TIME
22813 ++ select GRKERNSEC_SIGNAL
22814 ++ select GRKERNSEC_CHROOT
22815 ++ select GRKERNSEC_CHROOT_UNIX
22816 ++ select GRKERNSEC_CHROOT_MOUNT
22817 ++ select GRKERNSEC_CHROOT_PIVOT
22818 ++ select GRKERNSEC_CHROOT_DOUBLE
22819 ++ select GRKERNSEC_CHROOT_CHDIR
22820 ++ select GRKERNSEC_CHROOT_MKNOD
22821 ++ select GRKERNSEC_PROC
22822 ++ select GRKERNSEC_PROC_USERGROUP
22823 ++ select GRKERNSEC_MODSTOP if (MODULES)
22824 ++ select PAX_RANDUSTACK
22825 ++ select PAX_ASLR
22826 ++ select PAX_RANDMMAP
22827 ++
22828 ++ help
22829 ++ If you say Y here, several features in addition to those included
22830 ++ in the low additional security level will be enabled. These
22831 ++ features provide even more security to your system, though in rare
22832 ++ cases they may be incompatible with very old or poorly written
22833 ++ software. If you enable this option, make sure that your auth
22834 ++ service (identd) is running as gid 1001. With this option,
22835 ++ the following features (in addition to those provided in the
22836 ++ low additional security level) will be enabled:
22837 ++
22838 ++ - Failed fork logging
22839 ++ - Time change logging
22840 ++ - Signal logging
22841 ++ - Deny mounts in chroot
22842 ++ - Deny double chrooting
22843 ++ - Deny sysctl writes in chroot
22844 ++ - Deny mknod in chroot
22845 ++ - Deny access to abstract AF_UNIX sockets out of chroot
22846 ++ - Deny pivot_root in chroot
22847 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
22848 ++ - /proc restrictions with special GID set to 10 (usually wheel)
22849 ++ - Address Space Layout Randomization (ASLR)
22850 ++
22851 ++config GRKERNSEC_HIGH
22852 ++ bool "High"
22853 ++ select GRKERNSEC_LINK
22854 ++ select GRKERNSEC_FIFO
22855 ++ select GRKERNSEC_EXECVE
22856 ++ select GRKERNSEC_DMESG
22857 ++ select GRKERNSEC_FORKFAIL
22858 ++ select GRKERNSEC_TIME
22859 ++ select GRKERNSEC_SIGNAL
22860 ++ select GRKERNSEC_CHROOT_SHMAT
22861 ++ select GRKERNSEC_CHROOT_UNIX
22862 ++ select GRKERNSEC_CHROOT_MOUNT
22863 ++ select GRKERNSEC_CHROOT_FCHDIR
22864 ++ select GRKERNSEC_CHROOT_PIVOT
22865 ++ select GRKERNSEC_CHROOT_DOUBLE
22866 ++ select GRKERNSEC_CHROOT_CHDIR
22867 ++ select GRKERNSEC_CHROOT_MKNOD
22868 ++ select GRKERNSEC_CHROOT_CAPS
22869 ++ select GRKERNSEC_CHROOT_SYSCTL
22870 ++ select GRKERNSEC_CHROOT_FINDTASK
22871 ++ select GRKERNSEC_PROC
22872 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22873 ++ select GRKERNSEC_HIDESYM
22874 ++ select GRKERNSEC_BRUTE
22875 ++ select GRKERNSEC_PROC_USERGROUP
22876 ++ select GRKERNSEC_KMEM
22877 ++ select GRKERNSEC_RESLOG
22878 ++ select GRKERNSEC_RANDNET
22879 ++ select GRKERNSEC_PROC_ADD
22880 ++ select GRKERNSEC_CHROOT_CHMOD
22881 ++ select GRKERNSEC_CHROOT_NICE
22882 ++ select GRKERNSEC_AUDIT_MOUNT
22883 ++ select GRKERNSEC_MODSTOP if (MODULES)
22884 ++ select PAX
22885 ++ select PAX_RANDUSTACK
22886 ++ select PAX_ASLR
22887 ++ select PAX_RANDMMAP
22888 ++ select PAX_NOEXEC
22889 ++ select PAX_MPROTECT
22890 ++ select PAX_EI_PAX
22891 ++ select PAX_PT_PAX_FLAGS
22892 ++ select PAX_HAVE_ACL_FLAGS
22893 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
22894 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
22895 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
22896 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
22897 ++ select PAX_PAGEEXEC if (!X86)
22898 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
22899 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
22900 ++ select PAX_SYSCALL if (PPC32)
22901 ++ select PAX_EMUTRAMP if (PARISC)
22902 ++ select PAX_EMUSIGRT if (PARISC)
22903 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
22904 ++ help
22905 ++ If you say Y here, many of the features of grsecurity will be
22906 ++ enabled, which will protect you against many kinds of attacks
22907 ++ against your system. The heightened security comes at a cost
22908 ++ of an increased chance of incompatibilities with rare software
22909 ++ on your machine. Since this security level enables PaX, you should
22910 ++ view <http://pax.grsecurity.net> and read about the PaX
22911 ++ project. While you are there, download chpax and run it on
22912 ++ binaries that cause problems with PaX. Also remember that
22913 ++ since the /proc restrictions are enabled, you must run your
22914 ++ identd as gid 1001. This security level enables the following
22915 ++ features in addition to those listed in the low and medium
22916 ++ security levels:
22917 ++
22918 ++ - Additional /proc restrictions
22919 ++ - Chmod restrictions in chroot
22920 ++ - No signals, ptrace, or viewing of processes outside of chroot
22921 ++ - Capability restrictions in chroot
22922 ++ - Deny fchdir out of chroot
22923 ++ - Priority restrictions in chroot
22924 ++ - Segmentation-based implementation of PaX
22925 ++ - Mprotect restrictions
22926 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
22927 ++ - Kernel stack randomization
22928 ++ - Mount/unmount/remount logging
22929 ++ - Kernel symbol hiding
22930 ++ - Prevention of memory exhaustion-based exploits
22931 ++config GRKERNSEC_CUSTOM
22932 ++ bool "Custom"
22933 ++ help
22934 ++ If you say Y here, you will be able to configure every grsecurity
22935 ++ option, which allows you to enable many more features that aren't
22936 ++ covered in the basic security levels. These additional features
22937 ++ include TPE, socket restrictions, and the sysctl system for
22938 ++ grsecurity. It is advised that you read through the help for
22939 ++ each option to determine its usefulness in your situation.
22940 ++
22941 ++endchoice
22942 ++
22943 ++menu "Address Space Protection"
22944 ++depends on GRKERNSEC
22945 ++
22946 ++config GRKERNSEC_KMEM
22947 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
22948 ++ help
22949 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
22950 ++ be written to via mmap or otherwise to modify the running kernel.
22951 ++ /dev/port will also not be allowed to be opened. If you have module
22952 ++ support disabled, enabling this will close up four ways that are
22953 ++ currently used to insert malicious code into the running kernel.
22954 ++ Even with all these features enabled, we still highly recommend that
22955 ++ you use the RBAC system, as it is still possible for an attacker to
22956 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
22957 ++ If you are not using XFree86, you may be able to stop this additional
22958 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
22959 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
22960 ++ but only to video memory, which is the only writing we allow in this
22961 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
22962 ++ not be allowed to mprotect it with PROT_WRITE later.
22963 ++ It is highly recommended that you say Y here if you meet all the
22964 ++ conditions above.
22965 ++
22966 ++config GRKERNSEC_IO
22967 ++ bool "Disable privileged I/O"
22968 ++ depends on X86
22969 ++ select RTC
22970 ++ help
22971 ++ If you say Y here, all ioperm and iopl calls will return an error.
22972 ++ Ioperm and iopl can be used to modify the running kernel.
22973 ++ Unfortunately, some programs need this access to operate properly,
22974 ++ the most notable of which are XFree86 and hwclock. hwclock can be
22975 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
22976 ++ enabled if this option is enabled, to ensure that hwclock operates
22977 ++ correctly. XFree86 still will not operate correctly with this option
22978 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
22979 ++ and you still want to protect your kernel against modification,
22980 ++ use the RBAC system.
22981 ++
22982 ++config GRKERNSEC_PROC_MEMMAP
22983 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
22984 ++ depends on PAX_NOEXEC || PAX_ASLR
22985 ++ help
22986 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
22987 ++ give no information about the addresses of its mappings if
22988 ++ PaX features that rely on random addresses are enabled on the task.
22989 ++ If you use PaX it is greatly recommended that you say Y here as it
22990 ++ closes up a hole that makes the full ASLR useless for suid
22991 ++ binaries.
22992 ++
22993 ++config GRKERNSEC_BRUTE
22994 ++ bool "Deter exploit bruteforcing"
22995 ++ help
22996 ++ If you say Y here, attempts to bruteforce exploits against forking
22997 ++ daemons such as apache or sshd will be deterred. When a child of a
22998 ++ forking daemon is killed by PaX or crashes due to an illegal
22999 ++ instruction, the parent process will be delayed 30 seconds upon every
23000 ++ subsequent fork until the administrator is able to assess the
23001 ++ situation and restart the daemon. It is recommended that you also
23002 ++ enable signal logging in the auditing section so that logs are
23003 ++ generated when a process performs an illegal instruction.
23004 ++
23005 ++config GRKERNSEC_MODSTOP
23006 ++ bool "Runtime module disabling"
23007 ++ depends on MODULES
23008 ++ help
23009 ++ If you say Y here, you will be able to disable the ability to (un)load
23010 ++ modules at runtime. This feature is useful if you need the ability
23011 ++ to load kernel modules at boot time, but do not want to allow an
23012 ++ attacker to load a rootkit kernel module into the system, or to remove
23013 ++ a loaded kernel module important to system functioning. You should
23014 ++ enable the /dev/mem protection feature as well, since rootkits can be
23015 ++ inserted into the kernel via other methods than kernel modules. Since
23016 ++ an untrusted module could still be loaded by modifying init scripts and
23017 ++ rebooting the system, it is also recommended that you enable the RBAC
23018 ++ system. If you enable this option, a sysctl option with name
23019 ++ "disable_modules" will be created. Setting this option to "1" disables
23020 ++ module loading. After this option is set, no further writes to it are
23021 ++ allowed until the system is rebooted.
23022 ++
23023 ++config GRKERNSEC_HIDESYM
23024 ++ bool "Hide kernel symbols"
23025 ++ help
23026 ++ If you say Y here, getting information on loaded modules, and
23027 ++ displaying all kernel symbols through a syscall will be restricted
23028 ++ to users with CAP_SYS_MODULE. This option is only effective
23029 ++ provided the following conditions are met:
23030 ++ 1) The kernel using grsecurity is not precompiled by some distribution
23031 ++ 2) You are using the RBAC system and hiding other files such as your
23032 ++ kernel image and System.map
23033 ++ 3) You have the additional /proc restrictions enabled, which removes
23034 ++ /proc/kcore
23035 ++ If the above conditions are met, this option will aid to provide a
23036 ++ useful protection against local and remote kernel exploitation of
23037 ++ overflows and arbitrary read/write vulnerabilities.
23038 ++
23039 ++endmenu
23040 ++menu "Role Based Access Control Options"
23041 ++depends on GRKERNSEC
23042 ++
23043 ++config GRKERNSEC_ACL_HIDEKERN
23044 ++ bool "Hide kernel processes"
23045 ++ help
23046 ++ If you say Y here, all kernel threads will be hidden to all
23047 ++ processes but those whose subject has the "view hidden processes"
23048 ++ flag.
23049 ++
23050 ++config GRKERNSEC_ACL_MAXTRIES
23051 ++ int "Maximum tries before password lockout"
23052 ++ default 3
23053 ++ help
23054 ++ This option enforces the maximum number of times a user can attempt
23055 ++ to authorize themselves with the grsecurity RBAC system before being
23056 ++ denied the ability to attempt authorization again for a specified time.
23057 ++ The lower the number, the harder it will be to brute-force a password.
23058 ++
23059 ++config GRKERNSEC_ACL_TIMEOUT
23060 ++ int "Time to wait after max password tries, in seconds"
23061 ++ default 30
23062 ++ help
23063 ++ This option specifies the time the user must wait after attempting to
23064 ++ authorize to the RBAC system with the maximum number of invalid
23065 ++ passwords. The higher the number, the harder it will be to brute-force
23066 ++ a password.
23067 ++
23068 ++endmenu
23069 ++menu "Filesystem Protections"
23070 ++depends on GRKERNSEC
23071 ++
23072 ++config GRKERNSEC_PROC
23073 ++ bool "Proc restrictions"
23074 ++ help
23075 ++ If you say Y here, the permissions of the /proc filesystem
23076 ++ will be altered to enhance system security and privacy. You MUST
23077 ++ choose either a user only restriction or a user and group restriction.
23078 ++ Depending upon the option you choose, you can either restrict users to
23079 ++ see only the processes they themselves run, or choose a group that can
23080 ++ view all processes and files normally restricted to root if you choose
23081 ++ the "restrict to user only" option. NOTE: If you're running identd as
23082 ++ a non-root user, you will have to run it as the group you specify here.
23083 ++
23084 ++config GRKERNSEC_PROC_USER
23085 ++ bool "Restrict /proc to user only"
23086 ++ depends on GRKERNSEC_PROC
23087 ++ help
23088 ++ If you say Y here, non-root users will only be able to view their own
23089 ++ processes, and restricts them from viewing network-related information,
23090 ++ and viewing kernel symbol and module information.
23091 ++
23092 ++config GRKERNSEC_PROC_USERGROUP
23093 ++ bool "Allow special group"
23094 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
23095 ++ help
23096 ++ If you say Y here, you will be able to select a group that will be
23097 ++ able to view all processes, network-related information, and
23098 ++ kernel and symbol information. This option is useful if you want
23099 ++ to run identd as a non-root user.
23100 ++
23101 ++config GRKERNSEC_PROC_GID
23102 ++ int "GID for special group"
23103 ++ depends on GRKERNSEC_PROC_USERGROUP
23104 ++ default 1001
23105 ++
23106 ++config GRKERNSEC_PROC_ADD
23107 ++ bool "Additional restrictions"
23108 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
23109 ++ help
23110 ++ If you say Y here, additional restrictions will be placed on
23111 ++ /proc that keep normal users from viewing device information and
23112 ++ slabinfo information that could be useful for exploits.
23113 ++
23114 ++config GRKERNSEC_LINK
23115 ++ bool "Linking restrictions"
23116 ++ help
23117 ++ If you say Y here, /tmp race exploits will be prevented, since users
23118 ++ will no longer be able to follow symlinks owned by other users in
23119 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
23120 ++ symlink is the owner of the directory. users will also not be
23121 ++ able to hardlink to files they do not own. If the sysctl option is
23122 ++ enabled, a sysctl option with name "linking_restrictions" is created.
23123 ++
23124 ++config GRKERNSEC_FIFO
23125 ++ bool "FIFO restrictions"
23126 ++ help
23127 ++ If you say Y here, users will not be able to write to FIFOs they don't
23128 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
23129 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
23130 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
23131 ++ created.
23132 ++
23133 ++config GRKERNSEC_CHROOT
23134 ++ bool "Chroot jail restrictions"
23135 ++ help
23136 ++ If you say Y here, you will be able to choose several options that will
23137 ++ make breaking out of a chrooted jail much more difficult. If you
23138 ++ encounter no software incompatibilities with the following options, it
23139 ++ is recommended that you enable each one.
23140 ++
23141 ++config GRKERNSEC_CHROOT_MOUNT
23142 ++ bool "Deny mounts"
23143 ++ depends on GRKERNSEC_CHROOT
23144 ++ help
23145 ++ If you say Y here, processes inside a chroot will not be able to
23146 ++ mount or remount filesystems. If the sysctl option is enabled, a
23147 ++ sysctl option with name "chroot_deny_mount" is created.
23148 ++
23149 ++config GRKERNSEC_CHROOT_DOUBLE
23150 ++ bool "Deny double-chroots"
23151 ++ depends on GRKERNSEC_CHROOT
23152 ++ help
23153 ++ If you say Y here, processes inside a chroot will not be able to chroot
23154 ++ again outside the chroot. This is a widely used method of breaking
23155 ++ out of a chroot jail and should not be allowed. If the sysctl
23156 ++ option is enabled, a sysctl option with name
23157 ++ "chroot_deny_chroot" is created.
23158 ++
23159 ++config GRKERNSEC_CHROOT_PIVOT
23160 ++ bool "Deny pivot_root in chroot"
23161 ++ depends on GRKERNSEC_CHROOT
23162 ++ help
23163 ++ If you say Y here, processes inside a chroot will not be able to use
23164 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
23165 ++ works similar to chroot in that it changes the root filesystem. This
23166 ++ function could be misused in a chrooted process to attempt to break out
23167 ++ of the chroot, and therefore should not be allowed. If the sysctl
23168 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
23169 ++ created.
23170 ++
23171 ++config GRKERNSEC_CHROOT_CHDIR
23172 ++ bool "Enforce chdir(\"/\") on all chroots"
23173 ++ depends on GRKERNSEC_CHROOT
23174 ++ help
23175 ++ If you say Y here, the current working directory of all newly-chrooted
23176 ++ applications will be set to the the root directory of the chroot.
23177 ++ The man page on chroot(2) states:
23178 ++ Note that this call does not change the current working
23179 ++ directory, so that `.' can be outside the tree rooted at
23180 ++ `/'. In particular, the super-user can escape from a
23181 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
23182 ++
23183 ++ It is recommended that you say Y here, since it's not known to break
23184 ++ any software. If the sysctl option is enabled, a sysctl option with
23185 ++ name "chroot_enforce_chdir" is created.
23186 ++
23187 ++config GRKERNSEC_CHROOT_CHMOD
23188 ++ bool "Deny (f)chmod +s"
23189 ++ depends on GRKERNSEC_CHROOT
23190 ++ help
23191 ++ If you say Y here, processes inside a chroot will not be able to chmod
23192 ++ or fchmod files to make them have suid or sgid bits. This protects
23193 ++ against another published method of breaking a chroot. If the sysctl
23194 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
23195 ++ created.
23196 ++
23197 ++config GRKERNSEC_CHROOT_FCHDIR
23198 ++ bool "Deny fchdir out of chroot"
23199 ++ depends on GRKERNSEC_CHROOT
23200 ++ help
23201 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
23202 ++ to a file descriptor of the chrooting process that points to a directory
23203 ++ outside the filesystem will be stopped. If the sysctl option
23204 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
23205 ++
23206 ++config GRKERNSEC_CHROOT_MKNOD
23207 ++ bool "Deny mknod"
23208 ++ depends on GRKERNSEC_CHROOT
23209 ++ help
23210 ++ If you say Y here, processes inside a chroot will not be allowed to
23211 ++ mknod. The problem with using mknod inside a chroot is that it
23212 ++ would allow an attacker to create a device entry that is the same
23213 ++ as one on the physical root of your system, which could range from
23214 ++ anything from the console device to a device for your harddrive (which
23215 ++ they could then use to wipe the drive or steal data). It is recommended
23216 ++ that you say Y here, unless you run into software incompatibilities.
23217 ++ If the sysctl option is enabled, a sysctl option with name
23218 ++ "chroot_deny_mknod" is created.
23219 ++
23220 ++config GRKERNSEC_CHROOT_SHMAT
23221 ++ bool "Deny shmat() out of chroot"
23222 ++ depends on GRKERNSEC_CHROOT
23223 ++ help
23224 ++ If you say Y here, processes inside a chroot will not be able to attach
23225 ++ to shared memory segments that were created outside of the chroot jail.
23226 ++ It is recommended that you say Y here. If the sysctl option is enabled,
23227 ++ a sysctl option with name "chroot_deny_shmat" is created.
23228 ++
23229 ++config GRKERNSEC_CHROOT_UNIX
23230 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
23231 ++ depends on GRKERNSEC_CHROOT
23232 ++ help
23233 ++ If you say Y here, processes inside a chroot will not be able to
23234 ++ connect to abstract (meaning not belonging to a filesystem) Unix
23235 ++ domain sockets that were bound outside of a chroot. It is recommended
23236 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
23237 ++ with name "chroot_deny_unix" is created.
23238 ++
23239 ++config GRKERNSEC_CHROOT_FINDTASK
23240 ++ bool "Protect outside processes"
23241 ++ depends on GRKERNSEC_CHROOT
23242 ++ help
23243 ++ If you say Y here, processes inside a chroot will not be able to
23244 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
23245 ++ or view any process outside of the chroot. If the sysctl
23246 ++ option is enabled, a sysctl option with name "chroot_findtask" is
23247 ++ created.
23248 ++
23249 ++config GRKERNSEC_CHROOT_NICE
23250 ++ bool "Restrict priority changes"
23251 ++ depends on GRKERNSEC_CHROOT
23252 ++ help
23253 ++ If you say Y here, processes inside a chroot will not be able to raise
23254 ++ the priority of processes in the chroot, or alter the priority of
23255 ++ processes outside the chroot. This provides more security than simply
23256 ++ removing CAP_SYS_NICE from the process' capability set. If the
23257 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
23258 ++ is created.
23259 ++
23260 ++config GRKERNSEC_CHROOT_SYSCTL
23261 ++ bool "Deny sysctl writes"
23262 ++ depends on GRKERNSEC_CHROOT
23263 ++ help
23264 ++ If you say Y here, an attacker in a chroot will not be able to
23265 ++ write to sysctl entries, either by sysctl(2) or through a /proc
23266 ++ interface. It is strongly recommended that you say Y here. If the
23267 ++ sysctl option is enabled, a sysctl option with name
23268 ++ "chroot_deny_sysctl" is created.
23269 ++
23270 ++config GRKERNSEC_CHROOT_CAPS
23271 ++ bool "Capability restrictions"
23272 ++ depends on GRKERNSEC_CHROOT
23273 ++ help
23274 ++ If you say Y here, the capabilities on all root processes within a
23275 ++ chroot jail will be lowered to stop module insertion, raw i/o,
23276 ++ system and net admin tasks, rebooting the system, modifying immutable
23277 ++ files, modifying IPC owned by another, and changing the system time.
23278 ++ This is left an option because it can break some apps. Disable this
23279 ++ if your chrooted apps are having problems performing those kinds of
23280 ++ tasks. If the sysctl option is enabled, a sysctl option with
23281 ++ name "chroot_caps" is created.
23282 ++
23283 ++endmenu
23284 ++menu "Kernel Auditing"
23285 ++depends on GRKERNSEC
23286 ++
23287 ++config GRKERNSEC_AUDIT_GROUP
23288 ++ bool "Single group for auditing"
23289 ++ help
23290 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
23291 ++ will only operate on a group you specify. This option is recommended
23292 ++ if you only want to watch certain users instead of having a large
23293 ++ amount of logs from the entire system. If the sysctl option is enabled,
23294 ++ a sysctl option with name "audit_group" is created.
23295 ++
23296 ++config GRKERNSEC_AUDIT_GID
23297 ++ int "GID for auditing"
23298 ++ depends on GRKERNSEC_AUDIT_GROUP
23299 ++ default 1007
23300 ++
23301 ++config GRKERNSEC_EXECLOG
23302 ++ bool "Exec logging"
23303 ++ help
23304 ++ If you say Y here, all execve() calls will be logged (since the
23305 ++ other exec*() calls are frontends to execve(), all execution
23306 ++ will be logged). Useful for shell-servers that like to keep track
23307 ++ of their users. If the sysctl option is enabled, a sysctl option with
23308 ++ name "exec_logging" is created.
23309 ++ WARNING: This option when enabled will produce a LOT of logs, especially
23310 ++ on an active system.
23311 ++
23312 ++config GRKERNSEC_RESLOG
23313 ++ bool "Resource logging"
23314 ++ help
23315 ++ If you say Y here, all attempts to overstep resource limits will
23316 ++ be logged with the resource name, the requested size, and the current
23317 ++ limit. It is highly recommended that you say Y here. If the sysctl
23318 ++ option is enabled, a sysctl option with name "resource_logging" is
23319 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
23320 ++
23321 ++config GRKERNSEC_CHROOT_EXECLOG
23322 ++ bool "Log execs within chroot"
23323 ++ help
23324 ++ If you say Y here, all executions inside a chroot jail will be logged
23325 ++ to syslog. This can cause a large amount of logs if certain
23326 ++ applications (eg. djb's daemontools) are installed on the system, and
23327 ++ is therefore left as an option. If the sysctl option is enabled, a
23328 ++ sysctl option with name "chroot_execlog" is created.
23329 ++
23330 ++config GRKERNSEC_AUDIT_CHDIR
23331 ++ bool "Chdir logging"
23332 ++ help
23333 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
23334 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
23335 ++
23336 ++config GRKERNSEC_AUDIT_MOUNT
23337 ++ bool "(Un)Mount logging"
23338 ++ help
23339 ++ If you say Y here, all mounts and unmounts will be logged. If the
23340 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
23341 ++ created.
23342 ++
23343 ++config GRKERNSEC_AUDIT_IPC
23344 ++ bool "IPC logging"
23345 ++ help
23346 ++ If you say Y here, creation and removal of message queues, semaphores,
23347 ++ and shared memory will be logged. If the sysctl option is enabled, a
23348 ++ sysctl option with name "audit_ipc" is created.
23349 ++
23350 ++config GRKERNSEC_SIGNAL
23351 ++ bool "Signal logging"
23352 ++ help
23353 ++ If you say Y here, certain important signals will be logged, such as
23354 ++ SIGSEGV, which will as a result inform you of when a error in a program
23355 ++ occurred, which in some cases could mean a possible exploit attempt.
23356 ++ If the sysctl option is enabled, a sysctl option with name
23357 ++ "signal_logging" is created.
23358 ++
23359 ++config GRKERNSEC_FORKFAIL
23360 ++ bool "Fork failure logging"
23361 ++ help
23362 ++ If you say Y here, all failed fork() attempts will be logged.
23363 ++ This could suggest a fork bomb, or someone attempting to overstep
23364 ++ their process limit. If the sysctl option is enabled, a sysctl option
23365 ++ with name "forkfail_logging" is created.
23366 ++
23367 ++config GRKERNSEC_TIME
23368 ++ bool "Time change logging"
23369 ++ help
23370 ++ If you say Y here, any changes of the system clock will be logged.
23371 ++ If the sysctl option is enabled, a sysctl option with name
23372 ++ "timechange_logging" is created.
23373 ++
23374 ++config GRKERNSEC_PROC_IPADDR
23375 ++ bool "/proc/<pid>/ipaddr support"
23376 ++ help
23377 ++ If you say Y here, a new entry will be added to each /proc/<pid>
23378 ++ directory that contains the IP address of the person using the task.
23379 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
23380 ++ This information can be useful for IDS/IPSes to perform remote response
23381 ++ to a local attack. The entry is readable by only the owner of the
23382 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
23383 ++ the RBAC system), and thus does not create privacy concerns.
23384 ++
23385 ++config GRKERNSEC_AUDIT_TEXTREL
23386 ++ bool 'ELF text relocations logging (READ HELP)'
23387 ++ depends on PAX_MPROTECT
23388 ++ help
23389 ++ If you say Y here, text relocations will be logged with the filename
23390 ++ of the offending library or binary. The purpose of the feature is
23391 ++ to help Linux distribution developers get rid of libraries and
23392 ++ binaries that need text relocations which hinder the future progress
23393 ++ of PaX. Only Linux distribution developers should say Y here, and
23394 ++ never on a production machine, as this option creates an information
23395 ++ leak that could aid an attacker in defeating the randomization of
23396 ++ a single memory region. If the sysctl option is enabled, a sysctl
23397 ++ option with name "audit_textrel" is created.
23398 ++
23399 ++endmenu
23400 ++
23401 ++menu "Executable Protections"
23402 ++depends on GRKERNSEC
23403 ++
23404 ++config GRKERNSEC_EXECVE
23405 ++ bool "Enforce RLIMIT_NPROC on execs"
23406 ++ help
23407 ++ If you say Y here, users with a resource limit on processes will
23408 ++ have the value checked during execve() calls. The current system
23409 ++ only checks the system limit during fork() calls. If the sysctl option
23410 ++ is enabled, a sysctl option with name "execve_limiting" is created.
23411 ++
23412 ++config GRKERNSEC_DMESG
23413 ++ bool "Dmesg(8) restriction"
23414 ++ help
23415 ++ If you say Y here, non-root users will not be able to use dmesg(8)
23416 ++ to view up to the last 4kb of messages in the kernel's log buffer.
23417 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
23418 ++ created.
23419 ++
23420 ++config GRKERNSEC_TPE
23421 ++ bool "Trusted Path Execution (TPE)"
23422 ++ help
23423 ++ If you say Y here, you will be able to choose a gid to add to the
23424 ++ supplementary groups of users you want to mark as "untrusted."
23425 ++ These users will not be able to execute any files that are not in
23426 ++ root-owned directories writable only by root. If the sysctl option
23427 ++ is enabled, a sysctl option with name "tpe" is created.
23428 ++
23429 ++config GRKERNSEC_TPE_ALL
23430 ++ bool "Partially restrict non-root users"
23431 ++ depends on GRKERNSEC_TPE
23432 ++ help
23433 ++ If you say Y here, All non-root users other than the ones in the
23434 ++ group specified in the main TPE option will only be allowed to
23435 ++ execute files in directories they own that are not group or
23436 ++ world-writable, or in directories owned by root and writable only by
23437 ++ root. If the sysctl option is enabled, a sysctl option with name
23438 ++ "tpe_restrict_all" is created.
23439 ++
23440 ++config GRKERNSEC_TPE_INVERT
23441 ++ bool "Invert GID option"
23442 ++ depends on GRKERNSEC_TPE
23443 ++ help
23444 ++ If you say Y here, the group you specify in the TPE configuration will
23445 ++ decide what group TPE restrictions will be *disabled* for. This
23446 ++ option is useful if you want TPE restrictions to be applied to most
23447 ++ users on the system.
23448 ++
23449 ++config GRKERNSEC_TPE_GID
23450 ++ int "GID for untrusted users"
23451 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
23452 ++ default 1005
23453 ++ help
23454 ++ If you have selected the "Invert GID option" above, setting this
23455 ++ GID determines what group TPE restrictions will be *disabled* for.
23456 ++ If you have not selected the "Invert GID option" above, setting this
23457 ++ GID determines what group TPE restrictions will be *enabled* for.
23458 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23459 ++ is created.
23460 ++
23461 ++config GRKERNSEC_TPE_GID
23462 ++ int "GID for trusted users"
23463 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
23464 ++ default 1005
23465 ++ help
23466 ++ If you have selected the "Invert GID option" above, setting this
23467 ++ GID determines what group TPE restrictions will be *disabled* for.
23468 ++ If you have not selected the "Invert GID option" above, setting this
23469 ++ GID determines what group TPE restrictions will be *enabled* for.
23470 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23471 ++ is created.
23472 ++
23473 ++endmenu
23474 ++menu "Network Protections"
23475 ++depends on GRKERNSEC
23476 ++
23477 ++config GRKERNSEC_RANDNET
23478 ++ bool "Larger entropy pools"
23479 ++ help
23480 ++ If you say Y here, the entropy pools used for many features of Linux
23481 ++ and grsecurity will be doubled in size. Since several grsecurity
23482 ++ features use additional randomness, it is recommended that you say Y
23483 ++ here. Saying Y here has a similar effect as modifying
23484 ++ /proc/sys/kernel/random/poolsize.
23485 ++
23486 ++config GRKERNSEC_SOCKET
23487 ++ bool "Socket restrictions"
23488 ++ help
23489 ++ If you say Y here, you will be able to choose from several options.
23490 ++ If you assign a GID on your system and add it to the supplementary
23491 ++ groups of users you want to restrict socket access to, this patch
23492 ++ will perform up to three things, based on the option(s) you choose.
23493 ++
23494 ++config GRKERNSEC_SOCKET_ALL
23495 ++ bool "Deny any sockets to group"
23496 ++ depends on GRKERNSEC_SOCKET
23497 ++ help
23498 ++ If you say Y here, you will be able to choose a GID of whose users will
23499 ++ be unable to connect to other hosts from your machine or run server
23500 ++ applications from your machine. If the sysctl option is enabled, a
23501 ++ sysctl option with name "socket_all" is created.
23502 ++
23503 ++config GRKERNSEC_SOCKET_ALL_GID
23504 ++ int "GID to deny all sockets for"
23505 ++ depends on GRKERNSEC_SOCKET_ALL
23506 ++ default 1004
23507 ++ help
23508 ++ Here you can choose the GID to disable socket access for. Remember to
23509 ++ add the users you want socket access disabled for to the GID
23510 ++ specified here. If the sysctl option is enabled, a sysctl option
23511 ++ with name "socket_all_gid" is created.
23512 ++
23513 ++config GRKERNSEC_SOCKET_CLIENT
23514 ++ bool "Deny client sockets to group"
23515 ++ depends on GRKERNSEC_SOCKET
23516 ++ help
23517 ++ If you say Y here, you will be able to choose a GID of whose users will
23518 ++ be unable to connect to other hosts from your machine, but will be
23519 ++ able to run servers. If this option is enabled, all users in the group
23520 ++ you specify will have to use passive mode when initiating ftp transfers
23521 ++ from the shell on your machine. If the sysctl option is enabled, a
23522 ++ sysctl option with name "socket_client" is created.
23523 ++
23524 ++config GRKERNSEC_SOCKET_CLIENT_GID
23525 ++ int "GID to deny client sockets for"
23526 ++ depends on GRKERNSEC_SOCKET_CLIENT
23527 ++ default 1003
23528 ++ help
23529 ++ Here you can choose the GID to disable client socket access for.
23530 ++ Remember to add the users you want client socket access disabled for to
23531 ++ the GID specified here. If the sysctl option is enabled, a sysctl
23532 ++ option with name "socket_client_gid" is created.
23533 ++
23534 ++config GRKERNSEC_SOCKET_SERVER
23535 ++ bool "Deny server sockets to group"
23536 ++ depends on GRKERNSEC_SOCKET
23537 ++ help
23538 ++ If you say Y here, you will be able to choose a GID of whose users will
23539 ++ be unable to run server applications from your machine. If the sysctl
23540 ++ option is enabled, a sysctl option with name "socket_server" is created.
23541 ++
23542 ++config GRKERNSEC_SOCKET_SERVER_GID
23543 ++ int "GID to deny server sockets for"
23544 ++ depends on GRKERNSEC_SOCKET_SERVER
23545 ++ default 1002
23546 ++ help
23547 ++ Here you can choose the GID to disable server socket access for.
23548 ++ Remember to add the users you want server socket access disabled for to
23549 ++ the GID specified here. If the sysctl option is enabled, a sysctl
23550 ++ option with name "socket_server_gid" is created.
23551 ++
23552 ++endmenu
23553 ++menu "Sysctl support"
23554 ++depends on GRKERNSEC && SYSCTL
23555 ++
23556 ++config GRKERNSEC_SYSCTL
23557 ++ bool "Sysctl support"
23558 ++ help
23559 ++ If you say Y here, you will be able to change the options that
23560 ++ grsecurity runs with at bootup, without having to recompile your
23561 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
23562 ++ to enable (1) or disable (0) various features. All the sysctl entries
23563 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
23564 ++ All features enabled in the kernel configuration are disabled at boot
23565 ++ if you do not say Y to the "Turn on features by default" option.
23566 ++ All options should be set at startup, and the grsec_lock entry should
23567 ++ be set to a non-zero value after all the options are set.
23568 ++ *THIS IS EXTREMELY IMPORTANT*
23569 ++
23570 ++config GRKERNSEC_SYSCTL_ON
23571 ++ bool "Turn on features by default"
23572 ++ depends on GRKERNSEC_SYSCTL
23573 ++ help
23574 ++ If you say Y here, instead of having all features enabled in the
23575 ++ kernel configuration disabled at boot time, the features will be
23576 ++ enabled at boot time. It is recommended you say Y here unless
23577 ++ there is some reason you would want all sysctl-tunable features to
23578 ++ be disabled by default. As mentioned elsewhere, it is important
23579 ++ to enable the grsec_lock entry once you have finished modifying
23580 ++ the sysctl entries.
23581 ++
23582 ++endmenu
23583 ++menu "Logging Options"
23584 ++depends on GRKERNSEC
23585 ++
23586 ++config GRKERNSEC_FLOODTIME
23587 ++ int "Seconds in between log messages (minimum)"
23588 ++ default 10
23589 ++ help
23590 ++ This option allows you to enforce the number of seconds between
23591 ++ grsecurity log messages. The default should be suitable for most
23592 ++ people, however, if you choose to change it, choose a value small enough
23593 ++ to allow informative logs to be produced, but large enough to
23594 ++ prevent flooding.
23595 ++
23596 ++config GRKERNSEC_FLOODBURST
23597 ++ int "Number of messages in a burst (maximum)"
23598 ++ default 4
23599 ++ help
23600 ++ This option allows you to choose the maximum number of messages allowed
23601 ++ within the flood time interval you chose in a separate option. The
23602 ++ default should be suitable for most people, however if you find that
23603 ++ many of your logs are being interpreted as flooding, you may want to
23604 ++ raise this value.
23605 ++
23606 ++endmenu
23607 ++
23608 ++endmenu
23609 +diff -urNp a/grsecurity/Makefile b/grsecurity/Makefile
23610 +--- a/grsecurity/Makefile 1969-12-31 16:00:00.000000000 -0800
23611 ++++ b/grsecurity/Makefile 2008-08-20 18:36:57.000000000 -0700
23612 +@@ -0,0 +1,20 @@
23613 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
23614 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
23615 ++# into an RBAC system
23616 ++#
23617 ++# All code in this directory and various hooks inserted throughout the kernel
23618 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
23619 ++
23620 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
23621 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
23622 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
23623 ++
23624 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
23625 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
23626 ++ gracl_learn.o grsec_log.o
23627 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
23628 ++
23629 ++ifndef CONFIG_GRKERNSEC
23630 ++obj-y += grsec_disabled.o
23631 ++endif
23632 ++
23633 +diff -urNp a/grsecurity/gracl.c b/grsecurity/gracl.c
23634 +--- a/grsecurity/gracl.c 1969-12-31 16:00:00.000000000 -0800
23635 ++++ b/grsecurity/gracl.c 2008-08-20 18:36:57.000000000 -0700
23636 +@@ -0,0 +1,3721 @@
23637 ++#include <linux/kernel.h>
23638 ++#include <linux/module.h>
23639 ++#include <linux/sched.h>
23640 ++#include <linux/mm.h>
23641 ++#include <linux/file.h>
23642 ++#include <linux/fs.h>
23643 ++#include <linux/namei.h>
23644 ++#include <linux/mount.h>
23645 ++#include <linux/tty.h>
23646 ++#include <linux/proc_fs.h>
23647 ++#include <linux/smp_lock.h>
23648 ++#include <linux/slab.h>
23649 ++#include <linux/vmalloc.h>
23650 ++#include <linux/types.h>
23651 ++#include <linux/sysctl.h>
23652 ++#include <linux/netdevice.h>
23653 ++#include <linux/ptrace.h>
23654 ++#include <linux/gracl.h>
23655 ++#include <linux/gralloc.h>
23656 ++#include <linux/grsecurity.h>
23657 ++#include <linux/grinternal.h>
23658 ++#include <linux/pid_namespace.h>
23659 ++#include <linux/percpu.h>
23660 ++
23661 ++#include <asm/uaccess.h>
23662 ++#include <asm/errno.h>
23663 ++#include <asm/mman.h>
23664 ++
23665 ++static struct acl_role_db acl_role_set;
23666 ++static struct name_db name_set;
23667 ++static struct inodev_db inodev_set;
23668 ++
23669 ++/* for keeping track of userspace pointers used for subjects, so we
23670 ++ can share references in the kernel as well
23671 ++*/
23672 ++
23673 ++static struct dentry *real_root;
23674 ++static struct vfsmount *real_root_mnt;
23675 ++
23676 ++static struct acl_subj_map_db subj_map_set;
23677 ++
23678 ++static struct acl_role_label *default_role;
23679 ++
23680 ++static u16 acl_sp_role_value;
23681 ++
23682 ++extern char *gr_shared_page[4];
23683 ++static DECLARE_MUTEX(gr_dev_sem);
23684 ++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
23685 ++
23686 ++struct gr_arg *gr_usermode;
23687 ++
23688 ++static unsigned int gr_status = GR_STATUS_INIT;
23689 ++
23690 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
23691 ++extern void gr_clear_learn_entries(void);
23692 ++
23693 ++#ifdef CONFIG_GRKERNSEC_RESLOG
23694 ++extern void gr_log_resource(const struct task_struct *task,
23695 ++ const int res, const unsigned long wanted, const int gt);
23696 ++#endif
23697 ++
23698 ++unsigned char *gr_system_salt;
23699 ++unsigned char *gr_system_sum;
23700 ++
23701 ++static struct sprole_pw **acl_special_roles = NULL;
23702 ++static __u16 num_sprole_pws = 0;
23703 ++
23704 ++static struct acl_role_label *kernel_role = NULL;
23705 ++
23706 ++static unsigned int gr_auth_attempts = 0;
23707 ++static unsigned long gr_auth_expires = 0UL;
23708 ++
23709 ++extern struct vfsmount *sock_mnt;
23710 ++extern struct vfsmount *pipe_mnt;
23711 ++extern struct vfsmount *shm_mnt;
23712 ++static struct acl_object_label *fakefs_obj;
23713 ++
23714 ++extern int gr_init_uidset(void);
23715 ++extern void gr_free_uidset(void);
23716 ++extern void gr_remove_uid(uid_t uid);
23717 ++extern int gr_find_uid(uid_t uid);
23718 ++
23719 ++__inline__ int
23720 ++gr_acl_is_enabled(void)
23721 ++{
23722 ++ return (gr_status & GR_READY);
23723 ++}
23724 ++
23725 ++char gr_roletype_to_char(void)
23726 ++{
23727 ++ switch (current->role->roletype &
23728 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
23729 ++ GR_ROLE_SPECIAL)) {
23730 ++ case GR_ROLE_DEFAULT:
23731 ++ return 'D';
23732 ++ case GR_ROLE_USER:
23733 ++ return 'U';
23734 ++ case GR_ROLE_GROUP:
23735 ++ return 'G';
23736 ++ case GR_ROLE_SPECIAL:
23737 ++ return 'S';
23738 ++ }
23739 ++
23740 ++ return 'X';
23741 ++}
23742 ++
23743 ++__inline__ int
23744 ++gr_acl_tpe_check(void)
23745 ++{
23746 ++ if (unlikely(!(gr_status & GR_READY)))
23747 ++ return 0;
23748 ++ if (current->role->roletype & GR_ROLE_TPE)
23749 ++ return 1;
23750 ++ else
23751 ++ return 0;
23752 ++}
23753 ++
23754 ++int
23755 ++gr_handle_rawio(const struct inode *inode)
23756 ++{
23757 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23758 ++ if (inode && S_ISBLK(inode->i_mode) &&
23759 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
23760 ++ !capable(CAP_SYS_RAWIO))
23761 ++ return 1;
23762 ++#endif
23763 ++ return 0;
23764 ++}
23765 ++
23766 ++static int
23767 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
23768 ++{
23769 ++ int i;
23770 ++ unsigned long *l1;
23771 ++ unsigned long *l2;
23772 ++ unsigned char *c1;
23773 ++ unsigned char *c2;
23774 ++ int num_longs;
23775 ++
23776 ++ if (likely(lena != lenb))
23777 ++ return 0;
23778 ++
23779 ++ l1 = (unsigned long *)a;
23780 ++ l2 = (unsigned long *)b;
23781 ++
23782 ++ num_longs = lena / sizeof(unsigned long);
23783 ++
23784 ++ for (i = num_longs; i--; l1++, l2++) {
23785 ++ if (unlikely(*l1 != *l2))
23786 ++ return 0;
23787 ++ }
23788 ++
23789 ++ c1 = (unsigned char *) l1;
23790 ++ c2 = (unsigned char *) l2;
23791 ++
23792 ++ i = lena - (num_longs * sizeof(unsigned long));
23793 ++
23794 ++ for (; i--; c1++, c2++) {
23795 ++ if (unlikely(*c1 != *c2))
23796 ++ return 0;
23797 ++ }
23798 ++
23799 ++ return 1;
23800 ++}
23801 ++
23802 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
23803 ++ struct dentry *root, struct vfsmount *rootmnt,
23804 ++ char *buffer, int buflen)
23805 ++{
23806 ++ char * end = buffer+buflen;
23807 ++ char * retval;
23808 ++ int namelen;
23809 ++
23810 ++ *--end = '\0';
23811 ++ buflen--;
23812 ++
23813 ++ if (buflen < 1)
23814 ++ goto Elong;
23815 ++ /* Get '/' right */
23816 ++ retval = end-1;
23817 ++ *retval = '/';
23818 ++
23819 ++ for (;;) {
23820 ++ struct dentry * parent;
23821 ++
23822 ++ if (dentry == root && vfsmnt == rootmnt)
23823 ++ break;
23824 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
23825 ++ /* Global root? */
23826 ++ spin_lock(&vfsmount_lock);
23827 ++ if (vfsmnt->mnt_parent == vfsmnt) {
23828 ++ spin_unlock(&vfsmount_lock);
23829 ++ goto global_root;
23830 ++ }
23831 ++ dentry = vfsmnt->mnt_mountpoint;
23832 ++ vfsmnt = vfsmnt->mnt_parent;
23833 ++ spin_unlock(&vfsmount_lock);
23834 ++ continue;
23835 ++ }
23836 ++ parent = dentry->d_parent;
23837 ++ prefetch(parent);
23838 ++ namelen = dentry->d_name.len;
23839 ++ buflen -= namelen + 1;
23840 ++ if (buflen < 0)
23841 ++ goto Elong;
23842 ++ end -= namelen;
23843 ++ memcpy(end, dentry->d_name.name, namelen);
23844 ++ *--end = '/';
23845 ++ retval = end;
23846 ++ dentry = parent;
23847 ++ }
23848 ++
23849 ++ return retval;
23850 ++
23851 ++global_root:
23852 ++ namelen = dentry->d_name.len;
23853 ++ buflen -= namelen;
23854 ++ if (buflen < 0)
23855 ++ goto Elong;
23856 ++ retval -= namelen-1; /* hit the slash */
23857 ++ memcpy(retval, dentry->d_name.name, namelen);
23858 ++ return retval;
23859 ++Elong:
23860 ++ return ERR_PTR(-ENAMETOOLONG);
23861 ++}
23862 ++
23863 ++static char *
23864 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
23865 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
23866 ++{
23867 ++ char *retval;
23868 ++
23869 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
23870 ++ if (unlikely(IS_ERR(retval)))
23871 ++ retval = strcpy(buf, "<path too long>");
23872 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
23873 ++ retval[1] = '\0';
23874 ++
23875 ++ return retval;
23876 ++}
23877 ++
23878 ++static char *
23879 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
23880 ++ char *buf, int buflen)
23881 ++{
23882 ++ char *res;
23883 ++
23884 ++ /* we can use real_root, real_root_mnt, because this is only called
23885 ++ by the RBAC system */
23886 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
23887 ++
23888 ++ return res;
23889 ++}
23890 ++
23891 ++static char *
23892 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
23893 ++ char *buf, int buflen)
23894 ++{
23895 ++ char *res;
23896 ++ struct dentry *root;
23897 ++ struct vfsmount *rootmnt;
23898 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
23899 ++
23900 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
23901 ++ read_lock(&reaper->fs->lock);
23902 ++ root = dget(reaper->fs->root.dentry);
23903 ++ rootmnt = mntget(reaper->fs->root.mnt);
23904 ++ read_unlock(&reaper->fs->lock);
23905 ++
23906 ++ spin_lock(&dcache_lock);
23907 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
23908 ++ spin_unlock(&dcache_lock);
23909 ++
23910 ++ dput(root);
23911 ++ mntput(rootmnt);
23912 ++ return res;
23913 ++}
23914 ++
23915 ++static char *
23916 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
23917 ++{
23918 ++ char *ret;
23919 ++ spin_lock(&dcache_lock);
23920 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
23921 ++ PAGE_SIZE);
23922 ++ spin_unlock(&dcache_lock);
23923 ++ return ret;
23924 ++}
23925 ++
23926 ++char *
23927 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
23928 ++{
23929 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
23930 ++ PAGE_SIZE);
23931 ++}
23932 ++
23933 ++char *
23934 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
23935 ++{
23936 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
23937 ++ PAGE_SIZE);
23938 ++}
23939 ++
23940 ++char *
23941 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
23942 ++{
23943 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
23944 ++ PAGE_SIZE);
23945 ++}
23946 ++
23947 ++char *
23948 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
23949 ++{
23950 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
23951 ++ PAGE_SIZE);
23952 ++}
23953 ++
23954 ++char *
23955 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
23956 ++{
23957 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
23958 ++ PAGE_SIZE);
23959 ++}
23960 ++
23961 ++__inline__ __u32
23962 ++to_gr_audit(const __u32 reqmode)
23963 ++{
23964 ++ /* masks off auditable permission flags, then shifts them to create
23965 ++ auditing flags, and adds the special case of append auditing if
23966 ++ we're requesting write */
23967 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
23968 ++}
23969 ++
23970 ++struct acl_subject_label *
23971 ++lookup_subject_map(const struct acl_subject_label *userp)
23972 ++{
23973 ++ unsigned int index = shash(userp, subj_map_set.s_size);
23974 ++ struct subject_map *match;
23975 ++
23976 ++ match = subj_map_set.s_hash[index];
23977 ++
23978 ++ while (match && match->user != userp)
23979 ++ match = match->next;
23980 ++
23981 ++ if (match != NULL)
23982 ++ return match->kernel;
23983 ++ else
23984 ++ return NULL;
23985 ++}
23986 ++
23987 ++static void
23988 ++insert_subj_map_entry(struct subject_map *subjmap)
23989 ++{
23990 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
23991 ++ struct subject_map **curr;
23992 ++
23993 ++ subjmap->prev = NULL;
23994 ++
23995 ++ curr = &subj_map_set.s_hash[index];
23996 ++ if (*curr != NULL)
23997 ++ (*curr)->prev = subjmap;
23998 ++
23999 ++ subjmap->next = *curr;
24000 ++ *curr = subjmap;
24001 ++
24002 ++ return;
24003 ++}
24004 ++
24005 ++static struct acl_role_label *
24006 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
24007 ++ const gid_t gid)
24008 ++{
24009 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
24010 ++ struct acl_role_label *match;
24011 ++ struct role_allowed_ip *ipp;
24012 ++ unsigned int x;
24013 ++
24014 ++ match = acl_role_set.r_hash[index];
24015 ++
24016 ++ while (match) {
24017 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
24018 ++ for (x = 0; x < match->domain_child_num; x++) {
24019 ++ if (match->domain_children[x] == uid)
24020 ++ goto found;
24021 ++ }
24022 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
24023 ++ break;
24024 ++ match = match->next;
24025 ++ }
24026 ++found:
24027 ++ if (match == NULL) {
24028 ++ try_group:
24029 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
24030 ++ match = acl_role_set.r_hash[index];
24031 ++
24032 ++ while (match) {
24033 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
24034 ++ for (x = 0; x < match->domain_child_num; x++) {
24035 ++ if (match->domain_children[x] == gid)
24036 ++ goto found2;
24037 ++ }
24038 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
24039 ++ break;
24040 ++ match = match->next;
24041 ++ }
24042 ++found2:
24043 ++ if (match == NULL)
24044 ++ match = default_role;
24045 ++ if (match->allowed_ips == NULL)
24046 ++ return match;
24047 ++ else {
24048 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
24049 ++ if (likely
24050 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
24051 ++ (ntohl(ipp->addr) & ipp->netmask)))
24052 ++ return match;
24053 ++ }
24054 ++ match = default_role;
24055 ++ }
24056 ++ } else if (match->allowed_ips == NULL) {
24057 ++ return match;
24058 ++ } else {
24059 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
24060 ++ if (likely
24061 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
24062 ++ (ntohl(ipp->addr) & ipp->netmask)))
24063 ++ return match;
24064 ++ }
24065 ++ goto try_group;
24066 ++ }
24067 ++
24068 ++ return match;
24069 ++}
24070 ++
24071 ++struct acl_subject_label *
24072 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
24073 ++ const struct acl_role_label *role)
24074 ++{
24075 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
24076 ++ struct acl_subject_label *match;
24077 ++
24078 ++ match = role->subj_hash[index];
24079 ++
24080 ++ while (match && (match->inode != ino || match->device != dev ||
24081 ++ (match->mode & GR_DELETED))) {
24082 ++ match = match->next;
24083 ++ }
24084 ++
24085 ++ if (match && !(match->mode & GR_DELETED))
24086 ++ return match;
24087 ++ else
24088 ++ return NULL;
24089 ++}
24090 ++
24091 ++static struct acl_object_label *
24092 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
24093 ++ const struct acl_subject_label *subj)
24094 ++{
24095 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
24096 ++ struct acl_object_label *match;
24097 ++
24098 ++ match = subj->obj_hash[index];
24099 ++
24100 ++ while (match && (match->inode != ino || match->device != dev ||
24101 ++ (match->mode & GR_DELETED))) {
24102 ++ match = match->next;
24103 ++ }
24104 ++
24105 ++ if (match && !(match->mode & GR_DELETED))
24106 ++ return match;
24107 ++ else
24108 ++ return NULL;
24109 ++}
24110 ++
24111 ++static struct acl_object_label *
24112 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
24113 ++ const struct acl_subject_label *subj)
24114 ++{
24115 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
24116 ++ struct acl_object_label *match;
24117 ++
24118 ++ match = subj->obj_hash[index];
24119 ++
24120 ++ while (match && (match->inode != ino || match->device != dev ||
24121 ++ !(match->mode & GR_DELETED))) {
24122 ++ match = match->next;
24123 ++ }
24124 ++
24125 ++ if (match && (match->mode & GR_DELETED))
24126 ++ return match;
24127 ++
24128 ++ match = subj->obj_hash[index];
24129 ++
24130 ++ while (match && (match->inode != ino || match->device != dev ||
24131 ++ (match->mode & GR_DELETED))) {
24132 ++ match = match->next;
24133 ++ }
24134 ++
24135 ++ if (match && !(match->mode & GR_DELETED))
24136 ++ return match;
24137 ++ else
24138 ++ return NULL;
24139 ++}
24140 ++
24141 ++static struct name_entry *
24142 ++lookup_name_entry(const char *name)
24143 ++{
24144 ++ unsigned int len = strlen(name);
24145 ++ unsigned int key = full_name_hash(name, len);
24146 ++ unsigned int index = key % name_set.n_size;
24147 ++ struct name_entry *match;
24148 ++
24149 ++ match = name_set.n_hash[index];
24150 ++
24151 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
24152 ++ match = match->next;
24153 ++
24154 ++ return match;
24155 ++}
24156 ++
24157 ++static struct name_entry *
24158 ++lookup_name_entry_create(const char *name)
24159 ++{
24160 ++ unsigned int len = strlen(name);
24161 ++ unsigned int key = full_name_hash(name, len);
24162 ++ unsigned int index = key % name_set.n_size;
24163 ++ struct name_entry *match;
24164 ++
24165 ++ match = name_set.n_hash[index];
24166 ++
24167 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
24168 ++ !match->deleted))
24169 ++ match = match->next;
24170 ++
24171 ++ if (match && match->deleted)
24172 ++ return match;
24173 ++
24174 ++ match = name_set.n_hash[index];
24175 ++
24176 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
24177 ++ match->deleted))
24178 ++ match = match->next;
24179 ++
24180 ++ if (match && !match->deleted)
24181 ++ return match;
24182 ++ else
24183 ++ return NULL;
24184 ++}
24185 ++
24186 ++static struct inodev_entry *
24187 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
24188 ++{
24189 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
24190 ++ struct inodev_entry *match;
24191 ++
24192 ++ match = inodev_set.i_hash[index];
24193 ++
24194 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
24195 ++ match = match->next;
24196 ++
24197 ++ return match;
24198 ++}
24199 ++
24200 ++static void
24201 ++insert_inodev_entry(struct inodev_entry *entry)
24202 ++{
24203 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
24204 ++ inodev_set.i_size);
24205 ++ struct inodev_entry **curr;
24206 ++
24207 ++ entry->prev = NULL;
24208 ++
24209 ++ curr = &inodev_set.i_hash[index];
24210 ++ if (*curr != NULL)
24211 ++ (*curr)->prev = entry;
24212 ++
24213 ++ entry->next = *curr;
24214 ++ *curr = entry;
24215 ++
24216 ++ return;
24217 ++}
24218 ++
24219 ++static void
24220 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
24221 ++{
24222 ++ unsigned int index =
24223 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
24224 ++ struct acl_role_label **curr;
24225 ++
24226 ++ role->prev = NULL;
24227 ++
24228 ++ curr = &acl_role_set.r_hash[index];
24229 ++ if (*curr != NULL)
24230 ++ (*curr)->prev = role;
24231 ++
24232 ++ role->next = *curr;
24233 ++ *curr = role;
24234 ++
24235 ++ return;
24236 ++}
24237 ++
24238 ++static void
24239 ++insert_acl_role_label(struct acl_role_label *role)
24240 ++{
24241 ++ int i;
24242 ++
24243 ++ if (role->roletype & GR_ROLE_DOMAIN) {
24244 ++ for (i = 0; i < role->domain_child_num; i++)
24245 ++ __insert_acl_role_label(role, role->domain_children[i]);
24246 ++ } else
24247 ++ __insert_acl_role_label(role, role->uidgid);
24248 ++}
24249 ++
24250 ++static int
24251 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
24252 ++{
24253 ++ struct name_entry **curr, *nentry;
24254 ++ struct inodev_entry *ientry;
24255 ++ unsigned int len = strlen(name);
24256 ++ unsigned int key = full_name_hash(name, len);
24257 ++ unsigned int index = key % name_set.n_size;
24258 ++
24259 ++ curr = &name_set.n_hash[index];
24260 ++
24261 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
24262 ++ curr = &((*curr)->next);
24263 ++
24264 ++ if (*curr != NULL)
24265 ++ return 1;
24266 ++
24267 ++ nentry = acl_alloc(sizeof (struct name_entry));
24268 ++ if (nentry == NULL)
24269 ++ return 0;
24270 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
24271 ++ if (ientry == NULL)
24272 ++ return 0;
24273 ++ ientry->nentry = nentry;
24274 ++
24275 ++ nentry->key = key;
24276 ++ nentry->name = name;
24277 ++ nentry->inode = inode;
24278 ++ nentry->device = device;
24279 ++ nentry->len = len;
24280 ++ nentry->deleted = deleted;
24281 ++
24282 ++ nentry->prev = NULL;
24283 ++ curr = &name_set.n_hash[index];
24284 ++ if (*curr != NULL)
24285 ++ (*curr)->prev = nentry;
24286 ++ nentry->next = *curr;
24287 ++ *curr = nentry;
24288 ++
24289 ++ /* insert us into the table searchable by inode/dev */
24290 ++ insert_inodev_entry(ientry);
24291 ++
24292 ++ return 1;
24293 ++}
24294 ++
24295 ++static void
24296 ++insert_acl_obj_label(struct acl_object_label *obj,
24297 ++ struct acl_subject_label *subj)
24298 ++{
24299 ++ unsigned int index =
24300 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
24301 ++ struct acl_object_label **curr;
24302 ++
24303 ++
24304 ++ obj->prev = NULL;
24305 ++
24306 ++ curr = &subj->obj_hash[index];
24307 ++ if (*curr != NULL)
24308 ++ (*curr)->prev = obj;
24309 ++
24310 ++ obj->next = *curr;
24311 ++ *curr = obj;
24312 ++
24313 ++ return;
24314 ++}
24315 ++
24316 ++static void
24317 ++insert_acl_subj_label(struct acl_subject_label *obj,
24318 ++ struct acl_role_label *role)
24319 ++{
24320 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
24321 ++ struct acl_subject_label **curr;
24322 ++
24323 ++ obj->prev = NULL;
24324 ++
24325 ++ curr = &role->subj_hash[index];
24326 ++ if (*curr != NULL)
24327 ++ (*curr)->prev = obj;
24328 ++
24329 ++ obj->next = *curr;
24330 ++ *curr = obj;
24331 ++
24332 ++ return;
24333 ++}
24334 ++
24335 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
24336 ++
24337 ++static void *
24338 ++create_table(__u32 * len, int elementsize)
24339 ++{
24340 ++ unsigned int table_sizes[] = {
24341 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
24342 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
24343 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
24344 ++ 268435399, 536870909, 1073741789, 2147483647
24345 ++ };
24346 ++ void *newtable = NULL;
24347 ++ unsigned int pwr = 0;
24348 ++
24349 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
24350 ++ table_sizes[pwr] <= *len)
24351 ++ pwr++;
24352 ++
24353 ++ if (table_sizes[pwr] <= *len)
24354 ++ return newtable;
24355 ++
24356 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
24357 ++ newtable =
24358 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
24359 ++ else
24360 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
24361 ++
24362 ++ *len = table_sizes[pwr];
24363 ++
24364 ++ return newtable;
24365 ++}
24366 ++
24367 ++static int
24368 ++init_variables(const struct gr_arg *arg)
24369 ++{
24370 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
24371 ++ unsigned int stacksize;
24372 ++
24373 ++ subj_map_set.s_size = arg->role_db.num_subjects;
24374 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
24375 ++ name_set.n_size = arg->role_db.num_objects;
24376 ++ inodev_set.i_size = arg->role_db.num_objects;
24377 ++
24378 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
24379 ++ !name_set.n_size || !inodev_set.i_size)
24380 ++ return 1;
24381 ++
24382 ++ if (!gr_init_uidset())
24383 ++ return 1;
24384 ++
24385 ++ /* set up the stack that holds allocation info */
24386 ++
24387 ++ stacksize = arg->role_db.num_pointers + 5;
24388 ++
24389 ++ if (!acl_alloc_stack_init(stacksize))
24390 ++ return 1;
24391 ++
24392 ++ /* grab reference for the real root dentry and vfsmount */
24393 ++ read_lock(&reaper->fs->lock);
24394 ++ real_root_mnt = mntget(reaper->fs->root.mnt);
24395 ++ real_root = dget(reaper->fs->root.dentry);
24396 ++ read_unlock(&reaper->fs->lock);
24397 ++
24398 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
24399 ++ if (fakefs_obj == NULL)
24400 ++ return 1;
24401 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
24402 ++
24403 ++ subj_map_set.s_hash =
24404 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
24405 ++ acl_role_set.r_hash =
24406 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
24407 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
24408 ++ inodev_set.i_hash =
24409 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
24410 ++
24411 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
24412 ++ !name_set.n_hash || !inodev_set.i_hash)
24413 ++ return 1;
24414 ++
24415 ++ memset(subj_map_set.s_hash, 0,
24416 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
24417 ++ memset(acl_role_set.r_hash, 0,
24418 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
24419 ++ memset(name_set.n_hash, 0,
24420 ++ sizeof (struct name_entry *) * name_set.n_size);
24421 ++ memset(inodev_set.i_hash, 0,
24422 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
24423 ++
24424 ++ return 0;
24425 ++}
24426 ++
24427 ++/* free information not needed after startup
24428 ++ currently contains user->kernel pointer mappings for subjects
24429 ++*/
24430 ++
24431 ++static void
24432 ++free_init_variables(void)
24433 ++{
24434 ++ __u32 i;
24435 ++
24436 ++ if (subj_map_set.s_hash) {
24437 ++ for (i = 0; i < subj_map_set.s_size; i++) {
24438 ++ if (subj_map_set.s_hash[i]) {
24439 ++ kfree(subj_map_set.s_hash[i]);
24440 ++ subj_map_set.s_hash[i] = NULL;
24441 ++ }
24442 ++ }
24443 ++
24444 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
24445 ++ PAGE_SIZE)
24446 ++ kfree(subj_map_set.s_hash);
24447 ++ else
24448 ++ vfree(subj_map_set.s_hash);
24449 ++ }
24450 ++
24451 ++ return;
24452 ++}
24453 ++
24454 ++static void
24455 ++free_variables(void)
24456 ++{
24457 ++ struct acl_subject_label *s;
24458 ++ struct acl_role_label *r;
24459 ++ struct task_struct *task, *task2;
24460 ++ unsigned int i, x;
24461 ++
24462 ++ gr_clear_learn_entries();
24463 ++
24464 ++ read_lock(&tasklist_lock);
24465 ++ do_each_thread(task2, task) {
24466 ++ task->acl_sp_role = 0;
24467 ++ task->acl_role_id = 0;
24468 ++ task->acl = NULL;
24469 ++ task->role = NULL;
24470 ++ } while_each_thread(task2, task);
24471 ++ read_unlock(&tasklist_lock);
24472 ++
24473 ++ /* release the reference to the real root dentry and vfsmount */
24474 ++ if (real_root)
24475 ++ dput(real_root);
24476 ++ real_root = NULL;
24477 ++ if (real_root_mnt)
24478 ++ mntput(real_root_mnt);
24479 ++ real_root_mnt = NULL;
24480 ++
24481 ++ /* free all object hash tables */
24482 ++
24483 ++ FOR_EACH_ROLE_START(r, i)
24484 ++ if (r->subj_hash == NULL)
24485 ++ break;
24486 ++ FOR_EACH_SUBJECT_START(r, s, x)
24487 ++ if (s->obj_hash == NULL)
24488 ++ break;
24489 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
24490 ++ kfree(s->obj_hash);
24491 ++ else
24492 ++ vfree(s->obj_hash);
24493 ++ FOR_EACH_SUBJECT_END(s, x)
24494 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
24495 ++ if (s->obj_hash == NULL)
24496 ++ break;
24497 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
24498 ++ kfree(s->obj_hash);
24499 ++ else
24500 ++ vfree(s->obj_hash);
24501 ++ FOR_EACH_NESTED_SUBJECT_END(s)
24502 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
24503 ++ kfree(r->subj_hash);
24504 ++ else
24505 ++ vfree(r->subj_hash);
24506 ++ r->subj_hash = NULL;
24507 ++ FOR_EACH_ROLE_END(r,i)
24508 ++
24509 ++ acl_free_all();
24510 ++
24511 ++ if (acl_role_set.r_hash) {
24512 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
24513 ++ PAGE_SIZE)
24514 ++ kfree(acl_role_set.r_hash);
24515 ++ else
24516 ++ vfree(acl_role_set.r_hash);
24517 ++ }
24518 ++ if (name_set.n_hash) {
24519 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
24520 ++ PAGE_SIZE)
24521 ++ kfree(name_set.n_hash);
24522 ++ else
24523 ++ vfree(name_set.n_hash);
24524 ++ }
24525 ++
24526 ++ if (inodev_set.i_hash) {
24527 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
24528 ++ PAGE_SIZE)
24529 ++ kfree(inodev_set.i_hash);
24530 ++ else
24531 ++ vfree(inodev_set.i_hash);
24532 ++ }
24533 ++
24534 ++ gr_free_uidset();
24535 ++
24536 ++ memset(&name_set, 0, sizeof (struct name_db));
24537 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
24538 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
24539 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
24540 ++
24541 ++ default_role = NULL;
24542 ++
24543 ++ return;
24544 ++}
24545 ++
24546 ++static __u32
24547 ++count_user_objs(struct acl_object_label *userp)
24548 ++{
24549 ++ struct acl_object_label o_tmp;
24550 ++ __u32 num = 0;
24551 ++
24552 ++ while (userp) {
24553 ++ if (copy_from_user(&o_tmp, userp,
24554 ++ sizeof (struct acl_object_label)))
24555 ++ break;
24556 ++
24557 ++ userp = o_tmp.prev;
24558 ++ num++;
24559 ++ }
24560 ++
24561 ++ return num;
24562 ++}
24563 ++
24564 ++static struct acl_subject_label *
24565 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
24566 ++
24567 ++static int
24568 ++copy_user_glob(struct acl_object_label *obj)
24569 ++{
24570 ++ struct acl_object_label *g_tmp, **guser;
24571 ++ unsigned int len;
24572 ++ char *tmp;
24573 ++
24574 ++ if (obj->globbed == NULL)
24575 ++ return 0;
24576 ++
24577 ++ guser = &obj->globbed;
24578 ++ while (*guser) {
24579 ++ g_tmp = (struct acl_object_label *)
24580 ++ acl_alloc(sizeof (struct acl_object_label));
24581 ++ if (g_tmp == NULL)
24582 ++ return -ENOMEM;
24583 ++
24584 ++ if (copy_from_user(g_tmp, *guser,
24585 ++ sizeof (struct acl_object_label)))
24586 ++ return -EFAULT;
24587 ++
24588 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
24589 ++
24590 ++ if (!len || len >= PATH_MAX)
24591 ++ return -EINVAL;
24592 ++
24593 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24594 ++ return -ENOMEM;
24595 ++
24596 ++ if (copy_from_user(tmp, g_tmp->filename, len))
24597 ++ return -EFAULT;
24598 ++
24599 ++ g_tmp->filename = tmp;
24600 ++
24601 ++ *guser = g_tmp;
24602 ++ guser = &(g_tmp->next);
24603 ++ }
24604 ++
24605 ++ return 0;
24606 ++}
24607 ++
24608 ++static int
24609 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
24610 ++ struct acl_role_label *role)
24611 ++{
24612 ++ struct acl_object_label *o_tmp;
24613 ++ unsigned int len;
24614 ++ int ret;
24615 ++ char *tmp;
24616 ++
24617 ++ while (userp) {
24618 ++ if ((o_tmp = (struct acl_object_label *)
24619 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
24620 ++ return -ENOMEM;
24621 ++
24622 ++ if (copy_from_user(o_tmp, userp,
24623 ++ sizeof (struct acl_object_label)))
24624 ++ return -EFAULT;
24625 ++
24626 ++ userp = o_tmp->prev;
24627 ++
24628 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
24629 ++
24630 ++ if (!len || len >= PATH_MAX)
24631 ++ return -EINVAL;
24632 ++
24633 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24634 ++ return -ENOMEM;
24635 ++
24636 ++ if (copy_from_user(tmp, o_tmp->filename, len))
24637 ++ return -EFAULT;
24638 ++
24639 ++ o_tmp->filename = tmp;
24640 ++
24641 ++ insert_acl_obj_label(o_tmp, subj);
24642 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
24643 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
24644 ++ return -ENOMEM;
24645 ++
24646 ++ ret = copy_user_glob(o_tmp);
24647 ++ if (ret)
24648 ++ return ret;
24649 ++
24650 ++ if (o_tmp->nested) {
24651 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
24652 ++ if (IS_ERR(o_tmp->nested))
24653 ++ return PTR_ERR(o_tmp->nested);
24654 ++
24655 ++ /* insert into nested subject list */
24656 ++ o_tmp->nested->next = role->hash->first;
24657 ++ role->hash->first = o_tmp->nested;
24658 ++ }
24659 ++ }
24660 ++
24661 ++ return 0;
24662 ++}
24663 ++
24664 ++static __u32
24665 ++count_user_subjs(struct acl_subject_label *userp)
24666 ++{
24667 ++ struct acl_subject_label s_tmp;
24668 ++ __u32 num = 0;
24669 ++
24670 ++ while (userp) {
24671 ++ if (copy_from_user(&s_tmp, userp,
24672 ++ sizeof (struct acl_subject_label)))
24673 ++ break;
24674 ++
24675 ++ userp = s_tmp.prev;
24676 ++ /* do not count nested subjects against this count, since
24677 ++ they are not included in the hash table, but are
24678 ++ attached to objects. We have already counted
24679 ++ the subjects in userspace for the allocation
24680 ++ stack
24681 ++ */
24682 ++ if (!(s_tmp.mode & GR_NESTED))
24683 ++ num++;
24684 ++ }
24685 ++
24686 ++ return num;
24687 ++}
24688 ++
24689 ++static int
24690 ++copy_user_allowedips(struct acl_role_label *rolep)
24691 ++{
24692 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
24693 ++
24694 ++ ruserip = rolep->allowed_ips;
24695 ++
24696 ++ while (ruserip) {
24697 ++ rlast = rtmp;
24698 ++
24699 ++ if ((rtmp = (struct role_allowed_ip *)
24700 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
24701 ++ return -ENOMEM;
24702 ++
24703 ++ if (copy_from_user(rtmp, ruserip,
24704 ++ sizeof (struct role_allowed_ip)))
24705 ++ return -EFAULT;
24706 ++
24707 ++ ruserip = rtmp->prev;
24708 ++
24709 ++ if (!rlast) {
24710 ++ rtmp->prev = NULL;
24711 ++ rolep->allowed_ips = rtmp;
24712 ++ } else {
24713 ++ rlast->next = rtmp;
24714 ++ rtmp->prev = rlast;
24715 ++ }
24716 ++
24717 ++ if (!ruserip)
24718 ++ rtmp->next = NULL;
24719 ++ }
24720 ++
24721 ++ return 0;
24722 ++}
24723 ++
24724 ++static int
24725 ++copy_user_transitions(struct acl_role_label *rolep)
24726 ++{
24727 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
24728 ++
24729 ++ unsigned int len;
24730 ++ char *tmp;
24731 ++
24732 ++ rusertp = rolep->transitions;
24733 ++
24734 ++ while (rusertp) {
24735 ++ rlast = rtmp;
24736 ++
24737 ++ if ((rtmp = (struct role_transition *)
24738 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
24739 ++ return -ENOMEM;
24740 ++
24741 ++ if (copy_from_user(rtmp, rusertp,
24742 ++ sizeof (struct role_transition)))
24743 ++ return -EFAULT;
24744 ++
24745 ++ rusertp = rtmp->prev;
24746 ++
24747 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
24748 ++
24749 ++ if (!len || len >= GR_SPROLE_LEN)
24750 ++ return -EINVAL;
24751 ++
24752 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24753 ++ return -ENOMEM;
24754 ++
24755 ++ if (copy_from_user(tmp, rtmp->rolename, len))
24756 ++ return -EFAULT;
24757 ++
24758 ++ rtmp->rolename = tmp;
24759 ++
24760 ++ if (!rlast) {
24761 ++ rtmp->prev = NULL;
24762 ++ rolep->transitions = rtmp;
24763 ++ } else {
24764 ++ rlast->next = rtmp;
24765 ++ rtmp->prev = rlast;
24766 ++ }
24767 ++
24768 ++ if (!rusertp)
24769 ++ rtmp->next = NULL;
24770 ++ }
24771 ++
24772 ++ return 0;
24773 ++}
24774 ++
24775 ++static struct acl_subject_label *
24776 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
24777 ++{
24778 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
24779 ++ unsigned int len;
24780 ++ char *tmp;
24781 ++ __u32 num_objs;
24782 ++ struct acl_ip_label **i_tmp, *i_utmp2;
24783 ++ struct gr_hash_struct ghash;
24784 ++ struct subject_map *subjmap;
24785 ++ unsigned int i_num;
24786 ++ int err;
24787 ++
24788 ++ s_tmp = lookup_subject_map(userp);
24789 ++
24790 ++ /* we've already copied this subject into the kernel, just return
24791 ++ the reference to it, and don't copy it over again
24792 ++ */
24793 ++ if (s_tmp)
24794 ++ return(s_tmp);
24795 ++
24796 ++ if ((s_tmp = (struct acl_subject_label *)
24797 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
24798 ++ return ERR_PTR(-ENOMEM);
24799 ++
24800 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
24801 ++ if (subjmap == NULL)
24802 ++ return ERR_PTR(-ENOMEM);
24803 ++
24804 ++ subjmap->user = userp;
24805 ++ subjmap->kernel = s_tmp;
24806 ++ insert_subj_map_entry(subjmap);
24807 ++
24808 ++ if (copy_from_user(s_tmp, userp,
24809 ++ sizeof (struct acl_subject_label)))
24810 ++ return ERR_PTR(-EFAULT);
24811 ++
24812 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
24813 ++
24814 ++ if (!len || len >= PATH_MAX)
24815 ++ return ERR_PTR(-EINVAL);
24816 ++
24817 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24818 ++ return ERR_PTR(-ENOMEM);
24819 ++
24820 ++ if (copy_from_user(tmp, s_tmp->filename, len))
24821 ++ return ERR_PTR(-EFAULT);
24822 ++
24823 ++ s_tmp->filename = tmp;
24824 ++
24825 ++ if (!strcmp(s_tmp->filename, "/"))
24826 ++ role->root_label = s_tmp;
24827 ++
24828 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
24829 ++ return ERR_PTR(-EFAULT);
24830 ++
24831 ++ /* copy user and group transition tables */
24832 ++
24833 ++ if (s_tmp->user_trans_num) {
24834 ++ uid_t *uidlist;
24835 ++
24836 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
24837 ++ if (uidlist == NULL)
24838 ++ return ERR_PTR(-ENOMEM);
24839 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
24840 ++ return ERR_PTR(-EFAULT);
24841 ++
24842 ++ s_tmp->user_transitions = uidlist;
24843 ++ }
24844 ++
24845 ++ if (s_tmp->group_trans_num) {
24846 ++ gid_t *gidlist;
24847 ++
24848 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
24849 ++ if (gidlist == NULL)
24850 ++ return ERR_PTR(-ENOMEM);
24851 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
24852 ++ return ERR_PTR(-EFAULT);
24853 ++
24854 ++ s_tmp->group_transitions = gidlist;
24855 ++ }
24856 ++
24857 ++ /* set up object hash table */
24858 ++ num_objs = count_user_objs(ghash.first);
24859 ++
24860 ++ s_tmp->obj_hash_size = num_objs;
24861 ++ s_tmp->obj_hash =
24862 ++ (struct acl_object_label **)
24863 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
24864 ++
24865 ++ if (!s_tmp->obj_hash)
24866 ++ return ERR_PTR(-ENOMEM);
24867 ++
24868 ++ memset(s_tmp->obj_hash, 0,
24869 ++ s_tmp->obj_hash_size *
24870 ++ sizeof (struct acl_object_label *));
24871 ++
24872 ++ /* add in objects */
24873 ++ err = copy_user_objs(ghash.first, s_tmp, role);
24874 ++
24875 ++ if (err)
24876 ++ return ERR_PTR(err);
24877 ++
24878 ++ /* set pointer for parent subject */
24879 ++ if (s_tmp->parent_subject) {
24880 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
24881 ++
24882 ++ if (IS_ERR(s_tmp2))
24883 ++ return s_tmp2;
24884 ++
24885 ++ s_tmp->parent_subject = s_tmp2;
24886 ++ }
24887 ++
24888 ++ /* add in ip acls */
24889 ++
24890 ++ if (!s_tmp->ip_num) {
24891 ++ s_tmp->ips = NULL;
24892 ++ goto insert;
24893 ++ }
24894 ++
24895 ++ i_tmp =
24896 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
24897 ++ sizeof (struct
24898 ++ acl_ip_label *));
24899 ++
24900 ++ if (!i_tmp)
24901 ++ return ERR_PTR(-ENOMEM);
24902 ++
24903 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
24904 ++ *(i_tmp + i_num) =
24905 ++ (struct acl_ip_label *)
24906 ++ acl_alloc(sizeof (struct acl_ip_label));
24907 ++ if (!*(i_tmp + i_num))
24908 ++ return ERR_PTR(-ENOMEM);
24909 ++
24910 ++ if (copy_from_user
24911 ++ (&i_utmp2, s_tmp->ips + i_num,
24912 ++ sizeof (struct acl_ip_label *)))
24913 ++ return ERR_PTR(-EFAULT);
24914 ++
24915 ++ if (copy_from_user
24916 ++ (*(i_tmp + i_num), i_utmp2,
24917 ++ sizeof (struct acl_ip_label)))
24918 ++ return ERR_PTR(-EFAULT);
24919 ++
24920 ++ if ((*(i_tmp + i_num))->iface == NULL)
24921 ++ continue;
24922 ++
24923 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
24924 ++ if (!len || len >= IFNAMSIZ)
24925 ++ return ERR_PTR(-EINVAL);
24926 ++ tmp = acl_alloc(len);
24927 ++ if (tmp == NULL)
24928 ++ return ERR_PTR(-ENOMEM);
24929 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
24930 ++ return ERR_PTR(-EFAULT);
24931 ++ (*(i_tmp + i_num))->iface = tmp;
24932 ++ }
24933 ++
24934 ++ s_tmp->ips = i_tmp;
24935 ++
24936 ++insert:
24937 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
24938 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
24939 ++ return ERR_PTR(-ENOMEM);
24940 ++
24941 ++ return s_tmp;
24942 ++}
24943 ++
24944 ++static int
24945 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
24946 ++{
24947 ++ struct acl_subject_label s_pre;
24948 ++ struct acl_subject_label * ret;
24949 ++ int err;
24950 ++
24951 ++ while (userp) {
24952 ++ if (copy_from_user(&s_pre, userp,
24953 ++ sizeof (struct acl_subject_label)))
24954 ++ return -EFAULT;
24955 ++
24956 ++ /* do not add nested subjects here, add
24957 ++ while parsing objects
24958 ++ */
24959 ++
24960 ++ if (s_pre.mode & GR_NESTED) {
24961 ++ userp = s_pre.prev;
24962 ++ continue;
24963 ++ }
24964 ++
24965 ++ ret = do_copy_user_subj(userp, role);
24966 ++
24967 ++ err = PTR_ERR(ret);
24968 ++ if (IS_ERR(ret))
24969 ++ return err;
24970 ++
24971 ++ insert_acl_subj_label(ret, role);
24972 ++
24973 ++ userp = s_pre.prev;
24974 ++ }
24975 ++
24976 ++ return 0;
24977 ++}
24978 ++
24979 ++static int
24980 ++copy_user_acl(struct gr_arg *arg)
24981 ++{
24982 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
24983 ++ struct sprole_pw *sptmp;
24984 ++ struct gr_hash_struct *ghash;
24985 ++ uid_t *domainlist;
24986 ++ unsigned int r_num;
24987 ++ unsigned int len;
24988 ++ char *tmp;
24989 ++ int err = 0;
24990 ++ __u16 i;
24991 ++ __u32 num_subjs;
24992 ++
24993 ++ /* we need a default and kernel role */
24994 ++ if (arg->role_db.num_roles < 2)
24995 ++ return -EINVAL;
24996 ++
24997 ++ /* copy special role authentication info from userspace */
24998 ++
24999 ++ num_sprole_pws = arg->num_sprole_pws;
25000 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
25001 ++
25002 ++ if (!acl_special_roles) {
25003 ++ err = -ENOMEM;
25004 ++ goto cleanup;
25005 ++ }
25006 ++
25007 ++ for (i = 0; i < num_sprole_pws; i++) {
25008 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
25009 ++ if (!sptmp) {
25010 ++ err = -ENOMEM;
25011 ++ goto cleanup;
25012 ++ }
25013 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
25014 ++ sizeof (struct sprole_pw))) {
25015 ++ err = -EFAULT;
25016 ++ goto cleanup;
25017 ++ }
25018 ++
25019 ++ len =
25020 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
25021 ++
25022 ++ if (!len || len >= GR_SPROLE_LEN) {
25023 ++ err = -EINVAL;
25024 ++ goto cleanup;
25025 ++ }
25026 ++
25027 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
25028 ++ err = -ENOMEM;
25029 ++ goto cleanup;
25030 ++ }
25031 ++
25032 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
25033 ++ err = -EFAULT;
25034 ++ goto cleanup;
25035 ++ }
25036 ++
25037 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25038 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
25039 ++#endif
25040 ++ sptmp->rolename = tmp;
25041 ++ acl_special_roles[i] = sptmp;
25042 ++ }
25043 ++
25044 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
25045 ++
25046 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
25047 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
25048 ++
25049 ++ if (!r_tmp) {
25050 ++ err = -ENOMEM;
25051 ++ goto cleanup;
25052 ++ }
25053 ++
25054 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
25055 ++ sizeof (struct acl_role_label *))) {
25056 ++ err = -EFAULT;
25057 ++ goto cleanup;
25058 ++ }
25059 ++
25060 ++ if (copy_from_user(r_tmp, r_utmp2,
25061 ++ sizeof (struct acl_role_label))) {
25062 ++ err = -EFAULT;
25063 ++ goto cleanup;
25064 ++ }
25065 ++
25066 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
25067 ++
25068 ++ if (!len || len >= PATH_MAX) {
25069 ++ err = -EINVAL;
25070 ++ goto cleanup;
25071 ++ }
25072 ++
25073 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
25074 ++ err = -ENOMEM;
25075 ++ goto cleanup;
25076 ++ }
25077 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
25078 ++ err = -EFAULT;
25079 ++ goto cleanup;
25080 ++ }
25081 ++ r_tmp->rolename = tmp;
25082 ++
25083 ++ if (!strcmp(r_tmp->rolename, "default")
25084 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
25085 ++ default_role = r_tmp;
25086 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
25087 ++ kernel_role = r_tmp;
25088 ++ }
25089 ++
25090 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
25091 ++ err = -ENOMEM;
25092 ++ goto cleanup;
25093 ++ }
25094 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
25095 ++ err = -EFAULT;
25096 ++ goto cleanup;
25097 ++ }
25098 ++
25099 ++ r_tmp->hash = ghash;
25100 ++
25101 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
25102 ++
25103 ++ r_tmp->subj_hash_size = num_subjs;
25104 ++ r_tmp->subj_hash =
25105 ++ (struct acl_subject_label **)
25106 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
25107 ++
25108 ++ if (!r_tmp->subj_hash) {
25109 ++ err = -ENOMEM;
25110 ++ goto cleanup;
25111 ++ }
25112 ++
25113 ++ err = copy_user_allowedips(r_tmp);
25114 ++ if (err)
25115 ++ goto cleanup;
25116 ++
25117 ++ /* copy domain info */
25118 ++ if (r_tmp->domain_children != NULL) {
25119 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
25120 ++ if (domainlist == NULL) {
25121 ++ err = -ENOMEM;
25122 ++ goto cleanup;
25123 ++ }
25124 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
25125 ++ err = -EFAULT;
25126 ++ goto cleanup;
25127 ++ }
25128 ++ r_tmp->domain_children = domainlist;
25129 ++ }
25130 ++
25131 ++ err = copy_user_transitions(r_tmp);
25132 ++ if (err)
25133 ++ goto cleanup;
25134 ++
25135 ++ memset(r_tmp->subj_hash, 0,
25136 ++ r_tmp->subj_hash_size *
25137 ++ sizeof (struct acl_subject_label *));
25138 ++
25139 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
25140 ++
25141 ++ if (err)
25142 ++ goto cleanup;
25143 ++
25144 ++ /* set nested subject list to null */
25145 ++ r_tmp->hash->first = NULL;
25146 ++
25147 ++ insert_acl_role_label(r_tmp);
25148 ++ }
25149 ++
25150 ++ goto return_err;
25151 ++ cleanup:
25152 ++ free_variables();
25153 ++ return_err:
25154 ++ return err;
25155 ++
25156 ++}
25157 ++
25158 ++static int
25159 ++gracl_init(struct gr_arg *args)
25160 ++{
25161 ++ int error = 0;
25162 ++
25163 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
25164 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
25165 ++
25166 ++ if (init_variables(args)) {
25167 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
25168 ++ error = -ENOMEM;
25169 ++ free_variables();
25170 ++ goto out;
25171 ++ }
25172 ++
25173 ++ error = copy_user_acl(args);
25174 ++ free_init_variables();
25175 ++ if (error) {
25176 ++ free_variables();
25177 ++ goto out;
25178 ++ }
25179 ++
25180 ++ if ((error = gr_set_acls(0))) {
25181 ++ free_variables();
25182 ++ goto out;
25183 ++ }
25184 ++
25185 ++ gr_status |= GR_READY;
25186 ++ out:
25187 ++ return error;
25188 ++}
25189 ++
25190 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
25191 ++
25192 ++static int
25193 ++glob_match(const char *p, const char *n)
25194 ++{
25195 ++ char c;
25196 ++
25197 ++ while ((c = *p++) != '\0') {
25198 ++ switch (c) {
25199 ++ case '?':
25200 ++ if (*n == '\0')
25201 ++ return 1;
25202 ++ else if (*n == '/')
25203 ++ return 1;
25204 ++ break;
25205 ++ case '\\':
25206 ++ if (*n != c)
25207 ++ return 1;
25208 ++ break;
25209 ++ case '*':
25210 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
25211 ++ if (*n == '/')
25212 ++ return 1;
25213 ++ else if (c == '?') {
25214 ++ if (*n == '\0')
25215 ++ return 1;
25216 ++ else
25217 ++ ++n;
25218 ++ }
25219 ++ }
25220 ++ if (c == '\0') {
25221 ++ return 0;
25222 ++ } else {
25223 ++ const char *endp;
25224 ++
25225 ++ if ((endp = strchr(n, '/')) == NULL)
25226 ++ endp = n + strlen(n);
25227 ++
25228 ++ if (c == '[') {
25229 ++ for (--p; n < endp; ++n)
25230 ++ if (!glob_match(p, n))
25231 ++ return 0;
25232 ++ } else if (c == '/') {
25233 ++ while (*n != '\0' && *n != '/')
25234 ++ ++n;
25235 ++ if (*n == '/' && !glob_match(p, n + 1))
25236 ++ return 0;
25237 ++ } else {
25238 ++ for (--p; n < endp; ++n)
25239 ++ if (*n == c && !glob_match(p, n))
25240 ++ return 0;
25241 ++ }
25242 ++
25243 ++ return 1;
25244 ++ }
25245 ++ case '[':
25246 ++ {
25247 ++ int not;
25248 ++ char cold;
25249 ++
25250 ++ if (*n == '\0' || *n == '/')
25251 ++ return 1;
25252 ++
25253 ++ not = (*p == '!' || *p == '^');
25254 ++ if (not)
25255 ++ ++p;
25256 ++
25257 ++ c = *p++;
25258 ++ for (;;) {
25259 ++ unsigned char fn = (unsigned char)*n;
25260 ++
25261 ++ if (c == '\0')
25262 ++ return 1;
25263 ++ else {
25264 ++ if (c == fn)
25265 ++ goto matched;
25266 ++ cold = c;
25267 ++ c = *p++;
25268 ++
25269 ++ if (c == '-' && *p != ']') {
25270 ++ unsigned char cend = *p++;
25271 ++
25272 ++ if (cend == '\0')
25273 ++ return 1;
25274 ++
25275 ++ if (cold <= fn && fn <= cend)
25276 ++ goto matched;
25277 ++
25278 ++ c = *p++;
25279 ++ }
25280 ++ }
25281 ++
25282 ++ if (c == ']')
25283 ++ break;
25284 ++ }
25285 ++ if (!not)
25286 ++ return 1;
25287 ++ break;
25288 ++ matched:
25289 ++ while (c != ']') {
25290 ++ if (c == '\0')
25291 ++ return 1;
25292 ++
25293 ++ c = *p++;
25294 ++ }
25295 ++ if (not)
25296 ++ return 1;
25297 ++ }
25298 ++ break;
25299 ++ default:
25300 ++ if (c != *n)
25301 ++ return 1;
25302 ++ }
25303 ++
25304 ++ ++n;
25305 ++ }
25306 ++
25307 ++ if (*n == '\0')
25308 ++ return 0;
25309 ++
25310 ++ if (*n == '/')
25311 ++ return 0;
25312 ++
25313 ++ return 1;
25314 ++}
25315 ++
25316 ++static struct acl_object_label *
25317 ++chk_glob_label(struct acl_object_label *globbed,
25318 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
25319 ++{
25320 ++ struct acl_object_label *tmp;
25321 ++
25322 ++ if (*path == NULL)
25323 ++ *path = gr_to_filename_nolock(dentry, mnt);
25324 ++
25325 ++ tmp = globbed;
25326 ++
25327 ++ while (tmp) {
25328 ++ if (!glob_match(tmp->filename, *path))
25329 ++ return tmp;
25330 ++ tmp = tmp->next;
25331 ++ }
25332 ++
25333 ++ return NULL;
25334 ++}
25335 ++
25336 ++static struct acl_object_label *
25337 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
25338 ++ const ino_t curr_ino, const dev_t curr_dev,
25339 ++ const struct acl_subject_label *subj, char **path)
25340 ++{
25341 ++ struct acl_subject_label *tmpsubj;
25342 ++ struct acl_object_label *retval;
25343 ++ struct acl_object_label *retval2;
25344 ++
25345 ++ tmpsubj = (struct acl_subject_label *) subj;
25346 ++ read_lock(&gr_inode_lock);
25347 ++ do {
25348 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
25349 ++ if (retval) {
25350 ++ if (retval->globbed) {
25351 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
25352 ++ (struct vfsmount *)orig_mnt, path);
25353 ++ if (retval2)
25354 ++ retval = retval2;
25355 ++ }
25356 ++ break;
25357 ++ }
25358 ++ } while ((tmpsubj = tmpsubj->parent_subject));
25359 ++ read_unlock(&gr_inode_lock);
25360 ++
25361 ++ return retval;
25362 ++}
25363 ++
25364 ++static __inline__ struct acl_object_label *
25365 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
25366 ++ const struct dentry *curr_dentry,
25367 ++ const struct acl_subject_label *subj, char **path)
25368 ++{
25369 ++ return __full_lookup(orig_dentry, orig_mnt,
25370 ++ curr_dentry->d_inode->i_ino,
25371 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
25372 ++}
25373 ++
25374 ++static struct acl_object_label *
25375 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25376 ++ const struct acl_subject_label *subj, char *path)
25377 ++{
25378 ++ struct dentry *dentry = (struct dentry *) l_dentry;
25379 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
25380 ++ struct acl_object_label *retval;
25381 ++
25382 ++ spin_lock(&dcache_lock);
25383 ++
25384 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
25385 ++ /* ignore Eric Biederman */
25386 ++ IS_PRIVATE(l_dentry->d_inode))) {
25387 ++ retval = fakefs_obj;
25388 ++ goto out;
25389 ++ }
25390 ++
25391 ++ for (;;) {
25392 ++ if (dentry == real_root && mnt == real_root_mnt)
25393 ++ break;
25394 ++
25395 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
25396 ++ if (mnt->mnt_parent == mnt)
25397 ++ break;
25398 ++
25399 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25400 ++ if (retval != NULL)
25401 ++ goto out;
25402 ++
25403 ++ dentry = mnt->mnt_mountpoint;
25404 ++ mnt = mnt->mnt_parent;
25405 ++ continue;
25406 ++ }
25407 ++
25408 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25409 ++ if (retval != NULL)
25410 ++ goto out;
25411 ++
25412 ++ dentry = dentry->d_parent;
25413 ++ }
25414 ++
25415 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25416 ++
25417 ++ if (retval == NULL)
25418 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
25419 ++out:
25420 ++ spin_unlock(&dcache_lock);
25421 ++ return retval;
25422 ++}
25423 ++
25424 ++static __inline__ struct acl_object_label *
25425 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25426 ++ const struct acl_subject_label *subj)
25427 ++{
25428 ++ char *path = NULL;
25429 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
25430 ++}
25431 ++
25432 ++static __inline__ struct acl_object_label *
25433 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25434 ++ const struct acl_subject_label *subj, char *path)
25435 ++{
25436 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
25437 ++}
25438 ++
25439 ++static struct acl_subject_label *
25440 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25441 ++ const struct acl_role_label *role)
25442 ++{
25443 ++ struct dentry *dentry = (struct dentry *) l_dentry;
25444 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
25445 ++ struct acl_subject_label *retval;
25446 ++
25447 ++ spin_lock(&dcache_lock);
25448 ++
25449 ++ for (;;) {
25450 ++ if (dentry == real_root && mnt == real_root_mnt)
25451 ++ break;
25452 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
25453 ++ if (mnt->mnt_parent == mnt)
25454 ++ break;
25455 ++
25456 ++ read_lock(&gr_inode_lock);
25457 ++ retval =
25458 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
25459 ++ dentry->d_inode->i_sb->s_dev, role);
25460 ++ read_unlock(&gr_inode_lock);
25461 ++ if (retval != NULL)
25462 ++ goto out;
25463 ++
25464 ++ dentry = mnt->mnt_mountpoint;
25465 ++ mnt = mnt->mnt_parent;
25466 ++ continue;
25467 ++ }
25468 ++
25469 ++ read_lock(&gr_inode_lock);
25470 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
25471 ++ dentry->d_inode->i_sb->s_dev, role);
25472 ++ read_unlock(&gr_inode_lock);
25473 ++ if (retval != NULL)
25474 ++ goto out;
25475 ++
25476 ++ dentry = dentry->d_parent;
25477 ++ }
25478 ++
25479 ++ read_lock(&gr_inode_lock);
25480 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
25481 ++ dentry->d_inode->i_sb->s_dev, role);
25482 ++ read_unlock(&gr_inode_lock);
25483 ++
25484 ++ if (unlikely(retval == NULL)) {
25485 ++ read_lock(&gr_inode_lock);
25486 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
25487 ++ real_root->d_inode->i_sb->s_dev, role);
25488 ++ read_unlock(&gr_inode_lock);
25489 ++ }
25490 ++out:
25491 ++ spin_unlock(&dcache_lock);
25492 ++
25493 ++ return retval;
25494 ++}
25495 ++
25496 ++static void
25497 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
25498 ++{
25499 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
25500 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
25501 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
25502 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
25503 ++
25504 ++ return;
25505 ++}
25506 ++
25507 ++static void
25508 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
25509 ++{
25510 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
25511 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
25512 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
25513 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
25514 ++
25515 ++ return;
25516 ++}
25517 ++
25518 ++static void
25519 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
25520 ++ const unsigned int effective, const unsigned int fs)
25521 ++{
25522 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
25523 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
25524 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
25525 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
25526 ++
25527 ++ return;
25528 ++}
25529 ++
25530 ++__u32
25531 ++gr_check_link(const struct dentry * new_dentry,
25532 ++ const struct dentry * parent_dentry,
25533 ++ const struct vfsmount * parent_mnt,
25534 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
25535 ++{
25536 ++ struct acl_object_label *obj;
25537 ++ __u32 oldmode, newmode;
25538 ++ __u32 needmode;
25539 ++
25540 ++ if (unlikely(!(gr_status & GR_READY)))
25541 ++ return (GR_CREATE | GR_LINK);
25542 ++
25543 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
25544 ++ oldmode = obj->mode;
25545 ++
25546 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25547 ++ oldmode |= (GR_CREATE | GR_LINK);
25548 ++
25549 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
25550 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
25551 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
25552 ++
25553 ++ newmode =
25554 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
25555 ++ oldmode | needmode);
25556 ++
25557 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
25558 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
25559 ++ GR_INHERIT | GR_AUDIT_INHERIT);
25560 ++
25561 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
25562 ++ goto bad;
25563 ++
25564 ++ if ((oldmode & needmode) != needmode)
25565 ++ goto bad;
25566 ++
25567 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
25568 ++ if ((newmode & needmode) != needmode)
25569 ++ goto bad;
25570 ++
25571 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
25572 ++ return newmode;
25573 ++bad:
25574 ++ needmode = oldmode;
25575 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
25576 ++ needmode |= GR_SETID;
25577 ++
25578 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
25579 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
25580 ++ return (GR_CREATE | GR_LINK);
25581 ++ } else if (newmode & GR_SUPPRESS)
25582 ++ return GR_SUPPRESS;
25583 ++ else
25584 ++ return 0;
25585 ++}
25586 ++
25587 ++__u32
25588 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
25589 ++ const struct vfsmount * mnt)
25590 ++{
25591 ++ __u32 retval = mode;
25592 ++ struct acl_subject_label *curracl;
25593 ++ struct acl_object_label *currobj;
25594 ++
25595 ++ if (unlikely(!(gr_status & GR_READY)))
25596 ++ return (mode & ~GR_AUDITS);
25597 ++
25598 ++ curracl = current->acl;
25599 ++
25600 ++ currobj = chk_obj_label(dentry, mnt, curracl);
25601 ++ retval = currobj->mode & mode;
25602 ++
25603 ++ if (unlikely
25604 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
25605 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
25606 ++ __u32 new_mode = mode;
25607 ++
25608 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25609 ++
25610 ++ retval = new_mode;
25611 ++
25612 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
25613 ++ new_mode |= GR_INHERIT;
25614 ++
25615 ++ if (!(mode & GR_NOLEARN))
25616 ++ gr_log_learn(current, dentry, mnt, new_mode);
25617 ++ }
25618 ++
25619 ++ return retval;
25620 ++}
25621 ++
25622 ++__u32
25623 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
25624 ++ const struct vfsmount * mnt, const __u32 mode)
25625 ++{
25626 ++ struct name_entry *match;
25627 ++ struct acl_object_label *matchpo;
25628 ++ struct acl_subject_label *curracl;
25629 ++ char *path;
25630 ++ __u32 retval;
25631 ++
25632 ++ if (unlikely(!(gr_status & GR_READY)))
25633 ++ return (mode & ~GR_AUDITS);
25634 ++
25635 ++ preempt_disable();
25636 ++ path = gr_to_filename_rbac(new_dentry, mnt);
25637 ++ match = lookup_name_entry_create(path);
25638 ++
25639 ++ if (!match)
25640 ++ goto check_parent;
25641 ++
25642 ++ curracl = current->acl;
25643 ++
25644 ++ read_lock(&gr_inode_lock);
25645 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
25646 ++ read_unlock(&gr_inode_lock);
25647 ++
25648 ++ if (matchpo) {
25649 ++ if ((matchpo->mode & mode) !=
25650 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
25651 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
25652 ++ __u32 new_mode = mode;
25653 ++
25654 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25655 ++
25656 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
25657 ++
25658 ++ preempt_enable();
25659 ++ return new_mode;
25660 ++ }
25661 ++ preempt_enable();
25662 ++ return (matchpo->mode & mode);
25663 ++ }
25664 ++
25665 ++ check_parent:
25666 ++ curracl = current->acl;
25667 ++
25668 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
25669 ++ retval = matchpo->mode & mode;
25670 ++
25671 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
25672 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
25673 ++ __u32 new_mode = mode;
25674 ++
25675 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25676 ++
25677 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
25678 ++ preempt_enable();
25679 ++ return new_mode;
25680 ++ }
25681 ++
25682 ++ preempt_enable();
25683 ++ return retval;
25684 ++}
25685 ++
25686 ++int
25687 ++gr_check_hidden_task(const struct task_struct *task)
25688 ++{
25689 ++ if (unlikely(!(gr_status & GR_READY)))
25690 ++ return 0;
25691 ++
25692 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
25693 ++ return 1;
25694 ++
25695 ++ return 0;
25696 ++}
25697 ++
25698 ++int
25699 ++gr_check_protected_task(const struct task_struct *task)
25700 ++{
25701 ++ if (unlikely(!(gr_status & GR_READY) || !task))
25702 ++ return 0;
25703 ++
25704 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
25705 ++ task->acl != current->acl)
25706 ++ return 1;
25707 ++
25708 ++ return 0;
25709 ++}
25710 ++
25711 ++void
25712 ++gr_copy_label(struct task_struct *tsk)
25713 ++{
25714 ++ tsk->signal->used_accept = 0;
25715 ++ tsk->acl_sp_role = 0;
25716 ++ tsk->acl_role_id = current->acl_role_id;
25717 ++ tsk->acl = current->acl;
25718 ++ tsk->role = current->role;
25719 ++ tsk->signal->curr_ip = current->signal->curr_ip;
25720 ++ if (current->exec_file)
25721 ++ get_file(current->exec_file);
25722 ++ tsk->exec_file = current->exec_file;
25723 ++ tsk->is_writable = current->is_writable;
25724 ++ if (unlikely(current->signal->used_accept))
25725 ++ current->signal->curr_ip = 0;
25726 ++
25727 ++ return;
25728 ++}
25729 ++
25730 ++static void
25731 ++gr_set_proc_res(struct task_struct *task)
25732 ++{
25733 ++ struct acl_subject_label *proc;
25734 ++ unsigned short i;
25735 ++
25736 ++ proc = task->acl;
25737 ++
25738 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
25739 ++ return;
25740 ++
25741 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
25742 ++ if (!(proc->resmask & (1 << i)))
25743 ++ continue;
25744 ++
25745 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
25746 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
25747 ++ }
25748 ++
25749 ++ return;
25750 ++}
25751 ++
25752 ++int
25753 ++gr_check_user_change(int real, int effective, int fs)
25754 ++{
25755 ++ unsigned int i;
25756 ++ __u16 num;
25757 ++ uid_t *uidlist;
25758 ++ int curuid;
25759 ++ int realok = 0;
25760 ++ int effectiveok = 0;
25761 ++ int fsok = 0;
25762 ++
25763 ++ if (unlikely(!(gr_status & GR_READY)))
25764 ++ return 0;
25765 ++
25766 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25767 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
25768 ++
25769 ++ num = current->acl->user_trans_num;
25770 ++ uidlist = current->acl->user_transitions;
25771 ++
25772 ++ if (uidlist == NULL)
25773 ++ return 0;
25774 ++
25775 ++ if (real == -1)
25776 ++ realok = 1;
25777 ++ if (effective == -1)
25778 ++ effectiveok = 1;
25779 ++ if (fs == -1)
25780 ++ fsok = 1;
25781 ++
25782 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
25783 ++ for (i = 0; i < num; i++) {
25784 ++ curuid = (int)uidlist[i];
25785 ++ if (real == curuid)
25786 ++ realok = 1;
25787 ++ if (effective == curuid)
25788 ++ effectiveok = 1;
25789 ++ if (fs == curuid)
25790 ++ fsok = 1;
25791 ++ }
25792 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
25793 ++ for (i = 0; i < num; i++) {
25794 ++ curuid = (int)uidlist[i];
25795 ++ if (real == curuid)
25796 ++ break;
25797 ++ if (effective == curuid)
25798 ++ break;
25799 ++ if (fs == curuid)
25800 ++ break;
25801 ++ }
25802 ++ /* not in deny list */
25803 ++ if (i == num) {
25804 ++ realok = 1;
25805 ++ effectiveok = 1;
25806 ++ fsok = 1;
25807 ++ }
25808 ++ }
25809 ++
25810 ++ if (realok && effectiveok && fsok)
25811 ++ return 0;
25812 ++ else {
25813 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
25814 ++ return 1;
25815 ++ }
25816 ++}
25817 ++
25818 ++int
25819 ++gr_check_group_change(int real, int effective, int fs)
25820 ++{
25821 ++ unsigned int i;
25822 ++ __u16 num;
25823 ++ gid_t *gidlist;
25824 ++ int curgid;
25825 ++ int realok = 0;
25826 ++ int effectiveok = 0;
25827 ++ int fsok = 0;
25828 ++
25829 ++ if (unlikely(!(gr_status & GR_READY)))
25830 ++ return 0;
25831 ++
25832 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25833 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
25834 ++
25835 ++ num = current->acl->group_trans_num;
25836 ++ gidlist = current->acl->group_transitions;
25837 ++
25838 ++ if (gidlist == NULL)
25839 ++ return 0;
25840 ++
25841 ++ if (real == -1)
25842 ++ realok = 1;
25843 ++ if (effective == -1)
25844 ++ effectiveok = 1;
25845 ++ if (fs == -1)
25846 ++ fsok = 1;
25847 ++
25848 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
25849 ++ for (i = 0; i < num; i++) {
25850 ++ curgid = (int)gidlist[i];
25851 ++ if (real == curgid)
25852 ++ realok = 1;
25853 ++ if (effective == curgid)
25854 ++ effectiveok = 1;
25855 ++ if (fs == curgid)
25856 ++ fsok = 1;
25857 ++ }
25858 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
25859 ++ for (i = 0; i < num; i++) {
25860 ++ curgid = (int)gidlist[i];
25861 ++ if (real == curgid)
25862 ++ break;
25863 ++ if (effective == curgid)
25864 ++ break;
25865 ++ if (fs == curgid)
25866 ++ break;
25867 ++ }
25868 ++ /* not in deny list */
25869 ++ if (i == num) {
25870 ++ realok = 1;
25871 ++ effectiveok = 1;
25872 ++ fsok = 1;
25873 ++ }
25874 ++ }
25875 ++
25876 ++ if (realok && effectiveok && fsok)
25877 ++ return 0;
25878 ++ else {
25879 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
25880 ++ return 1;
25881 ++ }
25882 ++}
25883 ++
25884 ++void
25885 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
25886 ++{
25887 ++ struct acl_role_label *role = task->role;
25888 ++ struct acl_subject_label *subj = NULL;
25889 ++ struct acl_object_label *obj;
25890 ++ struct file *filp;
25891 ++
25892 ++ if (unlikely(!(gr_status & GR_READY)))
25893 ++ return;
25894 ++
25895 ++ filp = task->exec_file;
25896 ++
25897 ++ /* kernel process, we'll give them the kernel role */
25898 ++ if (unlikely(!filp)) {
25899 ++ task->role = kernel_role;
25900 ++ task->acl = kernel_role->root_label;
25901 ++ return;
25902 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
25903 ++ role = lookup_acl_role_label(task, uid, gid);
25904 ++
25905 ++ /* perform subject lookup in possibly new role
25906 ++ we can use this result below in the case where role == task->role
25907 ++ */
25908 ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
25909 ++
25910 ++ /* if we changed uid/gid, but result in the same role
25911 ++ and are using inheritance, don't lose the inherited subject
25912 ++ if current subject is other than what normal lookup
25913 ++ would result in, we arrived via inheritance, don't
25914 ++ lose subject
25915 ++ */
25916 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
25917 ++ (subj == task->acl)))
25918 ++ task->acl = subj;
25919 ++
25920 ++ task->role = role;
25921 ++
25922 ++ task->is_writable = 0;
25923 ++
25924 ++ /* ignore additional mmap checks for processes that are writable
25925 ++ by the default ACL */
25926 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
25927 ++ if (unlikely(obj->mode & GR_WRITE))
25928 ++ task->is_writable = 1;
25929 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
25930 ++ if (unlikely(obj->mode & GR_WRITE))
25931 ++ task->is_writable = 1;
25932 ++
25933 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25934 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
25935 ++#endif
25936 ++
25937 ++ gr_set_proc_res(task);
25938 ++
25939 ++ return;
25940 ++}
25941 ++
25942 ++int
25943 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
25944 ++{
25945 ++ struct task_struct *task = current;
25946 ++ struct acl_subject_label *newacl;
25947 ++ struct acl_object_label *obj;
25948 ++ __u32 retmode;
25949 ++
25950 ++ if (unlikely(!(gr_status & GR_READY)))
25951 ++ return 0;
25952 ++
25953 ++ newacl = chk_subj_label(dentry, mnt, task->role);
25954 ++
25955 ++ task_lock(task);
25956 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
25957 ++ GR_POVERRIDE) && (task->acl != newacl) &&
25958 ++ !(task->role->roletype & GR_ROLE_GOD) &&
25959 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
25960 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
25961 ++ (atomic_read(&task->fs->count) > 1 ||
25962 ++ atomic_read(&task->files->count) > 1 ||
25963 ++ atomic_read(&task->sighand->count) > 1)) {
25964 ++ task_unlock(task);
25965 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
25966 ++ return -EACCES;
25967 ++ }
25968 ++ task_unlock(task);
25969 ++
25970 ++ obj = chk_obj_label(dentry, mnt, task->acl);
25971 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
25972 ++
25973 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
25974 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
25975 ++ if (obj->nested)
25976 ++ task->acl = obj->nested;
25977 ++ else
25978 ++ task->acl = newacl;
25979 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
25980 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
25981 ++
25982 ++ task->is_writable = 0;
25983 ++
25984 ++ /* ignore additional mmap checks for processes that are writable
25985 ++ by the default ACL */
25986 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
25987 ++ if (unlikely(obj->mode & GR_WRITE))
25988 ++ task->is_writable = 1;
25989 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
25990 ++ if (unlikely(obj->mode & GR_WRITE))
25991 ++ task->is_writable = 1;
25992 ++
25993 ++ gr_set_proc_res(task);
25994 ++
25995 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25996 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
25997 ++#endif
25998 ++ return 0;
25999 ++}
26000 ++
26001 ++/* always called with valid inodev ptr */
26002 ++static void
26003 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
26004 ++{
26005 ++ struct acl_object_label *matchpo;
26006 ++ struct acl_subject_label *matchps;
26007 ++ struct acl_subject_label *subj;
26008 ++ struct acl_role_label *role;
26009 ++ unsigned int i, x;
26010 ++
26011 ++ FOR_EACH_ROLE_START(role, i)
26012 ++ FOR_EACH_SUBJECT_START(role, subj, x)
26013 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
26014 ++ matchpo->mode |= GR_DELETED;
26015 ++ FOR_EACH_SUBJECT_END(subj,x)
26016 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
26017 ++ if (subj->inode == ino && subj->device == dev)
26018 ++ subj->mode |= GR_DELETED;
26019 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
26020 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
26021 ++ matchps->mode |= GR_DELETED;
26022 ++ FOR_EACH_ROLE_END(role,i)
26023 ++
26024 ++ inodev->nentry->deleted = 1;
26025 ++
26026 ++ return;
26027 ++}
26028 ++
26029 ++void
26030 ++gr_handle_delete(const ino_t ino, const dev_t dev)
26031 ++{
26032 ++ struct inodev_entry *inodev;
26033 ++
26034 ++ if (unlikely(!(gr_status & GR_READY)))
26035 ++ return;
26036 ++
26037 ++ write_lock(&gr_inode_lock);
26038 ++ inodev = lookup_inodev_entry(ino, dev);
26039 ++ if (inodev != NULL)
26040 ++ do_handle_delete(inodev, ino, dev);
26041 ++ write_unlock(&gr_inode_lock);
26042 ++
26043 ++ return;
26044 ++}
26045 ++
26046 ++static void
26047 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
26048 ++ const ino_t newinode, const dev_t newdevice,
26049 ++ struct acl_subject_label *subj)
26050 ++{
26051 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
26052 ++ struct acl_object_label *match;
26053 ++
26054 ++ match = subj->obj_hash[index];
26055 ++
26056 ++ while (match && (match->inode != oldinode ||
26057 ++ match->device != olddevice ||
26058 ++ !(match->mode & GR_DELETED)))
26059 ++ match = match->next;
26060 ++
26061 ++ if (match && (match->inode == oldinode)
26062 ++ && (match->device == olddevice)
26063 ++ && (match->mode & GR_DELETED)) {
26064 ++ if (match->prev == NULL) {
26065 ++ subj->obj_hash[index] = match->next;
26066 ++ if (match->next != NULL)
26067 ++ match->next->prev = NULL;
26068 ++ } else {
26069 ++ match->prev->next = match->next;
26070 ++ if (match->next != NULL)
26071 ++ match->next->prev = match->prev;
26072 ++ }
26073 ++ match->prev = NULL;
26074 ++ match->next = NULL;
26075 ++ match->inode = newinode;
26076 ++ match->device = newdevice;
26077 ++ match->mode &= ~GR_DELETED;
26078 ++
26079 ++ insert_acl_obj_label(match, subj);
26080 ++ }
26081 ++
26082 ++ return;
26083 ++}
26084 ++
26085 ++static void
26086 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
26087 ++ const ino_t newinode, const dev_t newdevice,
26088 ++ struct acl_role_label *role)
26089 ++{
26090 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
26091 ++ struct acl_subject_label *match;
26092 ++
26093 ++ match = role->subj_hash[index];
26094 ++
26095 ++ while (match && (match->inode != oldinode ||
26096 ++ match->device != olddevice ||
26097 ++ !(match->mode & GR_DELETED)))
26098 ++ match = match->next;
26099 ++
26100 ++ if (match && (match->inode == oldinode)
26101 ++ && (match->device == olddevice)
26102 ++ && (match->mode & GR_DELETED)) {
26103 ++ if (match->prev == NULL) {
26104 ++ role->subj_hash[index] = match->next;
26105 ++ if (match->next != NULL)
26106 ++ match->next->prev = NULL;
26107 ++ } else {
26108 ++ match->prev->next = match->next;
26109 ++ if (match->next != NULL)
26110 ++ match->next->prev = match->prev;
26111 ++ }
26112 ++ match->prev = NULL;
26113 ++ match->next = NULL;
26114 ++ match->inode = newinode;
26115 ++ match->device = newdevice;
26116 ++ match->mode &= ~GR_DELETED;
26117 ++
26118 ++ insert_acl_subj_label(match, role);
26119 ++ }
26120 ++
26121 ++ return;
26122 ++}
26123 ++
26124 ++static void
26125 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
26126 ++ const ino_t newinode, const dev_t newdevice)
26127 ++{
26128 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
26129 ++ struct inodev_entry *match;
26130 ++
26131 ++ match = inodev_set.i_hash[index];
26132 ++
26133 ++ while (match && (match->nentry->inode != oldinode ||
26134 ++ match->nentry->device != olddevice || !match->nentry->deleted))
26135 ++ match = match->next;
26136 ++
26137 ++ if (match && (match->nentry->inode == oldinode)
26138 ++ && (match->nentry->device == olddevice) &&
26139 ++ match->nentry->deleted) {
26140 ++ if (match->prev == NULL) {
26141 ++ inodev_set.i_hash[index] = match->next;
26142 ++ if (match->next != NULL)
26143 ++ match->next->prev = NULL;
26144 ++ } else {
26145 ++ match->prev->next = match->next;
26146 ++ if (match->next != NULL)
26147 ++ match->next->prev = match->prev;
26148 ++ }
26149 ++ match->prev = NULL;
26150 ++ match->next = NULL;
26151 ++ match->nentry->inode = newinode;
26152 ++ match->nentry->device = newdevice;
26153 ++ match->nentry->deleted = 0;
26154 ++
26155 ++ insert_inodev_entry(match);
26156 ++ }
26157 ++
26158 ++ return;
26159 ++}
26160 ++
26161 ++static void
26162 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
26163 ++ const struct vfsmount *mnt)
26164 ++{
26165 ++ struct acl_subject_label *subj;
26166 ++ struct acl_role_label *role;
26167 ++ unsigned int i, x;
26168 ++
26169 ++ FOR_EACH_ROLE_START(role, i)
26170 ++ update_acl_subj_label(matchn->inode, matchn->device,
26171 ++ dentry->d_inode->i_ino,
26172 ++ dentry->d_inode->i_sb->s_dev, role);
26173 ++
26174 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
26175 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
26176 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
26177 ++ subj->inode = dentry->d_inode->i_ino;
26178 ++ subj->device = dentry->d_inode->i_sb->s_dev;
26179 ++ }
26180 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
26181 ++ FOR_EACH_SUBJECT_START(role, subj, x)
26182 ++ update_acl_obj_label(matchn->inode, matchn->device,
26183 ++ dentry->d_inode->i_ino,
26184 ++ dentry->d_inode->i_sb->s_dev, subj);
26185 ++ FOR_EACH_SUBJECT_END(subj,x)
26186 ++ FOR_EACH_ROLE_END(role,i)
26187 ++
26188 ++ update_inodev_entry(matchn->inode, matchn->device,
26189 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
26190 ++
26191 ++ return;
26192 ++}
26193 ++
26194 ++void
26195 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
26196 ++{
26197 ++ struct name_entry *matchn;
26198 ++
26199 ++ if (unlikely(!(gr_status & GR_READY)))
26200 ++ return;
26201 ++
26202 ++ preempt_disable();
26203 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
26204 ++
26205 ++ if (unlikely((unsigned long)matchn)) {
26206 ++ write_lock(&gr_inode_lock);
26207 ++ do_handle_create(matchn, dentry, mnt);
26208 ++ write_unlock(&gr_inode_lock);
26209 ++ }
26210 ++ preempt_enable();
26211 ++
26212 ++ return;
26213 ++}
26214 ++
26215 ++void
26216 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26217 ++ struct dentry *old_dentry,
26218 ++ struct dentry *new_dentry,
26219 ++ struct vfsmount *mnt, const __u8 replace)
26220 ++{
26221 ++ struct name_entry *matchn;
26222 ++ struct inodev_entry *inodev;
26223 ++
26224 ++ /* vfs_rename swaps the name and parent link for old_dentry and
26225 ++ new_dentry
26226 ++ at this point, old_dentry has the new name, parent link, and inode
26227 ++ for the renamed file
26228 ++ if a file is being replaced by a rename, new_dentry has the inode
26229 ++ and name for the replaced file
26230 ++ */
26231 ++
26232 ++ if (unlikely(!(gr_status & GR_READY)))
26233 ++ return;
26234 ++
26235 ++ preempt_disable();
26236 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
26237 ++
26238 ++ /* we wouldn't have to check d_inode if it weren't for
26239 ++ NFS silly-renaming
26240 ++ */
26241 ++
26242 ++ write_lock(&gr_inode_lock);
26243 ++ if (unlikely(replace && new_dentry->d_inode)) {
26244 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
26245 ++ new_dentry->d_inode->i_sb->s_dev);
26246 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
26247 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
26248 ++ new_dentry->d_inode->i_sb->s_dev);
26249 ++ }
26250 ++
26251 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
26252 ++ old_dentry->d_inode->i_sb->s_dev);
26253 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
26254 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
26255 ++ old_dentry->d_inode->i_sb->s_dev);
26256 ++
26257 ++ if (unlikely((unsigned long)matchn))
26258 ++ do_handle_create(matchn, old_dentry, mnt);
26259 ++
26260 ++ write_unlock(&gr_inode_lock);
26261 ++ preempt_enable();
26262 ++
26263 ++ return;
26264 ++}
26265 ++
26266 ++static int
26267 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
26268 ++ unsigned char **sum)
26269 ++{
26270 ++ struct acl_role_label *r;
26271 ++ struct role_allowed_ip *ipp;
26272 ++ struct role_transition *trans;
26273 ++ unsigned int i;
26274 ++ int found = 0;
26275 ++
26276 ++ /* check transition table */
26277 ++
26278 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
26279 ++ if (!strcmp(rolename, trans->rolename)) {
26280 ++ found = 1;
26281 ++ break;
26282 ++ }
26283 ++ }
26284 ++
26285 ++ if (!found)
26286 ++ return 0;
26287 ++
26288 ++ /* handle special roles that do not require authentication
26289 ++ and check ip */
26290 ++
26291 ++ FOR_EACH_ROLE_START(r, i)
26292 ++ if (!strcmp(rolename, r->rolename) &&
26293 ++ (r->roletype & GR_ROLE_SPECIAL)) {
26294 ++ found = 0;
26295 ++ if (r->allowed_ips != NULL) {
26296 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
26297 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
26298 ++ (ntohl(ipp->addr) & ipp->netmask))
26299 ++ found = 1;
26300 ++ }
26301 ++ } else
26302 ++ found = 2;
26303 ++ if (!found)
26304 ++ return 0;
26305 ++
26306 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
26307 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
26308 ++ *salt = NULL;
26309 ++ *sum = NULL;
26310 ++ return 1;
26311 ++ }
26312 ++ }
26313 ++ FOR_EACH_ROLE_END(r,i)
26314 ++
26315 ++ for (i = 0; i < num_sprole_pws; i++) {
26316 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
26317 ++ *salt = acl_special_roles[i]->salt;
26318 ++ *sum = acl_special_roles[i]->sum;
26319 ++ return 1;
26320 ++ }
26321 ++ }
26322 ++
26323 ++ return 0;
26324 ++}
26325 ++
26326 ++static void
26327 ++assign_special_role(char *rolename)
26328 ++{
26329 ++ struct acl_object_label *obj;
26330 ++ struct acl_role_label *r;
26331 ++ struct acl_role_label *assigned = NULL;
26332 ++ struct task_struct *tsk;
26333 ++ struct file *filp;
26334 ++ unsigned int i;
26335 ++
26336 ++ FOR_EACH_ROLE_START(r, i)
26337 ++ if (!strcmp(rolename, r->rolename) &&
26338 ++ (r->roletype & GR_ROLE_SPECIAL))
26339 ++ assigned = r;
26340 ++ FOR_EACH_ROLE_END(r,i)
26341 ++
26342 ++ if (!assigned)
26343 ++ return;
26344 ++
26345 ++ read_lock(&tasklist_lock);
26346 ++ read_lock(&grsec_exec_file_lock);
26347 ++
26348 ++ tsk = current->parent;
26349 ++ if (tsk == NULL)
26350 ++ goto out_unlock;
26351 ++
26352 ++ filp = tsk->exec_file;
26353 ++ if (filp == NULL)
26354 ++ goto out_unlock;
26355 ++
26356 ++ tsk->is_writable = 0;
26357 ++
26358 ++ tsk->acl_sp_role = 1;
26359 ++ tsk->acl_role_id = ++acl_sp_role_value;
26360 ++ tsk->role = assigned;
26361 ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
26362 ++
26363 ++ /* ignore additional mmap checks for processes that are writable
26364 ++ by the default ACL */
26365 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
26366 ++ if (unlikely(obj->mode & GR_WRITE))
26367 ++ tsk->is_writable = 1;
26368 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
26369 ++ if (unlikely(obj->mode & GR_WRITE))
26370 ++ tsk->is_writable = 1;
26371 ++
26372 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26373 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
26374 ++#endif
26375 ++
26376 ++out_unlock:
26377 ++ read_unlock(&grsec_exec_file_lock);
26378 ++ read_unlock(&tasklist_lock);
26379 ++ return;
26380 ++}
26381 ++
26382 ++int gr_check_secure_terminal(struct task_struct *task)
26383 ++{
26384 ++ struct task_struct *p, *p2, *p3;
26385 ++ struct files_struct *files;
26386 ++ struct fdtable *fdt;
26387 ++ struct file *our_file = NULL, *file;
26388 ++ int i;
26389 ++
26390 ++ if (task->signal->tty == NULL)
26391 ++ return 1;
26392 ++
26393 ++ files = get_files_struct(task);
26394 ++ if (files != NULL) {
26395 ++ rcu_read_lock();
26396 ++ fdt = files_fdtable(files);
26397 ++ for (i=0; i < fdt->max_fds; i++) {
26398 ++ file = fcheck_files(files, i);
26399 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
26400 ++ get_file(file);
26401 ++ our_file = file;
26402 ++ }
26403 ++ }
26404 ++ rcu_read_unlock();
26405 ++ put_files_struct(files);
26406 ++ }
26407 ++
26408 ++ if (our_file == NULL)
26409 ++ return 1;
26410 ++
26411 ++ read_lock(&tasklist_lock);
26412 ++ do_each_thread(p2, p) {
26413 ++ files = get_files_struct(p);
26414 ++ if (files == NULL ||
26415 ++ (p->signal && p->signal->tty == task->signal->tty)) {
26416 ++ if (files != NULL)
26417 ++ put_files_struct(files);
26418 ++ continue;
26419 ++ }
26420 ++ rcu_read_lock();
26421 ++ fdt = files_fdtable(files);
26422 ++ for (i=0; i < fdt->max_fds; i++) {
26423 ++ file = fcheck_files(files, i);
26424 ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
26425 ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
26426 ++ p3 = task;
26427 ++ while (p3->pid > 0) {
26428 ++ if (p3 == p)
26429 ++ break;
26430 ++ p3 = p3->parent;
26431 ++ }
26432 ++ if (p3 == p)
26433 ++ break;
26434 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
26435 ++ gr_handle_alertkill(p);
26436 ++ rcu_read_unlock();
26437 ++ put_files_struct(files);
26438 ++ read_unlock(&tasklist_lock);
26439 ++ fput(our_file);
26440 ++ return 0;
26441 ++ }
26442 ++ }
26443 ++ rcu_read_unlock();
26444 ++ put_files_struct(files);
26445 ++ } while_each_thread(p2, p);
26446 ++ read_unlock(&tasklist_lock);
26447 ++
26448 ++ fput(our_file);
26449 ++ return 1;
26450 ++}
26451 ++
26452 ++ssize_t
26453 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
26454 ++{
26455 ++ struct gr_arg_wrapper uwrap;
26456 ++ unsigned char *sprole_salt;
26457 ++ unsigned char *sprole_sum;
26458 ++ int error = sizeof (struct gr_arg_wrapper);
26459 ++ int error2 = 0;
26460 ++
26461 ++ down(&gr_dev_sem);
26462 ++
26463 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
26464 ++ error = -EPERM;
26465 ++ goto out;
26466 ++ }
26467 ++
26468 ++ if (count != sizeof (struct gr_arg_wrapper)) {
26469 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
26470 ++ error = -EINVAL;
26471 ++ goto out;
26472 ++ }
26473 ++
26474 ++
26475 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
26476 ++ gr_auth_expires = 0;
26477 ++ gr_auth_attempts = 0;
26478 ++ }
26479 ++
26480 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
26481 ++ error = -EFAULT;
26482 ++ goto out;
26483 ++ }
26484 ++
26485 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
26486 ++ error = -EINVAL;
26487 ++ goto out;
26488 ++ }
26489 ++
26490 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
26491 ++ error = -EFAULT;
26492 ++ goto out;
26493 ++ }
26494 ++
26495 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
26496 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
26497 ++ time_after(gr_auth_expires, get_seconds())) {
26498 ++ error = -EBUSY;
26499 ++ goto out;
26500 ++ }
26501 ++
26502 ++ /* if non-root trying to do anything other than use a special role,
26503 ++ do not attempt authentication, do not count towards authentication
26504 ++ locking
26505 ++ */
26506 ++
26507 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
26508 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
26509 ++ current->uid) {
26510 ++ error = -EPERM;
26511 ++ goto out;
26512 ++ }
26513 ++
26514 ++ /* ensure pw and special role name are null terminated */
26515 ++
26516 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
26517 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
26518 ++
26519 ++ /* Okay.
26520 ++ * We have our enough of the argument structure..(we have yet
26521 ++ * to copy_from_user the tables themselves) . Copy the tables
26522 ++ * only if we need them, i.e. for loading operations. */
26523 ++
26524 ++ switch (gr_usermode->mode) {
26525 ++ case STATUS:
26526 ++ if (gr_status & GR_READY) {
26527 ++ error = 1;
26528 ++ if (!gr_check_secure_terminal(current))
26529 ++ error = 3;
26530 ++ } else
26531 ++ error = 2;
26532 ++ goto out;
26533 ++ case SHUTDOWN:
26534 ++ if ((gr_status & GR_READY)
26535 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26536 ++ gr_status &= ~GR_READY;
26537 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
26538 ++ free_variables();
26539 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
26540 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
26541 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
26542 ++ } else if (gr_status & GR_READY) {
26543 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
26544 ++ error = -EPERM;
26545 ++ } else {
26546 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
26547 ++ error = -EAGAIN;
26548 ++ }
26549 ++ break;
26550 ++ case ENABLE:
26551 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
26552 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
26553 ++ else {
26554 ++ if (gr_status & GR_READY)
26555 ++ error = -EAGAIN;
26556 ++ else
26557 ++ error = error2;
26558 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
26559 ++ }
26560 ++ break;
26561 ++ case RELOAD:
26562 ++ if (!(gr_status & GR_READY)) {
26563 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
26564 ++ error = -EAGAIN;
26565 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26566 ++ lock_kernel();
26567 ++ gr_status &= ~GR_READY;
26568 ++ free_variables();
26569 ++ if (!(error2 = gracl_init(gr_usermode))) {
26570 ++ unlock_kernel();
26571 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
26572 ++ } else {
26573 ++ unlock_kernel();
26574 ++ error = error2;
26575 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
26576 ++ }
26577 ++ } else {
26578 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
26579 ++ error = -EPERM;
26580 ++ }
26581 ++ break;
26582 ++ case SEGVMOD:
26583 ++ if (unlikely(!(gr_status & GR_READY))) {
26584 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
26585 ++ error = -EAGAIN;
26586 ++ break;
26587 ++ }
26588 ++
26589 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26590 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
26591 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
26592 ++ struct acl_subject_label *segvacl;
26593 ++ segvacl =
26594 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
26595 ++ gr_usermode->segv_device,
26596 ++ current->role);
26597 ++ if (segvacl) {
26598 ++ segvacl->crashes = 0;
26599 ++ segvacl->expires = 0;
26600 ++ }
26601 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
26602 ++ gr_remove_uid(gr_usermode->segv_uid);
26603 ++ }
26604 ++ } else {
26605 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
26606 ++ error = -EPERM;
26607 ++ }
26608 ++ break;
26609 ++ case SPROLE:
26610 ++ case SPROLEPAM:
26611 ++ if (unlikely(!(gr_status & GR_READY))) {
26612 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
26613 ++ error = -EAGAIN;
26614 ++ break;
26615 ++ }
26616 ++
26617 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
26618 ++ current->role->expires = 0;
26619 ++ current->role->auth_attempts = 0;
26620 ++ }
26621 ++
26622 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
26623 ++ time_after(current->role->expires, get_seconds())) {
26624 ++ error = -EBUSY;
26625 ++ goto out;
26626 ++ }
26627 ++
26628 ++ if (lookup_special_role_auth
26629 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
26630 ++ && ((!sprole_salt && !sprole_sum)
26631 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
26632 ++ char *p = "";
26633 ++ assign_special_role(gr_usermode->sp_role);
26634 ++ read_lock(&tasklist_lock);
26635 ++ if (current->parent)
26636 ++ p = current->parent->role->rolename;
26637 ++ read_unlock(&tasklist_lock);
26638 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
26639 ++ p, acl_sp_role_value);
26640 ++ } else {
26641 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
26642 ++ error = -EPERM;
26643 ++ if(!(current->role->auth_attempts++))
26644 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
26645 ++
26646 ++ goto out;
26647 ++ }
26648 ++ break;
26649 ++ case UNSPROLE:
26650 ++ if (unlikely(!(gr_status & GR_READY))) {
26651 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
26652 ++ error = -EAGAIN;
26653 ++ break;
26654 ++ }
26655 ++
26656 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
26657 ++ char *p = "";
26658 ++ int i = 0;
26659 ++
26660 ++ read_lock(&tasklist_lock);
26661 ++ if (current->parent) {
26662 ++ p = current->parent->role->rolename;
26663 ++ i = current->parent->acl_role_id;
26664 ++ }
26665 ++ read_unlock(&tasklist_lock);
26666 ++
26667 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
26668 ++ gr_set_acls(1);
26669 ++ } else {
26670 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
26671 ++ error = -EPERM;
26672 ++ goto out;
26673 ++ }
26674 ++ break;
26675 ++ default:
26676 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
26677 ++ error = -EINVAL;
26678 ++ break;
26679 ++ }
26680 ++
26681 ++ if (error != -EPERM)
26682 ++ goto out;
26683 ++
26684 ++ if(!(gr_auth_attempts++))
26685 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
26686 ++
26687 ++ out:
26688 ++ up(&gr_dev_sem);
26689 ++ return error;
26690 ++}
26691 ++
26692 ++int
26693 ++gr_set_acls(const int type)
26694 ++{
26695 ++ struct acl_object_label *obj;
26696 ++ struct task_struct *task, *task2;
26697 ++ struct file *filp;
26698 ++ struct acl_role_label *role = current->role;
26699 ++ __u16 acl_role_id = current->acl_role_id;
26700 ++
26701 ++ read_lock(&tasklist_lock);
26702 ++ read_lock(&grsec_exec_file_lock);
26703 ++ do_each_thread(task2, task) {
26704 ++ /* check to see if we're called from the exit handler,
26705 ++ if so, only replace ACLs that have inherited the admin
26706 ++ ACL */
26707 ++
26708 ++ if (type && (task->role != role ||
26709 ++ task->acl_role_id != acl_role_id))
26710 ++ continue;
26711 ++
26712 ++ task->acl_role_id = 0;
26713 ++ task->acl_sp_role = 0;
26714 ++
26715 ++ if ((filp = task->exec_file)) {
26716 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
26717 ++
26718 ++ task->acl =
26719 ++ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
26720 ++ task->role);
26721 ++ if (task->acl) {
26722 ++ struct acl_subject_label *curr;
26723 ++ curr = task->acl;
26724 ++
26725 ++ task->is_writable = 0;
26726 ++ /* ignore additional mmap checks for processes that are writable
26727 ++ by the default ACL */
26728 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
26729 ++ if (unlikely(obj->mode & GR_WRITE))
26730 ++ task->is_writable = 1;
26731 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
26732 ++ if (unlikely(obj->mode & GR_WRITE))
26733 ++ task->is_writable = 1;
26734 ++
26735 ++ gr_set_proc_res(task);
26736 ++
26737 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26738 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
26739 ++#endif
26740 ++ } else {
26741 ++ read_unlock(&grsec_exec_file_lock);
26742 ++ read_unlock(&tasklist_lock);
26743 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
26744 ++ return 1;
26745 ++ }
26746 ++ } else {
26747 ++ // it's a kernel process
26748 ++ task->role = kernel_role;
26749 ++ task->acl = kernel_role->root_label;
26750 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
26751 ++ task->acl->mode &= ~GR_PROCFIND;
26752 ++#endif
26753 ++ }
26754 ++ } while_each_thread(task2, task);
26755 ++ read_unlock(&grsec_exec_file_lock);
26756 ++ read_unlock(&tasklist_lock);
26757 ++ return 0;
26758 ++}
26759 ++
26760 ++void
26761 ++gr_learn_resource(const struct task_struct *task,
26762 ++ const int res, const unsigned long wanted, const int gt)
26763 ++{
26764 ++ struct acl_subject_label *acl;
26765 ++
26766 ++ if (unlikely((gr_status & GR_READY) &&
26767 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
26768 ++ goto skip_reslog;
26769 ++
26770 ++#ifdef CONFIG_GRKERNSEC_RESLOG
26771 ++ gr_log_resource(task, res, wanted, gt);
26772 ++#endif
26773 ++ skip_reslog:
26774 ++
26775 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
26776 ++ return;
26777 ++
26778 ++ acl = task->acl;
26779 ++
26780 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
26781 ++ !(acl->resmask & (1 << (unsigned short) res))))
26782 ++ return;
26783 ++
26784 ++ if (wanted >= acl->res[res].rlim_cur) {
26785 ++ unsigned long res_add;
26786 ++
26787 ++ res_add = wanted;
26788 ++ switch (res) {
26789 ++ case RLIMIT_CPU:
26790 ++ res_add += GR_RLIM_CPU_BUMP;
26791 ++ break;
26792 ++ case RLIMIT_FSIZE:
26793 ++ res_add += GR_RLIM_FSIZE_BUMP;
26794 ++ break;
26795 ++ case RLIMIT_DATA:
26796 ++ res_add += GR_RLIM_DATA_BUMP;
26797 ++ break;
26798 ++ case RLIMIT_STACK:
26799 ++ res_add += GR_RLIM_STACK_BUMP;
26800 ++ break;
26801 ++ case RLIMIT_CORE:
26802 ++ res_add += GR_RLIM_CORE_BUMP;
26803 ++ break;
26804 ++ case RLIMIT_RSS:
26805 ++ res_add += GR_RLIM_RSS_BUMP;
26806 ++ break;
26807 ++ case RLIMIT_NPROC:
26808 ++ res_add += GR_RLIM_NPROC_BUMP;
26809 ++ break;
26810 ++ case RLIMIT_NOFILE:
26811 ++ res_add += GR_RLIM_NOFILE_BUMP;
26812 ++ break;
26813 ++ case RLIMIT_MEMLOCK:
26814 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
26815 ++ break;
26816 ++ case RLIMIT_AS:
26817 ++ res_add += GR_RLIM_AS_BUMP;
26818 ++ break;
26819 ++ case RLIMIT_LOCKS:
26820 ++ res_add += GR_RLIM_LOCKS_BUMP;
26821 ++ break;
26822 ++ }
26823 ++
26824 ++ acl->res[res].rlim_cur = res_add;
26825 ++
26826 ++ if (wanted > acl->res[res].rlim_max)
26827 ++ acl->res[res].rlim_max = res_add;
26828 ++
26829 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
26830 ++ task->role->roletype, acl->filename,
26831 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
26832 ++ "", (unsigned long) res);
26833 ++ }
26834 ++
26835 ++ return;
26836 ++}
26837 ++
26838 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26839 ++void
26840 ++pax_set_initial_flags(struct linux_binprm *bprm)
26841 ++{
26842 ++ struct task_struct *task = current;
26843 ++ struct acl_subject_label *proc;
26844 ++ unsigned long flags;
26845 ++
26846 ++ if (unlikely(!(gr_status & GR_READY)))
26847 ++ return;
26848 ++
26849 ++ flags = pax_get_flags(task);
26850 ++
26851 ++ proc = task->acl;
26852 ++
26853 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
26854 ++ flags &= ~MF_PAX_PAGEEXEC;
26855 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
26856 ++ flags &= ~MF_PAX_SEGMEXEC;
26857 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
26858 ++ flags &= ~MF_PAX_RANDMMAP;
26859 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
26860 ++ flags &= ~MF_PAX_EMUTRAMP;
26861 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
26862 ++ flags &= ~MF_PAX_MPROTECT;
26863 ++
26864 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
26865 ++ flags |= MF_PAX_PAGEEXEC;
26866 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
26867 ++ flags |= MF_PAX_SEGMEXEC;
26868 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
26869 ++ flags |= MF_PAX_RANDMMAP;
26870 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
26871 ++ flags |= MF_PAX_EMUTRAMP;
26872 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
26873 ++ flags |= MF_PAX_MPROTECT;
26874 ++
26875 ++ pax_set_flags(task, flags);
26876 ++
26877 ++ return;
26878 ++}
26879 ++#endif
26880 ++
26881 ++#ifdef CONFIG_SYSCTL
26882 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
26883 ++ system to save 35kb of memory */
26884 ++
26885 ++/* we modify the passed in filename, but adjust it back before returning */
26886 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
26887 ++{
26888 ++ struct name_entry *nmatch;
26889 ++ char *p, *lastp = NULL;
26890 ++ struct acl_object_label *obj = NULL, *tmp;
26891 ++ struct acl_subject_label *tmpsubj;
26892 ++ char c = '\0';
26893 ++
26894 ++ read_lock(&gr_inode_lock);
26895 ++
26896 ++ p = name + len - 1;
26897 ++ do {
26898 ++ nmatch = lookup_name_entry(name);
26899 ++ if (lastp != NULL)
26900 ++ *lastp = c;
26901 ++
26902 ++ if (nmatch == NULL)
26903 ++ goto next_component;
26904 ++ tmpsubj = current->acl;
26905 ++ do {
26906 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
26907 ++ if (obj != NULL) {
26908 ++ tmp = obj->globbed;
26909 ++ while (tmp) {
26910 ++ if (!glob_match(tmp->filename, name)) {
26911 ++ obj = tmp;
26912 ++ goto found_obj;
26913 ++ }
26914 ++ tmp = tmp->next;
26915 ++ }
26916 ++ goto found_obj;
26917 ++ }
26918 ++ } while ((tmpsubj = tmpsubj->parent_subject));
26919 ++next_component:
26920 ++ /* end case */
26921 ++ if (p == name)
26922 ++ break;
26923 ++
26924 ++ while (*p != '/')
26925 ++ p--;
26926 ++ if (p == name)
26927 ++ lastp = p + 1;
26928 ++ else {
26929 ++ lastp = p;
26930 ++ p--;
26931 ++ }
26932 ++ c = *lastp;
26933 ++ *lastp = '\0';
26934 ++ } while (1);
26935 ++found_obj:
26936 ++ read_unlock(&gr_inode_lock);
26937 ++ /* obj returned will always be non-null */
26938 ++ return obj;
26939 ++}
26940 ++
26941 ++/* returns 0 when allowing, non-zero on error
26942 ++ op of 0 is used for readdir, so we don't log the names of hidden files
26943 ++*/
26944 ++__u32
26945 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
26946 ++{
26947 ++ ctl_table *tmp;
26948 ++ const char *proc_sys = "/proc/sys";
26949 ++ char *path;
26950 ++ struct acl_object_label *obj;
26951 ++ unsigned short len = 0, pos = 0, depth = 0, i;
26952 ++ __u32 err = 0;
26953 ++ __u32 mode = 0;
26954 ++
26955 ++ if (unlikely(!(gr_status & GR_READY)))
26956 ++ return 0;
26957 ++
26958 ++ /* for now, ignore operations on non-sysctl entries if it's not a
26959 ++ readdir*/
26960 ++ if (table->child != NULL && op != 0)
26961 ++ return 0;
26962 ++
26963 ++ mode |= GR_FIND;
26964 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
26965 ++ if (op & 004)
26966 ++ mode |= GR_READ;
26967 ++ if (op & 002)
26968 ++ mode |= GR_WRITE;
26969 ++
26970 ++ preempt_disable();
26971 ++
26972 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
26973 ++
26974 ++ /* it's only a read/write if it's an actual entry, not a dir
26975 ++ (which are opened for readdir)
26976 ++ */
26977 ++
26978 ++ /* convert the requested sysctl entry into a pathname */
26979 ++
26980 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
26981 ++ len += strlen(tmp->procname);
26982 ++ len++;
26983 ++ depth++;
26984 ++ }
26985 ++
26986 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
26987 ++ /* deny */
26988 ++ goto out;
26989 ++ }
26990 ++
26991 ++ memset(path, 0, PAGE_SIZE);
26992 ++
26993 ++ memcpy(path, proc_sys, strlen(proc_sys));
26994 ++
26995 ++ pos += strlen(proc_sys);
26996 ++
26997 ++ for (; depth > 0; depth--) {
26998 ++ path[pos] = '/';
26999 ++ pos++;
27000 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
27001 ++ if (depth == i) {
27002 ++ memcpy(path + pos, tmp->procname,
27003 ++ strlen(tmp->procname));
27004 ++ pos += strlen(tmp->procname);
27005 ++ }
27006 ++ i++;
27007 ++ }
27008 ++ }
27009 ++
27010 ++ obj = gr_lookup_by_name(path, pos);
27011 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
27012 ++
27013 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
27014 ++ ((err & mode) != mode))) {
27015 ++ __u32 new_mode = mode;
27016 ++
27017 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
27018 ++
27019 ++ err = 0;
27020 ++ gr_log_learn_sysctl(current, path, new_mode);
27021 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
27022 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
27023 ++ err = -ENOENT;
27024 ++ } else if (!(err & GR_FIND)) {
27025 ++ err = -ENOENT;
27026 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
27027 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
27028 ++ path, (mode & GR_READ) ? " reading" : "",
27029 ++ (mode & GR_WRITE) ? " writing" : "");
27030 ++ err = -EACCES;
27031 ++ } else if ((err & mode) != mode) {
27032 ++ err = -EACCES;
27033 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
27034 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
27035 ++ path, (mode & GR_READ) ? " reading" : "",
27036 ++ (mode & GR_WRITE) ? " writing" : "");
27037 ++ err = 0;
27038 ++ } else
27039 ++ err = 0;
27040 ++
27041 ++ out:
27042 ++ preempt_enable();
27043 ++
27044 ++ return err;
27045 ++}
27046 ++#endif
27047 ++
27048 ++int
27049 ++gr_handle_proc_ptrace(struct task_struct *task)
27050 ++{
27051 ++ struct file *filp;
27052 ++ struct task_struct *tmp = task;
27053 ++ struct task_struct *curtemp = current;
27054 ++ __u32 retmode;
27055 ++
27056 ++ if (unlikely(!(gr_status & GR_READY)))
27057 ++ return 0;
27058 ++
27059 ++ read_lock(&tasklist_lock);
27060 ++ read_lock(&grsec_exec_file_lock);
27061 ++ filp = task->exec_file;
27062 ++
27063 ++ while (tmp->pid > 0) {
27064 ++ if (tmp == curtemp)
27065 ++ break;
27066 ++ tmp = tmp->parent;
27067 ++ }
27068 ++
27069 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
27070 ++ read_unlock(&grsec_exec_file_lock);
27071 ++ read_unlock(&tasklist_lock);
27072 ++ return 1;
27073 ++ }
27074 ++
27075 ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
27076 ++ read_unlock(&grsec_exec_file_lock);
27077 ++ read_unlock(&tasklist_lock);
27078 ++
27079 ++ if (retmode & GR_NOPTRACE)
27080 ++ return 1;
27081 ++
27082 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
27083 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
27084 ++ && current->pid != task->pid)))
27085 ++ return 1;
27086 ++
27087 ++ return 0;
27088 ++}
27089 ++
27090 ++int
27091 ++gr_handle_ptrace(struct task_struct *task, const long request)
27092 ++{
27093 ++ struct task_struct *tmp = task;
27094 ++ struct task_struct *curtemp = current;
27095 ++ __u32 retmode;
27096 ++
27097 ++ if (unlikely(!(gr_status & GR_READY)))
27098 ++ return 0;
27099 ++
27100 ++ read_lock(&tasklist_lock);
27101 ++ while (tmp->pid > 0) {
27102 ++ if (tmp == curtemp)
27103 ++ break;
27104 ++ tmp = tmp->parent;
27105 ++ }
27106 ++
27107 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
27108 ++ read_unlock(&tasklist_lock);
27109 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27110 ++ return 1;
27111 ++ }
27112 ++ read_unlock(&tasklist_lock);
27113 ++
27114 ++ read_lock(&grsec_exec_file_lock);
27115 ++ if (unlikely(!task->exec_file)) {
27116 ++ read_unlock(&grsec_exec_file_lock);
27117 ++ return 0;
27118 ++ }
27119 ++
27120 ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
27121 ++ read_unlock(&grsec_exec_file_lock);
27122 ++
27123 ++ if (retmode & GR_NOPTRACE) {
27124 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27125 ++ return 1;
27126 ++ }
27127 ++
27128 ++ if (retmode & GR_PTRACERD) {
27129 ++ switch (request) {
27130 ++ case PTRACE_POKETEXT:
27131 ++ case PTRACE_POKEDATA:
27132 ++ case PTRACE_POKEUSR:
27133 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
27134 ++ case PTRACE_SETREGS:
27135 ++ case PTRACE_SETFPREGS:
27136 ++#endif
27137 ++#ifdef CONFIG_X86
27138 ++ case PTRACE_SETFPXREGS:
27139 ++#endif
27140 ++#ifdef CONFIG_ALTIVEC
27141 ++ case PTRACE_SETVRREGS:
27142 ++#endif
27143 ++ return 1;
27144 ++ default:
27145 ++ return 0;
27146 ++ }
27147 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
27148 ++ !(current->role->roletype & GR_ROLE_GOD) &&
27149 ++ (current->acl != task->acl)) {
27150 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27151 ++ return 1;
27152 ++ }
27153 ++
27154 ++ return 0;
27155 ++}
27156 ++
27157 ++static int is_writable_mmap(const struct file *filp)
27158 ++{
27159 ++ struct task_struct *task = current;
27160 ++ struct acl_object_label *obj, *obj2;
27161 ++
27162 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
27163 ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
27164 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
27165 ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
27166 ++ task->role->root_label);
27167 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
27168 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
27169 ++ return 1;
27170 ++ }
27171 ++ }
27172 ++ return 0;
27173 ++}
27174 ++
27175 ++int
27176 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
27177 ++{
27178 ++ __u32 mode;
27179 ++
27180 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
27181 ++ return 1;
27182 ++
27183 ++ if (is_writable_mmap(file))
27184 ++ return 0;
27185 ++
27186 ++ mode =
27187 ++ gr_search_file(file->f_path.dentry,
27188 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
27189 ++ file->f_path.mnt);
27190 ++
27191 ++ if (!gr_tpe_allow(file))
27192 ++ return 0;
27193 ++
27194 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
27195 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27196 ++ return 0;
27197 ++ } else if (unlikely(!(mode & GR_EXEC))) {
27198 ++ return 0;
27199 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
27200 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27201 ++ return 1;
27202 ++ }
27203 ++
27204 ++ return 1;
27205 ++}
27206 ++
27207 ++int
27208 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
27209 ++{
27210 ++ __u32 mode;
27211 ++
27212 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
27213 ++ return 1;
27214 ++
27215 ++ if (is_writable_mmap(file))
27216 ++ return 0;
27217 ++
27218 ++ mode =
27219 ++ gr_search_file(file->f_path.dentry,
27220 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
27221 ++ file->f_path.mnt);
27222 ++
27223 ++ if (!gr_tpe_allow(file))
27224 ++ return 0;
27225 ++
27226 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
27227 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27228 ++ return 0;
27229 ++ } else if (unlikely(!(mode & GR_EXEC))) {
27230 ++ return 0;
27231 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
27232 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27233 ++ return 1;
27234 ++ }
27235 ++
27236 ++ return 1;
27237 ++}
27238 ++
27239 ++void
27240 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
27241 ++{
27242 ++ unsigned long runtime;
27243 ++ unsigned long cputime;
27244 ++ unsigned int wday, cday;
27245 ++ __u8 whr, chr;
27246 ++ __u8 wmin, cmin;
27247 ++ __u8 wsec, csec;
27248 ++ struct timespec timeval;
27249 ++
27250 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
27251 ++ !(task->acl->mode & GR_PROCACCT)))
27252 ++ return;
27253 ++
27254 ++ do_posix_clock_monotonic_gettime(&timeval);
27255 ++ runtime = timeval.tv_sec - task->start_time.tv_sec;
27256 ++ wday = runtime / (3600 * 24);
27257 ++ runtime -= wday * (3600 * 24);
27258 ++ whr = runtime / 3600;
27259 ++ runtime -= whr * 3600;
27260 ++ wmin = runtime / 60;
27261 ++ runtime -= wmin * 60;
27262 ++ wsec = runtime;
27263 ++
27264 ++ cputime = (task->utime + task->stime) / HZ;
27265 ++ cday = cputime / (3600 * 24);
27266 ++ cputime -= cday * (3600 * 24);
27267 ++ chr = cputime / 3600;
27268 ++ cputime -= chr * 3600;
27269 ++ cmin = cputime / 60;
27270 ++ cputime -= cmin * 60;
27271 ++ csec = cputime;
27272 ++
27273 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
27274 ++
27275 ++ return;
27276 ++}
27277 ++
27278 ++void gr_set_kernel_label(struct task_struct *task)
27279 ++{
27280 ++ if (gr_status & GR_READY) {
27281 ++ task->role = kernel_role;
27282 ++ task->acl = kernel_role->root_label;
27283 ++ }
27284 ++ return;
27285 ++}
27286 ++
27287 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
27288 ++{
27289 ++ struct task_struct *task = current;
27290 ++ struct dentry *dentry = file->f_path.dentry;
27291 ++ struct vfsmount *mnt = file->f_path.mnt;
27292 ++ struct acl_object_label *obj, *tmp;
27293 ++ struct acl_subject_label *subj;
27294 ++ unsigned int bufsize;
27295 ++ int is_not_root;
27296 ++ char *path;
27297 ++
27298 ++ if (unlikely(!(gr_status & GR_READY)))
27299 ++ return 1;
27300 ++
27301 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
27302 ++ return 1;
27303 ++
27304 ++ /* ignore Eric Biederman */
27305 ++ if (IS_PRIVATE(dentry->d_inode))
27306 ++ return 1;
27307 ++
27308 ++ subj = task->acl;
27309 ++ do {
27310 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
27311 ++ if (obj != NULL)
27312 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27313 ++ } while ((subj = subj->parent_subject));
27314 ++
27315 ++ obj = chk_obj_label(dentry, mnt, task->acl);
27316 ++ if (obj->globbed == NULL)
27317 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27318 ++
27319 ++ is_not_root = ((obj->filename[0] == '/') &&
27320 ++ (obj->filename[1] == '\0')) ? 0 : 1;
27321 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
27322 ++
27323 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
27324 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
27325 ++ return 1;
27326 ++
27327 ++ preempt_disable();
27328 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
27329 ++ bufsize);
27330 ++
27331 ++ bufsize = strlen(path);
27332 ++
27333 ++ /* if base is "/", don't append an additional slash */
27334 ++ if (is_not_root)
27335 ++ *(path + bufsize) = '/';
27336 ++ memcpy(path + bufsize + is_not_root, name, namelen);
27337 ++ *(path + bufsize + namelen + is_not_root) = '\0';
27338 ++
27339 ++ tmp = obj->globbed;
27340 ++ while (tmp) {
27341 ++ if (!glob_match(tmp->filename, path)) {
27342 ++ preempt_enable();
27343 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
27344 ++ }
27345 ++ tmp = tmp->next;
27346 ++ }
27347 ++ preempt_enable();
27348 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27349 ++}
27350 ++
27351 ++EXPORT_SYMBOL(gr_learn_resource);
27352 ++EXPORT_SYMBOL(gr_set_kernel_label);
27353 ++#ifdef CONFIG_SECURITY
27354 ++EXPORT_SYMBOL(gr_check_user_change);
27355 ++EXPORT_SYMBOL(gr_check_group_change);
27356 ++#endif
27357 ++
27358 +diff -urNp a/grsecurity/gracl_alloc.c b/grsecurity/gracl_alloc.c
27359 +--- a/grsecurity/gracl_alloc.c 1969-12-31 16:00:00.000000000 -0800
27360 ++++ b/grsecurity/gracl_alloc.c 2008-08-20 18:36:57.000000000 -0700
27361 +@@ -0,0 +1,91 @@
27362 ++#include <linux/kernel.h>
27363 ++#include <linux/mm.h>
27364 ++#include <linux/slab.h>
27365 ++#include <linux/vmalloc.h>
27366 ++#include <linux/gracl.h>
27367 ++#include <linux/grsecurity.h>
27368 ++
27369 ++static unsigned long alloc_stack_next = 1;
27370 ++static unsigned long alloc_stack_size = 1;
27371 ++static void **alloc_stack;
27372 ++
27373 ++static __inline__ int
27374 ++alloc_pop(void)
27375 ++{
27376 ++ if (alloc_stack_next == 1)
27377 ++ return 0;
27378 ++
27379 ++ kfree(alloc_stack[alloc_stack_next - 2]);
27380 ++
27381 ++ alloc_stack_next--;
27382 ++
27383 ++ return 1;
27384 ++}
27385 ++
27386 ++static __inline__ void
27387 ++alloc_push(void *buf)
27388 ++{
27389 ++ if (alloc_stack_next >= alloc_stack_size)
27390 ++ BUG();
27391 ++
27392 ++ alloc_stack[alloc_stack_next - 1] = buf;
27393 ++
27394 ++ alloc_stack_next++;
27395 ++
27396 ++ return;
27397 ++}
27398 ++
27399 ++void *
27400 ++acl_alloc(unsigned long len)
27401 ++{
27402 ++ void *ret;
27403 ++
27404 ++ if (len > PAGE_SIZE)
27405 ++ BUG();
27406 ++
27407 ++ ret = kmalloc(len, GFP_KERNEL);
27408 ++
27409 ++ if (ret)
27410 ++ alloc_push(ret);
27411 ++
27412 ++ return ret;
27413 ++}
27414 ++
27415 ++void
27416 ++acl_free_all(void)
27417 ++{
27418 ++ if (gr_acl_is_enabled() || !alloc_stack)
27419 ++ return;
27420 ++
27421 ++ while (alloc_pop()) ;
27422 ++
27423 ++ if (alloc_stack) {
27424 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
27425 ++ kfree(alloc_stack);
27426 ++ else
27427 ++ vfree(alloc_stack);
27428 ++ }
27429 ++
27430 ++ alloc_stack = NULL;
27431 ++ alloc_stack_size = 1;
27432 ++ alloc_stack_next = 1;
27433 ++
27434 ++ return;
27435 ++}
27436 ++
27437 ++int
27438 ++acl_alloc_stack_init(unsigned long size)
27439 ++{
27440 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
27441 ++ alloc_stack =
27442 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
27443 ++ else
27444 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
27445 ++
27446 ++ alloc_stack_size = size;
27447 ++
27448 ++ if (!alloc_stack)
27449 ++ return 0;
27450 ++ else
27451 ++ return 1;
27452 ++}
27453 +diff -urNp a/grsecurity/gracl_cap.c b/grsecurity/gracl_cap.c
27454 +--- a/grsecurity/gracl_cap.c 1969-12-31 16:00:00.000000000 -0800
27455 ++++ b/grsecurity/gracl_cap.c 2008-08-20 18:36:57.000000000 -0700
27456 +@@ -0,0 +1,129 @@
27457 ++#include <linux/kernel.h>
27458 ++#include <linux/module.h>
27459 ++#include <linux/sched.h>
27460 ++#include <linux/gracl.h>
27461 ++#include <linux/grsecurity.h>
27462 ++#include <linux/grinternal.h>
27463 ++
27464 ++static const char *captab_log[] = {
27465 ++ "CAP_CHOWN",
27466 ++ "CAP_DAC_OVERRIDE",
27467 ++ "CAP_DAC_READ_SEARCH",
27468 ++ "CAP_FOWNER",
27469 ++ "CAP_FSETID",
27470 ++ "CAP_KILL",
27471 ++ "CAP_SETGID",
27472 ++ "CAP_SETUID",
27473 ++ "CAP_SETPCAP",
27474 ++ "CAP_LINUX_IMMUTABLE",
27475 ++ "CAP_NET_BIND_SERVICE",
27476 ++ "CAP_NET_BROADCAST",
27477 ++ "CAP_NET_ADMIN",
27478 ++ "CAP_NET_RAW",
27479 ++ "CAP_IPC_LOCK",
27480 ++ "CAP_IPC_OWNER",
27481 ++ "CAP_SYS_MODULE",
27482 ++ "CAP_SYS_RAWIO",
27483 ++ "CAP_SYS_CHROOT",
27484 ++ "CAP_SYS_PTRACE",
27485 ++ "CAP_SYS_PACCT",
27486 ++ "CAP_SYS_ADMIN",
27487 ++ "CAP_SYS_BOOT",
27488 ++ "CAP_SYS_NICE",
27489 ++ "CAP_SYS_RESOURCE",
27490 ++ "CAP_SYS_TIME",
27491 ++ "CAP_SYS_TTY_CONFIG",
27492 ++ "CAP_MKNOD",
27493 ++ "CAP_LEASE",
27494 ++ "CAP_AUDIT_WRITE",
27495 ++ "CAP_AUDIT_CONTROL",
27496 ++ "CAP_SETFCAP",
27497 ++ "CAP_MAC_OVERRIDE",
27498 ++ "CAP_MAC_ADMIN"
27499 ++};
27500 ++
27501 ++EXPORT_SYMBOL(gr_task_is_capable);
27502 ++EXPORT_SYMBOL(gr_is_capable_nolog);
27503 ++
27504 ++int
27505 ++gr_task_is_capable(struct task_struct *task, const int cap)
27506 ++{
27507 ++ struct acl_subject_label *curracl;
27508 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
27509 ++
27510 ++ if (!gr_acl_is_enabled())
27511 ++ return 1;
27512 ++
27513 ++ curracl = task->acl;
27514 ++
27515 ++ cap_drop = curracl->cap_lower;
27516 ++ cap_mask = curracl->cap_mask;
27517 ++
27518 ++ while ((curracl = curracl->parent_subject)) {
27519 ++ /* if the cap isn't specified in the current computed mask but is specified in the
27520 ++ current level subject, and is lowered in the current level subject, then add
27521 ++ it to the set of dropped capabilities
27522 ++ otherwise, add the current level subject's mask to the current computed mask
27523 ++ */
27524 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
27525 ++ cap_raise(cap_mask, cap);
27526 ++ if (cap_raised(curracl->cap_lower, cap))
27527 ++ cap_raise(cap_drop, cap);
27528 ++ }
27529 ++ }
27530 ++
27531 ++ if (!cap_raised(cap_drop, cap))
27532 ++ return 1;
27533 ++
27534 ++ curracl = task->acl;
27535 ++
27536 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
27537 ++ && cap_raised(task->cap_effective, cap)) {
27538 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
27539 ++ task->role->roletype, task->uid,
27540 ++ task->gid, task->exec_file ?
27541 ++ gr_to_filename(task->exec_file->f_path.dentry,
27542 ++ task->exec_file->f_path.mnt) : curracl->filename,
27543 ++ curracl->filename, 0UL,
27544 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
27545 ++ return 1;
27546 ++ }
27547 ++
27548 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
27549 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
27550 ++ return 0;
27551 ++}
27552 ++
27553 ++int
27554 ++gr_is_capable_nolog(const int cap)
27555 ++{
27556 ++ struct acl_subject_label *curracl;
27557 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
27558 ++
27559 ++ if (!gr_acl_is_enabled())
27560 ++ return 1;
27561 ++
27562 ++ curracl = current->acl;
27563 ++
27564 ++ cap_drop = curracl->cap_lower;
27565 ++ cap_mask = curracl->cap_mask;
27566 ++
27567 ++ while ((curracl = curracl->parent_subject)) {
27568 ++ /* if the cap isn't specified in the current computed mask but is specified in the
27569 ++ current level subject, and is lowered in the current level subject, then add
27570 ++ it to the set of dropped capabilities
27571 ++ otherwise, add the current level subject's mask to the current computed mask
27572 ++ */
27573 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
27574 ++ cap_raise(cap_mask, cap);
27575 ++ if (cap_raised(curracl->cap_lower, cap))
27576 ++ cap_raise(cap_drop, cap);
27577 ++ }
27578 ++ }
27579 ++
27580 ++ if (!cap_raised(cap_drop, cap))
27581 ++ return 1;
27582 ++
27583 ++ return 0;
27584 ++}
27585 ++
27586 +diff -urNp a/grsecurity/gracl_fs.c b/grsecurity/gracl_fs.c
27587 +--- a/grsecurity/gracl_fs.c 1969-12-31 16:00:00.000000000 -0800
27588 ++++ b/grsecurity/gracl_fs.c 2008-08-20 18:36:57.000000000 -0700
27589 +@@ -0,0 +1,423 @@
27590 ++#include <linux/kernel.h>
27591 ++#include <linux/sched.h>
27592 ++#include <linux/types.h>
27593 ++#include <linux/fs.h>
27594 ++#include <linux/file.h>
27595 ++#include <linux/stat.h>
27596 ++#include <linux/grsecurity.h>
27597 ++#include <linux/grinternal.h>
27598 ++#include <linux/gracl.h>
27599 ++
27600 ++__u32
27601 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
27602 ++ const struct vfsmount * mnt)
27603 ++{
27604 ++ __u32 mode;
27605 ++
27606 ++ if (unlikely(!dentry->d_inode))
27607 ++ return GR_FIND;
27608 ++
27609 ++ mode =
27610 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
27611 ++
27612 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
27613 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
27614 ++ return mode;
27615 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
27616 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
27617 ++ return 0;
27618 ++ } else if (unlikely(!(mode & GR_FIND)))
27619 ++ return 0;
27620 ++
27621 ++ return GR_FIND;
27622 ++}
27623 ++
27624 ++__u32
27625 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
27626 ++ const int fmode)
27627 ++{
27628 ++ __u32 reqmode = GR_FIND;
27629 ++ __u32 mode;
27630 ++
27631 ++ if (unlikely(!dentry->d_inode))
27632 ++ return reqmode;
27633 ++
27634 ++ if (unlikely(fmode & O_APPEND))
27635 ++ reqmode |= GR_APPEND;
27636 ++ else if (unlikely(fmode & FMODE_WRITE))
27637 ++ reqmode |= GR_WRITE;
27638 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
27639 ++ reqmode |= GR_READ;
27640 ++
27641 ++ mode =
27642 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
27643 ++ mnt);
27644 ++
27645 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27646 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
27647 ++ reqmode & GR_READ ? " reading" : "",
27648 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27649 ++ GR_APPEND ? " appending" : "");
27650 ++ return reqmode;
27651 ++ } else
27652 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27653 ++ {
27654 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
27655 ++ reqmode & GR_READ ? " reading" : "",
27656 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27657 ++ GR_APPEND ? " appending" : "");
27658 ++ return 0;
27659 ++ } else if (unlikely((mode & reqmode) != reqmode))
27660 ++ return 0;
27661 ++
27662 ++ return reqmode;
27663 ++}
27664 ++
27665 ++__u32
27666 ++gr_acl_handle_creat(const struct dentry * dentry,
27667 ++ const struct dentry * p_dentry,
27668 ++ const struct vfsmount * p_mnt, const int fmode,
27669 ++ const int imode)
27670 ++{
27671 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
27672 ++ __u32 mode;
27673 ++
27674 ++ if (unlikely(fmode & O_APPEND))
27675 ++ reqmode |= GR_APPEND;
27676 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
27677 ++ reqmode |= GR_READ;
27678 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
27679 ++ reqmode |= GR_SETID;
27680 ++
27681 ++ mode =
27682 ++ gr_check_create(dentry, p_dentry, p_mnt,
27683 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
27684 ++
27685 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27686 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
27687 ++ reqmode & GR_READ ? " reading" : "",
27688 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27689 ++ GR_APPEND ? " appending" : "");
27690 ++ return reqmode;
27691 ++ } else
27692 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27693 ++ {
27694 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
27695 ++ reqmode & GR_READ ? " reading" : "",
27696 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27697 ++ GR_APPEND ? " appending" : "");
27698 ++ return 0;
27699 ++ } else if (unlikely((mode & reqmode) != reqmode))
27700 ++ return 0;
27701 ++
27702 ++ return reqmode;
27703 ++}
27704 ++
27705 ++__u32
27706 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
27707 ++ const int fmode)
27708 ++{
27709 ++ __u32 mode, reqmode = GR_FIND;
27710 ++
27711 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
27712 ++ reqmode |= GR_EXEC;
27713 ++ if (fmode & S_IWOTH)
27714 ++ reqmode |= GR_WRITE;
27715 ++ if (fmode & S_IROTH)
27716 ++ reqmode |= GR_READ;
27717 ++
27718 ++ mode =
27719 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
27720 ++ mnt);
27721 ++
27722 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27723 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
27724 ++ reqmode & GR_READ ? " reading" : "",
27725 ++ reqmode & GR_WRITE ? " writing" : "",
27726 ++ reqmode & GR_EXEC ? " executing" : "");
27727 ++ return reqmode;
27728 ++ } else
27729 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27730 ++ {
27731 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
27732 ++ reqmode & GR_READ ? " reading" : "",
27733 ++ reqmode & GR_WRITE ? " writing" : "",
27734 ++ reqmode & GR_EXEC ? " executing" : "");
27735 ++ return 0;
27736 ++ } else if (unlikely((mode & reqmode) != reqmode))
27737 ++ return 0;
27738 ++
27739 ++ return reqmode;
27740 ++}
27741 ++
27742 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
27743 ++{
27744 ++ __u32 mode;
27745 ++
27746 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
27747 ++
27748 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
27749 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
27750 ++ return mode;
27751 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
27752 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
27753 ++ return 0;
27754 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
27755 ++ return 0;
27756 ++
27757 ++ return (reqmode);
27758 ++}
27759 ++
27760 ++__u32
27761 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
27762 ++{
27763 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
27764 ++}
27765 ++
27766 ++__u32
27767 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
27768 ++{
27769 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
27770 ++}
27771 ++
27772 ++__u32
27773 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
27774 ++{
27775 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
27776 ++}
27777 ++
27778 ++__u32
27779 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
27780 ++{
27781 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
27782 ++}
27783 ++
27784 ++__u32
27785 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
27786 ++ mode_t mode)
27787 ++{
27788 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
27789 ++ return 1;
27790 ++
27791 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
27792 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
27793 ++ GR_FCHMOD_ACL_MSG);
27794 ++ } else {
27795 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
27796 ++ }
27797 ++}
27798 ++
27799 ++__u32
27800 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
27801 ++ mode_t mode)
27802 ++{
27803 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
27804 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
27805 ++ GR_CHMOD_ACL_MSG);
27806 ++ } else {
27807 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
27808 ++ }
27809 ++}
27810 ++
27811 ++__u32
27812 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
27813 ++{
27814 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
27815 ++}
27816 ++
27817 ++__u32
27818 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
27819 ++{
27820 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
27821 ++}
27822 ++
27823 ++__u32
27824 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
27825 ++{
27826 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
27827 ++ GR_UNIXCONNECT_ACL_MSG);
27828 ++}
27829 ++
27830 ++/* hardlinks require at minimum create permission,
27831 ++ any additional privilege required is based on the
27832 ++ privilege of the file being linked to
27833 ++*/
27834 ++__u32
27835 ++gr_acl_handle_link(const struct dentry * new_dentry,
27836 ++ const struct dentry * parent_dentry,
27837 ++ const struct vfsmount * parent_mnt,
27838 ++ const struct dentry * old_dentry,
27839 ++ const struct vfsmount * old_mnt, const char *to)
27840 ++{
27841 ++ __u32 mode;
27842 ++ __u32 needmode = GR_CREATE | GR_LINK;
27843 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
27844 ++
27845 ++ mode =
27846 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
27847 ++ old_mnt);
27848 ++
27849 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
27850 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
27851 ++ return mode;
27852 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
27853 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
27854 ++ return 0;
27855 ++ } else if (unlikely((mode & needmode) != needmode))
27856 ++ return 0;
27857 ++
27858 ++ return 1;
27859 ++}
27860 ++
27861 ++__u32
27862 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
27863 ++ const struct dentry * parent_dentry,
27864 ++ const struct vfsmount * parent_mnt, const char *from)
27865 ++{
27866 ++ __u32 needmode = GR_WRITE | GR_CREATE;
27867 ++ __u32 mode;
27868 ++
27869 ++ mode =
27870 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
27871 ++ GR_CREATE | GR_AUDIT_CREATE |
27872 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
27873 ++
27874 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
27875 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
27876 ++ return mode;
27877 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
27878 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
27879 ++ return 0;
27880 ++ } else if (unlikely((mode & needmode) != needmode))
27881 ++ return 0;
27882 ++
27883 ++ return (GR_WRITE | GR_CREATE);
27884 ++}
27885 ++
27886 ++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)
27887 ++{
27888 ++ __u32 mode;
27889 ++
27890 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
27891 ++
27892 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
27893 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
27894 ++ return mode;
27895 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
27896 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
27897 ++ return 0;
27898 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
27899 ++ return 0;
27900 ++
27901 ++ return (reqmode);
27902 ++}
27903 ++
27904 ++__u32
27905 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
27906 ++ const struct dentry * parent_dentry,
27907 ++ const struct vfsmount * parent_mnt,
27908 ++ const int mode)
27909 ++{
27910 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
27911 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
27912 ++ reqmode |= GR_SETID;
27913 ++
27914 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
27915 ++ reqmode, GR_MKNOD_ACL_MSG);
27916 ++}
27917 ++
27918 ++__u32
27919 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
27920 ++ const struct dentry *parent_dentry,
27921 ++ const struct vfsmount *parent_mnt)
27922 ++{
27923 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
27924 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
27925 ++}
27926 ++
27927 ++#define RENAME_CHECK_SUCCESS(old, new) \
27928 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
27929 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
27930 ++
27931 ++int
27932 ++gr_acl_handle_rename(struct dentry *new_dentry,
27933 ++ struct dentry *parent_dentry,
27934 ++ const struct vfsmount *parent_mnt,
27935 ++ struct dentry *old_dentry,
27936 ++ struct inode *old_parent_inode,
27937 ++ struct vfsmount *old_mnt, const char *newname)
27938 ++{
27939 ++ __u32 comp1, comp2;
27940 ++ int error = 0;
27941 ++
27942 ++ if (unlikely(!gr_acl_is_enabled()))
27943 ++ return 0;
27944 ++
27945 ++ if (!new_dentry->d_inode) {
27946 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
27947 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
27948 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
27949 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
27950 ++ GR_DELETE | GR_AUDIT_DELETE |
27951 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
27952 ++ GR_SUPPRESS, old_mnt);
27953 ++ } else {
27954 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
27955 ++ GR_CREATE | GR_DELETE |
27956 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
27957 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
27958 ++ GR_SUPPRESS, parent_mnt);
27959 ++ comp2 =
27960 ++ gr_search_file(old_dentry,
27961 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
27962 ++ GR_DELETE | GR_AUDIT_DELETE |
27963 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
27964 ++ }
27965 ++
27966 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
27967 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
27968 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
27969 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
27970 ++ && !(comp2 & GR_SUPPRESS)) {
27971 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
27972 ++ error = -EACCES;
27973 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
27974 ++ error = -EACCES;
27975 ++
27976 ++ return error;
27977 ++}
27978 ++
27979 ++void
27980 ++gr_acl_handle_exit(void)
27981 ++{
27982 ++ u16 id;
27983 ++ char *rolename;
27984 ++ struct file *exec_file;
27985 ++
27986 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
27987 ++ id = current->acl_role_id;
27988 ++ rolename = current->role->rolename;
27989 ++ gr_set_acls(1);
27990 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
27991 ++ }
27992 ++
27993 ++ write_lock(&grsec_exec_file_lock);
27994 ++ exec_file = current->exec_file;
27995 ++ current->exec_file = NULL;
27996 ++ write_unlock(&grsec_exec_file_lock);
27997 ++
27998 ++ if (exec_file)
27999 ++ fput(exec_file);
28000 ++}
28001 ++
28002 ++int
28003 ++gr_acl_handle_procpidmem(const struct task_struct *task)
28004 ++{
28005 ++ if (unlikely(!gr_acl_is_enabled()))
28006 ++ return 0;
28007 ++
28008 ++ if (task != current && task->acl->mode & GR_PROTPROCFD)
28009 ++ return -EACCES;
28010 ++
28011 ++ return 0;
28012 ++}
28013 +diff -urNp a/grsecurity/gracl_ip.c b/grsecurity/gracl_ip.c
28014 +--- a/grsecurity/gracl_ip.c 1969-12-31 16:00:00.000000000 -0800
28015 ++++ b/grsecurity/gracl_ip.c 2008-08-20 18:36:57.000000000 -0700
28016 +@@ -0,0 +1,313 @@
28017 ++#include <linux/kernel.h>
28018 ++#include <asm/uaccess.h>
28019 ++#include <asm/errno.h>
28020 ++#include <net/sock.h>
28021 ++#include <linux/file.h>
28022 ++#include <linux/fs.h>
28023 ++#include <linux/net.h>
28024 ++#include <linux/in.h>
28025 ++#include <linux/skbuff.h>
28026 ++#include <linux/ip.h>
28027 ++#include <linux/udp.h>
28028 ++#include <linux/smp_lock.h>
28029 ++#include <linux/types.h>
28030 ++#include <linux/sched.h>
28031 ++#include <linux/netdevice.h>
28032 ++#include <linux/inetdevice.h>
28033 ++#include <linux/gracl.h>
28034 ++#include <linux/grsecurity.h>
28035 ++#include <linux/grinternal.h>
28036 ++
28037 ++#define GR_BIND 0x01
28038 ++#define GR_CONNECT 0x02
28039 ++#define GR_INVERT 0x04
28040 ++
28041 ++static const char * gr_protocols[256] = {
28042 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
28043 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
28044 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
28045 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
28046 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
28047 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
28048 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
28049 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
28050 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
28051 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
28052 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
28053 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
28054 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
28055 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
28056 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
28057 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
28058 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
28059 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
28060 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
28061 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
28062 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
28063 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
28064 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
28065 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
28066 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
28067 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
28068 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
28069 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
28070 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
28071 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
28072 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
28073 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
28074 ++ };
28075 ++
28076 ++static const char * gr_socktypes[11] = {
28077 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
28078 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
28079 ++ };
28080 ++
28081 ++const char *
28082 ++gr_proto_to_name(unsigned char proto)
28083 ++{
28084 ++ return gr_protocols[proto];
28085 ++}
28086 ++
28087 ++const char *
28088 ++gr_socktype_to_name(unsigned char type)
28089 ++{
28090 ++ return gr_socktypes[type];
28091 ++}
28092 ++
28093 ++int
28094 ++gr_search_socket(const int domain, const int type, const int protocol)
28095 ++{
28096 ++ struct acl_subject_label *curr;
28097 ++
28098 ++ if (unlikely(!gr_acl_is_enabled()))
28099 ++ goto exit;
28100 ++
28101 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
28102 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
28103 ++ goto exit; // let the kernel handle it
28104 ++
28105 ++ curr = current->acl;
28106 ++
28107 ++ if (!curr->ips)
28108 ++ goto exit;
28109 ++
28110 ++ if ((curr->ip_type & (1 << type)) &&
28111 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
28112 ++ goto exit;
28113 ++
28114 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
28115 ++ /* we don't place acls on raw sockets , and sometimes
28116 ++ dgram/ip sockets are opened for ioctl and not
28117 ++ bind/connect, so we'll fake a bind learn log */
28118 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
28119 ++ __u32 fakeip = 0;
28120 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28121 ++ current->role->roletype, current->uid,
28122 ++ current->gid, current->exec_file ?
28123 ++ gr_to_filename(current->exec_file->f_path.dentry,
28124 ++ current->exec_file->f_path.mnt) :
28125 ++ curr->filename, curr->filename,
28126 ++ NIPQUAD(fakeip), 0, type,
28127 ++ protocol, GR_CONNECT,
28128 ++NIPQUAD(current->signal->curr_ip));
28129 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
28130 ++ __u32 fakeip = 0;
28131 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28132 ++ current->role->roletype, current->uid,
28133 ++ current->gid, current->exec_file ?
28134 ++ gr_to_filename(current->exec_file->f_path.dentry,
28135 ++ current->exec_file->f_path.mnt) :
28136 ++ curr->filename, curr->filename,
28137 ++ NIPQUAD(fakeip), 0, type,
28138 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
28139 ++ }
28140 ++ /* we'll log when they use connect or bind */
28141 ++ goto exit;
28142 ++ }
28143 ++
28144 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
28145 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
28146 ++
28147 ++ return 0;
28148 ++ exit:
28149 ++ return 1;
28150 ++}
28151 ++
28152 ++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)
28153 ++{
28154 ++ if ((ip->mode & mode) &&
28155 ++ (ip_port >= ip->low) &&
28156 ++ (ip_port <= ip->high) &&
28157 ++ ((ntohl(ip_addr) & our_netmask) ==
28158 ++ (ntohl(our_addr) & our_netmask))
28159 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
28160 ++ && (ip->type & (1 << type))) {
28161 ++ if (ip->mode & GR_INVERT)
28162 ++ return 2; // specifically denied
28163 ++ else
28164 ++ return 1; // allowed
28165 ++ }
28166 ++
28167 ++ return 0; // not specifically allowed, may continue parsing
28168 ++}
28169 ++
28170 ++static int
28171 ++gr_search_connectbind(const int mode, const struct sock *sk,
28172 ++ const struct sockaddr_in *addr, const int type)
28173 ++{
28174 ++ char iface[IFNAMSIZ] = {0};
28175 ++ struct acl_subject_label *curr;
28176 ++ struct acl_ip_label *ip;
28177 ++ struct net_device *dev;
28178 ++ struct in_device *idev;
28179 ++ unsigned long i;
28180 ++ int ret;
28181 ++ __u32 ip_addr = 0;
28182 ++ __u32 our_addr;
28183 ++ __u32 our_netmask;
28184 ++ char *p;
28185 ++ __u16 ip_port = 0;
28186 ++
28187 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
28188 ++ return 1;
28189 ++
28190 ++ curr = current->acl;
28191 ++
28192 ++ if (!curr->ips)
28193 ++ return 1;
28194 ++
28195 ++ ip_addr = addr->sin_addr.s_addr;
28196 ++ ip_port = ntohs(addr->sin_port);
28197 ++
28198 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
28199 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28200 ++ current->role->roletype, current->uid,
28201 ++ current->gid, current->exec_file ?
28202 ++ gr_to_filename(current->exec_file->f_path.dentry,
28203 ++ current->exec_file->f_path.mnt) :
28204 ++ curr->filename, curr->filename,
28205 ++ NIPQUAD(ip_addr), ip_port, type,
28206 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
28207 ++ return 1;
28208 ++ }
28209 ++
28210 ++ for (i = 0; i < curr->ip_num; i++) {
28211 ++ ip = *(curr->ips + i);
28212 ++ if (ip->iface != NULL) {
28213 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
28214 ++ p = strchr(iface, ':');
28215 ++ if (p != NULL)
28216 ++ *p = '\0';
28217 ++ dev = dev_get_by_name(sk->sk_net, iface);
28218 ++ if (dev == NULL)
28219 ++ continue;
28220 ++ idev = in_dev_get(dev);
28221 ++ if (idev == NULL) {
28222 ++ dev_put(dev);
28223 ++ continue;
28224 ++ }
28225 ++ rcu_read_lock();
28226 ++ for_ifa(idev) {
28227 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
28228 ++ our_addr = ifa->ifa_address;
28229 ++ our_netmask = 0xffffffff;
28230 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
28231 ++ if (ret == 1) {
28232 ++ rcu_read_unlock();
28233 ++ in_dev_put(idev);
28234 ++ dev_put(dev);
28235 ++ return 1;
28236 ++ } else if (ret == 2) {
28237 ++ rcu_read_unlock();
28238 ++ in_dev_put(idev);
28239 ++ dev_put(dev);
28240 ++ goto denied;
28241 ++ }
28242 ++ }
28243 ++ } endfor_ifa(idev);
28244 ++ rcu_read_unlock();
28245 ++ in_dev_put(idev);
28246 ++ dev_put(dev);
28247 ++ } else {
28248 ++ our_addr = ip->addr;
28249 ++ our_netmask = ip->netmask;
28250 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
28251 ++ if (ret == 1)
28252 ++ return 1;
28253 ++ else if (ret == 2)
28254 ++ goto denied;
28255 ++ }
28256 ++ }
28257 ++
28258 ++denied:
28259 ++ if (mode == GR_BIND)
28260 ++ 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));
28261 ++ else if (mode == GR_CONNECT)
28262 ++ 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));
28263 ++
28264 ++ return 0;
28265 ++}
28266 ++
28267 ++int
28268 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
28269 ++{
28270 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
28271 ++}
28272 ++
28273 ++int
28274 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
28275 ++{
28276 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
28277 ++}
28278 ++
28279 ++int gr_search_listen(const struct socket *sock)
28280 ++{
28281 ++ struct sock *sk = sock->sk;
28282 ++ struct sockaddr_in addr;
28283 ++
28284 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
28285 ++ addr.sin_port = inet_sk(sk)->sport;
28286 ++
28287 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
28288 ++}
28289 ++
28290 ++int gr_search_accept(const struct socket *sock)
28291 ++{
28292 ++ struct sock *sk = sock->sk;
28293 ++ struct sockaddr_in addr;
28294 ++
28295 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
28296 ++ addr.sin_port = inet_sk(sk)->sport;
28297 ++
28298 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
28299 ++}
28300 ++
28301 ++int
28302 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
28303 ++{
28304 ++ if (addr)
28305 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
28306 ++ else {
28307 ++ struct sockaddr_in sin;
28308 ++ const struct inet_sock *inet = inet_sk(sk);
28309 ++
28310 ++ sin.sin_addr.s_addr = inet->daddr;
28311 ++ sin.sin_port = inet->dport;
28312 ++
28313 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
28314 ++ }
28315 ++}
28316 ++
28317 ++int
28318 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
28319 ++{
28320 ++ struct sockaddr_in sin;
28321 ++
28322 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
28323 ++ return 1; // skip this packet
28324 ++
28325 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
28326 ++ sin.sin_port = udp_hdr(skb)->source;
28327 ++
28328 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
28329 ++}
28330 +diff -urNp a/grsecurity/gracl_learn.c b/grsecurity/gracl_learn.c
28331 +--- a/grsecurity/gracl_learn.c 1969-12-31 16:00:00.000000000 -0800
28332 ++++ b/grsecurity/gracl_learn.c 2008-08-20 18:36:57.000000000 -0700
28333 +@@ -0,0 +1,211 @@
28334 ++#include <linux/kernel.h>
28335 ++#include <linux/mm.h>
28336 ++#include <linux/sched.h>
28337 ++#include <linux/poll.h>
28338 ++#include <linux/smp_lock.h>
28339 ++#include <linux/string.h>
28340 ++#include <linux/file.h>
28341 ++#include <linux/types.h>
28342 ++#include <linux/vmalloc.h>
28343 ++#include <linux/grinternal.h>
28344 ++
28345 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
28346 ++ size_t count, loff_t *ppos);
28347 ++extern int gr_acl_is_enabled(void);
28348 ++
28349 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
28350 ++static int gr_learn_attached;
28351 ++
28352 ++/* use a 512k buffer */
28353 ++#define LEARN_BUFFER_SIZE (512 * 1024)
28354 ++
28355 ++static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
28356 ++static DECLARE_MUTEX(gr_learn_user_sem);
28357 ++
28358 ++/* we need to maintain two buffers, so that the kernel context of grlearn
28359 ++ uses a semaphore around the userspace copying, and the other kernel contexts
28360 ++ use a spinlock when copying into the buffer, since they cannot sleep
28361 ++*/
28362 ++static char *learn_buffer;
28363 ++static char *learn_buffer_user;
28364 ++static int learn_buffer_len;
28365 ++static int learn_buffer_user_len;
28366 ++
28367 ++static ssize_t
28368 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
28369 ++{
28370 ++ DECLARE_WAITQUEUE(wait, current);
28371 ++ ssize_t retval = 0;
28372 ++
28373 ++ add_wait_queue(&learn_wait, &wait);
28374 ++ set_current_state(TASK_INTERRUPTIBLE);
28375 ++ do {
28376 ++ down(&gr_learn_user_sem);
28377 ++ spin_lock(&gr_learn_lock);
28378 ++ if (learn_buffer_len)
28379 ++ break;
28380 ++ spin_unlock(&gr_learn_lock);
28381 ++ up(&gr_learn_user_sem);
28382 ++ if (file->f_flags & O_NONBLOCK) {
28383 ++ retval = -EAGAIN;
28384 ++ goto out;
28385 ++ }
28386 ++ if (signal_pending(current)) {
28387 ++ retval = -ERESTARTSYS;
28388 ++ goto out;
28389 ++ }
28390 ++
28391 ++ schedule();
28392 ++ } while (1);
28393 ++
28394 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
28395 ++ learn_buffer_user_len = learn_buffer_len;
28396 ++ retval = learn_buffer_len;
28397 ++ learn_buffer_len = 0;
28398 ++
28399 ++ spin_unlock(&gr_learn_lock);
28400 ++
28401 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
28402 ++ retval = -EFAULT;
28403 ++
28404 ++ up(&gr_learn_user_sem);
28405 ++out:
28406 ++ set_current_state(TASK_RUNNING);
28407 ++ remove_wait_queue(&learn_wait, &wait);
28408 ++ return retval;
28409 ++}
28410 ++
28411 ++static unsigned int
28412 ++poll_learn(struct file * file, poll_table * wait)
28413 ++{
28414 ++ poll_wait(file, &learn_wait, wait);
28415 ++
28416 ++ if (learn_buffer_len)
28417 ++ return (POLLIN | POLLRDNORM);
28418 ++
28419 ++ return 0;
28420 ++}
28421 ++
28422 ++void
28423 ++gr_clear_learn_entries(void)
28424 ++{
28425 ++ char *tmp;
28426 ++
28427 ++ down(&gr_learn_user_sem);
28428 ++ if (learn_buffer != NULL) {
28429 ++ spin_lock(&gr_learn_lock);
28430 ++ tmp = learn_buffer;
28431 ++ learn_buffer = NULL;
28432 ++ spin_unlock(&gr_learn_lock);
28433 ++ vfree(learn_buffer);
28434 ++ }
28435 ++ if (learn_buffer_user != NULL) {
28436 ++ vfree(learn_buffer_user);
28437 ++ learn_buffer_user = NULL;
28438 ++ }
28439 ++ learn_buffer_len = 0;
28440 ++ up(&gr_learn_user_sem);
28441 ++
28442 ++ return;
28443 ++}
28444 ++
28445 ++void
28446 ++gr_add_learn_entry(const char *fmt, ...)
28447 ++{
28448 ++ va_list args;
28449 ++ unsigned int len;
28450 ++
28451 ++ if (!gr_learn_attached)
28452 ++ return;
28453 ++
28454 ++ spin_lock(&gr_learn_lock);
28455 ++
28456 ++ /* leave a gap at the end so we know when it's "full" but don't have to
28457 ++ compute the exact length of the string we're trying to append
28458 ++ */
28459 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
28460 ++ spin_unlock(&gr_learn_lock);
28461 ++ wake_up_interruptible(&learn_wait);
28462 ++ return;
28463 ++ }
28464 ++ if (learn_buffer == NULL) {
28465 ++ spin_unlock(&gr_learn_lock);
28466 ++ return;
28467 ++ }
28468 ++
28469 ++ va_start(args, fmt);
28470 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
28471 ++ va_end(args);
28472 ++
28473 ++ learn_buffer_len += len + 1;
28474 ++
28475 ++ spin_unlock(&gr_learn_lock);
28476 ++ wake_up_interruptible(&learn_wait);
28477 ++
28478 ++ return;
28479 ++}
28480 ++
28481 ++static int
28482 ++open_learn(struct inode *inode, struct file *file)
28483 ++{
28484 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
28485 ++ return -EBUSY;
28486 ++ if (file->f_mode & FMODE_READ) {
28487 ++ int retval = 0;
28488 ++ down(&gr_learn_user_sem);
28489 ++ if (learn_buffer == NULL)
28490 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
28491 ++ if (learn_buffer_user == NULL)
28492 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
28493 ++ if (learn_buffer == NULL) {
28494 ++ retval = -ENOMEM;
28495 ++ goto out_error;
28496 ++ }
28497 ++ if (learn_buffer_user == NULL) {
28498 ++ retval = -ENOMEM;
28499 ++ goto out_error;
28500 ++ }
28501 ++ learn_buffer_len = 0;
28502 ++ learn_buffer_user_len = 0;
28503 ++ gr_learn_attached = 1;
28504 ++out_error:
28505 ++ up(&gr_learn_user_sem);
28506 ++ return retval;
28507 ++ }
28508 ++ return 0;
28509 ++}
28510 ++
28511 ++static int
28512 ++close_learn(struct inode *inode, struct file *file)
28513 ++{
28514 ++ char *tmp;
28515 ++
28516 ++ if (file->f_mode & FMODE_READ) {
28517 ++ down(&gr_learn_user_sem);
28518 ++ if (learn_buffer != NULL) {
28519 ++ spin_lock(&gr_learn_lock);
28520 ++ tmp = learn_buffer;
28521 ++ learn_buffer = NULL;
28522 ++ spin_unlock(&gr_learn_lock);
28523 ++ vfree(tmp);
28524 ++ }
28525 ++ if (learn_buffer_user != NULL) {
28526 ++ vfree(learn_buffer_user);
28527 ++ learn_buffer_user = NULL;
28528 ++ }
28529 ++ learn_buffer_len = 0;
28530 ++ learn_buffer_user_len = 0;
28531 ++ gr_learn_attached = 0;
28532 ++ up(&gr_learn_user_sem);
28533 ++ }
28534 ++
28535 ++ return 0;
28536 ++}
28537 ++
28538 ++struct file_operations grsec_fops = {
28539 ++ .read = read_learn,
28540 ++ .write = write_grsec_handler,
28541 ++ .open = open_learn,
28542 ++ .release = close_learn,
28543 ++ .poll = poll_learn,
28544 ++};
28545 +diff -urNp a/grsecurity/gracl_res.c b/grsecurity/gracl_res.c
28546 +--- a/grsecurity/gracl_res.c 1969-12-31 16:00:00.000000000 -0800
28547 ++++ b/grsecurity/gracl_res.c 2008-08-20 18:36:57.000000000 -0700
28548 +@@ -0,0 +1,45 @@
28549 ++#include <linux/kernel.h>
28550 ++#include <linux/sched.h>
28551 ++#include <linux/gracl.h>
28552 ++#include <linux/grinternal.h>
28553 ++
28554 ++static const char *restab_log[] = {
28555 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
28556 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
28557 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
28558 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
28559 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
28560 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
28561 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
28562 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
28563 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
28564 ++ [RLIMIT_AS] = "RLIMIT_AS",
28565 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
28566 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
28567 ++};
28568 ++
28569 ++void
28570 ++gr_log_resource(const struct task_struct *task,
28571 ++ const int res, const unsigned long wanted, const int gt)
28572 ++{
28573 ++ if (res == RLIMIT_NPROC &&
28574 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
28575 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
28576 ++ return;
28577 ++ else if (res == RLIMIT_MEMLOCK &&
28578 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
28579 ++ return;
28580 ++
28581 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
28582 ++ return;
28583 ++
28584 ++ preempt_disable();
28585 ++
28586 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
28587 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
28588 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
28589 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
28590 ++ preempt_enable_no_resched();
28591 ++
28592 ++ return;
28593 ++}
28594 +diff -urNp a/grsecurity/gracl_segv.c b/grsecurity/gracl_segv.c
28595 +--- a/grsecurity/gracl_segv.c 1969-12-31 16:00:00.000000000 -0800
28596 ++++ b/grsecurity/gracl_segv.c 2008-08-20 18:36:57.000000000 -0700
28597 +@@ -0,0 +1,301 @@
28598 ++#include <linux/kernel.h>
28599 ++#include <linux/mm.h>
28600 ++#include <asm/uaccess.h>
28601 ++#include <asm/errno.h>
28602 ++#include <asm/mman.h>
28603 ++#include <net/sock.h>
28604 ++#include <linux/file.h>
28605 ++#include <linux/fs.h>
28606 ++#include <linux/net.h>
28607 ++#include <linux/in.h>
28608 ++#include <linux/smp_lock.h>
28609 ++#include <linux/slab.h>
28610 ++#include <linux/types.h>
28611 ++#include <linux/sched.h>
28612 ++#include <linux/timer.h>
28613 ++#include <linux/gracl.h>
28614 ++#include <linux/grsecurity.h>
28615 ++#include <linux/grinternal.h>
28616 ++
28617 ++static struct crash_uid *uid_set;
28618 ++static unsigned short uid_used;
28619 ++static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
28620 ++extern rwlock_t gr_inode_lock;
28621 ++extern struct acl_subject_label *
28622 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
28623 ++ struct acl_role_label *role);
28624 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
28625 ++
28626 ++int
28627 ++gr_init_uidset(void)
28628 ++{
28629 ++ uid_set =
28630 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
28631 ++ uid_used = 0;
28632 ++
28633 ++ return uid_set ? 1 : 0;
28634 ++}
28635 ++
28636 ++void
28637 ++gr_free_uidset(void)
28638 ++{
28639 ++ if (uid_set)
28640 ++ kfree(uid_set);
28641 ++
28642 ++ return;
28643 ++}
28644 ++
28645 ++int
28646 ++gr_find_uid(const uid_t uid)
28647 ++{
28648 ++ struct crash_uid *tmp = uid_set;
28649 ++ uid_t buid;
28650 ++ int low = 0, high = uid_used - 1, mid;
28651 ++
28652 ++ while (high >= low) {
28653 ++ mid = (low + high) >> 1;
28654 ++ buid = tmp[mid].uid;
28655 ++ if (buid == uid)
28656 ++ return mid;
28657 ++ if (buid > uid)
28658 ++ high = mid - 1;
28659 ++ if (buid < uid)
28660 ++ low = mid + 1;
28661 ++ }
28662 ++
28663 ++ return -1;
28664 ++}
28665 ++
28666 ++static __inline__ void
28667 ++gr_insertsort(void)
28668 ++{
28669 ++ unsigned short i, j;
28670 ++ struct crash_uid index;
28671 ++
28672 ++ for (i = 1; i < uid_used; i++) {
28673 ++ index = uid_set[i];
28674 ++ j = i;
28675 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
28676 ++ uid_set[j] = uid_set[j - 1];
28677 ++ j--;
28678 ++ }
28679 ++ uid_set[j] = index;
28680 ++ }
28681 ++
28682 ++ return;
28683 ++}
28684 ++
28685 ++static __inline__ void
28686 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
28687 ++{
28688 ++ int loc;
28689 ++
28690 ++ if (uid_used == GR_UIDTABLE_MAX)
28691 ++ return;
28692 ++
28693 ++ loc = gr_find_uid(uid);
28694 ++
28695 ++ if (loc >= 0) {
28696 ++ uid_set[loc].expires = expires;
28697 ++ return;
28698 ++ }
28699 ++
28700 ++ uid_set[uid_used].uid = uid;
28701 ++ uid_set[uid_used].expires = expires;
28702 ++ uid_used++;
28703 ++
28704 ++ gr_insertsort();
28705 ++
28706 ++ return;
28707 ++}
28708 ++
28709 ++void
28710 ++gr_remove_uid(const unsigned short loc)
28711 ++{
28712 ++ unsigned short i;
28713 ++
28714 ++ for (i = loc + 1; i < uid_used; i++)
28715 ++ uid_set[i - 1] = uid_set[i];
28716 ++
28717 ++ uid_used--;
28718 ++
28719 ++ return;
28720 ++}
28721 ++
28722 ++int
28723 ++gr_check_crash_uid(const uid_t uid)
28724 ++{
28725 ++ int loc;
28726 ++ int ret = 0;
28727 ++
28728 ++ if (unlikely(!gr_acl_is_enabled()))
28729 ++ return 0;
28730 ++
28731 ++ spin_lock(&gr_uid_lock);
28732 ++ loc = gr_find_uid(uid);
28733 ++
28734 ++ if (loc < 0)
28735 ++ goto out_unlock;
28736 ++
28737 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
28738 ++ gr_remove_uid(loc);
28739 ++ else
28740 ++ ret = 1;
28741 ++
28742 ++out_unlock:
28743 ++ spin_unlock(&gr_uid_lock);
28744 ++ return ret;
28745 ++}
28746 ++
28747 ++static __inline__ int
28748 ++proc_is_setxid(const struct task_struct *task)
28749 ++{
28750 ++ if (task->uid != task->euid || task->uid != task->suid ||
28751 ++ task->uid != task->fsuid)
28752 ++ return 1;
28753 ++ if (task->gid != task->egid || task->gid != task->sgid ||
28754 ++ task->gid != task->fsgid)
28755 ++ return 1;
28756 ++
28757 ++ return 0;
28758 ++}
28759 ++static __inline__ int
28760 ++gr_fake_force_sig(int sig, struct task_struct *t)
28761 ++{
28762 ++ unsigned long int flags;
28763 ++ int ret, blocked, ignored;
28764 ++ struct k_sigaction *action;
28765 ++
28766 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
28767 ++ action = &t->sighand->action[sig-1];
28768 ++ ignored = action->sa.sa_handler == SIG_IGN;
28769 ++ blocked = sigismember(&t->blocked, sig);
28770 ++ if (blocked || ignored) {
28771 ++ action->sa.sa_handler = SIG_DFL;
28772 ++ if (blocked) {
28773 ++ sigdelset(&t->blocked, sig);
28774 ++ recalc_sigpending_and_wake(t);
28775 ++ }
28776 ++ }
28777 ++ ret = specific_send_sig_info(sig, (void*)1L, t);
28778 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
28779 ++
28780 ++ return ret;
28781 ++}
28782 ++
28783 ++void
28784 ++gr_handle_crash(struct task_struct *task, const int sig)
28785 ++{
28786 ++ struct acl_subject_label *curr;
28787 ++ struct acl_subject_label *curr2;
28788 ++ struct task_struct *tsk, *tsk2;
28789 ++
28790 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
28791 ++ return;
28792 ++
28793 ++ if (unlikely(!gr_acl_is_enabled()))
28794 ++ return;
28795 ++
28796 ++ curr = task->acl;
28797 ++
28798 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
28799 ++ return;
28800 ++
28801 ++ if (time_before_eq(curr->expires, get_seconds())) {
28802 ++ curr->expires = 0;
28803 ++ curr->crashes = 0;
28804 ++ }
28805 ++
28806 ++ curr->crashes++;
28807 ++
28808 ++ if (!curr->expires)
28809 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
28810 ++
28811 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
28812 ++ time_after(curr->expires, get_seconds())) {
28813 ++ if (task->uid && proc_is_setxid(task)) {
28814 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
28815 ++ spin_lock(&gr_uid_lock);
28816 ++ gr_insert_uid(task->uid, curr->expires);
28817 ++ spin_unlock(&gr_uid_lock);
28818 ++ curr->expires = 0;
28819 ++ curr->crashes = 0;
28820 ++ read_lock(&tasklist_lock);
28821 ++ do_each_thread(tsk2, tsk) {
28822 ++ if (tsk != task && tsk->uid == task->uid)
28823 ++ gr_fake_force_sig(SIGKILL, tsk);
28824 ++ } while_each_thread(tsk2, tsk);
28825 ++ read_unlock(&tasklist_lock);
28826 ++ } else {
28827 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
28828 ++ read_lock(&tasklist_lock);
28829 ++ do_each_thread(tsk2, tsk) {
28830 ++ if (likely(tsk != task)) {
28831 ++ curr2 = tsk->acl;
28832 ++
28833 ++ if (curr2->device == curr->device &&
28834 ++ curr2->inode == curr->inode)
28835 ++ gr_fake_force_sig(SIGKILL, tsk);
28836 ++ }
28837 ++ } while_each_thread(tsk2, tsk);
28838 ++ read_unlock(&tasklist_lock);
28839 ++ }
28840 ++ }
28841 ++
28842 ++ return;
28843 ++}
28844 ++
28845 ++int
28846 ++gr_check_crash_exec(const struct file *filp)
28847 ++{
28848 ++ struct acl_subject_label *curr;
28849 ++
28850 ++ if (unlikely(!gr_acl_is_enabled()))
28851 ++ return 0;
28852 ++
28853 ++ read_lock(&gr_inode_lock);
28854 ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
28855 ++ filp->f_path.dentry->d_inode->i_sb->s_dev,
28856 ++ current->role);
28857 ++ read_unlock(&gr_inode_lock);
28858 ++
28859 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
28860 ++ (!curr->crashes && !curr->expires))
28861 ++ return 0;
28862 ++
28863 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
28864 ++ time_after(curr->expires, get_seconds()))
28865 ++ return 1;
28866 ++ else if (time_before_eq(curr->expires, get_seconds())) {
28867 ++ curr->crashes = 0;
28868 ++ curr->expires = 0;
28869 ++ }
28870 ++
28871 ++ return 0;
28872 ++}
28873 ++
28874 ++void
28875 ++gr_handle_alertkill(struct task_struct *task)
28876 ++{
28877 ++ struct acl_subject_label *curracl;
28878 ++ __u32 curr_ip;
28879 ++ struct task_struct *p, *p2;
28880 ++
28881 ++ if (unlikely(!gr_acl_is_enabled()))
28882 ++ return;
28883 ++
28884 ++ curracl = task->acl;
28885 ++ curr_ip = task->signal->curr_ip;
28886 ++
28887 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
28888 ++ read_lock(&tasklist_lock);
28889 ++ do_each_thread(p2, p) {
28890 ++ if (p->signal->curr_ip == curr_ip)
28891 ++ gr_fake_force_sig(SIGKILL, p);
28892 ++ } while_each_thread(p2, p);
28893 ++ read_unlock(&tasklist_lock);
28894 ++ } else if (curracl->mode & GR_KILLPROC)
28895 ++ gr_fake_force_sig(SIGKILL, task);
28896 ++
28897 ++ return;
28898 ++}
28899 +diff -urNp a/grsecurity/gracl_shm.c b/grsecurity/gracl_shm.c
28900 +--- a/grsecurity/gracl_shm.c 1969-12-31 16:00:00.000000000 -0800
28901 ++++ b/grsecurity/gracl_shm.c 2008-08-20 18:36:57.000000000 -0700
28902 +@@ -0,0 +1,33 @@
28903 ++#include <linux/kernel.h>
28904 ++#include <linux/mm.h>
28905 ++#include <linux/sched.h>
28906 ++#include <linux/file.h>
28907 ++#include <linux/ipc.h>
28908 ++#include <linux/gracl.h>
28909 ++#include <linux/grsecurity.h>
28910 ++#include <linux/grinternal.h>
28911 ++
28912 ++int
28913 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
28914 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
28915 ++{
28916 ++ struct task_struct *task;
28917 ++
28918 ++ if (!gr_acl_is_enabled())
28919 ++ return 1;
28920 ++
28921 ++ task = find_task_by_pid(shm_cprid);
28922 ++
28923 ++ if (unlikely(!task))
28924 ++ task = find_task_by_pid(shm_lapid);
28925 ++
28926 ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
28927 ++ (task->pid == shm_lapid)) &&
28928 ++ (task->acl->mode & GR_PROTSHM) &&
28929 ++ (task->acl != current->acl))) {
28930 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
28931 ++ return 0;
28932 ++ }
28933 ++
28934 ++ return 1;
28935 ++}
28936 +diff -urNp a/grsecurity/grsec_chdir.c b/grsecurity/grsec_chdir.c
28937 +--- a/grsecurity/grsec_chdir.c 1969-12-31 16:00:00.000000000 -0800
28938 ++++ b/grsecurity/grsec_chdir.c 2008-08-20 18:36:57.000000000 -0700
28939 +@@ -0,0 +1,19 @@
28940 ++#include <linux/kernel.h>
28941 ++#include <linux/sched.h>
28942 ++#include <linux/fs.h>
28943 ++#include <linux/file.h>
28944 ++#include <linux/grsecurity.h>
28945 ++#include <linux/grinternal.h>
28946 ++
28947 ++void
28948 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
28949 ++{
28950 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
28951 ++ if ((grsec_enable_chdir && grsec_enable_group &&
28952 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
28953 ++ !grsec_enable_group)) {
28954 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
28955 ++ }
28956 ++#endif
28957 ++ return;
28958 ++}
28959 +diff -urNp a/grsecurity/grsec_chroot.c b/grsecurity/grsec_chroot.c
28960 +--- a/grsecurity/grsec_chroot.c 1969-12-31 16:00:00.000000000 -0800
28961 ++++ b/grsecurity/grsec_chroot.c 2008-08-20 18:36:57.000000000 -0700
28962 +@@ -0,0 +1,336 @@
28963 ++#include <linux/kernel.h>
28964 ++#include <linux/module.h>
28965 ++#include <linux/sched.h>
28966 ++#include <linux/file.h>
28967 ++#include <linux/fs.h>
28968 ++#include <linux/mount.h>
28969 ++#include <linux/types.h>
28970 ++#include <linux/pid_namespace.h>
28971 ++#include <linux/grsecurity.h>
28972 ++#include <linux/grinternal.h>
28973 ++
28974 ++int
28975 ++gr_handle_chroot_unix(const pid_t pid)
28976 ++{
28977 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
28978 ++ struct pid *spid = NULL;
28979 ++
28980 ++ if (unlikely(!grsec_enable_chroot_unix))
28981 ++ return 1;
28982 ++
28983 ++ if (likely(!proc_is_chrooted(current)))
28984 ++ return 1;
28985 ++
28986 ++ read_lock(&tasklist_lock);
28987 ++
28988 ++ spid = find_pid(pid);
28989 ++ if (spid) {
28990 ++ struct task_struct *p;
28991 ++ p = pid_task(spid, PIDTYPE_PID);
28992 ++ task_lock(p);
28993 ++ if (unlikely(!have_same_root(current, p))) {
28994 ++ task_unlock(p);
28995 ++ read_unlock(&tasklist_lock);
28996 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
28997 ++ return 0;
28998 ++ }
28999 ++ task_unlock(p);
29000 ++ }
29001 ++ read_unlock(&tasklist_lock);
29002 ++#endif
29003 ++ return 1;
29004 ++}
29005 ++
29006 ++int
29007 ++gr_handle_chroot_nice(void)
29008 ++{
29009 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
29010 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
29011 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
29012 ++ return -EPERM;
29013 ++ }
29014 ++#endif
29015 ++ return 0;
29016 ++}
29017 ++
29018 ++int
29019 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
29020 ++{
29021 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
29022 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
29023 ++ && proc_is_chrooted(current)) {
29024 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
29025 ++ return -EACCES;
29026 ++ }
29027 ++#endif
29028 ++ return 0;
29029 ++}
29030 ++
29031 ++int
29032 ++gr_handle_chroot_rawio(const struct inode *inode)
29033 ++{
29034 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
29035 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
29036 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
29037 ++ return 1;
29038 ++#endif
29039 ++ return 0;
29040 ++}
29041 ++
29042 ++int
29043 ++gr_pid_is_chrooted(struct task_struct *p)
29044 ++{
29045 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
29046 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
29047 ++ return 0;
29048 ++
29049 ++ task_lock(p);
29050 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
29051 ++ !have_same_root(current, p)) {
29052 ++ task_unlock(p);
29053 ++ return 1;
29054 ++ }
29055 ++ task_unlock(p);
29056 ++#endif
29057 ++ return 0;
29058 ++}
29059 ++
29060 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
29061 ++
29062 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
29063 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
29064 ++{
29065 ++ struct dentry *dentry = (struct dentry *)u_dentry;
29066 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
29067 ++ struct dentry *realroot;
29068 ++ struct vfsmount *realrootmnt;
29069 ++ struct dentry *currentroot;
29070 ++ struct vfsmount *currentmnt;
29071 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
29072 ++ int ret = 1;
29073 ++
29074 ++ read_lock(&reaper->fs->lock);
29075 ++ realrootmnt = mntget(reaper->fs->root.mnt);
29076 ++ realroot = dget(reaper->fs->root.dentry);
29077 ++ read_unlock(&reaper->fs->lock);
29078 ++
29079 ++ read_lock(&current->fs->lock);
29080 ++ currentmnt = mntget(current->fs->root.mnt);
29081 ++ currentroot = dget(current->fs->root.dentry);
29082 ++ read_unlock(&current->fs->lock);
29083 ++
29084 ++ spin_lock(&dcache_lock);
29085 ++ for (;;) {
29086 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
29087 ++ || (dentry == currentroot && mnt == currentmnt)))
29088 ++ break;
29089 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
29090 ++ if (mnt->mnt_parent == mnt)
29091 ++ break;
29092 ++ dentry = mnt->mnt_mountpoint;
29093 ++ mnt = mnt->mnt_parent;
29094 ++ continue;
29095 ++ }
29096 ++ dentry = dentry->d_parent;
29097 ++ }
29098 ++ spin_unlock(&dcache_lock);
29099 ++
29100 ++ dput(currentroot);
29101 ++ mntput(currentmnt);
29102 ++
29103 ++ /* access is outside of chroot */
29104 ++ if (dentry == realroot && mnt == realrootmnt)
29105 ++ ret = 0;
29106 ++
29107 ++ dput(realroot);
29108 ++ mntput(realrootmnt);
29109 ++ return ret;
29110 ++}
29111 ++#endif
29112 ++
29113 ++int
29114 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
29115 ++{
29116 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
29117 ++ if (!grsec_enable_chroot_fchdir)
29118 ++ return 1;
29119 ++
29120 ++ if (!proc_is_chrooted(current))
29121 ++ return 1;
29122 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
29123 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
29124 ++ return 0;
29125 ++ }
29126 ++#endif
29127 ++ return 1;
29128 ++}
29129 ++
29130 ++int
29131 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29132 ++ const time_t shm_createtime)
29133 ++{
29134 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
29135 ++ struct pid *pid = NULL;
29136 ++ time_t starttime;
29137 ++
29138 ++ if (unlikely(!grsec_enable_chroot_shmat))
29139 ++ return 1;
29140 ++
29141 ++ if (likely(!proc_is_chrooted(current)))
29142 ++ return 1;
29143 ++
29144 ++ read_lock(&tasklist_lock);
29145 ++
29146 ++ pid = find_pid(shm_cprid);
29147 ++ if (pid) {
29148 ++ struct task_struct *p;
29149 ++ p = pid_task(pid, PIDTYPE_PID);
29150 ++ task_lock(p);
29151 ++ starttime = p->start_time.tv_sec;
29152 ++ if (unlikely(!have_same_root(current, p) &&
29153 ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
29154 ++ task_unlock(p);
29155 ++ read_unlock(&tasklist_lock);
29156 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
29157 ++ return 0;
29158 ++ }
29159 ++ task_unlock(p);
29160 ++ } else {
29161 ++ pid = find_pid(shm_lapid);
29162 ++ if (pid) {
29163 ++ struct task_struct *p;
29164 ++ p = pid_task(pid, PIDTYPE_PID);
29165 ++ task_lock(p);
29166 ++ if (unlikely(!have_same_root(current, p))) {
29167 ++ task_unlock(p);
29168 ++ read_unlock(&tasklist_lock);
29169 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
29170 ++ return 0;
29171 ++ }
29172 ++ task_unlock(p);
29173 ++ }
29174 ++ }
29175 ++
29176 ++ read_unlock(&tasklist_lock);
29177 ++#endif
29178 ++ return 1;
29179 ++}
29180 ++
29181 ++void
29182 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
29183 ++{
29184 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
29185 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
29186 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
29187 ++#endif
29188 ++ return;
29189 ++}
29190 ++
29191 ++int
29192 ++gr_handle_chroot_mknod(const struct dentry *dentry,
29193 ++ const struct vfsmount *mnt, const int mode)
29194 ++{
29195 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
29196 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
29197 ++ proc_is_chrooted(current)) {
29198 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
29199 ++ return -EPERM;
29200 ++ }
29201 ++#endif
29202 ++ return 0;
29203 ++}
29204 ++
29205 ++int
29206 ++gr_handle_chroot_mount(const struct dentry *dentry,
29207 ++ const struct vfsmount *mnt, const char *dev_name)
29208 ++{
29209 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
29210 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
29211 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
29212 ++ return -EPERM;
29213 ++ }
29214 ++#endif
29215 ++ return 0;
29216 ++}
29217 ++
29218 ++int
29219 ++gr_handle_chroot_pivot(void)
29220 ++{
29221 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
29222 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
29223 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
29224 ++ return -EPERM;
29225 ++ }
29226 ++#endif
29227 ++ return 0;
29228 ++}
29229 ++
29230 ++int
29231 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
29232 ++{
29233 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
29234 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
29235 ++ !gr_is_outside_chroot(dentry, mnt)) {
29236 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
29237 ++ return -EPERM;
29238 ++ }
29239 ++#endif
29240 ++ return 0;
29241 ++}
29242 ++
29243 ++void
29244 ++gr_handle_chroot_caps(struct task_struct *task)
29245 ++{
29246 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
29247 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
29248 ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
29249 ++ task->cap_permitted =
29250 ++ cap_drop(task->cap_permitted, chroot_caps);
29251 ++ task->cap_inheritable =
29252 ++ cap_drop(task->cap_inheritable, chroot_caps);
29253 ++ task->cap_effective =
29254 ++ cap_drop(task->cap_effective, chroot_caps);
29255 ++ }
29256 ++#endif
29257 ++ return;
29258 ++}
29259 ++
29260 ++int
29261 ++gr_handle_chroot_sysctl(const int op)
29262 ++{
29263 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
29264 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
29265 ++ && (op & 002))
29266 ++ return -EACCES;
29267 ++#endif
29268 ++ return 0;
29269 ++}
29270 ++
29271 ++void
29272 ++gr_handle_chroot_chdir(struct path *path)
29273 ++{
29274 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
29275 ++ if (grsec_enable_chroot_chdir)
29276 ++ set_fs_pwd(current->fs, path);
29277 ++#endif
29278 ++ return;
29279 ++}
29280 ++
29281 ++int
29282 ++gr_handle_chroot_chmod(const struct dentry *dentry,
29283 ++ const struct vfsmount *mnt, const int mode)
29284 ++{
29285 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
29286 ++ if (grsec_enable_chroot_chmod &&
29287 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
29288 ++ proc_is_chrooted(current)) {
29289 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
29290 ++ return -EPERM;
29291 ++ }
29292 ++#endif
29293 ++ return 0;
29294 ++}
29295 ++
29296 ++#ifdef CONFIG_SECURITY
29297 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
29298 ++#endif
29299 +diff -urNp a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
29300 +--- a/grsecurity/grsec_disabled.c 1969-12-31 16:00:00.000000000 -0800
29301 ++++ b/grsecurity/grsec_disabled.c 2008-08-20 18:36:57.000000000 -0700
29302 +@@ -0,0 +1,418 @@
29303 ++#include <linux/kernel.h>
29304 ++#include <linux/module.h>
29305 ++#include <linux/sched.h>
29306 ++#include <linux/file.h>
29307 ++#include <linux/fs.h>
29308 ++#include <linux/kdev_t.h>
29309 ++#include <linux/net.h>
29310 ++#include <linux/in.h>
29311 ++#include <linux/ip.h>
29312 ++#include <linux/skbuff.h>
29313 ++#include <linux/sysctl.h>
29314 ++
29315 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29316 ++void
29317 ++pax_set_initial_flags(struct linux_binprm *bprm)
29318 ++{
29319 ++ return;
29320 ++}
29321 ++#endif
29322 ++
29323 ++#ifdef CONFIG_SYSCTL
29324 ++__u32
29325 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
29326 ++{
29327 ++ return 0;
29328 ++}
29329 ++#endif
29330 ++
29331 ++int
29332 ++gr_acl_is_enabled(void)
29333 ++{
29334 ++ return 0;
29335 ++}
29336 ++
29337 ++int
29338 ++gr_handle_rawio(const struct inode *inode)
29339 ++{
29340 ++ return 0;
29341 ++}
29342 ++
29343 ++void
29344 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
29345 ++{
29346 ++ return;
29347 ++}
29348 ++
29349 ++int
29350 ++gr_handle_ptrace(struct task_struct *task, const long request)
29351 ++{
29352 ++ return 0;
29353 ++}
29354 ++
29355 ++int
29356 ++gr_handle_proc_ptrace(struct task_struct *task)
29357 ++{
29358 ++ return 0;
29359 ++}
29360 ++
29361 ++void
29362 ++gr_learn_resource(const struct task_struct *task,
29363 ++ const int res, const unsigned long wanted, const int gt)
29364 ++{
29365 ++ return;
29366 ++}
29367 ++
29368 ++int
29369 ++gr_set_acls(const int type)
29370 ++{
29371 ++ return 0;
29372 ++}
29373 ++
29374 ++int
29375 ++gr_check_hidden_task(const struct task_struct *tsk)
29376 ++{
29377 ++ return 0;
29378 ++}
29379 ++
29380 ++int
29381 ++gr_check_protected_task(const struct task_struct *task)
29382 ++{
29383 ++ return 0;
29384 ++}
29385 ++
29386 ++void
29387 ++gr_copy_label(struct task_struct *tsk)
29388 ++{
29389 ++ return;
29390 ++}
29391 ++
29392 ++void
29393 ++gr_set_pax_flags(struct task_struct *task)
29394 ++{
29395 ++ return;
29396 ++}
29397 ++
29398 ++int
29399 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
29400 ++{
29401 ++ return 0;
29402 ++}
29403 ++
29404 ++void
29405 ++gr_handle_delete(const ino_t ino, const dev_t dev)
29406 ++{
29407 ++ return;
29408 ++}
29409 ++
29410 ++void
29411 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
29412 ++{
29413 ++ return;
29414 ++}
29415 ++
29416 ++void
29417 ++gr_handle_crash(struct task_struct *task, const int sig)
29418 ++{
29419 ++ return;
29420 ++}
29421 ++
29422 ++int
29423 ++gr_check_crash_exec(const struct file *filp)
29424 ++{
29425 ++ return 0;
29426 ++}
29427 ++
29428 ++int
29429 ++gr_check_crash_uid(const uid_t uid)
29430 ++{
29431 ++ return 0;
29432 ++}
29433 ++
29434 ++void
29435 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
29436 ++ struct dentry *old_dentry,
29437 ++ struct dentry *new_dentry,
29438 ++ struct vfsmount *mnt, const __u8 replace)
29439 ++{
29440 ++ return;
29441 ++}
29442 ++
29443 ++int
29444 ++gr_search_socket(const int family, const int type, const int protocol)
29445 ++{
29446 ++ return 1;
29447 ++}
29448 ++
29449 ++int
29450 ++gr_search_connectbind(const int mode, const struct socket *sock,
29451 ++ const struct sockaddr_in *addr)
29452 ++{
29453 ++ return 1;
29454 ++}
29455 ++
29456 ++int
29457 ++gr_task_is_capable(struct task_struct *task, const int cap)
29458 ++{
29459 ++ return 1;
29460 ++}
29461 ++
29462 ++int
29463 ++gr_is_capable_nolog(const int cap)
29464 ++{
29465 ++ return 1;
29466 ++}
29467 ++
29468 ++void
29469 ++gr_handle_alertkill(struct task_struct *task)
29470 ++{
29471 ++ return;
29472 ++}
29473 ++
29474 ++__u32
29475 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
29476 ++{
29477 ++ return 1;
29478 ++}
29479 ++
29480 ++__u32
29481 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
29482 ++ const struct vfsmount * mnt)
29483 ++{
29484 ++ return 1;
29485 ++}
29486 ++
29487 ++__u32
29488 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
29489 ++ const int fmode)
29490 ++{
29491 ++ return 1;
29492 ++}
29493 ++
29494 ++__u32
29495 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
29496 ++{
29497 ++ return 1;
29498 ++}
29499 ++
29500 ++__u32
29501 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
29502 ++{
29503 ++ return 1;
29504 ++}
29505 ++
29506 ++int
29507 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
29508 ++ unsigned int *vm_flags)
29509 ++{
29510 ++ return 1;
29511 ++}
29512 ++
29513 ++__u32
29514 ++gr_acl_handle_truncate(const struct dentry * dentry,
29515 ++ const struct vfsmount * mnt)
29516 ++{
29517 ++ return 1;
29518 ++}
29519 ++
29520 ++__u32
29521 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
29522 ++{
29523 ++ return 1;
29524 ++}
29525 ++
29526 ++__u32
29527 ++gr_acl_handle_access(const struct dentry * dentry,
29528 ++ const struct vfsmount * mnt, const int fmode)
29529 ++{
29530 ++ return 1;
29531 ++}
29532 ++
29533 ++__u32
29534 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
29535 ++ mode_t mode)
29536 ++{
29537 ++ return 1;
29538 ++}
29539 ++
29540 ++__u32
29541 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
29542 ++ mode_t mode)
29543 ++{
29544 ++ return 1;
29545 ++}
29546 ++
29547 ++__u32
29548 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
29549 ++{
29550 ++ return 1;
29551 ++}
29552 ++
29553 ++void
29554 ++grsecurity_init(void)
29555 ++{
29556 ++ return;
29557 ++}
29558 ++
29559 ++__u32
29560 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
29561 ++ const struct dentry * parent_dentry,
29562 ++ const struct vfsmount * parent_mnt,
29563 ++ const int mode)
29564 ++{
29565 ++ return 1;
29566 ++}
29567 ++
29568 ++__u32
29569 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
29570 ++ const struct dentry * parent_dentry,
29571 ++ const struct vfsmount * parent_mnt)
29572 ++{
29573 ++ return 1;
29574 ++}
29575 ++
29576 ++__u32
29577 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
29578 ++ const struct dentry * parent_dentry,
29579 ++ const struct vfsmount * parent_mnt, const char *from)
29580 ++{
29581 ++ return 1;
29582 ++}
29583 ++
29584 ++__u32
29585 ++gr_acl_handle_link(const struct dentry * new_dentry,
29586 ++ const struct dentry * parent_dentry,
29587 ++ const struct vfsmount * parent_mnt,
29588 ++ const struct dentry * old_dentry,
29589 ++ const struct vfsmount * old_mnt, const char *to)
29590 ++{
29591 ++ return 1;
29592 ++}
29593 ++
29594 ++int
29595 ++gr_acl_handle_rename(const struct dentry *new_dentry,
29596 ++ const struct dentry *parent_dentry,
29597 ++ const struct vfsmount *parent_mnt,
29598 ++ const struct dentry *old_dentry,
29599 ++ const struct inode *old_parent_inode,
29600 ++ const struct vfsmount *old_mnt, const char *newname)
29601 ++{
29602 ++ return 0;
29603 ++}
29604 ++
29605 ++int
29606 ++gr_acl_handle_filldir(const struct file *file, const char *name,
29607 ++ const int namelen, const ino_t ino)
29608 ++{
29609 ++ return 1;
29610 ++}
29611 ++
29612 ++int
29613 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29614 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
29615 ++{
29616 ++ return 1;
29617 ++}
29618 ++
29619 ++int
29620 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
29621 ++{
29622 ++ return 1;
29623 ++}
29624 ++
29625 ++int
29626 ++gr_search_accept(const struct socket *sock)
29627 ++{
29628 ++ return 1;
29629 ++}
29630 ++
29631 ++int
29632 ++gr_search_listen(const struct socket *sock)
29633 ++{
29634 ++ return 1;
29635 ++}
29636 ++
29637 ++int
29638 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
29639 ++{
29640 ++ return 1;
29641 ++}
29642 ++
29643 ++__u32
29644 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
29645 ++{
29646 ++ return 1;
29647 ++}
29648 ++
29649 ++__u32
29650 ++gr_acl_handle_creat(const struct dentry * dentry,
29651 ++ const struct dentry * p_dentry,
29652 ++ const struct vfsmount * p_mnt, const int fmode,
29653 ++ const int imode)
29654 ++{
29655 ++ return 1;
29656 ++}
29657 ++
29658 ++void
29659 ++gr_acl_handle_exit(void)
29660 ++{
29661 ++ return;
29662 ++}
29663 ++
29664 ++int
29665 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
29666 ++{
29667 ++ return 1;
29668 ++}
29669 ++
29670 ++void
29671 ++gr_set_role_label(const uid_t uid, const gid_t gid)
29672 ++{
29673 ++ return;
29674 ++}
29675 ++
29676 ++int
29677 ++gr_acl_handle_procpidmem(const struct task_struct *task)
29678 ++{
29679 ++ return 0;
29680 ++}
29681 ++
29682 ++int
29683 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
29684 ++{
29685 ++ return 1;
29686 ++}
29687 ++
29688 ++int
29689 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
29690 ++{
29691 ++ return 1;
29692 ++}
29693 ++
29694 ++void
29695 ++gr_set_kernel_label(struct task_struct *task)
29696 ++{
29697 ++ return;
29698 ++}
29699 ++
29700 ++int
29701 ++gr_check_user_change(int real, int effective, int fs)
29702 ++{
29703 ++ return 0;
29704 ++}
29705 ++
29706 ++int
29707 ++gr_check_group_change(int real, int effective, int fs)
29708 ++{
29709 ++ return 0;
29710 ++}
29711 ++
29712 ++
29713 ++EXPORT_SYMBOL(gr_task_is_capable);
29714 ++EXPORT_SYMBOL(gr_is_capable_nolog);
29715 ++EXPORT_SYMBOL(gr_learn_resource);
29716 ++EXPORT_SYMBOL(gr_set_kernel_label);
29717 ++#ifdef CONFIG_SECURITY
29718 ++EXPORT_SYMBOL(gr_check_user_change);
29719 ++EXPORT_SYMBOL(gr_check_group_change);
29720 ++#endif
29721 +diff -urNp a/grsecurity/grsec_exec.c b/grsecurity/grsec_exec.c
29722 +--- a/grsecurity/grsec_exec.c 1969-12-31 16:00:00.000000000 -0800
29723 ++++ b/grsecurity/grsec_exec.c 2008-08-20 18:36:57.000000000 -0700
29724 +@@ -0,0 +1,88 @@
29725 ++#include <linux/kernel.h>
29726 ++#include <linux/sched.h>
29727 ++#include <linux/file.h>
29728 ++#include <linux/binfmts.h>
29729 ++#include <linux/smp_lock.h>
29730 ++#include <linux/fs.h>
29731 ++#include <linux/types.h>
29732 ++#include <linux/grdefs.h>
29733 ++#include <linux/grinternal.h>
29734 ++#include <linux/capability.h>
29735 ++
29736 ++#include <asm/uaccess.h>
29737 ++
29738 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
29739 ++static char gr_exec_arg_buf[132];
29740 ++static DECLARE_MUTEX(gr_exec_arg_sem);
29741 ++#endif
29742 ++
29743 ++int
29744 ++gr_handle_nproc(void)
29745 ++{
29746 ++#ifdef CONFIG_GRKERNSEC_EXECVE
29747 ++ if (grsec_enable_execve && current->user &&
29748 ++ (atomic_read(&current->user->processes) >
29749 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
29750 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
29751 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
29752 ++ return -EAGAIN;
29753 ++ }
29754 ++#endif
29755 ++ return 0;
29756 ++}
29757 ++
29758 ++void
29759 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
29760 ++{
29761 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
29762 ++ char *grarg = gr_exec_arg_buf;
29763 ++ unsigned int i, x, execlen = 0;
29764 ++ char c;
29765 ++
29766 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
29767 ++ in_group_p(grsec_audit_gid))
29768 ++ || (grsec_enable_execlog && !grsec_enable_group)))
29769 ++ return;
29770 ++
29771 ++ down(&gr_exec_arg_sem);
29772 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
29773 ++
29774 ++ if (unlikely(argv == NULL))
29775 ++ goto log;
29776 ++
29777 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
29778 ++ const char __user *p;
29779 ++ unsigned int len;
29780 ++
29781 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
29782 ++ goto log;
29783 ++ if (!p)
29784 ++ goto log;
29785 ++ len = strnlen_user(p, 128 - execlen);
29786 ++ if (len > 128 - execlen)
29787 ++ len = 128 - execlen;
29788 ++ else if (len > 0)
29789 ++ len--;
29790 ++ if (copy_from_user(grarg + execlen, p, len))
29791 ++ goto log;
29792 ++
29793 ++ /* rewrite unprintable characters */
29794 ++ for (x = 0; x < len; x++) {
29795 ++ c = *(grarg + execlen + x);
29796 ++ if (c < 32 || c > 126)
29797 ++ *(grarg + execlen + x) = ' ';
29798 ++ }
29799 ++
29800 ++ execlen += len;
29801 ++ *(grarg + execlen) = ' ';
29802 ++ *(grarg + execlen + 1) = '\0';
29803 ++ execlen++;
29804 ++ }
29805 ++
29806 ++ log:
29807 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
29808 ++ bprm->file->f_path.mnt, grarg);
29809 ++ up(&gr_exec_arg_sem);
29810 ++#endif
29811 ++ return;
29812 ++}
29813 +diff -urNp a/grsecurity/grsec_fifo.c b/grsecurity/grsec_fifo.c
29814 +--- a/grsecurity/grsec_fifo.c 1969-12-31 16:00:00.000000000 -0800
29815 ++++ b/grsecurity/grsec_fifo.c 2008-08-20 18:36:57.000000000 -0700
29816 +@@ -0,0 +1,22 @@
29817 ++#include <linux/kernel.h>
29818 ++#include <linux/sched.h>
29819 ++#include <linux/fs.h>
29820 ++#include <linux/file.h>
29821 ++#include <linux/grinternal.h>
29822 ++
29823 ++int
29824 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
29825 ++ const struct dentry *dir, const int flag, const int acc_mode)
29826 ++{
29827 ++#ifdef CONFIG_GRKERNSEC_FIFO
29828 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
29829 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
29830 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
29831 ++ (current->fsuid != dentry->d_inode->i_uid)) {
29832 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
29833 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
29834 ++ return -EACCES;
29835 ++ }
29836 ++#endif
29837 ++ return 0;
29838 ++}
29839 +diff -urNp a/grsecurity/grsec_fork.c b/grsecurity/grsec_fork.c
29840 +--- a/grsecurity/grsec_fork.c 1969-12-31 16:00:00.000000000 -0800
29841 ++++ b/grsecurity/grsec_fork.c 2008-08-20 18:36:57.000000000 -0700
29842 +@@ -0,0 +1,15 @@
29843 ++#include <linux/kernel.h>
29844 ++#include <linux/sched.h>
29845 ++#include <linux/grsecurity.h>
29846 ++#include <linux/grinternal.h>
29847 ++#include <linux/errno.h>
29848 ++
29849 ++void
29850 ++gr_log_forkfail(const int retval)
29851 ++{
29852 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
29853 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
29854 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
29855 ++#endif
29856 ++ return;
29857 ++}
29858 +diff -urNp a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c
29859 +--- a/grsecurity/grsec_init.c 1969-12-31 16:00:00.000000000 -0800
29860 ++++ b/grsecurity/grsec_init.c 2008-08-20 18:36:57.000000000 -0700
29861 +@@ -0,0 +1,226 @@
29862 ++#include <linux/kernel.h>
29863 ++#include <linux/sched.h>
29864 ++#include <linux/mm.h>
29865 ++#include <linux/smp_lock.h>
29866 ++#include <linux/gracl.h>
29867 ++#include <linux/slab.h>
29868 ++#include <linux/vmalloc.h>
29869 ++#include <linux/percpu.h>
29870 ++
29871 ++int grsec_enable_link;
29872 ++int grsec_enable_dmesg;
29873 ++int grsec_enable_fifo;
29874 ++int grsec_enable_execve;
29875 ++int grsec_enable_execlog;
29876 ++int grsec_enable_signal;
29877 ++int grsec_enable_forkfail;
29878 ++int grsec_enable_time;
29879 ++int grsec_enable_audit_textrel;
29880 ++int grsec_enable_group;
29881 ++int grsec_audit_gid;
29882 ++int grsec_enable_chdir;
29883 ++int grsec_enable_audit_ipc;
29884 ++int grsec_enable_mount;
29885 ++int grsec_enable_chroot_findtask;
29886 ++int grsec_enable_chroot_mount;
29887 ++int grsec_enable_chroot_shmat;
29888 ++int grsec_enable_chroot_fchdir;
29889 ++int grsec_enable_chroot_double;
29890 ++int grsec_enable_chroot_pivot;
29891 ++int grsec_enable_chroot_chdir;
29892 ++int grsec_enable_chroot_chmod;
29893 ++int grsec_enable_chroot_mknod;
29894 ++int grsec_enable_chroot_nice;
29895 ++int grsec_enable_chroot_execlog;
29896 ++int grsec_enable_chroot_caps;
29897 ++int grsec_enable_chroot_sysctl;
29898 ++int grsec_enable_chroot_unix;
29899 ++int grsec_enable_tpe;
29900 ++int grsec_tpe_gid;
29901 ++int grsec_enable_tpe_all;
29902 ++int grsec_enable_socket_all;
29903 ++int grsec_socket_all_gid;
29904 ++int grsec_enable_socket_client;
29905 ++int grsec_socket_client_gid;
29906 ++int grsec_enable_socket_server;
29907 ++int grsec_socket_server_gid;
29908 ++int grsec_resource_logging;
29909 ++int grsec_lock;
29910 ++
29911 ++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
29912 ++unsigned long grsec_alert_wtime = 0;
29913 ++unsigned long grsec_alert_fyet = 0;
29914 ++
29915 ++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
29916 ++
29917 ++rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
29918 ++
29919 ++char *gr_shared_page[4];
29920 ++
29921 ++char *gr_alert_log_fmt;
29922 ++char *gr_audit_log_fmt;
29923 ++char *gr_alert_log_buf;
29924 ++char *gr_audit_log_buf;
29925 ++
29926 ++extern struct gr_arg *gr_usermode;
29927 ++extern unsigned char *gr_system_salt;
29928 ++extern unsigned char *gr_system_sum;
29929 ++
29930 ++void
29931 ++grsecurity_init(void)
29932 ++{
29933 ++ int j;
29934 ++ /* create the per-cpu shared pages */
29935 ++
29936 ++ for (j = 0; j < 4; j++) {
29937 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
29938 ++ if (gr_shared_page[j] == NULL) {
29939 ++ panic("Unable to allocate grsecurity shared page");
29940 ++ return;
29941 ++ }
29942 ++ }
29943 ++
29944 ++ /* allocate log buffers */
29945 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
29946 ++ if (!gr_alert_log_fmt) {
29947 ++ panic("Unable to allocate grsecurity alert log format buffer");
29948 ++ return;
29949 ++ }
29950 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
29951 ++ if (!gr_audit_log_fmt) {
29952 ++ panic("Unable to allocate grsecurity audit log format buffer");
29953 ++ return;
29954 ++ }
29955 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
29956 ++ if (!gr_alert_log_buf) {
29957 ++ panic("Unable to allocate grsecurity alert log buffer");
29958 ++ return;
29959 ++ }
29960 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
29961 ++ if (!gr_audit_log_buf) {
29962 ++ panic("Unable to allocate grsecurity audit log buffer");
29963 ++ return;
29964 ++ }
29965 ++
29966 ++ /* allocate memory for authentication structure */
29967 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
29968 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
29969 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
29970 ++
29971 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
29972 ++ panic("Unable to allocate grsecurity authentication structure");
29973 ++ return;
29974 ++ }
29975 ++
29976 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
29977 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
29978 ++ grsec_lock = 1;
29979 ++#endif
29980 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
29981 ++ grsec_enable_audit_textrel = 1;
29982 ++#endif
29983 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
29984 ++ grsec_enable_group = 1;
29985 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
29986 ++#endif
29987 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
29988 ++ grsec_enable_chdir = 1;
29989 ++#endif
29990 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
29991 ++ grsec_enable_audit_ipc = 1;
29992 ++#endif
29993 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
29994 ++ grsec_enable_mount = 1;
29995 ++#endif
29996 ++#ifdef CONFIG_GRKERNSEC_LINK
29997 ++ grsec_enable_link = 1;
29998 ++#endif
29999 ++#ifdef CONFIG_GRKERNSEC_DMESG
30000 ++ grsec_enable_dmesg = 1;
30001 ++#endif
30002 ++#ifdef CONFIG_GRKERNSEC_FIFO
30003 ++ grsec_enable_fifo = 1;
30004 ++#endif
30005 ++#ifdef CONFIG_GRKERNSEC_EXECVE
30006 ++ grsec_enable_execve = 1;
30007 ++#endif
30008 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
30009 ++ grsec_enable_execlog = 1;
30010 ++#endif
30011 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
30012 ++ grsec_enable_signal = 1;
30013 ++#endif
30014 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
30015 ++ grsec_enable_forkfail = 1;
30016 ++#endif
30017 ++#ifdef CONFIG_GRKERNSEC_TIME
30018 ++ grsec_enable_time = 1;
30019 ++#endif
30020 ++#ifdef CONFIG_GRKERNSEC_RESLOG
30021 ++ grsec_resource_logging = 1;
30022 ++#endif
30023 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
30024 ++ grsec_enable_chroot_findtask = 1;
30025 ++#endif
30026 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
30027 ++ grsec_enable_chroot_unix = 1;
30028 ++#endif
30029 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
30030 ++ grsec_enable_chroot_mount = 1;
30031 ++#endif
30032 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
30033 ++ grsec_enable_chroot_fchdir = 1;
30034 ++#endif
30035 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
30036 ++ grsec_enable_chroot_shmat = 1;
30037 ++#endif
30038 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
30039 ++ grsec_enable_chroot_double = 1;
30040 ++#endif
30041 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
30042 ++ grsec_enable_chroot_pivot = 1;
30043 ++#endif
30044 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
30045 ++ grsec_enable_chroot_chdir = 1;
30046 ++#endif
30047 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
30048 ++ grsec_enable_chroot_chmod = 1;
30049 ++#endif
30050 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
30051 ++ grsec_enable_chroot_mknod = 1;
30052 ++#endif
30053 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
30054 ++ grsec_enable_chroot_nice = 1;
30055 ++#endif
30056 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
30057 ++ grsec_enable_chroot_execlog = 1;
30058 ++#endif
30059 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
30060 ++ grsec_enable_chroot_caps = 1;
30061 ++#endif
30062 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
30063 ++ grsec_enable_chroot_sysctl = 1;
30064 ++#endif
30065 ++#ifdef CONFIG_GRKERNSEC_TPE
30066 ++ grsec_enable_tpe = 1;
30067 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
30068 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
30069 ++ grsec_enable_tpe_all = 1;
30070 ++#endif
30071 ++#endif
30072 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
30073 ++ grsec_enable_socket_all = 1;
30074 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
30075 ++#endif
30076 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
30077 ++ grsec_enable_socket_client = 1;
30078 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
30079 ++#endif
30080 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30081 ++ grsec_enable_socket_server = 1;
30082 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
30083 ++#endif
30084 ++#endif
30085 ++
30086 ++ return;
30087 ++}
30088 +diff -urNp a/grsecurity/grsec_ipc.c b/grsecurity/grsec_ipc.c
30089 +--- a/grsecurity/grsec_ipc.c 1969-12-31 16:00:00.000000000 -0800
30090 ++++ b/grsecurity/grsec_ipc.c 2008-08-20 18:36:57.000000000 -0700
30091 +@@ -0,0 +1,81 @@
30092 ++#include <linux/kernel.h>
30093 ++#include <linux/sched.h>
30094 ++#include <linux/types.h>
30095 ++#include <linux/ipc.h>
30096 ++#include <linux/grsecurity.h>
30097 ++#include <linux/grinternal.h>
30098 ++
30099 ++void
30100 ++gr_log_msgget(const int ret, const int msgflg)
30101 ++{
30102 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30103 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30104 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30105 ++ !grsec_enable_group)) && (ret >= 0)
30106 ++ && (msgflg & IPC_CREAT))
30107 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
30108 ++#endif
30109 ++ return;
30110 ++}
30111 ++
30112 ++void
30113 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
30114 ++{
30115 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30116 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30117 ++ grsec_enable_audit_ipc) ||
30118 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30119 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
30120 ++#endif
30121 ++ return;
30122 ++}
30123 ++
30124 ++void
30125 ++gr_log_semget(const int err, const int semflg)
30126 ++{
30127 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30128 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30129 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30130 ++ !grsec_enable_group)) && (err >= 0)
30131 ++ && (semflg & IPC_CREAT))
30132 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
30133 ++#endif
30134 ++ return;
30135 ++}
30136 ++
30137 ++void
30138 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
30139 ++{
30140 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30141 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30142 ++ grsec_enable_audit_ipc) ||
30143 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30144 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
30145 ++#endif
30146 ++ return;
30147 ++}
30148 ++
30149 ++void
30150 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
30151 ++{
30152 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30153 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30154 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30155 ++ !grsec_enable_group)) && (err >= 0)
30156 ++ && (shmflg & IPC_CREAT))
30157 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
30158 ++#endif
30159 ++ return;
30160 ++}
30161 ++
30162 ++void
30163 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
30164 ++{
30165 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30166 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30167 ++ grsec_enable_audit_ipc) ||
30168 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30169 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
30170 ++#endif
30171 ++ return;
30172 ++}
30173 +diff -urNp a/grsecurity/grsec_link.c b/grsecurity/grsec_link.c
30174 +--- a/grsecurity/grsec_link.c 1969-12-31 16:00:00.000000000 -0800
30175 ++++ b/grsecurity/grsec_link.c 2008-08-20 18:36:57.000000000 -0700
30176 +@@ -0,0 +1,39 @@
30177 ++#include <linux/kernel.h>
30178 ++#include <linux/sched.h>
30179 ++#include <linux/fs.h>
30180 ++#include <linux/file.h>
30181 ++#include <linux/grinternal.h>
30182 ++
30183 ++int
30184 ++gr_handle_follow_link(const struct inode *parent,
30185 ++ const struct inode *inode,
30186 ++ const struct dentry *dentry, const struct vfsmount *mnt)
30187 ++{
30188 ++#ifdef CONFIG_GRKERNSEC_LINK
30189 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
30190 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
30191 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
30192 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
30193 ++ return -EACCES;
30194 ++ }
30195 ++#endif
30196 ++ return 0;
30197 ++}
30198 ++
30199 ++int
30200 ++gr_handle_hardlink(const struct dentry *dentry,
30201 ++ const struct vfsmount *mnt,
30202 ++ struct inode *inode, const int mode, const char *to)
30203 ++{
30204 ++#ifdef CONFIG_GRKERNSEC_LINK
30205 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
30206 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
30207 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
30208 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
30209 ++ !capable(CAP_FOWNER) && current->uid) {
30210 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
30211 ++ return -EPERM;
30212 ++ }
30213 ++#endif
30214 ++ return 0;
30215 ++}
30216 +diff -urNp a/grsecurity/grsec_log.c b/grsecurity/grsec_log.c
30217 +--- a/grsecurity/grsec_log.c 1969-12-31 16:00:00.000000000 -0800
30218 ++++ b/grsecurity/grsec_log.c 2008-08-20 18:36:57.000000000 -0700
30219 +@@ -0,0 +1,269 @@
30220 ++#include <linux/kernel.h>
30221 ++#include <linux/sched.h>
30222 ++#include <linux/file.h>
30223 ++#include <linux/tty.h>
30224 ++#include <linux/fs.h>
30225 ++#include <linux/grinternal.h>
30226 ++
30227 ++#define BEGIN_LOCKS(x) \
30228 ++ read_lock(&tasklist_lock); \
30229 ++ read_lock(&grsec_exec_file_lock); \
30230 ++ if (x != GR_DO_AUDIT) \
30231 ++ spin_lock(&grsec_alert_lock); \
30232 ++ else \
30233 ++ spin_lock(&grsec_audit_lock)
30234 ++
30235 ++#define END_LOCKS(x) \
30236 ++ if (x != GR_DO_AUDIT) \
30237 ++ spin_unlock(&grsec_alert_lock); \
30238 ++ else \
30239 ++ spin_unlock(&grsec_audit_lock); \
30240 ++ read_unlock(&grsec_exec_file_lock); \
30241 ++ read_unlock(&tasklist_lock); \
30242 ++ if (x == GR_DONT_AUDIT) \
30243 ++ gr_handle_alertkill(current)
30244 ++
30245 ++enum {
30246 ++ FLOODING,
30247 ++ NO_FLOODING
30248 ++};
30249 ++
30250 ++extern char *gr_alert_log_fmt;
30251 ++extern char *gr_audit_log_fmt;
30252 ++extern char *gr_alert_log_buf;
30253 ++extern char *gr_audit_log_buf;
30254 ++
30255 ++static int gr_log_start(int audit)
30256 ++{
30257 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
30258 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
30259 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30260 ++
30261 ++ if (audit == GR_DO_AUDIT)
30262 ++ goto set_fmt;
30263 ++
30264 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
30265 ++ grsec_alert_wtime = jiffies;
30266 ++ grsec_alert_fyet = 0;
30267 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
30268 ++ grsec_alert_fyet++;
30269 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
30270 ++ grsec_alert_wtime = jiffies;
30271 ++ grsec_alert_fyet++;
30272 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
30273 ++ return FLOODING;
30274 ++ } else return FLOODING;
30275 ++
30276 ++set_fmt:
30277 ++ memset(buf, 0, PAGE_SIZE);
30278 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
30279 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
30280 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
30281 ++ } else if (current->signal->curr_ip) {
30282 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
30283 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
30284 ++ } else if (gr_acl_is_enabled()) {
30285 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
30286 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
30287 ++ } else {
30288 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
30289 ++ strcpy(buf, fmt);
30290 ++ }
30291 ++
30292 ++ return NO_FLOODING;
30293 ++}
30294 ++
30295 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
30296 ++{
30297 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30298 ++ unsigned int len = strlen(buf);
30299 ++
30300 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
30301 ++
30302 ++ return;
30303 ++}
30304 ++
30305 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
30306 ++{
30307 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30308 ++ unsigned int len = strlen(buf);
30309 ++ va_list ap;
30310 ++
30311 ++ va_start(ap, msg);
30312 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
30313 ++ va_end(ap);
30314 ++
30315 ++ return;
30316 ++}
30317 ++
30318 ++static void gr_log_end(int audit)
30319 ++{
30320 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30321 ++ unsigned int len = strlen(buf);
30322 ++
30323 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
30324 ++ printk("%s\n", buf);
30325 ++
30326 ++ return;
30327 ++}
30328 ++
30329 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
30330 ++{
30331 ++ int logtype;
30332 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
30333 ++ char *str1, *str2, *str3;
30334 ++ int num1, num2;
30335 ++ unsigned long ulong1, ulong2;
30336 ++ struct dentry *dentry;
30337 ++ struct vfsmount *mnt;
30338 ++ struct file *file;
30339 ++ struct task_struct *task;
30340 ++ va_list ap;
30341 ++
30342 ++ BEGIN_LOCKS(audit);
30343 ++ logtype = gr_log_start(audit);
30344 ++ if (logtype == FLOODING) {
30345 ++ END_LOCKS(audit);
30346 ++ return;
30347 ++ }
30348 ++ va_start(ap, argtypes);
30349 ++ switch (argtypes) {
30350 ++ case GR_TTYSNIFF:
30351 ++ task = va_arg(ap, struct task_struct *);
30352 ++ 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);
30353 ++ break;
30354 ++ case GR_SYSCTL_HIDDEN:
30355 ++ str1 = va_arg(ap, char *);
30356 ++ gr_log_middle_varargs(audit, msg, result, str1);
30357 ++ break;
30358 ++ case GR_RBAC:
30359 ++ dentry = va_arg(ap, struct dentry *);
30360 ++ mnt = va_arg(ap, struct vfsmount *);
30361 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
30362 ++ break;
30363 ++ case GR_RBAC_STR:
30364 ++ dentry = va_arg(ap, struct dentry *);
30365 ++ mnt = va_arg(ap, struct vfsmount *);
30366 ++ str1 = va_arg(ap, char *);
30367 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
30368 ++ break;
30369 ++ case GR_STR_RBAC:
30370 ++ str1 = va_arg(ap, char *);
30371 ++ dentry = va_arg(ap, struct dentry *);
30372 ++ mnt = va_arg(ap, struct vfsmount *);
30373 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
30374 ++ break;
30375 ++ case GR_RBAC_MODE2:
30376 ++ dentry = va_arg(ap, struct dentry *);
30377 ++ mnt = va_arg(ap, struct vfsmount *);
30378 ++ str1 = va_arg(ap, char *);
30379 ++ str2 = va_arg(ap, char *);
30380 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
30381 ++ break;
30382 ++ case GR_RBAC_MODE3:
30383 ++ dentry = va_arg(ap, struct dentry *);
30384 ++ mnt = va_arg(ap, struct vfsmount *);
30385 ++ str1 = va_arg(ap, char *);
30386 ++ str2 = va_arg(ap, char *);
30387 ++ str3 = va_arg(ap, char *);
30388 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
30389 ++ break;
30390 ++ case GR_FILENAME:
30391 ++ dentry = va_arg(ap, struct dentry *);
30392 ++ mnt = va_arg(ap, struct vfsmount *);
30393 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
30394 ++ break;
30395 ++ case GR_STR_FILENAME:
30396 ++ str1 = va_arg(ap, char *);
30397 ++ dentry = va_arg(ap, struct dentry *);
30398 ++ mnt = va_arg(ap, struct vfsmount *);
30399 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
30400 ++ break;
30401 ++ case GR_FILENAME_STR:
30402 ++ dentry = va_arg(ap, struct dentry *);
30403 ++ mnt = va_arg(ap, struct vfsmount *);
30404 ++ str1 = va_arg(ap, char *);
30405 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
30406 ++ break;
30407 ++ case GR_FILENAME_TWO_INT:
30408 ++ dentry = va_arg(ap, struct dentry *);
30409 ++ mnt = va_arg(ap, struct vfsmount *);
30410 ++ num1 = va_arg(ap, int);
30411 ++ num2 = va_arg(ap, int);
30412 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
30413 ++ break;
30414 ++ case GR_FILENAME_TWO_INT_STR:
30415 ++ dentry = va_arg(ap, struct dentry *);
30416 ++ mnt = va_arg(ap, struct vfsmount *);
30417 ++ num1 = va_arg(ap, int);
30418 ++ num2 = va_arg(ap, int);
30419 ++ str1 = va_arg(ap, char *);
30420 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
30421 ++ break;
30422 ++ case GR_TEXTREL:
30423 ++ file = va_arg(ap, struct file *);
30424 ++ ulong1 = va_arg(ap, unsigned long);
30425 ++ ulong2 = va_arg(ap, unsigned long);
30426 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
30427 ++ break;
30428 ++ case GR_PTRACE:
30429 ++ task = va_arg(ap, struct task_struct *);
30430 ++ 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);
30431 ++ break;
30432 ++ case GR_RESOURCE:
30433 ++ task = va_arg(ap, struct task_struct *);
30434 ++ ulong1 = va_arg(ap, unsigned long);
30435 ++ str1 = va_arg(ap, char *);
30436 ++ ulong2 = va_arg(ap, unsigned long);
30437 ++ 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);
30438 ++ break;
30439 ++ case GR_CAP:
30440 ++ task = va_arg(ap, struct task_struct *);
30441 ++ str1 = va_arg(ap, char *);
30442 ++ 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);
30443 ++ break;
30444 ++ case GR_SIG:
30445 ++ task = va_arg(ap, struct task_struct *);
30446 ++ num1 = va_arg(ap, int);
30447 ++ 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);
30448 ++ break;
30449 ++ case GR_CRASH1:
30450 ++ task = va_arg(ap, struct task_struct *);
30451 ++ ulong1 = va_arg(ap, unsigned long);
30452 ++ 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);
30453 ++ break;
30454 ++ case GR_CRASH2:
30455 ++ task = va_arg(ap, struct task_struct *);
30456 ++ ulong1 = va_arg(ap, unsigned long);
30457 ++ 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);
30458 ++ break;
30459 ++ case GR_PSACCT:
30460 ++ {
30461 ++ unsigned int wday, cday;
30462 ++ __u8 whr, chr;
30463 ++ __u8 wmin, cmin;
30464 ++ __u8 wsec, csec;
30465 ++ char cur_tty[64] = { 0 };
30466 ++ char parent_tty[64] = { 0 };
30467 ++
30468 ++ task = va_arg(ap, struct task_struct *);
30469 ++ wday = va_arg(ap, unsigned int);
30470 ++ cday = va_arg(ap, unsigned int);
30471 ++ whr = va_arg(ap, int);
30472 ++ chr = va_arg(ap, int);
30473 ++ wmin = va_arg(ap, int);
30474 ++ cmin = va_arg(ap, int);
30475 ++ wsec = va_arg(ap, int);
30476 ++ csec = va_arg(ap, int);
30477 ++ ulong1 = va_arg(ap, unsigned long);
30478 ++
30479 ++ 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);
30480 ++ }
30481 ++ break;
30482 ++ default:
30483 ++ gr_log_middle(audit, msg, ap);
30484 ++ }
30485 ++ va_end(ap);
30486 ++ gr_log_end(audit);
30487 ++ END_LOCKS(audit);
30488 ++}
30489 +diff -urNp a/grsecurity/grsec_mem.c b/grsecurity/grsec_mem.c
30490 +--- a/grsecurity/grsec_mem.c 1969-12-31 16:00:00.000000000 -0800
30491 ++++ b/grsecurity/grsec_mem.c 2008-08-20 18:36:57.000000000 -0700
30492 +@@ -0,0 +1,71 @@
30493 ++#include <linux/kernel.h>
30494 ++#include <linux/sched.h>
30495 ++#include <linux/mm.h>
30496 ++#include <linux/mman.h>
30497 ++#include <linux/grinternal.h>
30498 ++
30499 ++void
30500 ++gr_handle_ioperm(void)
30501 ++{
30502 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
30503 ++ return;
30504 ++}
30505 ++
30506 ++void
30507 ++gr_handle_iopl(void)
30508 ++{
30509 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
30510 ++ return;
30511 ++}
30512 ++
30513 ++void
30514 ++gr_handle_mem_write(void)
30515 ++{
30516 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
30517 ++ return;
30518 ++}
30519 ++
30520 ++void
30521 ++gr_handle_kmem_write(void)
30522 ++{
30523 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
30524 ++ return;
30525 ++}
30526 ++
30527 ++void
30528 ++gr_handle_open_port(void)
30529 ++{
30530 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
30531 ++ return;
30532 ++}
30533 ++
30534 ++int
30535 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
30536 ++{
30537 ++ unsigned long start, end;
30538 ++
30539 ++ start = offset;
30540 ++ end = start + vma->vm_end - vma->vm_start;
30541 ++
30542 ++ if (start > end) {
30543 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
30544 ++ return -EPERM;
30545 ++ }
30546 ++
30547 ++ /* allowed ranges : ISA I/O BIOS */
30548 ++ if ((start >= __pa(high_memory))
30549 ++#ifdef CONFIG_X86
30550 ++ || (start >= 0x000a0000 && end <= 0x00100000)
30551 ++ || (start >= 0x00000000 && end <= 0x00001000)
30552 ++#endif
30553 ++ )
30554 ++ return 0;
30555 ++
30556 ++ if (vma->vm_flags & VM_WRITE) {
30557 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
30558 ++ return -EPERM;
30559 ++ } else
30560 ++ vma->vm_flags &= ~VM_MAYWRITE;
30561 ++
30562 ++ return 0;
30563 ++}
30564 +diff -urNp a/grsecurity/grsec_mount.c b/grsecurity/grsec_mount.c
30565 +--- a/grsecurity/grsec_mount.c 1969-12-31 16:00:00.000000000 -0800
30566 ++++ b/grsecurity/grsec_mount.c 2008-08-20 18:36:57.000000000 -0700
30567 +@@ -0,0 +1,34 @@
30568 ++#include <linux/kernel.h>
30569 ++#include <linux/sched.h>
30570 ++#include <linux/grsecurity.h>
30571 ++#include <linux/grinternal.h>
30572 ++
30573 ++void
30574 ++gr_log_remount(const char *devname, const int retval)
30575 ++{
30576 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30577 ++ if (grsec_enable_mount && (retval >= 0))
30578 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
30579 ++#endif
30580 ++ return;
30581 ++}
30582 ++
30583 ++void
30584 ++gr_log_unmount(const char *devname, const int retval)
30585 ++{
30586 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30587 ++ if (grsec_enable_mount && (retval >= 0))
30588 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
30589 ++#endif
30590 ++ return;
30591 ++}
30592 ++
30593 ++void
30594 ++gr_log_mount(const char *from, const char *to, const int retval)
30595 ++{
30596 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30597 ++ if (grsec_enable_mount && (retval >= 0))
30598 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
30599 ++#endif
30600 ++ return;
30601 ++}
30602 +diff -urNp a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c
30603 +--- a/grsecurity/grsec_sig.c 1969-12-31 16:00:00.000000000 -0800
30604 ++++ b/grsecurity/grsec_sig.c 2008-08-20 18:36:57.000000000 -0700
30605 +@@ -0,0 +1,58 @@
30606 ++#include <linux/kernel.h>
30607 ++#include <linux/sched.h>
30608 ++#include <linux/delay.h>
30609 ++#include <linux/grsecurity.h>
30610 ++#include <linux/grinternal.h>
30611 ++
30612 ++void
30613 ++gr_log_signal(const int sig, const struct task_struct *t)
30614 ++{
30615 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
30616 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
30617 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
30618 ++ if (t->pid == current->pid) {
30619 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
30620 ++ } else {
30621 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
30622 ++ }
30623 ++ }
30624 ++#endif
30625 ++ return;
30626 ++}
30627 ++
30628 ++int
30629 ++gr_handle_signal(const struct task_struct *p, const int sig)
30630 ++{
30631 ++#ifdef CONFIG_GRKERNSEC
30632 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
30633 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
30634 ++ return -EPERM;
30635 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
30636 ++ return -EPERM;
30637 ++ }
30638 ++#endif
30639 ++ return 0;
30640 ++}
30641 ++
30642 ++void gr_handle_brute_attach(struct task_struct *p)
30643 ++{
30644 ++#ifdef CONFIG_GRKERNSEC_BRUTE
30645 ++ read_lock(&tasklist_lock);
30646 ++ read_lock(&grsec_exec_file_lock);
30647 ++ if (p->parent && p->parent->exec_file == p->exec_file)
30648 ++ p->parent->brute = 1;
30649 ++ read_unlock(&grsec_exec_file_lock);
30650 ++ read_unlock(&tasklist_lock);
30651 ++#endif
30652 ++ return;
30653 ++}
30654 ++
30655 ++void gr_handle_brute_check(void)
30656 ++{
30657 ++#ifdef CONFIG_GRKERNSEC_BRUTE
30658 ++ if (current->brute)
30659 ++ msleep(30 * 1000);
30660 ++#endif
30661 ++ return;
30662 ++}
30663 ++
30664 +diff -urNp a/grsecurity/grsec_sock.c b/grsecurity/grsec_sock.c
30665 +--- a/grsecurity/grsec_sock.c 1969-12-31 16:00:00.000000000 -0800
30666 ++++ b/grsecurity/grsec_sock.c 2008-08-20 18:36:57.000000000 -0700
30667 +@@ -0,0 +1,274 @@
30668 ++#include <linux/kernel.h>
30669 ++#include <linux/module.h>
30670 ++#include <linux/sched.h>
30671 ++#include <linux/file.h>
30672 ++#include <linux/net.h>
30673 ++#include <linux/in.h>
30674 ++#include <linux/ip.h>
30675 ++#include <net/sock.h>
30676 ++#include <net/inet_sock.h>
30677 ++#include <linux/grsecurity.h>
30678 ++#include <linux/grinternal.h>
30679 ++#include <linux/gracl.h>
30680 ++
30681 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
30682 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
30683 ++EXPORT_SYMBOL(udp_v4_lookup);
30684 ++#endif
30685 ++
30686 ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
30687 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
30688 ++
30689 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
30690 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
30691 ++
30692 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
30693 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
30694 ++
30695 ++#ifdef CONFIG_UNIX_MODULE
30696 ++EXPORT_SYMBOL(gr_acl_handle_unix);
30697 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
30698 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
30699 ++EXPORT_SYMBOL(gr_handle_create);
30700 ++#endif
30701 ++
30702 ++#ifdef CONFIG_GRKERNSEC
30703 ++#define gr_conn_table_size 32749
30704 ++struct conn_table_entry {
30705 ++ struct conn_table_entry *next;
30706 ++ struct signal_struct *sig;
30707 ++};
30708 ++
30709 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
30710 ++spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
30711 ++
30712 ++extern const char * gr_socktype_to_name(unsigned char type);
30713 ++extern const char * gr_proto_to_name(unsigned char proto);
30714 ++
30715 ++static __inline__ int
30716 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
30717 ++{
30718 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
30719 ++}
30720 ++
30721 ++static __inline__ int
30722 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
30723 ++ __u16 sport, __u16 dport)
30724 ++{
30725 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
30726 ++ sig->gr_sport == sport && sig->gr_dport == dport))
30727 ++ return 1;
30728 ++ else
30729 ++ return 0;
30730 ++}
30731 ++
30732 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
30733 ++{
30734 ++ struct conn_table_entry **match;
30735 ++ unsigned int index;
30736 ++
30737 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
30738 ++ sig->gr_sport, sig->gr_dport,
30739 ++ gr_conn_table_size);
30740 ++
30741 ++ newent->sig = sig;
30742 ++
30743 ++ match = &gr_conn_table[index];
30744 ++ newent->next = *match;
30745 ++ *match = newent;
30746 ++
30747 ++ return;
30748 ++}
30749 ++
30750 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
30751 ++{
30752 ++ struct conn_table_entry *match, *last = NULL;
30753 ++ unsigned int index;
30754 ++
30755 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
30756 ++ sig->gr_sport, sig->gr_dport,
30757 ++ gr_conn_table_size);
30758 ++
30759 ++ match = gr_conn_table[index];
30760 ++ while (match && !conn_match(match->sig,
30761 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
30762 ++ sig->gr_dport)) {
30763 ++ last = match;
30764 ++ match = match->next;
30765 ++ }
30766 ++
30767 ++ if (match) {
30768 ++ if (last)
30769 ++ last->next = match->next;
30770 ++ else
30771 ++ gr_conn_table[index] = NULL;
30772 ++ kfree(match);
30773 ++ }
30774 ++
30775 ++ return;
30776 ++}
30777 ++
30778 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
30779 ++ __u16 sport, __u16 dport)
30780 ++{
30781 ++ struct conn_table_entry *match;
30782 ++ unsigned int index;
30783 ++
30784 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
30785 ++
30786 ++ match = gr_conn_table[index];
30787 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
30788 ++ match = match->next;
30789 ++
30790 ++ if (match)
30791 ++ return match->sig;
30792 ++ else
30793 ++ return NULL;
30794 ++}
30795 ++
30796 ++#endif
30797 ++
30798 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
30799 ++{
30800 ++#ifdef CONFIG_GRKERNSEC
30801 ++ struct signal_struct *sig = task->signal;
30802 ++ struct conn_table_entry *newent;
30803 ++
30804 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
30805 ++ if (newent == NULL)
30806 ++ return;
30807 ++ /* no bh lock needed since we are called with bh disabled */
30808 ++ spin_lock(&gr_conn_table_lock);
30809 ++ gr_del_task_from_ip_table_nolock(sig);
30810 ++ sig->gr_saddr = inet->rcv_saddr;
30811 ++ sig->gr_daddr = inet->daddr;
30812 ++ sig->gr_sport = inet->sport;
30813 ++ sig->gr_dport = inet->dport;
30814 ++ gr_add_to_task_ip_table_nolock(sig, newent);
30815 ++ spin_unlock(&gr_conn_table_lock);
30816 ++#endif
30817 ++ return;
30818 ++}
30819 ++
30820 ++void gr_del_task_from_ip_table(struct task_struct *task)
30821 ++{
30822 ++#ifdef CONFIG_GRKERNSEC
30823 ++ spin_lock(&gr_conn_table_lock);
30824 ++ gr_del_task_from_ip_table_nolock(task->signal);
30825 ++ spin_unlock(&gr_conn_table_lock);
30826 ++#endif
30827 ++ return;
30828 ++}
30829 ++
30830 ++void
30831 ++gr_attach_curr_ip(const struct sock *sk)
30832 ++{
30833 ++#ifdef CONFIG_GRKERNSEC
30834 ++ struct signal_struct *p, *set;
30835 ++ const struct inet_sock *inet = inet_sk(sk);
30836 ++
30837 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
30838 ++ return;
30839 ++
30840 ++ set = current->signal;
30841 ++
30842 ++ spin_lock_bh(&gr_conn_table_lock);
30843 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
30844 ++ inet->dport, inet->sport);
30845 ++ if (unlikely(p != NULL)) {
30846 ++ set->curr_ip = p->curr_ip;
30847 ++ set->used_accept = 1;
30848 ++ gr_del_task_from_ip_table_nolock(p);
30849 ++ spin_unlock_bh(&gr_conn_table_lock);
30850 ++ return;
30851 ++ }
30852 ++ spin_unlock_bh(&gr_conn_table_lock);
30853 ++
30854 ++ set->curr_ip = inet->daddr;
30855 ++ set->used_accept = 1;
30856 ++#endif
30857 ++ return;
30858 ++}
30859 ++
30860 ++int
30861 ++gr_handle_sock_all(const int family, const int type, const int protocol)
30862 ++{
30863 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
30864 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
30865 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
30866 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
30867 ++ return -EACCES;
30868 ++ }
30869 ++#endif
30870 ++ return 0;
30871 ++}
30872 ++
30873 ++int
30874 ++gr_handle_sock_server(const struct sockaddr *sck)
30875 ++{
30876 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30877 ++ if (grsec_enable_socket_server &&
30878 ++ in_group_p(grsec_socket_server_gid) &&
30879 ++ sck && (sck->sa_family != AF_UNIX) &&
30880 ++ (sck->sa_family != AF_LOCAL)) {
30881 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
30882 ++ return -EACCES;
30883 ++ }
30884 ++#endif
30885 ++ return 0;
30886 ++}
30887 ++
30888 ++int
30889 ++gr_handle_sock_server_other(const struct sock *sck)
30890 ++{
30891 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30892 ++ if (grsec_enable_socket_server &&
30893 ++ in_group_p(grsec_socket_server_gid) &&
30894 ++ sck && (sck->sk_family != AF_UNIX) &&
30895 ++ (sck->sk_family != AF_LOCAL)) {
30896 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
30897 ++ return -EACCES;
30898 ++ }
30899 ++#endif
30900 ++ return 0;
30901 ++}
30902 ++
30903 ++int
30904 ++gr_handle_sock_client(const struct sockaddr *sck)
30905 ++{
30906 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
30907 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
30908 ++ sck && (sck->sa_family != AF_UNIX) &&
30909 ++ (sck->sa_family != AF_LOCAL)) {
30910 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
30911 ++ return -EACCES;
30912 ++ }
30913 ++#endif
30914 ++ return 0;
30915 ++}
30916 ++
30917 ++kernel_cap_t
30918 ++gr_cap_rtnetlink(struct sock *sock)
30919 ++{
30920 ++#ifdef CONFIG_GRKERNSEC
30921 ++ if (!gr_acl_is_enabled())
30922 ++ return current->cap_effective;
30923 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
30924 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
30925 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
30926 ++ return current->cap_effective;
30927 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
30928 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
30929 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
30930 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
30931 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
30932 ++ return current->cap_effective;
30933 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
30934 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
30935 ++ return current->cap_effective;
30936 ++ else
30937 ++ return __cap_empty_set;
30938 ++#else
30939 ++ return current->cap_effective;
30940 ++#endif
30941 ++}
30942 +diff -urNp a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c
30943 +--- a/grsecurity/grsec_sysctl.c 1969-12-31 16:00:00.000000000 -0800
30944 ++++ b/grsecurity/grsec_sysctl.c 2008-08-20 18:36:57.000000000 -0700
30945 +@@ -0,0 +1,435 @@
30946 ++#include <linux/kernel.h>
30947 ++#include <linux/sched.h>
30948 ++#include <linux/sysctl.h>
30949 ++#include <linux/grsecurity.h>
30950 ++#include <linux/grinternal.h>
30951 ++
30952 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
30953 ++int grsec_modstop;
30954 ++#endif
30955 ++
30956 ++int
30957 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
30958 ++{
30959 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
30960 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
30961 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
30962 ++ return -EACCES;
30963 ++ }
30964 ++#endif
30965 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
30966 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
30967 ++ grsec_modstop && (op & 002)) {
30968 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
30969 ++ return -EACCES;
30970 ++ }
30971 ++#endif
30972 ++ return 0;
30973 ++}
30974 ++
30975 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
30976 ++ctl_table grsecurity_table[] = {
30977 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
30978 ++#ifdef CONFIG_GRKERNSEC_LINK
30979 ++ {
30980 ++ .ctl_name = CTL_UNNUMBERED,
30981 ++ .procname = "linking_restrictions",
30982 ++ .data = &grsec_enable_link,
30983 ++ .maxlen = sizeof(int),
30984 ++ .mode = 0600,
30985 ++ .proc_handler = &proc_dointvec,
30986 ++ },
30987 ++#endif
30988 ++#ifdef CONFIG_GRKERNSEC_FIFO
30989 ++ {
30990 ++ .ctl_name = CTL_UNNUMBERED,
30991 ++ .procname = "fifo_restrictions",
30992 ++ .data = &grsec_enable_fifo,
30993 ++ .maxlen = sizeof(int),
30994 ++ .mode = 0600,
30995 ++ .proc_handler = &proc_dointvec,
30996 ++ },
30997 ++#endif
30998 ++#ifdef CONFIG_GRKERNSEC_EXECVE
30999 ++ {
31000 ++ .ctl_name = CTL_UNNUMBERED,
31001 ++ .procname = "execve_limiting",
31002 ++ .data = &grsec_enable_execve,
31003 ++ .maxlen = sizeof(int),
31004 ++ .mode = 0600,
31005 ++ .proc_handler = &proc_dointvec,
31006 ++ },
31007 ++#endif
31008 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
31009 ++ {
31010 ++ .ctl_name = CTL_UNNUMBERED,
31011 ++ .procname = "exec_logging",
31012 ++ .data = &grsec_enable_execlog,
31013 ++ .maxlen = sizeof(int),
31014 ++ .mode = 0600,
31015 ++ .proc_handler = &proc_dointvec,
31016 ++ },
31017 ++#endif
31018 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
31019 ++ {
31020 ++ .ctl_name = CTL_UNNUMBERED,
31021 ++ .procname = "signal_logging",
31022 ++ .data = &grsec_enable_signal,
31023 ++ .maxlen = sizeof(int),
31024 ++ .mode = 0600,
31025 ++ .proc_handler = &proc_dointvec,
31026 ++ },
31027 ++#endif
31028 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
31029 ++ {
31030 ++ .ctl_name = CTL_UNNUMBERED,
31031 ++ .procname = "forkfail_logging",
31032 ++ .data = &grsec_enable_forkfail,
31033 ++ .maxlen = sizeof(int),
31034 ++ .mode = 0600,
31035 ++ .proc_handler = &proc_dointvec,
31036 ++ },
31037 ++#endif
31038 ++#ifdef CONFIG_GRKERNSEC_TIME
31039 ++ {
31040 ++ .ctl_name = CTL_UNNUMBERED,
31041 ++ .procname = "timechange_logging",
31042 ++ .data = &grsec_enable_time,
31043 ++ .maxlen = sizeof(int),
31044 ++ .mode = 0600,
31045 ++ .proc_handler = &proc_dointvec,
31046 ++ },
31047 ++#endif
31048 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
31049 ++ {
31050 ++ .ctl_name = CTL_UNNUMBERED,
31051 ++ .procname = "chroot_deny_shmat",
31052 ++ .data = &grsec_enable_chroot_shmat,
31053 ++ .maxlen = sizeof(int),
31054 ++ .mode = 0600,
31055 ++ .proc_handler = &proc_dointvec,
31056 ++ },
31057 ++#endif
31058 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
31059 ++ {
31060 ++ .ctl_name = CTL_UNNUMBERED,
31061 ++ .procname = "chroot_deny_unix",
31062 ++ .data = &grsec_enable_chroot_unix,
31063 ++ .maxlen = sizeof(int),
31064 ++ .mode = 0600,
31065 ++ .proc_handler = &proc_dointvec,
31066 ++ },
31067 ++#endif
31068 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
31069 ++ {
31070 ++ .ctl_name = CTL_UNNUMBERED,
31071 ++ .procname = "chroot_deny_mount",
31072 ++ .data = &grsec_enable_chroot_mount,
31073 ++ .maxlen = sizeof(int),
31074 ++ .mode = 0600,
31075 ++ .proc_handler = &proc_dointvec,
31076 ++ },
31077 ++#endif
31078 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
31079 ++ {
31080 ++ .ctl_name = CTL_UNNUMBERED,
31081 ++ .procname = "chroot_deny_fchdir",
31082 ++ .data = &grsec_enable_chroot_fchdir,
31083 ++ .maxlen = sizeof(int),
31084 ++ .mode = 0600,
31085 ++ .proc_handler = &proc_dointvec,
31086 ++ },
31087 ++#endif
31088 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
31089 ++ {
31090 ++ .ctl_name = CTL_UNNUMBERED,
31091 ++ .procname = "chroot_deny_chroot",
31092 ++ .data = &grsec_enable_chroot_double,
31093 ++ .maxlen = sizeof(int),
31094 ++ .mode = 0600,
31095 ++ .proc_handler = &proc_dointvec,
31096 ++ },
31097 ++#endif
31098 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
31099 ++ {
31100 ++ .ctl_name = CTL_UNNUMBERED,
31101 ++ .procname = "chroot_deny_pivot",
31102 ++ .data = &grsec_enable_chroot_pivot,
31103 ++ .maxlen = sizeof(int),
31104 ++ .mode = 0600,
31105 ++ .proc_handler = &proc_dointvec,
31106 ++ },
31107 ++#endif
31108 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
31109 ++ {
31110 ++ .ctl_name = CTL_UNNUMBERED,
31111 ++ .procname = "chroot_enforce_chdir",
31112 ++ .data = &grsec_enable_chroot_chdir,
31113 ++ .maxlen = sizeof(int),
31114 ++ .mode = 0600,
31115 ++ .proc_handler = &proc_dointvec,
31116 ++ },
31117 ++#endif
31118 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
31119 ++ {
31120 ++ .ctl_name = CTL_UNNUMBERED,
31121 ++ .procname = "chroot_deny_chmod",
31122 ++ .data = &grsec_enable_chroot_chmod,
31123 ++ .maxlen = sizeof(int),
31124 ++ .mode = 0600,
31125 ++ .proc_handler = &proc_dointvec,
31126 ++ },
31127 ++#endif
31128 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
31129 ++ {
31130 ++ .ctl_name = CTL_UNNUMBERED,
31131 ++ .procname = "chroot_deny_mknod",
31132 ++ .data = &grsec_enable_chroot_mknod,
31133 ++ .maxlen = sizeof(int),
31134 ++ .mode = 0600,
31135 ++ .proc_handler = &proc_dointvec,
31136 ++ },
31137 ++#endif
31138 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
31139 ++ {
31140 ++ .ctl_name = CTL_UNNUMBERED,
31141 ++ .procname = "chroot_restrict_nice",
31142 ++ .data = &grsec_enable_chroot_nice,
31143 ++ .maxlen = sizeof(int),
31144 ++ .mode = 0600,
31145 ++ .proc_handler = &proc_dointvec,
31146 ++ },
31147 ++#endif
31148 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
31149 ++ {
31150 ++ .ctl_name = CTL_UNNUMBERED,
31151 ++ .procname = "chroot_execlog",
31152 ++ .data = &grsec_enable_chroot_execlog,
31153 ++ .maxlen = sizeof(int),
31154 ++ .mode = 0600,
31155 ++ .proc_handler = &proc_dointvec,
31156 ++ },
31157 ++#endif
31158 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
31159 ++ {
31160 ++ .ctl_name = CTL_UNNUMBERED,
31161 ++ .procname = "chroot_caps",
31162 ++ .data = &grsec_enable_chroot_caps,
31163 ++ .maxlen = sizeof(int),
31164 ++ .mode = 0600,
31165 ++ .proc_handler = &proc_dointvec,
31166 ++ },
31167 ++#endif
31168 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
31169 ++ {
31170 ++ .ctl_name = CTL_UNNUMBERED,
31171 ++ .procname = "chroot_deny_sysctl",
31172 ++ .data = &grsec_enable_chroot_sysctl,
31173 ++ .maxlen = sizeof(int),
31174 ++ .mode = 0600,
31175 ++ .proc_handler = &proc_dointvec,
31176 ++ },
31177 ++#endif
31178 ++#ifdef CONFIG_GRKERNSEC_TPE
31179 ++ {
31180 ++ .ctl_name = CTL_UNNUMBERED,
31181 ++ .procname = "tpe",
31182 ++ .data = &grsec_enable_tpe,
31183 ++ .maxlen = sizeof(int),
31184 ++ .mode = 0600,
31185 ++ .proc_handler = &proc_dointvec,
31186 ++ },
31187 ++ {
31188 ++ .ctl_name = CTL_UNNUMBERED,
31189 ++ .procname = "tpe_gid",
31190 ++ .data = &grsec_tpe_gid,
31191 ++ .maxlen = sizeof(int),
31192 ++ .mode = 0600,
31193 ++ .proc_handler = &proc_dointvec,
31194 ++ },
31195 ++#endif
31196 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
31197 ++ {
31198 ++ .ctl_name = CTL_UNNUMBERED,
31199 ++ .procname = "tpe_restrict_all",
31200 ++ .data = &grsec_enable_tpe_all,
31201 ++ .maxlen = sizeof(int),
31202 ++ .mode = 0600,
31203 ++ .proc_handler = &proc_dointvec,
31204 ++ },
31205 ++#endif
31206 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
31207 ++ {
31208 ++ .ctl_name = CTL_UNNUMBERED,
31209 ++ .procname = "socket_all",
31210 ++ .data = &grsec_enable_socket_all,
31211 ++ .maxlen = sizeof(int),
31212 ++ .mode = 0600,
31213 ++ .proc_handler = &proc_dointvec,
31214 ++ },
31215 ++ {
31216 ++ .ctl_name = CTL_UNNUMBERED,
31217 ++ .procname = "socket_all_gid",
31218 ++ .data = &grsec_socket_all_gid,
31219 ++ .maxlen = sizeof(int),
31220 ++ .mode = 0600,
31221 ++ .proc_handler = &proc_dointvec,
31222 ++ },
31223 ++#endif
31224 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
31225 ++ {
31226 ++ .ctl_name = CTL_UNNUMBERED,
31227 ++ .procname = "socket_client",
31228 ++ .data = &grsec_enable_socket_client,
31229 ++ .maxlen = sizeof(int),
31230 ++ .mode = 0600,
31231 ++ .proc_handler = &proc_dointvec,
31232 ++ },
31233 ++ {
31234 ++ .ctl_name = CTL_UNNUMBERED,
31235 ++ .procname = "socket_client_gid",
31236 ++ .data = &grsec_socket_client_gid,
31237 ++ .maxlen = sizeof(int),
31238 ++ .mode = 0600,
31239 ++ .proc_handler = &proc_dointvec,
31240 ++ },
31241 ++#endif
31242 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
31243 ++ {
31244 ++ .ctl_name = CTL_UNNUMBERED,
31245 ++ .procname = "socket_server",
31246 ++ .data = &grsec_enable_socket_server,
31247 ++ .maxlen = sizeof(int),
31248 ++ .mode = 0600,
31249 ++ .proc_handler = &proc_dointvec,
31250 ++ },
31251 ++ {
31252 ++ .ctl_name = CTL_UNNUMBERED,
31253 ++ .procname = "socket_server_gid",
31254 ++ .data = &grsec_socket_server_gid,
31255 ++ .maxlen = sizeof(int),
31256 ++ .mode = 0600,
31257 ++ .proc_handler = &proc_dointvec,
31258 ++ },
31259 ++#endif
31260 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
31261 ++ {
31262 ++ .ctl_name = CTL_UNNUMBERED,
31263 ++ .procname = "audit_group",
31264 ++ .data = &grsec_enable_group,
31265 ++ .maxlen = sizeof(int),
31266 ++ .mode = 0600,
31267 ++ .proc_handler = &proc_dointvec,
31268 ++ },
31269 ++ {
31270 ++ .ctl_name = CTL_UNNUMBERED,
31271 ++ .procname = "audit_gid",
31272 ++ .data = &grsec_audit_gid,
31273 ++ .maxlen = sizeof(int),
31274 ++ .mode = 0600,
31275 ++ .proc_handler = &proc_dointvec,
31276 ++ },
31277 ++#endif
31278 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
31279 ++ {
31280 ++ .ctl_name = CTL_UNNUMBERED,
31281 ++ .procname = "audit_chdir",
31282 ++ .data = &grsec_enable_chdir,
31283 ++ .maxlen = sizeof(int),
31284 ++ .mode = 0600,
31285 ++ .proc_handler = &proc_dointvec,
31286 ++ },
31287 ++#endif
31288 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
31289 ++ {
31290 ++ .ctl_name = CTL_UNNUMBERED,
31291 ++ .procname = "audit_mount",
31292 ++ .data = &grsec_enable_mount,
31293 ++ .maxlen = sizeof(int),
31294 ++ .mode = 0600,
31295 ++ .proc_handler = &proc_dointvec,
31296 ++ },
31297 ++#endif
31298 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
31299 ++ {
31300 ++ .ctl_name = CTL_UNNUMBERED,
31301 ++ .procname = "audit_ipc",
31302 ++ .data = &grsec_enable_audit_ipc,
31303 ++ .maxlen = sizeof(int),
31304 ++ .mode = 0600,
31305 ++ .proc_handler = &proc_dointvec,
31306 ++ },
31307 ++#endif
31308 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31309 ++ {
31310 ++ .ctl_name = CTL_UNNUMBERED,
31311 ++ .procname = "audit_textrel",
31312 ++ .data = &grsec_enable_audit_textrel,
31313 ++ .maxlen = sizeof(int),
31314 ++ .mode = 0600,
31315 ++ .proc_handler = &proc_dointvec,
31316 ++ },
31317 ++#endif
31318 ++#ifdef CONFIG_GRKERNSEC_DMESG
31319 ++ {
31320 ++ .ctl_name = CTL_UNNUMBERED,
31321 ++ .procname = "dmesg",
31322 ++ .data = &grsec_enable_dmesg,
31323 ++ .maxlen = sizeof(int),
31324 ++ .mode = 0600,
31325 ++ .proc_handler = &proc_dointvec,
31326 ++ },
31327 ++#endif
31328 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
31329 ++ {
31330 ++ .ctl_name = CTL_UNNUMBERED,
31331 ++ .procname = "chroot_findtask",
31332 ++ .data = &grsec_enable_chroot_findtask,
31333 ++ .maxlen = sizeof(int),
31334 ++ .mode = 0600,
31335 ++ .proc_handler = &proc_dointvec,
31336 ++ },
31337 ++#endif
31338 ++#ifdef CONFIG_GRKERNSEC_RESLOG
31339 ++ {
31340 ++ .ctl_name = CTL_UNNUMBERED,
31341 ++ .procname = "resource_logging",
31342 ++ .data = &grsec_resource_logging,
31343 ++ .maxlen = sizeof(int),
31344 ++ .mode = 0600,
31345 ++ .proc_handler = &proc_dointvec,
31346 ++ },
31347 ++#endif
31348 ++ {
31349 ++ .ctl_name = CTL_UNNUMBERED,
31350 ++ .procname = "grsec_lock",
31351 ++ .data = &grsec_lock,
31352 ++ .maxlen = sizeof(int),
31353 ++ .mode = 0600,
31354 ++ .proc_handler = &proc_dointvec,
31355 ++ },
31356 ++#endif
31357 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31358 ++ {
31359 ++ .ctl_name = CTL_UNNUMBERED,
31360 ++ .procname = "disable_modules",
31361 ++ .data = &grsec_modstop,
31362 ++ .maxlen = sizeof(int),
31363 ++ .mode = 0600,
31364 ++ .proc_handler = &proc_dointvec,
31365 ++ },
31366 ++#endif
31367 ++ { .ctl_name = 0 }
31368 ++};
31369 ++#endif
31370 ++
31371 ++int gr_check_modstop(void)
31372 ++{
31373 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31374 ++ if (grsec_modstop == 1) {
31375 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
31376 ++ return 1;
31377 ++ }
31378 ++#endif
31379 ++ return 0;
31380 ++}
31381 +diff -urNp a/grsecurity/grsec_textrel.c b/grsecurity/grsec_textrel.c
31382 +--- a/grsecurity/grsec_textrel.c 1969-12-31 16:00:00.000000000 -0800
31383 ++++ b/grsecurity/grsec_textrel.c 2008-08-20 18:36:57.000000000 -0700
31384 +@@ -0,0 +1,16 @@
31385 ++#include <linux/kernel.h>
31386 ++#include <linux/sched.h>
31387 ++#include <linux/mm.h>
31388 ++#include <linux/file.h>
31389 ++#include <linux/grinternal.h>
31390 ++#include <linux/grsecurity.h>
31391 ++
31392 ++void
31393 ++gr_log_textrel(struct vm_area_struct * vma)
31394 ++{
31395 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31396 ++ if (grsec_enable_audit_textrel)
31397 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
31398 ++#endif
31399 ++ return;
31400 ++}
31401 +diff -urNp a/grsecurity/grsec_time.c b/grsecurity/grsec_time.c
31402 +--- a/grsecurity/grsec_time.c 1969-12-31 16:00:00.000000000 -0800
31403 ++++ b/grsecurity/grsec_time.c 2008-08-20 18:36:57.000000000 -0700
31404 +@@ -0,0 +1,13 @@
31405 ++#include <linux/kernel.h>
31406 ++#include <linux/sched.h>
31407 ++#include <linux/grinternal.h>
31408 ++
31409 ++void
31410 ++gr_log_timechange(void)
31411 ++{
31412 ++#ifdef CONFIG_GRKERNSEC_TIME
31413 ++ if (grsec_enable_time)
31414 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
31415 ++#endif
31416 ++ return;
31417 ++}
31418 +diff -urNp a/grsecurity/grsec_tpe.c b/grsecurity/grsec_tpe.c
31419 +--- a/grsecurity/grsec_tpe.c 1969-12-31 16:00:00.000000000 -0800
31420 ++++ b/grsecurity/grsec_tpe.c 2008-08-20 18:36:57.000000000 -0700
31421 +@@ -0,0 +1,37 @@
31422 ++#include <linux/kernel.h>
31423 ++#include <linux/sched.h>
31424 ++#include <linux/file.h>
31425 ++#include <linux/fs.h>
31426 ++#include <linux/grinternal.h>
31427 ++
31428 ++extern int gr_acl_tpe_check(void);
31429 ++
31430 ++int
31431 ++gr_tpe_allow(const struct file *file)
31432 ++{
31433 ++#ifdef CONFIG_GRKERNSEC
31434 ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
31435 ++
31436 ++ if (current->uid && ((grsec_enable_tpe &&
31437 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
31438 ++ !in_group_p(grsec_tpe_gid)
31439 ++#else
31440 ++ in_group_p(grsec_tpe_gid)
31441 ++#endif
31442 ++ ) || gr_acl_tpe_check()) &&
31443 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
31444 ++ (inode->i_mode & S_IWOTH))))) {
31445 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
31446 ++ return 0;
31447 ++ }
31448 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
31449 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
31450 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
31451 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
31452 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
31453 ++ return 0;
31454 ++ }
31455 ++#endif
31456 ++#endif
31457 ++ return 1;
31458 ++}
31459 +diff -urNp a/grsecurity/grsum.c b/grsecurity/grsum.c
31460 +--- a/grsecurity/grsum.c 1969-12-31 16:00:00.000000000 -0800
31461 ++++ b/grsecurity/grsum.c 2008-08-20 18:36:57.000000000 -0700
31462 +@@ -0,0 +1,59 @@
31463 ++#include <linux/err.h>
31464 ++#include <linux/kernel.h>
31465 ++#include <linux/sched.h>
31466 ++#include <linux/mm.h>
31467 ++#include <linux/scatterlist.h>
31468 ++#include <linux/crypto.h>
31469 ++#include <linux/gracl.h>
31470 ++
31471 ++
31472 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
31473 ++#error "crypto and sha256 must be built into the kernel"
31474 ++#endif
31475 ++
31476 ++int
31477 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
31478 ++{
31479 ++ char *p;
31480 ++ struct crypto_hash *tfm;
31481 ++ struct hash_desc desc;
31482 ++ struct scatterlist sg;
31483 ++ unsigned char temp_sum[GR_SHA_LEN];
31484 ++ volatile int retval = 0;
31485 ++ volatile int dummy = 0;
31486 ++ unsigned int i;
31487 ++
31488 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
31489 ++ if (IS_ERR(tfm)) {
31490 ++ /* should never happen, since sha256 should be built in */
31491 ++ return 1;
31492 ++ }
31493 ++
31494 ++ desc.tfm = tfm;
31495 ++ desc.flags = 0;
31496 ++
31497 ++ crypto_hash_init(&desc);
31498 ++
31499 ++ p = salt;
31500 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
31501 ++ crypto_hash_update(&desc, &sg, sg.length);
31502 ++
31503 ++ p = entry->pw;
31504 ++ sg_set_buf(&sg, p, strlen(p));
31505 ++
31506 ++ crypto_hash_update(&desc, &sg, sg.length);
31507 ++
31508 ++ crypto_hash_final(&desc, temp_sum);
31509 ++
31510 ++ memset(entry->pw, 0, GR_PW_LEN);
31511 ++
31512 ++ for (i = 0; i < GR_SHA_LEN; i++)
31513 ++ if (sum[i] != temp_sum[i])
31514 ++ retval = 1;
31515 ++ else
31516 ++ dummy = 1; // waste a cycle
31517 ++
31518 ++ crypto_free_hash(tfm);
31519 ++
31520 ++ return retval;
31521 ++}
31522 +diff -urNp a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
31523 +--- a/include/asm-alpha/elf.h 2008-08-20 11:16:13.000000000 -0700
31524 ++++ b/include/asm-alpha/elf.h 2008-08-20 18:36:57.000000000 -0700
31525 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
31526 +
31527 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
31528 +
31529 ++#ifdef CONFIG_PAX_ASLR
31530 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
31531 ++
31532 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
31533 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
31534 ++#endif
31535 ++
31536 + /* $0 is set by ld.so to a pointer to a function which might be
31537 + registered using atexit. This provides a mean for the dynamic
31538 + linker to call DT_FINI functions for shared libraries that have
31539 +diff -urNp a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h
31540 +--- a/include/asm-alpha/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31541 ++++ b/include/asm-alpha/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31542 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
31543 + D(10) KM_IRQ1,
31544 + D(11) KM_SOFTIRQ0,
31545 + D(12) KM_SOFTIRQ1,
31546 +-D(13) KM_TYPE_NR
31547 ++D(13) KM_CLEARPAGE,
31548 ++D(14) KM_TYPE_NR
31549 + };
31550 +
31551 + #undef D
31552 +diff -urNp a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
31553 +--- a/include/asm-alpha/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31554 ++++ b/include/asm-alpha/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31555 +@@ -101,6 +101,17 @@ struct vm_area_struct;
31556 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
31557 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
31558 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
31559 ++
31560 ++#ifdef CONFIG_PAX_PAGEEXEC
31561 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
31562 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
31563 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
31564 ++#else
31565 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31566 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31567 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31568 ++#endif
31569 ++
31570 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
31571 +
31572 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
31573 +diff -urNp a/include/asm-arm/elf.h b/include/asm-arm/elf.h
31574 +--- a/include/asm-arm/elf.h 2008-08-20 11:16:13.000000000 -0700
31575 ++++ b/include/asm-arm/elf.h 2008-08-20 18:36:57.000000000 -0700
31576 +@@ -87,7 +87,14 @@ extern char elf_platform[];
31577 + the loader. We need to make sure that it is out of the way of the program
31578 + that it will "exec", and that there is sufficient room for the brk. */
31579 +
31580 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
31581 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31582 ++
31583 ++#ifdef CONFIG_PAX_ASLR
31584 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
31585 ++
31586 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
31587 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
31588 ++#endif
31589 +
31590 + /* When the program starts, a1 contains a pointer to a function to be
31591 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
31592 +diff -urNp a/include/asm-arm/kmap_types.h b/include/asm-arm/kmap_types.h
31593 +--- a/include/asm-arm/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31594 ++++ b/include/asm-arm/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31595 +@@ -18,6 +18,7 @@ enum km_type {
31596 + KM_IRQ1,
31597 + KM_SOFTIRQ0,
31598 + KM_SOFTIRQ1,
31599 ++ KM_CLEARPAGE,
31600 + KM_TYPE_NR
31601 + };
31602 +
31603 +diff -urNp a/include/asm-avr32/elf.h b/include/asm-avr32/elf.h
31604 +--- a/include/asm-avr32/elf.h 2008-08-20 11:16:13.000000000 -0700
31605 ++++ b/include/asm-avr32/elf.h 2008-08-20 18:36:57.000000000 -0700
31606 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
31607 + the loader. We need to make sure that it is out of the way of the program
31608 + that it will "exec", and that there is sufficient room for the brk. */
31609 +
31610 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
31611 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31612 +
31613 ++#ifdef CONFIG_PAX_ASLR
31614 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
31615 ++
31616 ++#define PAX_DELTA_MMAP_LEN 15
31617 ++#define PAX_DELTA_STACK_LEN 15
31618 ++#endif
31619 +
31620 + /* This yields a mask that user programs can use to figure out what
31621 + instruction set this CPU supports. This could be done in user space,
31622 +diff -urNp a/include/asm-avr32/kmap_types.h b/include/asm-avr32/kmap_types.h
31623 +--- a/include/asm-avr32/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31624 ++++ b/include/asm-avr32/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31625 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
31626 + D(11) KM_IRQ1,
31627 + D(12) KM_SOFTIRQ0,
31628 + D(13) KM_SOFTIRQ1,
31629 +-D(14) KM_TYPE_NR
31630 ++D(14) KM_CLEARPAGE,
31631 ++D(15) KM_TYPE_NR
31632 + };
31633 +
31634 + #undef D
31635 +diff -urNp a/include/asm-blackfin/kmap_types.h b/include/asm-blackfin/kmap_types.h
31636 +--- a/include/asm-blackfin/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31637 ++++ b/include/asm-blackfin/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31638 +@@ -15,6 +15,7 @@ enum km_type {
31639 + KM_IRQ1,
31640 + KM_SOFTIRQ0,
31641 + KM_SOFTIRQ1,
31642 ++ KM_CLEARPAGE,
31643 + KM_TYPE_NR
31644 + };
31645 +
31646 +diff -urNp a/include/asm-cris/kmap_types.h b/include/asm-cris/kmap_types.h
31647 +--- a/include/asm-cris/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31648 ++++ b/include/asm-cris/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31649 +@@ -19,6 +19,7 @@ enum km_type {
31650 + KM_IRQ1,
31651 + KM_SOFTIRQ0,
31652 + KM_SOFTIRQ1,
31653 ++ KM_CLEARPAGE,
31654 + KM_TYPE_NR
31655 + };
31656 +
31657 +diff -urNp a/include/asm-frv/kmap_types.h b/include/asm-frv/kmap_types.h
31658 +--- a/include/asm-frv/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31659 ++++ b/include/asm-frv/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31660 +@@ -23,6 +23,7 @@ enum km_type {
31661 + KM_IRQ1,
31662 + KM_SOFTIRQ0,
31663 + KM_SOFTIRQ1,
31664 ++ KM_CLEARPAGE,
31665 + KM_TYPE_NR
31666 + };
31667 +
31668 +diff -urNp a/include/asm-generic/futex.h b/include/asm-generic/futex.h
31669 +--- a/include/asm-generic/futex.h 2008-08-20 11:16:13.000000000 -0700
31670 ++++ b/include/asm-generic/futex.h 2008-08-20 18:36:57.000000000 -0700
31671 +@@ -8,7 +8,7 @@
31672 + #include <asm/uaccess.h>
31673 +
31674 + static inline int
31675 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
31676 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
31677 + {
31678 + int op = (encoded_op >> 28) & 7;
31679 + int cmp = (encoded_op >> 24) & 15;
31680 +@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
31681 + }
31682 +
31683 + static inline int
31684 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
31685 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
31686 + {
31687 + return -ENOSYS;
31688 + }
31689 +diff -urNp a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
31690 +--- a/include/asm-generic/vmlinux.lds.h 2008-08-20 11:16:13.000000000 -0700
31691 ++++ b/include/asm-generic/vmlinux.lds.h 2008-08-20 18:36:57.000000000 -0700
31692 +@@ -59,6 +59,7 @@
31693 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
31694 + VMLINUX_SYMBOL(__start_rodata) = .; \
31695 + *(.rodata) *(.rodata.*) \
31696 ++ *(.data.read_only) \
31697 + *(__vermagic) /* Kernel version magic */ \
31698 + *(__markers_strings) /* Markers: strings */ \
31699 + } \
31700 +diff -urNp a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h
31701 +--- a/include/asm-h8300/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31702 ++++ b/include/asm-h8300/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31703 +@@ -15,6 +15,7 @@ enum km_type {
31704 + KM_IRQ1,
31705 + KM_SOFTIRQ0,
31706 + KM_SOFTIRQ1,
31707 ++ KM_CLEARPAGE,
31708 + KM_TYPE_NR
31709 + };
31710 +
31711 +diff -urNp a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
31712 +--- a/include/asm-ia64/elf.h 2008-08-20 11:16:13.000000000 -0700
31713 ++++ b/include/asm-ia64/elf.h 2008-08-20 18:36:57.000000000 -0700
31714 +@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
31715 + typedef struct ia64_fpreg elf_fpreg_t;
31716 + typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
31717 +
31718 ++#ifdef CONFIG_PAX_ASLR
31719 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
31720 +
31721 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
31722 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
31723 ++#endif
31724 +
31725 + struct pt_regs; /* forward declaration... */
31726 + extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
31727 +diff -urNp a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h
31728 +--- a/include/asm-ia64/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31729 ++++ b/include/asm-ia64/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31730 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
31731 + D(10) KM_IRQ1,
31732 + D(11) KM_SOFTIRQ0,
31733 + D(12) KM_SOFTIRQ1,
31734 +-D(13) KM_TYPE_NR
31735 ++D(13) KM_CLEARPAGE,
31736 ++D(14) KM_TYPE_NR
31737 + };
31738 +
31739 + #undef D
31740 +diff -urNp a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
31741 +--- a/include/asm-ia64/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31742 ++++ b/include/asm-ia64/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31743 +@@ -143,6 +143,17 @@
31744 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31745 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31746 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
31747 ++
31748 ++#ifdef CONFIG_PAX_PAGEEXEC
31749 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
31750 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31751 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31752 ++#else
31753 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31754 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31755 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31756 ++#endif
31757 ++
31758 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
31759 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
31760 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
31761 +diff -urNp a/include/asm-m32r/kmap_types.h b/include/asm-m32r/kmap_types.h
31762 +--- a/include/asm-m32r/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31763 ++++ b/include/asm-m32r/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31764 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
31765 + D(10) KM_IRQ1,
31766 + D(11) KM_SOFTIRQ0,
31767 + D(12) KM_SOFTIRQ1,
31768 +-D(13) KM_TYPE_NR
31769 ++D(13) KM_CLEARPAGE,
31770 ++D(14) KM_TYPE_NR
31771 + };
31772 +
31773 + #undef D
31774 +diff -urNp a/include/asm-m68k/kmap_types.h b/include/asm-m68k/kmap_types.h
31775 +--- a/include/asm-m68k/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31776 ++++ b/include/asm-m68k/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31777 +@@ -15,6 +15,7 @@ enum km_type {
31778 + KM_IRQ1,
31779 + KM_SOFTIRQ0,
31780 + KM_SOFTIRQ1,
31781 ++ KM_CLEARPAGE,
31782 + KM_TYPE_NR
31783 + };
31784 +
31785 +diff -urNp a/include/asm-m68knommu/kmap_types.h b/include/asm-m68knommu/kmap_types.h
31786 +--- a/include/asm-m68knommu/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31787 ++++ b/include/asm-m68knommu/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31788 +@@ -15,6 +15,7 @@ enum km_type {
31789 + KM_IRQ1,
31790 + KM_SOFTIRQ0,
31791 + KM_SOFTIRQ1,
31792 ++ KM_CLEARPAGE,
31793 + KM_TYPE_NR
31794 + };
31795 +
31796 +diff -urNp a/include/asm-mips/elf.h b/include/asm-mips/elf.h
31797 +--- a/include/asm-mips/elf.h 2008-08-20 11:16:13.000000000 -0700
31798 ++++ b/include/asm-mips/elf.h 2008-08-20 18:36:57.000000000 -0700
31799 +@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
31800 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31801 + #endif
31802 +
31803 ++#ifdef CONFIG_PAX_ASLR
31804 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
31805 ++
31806 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
31807 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
31808 ++#endif
31809 ++
31810 + #endif /* _ASM_ELF_H */
31811 +diff -urNp a/include/asm-mips/kmap_types.h b/include/asm-mips/kmap_types.h
31812 +--- a/include/asm-mips/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31813 ++++ b/include/asm-mips/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31814 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
31815 + D(10) KM_IRQ1,
31816 + D(11) KM_SOFTIRQ0,
31817 + D(12) KM_SOFTIRQ1,
31818 +-D(13) KM_TYPE_NR
31819 ++D(13) KM_CLEARPAGE,
31820 ++D(14) KM_TYPE_NR
31821 + };
31822 +
31823 + #undef D
31824 +diff -urNp a/include/asm-mips/page.h b/include/asm-mips/page.h
31825 +--- a/include/asm-mips/page.h 2008-08-20 11:16:13.000000000 -0700
31826 ++++ b/include/asm-mips/page.h 2008-08-20 18:36:57.000000000 -0700
31827 +@@ -79,7 +79,7 @@ extern void copy_user_highpage(struct pa
31828 + #ifdef CONFIG_CPU_MIPS32
31829 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
31830 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
31831 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
31832 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
31833 + #else
31834 + typedef struct { unsigned long long pte; } pte_t;
31835 + #define pte_val(x) ((x).pte)
31836 +diff -urNp a/include/asm-mips/system.h b/include/asm-mips/system.h
31837 +--- a/include/asm-mips/system.h 2008-08-20 11:16:13.000000000 -0700
31838 ++++ b/include/asm-mips/system.h 2008-08-20 18:36:57.000000000 -0700
31839 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
31840 + */
31841 + #define __ARCH_WANT_UNLOCKED_CTXSW
31842 +
31843 +-extern unsigned long arch_align_stack(unsigned long sp);
31844 ++#define arch_align_stack(x) (x)
31845 +
31846 + #endif /* _ASM_SYSTEM_H */
31847 +diff -urNp a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h
31848 +--- a/include/asm-parisc/elf.h 2008-08-20 11:16:13.000000000 -0700
31849 ++++ b/include/asm-parisc/elf.h 2008-08-20 18:36:57.000000000 -0700
31850 +@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
31851 +
31852 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
31853 +
31854 ++#ifdef CONFIG_PAX_ASLR
31855 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
31856 ++
31857 ++#define PAX_DELTA_MMAP_LEN 16
31858 ++#define PAX_DELTA_STACK_LEN 16
31859 ++#endif
31860 ++
31861 + /* This yields a mask that user programs can use to figure out what
31862 + instruction set this CPU supports. This could be done in user space,
31863 + but it's not easy, and we've already done it here. */
31864 +diff -urNp a/include/asm-parisc/kmap_types.h b/include/asm-parisc/kmap_types.h
31865 +--- a/include/asm-parisc/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31866 ++++ b/include/asm-parisc/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31867 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
31868 + D(10) KM_IRQ1,
31869 + D(11) KM_SOFTIRQ0,
31870 + D(12) KM_SOFTIRQ1,
31871 +-D(13) KM_TYPE_NR
31872 ++D(13) KM_CLEARPAGE,
31873 ++D(14) KM_TYPE_NR
31874 + };
31875 +
31876 + #undef D
31877 +diff -urNp a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
31878 +--- a/include/asm-parisc/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31879 ++++ b/include/asm-parisc/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31880 +@@ -202,6 +202,17 @@
31881 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
31882 + #define PAGE_COPY PAGE_EXECREAD
31883 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
31884 ++
31885 ++#ifdef CONFIG_PAX_PAGEEXEC
31886 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
31887 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
31888 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
31889 ++#else
31890 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31891 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31892 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31893 ++#endif
31894 ++
31895 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
31896 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
31897 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
31898 +diff -urNp a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
31899 +--- a/include/asm-powerpc/elf.h 2008-08-20 11:16:13.000000000 -0700
31900 ++++ b/include/asm-powerpc/elf.h 2008-08-20 18:36:57.000000000 -0700
31901 +@@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
31902 + typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
31903 + #endif
31904 +
31905 ++#ifdef CONFIG_PAX_ASLR
31906 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
31907 ++
31908 ++#ifdef __powerpc64__
31909 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
31910 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
31911 ++#else
31912 ++#define PAX_DELTA_MMAP_LEN 15
31913 ++#define PAX_DELTA_STACK_LEN 15
31914 ++#endif
31915 ++#endif
31916 ++
31917 + #ifdef __KERNEL__
31918 + /*
31919 + * This is used to ensure we don't load something for the wrong architecture.
31920 +diff -urNp a/include/asm-powerpc/kmap_types.h b/include/asm-powerpc/kmap_types.h
31921 +--- a/include/asm-powerpc/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31922 ++++ b/include/asm-powerpc/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31923 +@@ -26,6 +26,7 @@ enum km_type {
31924 + KM_SOFTIRQ1,
31925 + KM_PPC_SYNC_PAGE,
31926 + KM_PPC_SYNC_ICACHE,
31927 ++ KM_CLEARPAGE,
31928 + KM_TYPE_NR
31929 + };
31930 +
31931 +diff -urNp a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
31932 +--- a/include/asm-powerpc/page.h 2008-08-20 11:16:13.000000000 -0700
31933 ++++ b/include/asm-powerpc/page.h 2008-08-20 18:36:57.000000000 -0700
31934 +@@ -70,8 +70,9 @@
31935 + * and needs to be executable. This means the whole heap ends
31936 + * up being executable.
31937 + */
31938 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
31939 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31940 ++#define VM_DATA_DEFAULT_FLAGS32 \
31941 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
31942 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31943 +
31944 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
31945 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31946 +diff -urNp a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h
31947 +--- a/include/asm-powerpc/page_64.h 2008-08-20 11:16:13.000000000 -0700
31948 ++++ b/include/asm-powerpc/page_64.h 2008-08-20 18:36:57.000000000 -0700
31949 +@@ -170,15 +170,18 @@ do { \
31950 + * stack by default, so in the absense of a PT_GNU_STACK program header
31951 + * we turn execute permission off.
31952 + */
31953 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
31954 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31955 ++#define VM_STACK_DEFAULT_FLAGS32 \
31956 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
31957 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31958 +
31959 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
31960 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31961 +
31962 ++#ifndef CONFIG_PAX_PAGEEXEC
31963 + #define VM_STACK_DEFAULT_FLAGS \
31964 + (test_thread_flag(TIF_32BIT) ? \
31965 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
31966 ++#endif
31967 +
31968 + #include <asm-generic/page.h>
31969 +
31970 +diff -urNp a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
31971 +--- a/include/asm-ppc/mmu_context.h 2008-08-20 11:16:13.000000000 -0700
31972 ++++ b/include/asm-ppc/mmu_context.h 2008-08-20 18:36:57.000000000 -0700
31973 +@@ -141,7 +141,8 @@ static inline void get_mmu_context(struc
31974 + static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
31975 + {
31976 + mm->context.id = NO_CONTEXT;
31977 +- mm->context.vdso_base = 0;
31978 ++ if (t == current)
31979 ++ mm->context.vdso_base = ~0UL;
31980 + return 0;
31981 + }
31982 +
31983 +diff -urNp a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
31984 +--- a/include/asm-ppc/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31985 ++++ b/include/asm-ppc/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31986 +@@ -390,11 +390,21 @@ extern unsigned long ioremap_bot, iorema
31987 +
31988 + #define PAGE_NONE __pgprot(_PAGE_BASE)
31989 + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
31990 +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
31991 ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
31992 + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
31993 +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
31994 ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
31995 + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
31996 +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
31997 ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
31998 ++
31999 ++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
32000 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
32001 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
32002 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
32003 ++#else
32004 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
32005 ++# define PAGE_COPY_NOEXEC PAGE_COPY
32006 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
32007 ++#endif
32008 +
32009 + #define PAGE_KERNEL __pgprot(_PAGE_RAM)
32010 + #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
32011 +@@ -406,21 +416,21 @@ extern unsigned long ioremap_bot, iorema
32012 + * This is the closest we can get..
32013 + */
32014 + #define __P000 PAGE_NONE
32015 +-#define __P001 PAGE_READONLY_X
32016 +-#define __P010 PAGE_COPY
32017 +-#define __P011 PAGE_COPY_X
32018 +-#define __P100 PAGE_READONLY
32019 ++#define __P001 PAGE_READONLY_NOEXEC
32020 ++#define __P010 PAGE_COPY_NOEXEC
32021 ++#define __P011 PAGE_COPY_NOEXEC
32022 ++#define __P100 PAGE_READONLY_X
32023 + #define __P101 PAGE_READONLY_X
32024 +-#define __P110 PAGE_COPY
32025 ++#define __P110 PAGE_COPY_X
32026 + #define __P111 PAGE_COPY_X
32027 +
32028 + #define __S000 PAGE_NONE
32029 +-#define __S001 PAGE_READONLY_X
32030 +-#define __S010 PAGE_SHARED
32031 +-#define __S011 PAGE_SHARED_X
32032 +-#define __S100 PAGE_READONLY
32033 ++#define __S001 PAGE_READONLY_NOEXEC
32034 ++#define __S010 PAGE_SHARED_NOEXEC
32035 ++#define __S011 PAGE_SHARED_NOEXEC
32036 ++#define __S100 PAGE_READONLY_X
32037 + #define __S101 PAGE_READONLY_X
32038 +-#define __S110 PAGE_SHARED
32039 ++#define __S110 PAGE_SHARED_X
32040 + #define __S111 PAGE_SHARED_X
32041 +
32042 + #ifndef __ASSEMBLY__
32043 +diff -urNp a/include/asm-s390/kmap_types.h b/include/asm-s390/kmap_types.h
32044 +--- a/include/asm-s390/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32045 ++++ b/include/asm-s390/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32046 +@@ -16,6 +16,7 @@ enum km_type {
32047 + KM_IRQ1,
32048 + KM_SOFTIRQ0,
32049 + KM_SOFTIRQ1,
32050 ++ KM_CLEARPAGE,
32051 + KM_TYPE_NR
32052 + };
32053 +
32054 +diff -urNp a/include/asm-sh/kmap_types.h b/include/asm-sh/kmap_types.h
32055 +--- a/include/asm-sh/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32056 ++++ b/include/asm-sh/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32057 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
32058 + D(10) KM_IRQ1,
32059 + D(11) KM_SOFTIRQ0,
32060 + D(12) KM_SOFTIRQ1,
32061 +-D(13) KM_TYPE_NR
32062 ++D(13) KM_CLEARPAGE,
32063 ++D(14) KM_TYPE_NR
32064 + };
32065 +
32066 + #undef D
32067 +diff -urNp a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
32068 +--- a/include/asm-sparc/elf.h 2008-08-20 11:16:13.000000000 -0700
32069 ++++ b/include/asm-sparc/elf.h 2008-08-20 18:36:57.000000000 -0700
32070 +@@ -120,6 +120,13 @@ typedef struct {
32071 +
32072 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
32073 +
32074 ++#ifdef CONFIG_PAX_ASLR
32075 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
32076 ++
32077 ++#define PAX_DELTA_MMAP_LEN 16
32078 ++#define PAX_DELTA_STACK_LEN 16
32079 ++#endif
32080 ++
32081 + /* This yields a mask that user programs can use to figure out what
32082 + instruction set this cpu supports. This can NOT be done in userspace
32083 + on Sparc. */
32084 +diff -urNp a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h
32085 +--- a/include/asm-sparc/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32086 ++++ b/include/asm-sparc/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32087 +@@ -15,6 +15,7 @@ enum km_type {
32088 + KM_IRQ1,
32089 + KM_SOFTIRQ0,
32090 + KM_SOFTIRQ1,
32091 ++ KM_CLEARPAGE,
32092 + KM_TYPE_NR
32093 + };
32094 +
32095 +diff -urNp a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
32096 +--- a/include/asm-sparc/pgtable.h 2008-08-20 11:16:13.000000000 -0700
32097 ++++ b/include/asm-sparc/pgtable.h 2008-08-20 18:36:57.000000000 -0700
32098 +@@ -48,6 +48,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
32099 + BTFIXUPDEF_INT(page_none)
32100 + BTFIXUPDEF_INT(page_copy)
32101 + BTFIXUPDEF_INT(page_readonly)
32102 ++
32103 ++#ifdef CONFIG_PAX_PAGEEXEC
32104 ++BTFIXUPDEF_INT(page_shared_noexec)
32105 ++BTFIXUPDEF_INT(page_copy_noexec)
32106 ++BTFIXUPDEF_INT(page_readonly_noexec)
32107 ++#endif
32108 ++
32109 + BTFIXUPDEF_INT(page_kernel)
32110 +
32111 + #define PMD_SHIFT SUN4C_PMD_SHIFT
32112 +@@ -69,6 +76,16 @@ extern pgprot_t PAGE_SHARED;
32113 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
32114 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
32115 +
32116 ++#ifdef CONFIG_PAX_PAGEEXEC
32117 ++extern pgprot_t PAGE_SHARED_NOEXEC;
32118 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
32119 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
32120 ++#else
32121 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
32122 ++# define PAGE_COPY_NOEXEC PAGE_COPY
32123 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
32124 ++#endif
32125 ++
32126 + extern unsigned long page_kernel;
32127 +
32128 + #ifdef MODULE
32129 +diff -urNp a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
32130 +--- a/include/asm-sparc/pgtsrmmu.h 2008-08-20 11:16:13.000000000 -0700
32131 ++++ b/include/asm-sparc/pgtsrmmu.h 2008-08-20 18:36:57.000000000 -0700
32132 +@@ -115,6 +115,16 @@
32133 + SRMMU_EXEC | SRMMU_REF)
32134 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32135 + SRMMU_EXEC | SRMMU_REF)
32136 ++
32137 ++#ifdef CONFIG_PAX_PAGEEXEC
32138 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32139 ++ SRMMU_WRITE | SRMMU_REF)
32140 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32141 ++ SRMMU_REF)
32142 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32143 ++ SRMMU_REF)
32144 ++#endif
32145 ++
32146 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
32147 + SRMMU_DIRTY | SRMMU_REF)
32148 +
32149 +diff -urNp a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
32150 +--- a/include/asm-sparc64/elf.h 2008-08-20 11:16:13.000000000 -0700
32151 ++++ b/include/asm-sparc64/elf.h 2008-08-20 18:36:57.000000000 -0700
32152 +@@ -164,6 +164,12 @@ typedef struct {
32153 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
32154 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
32155 +
32156 ++#ifdef CONFIG_PAX_ASLR
32157 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
32158 ++
32159 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
32160 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
32161 ++#endif
32162 +
32163 + /* This yields a mask that user programs can use to figure out what
32164 + instruction set this cpu supports. */
32165 +diff -urNp a/include/asm-sparc64/kmap_types.h b/include/asm-sparc64/kmap_types.h
32166 +--- a/include/asm-sparc64/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32167 ++++ b/include/asm-sparc64/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32168 +@@ -19,6 +19,7 @@ enum km_type {
32169 + KM_IRQ1,
32170 + KM_SOFTIRQ0,
32171 + KM_SOFTIRQ1,
32172 ++ KM_CLEARPAGE,
32173 + KM_TYPE_NR
32174 + };
32175 +
32176 +diff -urNp a/include/asm-um/kmap_types.h b/include/asm-um/kmap_types.h
32177 +--- a/include/asm-um/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32178 ++++ b/include/asm-um/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32179 +@@ -23,6 +23,7 @@ enum km_type {
32180 + KM_IRQ1,
32181 + KM_SOFTIRQ0,
32182 + KM_SOFTIRQ1,
32183 ++ KM_CLEARPAGE,
32184 + KM_TYPE_NR
32185 + };
32186 +
32187 +diff -urNp a/include/asm-v850/kmap_types.h b/include/asm-v850/kmap_types.h
32188 +--- a/include/asm-v850/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32189 ++++ b/include/asm-v850/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32190 +@@ -13,6 +13,7 @@ enum km_type {
32191 + KM_PTE1,
32192 + KM_IRQ0,
32193 + KM_IRQ1,
32194 ++ KM_CLEARPAGE,
32195 + KM_TYPE_NR
32196 + };
32197 +
32198 +diff -urNp a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h
32199 +--- a/include/asm-x86/alternative.h 2008-08-20 11:16:13.000000000 -0700
32200 ++++ b/include/asm-x86/alternative.h 2008-08-20 18:36:57.000000000 -0700
32201 +@@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
32202 + " .byte 662b-661b\n" /* sourcelen */ \
32203 + " .byte 664f-663f\n" /* replacementlen */ \
32204 + ".previous\n" \
32205 +- ".section .altinstr_replacement,\"ax\"\n" \
32206 ++ ".section .altinstr_replacement,\"a\"\n" \
32207 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
32208 + ".previous" :: "i" (feature) : "memory")
32209 +
32210 +@@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
32211 + " .byte 662b-661b\n" /* sourcelen */ \
32212 + " .byte 664f-663f\n" /* replacementlen */ \
32213 + ".previous\n" \
32214 +- ".section .altinstr_replacement,\"ax\"\n" \
32215 ++ ".section .altinstr_replacement,\"a\"\n" \
32216 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
32217 + ".previous" :: "i" (feature), ##input)
32218 +
32219 +@@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
32220 + " .byte 662b-661b\n" /* sourcelen */ \
32221 + " .byte 664f-663f\n" /* replacementlen */ \
32222 + ".previous\n" \
32223 +- ".section .altinstr_replacement,\"ax\"\n" \
32224 ++ ".section .altinstr_replacement,\"a\"\n" \
32225 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
32226 + ".previous" : output : [feat] "i" (feature), ##input)
32227 +
32228 +diff -urNp a/include/asm-x86/apic.h b/include/asm-x86/apic.h
32229 +--- a/include/asm-x86/apic.h 2008-08-20 11:16:13.000000000 -0700
32230 ++++ b/include/asm-x86/apic.h 2008-08-20 18:36:57.000000000 -0700
32231 +@@ -10,7 +10,7 @@
32232 +
32233 + #define ARCH_APICTIMER_STOPS_ON_C3 1
32234 +
32235 +-#define Dprintk(x...)
32236 ++#define Dprintk(x...) do {} while (0)
32237 +
32238 + /*
32239 + * Debugging macros
32240 +diff -urNp a/include/asm-x86/boot.h b/include/asm-x86/boot.h
32241 +--- a/include/asm-x86/boot.h 2008-08-20 11:16:13.000000000 -0700
32242 ++++ b/include/asm-x86/boot.h 2008-08-20 18:36:57.000000000 -0700
32243 +@@ -13,8 +13,13 @@
32244 + #define ASK_VGA 0xfffd /* ask for it at bootup */
32245 +
32246 + /* Physical address where kernel should be loaded. */
32247 +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
32248 ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
32249 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
32250 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
32251 +
32252 ++#ifndef __ASSEMBLY__
32253 ++extern unsigned char __LOAD_PHYSICAL_ADDR[];
32254 ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
32255 ++#endif
32256 ++
32257 + #endif /* _ASM_BOOT_H */
32258 +diff -urNp a/include/asm-x86/cache.h b/include/asm-x86/cache.h
32259 +--- a/include/asm-x86/cache.h 2008-08-20 11:16:13.000000000 -0700
32260 ++++ b/include/asm-x86/cache.h 2008-08-20 18:36:57.000000000 -0700
32261 +@@ -6,6 +6,7 @@
32262 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
32263 +
32264 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
32265 ++#define __read_only __attribute__((__section__(".data.read_only")))
32266 +
32267 + #ifdef CONFIG_X86_VSMP
32268 + /* vSMP Internode cacheline shift */
32269 +diff -urNp a/include/asm-x86/checksum_32.h b/include/asm-x86/checksum_32.h
32270 +--- a/include/asm-x86/checksum_32.h 2008-08-20 11:16:13.000000000 -0700
32271 ++++ b/include/asm-x86/checksum_32.h 2008-08-20 18:36:57.000000000 -0700
32272 +@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
32273 + asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
32274 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
32275 +
32276 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
32277 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
32278 ++
32279 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
32280 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
32281 ++
32282 + /*
32283 + * Note: when you get a NULL pointer exception here this means someone
32284 + * passed in an incorrect kernel address to one of these functions.
32285 +@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
32286 + int len, __wsum sum, int *err_ptr)
32287 + {
32288 + might_sleep();
32289 +- return csum_partial_copy_generic((__force void *)src, dst,
32290 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
32291 + len, sum, err_ptr, NULL);
32292 + }
32293 +
32294 +@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
32295 + {
32296 + might_sleep();
32297 + if (access_ok(VERIFY_WRITE, dst, len))
32298 +- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
32299 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
32300 +
32301 + if (len)
32302 + *err_ptr = -EFAULT;
32303 +diff -urNp a/include/asm-x86/desc.h b/include/asm-x86/desc.h
32304 +--- a/include/asm-x86/desc.h 2008-08-20 11:16:13.000000000 -0700
32305 ++++ b/include/asm-x86/desc.h 2008-08-20 18:36:57.000000000 -0700
32306 +@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
32307 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
32308 + desc->type = (info->read_exec_only ^ 1) << 1;
32309 + desc->type |= info->contents << 2;
32310 ++ desc->type |= info->seg_not_present ^ 1;
32311 + desc->s = 1;
32312 + desc->dpl = 0x3;
32313 + desc->p = info->seg_not_present ^ 1;
32314 +@@ -27,14 +28,15 @@ static inline void fill_ldt(struct desc_
32315 + }
32316 +
32317 + extern struct desc_ptr idt_descr;
32318 +-extern gate_desc idt_table[];
32319 ++extern gate_desc idt_table[256];
32320 +
32321 +-#ifdef CONFIG_X86_64
32322 +-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
32323 +-extern struct desc_ptr cpu_gdt_descr[];
32324 +-/* the cpu gdt accessor */
32325 +-#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
32326 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
32327 ++static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
32328 ++{
32329 ++ return cpu_gdt_table[cpu];
32330 ++}
32331 +
32332 ++#ifdef CONFIG_X86_64
32333 + static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
32334 + unsigned dpl, unsigned ist, unsigned seg)
32335 + {
32336 +@@ -51,16 +53,6 @@ static inline void pack_gate(gate_desc *
32337 + }
32338 +
32339 + #else
32340 +-struct gdt_page {
32341 +- struct desc_struct gdt[GDT_ENTRIES];
32342 +-} __attribute__((aligned(PAGE_SIZE)));
32343 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
32344 +-
32345 +-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
32346 +-{
32347 +- return per_cpu(gdt_page, cpu).gdt;
32348 +-}
32349 +-
32350 + static inline void pack_gate(gate_desc *gate, unsigned char type,
32351 + unsigned long base, unsigned dpl, unsigned flags, unsigned short seg)
32352 +
32353 +@@ -69,7 +61,6 @@ static inline void pack_gate(gate_desc *
32354 + gate->b = (base & 0xffff0000) |
32355 + (((0x80 | type | (dpl << 5)) & 0xff) << 8);
32356 + }
32357 +-
32358 + #endif
32359 +
32360 + static inline int desc_empty(const void *ptr)
32361 +@@ -105,19 +96,48 @@ static inline int desc_empty(const void
32362 + static inline void native_write_idt_entry(gate_desc *idt, int entry,
32363 + const gate_desc *gate)
32364 + {
32365 ++
32366 ++#ifdef CONFIG_PAX_KERNEXEC
32367 ++ unsigned long cr0;
32368 ++
32369 ++ pax_open_kernel(cr0);
32370 ++#endif
32371 ++
32372 + memcpy(&idt[entry], gate, sizeof(*gate));
32373 ++
32374 ++#ifdef CONFIG_PAX_KERNEXEC
32375 ++ pax_close_kernel(cr0);
32376 ++#endif
32377 ++
32378 + }
32379 +
32380 + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
32381 + const void *desc)
32382 + {
32383 ++
32384 ++#ifdef CONFIG_PAX_KERNEXEC
32385 ++ unsigned long cr0;
32386 ++
32387 ++ pax_open_kernel(cr0);
32388 ++#endif
32389 ++
32390 + memcpy(&ldt[entry], desc, 8);
32391 ++
32392 ++#ifdef CONFIG_PAX_KERNEXEC
32393 ++ pax_close_kernel(cr0);
32394 ++#endif
32395 ++
32396 + }
32397 +
32398 + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
32399 + const void *desc, int type)
32400 + {
32401 + unsigned int size;
32402 ++
32403 ++#ifdef CONFIG_PAX_KERNEXEC
32404 ++ unsigned long cr0;
32405 ++#endif
32406 ++
32407 + switch (type) {
32408 + case DESC_TSS:
32409 + size = sizeof(tss_desc);
32410 +@@ -129,7 +149,17 @@ static inline void native_write_gdt_entr
32411 + size = sizeof(struct desc_struct);
32412 + break;
32413 + }
32414 ++
32415 ++#ifdef CONFIG_PAX_KERNEXEC
32416 ++ pax_open_kernel(cr0);
32417 ++#endif
32418 ++
32419 + memcpy(&gdt[entry], desc, size);
32420 ++
32421 ++#ifdef CONFIG_PAX_KERNEXEC
32422 ++ pax_close_kernel(cr0);
32423 ++#endif
32424 ++
32425 + }
32426 +
32427 + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
32428 +@@ -201,7 +231,19 @@ static inline void native_set_ldt(const
32429 +
32430 + static inline void native_load_tr_desc(void)
32431 + {
32432 ++
32433 ++#ifdef CONFIG_PAX_KERNEXEC
32434 ++ unsigned long cr0;
32435 ++
32436 ++ pax_open_kernel(cr0);
32437 ++#endif
32438 ++
32439 + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
32440 ++
32441 ++#ifdef CONFIG_PAX_KERNEXEC
32442 ++ pax_close_kernel(cr0);
32443 ++#endif
32444 ++
32445 + }
32446 +
32447 + static inline void native_load_gdt(const struct desc_ptr *dtr)
32448 +@@ -236,8 +278,19 @@ static inline void native_load_tls(struc
32449 + unsigned int i;
32450 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
32451 +
32452 ++#ifdef CONFIG_PAX_KERNEXEC
32453 ++ unsigned long cr0;
32454 ++
32455 ++ pax_open_kernel(cr0);
32456 ++#endif
32457 ++
32458 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
32459 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
32460 ++
32461 ++#ifdef CONFIG_PAX_KERNEXEC
32462 ++ pax_close_kernel(cr0);
32463 ++#endif
32464 ++
32465 + }
32466 +
32467 + #define _LDT_empty(info) (\
32468 +@@ -353,6 +406,18 @@ static inline void set_system_gate_ist(i
32469 + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
32470 + }
32471 +
32472 ++#ifdef CONFIG_X86_32
32473 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
32474 ++{
32475 ++ struct desc_struct d;
32476 ++
32477 ++ if (likely(limit))
32478 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
32479 ++ pack_descriptor(&d, base, limit, 0xFB, 0xC);
32480 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
32481 ++}
32482 ++#endif
32483 ++
32484 + #else
32485 + /*
32486 + * GET_DESC_BASE reads the descriptor base of the specified segment.
32487 +diff -urNp a/include/asm-x86/elf.h b/include/asm-x86/elf.h
32488 +--- a/include/asm-x86/elf.h 2008-08-20 11:16:13.000000000 -0700
32489 ++++ b/include/asm-x86/elf.h 2008-08-20 18:36:57.000000000 -0700
32490 +@@ -243,7 +243,25 @@ extern int force_personality32;
32491 + the loader. We need to make sure that it is out of the way of the program
32492 + that it will "exec", and that there is sufficient room for the brk. */
32493 +
32494 ++#ifdef CONFIG_PAX_SEGMEXEC
32495 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
32496 ++#else
32497 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
32498 ++#endif
32499 ++
32500 ++#ifdef CONFIG_PAX_ASLR
32501 ++#ifdef CONFIG_X86_32
32502 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
32503 ++
32504 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
32505 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
32506 ++#else
32507 ++#define PAX_ELF_ET_DYN_BASE 0x400000UL
32508 ++
32509 ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
32510 ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
32511 ++#endif
32512 ++#endif
32513 +
32514 + /* This yields a mask that user programs can use to figure out what
32515 + instruction set this CPU supports. This could be done in user space,
32516 +@@ -292,7 +310,7 @@ do if (vdso_enabled) { \
32517 +
32518 + #define ARCH_DLINFO \
32519 + do if (vdso_enabled) { \
32520 +- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
32521 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR,current->mm->context.vdso);\
32522 + } while (0)
32523 +
32524 + #define AT_SYSINFO 32
32525 +@@ -303,7 +321,7 @@ do if (vdso_enabled) { \
32526 +
32527 + #endif /* !CONFIG_X86_32 */
32528 +
32529 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
32530 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
32531 +
32532 + #define VDSO_ENTRY \
32533 + ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
32534 +@@ -317,7 +335,4 @@ extern int arch_setup_additional_pages(s
32535 + extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
32536 + #define compat_arch_setup_additional_pages syscall32_setup_pages
32537 +
32538 +-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
32539 +-#define arch_randomize_brk arch_randomize_brk
32540 +-
32541 + #endif
32542 +diff -urNp a/include/asm-x86/futex.h b/include/asm-x86/futex.h
32543 +--- a/include/asm-x86/futex.h 2008-08-20 11:16:13.000000000 -0700
32544 ++++ b/include/asm-x86/futex.h 2008-08-20 18:36:57.000000000 -0700
32545 +@@ -11,6 +11,41 @@
32546 + #include <asm/system.h>
32547 + #include <asm/uaccess.h>
32548 +
32549 ++#ifdef CONFIG_X86_32
32550 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
32551 ++ __asm__ __volatile( \
32552 ++ "movw %w6, %%ds\n" \
32553 ++"1: " insn "\n" \
32554 ++"2: pushl %%ss\n \
32555 ++ popl %%ds\n \
32556 ++ .section .fixup,\"ax\"\n \
32557 ++3: mov %3, %1\n \
32558 ++ jmp 2b\n \
32559 ++ .previous\n" \
32560 ++ _ASM_EXTABLE(1b,3b) \
32561 ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
32562 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
32563 ++
32564 ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
32565 ++ __asm__ __volatile( \
32566 ++" movw %w7, %%es\n \
32567 ++1: movl %%es:%2, %0\n \
32568 ++ movl %0, %3\n" \
32569 ++ insn "\n" \
32570 ++"2: lock; cmpxchgl %3, %%es:%2\n \
32571 ++ jnz 1b\n \
32572 ++3: pushl %%ss\n \
32573 ++ popl %%es\n \
32574 ++ .section .fixup,\"ax\"\n \
32575 ++4: mov %5, %1\n \
32576 ++ jmp 3b\n \
32577 ++ .previous\n" \
32578 ++ _ASM_EXTABLE(1b,4b) \
32579 ++ _ASM_EXTABLE(2b,4b) \
32580 ++ : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
32581 ++ "=&r" (tem) \
32582 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
32583 ++#else
32584 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
32585 + __asm__ __volatile( \
32586 + "1: " insn "\n" \
32587 +@@ -38,6 +73,7 @@
32588 + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
32589 + "=&r" (tem) \
32590 + : "r" (oparg), "i" (-EFAULT), "1" (0))
32591 ++#endif
32592 +
32593 + static inline int
32594 + futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
32595 +@@ -64,11 +100,20 @@ futex_atomic_op_inuser(int encoded_op, i
32596 +
32597 + switch (op) {
32598 + case FUTEX_OP_SET:
32599 ++#ifdef CONFIG_X86_32
32600 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
32601 ++#else
32602 + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
32603 ++#endif
32604 + break;
32605 + case FUTEX_OP_ADD:
32606 ++#ifdef CONFIG_X86_32
32607 ++ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
32608 ++ uaddr, oparg);
32609 ++#else
32610 + __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
32611 + uaddr, oparg);
32612 ++#endif
32613 + break;
32614 + case FUTEX_OP_OR:
32615 + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
32616 +@@ -113,14 +158,26 @@ futex_atomic_cmpxchg_inatomic(int __user
32617 + return -EFAULT;
32618 +
32619 + __asm__ __volatile__(
32620 ++#ifdef CONFIG_X86_32
32621 ++ " movw %w5, %%ds \n"
32622 ++ "1: lock; cmpxchgl %3, %%ds:%1 \n"
32623 ++ "2: pushl %%ss \n"
32624 ++ " popl %%ds \n"
32625 ++ " .section .fixup, \"ax\" \n"
32626 ++#else
32627 + "1: lock; cmpxchgl %3, %1 \n"
32628 + "2: .section .fixup, \"ax\" \n"
32629 ++#endif
32630 + "3: mov %2, %0 \n"
32631 + " jmp 2b \n"
32632 + " .previous \n"
32633 + _ASM_EXTABLE(1b,3b)
32634 + : "=a" (oldval), "+m" (*uaddr)
32635 ++#ifdef CONFIG_X86_32
32636 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
32637 ++#else
32638 + : "i" (-EFAULT), "r" (newval), "0" (oldval)
32639 ++#endif
32640 + : "memory"
32641 + );
32642 +
32643 +diff -urNp a/include/asm-x86/i387.h b/include/asm-x86/i387.h
32644 +--- a/include/asm-x86/i387.h 2008-08-20 11:16:13.000000000 -0700
32645 ++++ b/include/asm-x86/i387.h 2008-08-20 18:36:57.000000000 -0700
32646 +@@ -202,13 +202,8 @@ static inline void restore_fpu(struct ta
32647 + }
32648 +
32649 + /* We need a safe address that is cheap to find and that is already
32650 +- in L1 during context switch. The best choices are unfortunately
32651 +- different for UP and SMP */
32652 +-#ifdef CONFIG_SMP
32653 +-#define safe_address (__per_cpu_offset[0])
32654 +-#else
32655 +-#define safe_address (kstat_cpu(0).cpustat.user)
32656 +-#endif
32657 ++ in L1 during context switch. */
32658 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
32659 +
32660 + /*
32661 + * These must be called with preempt disabled
32662 +diff -urNp a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h
32663 +--- a/include/asm-x86/io_64.h 2008-08-20 11:16:13.000000000 -0700
32664 ++++ b/include/asm-x86/io_64.h 2008-08-20 18:36:57.000000000 -0700
32665 +@@ -143,6 +143,17 @@ static inline void * phys_to_virt(unsign
32666 + }
32667 + #endif
32668 +
32669 ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
32670 ++static inline int valid_phys_addr_range (unsigned long addr, size_t count)
32671 ++{
32672 ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
32673 ++}
32674 ++
32675 ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
32676 ++{
32677 ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
32678 ++}
32679 ++
32680 + /*
32681 + * Change "struct page" to physical address.
32682 + */
32683 +diff -urNp a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h
32684 +--- a/include/asm-x86/irqflags.h 2008-08-20 11:16:13.000000000 -0700
32685 ++++ b/include/asm-x86/irqflags.h 2008-08-20 18:36:57.000000000 -0700
32686 +@@ -146,6 +146,8 @@ static inline unsigned long __raw_local_
32687 + #define INTERRUPT_RETURN iret
32688 + #define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit
32689 + #define GET_CR0_INTO_EAX movl %cr0, %eax
32690 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
32691 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
32692 + #endif
32693 +
32694 +
32695 +diff -urNp a/include/asm-x86/kmap_types.h b/include/asm-x86/kmap_types.h
32696 +--- a/include/asm-x86/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32697 ++++ b/include/asm-x86/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32698 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
32699 + D(10) KM_IRQ1,
32700 + D(11) KM_SOFTIRQ0,
32701 + D(12) KM_SOFTIRQ1,
32702 +-D(13) KM_TYPE_NR
32703 ++D(13) KM_CLEARPAGE,
32704 ++D(14) KM_TYPE_NR
32705 + };
32706 +
32707 + #undef D
32708 +diff -urNp a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h
32709 +--- a/include/asm-x86/linkage.h 2008-08-20 11:16:13.000000000 -0700
32710 ++++ b/include/asm-x86/linkage.h 2008-08-20 18:36:57.000000000 -0700
32711 +@@ -4,6 +4,11 @@
32712 + #ifdef CONFIG_X86_64
32713 + #define __ALIGN .p2align 4,,15
32714 + #define __ALIGN_STR ".p2align 4,,15"
32715 ++#else
32716 ++#ifdef CONFIG_X86_ALIGNMENT_16
32717 ++#define __ALIGN .align 16,0x90
32718 ++#define __ALIGN_STR ".align 16,0x90"
32719 ++#endif
32720 + #endif
32721 +
32722 + #ifdef CONFIG_X86_32
32723 +@@ -49,10 +54,5 @@
32724 +
32725 + #endif
32726 +
32727 +-#ifdef CONFIG_X86_ALIGNMENT_16
32728 +-#define __ALIGN .align 16,0x90
32729 +-#define __ALIGN_STR ".align 16,0x90"
32730 +-#endif
32731 +-
32732 + #endif
32733 +
32734 +diff -urNp a/include/asm-x86/mach-default/apm.h b/include/asm-x86/mach-default/apm.h
32735 +--- a/include/asm-x86/mach-default/apm.h 2008-08-20 11:16:13.000000000 -0700
32736 ++++ b/include/asm-x86/mach-default/apm.h 2008-08-20 18:36:57.000000000 -0700
32737 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
32738 + __asm__ __volatile__(APM_DO_ZERO_SEGS
32739 + "pushl %%edi\n\t"
32740 + "pushl %%ebp\n\t"
32741 +- "lcall *%%cs:apm_bios_entry\n\t"
32742 ++ "lcall *%%ss:apm_bios_entry\n\t"
32743 + "setc %%al\n\t"
32744 + "popl %%ebp\n\t"
32745 + "popl %%edi\n\t"
32746 +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
32747 + __asm__ __volatile__(APM_DO_ZERO_SEGS
32748 + "pushl %%edi\n\t"
32749 + "pushl %%ebp\n\t"
32750 +- "lcall *%%cs:apm_bios_entry\n\t"
32751 ++ "lcall *%%ss:apm_bios_entry\n\t"
32752 + "setc %%bl\n\t"
32753 + "popl %%ebp\n\t"
32754 + "popl %%edi\n\t"
32755 +diff -urNp a/include/asm-x86/mman.h b/include/asm-x86/mman.h
32756 +--- a/include/asm-x86/mman.h 2008-08-20 11:16:13.000000000 -0700
32757 ++++ b/include/asm-x86/mman.h 2008-08-20 18:36:57.000000000 -0700
32758 +@@ -16,4 +16,14 @@
32759 + #define MCL_CURRENT 1 /* lock all current mappings */
32760 + #define MCL_FUTURE 2 /* lock all future mappings */
32761 +
32762 ++#ifdef __KERNEL__
32763 ++#ifndef __ASSEMBLY__
32764 ++#ifdef CONFIG_X86_32
32765 ++#define arch_mmap_check i386_mmap_check
32766 ++int i386_mmap_check(unsigned long addr, unsigned long len,
32767 ++ unsigned long flags);
32768 ++#endif
32769 ++#endif
32770 ++#endif
32771 ++
32772 + #endif /* _ASM_X86_MMAN_H */
32773 +diff -urNp a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h
32774 +--- a/include/asm-x86/mmu.h 2008-08-20 11:16:13.000000000 -0700
32775 ++++ b/include/asm-x86/mmu.h 2008-08-20 18:36:57.000000000 -0700
32776 +@@ -11,13 +11,26 @@
32777 + * cpu_vm_mask is used to optimize ldt flushing.
32778 + */
32779 + typedef struct {
32780 +- void *ldt;
32781 ++ struct desc_struct *ldt;
32782 + #ifdef CONFIG_X86_64
32783 + rwlock_t ldtlock;
32784 + #endif
32785 + int size;
32786 + struct mutex lock;
32787 +- void *vdso;
32788 ++ unsigned long vdso;
32789 ++
32790 ++#ifdef CONFIG_X86_32
32791 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32792 ++ unsigned long user_cs_base;
32793 ++ unsigned long user_cs_limit;
32794 ++
32795 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
32796 ++ cpumask_t cpu_user_cs_mask;
32797 ++#endif
32798 ++
32799 ++#endif
32800 ++#endif
32801 ++
32802 + } mm_context_t;
32803 +
32804 + #ifdef CONFIG_SMP
32805 +diff -urNp a/include/asm-x86/mmu_context_32.h b/include/asm-x86/mmu_context_32.h
32806 +--- a/include/asm-x86/mmu_context_32.h 2008-08-20 11:16:13.000000000 -0700
32807 ++++ b/include/asm-x86/mmu_context_32.h 2008-08-20 18:36:57.000000000 -0700
32808 +@@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
32809 + */
32810 + if (unlikely(prev->context.ldt != next->context.ldt))
32811 + load_LDT_nolock(&next->context);
32812 ++
32813 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
32814 ++ if (!nx_enabled) {
32815 ++ smp_mb__before_clear_bit();
32816 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
32817 ++ smp_mb__after_clear_bit();
32818 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
32819 ++ }
32820 ++#endif
32821 ++
32822 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32823 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
32824 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
32825 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
32826 ++#endif
32827 ++
32828 + }
32829 + #ifdef CONFIG_SMP
32830 + else {
32831 +@@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
32832 + */
32833 + load_cr3(next->pgd);
32834 + load_LDT_nolock(&next->context);
32835 ++
32836 ++#ifdef CONFIG_PAX_PAGEEXEC
32837 ++ if (!nx_enabled)
32838 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
32839 ++#endif
32840 ++
32841 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32842 ++#ifdef CONFIG_PAX_PAGEEXEC
32843 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
32844 ++#endif
32845 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
32846 ++#endif
32847 ++
32848 + }
32849 + }
32850 + #endif
32851 +diff -urNp a/include/asm-x86/module.h b/include/asm-x86/module.h
32852 +--- a/include/asm-x86/module.h 2008-08-20 11:16:13.000000000 -0700
32853 ++++ b/include/asm-x86/module.h 2008-08-20 18:36:57.000000000 -0700
32854 +@@ -76,7 +76,12 @@ struct mod_arch_specific {};
32855 + # else
32856 + # define MODULE_STACKSIZE ""
32857 + # endif
32858 +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
32859 ++# ifdef CONFIG_GRKERNSEC
32860 ++# define MODULE_GRSEC "GRSECURITY "
32861 ++# else
32862 ++# define MODULE_GRSEC ""
32863 ++# endif
32864 ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
32865 + #endif
32866 +
32867 + #endif /* _ASM_MODULE_H */
32868 +diff -urNp a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
32869 +--- a/include/asm-x86/page_32.h 2008-08-20 11:16:13.000000000 -0700
32870 ++++ b/include/asm-x86/page_32.h 2008-08-20 18:36:57.000000000 -0700
32871 +@@ -13,6 +13,23 @@
32872 + */
32873 + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
32874 +
32875 ++#ifdef CONFIG_PAX_KERNEXEC
32876 ++#ifndef __ASSEMBLY__
32877 ++extern unsigned char MODULES_VADDR[];
32878 ++extern unsigned char MODULES_END[];
32879 ++extern unsigned char KERNEL_TEXT_OFFSET[];
32880 ++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
32881 ++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
32882 ++#endif
32883 ++#else
32884 ++#define ktla_ktva(addr) (addr)
32885 ++#define ktva_ktla(addr) (addr)
32886 ++#endif
32887 ++
32888 ++#ifdef CONFIG_PAX_PAGEEXEC
32889 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
32890 ++#endif
32891 ++
32892 + #ifdef CONFIG_X86_PAE
32893 + /* 44=32+12, the limit we can fit into an unsigned long pfn */
32894 + #define __PHYSICAL_MASK_SHIFT 44
32895 +diff -urNp a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
32896 +--- a/include/asm-x86/page_64.h 2008-08-20 11:16:13.000000000 -0700
32897 ++++ b/include/asm-x86/page_64.h 2008-08-20 18:36:57.000000000 -0700
32898 +@@ -43,6 +43,9 @@
32899 + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
32900 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
32901 +
32902 ++#define ktla_ktva(addr) (addr)
32903 ++#define ktva_ktla(addr) (addr)
32904 ++
32905 + /* See Documentation/x86_64/mm.txt for a description of the memory map. */
32906 + #define __PHYSICAL_MASK_SHIFT 46
32907 + #define __VIRTUAL_MASK_SHIFT 48
32908 +@@ -87,5 +90,6 @@ typedef struct { pteval_t pte; } pte_t;
32909 + #define pfn_valid(pfn) ((pfn) < end_pfn)
32910 + #endif
32911 +
32912 ++#define nx_enabled (1)
32913 +
32914 + #endif /* _X86_64_PAGE_H */
32915 +diff -urNp a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
32916 +--- a/include/asm-x86/paravirt.h 2008-08-20 11:16:13.000000000 -0700
32917 ++++ b/include/asm-x86/paravirt.h 2008-08-20 18:36:57.000000000 -0700
32918 +@@ -1356,24 +1356,24 @@ static inline unsigned long __raw_local_
32919 +
32920 + #define INTERRUPT_RETURN \
32921 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
32922 +- jmp *%cs:pv_cpu_ops+PV_CPU_iret)
32923 ++ jmp *%ss:pv_cpu_ops+PV_CPU_iret)
32924 +
32925 + #define DISABLE_INTERRUPTS(clobbers) \
32926 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
32927 + PV_SAVE_REGS; \
32928 +- call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
32929 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
32930 + PV_RESTORE_REGS;) \
32931 +
32932 + #define ENABLE_INTERRUPTS(clobbers) \
32933 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
32934 + PV_SAVE_REGS; \
32935 +- call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
32936 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
32937 + PV_RESTORE_REGS;)
32938 +
32939 + #define ENABLE_INTERRUPTS_SYSCALL_RET \
32940 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
32941 + CLBR_NONE, \
32942 +- jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
32943 ++ jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
32944 +
32945 +
32946 + #ifdef CONFIG_X86_32
32947 +diff -urNp a/include/asm-x86/pda.h b/include/asm-x86/pda.h
32948 +--- a/include/asm-x86/pda.h 2008-08-20 11:16:13.000000000 -0700
32949 ++++ b/include/asm-x86/pda.h 2008-08-20 18:36:57.000000000 -0700
32950 +@@ -16,11 +16,9 @@ struct x8664_pda {
32951 + unsigned long oldrsp; /* 24 user rsp for system call */
32952 + int irqcount; /* 32 Irq nesting counter. Starts -1 */
32953 + unsigned int cpunumber; /* 36 Logical CPU number */
32954 +-#ifdef CONFIG_CC_STACKPROTECTOR
32955 + unsigned long stack_canary; /* 40 stack canary value */
32956 + /* gcc-ABI: this canary MUST be at
32957 + offset 40!!! */
32958 +-#endif
32959 + char *irqstackptr;
32960 + unsigned int nodenumber; /* number of current node */
32961 + unsigned int __softirq_pending;
32962 +diff -urNp a/include/asm-x86/percpu.h b/include/asm-x86/percpu.h
32963 +--- a/include/asm-x86/percpu.h 2008-08-20 11:16:13.000000000 -0700
32964 ++++ b/include/asm-x86/percpu.h 2008-08-20 18:36:57.000000000 -0700
32965 +@@ -67,6 +67,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
32966 +
32967 + #define __my_cpu_offset x86_read_percpu(this_cpu_off)
32968 +
32969 ++#include <asm-generic/sections.h>
32970 ++#include <linux/threads.h>
32971 ++#define __per_cpu_offset __per_cpu_offset
32972 ++extern unsigned long __per_cpu_offset[NR_CPUS];
32973 ++#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
32974 ++
32975 + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
32976 + #define __percpu_seg "%%fs:"
32977 +
32978 +diff -urNp a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h
32979 +--- a/include/asm-x86/pgalloc_32.h 2008-08-20 11:16:13.000000000 -0700
32980 ++++ b/include/asm-x86/pgalloc_32.h 2008-08-20 18:36:57.000000000 -0700
32981 +@@ -21,7 +21,11 @@ static inline void pmd_populate_kernel(s
32982 + pmd_t *pmd, pte_t *pte)
32983 + {
32984 + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);
32985 ++#ifdef CONFIG_COMPAT_VDSO
32986 + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
32987 ++#else
32988 ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
32989 ++#endif
32990 + }
32991 +
32992 + static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
32993 +diff -urNp a/include/asm-x86/pgalloc_64.h b/include/asm-x86/pgalloc_64.h
32994 +--- a/include/asm-x86/pgalloc_64.h 2008-08-20 11:16:13.000000000 -0700
32995 ++++ b/include/asm-x86/pgalloc_64.h 2008-08-20 18:36:57.000000000 -0700
32996 +@@ -6,7 +6,7 @@
32997 + #include <linux/mm.h>
32998 +
32999 + #define pmd_populate_kernel(mm, pmd, pte) \
33000 +- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
33001 ++ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
33002 + #define pud_populate(mm, pud, pmd) \
33003 + set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
33004 + #define pgd_populate(mm, pgd, pud) \
33005 +diff -urNp a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h
33006 +--- a/include/asm-x86/pgtable-2level.h 2008-08-20 11:16:13.000000000 -0700
33007 ++++ b/include/asm-x86/pgtable-2level.h 2008-08-20 18:36:57.000000000 -0700
33008 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
33009 +
33010 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
33011 + {
33012 ++
33013 ++#ifdef CONFIG_PAX_KERNEXEC
33014 ++ unsigned long cr0;
33015 ++
33016 ++ pax_open_kernel(cr0);
33017 ++#endif
33018 ++
33019 + *pmdp = pmd;
33020 ++
33021 ++#ifdef CONFIG_PAX_KERNEXEC
33022 ++ pax_close_kernel(cr0);
33023 ++#endif
33024 ++
33025 + }
33026 +
33027 + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
33028 +diff -urNp a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
33029 +--- a/include/asm-x86/pgtable-3level.h 2008-08-20 11:16:13.000000000 -0700
33030 ++++ b/include/asm-x86/pgtable-3level.h 2008-08-20 18:36:57.000000000 -0700
33031 +@@ -64,11 +64,35 @@ static inline void native_set_pte_atomic
33032 + }
33033 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
33034 + {
33035 ++
33036 ++#ifdef CONFIG_PAX_KERNEXEC
33037 ++ unsigned long cr0;
33038 ++
33039 ++ pax_open_kernel(cr0);
33040 ++#endif
33041 ++
33042 + set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
33043 ++
33044 ++#ifdef CONFIG_PAX_KERNEXEC
33045 ++ pax_close_kernel(cr0);
33046 ++#endif
33047 ++
33048 + }
33049 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
33050 + {
33051 ++
33052 ++#ifdef CONFIG_PAX_KERNEXEC
33053 ++ unsigned long cr0;
33054 ++
33055 ++ pax_open_kernel(cr0);
33056 ++#endif
33057 ++
33058 + set_64bit((unsigned long long *)(pudp),native_pud_val(pud));
33059 ++
33060 ++#ifdef CONFIG_PAX_KERNEXEC
33061 ++ pax_close_kernel(cr0);
33062 ++#endif
33063 ++
33064 + }
33065 +
33066 + /*
33067 +diff -urNp a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
33068 +--- a/include/asm-x86/pgtable.h 2008-08-20 11:16:13.000000000 -0700
33069 ++++ b/include/asm-x86/pgtable.h 2008-08-20 18:36:57.000000000 -0700
33070 +@@ -67,6 +67,9 @@
33071 + #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
33072 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
33073 +
33074 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
33075 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
33076 ++
33077 + #ifdef CONFIG_X86_32
33078 + #define _PAGE_KERNEL_EXEC \
33079 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
33080 +@@ -87,7 +90,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
33081 + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
33082 + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
33083 + #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
33084 +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
33085 ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
33086 + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
33087 + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
33088 +
33089 +@@ -140,10 +143,13 @@ extern unsigned long empty_zero_page[PAG
33090 + extern spinlock_t pgd_lock;
33091 + extern struct list_head pgd_list;
33092 +
33093 ++extern pteval_t __supported_pte_mask;
33094 ++
33095 + /*
33096 + * The following only work if pte_present() is true.
33097 + * Undefined behaviour if not..
33098 + */
33099 ++static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
33100 + static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
33101 + static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
33102 + static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
33103 +@@ -157,10 +163,31 @@ static inline int pmd_large(pmd_t pte) {
33104 + (_PAGE_PSE|_PAGE_PRESENT);
33105 + }
33106 +
33107 ++static inline pte_t pte_exprotect(pte_t pte)
33108 ++{
33109 ++#ifdef CONFIG_X86_PAE
33110 ++ if (__supported_pte_mask & _PAGE_NX)
33111 ++ return __pte(pte_val(pte) | _PAGE_NX);
33112 ++ else
33113 ++#endif
33114 ++ return __pte(pte_val(pte) & ~_PAGE_USER);
33115 ++}
33116 ++
33117 + static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); }
33118 + static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); }
33119 + static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); }
33120 +-static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); }
33121 ++static inline pte_t pte_mkread(pte_t pte) { return __pte(pte_val(pte) | _PAGE_USER); }
33122 ++
33123 ++static inline pte_t pte_mkexec(pte_t pte)
33124 ++{
33125 ++#ifdef CONFIG_X86_PAE
33126 ++ if (__supported_pte_mask & _PAGE_NX)
33127 ++ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
33128 ++ else
33129 ++#endif
33130 ++ return __pte(pte_val(pte) | _PAGE_USER);
33131 ++}
33132 ++
33133 + static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); }
33134 + static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); }
33135 + static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); }
33136 +@@ -169,8 +196,6 @@ static inline pte_t pte_clrhuge(pte_t pt
33137 + static inline pte_t pte_mkglobal(pte_t pte) { return __pte(pte_val(pte) | _PAGE_GLOBAL); }
33138 + static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); }
33139 +
33140 +-extern pteval_t __supported_pte_mask;
33141 +-
33142 + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
33143 + {
33144 + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
33145 +diff -urNp a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
33146 +--- a/include/asm-x86/pgtable_32.h 2008-08-20 11:16:13.000000000 -0700
33147 ++++ b/include/asm-x86/pgtable_32.h 2008-08-20 18:36:57.000000000 -0700
33148 +@@ -25,8 +25,6 @@
33149 + struct mm_struct;
33150 + struct vm_area_struct;
33151 +
33152 +-extern pgd_t swapper_pg_dir[1024];
33153 +-
33154 + static inline void pgtable_cache_init(void) { }
33155 + static inline void check_pgt_cache(void) { }
33156 + void paging_init(void);
33157 +@@ -45,6 +43,11 @@ void paging_init(void);
33158 + # include <asm/pgtable-2level-defs.h>
33159 + #endif
33160 +
33161 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
33162 ++#ifdef CONFIG_X86_PAE
33163 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
33164 ++#endif
33165 ++
33166 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
33167 + #define PGDIR_MASK (~(PGDIR_SIZE-1))
33168 +
33169 +@@ -83,7 +86,7 @@ void paging_init(void);
33170 + #undef TEST_ACCESS_OK
33171 +
33172 + /* The boot page tables (all created as a single array) */
33173 +-extern unsigned long pg0[];
33174 ++extern pte_t pg0[];
33175 +
33176 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
33177 +
33178 +@@ -113,7 +116,19 @@ extern unsigned long pg0[];
33179 + */
33180 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
33181 + {
33182 +- memcpy(dst, src, count * sizeof(pgd_t));
33183 ++
33184 ++#ifdef CONFIG_PAX_KERNEXEC
33185 ++ unsigned long cr0;
33186 ++
33187 ++ pax_open_kernel(cr0);
33188 ++#endif
33189 ++
33190 ++ memcpy(dst, src, count * sizeof(pgd_t));
33191 ++
33192 ++#ifdef CONFIG_PAX_KERNEXEC
33193 ++ pax_close_kernel(cr0);
33194 ++#endif
33195 ++
33196 + }
33197 +
33198 + /*
33199 +@@ -223,6 +238,9 @@ static inline void paravirt_pagetable_se
33200 +
33201 + #endif /* !__ASSEMBLY__ */
33202 +
33203 ++#define HAVE_ARCH_UNMAPPED_AREA
33204 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
33205 ++
33206 + /*
33207 + * kern_addr_valid() is (1) for FLATMEM and (0) for
33208 + * SPARSEMEM and DISCONTIGMEM
33209 +diff -urNp a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
33210 +--- a/include/asm-x86/pgtable_64.h 2008-08-20 11:16:13.000000000 -0700
33211 ++++ b/include/asm-x86/pgtable_64.h 2008-08-20 18:36:57.000000000 -0700
33212 +@@ -96,7 +96,19 @@ static inline pte_t native_ptep_get_and_
33213 +
33214 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
33215 + {
33216 ++
33217 ++#ifdef CONFIG_PAX_KERNEXEC
33218 ++ unsigned long cr0;
33219 ++
33220 ++ pax_open_kernel(cr0);
33221 ++#endif
33222 ++
33223 + *pmdp = pmd;
33224 ++
33225 ++#ifdef CONFIG_PAX_KERNEXEC
33226 ++ pax_close_kernel(cr0);
33227 ++#endif
33228 ++
33229 + }
33230 +
33231 + static inline void native_pmd_clear(pmd_t *pmd)
33232 +@@ -148,17 +160,17 @@ static inline void native_pgd_clear(pgd_
33233 +
33234 + static inline unsigned long pgd_bad(pgd_t pgd)
33235 + {
33236 +- return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
33237 ++ return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
33238 + }
33239 +
33240 + static inline unsigned long pud_bad(pud_t pud)
33241 + {
33242 +- return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
33243 ++ return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
33244 + }
33245 +
33246 + static inline unsigned long pmd_bad(pmd_t pmd)
33247 + {
33248 +- return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
33249 ++ return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
33250 + }
33251 +
33252 + #define pte_none(x) (!pte_val(x))
33253 +diff -urNp a/include/asm-x86/processor.h b/include/asm-x86/processor.h
33254 +--- a/include/asm-x86/processor.h 2008-08-20 11:16:13.000000000 -0700
33255 ++++ b/include/asm-x86/processor.h 2008-08-20 18:36:57.000000000 -0700
33256 +@@ -236,7 +236,7 @@ struct tss_struct {
33257 + unsigned long stack[64];
33258 + } __attribute__((packed));
33259 +
33260 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
33261 ++extern struct tss_struct init_tss[NR_CPUS];
33262 +
33263 + /* Save the original ist values for checking stack pointers during debugging */
33264 + struct orig_ist {
33265 +@@ -714,11 +714,20 @@ static inline void prefetchw(const void
33266 + * User space process size: 3GB (default).
33267 + */
33268 + #define TASK_SIZE (PAGE_OFFSET)
33269 ++
33270 ++#ifdef CONFIG_PAX_SEGMEXEC
33271 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
33272 ++#endif
33273 ++
33274 ++#ifdef CONFIG_PAX_SEGMEXEC
33275 ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
33276 ++#else
33277 + #define STACK_TOP TASK_SIZE
33278 +-#define STACK_TOP_MAX STACK_TOP
33279 ++#endif
33280 ++#define STACK_TOP_MAX TASK_SIZE
33281 +
33282 + #define INIT_THREAD { \
33283 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
33284 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
33285 + .vm86_info = NULL, \
33286 + .sysenter_cs = __KERNEL_CS, \
33287 + .io_bitmap_ptr = NULL, \
33288 +@@ -733,7 +742,7 @@ static inline void prefetchw(const void
33289 + */
33290 + #define INIT_TSS { \
33291 + .x86_tss = { \
33292 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
33293 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
33294 + .ss0 = __KERNEL_DS, \
33295 + .ss1 = __KERNEL_CS, \
33296 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
33297 +@@ -757,11 +766,7 @@ static inline void prefetchw(const void
33298 + extern unsigned long thread_saved_pc(struct task_struct *tsk);
33299 +
33300 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
33301 +-#define KSTK_TOP(info) \
33302 +-({ \
33303 +- unsigned long *__ptr = (unsigned long *)(info); \
33304 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
33305 +-})
33306 ++#define KSTK_TOP(info) ((info)->task.thread.sp0)
33307 +
33308 + /*
33309 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
33310 +@@ -776,7 +781,7 @@ extern unsigned long thread_saved_pc(str
33311 + #define task_pt_regs(task) \
33312 + ({ \
33313 + struct pt_regs *__regs__; \
33314 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
33315 ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
33316 + __regs__ - 1; \
33317 + })
33318 +
33319 +@@ -792,7 +797,7 @@ extern unsigned long thread_saved_pc(str
33320 + * space during mmap's.
33321 + */
33322 + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
33323 +- 0xc0000000 : 0xFFFFe000)
33324 ++ 0xc0000000 : 0xFFFFf000)
33325 +
33326 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
33327 + IA32_PAGE_OFFSET : TASK_SIZE64)
33328 +@@ -837,6 +842,10 @@ extern unsigned long thread_saved_pc(str
33329 + */
33330 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
33331 +
33332 ++#ifdef CONFIG_PAX_SEGMEXEC
33333 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
33334 ++#endif
33335 ++
33336 + #define KSTK_EIP(task) (task_pt_regs(task)->ip)
33337 +
33338 + #endif
33339 +diff -urNp a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
33340 +--- a/include/asm-x86/ptrace.h 2008-08-20 11:16:13.000000000 -0700
33341 ++++ b/include/asm-x86/ptrace.h 2008-08-20 18:36:57.000000000 -0700
33342 +@@ -56,7 +56,6 @@ struct pt_regs {
33343 + };
33344 +
33345 + #include <asm/vm86.h>
33346 +-#include <asm/segment.h>
33347 +
33348 + #endif /* __KERNEL__ */
33349 +
33350 +@@ -129,6 +128,7 @@ struct pt_regs {
33351 +
33352 + /* the DS BTS struct is used for ptrace as well */
33353 + #include <asm/ds.h>
33354 ++#include <asm/segment.h>
33355 +
33356 + struct task_struct;
33357 +
33358 +@@ -148,28 +148,29 @@ void signal_fault(struct pt_regs *regs,
33359 + #define regs_return_value(regs) ((regs)->ax)
33360 +
33361 + /*
33362 +- * user_mode_vm(regs) determines whether a register set came from user mode.
33363 ++ * user_mode(regs) determines whether a register set came from user mode.
33364 + * This is true if V8086 mode was enabled OR if the register set was from
33365 + * protected mode with RPL-3 CS value. This tricky test checks that with
33366 + * one comparison. Many places in the kernel can bypass this full check
33367 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
33368 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
33369 ++ * be used.
33370 + */
33371 +-static inline int user_mode(struct pt_regs *regs)
33372 ++static inline int user_mode_novm(struct pt_regs *regs)
33373 + {
33374 + #ifdef CONFIG_X86_32
33375 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
33376 + #else
33377 +- return !!(regs->cs & 3);
33378 ++ return !!(regs->cs & SEGMENT_RPL_MASK);
33379 + #endif
33380 + }
33381 +
33382 +-static inline int user_mode_vm(struct pt_regs *regs)
33383 ++static inline int user_mode(struct pt_regs *regs)
33384 + {
33385 + #ifdef CONFIG_X86_32
33386 + return ((regs->cs & SEGMENT_RPL_MASK) |
33387 + (regs->flags & VM_MASK)) >= USER_RPL;
33388 + #else
33389 +- return user_mode(regs);
33390 ++ return user_mode_novm(regs);
33391 + #endif
33392 + }
33393 +
33394 +diff -urNp a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h
33395 +--- a/include/asm-x86/reboot.h 2008-08-20 11:16:13.000000000 -0700
33396 ++++ b/include/asm-x86/reboot.h 2008-08-20 18:36:57.000000000 -0700
33397 +@@ -15,6 +15,6 @@ struct machine_ops
33398 +
33399 + extern struct machine_ops machine_ops;
33400 +
33401 +-void machine_real_restart(unsigned char *code, int length);
33402 ++void machine_real_restart(const unsigned char *code, unsigned int length);
33403 +
33404 + #endif /* _ASM_REBOOT_H */
33405 +diff -urNp a/include/asm-x86/segment.h b/include/asm-x86/segment.h
33406 +--- a/include/asm-x86/segment.h 2008-08-20 11:16:13.000000000 -0700
33407 ++++ b/include/asm-x86/segment.h 2008-08-20 18:36:57.000000000 -0700
33408 +@@ -83,13 +83,19 @@
33409 + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
33410 + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
33411 +
33412 +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
33413 ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
33414 + #ifdef CONFIG_SMP
33415 + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
33416 + #else
33417 + #define __KERNEL_PERCPU 0
33418 + #endif
33419 +
33420 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
33421 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
33422 ++
33423 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
33424 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
33425 ++
33426 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
33427 +
33428 + /*
33429 +@@ -130,10 +136,10 @@
33430 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
33431 +
33432 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
33433 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
33434 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
33435 +
33436 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
33437 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
33438 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
33439 +
33440 +
33441 + #else
33442 +diff -urNp a/include/asm-x86/system.h b/include/asm-x86/system.h
33443 +--- a/include/asm-x86/system.h 2008-08-20 11:16:13.000000000 -0700
33444 ++++ b/include/asm-x86/system.h 2008-08-20 18:36:57.000000000 -0700
33445 +@@ -70,6 +70,8 @@ struct task_struct *__switch_to(struct t
33446 + ".globl thread_return\n" \
33447 + "thread_return:\n\t" \
33448 + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
33449 ++ "movq %P[task_canary](%%rsi),%%r8\n\t" \
33450 ++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
33451 + "movq %P[thread_info](%%rsi),%%r8\n\t" \
33452 + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
33453 + "movq %%rax,%%rdi\n\t" \
33454 +@@ -81,7 +83,9 @@ struct task_struct *__switch_to(struct t
33455 + [ti_flags] "i" (offsetof(struct thread_info, flags)), \
33456 + [tif_fork] "i" (TIF_FORK), \
33457 + [thread_info] "i" (offsetof(struct task_struct, stack)), \
33458 +- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
33459 ++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
33460 ++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
33461 ++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
33462 + : "memory", "cc" __EXTRA_CLOBBER)
33463 + #endif
33464 +
33465 +@@ -145,7 +149,7 @@ static inline unsigned long get_limit(un
33466 + unsigned long __limit;
33467 + __asm__("lsll %1,%0"
33468 + :"=r" (__limit):"r" (segment));
33469 +- return __limit+1;
33470 ++ return __limit;
33471 + }
33472 +
33473 + static inline void native_clts(void)
33474 +@@ -269,6 +273,21 @@ static inline void native_wbinvd(void)
33475 +
33476 + #define stts() write_cr0(8 | read_cr0())
33477 +
33478 ++#define pax_open_kernel(cr0) \
33479 ++do { \
33480 ++ typecheck(unsigned long, cr0); \
33481 ++ preempt_disable(); \
33482 ++ cr0 = read_cr0(); \
33483 ++ write_cr0(cr0 & ~X86_CR0_WP); \
33484 ++} while (0)
33485 ++
33486 ++#define pax_close_kernel(cr0) \
33487 ++do { \
33488 ++ typecheck(unsigned long, cr0); \
33489 ++ write_cr0(cr0); \
33490 ++ preempt_enable_no_resched(); \
33491 ++} while (0)
33492 ++
33493 + #endif /* __KERNEL__ */
33494 +
33495 + static inline void clflush(volatile void *__p)
33496 +@@ -284,7 +303,7 @@ void enable_hlt(void);
33497 + extern int es7000_plat;
33498 + void cpu_idle_wait(void);
33499 +
33500 +-extern unsigned long arch_align_stack(unsigned long sp);
33501 ++#define arch_align_stack(x) (x)
33502 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
33503 +
33504 + void default_idle(void);
33505 +diff -urNp a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h
33506 +--- a/include/asm-x86/uaccess_32.h 2008-08-20 11:16:13.000000000 -0700
33507 ++++ b/include/asm-x86/uaccess_32.h 2008-08-20 18:36:57.000000000 -0700
33508 +@@ -10,6 +10,7 @@
33509 + #include <linux/string.h>
33510 + #include <asm/asm.h>
33511 + #include <asm/page.h>
33512 ++#include <asm/segment.h>
33513 +
33514 + #define VERIFY_READ 0
33515 + #define VERIFY_WRITE 1
33516 +@@ -30,7 +31,8 @@
33517 +
33518 + #define get_ds() (KERNEL_DS)
33519 + #define get_fs() (current_thread_info()->addr_limit)
33520 +-#define set_fs(x) (current_thread_info()->addr_limit = (x))
33521 ++void __set_fs(mm_segment_t x, int cpu);
33522 ++void set_fs(mm_segment_t x);
33523 +
33524 + #define segment_eq(a,b) ((a).seg == (b).seg)
33525 +
33526 +@@ -102,6 +104,7 @@ struct exception_table_entry
33527 + };
33528 +
33529 + extern int fixup_exception(struct pt_regs *regs);
33530 ++#define ARCH_HAS_SORT_EXTABLE
33531 +
33532 + /*
33533 + * These are the main single-value transfer routines. They automatically
33534 +@@ -281,9 +284,12 @@ extern void __put_user_8(void);
33535 +
33536 + #define __put_user_u64(x, addr, err) \
33537 + __asm__ __volatile__( \
33538 +- "1: movl %%eax,0(%2)\n" \
33539 +- "2: movl %%edx,4(%2)\n" \
33540 ++ " movw %w5,%%ds\n" \
33541 ++ "1: movl %%eax,%%ds:0(%2)\n" \
33542 ++ "2: movl %%edx,%%ds:4(%2)\n" \
33543 + "3:\n" \
33544 ++ " pushl %%ss\n" \
33545 ++ " popl %%ds\n" \
33546 + ".section .fixup,\"ax\"\n" \
33547 + "4: movl %3,%0\n" \
33548 + " jmp 3b\n" \
33549 +@@ -291,7 +297,8 @@ extern void __put_user_8(void);
33550 + _ASM_EXTABLE(1b,4b) \
33551 + _ASM_EXTABLE(2b,4b) \
33552 + : "=r"(err) \
33553 +- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
33554 ++ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
33555 ++ "r"(__USER_DS))
33556 +
33557 + #ifdef CONFIG_X86_WP_WORKS_OK
33558 +
33559 +@@ -330,15 +337,19 @@ struct __large_struct { unsigned long bu
33560 + */
33561 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
33562 + __asm__ __volatile__( \
33563 +- "1: mov"itype" %"rtype"1,%2\n" \
33564 ++ " movw %w5,%%ds\n" \
33565 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
33566 + "2:\n" \
33567 ++ " pushl %%ss\n" \
33568 ++ " popl %%ds\n" \
33569 + ".section .fixup,\"ax\"\n" \
33570 + "3: movl %3,%0\n" \
33571 + " jmp 2b\n" \
33572 + ".previous\n" \
33573 + _ASM_EXTABLE(1b,3b) \
33574 + : "=r"(err) \
33575 +- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
33576 ++ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
33577 ++ "r"(__USER_DS))
33578 +
33579 +
33580 + #define __get_user_nocheck(x,ptr,size) \
33581 +@@ -366,8 +377,11 @@ do { \
33582 +
33583 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
33584 + __asm__ __volatile__( \
33585 +- "1: mov"itype" %2,%"rtype"1\n" \
33586 ++ " movw %w5,%%ds\n" \
33587 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
33588 + "2:\n" \
33589 ++ " pushl %%ss\n" \
33590 ++ " popl %%ds\n" \
33591 + ".section .fixup,\"ax\"\n" \
33592 + "3: movl %3,%0\n" \
33593 + " xor"itype" %"rtype"1,%"rtype"1\n" \
33594 +@@ -375,7 +389,7 @@ do { \
33595 + ".previous\n" \
33596 + _ASM_EXTABLE(1b,3b) \
33597 + : "=r"(err), ltype (x) \
33598 +- : "m"(__m(addr)), "i"(errret), "0"(err))
33599 ++ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
33600 +
33601 +
33602 + unsigned long __must_check __copy_to_user_ll(void __user *to,
33603 +diff -urNp a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h
33604 +--- a/include/asm-x86/uaccess_64.h 2008-08-20 11:16:13.000000000 -0700
33605 ++++ b/include/asm-x86/uaccess_64.h 2008-08-20 18:36:57.000000000 -0700
33606 +@@ -68,6 +68,7 @@ struct exception_table_entry
33607 + extern int fixup_exception(struct pt_regs *regs);
33608 +
33609 + #define ARCH_HAS_SEARCH_EXTABLE
33610 ++#define ARCH_HAS_SORT_EXTABLE
33611 +
33612 + /*
33613 + * These are the main single-value transfer routines. They automatically
33614 +diff -urNp a/include/asm-xtensa/kmap_types.h b/include/asm-xtensa/kmap_types.h
33615 +--- a/include/asm-xtensa/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
33616 ++++ b/include/asm-xtensa/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
33617 +@@ -25,6 +25,7 @@ enum km_type {
33618 + KM_IRQ1,
33619 + KM_SOFTIRQ0,
33620 + KM_SOFTIRQ1,
33621 ++ KM_CLEARPAGE,
33622 + KM_TYPE_NR
33623 + };
33624 +
33625 +diff -urNp a/include/linux/a.out.h b/include/linux/a.out.h
33626 +--- a/include/linux/a.out.h 2008-08-20 11:16:13.000000000 -0700
33627 ++++ b/include/linux/a.out.h 2008-08-20 18:36:57.000000000 -0700
33628 +@@ -41,6 +41,14 @@ enum machine_type {
33629 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
33630 + };
33631 +
33632 ++/* Constants for the N_FLAGS field */
33633 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
33634 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
33635 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
33636 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
33637 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
33638 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
33639 ++
33640 + #if !defined (N_MAGIC)
33641 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
33642 + #endif
33643 +diff -urNp a/include/linux/binfmts.h b/include/linux/binfmts.h
33644 +--- a/include/linux/binfmts.h 2008-08-20 11:16:13.000000000 -0700
33645 ++++ b/include/linux/binfmts.h 2008-08-20 18:36:57.000000000 -0700
33646 +@@ -49,6 +49,7 @@ struct linux_binprm{
33647 + unsigned interp_data;
33648 + unsigned long loader, exec;
33649 + unsigned long argv_len;
33650 ++ int misc;
33651 + };
33652 +
33653 + #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
33654 +@@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b
33655 + extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
33656 + extern int set_binfmt(struct linux_binfmt *new);
33657 +
33658 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
33659 ++void pax_report_insns(void *pc, void *sp);
33660 ++
33661 + #endif /* __KERNEL__ */
33662 + #endif /* _LINUX_BINFMTS_H */
33663 +diff -urNp a/include/linux/cache.h b/include/linux/cache.h
33664 +--- a/include/linux/cache.h 2008-08-20 11:16:13.000000000 -0700
33665 ++++ b/include/linux/cache.h 2008-08-20 18:36:57.000000000 -0700
33666 +@@ -16,6 +16,10 @@
33667 + #define __read_mostly
33668 + #endif
33669 +
33670 ++#ifndef __read_only
33671 ++#define __read_only __read_mostly
33672 ++#endif
33673 ++
33674 + #ifndef ____cacheline_aligned
33675 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
33676 + #endif
33677 +diff -urNp a/include/linux/capability.h b/include/linux/capability.h
33678 +--- a/include/linux/capability.h 2008-08-20 11:16:13.000000000 -0700
33679 ++++ b/include/linux/capability.h 2008-08-20 18:36:57.000000000 -0700
33680 +@@ -501,6 +501,7 @@ extern const kernel_cap_t __cap_full_set
33681 + extern const kernel_cap_t __cap_init_eff_set;
33682 +
33683 + int capable(int cap);
33684 ++int capable_nolog(int cap);
33685 + int __capable(struct task_struct *t, int cap);
33686 +
33687 + extern long cap_prctl_drop(unsigned long cap);
33688 +diff -urNp a/include/linux/elf.h b/include/linux/elf.h
33689 +--- a/include/linux/elf.h 2008-08-20 11:16:13.000000000 -0700
33690 ++++ b/include/linux/elf.h 2008-08-20 18:36:57.000000000 -0700
33691 +@@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
33692 +
33693 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
33694 +
33695 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
33696 ++
33697 ++/* Constants for the e_flags field */
33698 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
33699 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
33700 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
33701 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
33702 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
33703 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
33704 ++
33705 + /* These constants define the different elf file types */
33706 + #define ET_NONE 0
33707 + #define ET_REL 1
33708 +@@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
33709 + #define DT_DEBUG 21
33710 + #define DT_TEXTREL 22
33711 + #define DT_JMPREL 23
33712 ++#define DT_FLAGS 30
33713 ++ #define DF_TEXTREL 0x00000004
33714 + #define DT_ENCODING 32
33715 + #define OLD_DT_LOOS 0x60000000
33716 + #define DT_LOOS 0x6000000d
33717 +@@ -230,6 +242,19 @@ typedef struct elf64_hdr {
33718 + #define PF_W 0x2
33719 + #define PF_X 0x1
33720 +
33721 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
33722 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
33723 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
33724 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
33725 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
33726 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
33727 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
33728 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
33729 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
33730 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
33731 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
33732 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
33733 ++
33734 + typedef struct elf32_phdr{
33735 + Elf32_Word p_type;
33736 + Elf32_Off p_offset;
33737 +@@ -322,6 +347,8 @@ typedef struct elf64_shdr {
33738 + #define EI_OSABI 7
33739 + #define EI_PAD 8
33740 +
33741 ++#define EI_PAX 14
33742 ++
33743 + #define ELFMAG0 0x7f /* EI_MAG */
33744 + #define ELFMAG1 'E'
33745 + #define ELFMAG2 'L'
33746 +@@ -382,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
33747 + #define elf_phdr elf32_phdr
33748 + #define elf_note elf32_note
33749 + #define elf_addr_t Elf32_Off
33750 ++#define elf_dyn Elf32_Dyn
33751 +
33752 + #else
33753 +
33754 +@@ -390,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
33755 + #define elf_phdr elf64_phdr
33756 + #define elf_note elf64_note
33757 + #define elf_addr_t Elf64_Off
33758 ++#define elf_dyn Elf64_Dyn
33759 +
33760 + #endif
33761 +
33762 +diff -urNp a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
33763 +--- a/include/linux/ext4_fs_extents.h 2008-08-20 11:16:13.000000000 -0700
33764 ++++ b/include/linux/ext4_fs_extents.h 2008-08-20 18:36:57.000000000 -0700
33765 +@@ -50,7 +50,7 @@
33766 + #ifdef EXT_DEBUG
33767 + #define ext_debug(a...) printk(a)
33768 + #else
33769 +-#define ext_debug(a...)
33770 ++#define ext_debug(a...) do {} while (0)
33771 + #endif
33772 +
33773 + /*
33774 +diff -urNp a/include/linux/gracl.h b/include/linux/gracl.h
33775 +--- a/include/linux/gracl.h 1969-12-31 16:00:00.000000000 -0800
33776 ++++ b/include/linux/gracl.h 2008-08-20 18:36:57.000000000 -0700
33777 +@@ -0,0 +1,318 @@
33778 ++#ifndef GR_ACL_H
33779 ++#define GR_ACL_H
33780 ++
33781 ++#include <linux/grdefs.h>
33782 ++#include <linux/resource.h>
33783 ++#include <linux/capability.h>
33784 ++#include <linux/dcache.h>
33785 ++#include <asm/resource.h>
33786 ++
33787 ++/* Major status information */
33788 ++
33789 ++#define GR_VERSION "grsecurity 2.1.12"
33790 ++#define GRSECURITY_VERSION 0x2112
33791 ++
33792 ++enum {
33793 ++
33794 ++ SHUTDOWN = 0,
33795 ++ ENABLE = 1,
33796 ++ SPROLE = 2,
33797 ++ RELOAD = 3,
33798 ++ SEGVMOD = 4,
33799 ++ STATUS = 5,
33800 ++ UNSPROLE = 6,
33801 ++ PASSSET = 7,
33802 ++ SPROLEPAM = 8
33803 ++};
33804 ++
33805 ++/* Password setup definitions
33806 ++ * kernel/grhash.c */
33807 ++enum {
33808 ++ GR_PW_LEN = 128,
33809 ++ GR_SALT_LEN = 16,
33810 ++ GR_SHA_LEN = 32,
33811 ++};
33812 ++
33813 ++enum {
33814 ++ GR_SPROLE_LEN = 64,
33815 ++};
33816 ++
33817 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
33818 ++
33819 ++/* Begin Data Structures */
33820 ++
33821 ++struct sprole_pw {
33822 ++ unsigned char *rolename;
33823 ++ unsigned char salt[GR_SALT_LEN];
33824 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
33825 ++};
33826 ++
33827 ++struct name_entry {
33828 ++ __u32 key;
33829 ++ ino_t inode;
33830 ++ dev_t device;
33831 ++ char *name;
33832 ++ __u16 len;
33833 ++ __u8 deleted;
33834 ++ struct name_entry *prev;
33835 ++ struct name_entry *next;
33836 ++};
33837 ++
33838 ++struct inodev_entry {
33839 ++ struct name_entry *nentry;
33840 ++ struct inodev_entry *prev;
33841 ++ struct inodev_entry *next;
33842 ++};
33843 ++
33844 ++struct acl_role_db {
33845 ++ struct acl_role_label **r_hash;
33846 ++ __u32 r_size;
33847 ++};
33848 ++
33849 ++struct inodev_db {
33850 ++ struct inodev_entry **i_hash;
33851 ++ __u32 i_size;
33852 ++};
33853 ++
33854 ++struct name_db {
33855 ++ struct name_entry **n_hash;
33856 ++ __u32 n_size;
33857 ++};
33858 ++
33859 ++struct crash_uid {
33860 ++ uid_t uid;
33861 ++ unsigned long expires;
33862 ++};
33863 ++
33864 ++struct gr_hash_struct {
33865 ++ void **table;
33866 ++ void **nametable;
33867 ++ void *first;
33868 ++ __u32 table_size;
33869 ++ __u32 used_size;
33870 ++ int type;
33871 ++};
33872 ++
33873 ++/* Userspace Grsecurity ACL data structures */
33874 ++
33875 ++struct acl_subject_label {
33876 ++ char *filename;
33877 ++ ino_t inode;
33878 ++ dev_t device;
33879 ++ __u32 mode;
33880 ++ kernel_cap_t cap_mask;
33881 ++ kernel_cap_t cap_lower;
33882 ++
33883 ++ struct rlimit res[GR_NLIMITS];
33884 ++ __u16 resmask;
33885 ++
33886 ++ __u8 user_trans_type;
33887 ++ __u8 group_trans_type;
33888 ++ uid_t *user_transitions;
33889 ++ gid_t *group_transitions;
33890 ++ __u16 user_trans_num;
33891 ++ __u16 group_trans_num;
33892 ++
33893 ++ __u32 ip_proto[8];
33894 ++ __u32 ip_type;
33895 ++ struct acl_ip_label **ips;
33896 ++ __u32 ip_num;
33897 ++
33898 ++ __u32 crashes;
33899 ++ unsigned long expires;
33900 ++
33901 ++ struct acl_subject_label *parent_subject;
33902 ++ struct gr_hash_struct *hash;
33903 ++ struct acl_subject_label *prev;
33904 ++ struct acl_subject_label *next;
33905 ++
33906 ++ struct acl_object_label **obj_hash;
33907 ++ __u32 obj_hash_size;
33908 ++ __u16 pax_flags;
33909 ++};
33910 ++
33911 ++struct role_allowed_ip {
33912 ++ __u32 addr;
33913 ++ __u32 netmask;
33914 ++
33915 ++ struct role_allowed_ip *prev;
33916 ++ struct role_allowed_ip *next;
33917 ++};
33918 ++
33919 ++struct role_transition {
33920 ++ char *rolename;
33921 ++
33922 ++ struct role_transition *prev;
33923 ++ struct role_transition *next;
33924 ++};
33925 ++
33926 ++struct acl_role_label {
33927 ++ char *rolename;
33928 ++ uid_t uidgid;
33929 ++ __u16 roletype;
33930 ++
33931 ++ __u16 auth_attempts;
33932 ++ unsigned long expires;
33933 ++
33934 ++ struct acl_subject_label *root_label;
33935 ++ struct gr_hash_struct *hash;
33936 ++
33937 ++ struct acl_role_label *prev;
33938 ++ struct acl_role_label *next;
33939 ++
33940 ++ struct role_transition *transitions;
33941 ++ struct role_allowed_ip *allowed_ips;
33942 ++ uid_t *domain_children;
33943 ++ __u16 domain_child_num;
33944 ++
33945 ++ struct acl_subject_label **subj_hash;
33946 ++ __u32 subj_hash_size;
33947 ++};
33948 ++
33949 ++struct user_acl_role_db {
33950 ++ struct acl_role_label **r_table;
33951 ++ __u32 num_pointers; /* Number of allocations to track */
33952 ++ __u32 num_roles; /* Number of roles */
33953 ++ __u32 num_domain_children; /* Number of domain children */
33954 ++ __u32 num_subjects; /* Number of subjects */
33955 ++ __u32 num_objects; /* Number of objects */
33956 ++};
33957 ++
33958 ++struct acl_object_label {
33959 ++ char *filename;
33960 ++ ino_t inode;
33961 ++ dev_t device;
33962 ++ __u32 mode;
33963 ++
33964 ++ struct acl_subject_label *nested;
33965 ++ struct acl_object_label *globbed;
33966 ++
33967 ++ /* next two structures not used */
33968 ++
33969 ++ struct acl_object_label *prev;
33970 ++ struct acl_object_label *next;
33971 ++};
33972 ++
33973 ++struct acl_ip_label {
33974 ++ char *iface;
33975 ++ __u32 addr;
33976 ++ __u32 netmask;
33977 ++ __u16 low, high;
33978 ++ __u8 mode;
33979 ++ __u32 type;
33980 ++ __u32 proto[8];
33981 ++
33982 ++ /* next two structures not used */
33983 ++
33984 ++ struct acl_ip_label *prev;
33985 ++ struct acl_ip_label *next;
33986 ++};
33987 ++
33988 ++struct gr_arg {
33989 ++ struct user_acl_role_db role_db;
33990 ++ unsigned char pw[GR_PW_LEN];
33991 ++ unsigned char salt[GR_SALT_LEN];
33992 ++ unsigned char sum[GR_SHA_LEN];
33993 ++ unsigned char sp_role[GR_SPROLE_LEN];
33994 ++ struct sprole_pw *sprole_pws;
33995 ++ dev_t segv_device;
33996 ++ ino_t segv_inode;
33997 ++ uid_t segv_uid;
33998 ++ __u16 num_sprole_pws;
33999 ++ __u16 mode;
34000 ++};
34001 ++
34002 ++struct gr_arg_wrapper {
34003 ++ struct gr_arg *arg;
34004 ++ __u32 version;
34005 ++ __u32 size;
34006 ++};
34007 ++
34008 ++struct subject_map {
34009 ++ struct acl_subject_label *user;
34010 ++ struct acl_subject_label *kernel;
34011 ++ struct subject_map *prev;
34012 ++ struct subject_map *next;
34013 ++};
34014 ++
34015 ++struct acl_subj_map_db {
34016 ++ struct subject_map **s_hash;
34017 ++ __u32 s_size;
34018 ++};
34019 ++
34020 ++/* End Data Structures Section */
34021 ++
34022 ++/* Hash functions generated by empirical testing by Brad Spengler
34023 ++ Makes good use of the low bits of the inode. Generally 0-1 times
34024 ++ in loop for successful match. 0-3 for unsuccessful match.
34025 ++ Shift/add algorithm with modulus of table size and an XOR*/
34026 ++
34027 ++static __inline__ unsigned int
34028 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
34029 ++{
34030 ++ return (((uid << type) + (uid ^ type)) % sz);
34031 ++}
34032 ++
34033 ++ static __inline__ unsigned int
34034 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
34035 ++{
34036 ++ return ((const unsigned long)userp % sz);
34037 ++}
34038 ++
34039 ++static __inline__ unsigned int
34040 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
34041 ++{
34042 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
34043 ++}
34044 ++
34045 ++static __inline__ unsigned int
34046 ++nhash(const char *name, const __u16 len, const unsigned int sz)
34047 ++{
34048 ++ return full_name_hash(name, len) % sz;
34049 ++}
34050 ++
34051 ++#define FOR_EACH_ROLE_START(role,iter) \
34052 ++ role = NULL; \
34053 ++ iter = 0; \
34054 ++ while (iter < acl_role_set.r_size) { \
34055 ++ if (role == NULL) \
34056 ++ role = acl_role_set.r_hash[iter]; \
34057 ++ if (role == NULL) { \
34058 ++ iter++; \
34059 ++ continue; \
34060 ++ }
34061 ++
34062 ++#define FOR_EACH_ROLE_END(role,iter) \
34063 ++ role = role->next; \
34064 ++ if (role == NULL) \
34065 ++ iter++; \
34066 ++ }
34067 ++
34068 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
34069 ++ subj = NULL; \
34070 ++ iter = 0; \
34071 ++ while (iter < role->subj_hash_size) { \
34072 ++ if (subj == NULL) \
34073 ++ subj = role->subj_hash[iter]; \
34074 ++ if (subj == NULL) { \
34075 ++ iter++; \
34076 ++ continue; \
34077 ++ }
34078 ++
34079 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
34080 ++ subj = subj->next; \
34081 ++ if (subj == NULL) \
34082 ++ iter++; \
34083 ++ }
34084 ++
34085 ++
34086 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
34087 ++ subj = role->hash->first; \
34088 ++ while (subj != NULL) {
34089 ++
34090 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
34091 ++ subj = subj->next; \
34092 ++ }
34093 ++
34094 ++#endif
34095 ++
34096 +diff -urNp a/include/linux/gralloc.h b/include/linux/gralloc.h
34097 +--- a/include/linux/gralloc.h 1969-12-31 16:00:00.000000000 -0800
34098 ++++ b/include/linux/gralloc.h 2008-08-20 18:36:57.000000000 -0700
34099 +@@ -0,0 +1,8 @@
34100 ++#ifndef __GRALLOC_H
34101 ++#define __GRALLOC_H
34102 ++
34103 ++void acl_free_all(void);
34104 ++int acl_alloc_stack_init(unsigned long size);
34105 ++void *acl_alloc(unsigned long len);
34106 ++
34107 ++#endif
34108 +diff -urNp a/include/linux/grdefs.h b/include/linux/grdefs.h
34109 +--- a/include/linux/grdefs.h 1969-12-31 16:00:00.000000000 -0800
34110 ++++ b/include/linux/grdefs.h 2008-08-20 18:36:57.000000000 -0700
34111 +@@ -0,0 +1,131 @@
34112 ++#ifndef GRDEFS_H
34113 ++#define GRDEFS_H
34114 ++
34115 ++/* Begin grsecurity status declarations */
34116 ++
34117 ++enum {
34118 ++ GR_READY = 0x01,
34119 ++ GR_STATUS_INIT = 0x00 // disabled state
34120 ++};
34121 ++
34122 ++/* Begin ACL declarations */
34123 ++
34124 ++/* Role flags */
34125 ++
34126 ++enum {
34127 ++ GR_ROLE_USER = 0x0001,
34128 ++ GR_ROLE_GROUP = 0x0002,
34129 ++ GR_ROLE_DEFAULT = 0x0004,
34130 ++ GR_ROLE_SPECIAL = 0x0008,
34131 ++ GR_ROLE_AUTH = 0x0010,
34132 ++ GR_ROLE_NOPW = 0x0020,
34133 ++ GR_ROLE_GOD = 0x0040,
34134 ++ GR_ROLE_LEARN = 0x0080,
34135 ++ GR_ROLE_TPE = 0x0100,
34136 ++ GR_ROLE_DOMAIN = 0x0200,
34137 ++ GR_ROLE_PAM = 0x0400
34138 ++};
34139 ++
34140 ++/* ACL Subject and Object mode flags */
34141 ++enum {
34142 ++ GR_DELETED = 0x80000000
34143 ++};
34144 ++
34145 ++/* ACL Object-only mode flags */
34146 ++enum {
34147 ++ GR_READ = 0x00000001,
34148 ++ GR_APPEND = 0x00000002,
34149 ++ GR_WRITE = 0x00000004,
34150 ++ GR_EXEC = 0x00000008,
34151 ++ GR_FIND = 0x00000010,
34152 ++ GR_INHERIT = 0x00000020,
34153 ++ GR_SETID = 0x00000040,
34154 ++ GR_CREATE = 0x00000080,
34155 ++ GR_DELETE = 0x00000100,
34156 ++ GR_LINK = 0x00000200,
34157 ++ GR_AUDIT_READ = 0x00000400,
34158 ++ GR_AUDIT_APPEND = 0x00000800,
34159 ++ GR_AUDIT_WRITE = 0x00001000,
34160 ++ GR_AUDIT_EXEC = 0x00002000,
34161 ++ GR_AUDIT_FIND = 0x00004000,
34162 ++ GR_AUDIT_INHERIT= 0x00008000,
34163 ++ GR_AUDIT_SETID = 0x00010000,
34164 ++ GR_AUDIT_CREATE = 0x00020000,
34165 ++ GR_AUDIT_DELETE = 0x00040000,
34166 ++ GR_AUDIT_LINK = 0x00080000,
34167 ++ GR_PTRACERD = 0x00100000,
34168 ++ GR_NOPTRACE = 0x00200000,
34169 ++ GR_SUPPRESS = 0x00400000,
34170 ++ GR_NOLEARN = 0x00800000
34171 ++};
34172 ++
34173 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
34174 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
34175 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
34176 ++
34177 ++/* ACL subject-only mode flags */
34178 ++enum {
34179 ++ GR_KILL = 0x00000001,
34180 ++ GR_VIEW = 0x00000002,
34181 ++ GR_PROTECTED = 0x00000004,
34182 ++ GR_LEARN = 0x00000008,
34183 ++ GR_OVERRIDE = 0x00000010,
34184 ++ /* just a placeholder, this mode is only used in userspace */
34185 ++ GR_DUMMY = 0x00000020,
34186 ++ GR_PROTSHM = 0x00000040,
34187 ++ GR_KILLPROC = 0x00000080,
34188 ++ GR_KILLIPPROC = 0x00000100,
34189 ++ /* just a placeholder, this mode is only used in userspace */
34190 ++ GR_NOTROJAN = 0x00000200,
34191 ++ GR_PROTPROCFD = 0x00000400,
34192 ++ GR_PROCACCT = 0x00000800,
34193 ++ GR_RELAXPTRACE = 0x00001000,
34194 ++ GR_NESTED = 0x00002000,
34195 ++ GR_INHERITLEARN = 0x00004000,
34196 ++ GR_PROCFIND = 0x00008000,
34197 ++ GR_POVERRIDE = 0x00010000,
34198 ++ GR_KERNELAUTH = 0x00020000,
34199 ++};
34200 ++
34201 ++enum {
34202 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
34203 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
34204 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
34205 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
34206 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
34207 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
34208 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
34209 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
34210 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
34211 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
34212 ++};
34213 ++
34214 ++enum {
34215 ++ GR_ID_USER = 0x01,
34216 ++ GR_ID_GROUP = 0x02,
34217 ++};
34218 ++
34219 ++enum {
34220 ++ GR_ID_ALLOW = 0x01,
34221 ++ GR_ID_DENY = 0x02,
34222 ++};
34223 ++
34224 ++#define GR_CRASH_RES 11
34225 ++#define GR_UIDTABLE_MAX 500
34226 ++
34227 ++/* begin resource learning section */
34228 ++enum {
34229 ++ GR_RLIM_CPU_BUMP = 60,
34230 ++ GR_RLIM_FSIZE_BUMP = 50000,
34231 ++ GR_RLIM_DATA_BUMP = 10000,
34232 ++ GR_RLIM_STACK_BUMP = 1000,
34233 ++ GR_RLIM_CORE_BUMP = 10000,
34234 ++ GR_RLIM_RSS_BUMP = 500000,
34235 ++ GR_RLIM_NPROC_BUMP = 1,
34236 ++ GR_RLIM_NOFILE_BUMP = 5,
34237 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
34238 ++ GR_RLIM_AS_BUMP = 500000,
34239 ++ GR_RLIM_LOCKS_BUMP = 2
34240 ++};
34241 ++
34242 ++#endif
34243 +diff -urNp a/include/linux/grinternal.h b/include/linux/grinternal.h
34244 +--- a/include/linux/grinternal.h 1969-12-31 16:00:00.000000000 -0800
34245 ++++ b/include/linux/grinternal.h 2008-08-20 18:36:57.000000000 -0700
34246 +@@ -0,0 +1,210 @@
34247 ++#ifndef __GRINTERNAL_H
34248 ++#define __GRINTERNAL_H
34249 ++
34250 ++#ifdef CONFIG_GRKERNSEC
34251 ++
34252 ++#include <linux/fs.h>
34253 ++#include <linux/gracl.h>
34254 ++#include <linux/grdefs.h>
34255 ++#include <linux/grmsg.h>
34256 ++
34257 ++void gr_add_learn_entry(const char *fmt, ...);
34258 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
34259 ++ const struct vfsmount *mnt);
34260 ++__u32 gr_check_create(const struct dentry *new_dentry,
34261 ++ const struct dentry *parent,
34262 ++ const struct vfsmount *mnt, const __u32 mode);
34263 ++int gr_check_protected_task(const struct task_struct *task);
34264 ++__u32 to_gr_audit(const __u32 reqmode);
34265 ++int gr_set_acls(const int type);
34266 ++
34267 ++int gr_acl_is_enabled(void);
34268 ++char gr_roletype_to_char(void);
34269 ++
34270 ++void gr_handle_alertkill(struct task_struct *task);
34271 ++char *gr_to_filename(const struct dentry *dentry,
34272 ++ const struct vfsmount *mnt);
34273 ++char *gr_to_filename1(const struct dentry *dentry,
34274 ++ const struct vfsmount *mnt);
34275 ++char *gr_to_filename2(const struct dentry *dentry,
34276 ++ const struct vfsmount *mnt);
34277 ++char *gr_to_filename3(const struct dentry *dentry,
34278 ++ const struct vfsmount *mnt);
34279 ++
34280 ++extern int grsec_enable_link;
34281 ++extern int grsec_enable_fifo;
34282 ++extern int grsec_enable_execve;
34283 ++extern int grsec_enable_shm;
34284 ++extern int grsec_enable_execlog;
34285 ++extern int grsec_enable_signal;
34286 ++extern int grsec_enable_forkfail;
34287 ++extern int grsec_enable_time;
34288 ++extern int grsec_enable_chroot_shmat;
34289 ++extern int grsec_enable_chroot_findtask;
34290 ++extern int grsec_enable_chroot_mount;
34291 ++extern int grsec_enable_chroot_double;
34292 ++extern int grsec_enable_chroot_pivot;
34293 ++extern int grsec_enable_chroot_chdir;
34294 ++extern int grsec_enable_chroot_chmod;
34295 ++extern int grsec_enable_chroot_mknod;
34296 ++extern int grsec_enable_chroot_fchdir;
34297 ++extern int grsec_enable_chroot_nice;
34298 ++extern int grsec_enable_chroot_execlog;
34299 ++extern int grsec_enable_chroot_caps;
34300 ++extern int grsec_enable_chroot_sysctl;
34301 ++extern int grsec_enable_chroot_unix;
34302 ++extern int grsec_enable_tpe;
34303 ++extern int grsec_tpe_gid;
34304 ++extern int grsec_enable_tpe_all;
34305 ++extern int grsec_enable_sidcaps;
34306 ++extern int grsec_enable_socket_all;
34307 ++extern int grsec_socket_all_gid;
34308 ++extern int grsec_enable_socket_client;
34309 ++extern int grsec_socket_client_gid;
34310 ++extern int grsec_enable_socket_server;
34311 ++extern int grsec_socket_server_gid;
34312 ++extern int grsec_audit_gid;
34313 ++extern int grsec_enable_group;
34314 ++extern int grsec_enable_audit_ipc;
34315 ++extern int grsec_enable_audit_textrel;
34316 ++extern int grsec_enable_mount;
34317 ++extern int grsec_enable_chdir;
34318 ++extern int grsec_resource_logging;
34319 ++extern int grsec_lock;
34320 ++
34321 ++extern spinlock_t grsec_alert_lock;
34322 ++extern unsigned long grsec_alert_wtime;
34323 ++extern unsigned long grsec_alert_fyet;
34324 ++
34325 ++extern spinlock_t grsec_audit_lock;
34326 ++
34327 ++extern rwlock_t grsec_exec_file_lock;
34328 ++
34329 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
34330 ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \
34331 ++ tsk->exec_file->f_vfsmnt) : "/")
34332 ++
34333 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
34334 ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
34335 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
34336 ++
34337 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
34338 ++ gr_to_filename(tsk->exec_file->f_path.dentry, \
34339 ++ tsk->exec_file->f_vfsmnt) : "/")
34340 ++
34341 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
34342 ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
34343 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
34344 ++
34345 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
34346 ++ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
34347 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
34348 ++ (tsk_a->fs->root.dentry->d_inode->i_ino != \
34349 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
34350 ++
34351 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
34352 ++ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
34353 ++ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
34354 ++ (tsk_a->fs->root.dentry->d_inode->i_ino == \
34355 ++ tsk_b->fs->root.dentry->d_inode->i_ino))
34356 ++
34357 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
34358 ++ task->pid, task->uid, \
34359 ++ task->euid, task->gid, task->egid, \
34360 ++ gr_parent_task_fullpath(task), \
34361 ++ task->parent->comm, task->parent->pid, \
34362 ++ task->parent->uid, task->parent->euid, \
34363 ++ task->parent->gid, task->parent->egid
34364 ++
34365 ++#define GR_CHROOT_CAPS {{ \
34366 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
34367 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
34368 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
34369 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
34370 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
34371 ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
34372 ++
34373 ++#define security_learn(normal_msg,args...) \
34374 ++({ \
34375 ++ read_lock(&grsec_exec_file_lock); \
34376 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
34377 ++ read_unlock(&grsec_exec_file_lock); \
34378 ++})
34379 ++
34380 ++enum {
34381 ++ GR_DO_AUDIT,
34382 ++ GR_DONT_AUDIT,
34383 ++ GR_DONT_AUDIT_GOOD
34384 ++};
34385 ++
34386 ++enum {
34387 ++ GR_TTYSNIFF,
34388 ++ GR_RBAC,
34389 ++ GR_RBAC_STR,
34390 ++ GR_STR_RBAC,
34391 ++ GR_RBAC_MODE2,
34392 ++ GR_RBAC_MODE3,
34393 ++ GR_FILENAME,
34394 ++ GR_SYSCTL_HIDDEN,
34395 ++ GR_NOARGS,
34396 ++ GR_ONE_INT,
34397 ++ GR_ONE_INT_TWO_STR,
34398 ++ GR_ONE_STR,
34399 ++ GR_STR_INT,
34400 ++ GR_TWO_INT,
34401 ++ GR_THREE_INT,
34402 ++ GR_FIVE_INT_TWO_STR,
34403 ++ GR_TWO_STR,
34404 ++ GR_THREE_STR,
34405 ++ GR_FOUR_STR,
34406 ++ GR_STR_FILENAME,
34407 ++ GR_FILENAME_STR,
34408 ++ GR_FILENAME_TWO_INT,
34409 ++ GR_FILENAME_TWO_INT_STR,
34410 ++ GR_TEXTREL,
34411 ++ GR_PTRACE,
34412 ++ GR_RESOURCE,
34413 ++ GR_CAP,
34414 ++ GR_SIG,
34415 ++ GR_CRASH1,
34416 ++ GR_CRASH2,
34417 ++ GR_PSACCT
34418 ++};
34419 ++
34420 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
34421 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
34422 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
34423 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
34424 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
34425 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
34426 ++#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)
34427 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
34428 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
34429 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
34430 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
34431 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
34432 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
34433 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
34434 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
34435 ++#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)
34436 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
34437 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
34438 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
34439 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
34440 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
34441 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
34442 ++#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)
34443 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
34444 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
34445 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
34446 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
34447 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
34448 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
34449 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
34450 ++#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)
34451 ++
34452 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
34453 ++
34454 ++#endif
34455 ++
34456 ++#endif
34457 +diff -urNp a/include/linux/grmsg.h b/include/linux/grmsg.h
34458 +--- a/include/linux/grmsg.h 1969-12-31 16:00:00.000000000 -0800
34459 ++++ b/include/linux/grmsg.h 2008-08-20 18:36:57.000000000 -0700
34460 +@@ -0,0 +1,108 @@
34461 ++#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"
34462 ++#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"
34463 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
34464 ++#define GR_STOPMOD_MSG "denied modification of module state by "
34465 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
34466 ++#define GR_IOPL_MSG "denied use of iopl() by "
34467 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
34468 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
34469 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
34470 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
34471 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
34472 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
34473 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
34474 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
34475 ++#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"
34476 ++#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"
34477 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
34478 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
34479 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
34480 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
34481 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
34482 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
34483 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
34484 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
34485 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
34486 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
34487 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
34488 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
34489 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
34490 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
34491 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
34492 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
34493 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
34494 ++#define GR_NPROC_MSG "denied overstep of process limit by "
34495 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
34496 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
34497 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
34498 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
34499 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
34500 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
34501 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
34502 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
34503 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
34504 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
34505 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
34506 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
34507 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
34508 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
34509 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
34510 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
34511 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
34512 ++#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"
34513 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
34514 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
34515 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
34516 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
34517 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
34518 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
34519 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
34520 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
34521 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
34522 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
34523 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
34524 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
34525 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
34526 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
34527 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
34528 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
34529 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
34530 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
34531 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
34532 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
34533 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
34534 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
34535 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
34536 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
34537 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
34538 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
34539 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
34540 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
34541 ++#define GR_TIME_MSG "time set by "
34542 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
34543 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
34544 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
34545 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
34546 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
34547 ++#define GR_BIND_MSG "denied bind() by "
34548 ++#define GR_CONNECT_MSG "denied connect() by "
34549 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
34550 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
34551 ++#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"
34552 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
34553 ++#define GR_CAP_ACL_MSG "use of %s denied for "
34554 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
34555 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
34556 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
34557 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
34558 ++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
34559 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
34560 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
34561 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
34562 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
34563 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
34564 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
34565 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
34566 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
34567 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
34568 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
34569 +diff -urNp a/include/linux/grsecurity.h b/include/linux/grsecurity.h
34570 +--- a/include/linux/grsecurity.h 1969-12-31 16:00:00.000000000 -0800
34571 ++++ b/include/linux/grsecurity.h 2008-08-20 18:36:57.000000000 -0700
34572 +@@ -0,0 +1,200 @@
34573 ++#ifndef GR_SECURITY_H
34574 ++#define GR_SECURITY_H
34575 ++#include <linux/fs.h>
34576 ++#include <linux/binfmts.h>
34577 ++#include <linux/gracl.h>
34578 ++
34579 ++/* notify of brain-dead configs */
34580 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
34581 ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
34582 ++#endif
34583 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
34584 ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
34585 ++#endif
34586 ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
34587 ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
34588 ++#endif
34589 ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
34590 ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
34591 ++#endif
34592 ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
34593 ++#error "CONFIG_PAX enabled, but no PaX options are enabled."
34594 ++#endif
34595 ++
34596 ++void gr_handle_brute_attach(struct task_struct *p);
34597 ++void gr_handle_brute_check(void);
34598 ++
34599 ++char gr_roletype_to_char(void);
34600 ++
34601 ++int gr_check_user_change(int real, int effective, int fs);
34602 ++int gr_check_group_change(int real, int effective, int fs);
34603 ++
34604 ++void gr_del_task_from_ip_table(struct task_struct *p);
34605 ++
34606 ++int gr_pid_is_chrooted(struct task_struct *p);
34607 ++int gr_handle_chroot_nice(void);
34608 ++int gr_handle_chroot_sysctl(const int op);
34609 ++int gr_handle_chroot_setpriority(struct task_struct *p,
34610 ++ const int niceval);
34611 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
34612 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
34613 ++ const struct vfsmount *mnt);
34614 ++void gr_handle_chroot_caps(struct task_struct *task);
34615 ++void gr_handle_chroot_chdir(struct path *path);
34616 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
34617 ++ const struct vfsmount *mnt, const int mode);
34618 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
34619 ++ const struct vfsmount *mnt, const int mode);
34620 ++int gr_handle_chroot_mount(const struct dentry *dentry,
34621 ++ const struct vfsmount *mnt,
34622 ++ const char *dev_name);
34623 ++int gr_handle_chroot_pivot(void);
34624 ++int gr_handle_chroot_unix(const pid_t pid);
34625 ++
34626 ++int gr_handle_rawio(const struct inode *inode);
34627 ++int gr_handle_nproc(void);
34628 ++
34629 ++void gr_handle_ioperm(void);
34630 ++void gr_handle_iopl(void);
34631 ++
34632 ++int gr_tpe_allow(const struct file *file);
34633 ++
34634 ++int gr_random_pid(void);
34635 ++
34636 ++void gr_log_forkfail(const int retval);
34637 ++void gr_log_timechange(void);
34638 ++void gr_log_signal(const int sig, const struct task_struct *t);
34639 ++void gr_log_chdir(const struct dentry *dentry,
34640 ++ const struct vfsmount *mnt);
34641 ++void gr_log_chroot_exec(const struct dentry *dentry,
34642 ++ const struct vfsmount *mnt);
34643 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
34644 ++void gr_log_remount(const char *devname, const int retval);
34645 ++void gr_log_unmount(const char *devname, const int retval);
34646 ++void gr_log_mount(const char *from, const char *to, const int retval);
34647 ++void gr_log_msgget(const int ret, const int msgflg);
34648 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
34649 ++void gr_log_semget(const int err, const int semflg);
34650 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
34651 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
34652 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
34653 ++void gr_log_textrel(struct vm_area_struct *vma);
34654 ++
34655 ++int gr_handle_follow_link(const struct inode *parent,
34656 ++ const struct inode *inode,
34657 ++ const struct dentry *dentry,
34658 ++ const struct vfsmount *mnt);
34659 ++int gr_handle_fifo(const struct dentry *dentry,
34660 ++ const struct vfsmount *mnt,
34661 ++ const struct dentry *dir, const int flag,
34662 ++ const int acc_mode);
34663 ++int gr_handle_hardlink(const struct dentry *dentry,
34664 ++ const struct vfsmount *mnt,
34665 ++ struct inode *inode,
34666 ++ const int mode, const char *to);
34667 ++
34668 ++int gr_task_is_capable(struct task_struct *task, const int cap);
34669 ++int gr_is_capable_nolog(const int cap);
34670 ++void gr_learn_resource(const struct task_struct *task, const int limit,
34671 ++ const unsigned long wanted, const int gt);
34672 ++void gr_copy_label(struct task_struct *tsk);
34673 ++void gr_handle_crash(struct task_struct *task, const int sig);
34674 ++int gr_handle_signal(const struct task_struct *p, const int sig);
34675 ++int gr_check_crash_uid(const uid_t uid);
34676 ++int gr_check_protected_task(const struct task_struct *task);
34677 ++int gr_acl_handle_mmap(const struct file *file,
34678 ++ const unsigned long prot);
34679 ++int gr_acl_handle_mprotect(const struct file *file,
34680 ++ const unsigned long prot);
34681 ++int gr_check_hidden_task(const struct task_struct *tsk);
34682 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
34683 ++ const struct vfsmount *mnt);
34684 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
34685 ++ const struct vfsmount *mnt);
34686 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
34687 ++ const struct vfsmount *mnt, const int fmode);
34688 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
34689 ++ const struct vfsmount *mnt, mode_t mode);
34690 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
34691 ++ const struct vfsmount *mnt, mode_t mode);
34692 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
34693 ++ const struct vfsmount *mnt);
34694 ++int gr_handle_ptrace(struct task_struct *task, const long request);
34695 ++int gr_handle_proc_ptrace(struct task_struct *task);
34696 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
34697 ++ const struct vfsmount *mnt);
34698 ++int gr_check_crash_exec(const struct file *filp);
34699 ++int gr_acl_is_enabled(void);
34700 ++void gr_set_kernel_label(struct task_struct *task);
34701 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
34702 ++ const gid_t gid);
34703 ++int gr_set_proc_label(const struct dentry *dentry,
34704 ++ const struct vfsmount *mnt);
34705 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
34706 ++ const struct vfsmount *mnt);
34707 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
34708 ++ const struct vfsmount *mnt, const int fmode);
34709 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
34710 ++ const struct dentry *p_dentry,
34711 ++ const struct vfsmount *p_mnt, const int fmode,
34712 ++ const int imode);
34713 ++void gr_handle_create(const struct dentry *dentry,
34714 ++ const struct vfsmount *mnt);
34715 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
34716 ++ const struct dentry *parent_dentry,
34717 ++ const struct vfsmount *parent_mnt,
34718 ++ const int mode);
34719 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
34720 ++ const struct dentry *parent_dentry,
34721 ++ const struct vfsmount *parent_mnt);
34722 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
34723 ++ const struct vfsmount *mnt);
34724 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
34725 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
34726 ++ const struct vfsmount *mnt);
34727 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
34728 ++ const struct dentry *parent_dentry,
34729 ++ const struct vfsmount *parent_mnt,
34730 ++ const char *from);
34731 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
34732 ++ const struct dentry *parent_dentry,
34733 ++ const struct vfsmount *parent_mnt,
34734 ++ const struct dentry *old_dentry,
34735 ++ const struct vfsmount *old_mnt, const char *to);
34736 ++int gr_acl_handle_rename(struct dentry *new_dentry,
34737 ++ struct dentry *parent_dentry,
34738 ++ const struct vfsmount *parent_mnt,
34739 ++ struct dentry *old_dentry,
34740 ++ struct inode *old_parent_inode,
34741 ++ struct vfsmount *old_mnt, const char *newname);
34742 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
34743 ++ struct dentry *old_dentry,
34744 ++ struct dentry *new_dentry,
34745 ++ struct vfsmount *mnt, const __u8 replace);
34746 ++__u32 gr_check_link(const struct dentry *new_dentry,
34747 ++ const struct dentry *parent_dentry,
34748 ++ const struct vfsmount *parent_mnt,
34749 ++ const struct dentry *old_dentry,
34750 ++ const struct vfsmount *old_mnt);
34751 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
34752 ++ const unsigned int namelen, const ino_t ino);
34753 ++
34754 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
34755 ++ const struct vfsmount *mnt);
34756 ++void gr_acl_handle_exit(void);
34757 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
34758 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
34759 ++
34760 ++#ifdef CONFIG_GRKERNSEC
34761 ++void gr_handle_mem_write(void);
34762 ++void gr_handle_kmem_write(void);
34763 ++void gr_handle_open_port(void);
34764 ++int gr_handle_mem_mmap(const unsigned long offset,
34765 ++ struct vm_area_struct *vma);
34766 ++
34767 ++extern int grsec_enable_dmesg;
34768 ++extern int grsec_enable_randsrc;
34769 ++extern int grsec_enable_shm;
34770 ++#endif
34771 ++
34772 ++#endif
34773 +diff -urNp a/include/linux/highmem.h b/include/linux/highmem.h
34774 +--- a/include/linux/highmem.h 2008-08-20 11:16:13.000000000 -0700
34775 ++++ b/include/linux/highmem.h 2008-08-20 18:36:57.000000000 -0700
34776 +@@ -122,6 +122,13 @@ static inline void clear_highpage(struct
34777 + kunmap_atomic(kaddr, KM_USER0);
34778 + }
34779 +
34780 ++static inline void sanitize_highpage(struct page *page)
34781 ++{
34782 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
34783 ++ clear_page(kaddr);
34784 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
34785 ++}
34786 ++
34787 + static inline void zero_user_segments(struct page *page,
34788 + unsigned start1, unsigned end1,
34789 + unsigned start2, unsigned end2)
34790 +diff -urNp a/include/linux/irqflags.h b/include/linux/irqflags.h
34791 +--- a/include/linux/irqflags.h 2008-08-20 11:16:13.000000000 -0700
34792 ++++ b/include/linux/irqflags.h 2008-08-20 18:36:57.000000000 -0700
34793 +@@ -84,10 +84,10 @@
34794 +
34795 + #define irqs_disabled() \
34796 + ({ \
34797 +- unsigned long flags; \
34798 ++ unsigned long __flags; \
34799 + \
34800 +- raw_local_save_flags(flags); \
34801 +- raw_irqs_disabled_flags(flags); \
34802 ++ raw_local_save_flags(__flags); \
34803 ++ raw_irqs_disabled_flags(__flags); \
34804 + })
34805 +
34806 + #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
34807 +diff -urNp a/include/linux/jbd.h b/include/linux/jbd.h
34808 +--- a/include/linux/jbd.h 2008-08-20 11:16:13.000000000 -0700
34809 ++++ b/include/linux/jbd.h 2008-08-20 18:36:57.000000000 -0700
34810 +@@ -68,7 +68,7 @@ extern u8 journal_enable_debug;
34811 + } \
34812 + } while (0)
34813 + #else
34814 +-#define jbd_debug(f, a...) /**/
34815 ++#define jbd_debug(f, a...) do {} while (0)
34816 + #endif
34817 +
34818 + static inline void *jbd_alloc(size_t size, gfp_t flags)
34819 +diff -urNp a/include/linux/jbd2.h b/include/linux/jbd2.h
34820 +--- a/include/linux/jbd2.h 2008-08-20 11:16:13.000000000 -0700
34821 ++++ b/include/linux/jbd2.h 2008-08-20 18:36:57.000000000 -0700
34822 +@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
34823 + } \
34824 + } while (0)
34825 + #else
34826 +-#define jbd_debug(f, a...) /**/
34827 ++#define jbd_debug(f, a...) do {} while (0)
34828 + #endif
34829 +
34830 + static inline void *jbd2_alloc(size_t size, gfp_t flags)
34831 +diff -urNp a/include/linux/libata.h b/include/linux/libata.h
34832 +--- a/include/linux/libata.h 2008-08-20 11:16:13.000000000 -0700
34833 ++++ b/include/linux/libata.h 2008-08-20 18:36:57.000000000 -0700
34834 +@@ -63,11 +63,11 @@
34835 + #ifdef ATA_VERBOSE_DEBUG
34836 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
34837 + #else
34838 +-#define VPRINTK(fmt, args...)
34839 ++#define VPRINTK(fmt, args...) do {} while (0)
34840 + #endif /* ATA_VERBOSE_DEBUG */
34841 + #else
34842 +-#define DPRINTK(fmt, args...)
34843 +-#define VPRINTK(fmt, args...)
34844 ++#define DPRINTK(fmt, args...) do {} while (0)
34845 ++#define VPRINTK(fmt, args...) do {} while (0)
34846 + #endif /* ATA_DEBUG */
34847 +
34848 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
34849 +diff -urNp a/include/linux/mm.h b/include/linux/mm.h
34850 +--- a/include/linux/mm.h 2008-08-20 11:16:13.000000000 -0700
34851 ++++ b/include/linux/mm.h 2008-08-20 18:36:57.000000000 -0700
34852 +@@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
34853 + #include <asm/page.h>
34854 + #include <asm/pgtable.h>
34855 + #include <asm/processor.h>
34856 ++#include <asm/mman.h>
34857 +
34858 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
34859 +
34860 +@@ -108,6 +109,14 @@ extern unsigned int kobjsize(const void
34861 +
34862 + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
34863 +
34864 ++#ifdef CONFIG_PAX_PAGEEXEC
34865 ++#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
34866 ++#endif
34867 ++
34868 ++#ifdef CONFIG_PAX_MPROTECT
34869 ++#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
34870 ++#endif
34871 ++
34872 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
34873 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
34874 + #endif
34875 +@@ -836,6 +845,8 @@ struct shrinker {
34876 + extern void register_shrinker(struct shrinker *);
34877 + extern void unregister_shrinker(struct shrinker *);
34878 +
34879 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
34880 ++
34881 + int vma_wants_writenotify(struct vm_area_struct *vma);
34882 +
34883 + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
34884 +@@ -1074,6 +1085,7 @@ out:
34885 + }
34886 +
34887 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
34888 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
34889 +
34890 + extern unsigned long do_brk(unsigned long, unsigned long);
34891 +
34892 +@@ -1126,6 +1138,10 @@ extern struct vm_area_struct * find_vma(
34893 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
34894 + struct vm_area_struct **pprev);
34895 +
34896 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
34897 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
34898 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
34899 ++
34900 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
34901 + NULL if none. Assume start_addr < end_addr. */
34902 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
34903 +@@ -1142,7 +1158,6 @@ static inline unsigned long vma_pages(st
34904 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
34905 + }
34906 +
34907 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
34908 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
34909 + int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
34910 + unsigned long pfn, unsigned long size, pgprot_t);
34911 +@@ -1230,5 +1245,11 @@ int vmemmap_populate_basepages(struct pa
34912 + unsigned long pages, int node);
34913 + int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
34914 +
34915 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34916 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
34917 ++#else
34918 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
34919 ++#endif
34920 ++
34921 + #endif /* __KERNEL__ */
34922 + #endif /* _LINUX_MM_H */
34923 +diff -urNp a/include/linux/mm_types.h b/include/linux/mm_types.h
34924 +--- a/include/linux/mm_types.h 2008-08-20 11:16:13.000000000 -0700
34925 ++++ b/include/linux/mm_types.h 2008-08-20 18:36:57.000000000 -0700
34926 +@@ -154,6 +154,8 @@ struct vm_area_struct {
34927 + #ifdef CONFIG_NUMA
34928 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
34929 + #endif
34930 ++
34931 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
34932 + };
34933 +
34934 + struct mm_struct {
34935 +@@ -225,6 +227,24 @@ struct mm_struct {
34936 + #ifdef CONFIG_CGROUP_MEM_RES_CTLR
34937 + struct mem_cgroup *mem_cgroup;
34938 + #endif
34939 ++
34940 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
34941 ++ unsigned long pax_flags;
34942 ++#endif
34943 ++
34944 ++#ifdef CONFIG_PAX_DLRESOLVE
34945 ++ unsigned long call_dl_resolve;
34946 ++#endif
34947 ++
34948 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
34949 ++ unsigned long call_syscall;
34950 ++#endif
34951 ++
34952 ++#ifdef CONFIG_PAX_ASLR
34953 ++ unsigned long delta_mmap; /* randomized offset */
34954 ++ unsigned long delta_stack; /* randomized offset */
34955 ++#endif
34956 ++
34957 + };
34958 +
34959 + #endif /* _LINUX_MM_TYPES_H */
34960 +diff -urNp a/include/linux/module.h b/include/linux/module.h
34961 +--- a/include/linux/module.h 2008-08-20 11:16:13.000000000 -0700
34962 ++++ b/include/linux/module.h 2008-08-20 18:36:57.000000000 -0700
34963 +@@ -296,16 +296,16 @@ struct module
34964 + int (*init)(void);
34965 +
34966 + /* If this is non-NULL, vfree after init() returns */
34967 +- void *module_init;
34968 ++ void *module_init_rx, *module_init_rw;
34969 +
34970 + /* Here is the actual code + data, vfree'd on unload. */
34971 +- void *module_core;
34972 ++ void *module_core_rx, *module_core_rw;
34973 +
34974 + /* Here are the sizes of the init and core sections */
34975 +- unsigned long init_size, core_size;
34976 ++ unsigned long init_size_rw, core_size_rw;
34977 +
34978 + /* The size of the executable code in each section. */
34979 +- unsigned long init_text_size, core_text_size;
34980 ++ unsigned long init_size_rx, core_size_rx;
34981 +
34982 + /* The handle returned from unwind_add_table. */
34983 + void *unwind_info;
34984 +diff -urNp a/include/linux/moduleloader.h b/include/linux/moduleloader.h
34985 +--- a/include/linux/moduleloader.h 2008-08-20 11:16:13.000000000 -0700
34986 ++++ b/include/linux/moduleloader.h 2008-08-20 18:36:57.000000000 -0700
34987 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
34988 + sections. Returns NULL on failure. */
34989 + void *module_alloc(unsigned long size);
34990 +
34991 ++#ifdef CONFIG_PAX_KERNEXEC
34992 ++void *module_alloc_exec(unsigned long size);
34993 ++#else
34994 ++#define module_alloc_exec(x) module_alloc(x)
34995 ++#endif
34996 ++
34997 + /* Free memory returned from module_alloc. */
34998 + void module_free(struct module *mod, void *module_region);
34999 +
35000 ++#ifdef CONFIG_PAX_KERNEXEC
35001 ++void module_free_exec(struct module *mod, void *module_region);
35002 ++#else
35003 ++#define module_free_exec(x, y) module_free(x, y)
35004 ++#endif
35005 ++
35006 + /* Apply the given relocation to the (simplified) ELF. Return -error
35007 + or 0. */
35008 + int apply_relocate(Elf_Shdr *sechdrs,
35009 +diff -urNp a/include/linux/namei.h b/include/linux/namei.h
35010 +--- a/include/linux/namei.h 2008-08-20 11:16:13.000000000 -0700
35011 ++++ b/include/linux/namei.h 2008-08-20 18:36:57.000000000 -0700
35012 +@@ -21,7 +21,7 @@ struct nameidata {
35013 + unsigned int flags;
35014 + int last_type;
35015 + unsigned depth;
35016 +- char *saved_names[MAX_NESTED_LINKS + 1];
35017 ++ const char *saved_names[MAX_NESTED_LINKS + 1];
35018 +
35019 + /* Intent data */
35020 + union {
35021 +@@ -83,12 +83,12 @@ extern int follow_up(struct vfsmount **,
35022 + extern struct dentry *lock_rename(struct dentry *, struct dentry *);
35023 + extern void unlock_rename(struct dentry *, struct dentry *);
35024 +
35025 +-static inline void nd_set_link(struct nameidata *nd, char *path)
35026 ++static inline void nd_set_link(struct nameidata *nd, const char *path)
35027 + {
35028 + nd->saved_names[nd->depth] = path;
35029 + }
35030 +
35031 +-static inline char *nd_get_link(struct nameidata *nd)
35032 ++static inline const char *nd_get_link(struct nameidata *nd)
35033 + {
35034 + return nd->saved_names[nd->depth];
35035 + }
35036 +diff -urNp a/include/linux/percpu.h b/include/linux/percpu.h
35037 +--- a/include/linux/percpu.h 2008-08-20 11:16:13.000000000 -0700
35038 ++++ b/include/linux/percpu.h 2008-08-20 18:36:57.000000000 -0700
35039 +@@ -38,7 +38,7 @@
35040 + #endif
35041 +
35042 + #define PERCPU_ENOUGH_ROOM \
35043 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
35044 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
35045 + #endif /* PERCPU_ENOUGH_ROOM */
35046 +
35047 + /*
35048 +diff -urNp a/include/linux/poison.h b/include/linux/poison.h
35049 +--- a/include/linux/poison.h 2008-08-20 11:16:13.000000000 -0700
35050 ++++ b/include/linux/poison.h 2008-08-20 18:36:57.000000000 -0700
35051 +@@ -7,8 +7,8 @@
35052 + * under normal circumstances, used to verify that nobody uses
35053 + * non-initialized list entries.
35054 + */
35055 +-#define LIST_POISON1 ((void *) 0x00100100)
35056 +-#define LIST_POISON2 ((void *) 0x00200200)
35057 ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
35058 ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
35059 +
35060 + /********** mm/slab.c **********/
35061 + /*
35062 +diff -urNp a/include/linux/random.h b/include/linux/random.h
35063 +--- a/include/linux/random.h 2008-08-20 11:16:13.000000000 -0700
35064 ++++ b/include/linux/random.h 2008-08-20 18:36:57.000000000 -0700
35065 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
35066 + u32 random32(void);
35067 + void srandom32(u32 seed);
35068 +
35069 ++static inline unsigned long pax_get_random_long(void)
35070 ++{
35071 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
35072 ++}
35073 ++
35074 + #endif /* __KERNEL___ */
35075 +
35076 + #endif /* _LINUX_RANDOM_H */
35077 +diff -urNp a/include/linux/sched.h b/include/linux/sched.h
35078 +--- a/include/linux/sched.h 2008-08-20 11:16:13.000000000 -0700
35079 ++++ b/include/linux/sched.h 2008-08-20 18:36:57.000000000 -0700
35080 +@@ -97,6 +97,7 @@ struct exec_domain;
35081 + struct futex_pi_state;
35082 + struct robust_list_head;
35083 + struct bio;
35084 ++struct linux_binprm;
35085 +
35086 + /*
35087 + * List of flags we want to share for kernel threads,
35088 +@@ -542,6 +543,15 @@ struct signal_struct {
35089 + unsigned audit_tty;
35090 + struct tty_audit_buf *tty_audit_buf;
35091 + #endif
35092 ++
35093 ++#ifdef CONFIG_GRKERNSEC
35094 ++ u32 curr_ip;
35095 ++ u32 gr_saddr;
35096 ++ u32 gr_daddr;
35097 ++ u16 gr_sport;
35098 ++ u16 gr_dport;
35099 ++ u8 used_accept:1;
35100 ++#endif
35101 + };
35102 +
35103 + /* Context switch must be unlocked if interrupts are to be enabled */
35104 +@@ -993,7 +1003,7 @@ struct sched_rt_entity {
35105 +
35106 + struct task_struct {
35107 + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
35108 +- void *stack;
35109 ++ struct thread_info *stack;
35110 + atomic_t usage;
35111 + unsigned int flags; /* per process flags, defined below */
35112 + unsigned int ptrace;
35113 +@@ -1063,10 +1073,9 @@ struct task_struct {
35114 + pid_t pid;
35115 + pid_t tgid;
35116 +
35117 +-#ifdef CONFIG_CC_STACKPROTECTOR
35118 + /* Canary value for the -fstack-protector gcc feature */
35119 + unsigned long stack_canary;
35120 +-#endif
35121 ++
35122 + /*
35123 + * pointers to (original) parent process, youngest child, younger sibling,
35124 + * older sibling, respectively. (p->father can be replaced with
35125 +@@ -1087,8 +1096,8 @@ struct task_struct {
35126 + struct list_head thread_group;
35127 +
35128 + struct completion *vfork_done; /* for vfork() */
35129 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
35130 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
35131 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
35132 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
35133 +
35134 + unsigned int rt_priority;
35135 + cputime_t utime, stime, utimescaled, stimescaled;
35136 +@@ -1271,8 +1280,60 @@ struct task_struct {
35137 + int latency_record_count;
35138 + struct latency_record latency_record[LT_SAVECOUNT];
35139 + #endif
35140 ++
35141 ++#ifdef CONFIG_GRKERNSEC
35142 ++ /* grsecurity */
35143 ++ struct acl_subject_label *acl;
35144 ++ struct acl_role_label *role;
35145 ++ struct file *exec_file;
35146 ++ u16 acl_role_id;
35147 ++ u8 acl_sp_role;
35148 ++ u8 is_writable;
35149 ++ u8 brute;
35150 ++#endif
35151 ++
35152 + };
35153 +
35154 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
35155 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
35156 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
35157 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
35158 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
35159 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
35160 ++
35161 ++#ifdef CONFIG_PAX_SOFTMODE
35162 ++extern unsigned int pax_softmode;
35163 ++#endif
35164 ++
35165 ++extern int pax_check_flags(unsigned long *);
35166 ++
35167 ++/* if tsk != current then task_lock must be held on it */
35168 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
35169 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
35170 ++{
35171 ++ if (likely(tsk->mm))
35172 ++ return tsk->mm->pax_flags;
35173 ++ else
35174 ++ return 0UL;
35175 ++}
35176 ++
35177 ++/* if tsk != current then task_lock must be held on it */
35178 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
35179 ++{
35180 ++ if (likely(tsk->mm)) {
35181 ++ tsk->mm->pax_flags = flags;
35182 ++ return 0;
35183 ++ }
35184 ++ return -EINVAL;
35185 ++}
35186 ++#endif
35187 ++
35188 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
35189 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
35190 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
35191 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
35192 ++#endif
35193 ++
35194 + /*
35195 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
35196 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
35197 +@@ -1775,7 +1836,7 @@ extern void __cleanup_signal(struct sign
35198 + extern void __cleanup_sighand(struct sighand_struct *);
35199 + extern void exit_itimers(struct signal_struct *);
35200 +
35201 +-extern NORET_TYPE void do_group_exit(int);
35202 ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
35203 +
35204 + extern void daemonize(const char *, ...);
35205 + extern int allow_signal(int);
35206 +@@ -1877,8 +1938,8 @@ static inline void unlock_task_sighand(s
35207 +
35208 + #ifndef __HAVE_THREAD_FUNCTIONS
35209 +
35210 +-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
35211 +-#define task_stack_page(task) ((task)->stack)
35212 ++#define task_thread_info(task) ((task)->stack)
35213 ++#define task_stack_page(task) ((void *)(task)->stack)
35214 +
35215 + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
35216 + {
35217 +@@ -2026,6 +2087,12 @@ extern void arch_pick_mmap_layout(struct
35218 + static inline void arch_pick_mmap_layout(struct mm_struct *mm)
35219 + {
35220 + mm->mmap_base = TASK_UNMAPPED_BASE;
35221 ++
35222 ++#ifdef CONFIG_PAX_RANDMMAP
35223 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
35224 ++ mm->mmap_base += mm->delta_mmap;
35225 ++#endif
35226 ++
35227 + mm->get_unmapped_area = arch_get_unmapped_area;
35228 + mm->unmap_area = arch_unmap_area;
35229 + }
35230 +diff -urNp a/include/linux/screen_info.h b/include/linux/screen_info.h
35231 +--- a/include/linux/screen_info.h 2008-08-20 11:16:13.000000000 -0700
35232 ++++ b/include/linux/screen_info.h 2008-08-20 18:36:57.000000000 -0700
35233 +@@ -42,7 +42,8 @@ struct screen_info {
35234 + __u16 pages; /* 0x32 */
35235 + __u16 vesa_attributes; /* 0x34 */
35236 + __u32 capabilities; /* 0x36 */
35237 +- __u8 _reserved[6]; /* 0x3a */
35238 ++ __u16 vesapm_size; /* 0x3a */
35239 ++ __u8 _reserved[4]; /* 0x3c */
35240 + } __attribute__((packed));
35241 +
35242 + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
35243 +diff -urNp a/include/linux/shm.h b/include/linux/shm.h
35244 +--- a/include/linux/shm.h 2008-08-20 11:16:13.000000000 -0700
35245 ++++ b/include/linux/shm.h 2008-08-20 18:36:57.000000000 -0700
35246 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
35247 + pid_t shm_cprid;
35248 + pid_t shm_lprid;
35249 + struct user_struct *mlock_user;
35250 ++#ifdef CONFIG_GRKERNSEC
35251 ++ time_t shm_createtime;
35252 ++ pid_t shm_lapid;
35253 ++#endif
35254 + };
35255 +
35256 + /* shm_mode upper byte flags */
35257 +diff -urNp a/include/linux/sysctl.h b/include/linux/sysctl.h
35258 +--- a/include/linux/sysctl.h 2008-08-20 11:16:13.000000000 -0700
35259 ++++ b/include/linux/sysctl.h 2008-08-20 18:36:57.000000000 -0700
35260 +@@ -163,9 +163,21 @@ enum
35261 + KERN_MAX_LOCK_DEPTH=74,
35262 + KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
35263 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
35264 +-};
35265 ++#ifdef CONFIG_GRKERNSEC
35266 ++ KERN_GRSECURITY=98, /* grsecurity */
35267 ++#endif
35268 ++
35269 ++#ifdef CONFIG_PAX_SOFTMODE
35270 ++ KERN_PAX=99, /* PaX control */
35271 ++#endif
35272 +
35273 ++};
35274 +
35275 ++#ifdef CONFIG_PAX_SOFTMODE
35276 ++enum {
35277 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
35278 ++};
35279 ++#endif
35280 +
35281 + /* CTL_VM names: */
35282 + enum
35283 +diff -urNp a/include/linux/uaccess.h b/include/linux/uaccess.h
35284 +--- a/include/linux/uaccess.h 2008-08-20 11:16:13.000000000 -0700
35285 ++++ b/include/linux/uaccess.h 2008-08-20 18:36:57.000000000 -0700
35286 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
35287 + long ret; \
35288 + mm_segment_t old_fs = get_fs(); \
35289 + \
35290 +- set_fs(KERNEL_DS); \
35291 + pagefault_disable(); \
35292 ++ set_fs(KERNEL_DS); \
35293 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
35294 +- pagefault_enable(); \
35295 + set_fs(old_fs); \
35296 ++ pagefault_enable(); \
35297 + ret; \
35298 + })
35299 +
35300 +diff -urNp a/include/linux/udf_fs.h b/include/linux/udf_fs.h
35301 +--- a/include/linux/udf_fs.h 2008-08-20 11:16:13.000000000 -0700
35302 ++++ b/include/linux/udf_fs.h 2008-08-20 18:36:57.000000000 -0700
35303 +@@ -42,7 +42,7 @@
35304 + printk (f, ##a); \
35305 + } while (0)
35306 + #else
35307 +-#define udf_debug(f, a...) /**/
35308 ++#define udf_debug(f, a...) do {} while (0)
35309 + #endif
35310 +
35311 + #define udf_info(f, a...) \
35312 +diff -urNp a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
35313 +--- a/include/net/sctp/sctp.h 2008-08-20 11:16:13.000000000 -0700
35314 ++++ b/include/net/sctp/sctp.h 2008-08-20 18:36:57.000000000 -0700
35315 +@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
35316 +
35317 + #else /* SCTP_DEBUG */
35318 +
35319 +-#define SCTP_DEBUG_PRINTK(whatever...)
35320 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
35321 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
35322 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
35323 + #define SCTP_ENABLE_DEBUG
35324 + #define SCTP_DISABLE_DEBUG
35325 + #define SCTP_ASSERT(expr, str, func)
35326 +diff -urNp a/include/sound/core.h b/include/sound/core.h
35327 +--- a/include/sound/core.h 2008-08-20 11:16:13.000000000 -0700
35328 ++++ b/include/sound/core.h 2008-08-20 18:36:57.000000000 -0700
35329 +@@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
35330 +
35331 + #else /* !CONFIG_SND_DEBUG */
35332 +
35333 +-#define snd_printd(fmt, args...) /* nothing */
35334 ++#define snd_printd(fmt, args...) do {} while (0)
35335 + #define snd_assert(expr, args...) (void)(expr)
35336 +-#define snd_BUG() /* nothing */
35337 ++#define snd_BUG() do {} while (0)
35338 +
35339 + #endif /* CONFIG_SND_DEBUG */
35340 +
35341 +@@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
35342 + */
35343 + #define snd_printdd(format, args...) snd_printk(format, ##args)
35344 + #else
35345 +-#define snd_printdd(format, args...) /* nothing */
35346 ++#define snd_printdd(format, args...) do {} while (0)
35347 + #endif
35348 +
35349 +
35350 +diff -urNp a/init/Kconfig b/init/Kconfig
35351 +--- a/init/Kconfig 2008-08-20 11:16:13.000000000 -0700
35352 ++++ b/init/Kconfig 2008-08-20 18:36:57.000000000 -0700
35353 +@@ -539,6 +539,7 @@ config SYSCTL_SYSCALL
35354 + config KALLSYMS
35355 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
35356 + default y
35357 ++ depends on !GRKERNSEC_HIDESYM
35358 + help
35359 + Say Y here to let the kernel print out symbolic crash information and
35360 + symbolic stack backtraces. This increases the size of the kernel
35361 +diff -urNp a/init/do_mounts.c b/init/do_mounts.c
35362 +--- a/init/do_mounts.c 2008-08-20 11:16:13.000000000 -0700
35363 ++++ b/init/do_mounts.c 2008-08-20 18:36:57.000000000 -0700
35364 +@@ -188,11 +188,11 @@ static void __init get_fs_names(char *pa
35365 +
35366 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
35367 + {
35368 +- int err = sys_mount(name, "/root", fs, flags, data);
35369 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
35370 + if (err)
35371 + return err;
35372 +
35373 +- sys_chdir("/root");
35374 ++ sys_chdir((char __user *)"/root");
35375 + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
35376 + printk("VFS: Mounted root (%s filesystem)%s.\n",
35377 + current->fs->pwd.mnt->mnt_sb->s_type->name,
35378 +@@ -278,18 +278,18 @@ void __init change_floppy(char *fmt, ...
35379 + va_start(args, fmt);
35380 + vsprintf(buf, fmt, args);
35381 + va_end(args);
35382 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
35383 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
35384 + if (fd >= 0) {
35385 + sys_ioctl(fd, FDEJECT, 0);
35386 + sys_close(fd);
35387 + }
35388 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
35389 +- fd = sys_open("/dev/console", O_RDWR, 0);
35390 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
35391 + if (fd >= 0) {
35392 + sys_ioctl(fd, TCGETS, (long)&termios);
35393 + termios.c_lflag &= ~ICANON;
35394 + sys_ioctl(fd, TCSETSF, (long)&termios);
35395 +- sys_read(fd, &c, 1);
35396 ++ sys_read(fd, (char __user *)&c, 1);
35397 + termios.c_lflag |= ICANON;
35398 + sys_ioctl(fd, TCSETSF, (long)&termios);
35399 + sys_close(fd);
35400 +@@ -375,7 +375,7 @@ void __init prepare_namespace(void)
35401 +
35402 + mount_root();
35403 + out:
35404 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
35405 +- sys_chroot(".");
35406 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
35407 ++ sys_chroot((char __user *)".");
35408 + }
35409 +
35410 +diff -urNp a/init/do_mounts.h b/init/do_mounts.h
35411 +--- a/init/do_mounts.h 2008-08-20 11:16:13.000000000 -0700
35412 ++++ b/init/do_mounts.h 2008-08-20 18:36:57.000000000 -0700
35413 +@@ -15,15 +15,15 @@ extern char *root_device_name;
35414 +
35415 + static inline int create_dev(char *name, dev_t dev)
35416 + {
35417 +- sys_unlink(name);
35418 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
35419 ++ sys_unlink((char __user *)name);
35420 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
35421 + }
35422 +
35423 + #if BITS_PER_LONG == 32
35424 + static inline u32 bstat(char *name)
35425 + {
35426 + struct stat64 stat;
35427 +- if (sys_stat64(name, &stat) != 0)
35428 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
35429 + return 0;
35430 + if (!S_ISBLK(stat.st_mode))
35431 + return 0;
35432 +diff -urNp a/init/do_mounts_md.c b/init/do_mounts_md.c
35433 +--- a/init/do_mounts_md.c 2008-08-20 11:16:13.000000000 -0700
35434 ++++ b/init/do_mounts_md.c 2008-08-20 18:36:57.000000000 -0700
35435 +@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
35436 + partitioned ? "_d" : "", minor,
35437 + md_setup_args[ent].device_names);
35438 +
35439 +- fd = sys_open(name, 0, 0);
35440 ++ fd = sys_open((char __user *)name, 0, 0);
35441 + if (fd < 0) {
35442 + printk(KERN_ERR "md: open failed - cannot start "
35443 + "array %s\n", name);
35444 +@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
35445 + * array without it
35446 + */
35447 + sys_close(fd);
35448 +- fd = sys_open(name, 0, 0);
35449 ++ fd = sys_open((char __user *)name, 0, 0);
35450 + sys_ioctl(fd, BLKRRPART, 0);
35451 + }
35452 + sys_close(fd);
35453 +@@ -271,7 +271,7 @@ void __init md_run_setup(void)
35454 + if (raid_noautodetect)
35455 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
35456 + else {
35457 +- int fd = sys_open("/dev/md0", 0, 0);
35458 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
35459 + if (fd >= 0) {
35460 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
35461 + sys_close(fd);
35462 +diff -urNp a/init/initramfs.c b/init/initramfs.c
35463 +--- a/init/initramfs.c 2008-08-20 11:16:13.000000000 -0700
35464 ++++ b/init/initramfs.c 2008-08-20 18:36:57.000000000 -0700
35465 +@@ -240,7 +240,7 @@ static int __init maybe_link(void)
35466 + if (nlink >= 2) {
35467 + char *old = find_link(major, minor, ino, mode, collected);
35468 + if (old)
35469 +- return (sys_link(old, collected) < 0) ? -1 : 1;
35470 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
35471 + }
35472 + return 0;
35473 + }
35474 +@@ -249,11 +249,11 @@ static void __init clean_path(char *path
35475 + {
35476 + struct stat st;
35477 +
35478 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
35479 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
35480 + if (S_ISDIR(st.st_mode))
35481 +- sys_rmdir(path);
35482 ++ sys_rmdir((char __user *)path);
35483 + else
35484 +- sys_unlink(path);
35485 ++ sys_unlink((char __user *)path);
35486 + }
35487 + }
35488 +
35489 +@@ -276,7 +276,7 @@ static int __init do_name(void)
35490 + int openflags = O_WRONLY|O_CREAT;
35491 + if (ml != 1)
35492 + openflags |= O_TRUNC;
35493 +- wfd = sys_open(collected, openflags, mode);
35494 ++ wfd = sys_open((char __user *)collected, openflags, mode);
35495 +
35496 + if (wfd >= 0) {
35497 + sys_fchown(wfd, uid, gid);
35498 +@@ -285,15 +285,15 @@ static int __init do_name(void)
35499 + }
35500 + }
35501 + } else if (S_ISDIR(mode)) {
35502 +- sys_mkdir(collected, mode);
35503 +- sys_chown(collected, uid, gid);
35504 +- sys_chmod(collected, mode);
35505 ++ sys_mkdir((char __user *)collected, mode);
35506 ++ sys_chown((char __user *)collected, uid, gid);
35507 ++ sys_chmod((char __user *)collected, mode);
35508 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
35509 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
35510 + if (maybe_link() == 0) {
35511 +- sys_mknod(collected, mode, rdev);
35512 +- sys_chown(collected, uid, gid);
35513 +- sys_chmod(collected, mode);
35514 ++ sys_mknod((char __user *)collected, mode, rdev);
35515 ++ sys_chown((char __user *)collected, uid, gid);
35516 ++ sys_chmod((char __user *)collected, mode);
35517 + }
35518 + }
35519 + return 0;
35520 +@@ -302,13 +302,13 @@ static int __init do_name(void)
35521 + static int __init do_copy(void)
35522 + {
35523 + if (count >= body_len) {
35524 +- sys_write(wfd, victim, body_len);
35525 ++ sys_write(wfd, (char __user *)victim, body_len);
35526 + sys_close(wfd);
35527 + eat(body_len);
35528 + state = SkipIt;
35529 + return 0;
35530 + } else {
35531 +- sys_write(wfd, victim, count);
35532 ++ sys_write(wfd, (char __user *)victim, count);
35533 + body_len -= count;
35534 + eat(count);
35535 + return 1;
35536 +@@ -319,8 +319,8 @@ static int __init do_symlink(void)
35537 + {
35538 + collected[N_ALIGN(name_len) + body_len] = '\0';
35539 + clean_path(collected, 0);
35540 +- sys_symlink(collected + N_ALIGN(name_len), collected);
35541 +- sys_lchown(collected, uid, gid);
35542 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
35543 ++ sys_lchown((char __user *)collected, uid, gid);
35544 + state = SkipIt;
35545 + next_state = Reset;
35546 + return 0;
35547 +diff -urNp a/init/main.c b/init/main.c
35548 +--- a/init/main.c 2008-08-20 11:16:13.000000000 -0700
35549 ++++ b/init/main.c 2008-08-20 18:36:57.000000000 -0700
35550 +@@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
35551 + #ifdef CONFIG_TC
35552 + extern void tc_init(void);
35553 + #endif
35554 ++extern void grsecurity_init(void);
35555 +
35556 + enum system_states system_state;
35557 + EXPORT_SYMBOL(system_state);
35558 +@@ -187,6 +188,40 @@ static int __init set_reset_devices(char
35559 +
35560 + __setup("reset_devices", set_reset_devices);
35561 +
35562 ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
35563 ++static int __init setup_pax_nouderef(char *str)
35564 ++{
35565 ++ unsigned int cpu;
35566 ++
35567 ++#ifdef CONFIG_PAX_KERNEXEC
35568 ++ unsigned long cr0;
35569 ++
35570 ++ pax_open_kernel(cr0);
35571 ++#endif
35572 ++
35573 ++ for (cpu = 0; cpu < NR_CPUS; cpu++)
35574 ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
35575 ++
35576 ++#ifdef CONFIG_PAX_KERNEXEC
35577 ++ pax_close_kernel(cr0);
35578 ++#endif
35579 ++
35580 ++ return 1;
35581 ++}
35582 ++__setup("pax_nouderef", setup_pax_nouderef);
35583 ++#endif
35584 ++
35585 ++#ifdef CONFIG_PAX_SOFTMODE
35586 ++unsigned int pax_softmode;
35587 ++
35588 ++static int __init setup_pax_softmode(char *str)
35589 ++{
35590 ++ get_option(&str, &pax_softmode);
35591 ++ return 1;
35592 ++}
35593 ++__setup("pax_softmode=", setup_pax_softmode);
35594 ++#endif
35595 ++
35596 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
35597 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
35598 + static const char *panic_later, *panic_param;
35599 +@@ -364,7 +399,7 @@ static inline void smp_prepare_cpus(unsi
35600 + #else
35601 +
35602 + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
35603 +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
35604 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
35605 +
35606 + EXPORT_SYMBOL(__per_cpu_offset);
35607 +
35608 +@@ -668,7 +703,7 @@ static void __init do_initcalls(void)
35609 +
35610 + for (call = __initcall_start; call < __initcall_end; call++) {
35611 + ktime_t t0, t1, delta;
35612 +- char *msg = NULL;
35613 ++ const char *msg1 = "", *msg2 = "";
35614 + char msgbuf[40];
35615 + int result;
35616 +
35617 +@@ -697,23 +732,22 @@ static void __init do_initcalls(void)
35618 + (unsigned long) *call);
35619 + }
35620 +
35621 +- if (result && result != -ENODEV && initcall_debug) {
35622 +- sprintf(msgbuf, "error code %d", result);
35623 +- msg = msgbuf;
35624 +- }
35625 ++ msgbuf[0] = 0;
35626 ++ if (result && result != -ENODEV && initcall_debug)
35627 ++ sprintf(msgbuf, " error code %d", result);
35628 + if (preempt_count() != count) {
35629 +- msg = "preemption imbalance";
35630 ++ msg1 = " preemption imbalance";
35631 + preempt_count() = count;
35632 + }
35633 + if (irqs_disabled()) {
35634 +- msg = "disabled interrupts";
35635 ++ msg2 = " disabled interrupts";
35636 + local_irq_enable();
35637 + }
35638 +- if (msg) {
35639 ++ if (msgbuf[0] || *msg1 || *msg2) {
35640 + printk(KERN_WARNING "initcall at 0x%p", *call);
35641 + print_fn_descriptor_symbol(": %s()",
35642 + (unsigned long) *call);
35643 +- printk(": returned with %s\n", msg);
35644 ++ printk(": returned with%s%s%s\n", msgbuf, msg1, msg2);
35645 + }
35646 + }
35647 +
35648 +@@ -848,6 +882,8 @@ static int __init kernel_init(void * unu
35649 + prepare_namespace();
35650 + }
35651 +
35652 ++ grsecurity_init();
35653 ++
35654 + /*
35655 + * Ok, we have completed the initial bootup, and
35656 + * we're essentially up and running. Get rid of the
35657 +diff -urNp a/init/noinitramfs.c b/init/noinitramfs.c
35658 +--- a/init/noinitramfs.c 2008-08-20 11:16:13.000000000 -0700
35659 ++++ b/init/noinitramfs.c 2008-08-20 18:36:57.000000000 -0700
35660 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
35661 + {
35662 + int err;
35663 +
35664 +- err = sys_mkdir("/dev", 0755);
35665 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
35666 + if (err < 0)
35667 + goto out;
35668 +
35669 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
35670 + if (err < 0)
35671 + goto out;
35672 +
35673 +- err = sys_mkdir("/root", 0700);
35674 ++ err = sys_mkdir((const char __user *)"/root", 0700);
35675 + if (err < 0)
35676 + goto out;
35677 +
35678 +diff -urNp a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
35679 +--- a/ipc/ipc_sysctl.c 2008-08-20 11:16:13.000000000 -0700
35680 ++++ b/ipc/ipc_sysctl.c 2008-08-20 18:36:57.000000000 -0700
35681 +@@ -158,7 +158,7 @@ static struct ctl_table ipc_kern_table[]
35682 + .proc_handler = proc_ipc_dointvec,
35683 + .strategy = sysctl_ipc_data,
35684 + },
35685 +- {}
35686 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35687 + };
35688 +
35689 + static struct ctl_table ipc_root_table[] = {
35690 +@@ -168,7 +168,7 @@ static struct ctl_table ipc_root_table[]
35691 + .mode = 0555,
35692 + .child = ipc_kern_table,
35693 + },
35694 +- {}
35695 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35696 + };
35697 +
35698 + static int __init ipc_sysctl_init(void)
35699 +diff -urNp a/ipc/msg.c b/ipc/msg.c
35700 +--- a/ipc/msg.c 2008-08-20 11:16:13.000000000 -0700
35701 ++++ b/ipc/msg.c 2008-08-20 18:36:57.000000000 -0700
35702 +@@ -37,6 +37,7 @@
35703 + #include <linux/rwsem.h>
35704 + #include <linux/nsproxy.h>
35705 + #include <linux/ipc_namespace.h>
35706 ++#include <linux/grsecurity.h>
35707 +
35708 + #include <asm/current.h>
35709 + #include <asm/uaccess.h>
35710 +@@ -293,6 +294,7 @@ asmlinkage long sys_msgget(key_t key, in
35711 + struct ipc_namespace *ns;
35712 + struct ipc_ops msg_ops;
35713 + struct ipc_params msg_params;
35714 ++ long err;
35715 +
35716 + ns = current->nsproxy->ipc_ns;
35717 +
35718 +@@ -303,7 +305,11 @@ asmlinkage long sys_msgget(key_t key, in
35719 + msg_params.key = key;
35720 + msg_params.flg = msgflg;
35721 +
35722 +- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
35723 ++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
35724 ++
35725 ++ gr_log_msgget(err, msgflg);
35726 ++
35727 ++ return err;
35728 + }
35729 +
35730 + static inline unsigned long
35731 +@@ -564,6 +570,7 @@ asmlinkage long sys_msgctl(int msqid, in
35732 + break;
35733 + }
35734 + case IPC_RMID:
35735 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
35736 + freeque(ns, &msq->q_perm);
35737 + break;
35738 + }
35739 +diff -urNp a/ipc/sem.c b/ipc/sem.c
35740 +--- a/ipc/sem.c 2008-08-20 11:16:13.000000000 -0700
35741 ++++ b/ipc/sem.c 2008-08-20 18:36:57.000000000 -0700
35742 +@@ -83,6 +83,7 @@
35743 + #include <linux/rwsem.h>
35744 + #include <linux/nsproxy.h>
35745 + #include <linux/ipc_namespace.h>
35746 ++#include <linux/grsecurity.h>
35747 +
35748 + #include <asm/uaccess.h>
35749 + #include "util.h"
35750 +@@ -312,6 +313,7 @@ asmlinkage long sys_semget(key_t key, in
35751 + struct ipc_namespace *ns;
35752 + struct ipc_ops sem_ops;
35753 + struct ipc_params sem_params;
35754 ++ long err;
35755 +
35756 + ns = current->nsproxy->ipc_ns;
35757 +
35758 +@@ -326,7 +328,11 @@ asmlinkage long sys_semget(key_t key, in
35759 + sem_params.flg = semflg;
35760 + sem_params.u.nsems = nsems;
35761 +
35762 +- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
35763 ++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
35764 ++
35765 ++ gr_log_semget(err, semflg);
35766 ++
35767 ++ return err;
35768 + }
35769 +
35770 + /* Manage the doubly linked list sma->sem_pending as a FIFO:
35771 +@@ -909,6 +915,7 @@ static int semctl_down(struct ipc_namesp
35772 +
35773 + switch(cmd){
35774 + case IPC_RMID:
35775 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
35776 + freeary(ns, ipcp);
35777 + err = 0;
35778 + break;
35779 +diff -urNp a/ipc/shm.c b/ipc/shm.c
35780 +--- a/ipc/shm.c 2008-08-20 11:16:13.000000000 -0700
35781 ++++ b/ipc/shm.c 2008-08-20 18:36:57.000000000 -0700
35782 +@@ -39,6 +39,7 @@
35783 + #include <linux/nsproxy.h>
35784 + #include <linux/mount.h>
35785 + #include <linux/ipc_namespace.h>
35786 ++#include <linux/grsecurity.h>
35787 +
35788 + #include <asm/uaccess.h>
35789 +
35790 +@@ -70,6 +71,14 @@ static void shm_destroy (struct ipc_name
35791 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
35792 + #endif
35793 +
35794 ++#ifdef CONFIG_GRKERNSEC
35795 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
35796 ++ const time_t shm_createtime, const uid_t cuid,
35797 ++ const int shmid);
35798 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
35799 ++ const time_t shm_createtime);
35800 ++#endif
35801 ++
35802 + void shm_init_ns(struct ipc_namespace *ns)
35803 + {
35804 + ns->shm_ctlmax = SHMMAX;
35805 +@@ -88,6 +97,8 @@ static void do_shm_rmid(struct ipc_names
35806 + struct shmid_kernel *shp;
35807 + shp = container_of(ipcp, struct shmid_kernel, shm_perm);
35808 +
35809 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
35810 ++
35811 + if (shp->shm_nattch){
35812 + shp->shm_perm.mode |= SHM_DEST;
35813 + /* Do not find it any more */
35814 +@@ -428,6 +439,14 @@ static int newseg(struct ipc_namespace *
35815 + shp->shm_lprid = 0;
35816 + shp->shm_atim = shp->shm_dtim = 0;
35817 + shp->shm_ctim = get_seconds();
35818 ++#ifdef CONFIG_GRKERNSEC
35819 ++ {
35820 ++ struct timespec timeval;
35821 ++ do_posix_clock_monotonic_gettime(&timeval);
35822 ++
35823 ++ shp->shm_createtime = timeval.tv_sec;
35824 ++ }
35825 ++#endif
35826 + shp->shm_segsz = size;
35827 + shp->shm_nattch = 0;
35828 + shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
35829 +@@ -482,6 +501,7 @@ asmlinkage long sys_shmget (key_t key, s
35830 + struct ipc_namespace *ns;
35831 + struct ipc_ops shm_ops;
35832 + struct ipc_params shm_params;
35833 ++ long err;
35834 +
35835 + ns = current->nsproxy->ipc_ns;
35836 +
35837 +@@ -493,7 +513,11 @@ asmlinkage long sys_shmget (key_t key, s
35838 + shm_params.flg = shmflg;
35839 + shm_params.u.size = size;
35840 +
35841 +- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
35842 ++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
35843 ++
35844 ++ gr_log_shmget(err, shmflg, size);
35845 ++
35846 ++ return err;
35847 + }
35848 +
35849 + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
35850 +@@ -959,9 +983,21 @@ long do_shmat(int shmid, char __user *sh
35851 + if (err)
35852 + goto out_unlock;
35853 +
35854 ++#ifdef CONFIG_GRKERNSEC
35855 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
35856 ++ shp->shm_perm.cuid, shmid) ||
35857 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
35858 ++ err = -EACCES;
35859 ++ goto out_unlock;
35860 ++ }
35861 ++#endif
35862 ++
35863 + path.dentry = dget(shp->shm_file->f_path.dentry);
35864 + path.mnt = shp->shm_file->f_path.mnt;
35865 + shp->shm_nattch++;
35866 ++#ifdef CONFIG_GRKERNSEC
35867 ++ shp->shm_lapid = current->pid;
35868 ++#endif
35869 + size = i_size_read(path.dentry->d_inode);
35870 + shm_unlock(shp);
35871 +
35872 +diff -urNp a/kernel/acct.c b/kernel/acct.c
35873 +--- a/kernel/acct.c 2008-08-20 11:16:13.000000000 -0700
35874 ++++ b/kernel/acct.c 2008-08-20 18:36:57.000000000 -0700
35875 +@@ -519,7 +519,7 @@ static void do_acct_process(struct pid_n
35876 + */
35877 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
35878 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
35879 +- file->f_op->write(file, (char *)&ac,
35880 ++ file->f_op->write(file, (char __user *)&ac,
35881 + sizeof(acct_t), &file->f_pos);
35882 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
35883 + set_fs(fs);
35884 +diff -urNp a/kernel/capability.c b/kernel/capability.c
35885 +--- a/kernel/capability.c 2008-08-20 11:16:13.000000000 -0700
35886 ++++ b/kernel/capability.c 2008-08-20 18:36:57.000000000 -0700
35887 +@@ -13,6 +13,7 @@
35888 + #include <linux/security.h>
35889 + #include <linux/syscalls.h>
35890 + #include <linux/pid_namespace.h>
35891 ++#include <linux/grsecurity.h>
35892 + #include <asm/uaccess.h>
35893 +
35894 + /*
35895 +@@ -363,15 +364,25 @@ out:
35896 +
35897 + int __capable(struct task_struct *t, int cap)
35898 + {
35899 +- if (security_capable(t, cap) == 0) {
35900 ++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
35901 + t->flags |= PF_SUPERPRIV;
35902 + return 1;
35903 + }
35904 + return 0;
35905 + }
35906 +
35907 ++int capable_nolog(int cap)
35908 ++{
35909 ++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
35910 ++ current->flags |= PF_SUPERPRIV;
35911 ++ return 1;
35912 ++ }
35913 ++ return 0;
35914 ++}
35915 ++
35916 + int capable(int cap)
35917 + {
35918 + return __capable(current, cap);
35919 + }
35920 + EXPORT_SYMBOL(capable);
35921 ++EXPORT_SYMBOL(capable_nolog);
35922 +diff -urNp a/kernel/configs.c b/kernel/configs.c
35923 +--- a/kernel/configs.c 2008-08-20 11:16:13.000000000 -0700
35924 ++++ b/kernel/configs.c 2008-08-20 18:36:57.000000000 -0700
35925 +@@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
35926 + struct proc_dir_entry *entry;
35927 +
35928 + /* create the current config file */
35929 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
35930 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
35931 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
35932 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
35933 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
35934 ++#endif
35935 ++#else
35936 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
35937 + &proc_root);
35938 ++#endif
35939 + if (!entry)
35940 + return -ENOMEM;
35941 +
35942 +diff -urNp a/kernel/cpu.c b/kernel/cpu.c
35943 +--- a/kernel/cpu.c 2008-08-20 11:16:13.000000000 -0700
35944 ++++ b/kernel/cpu.c 2008-08-20 18:36:57.000000000 -0700
35945 +@@ -18,7 +18,7 @@
35946 + /* Serializes the updates to cpu_online_map, cpu_present_map */
35947 + static DEFINE_MUTEX(cpu_add_remove_lock);
35948 +
35949 +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
35950 ++static RAW_NOTIFIER_HEAD(cpu_chain);
35951 +
35952 + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
35953 + * Should always be manipulated under cpu_add_remove_lock
35954 +@@ -136,7 +136,7 @@ static void cpu_hotplug_done(void)
35955 + mutex_unlock(&cpu_hotplug.lock);
35956 + }
35957 + /* Need to know about CPUs going up/down? */
35958 +-int __cpuinit register_cpu_notifier(struct notifier_block *nb)
35959 ++int register_cpu_notifier(struct notifier_block *nb)
35960 + {
35961 + int ret;
35962 + cpu_maps_update_begin();
35963 +diff -urNp a/kernel/exit.c b/kernel/exit.c
35964 +--- a/kernel/exit.c 2008-08-20 11:16:13.000000000 -0700
35965 ++++ b/kernel/exit.c 2008-08-20 18:36:57.000000000 -0700
35966 +@@ -44,6 +44,11 @@
35967 + #include <linux/resource.h>
35968 + #include <linux/blkdev.h>
35969 + #include <linux/task_io_accounting_ops.h>
35970 ++#include <linux/grsecurity.h>
35971 ++
35972 ++#ifdef CONFIG_GRKERNSEC
35973 ++extern rwlock_t grsec_exec_file_lock;
35974 ++#endif
35975 +
35976 + #include <asm/uaccess.h>
35977 + #include <asm/unistd.h>
35978 +@@ -120,6 +125,7 @@ static void __exit_signal(struct task_st
35979 +
35980 + __unhash_process(tsk);
35981 +
35982 ++ gr_del_task_from_ip_table(tsk);
35983 + tsk->signal = NULL;
35984 + tsk->sighand = NULL;
35985 + spin_unlock(&sighand->siglock);
35986 +@@ -301,12 +307,23 @@ static void reparent_to_kthreadd(void)
35987 + {
35988 + write_lock_irq(&tasklist_lock);
35989 +
35990 ++#ifdef CONFIG_GRKERNSEC
35991 ++ write_lock(&grsec_exec_file_lock);
35992 ++ if (current->exec_file) {
35993 ++ fput(current->exec_file);
35994 ++ current->exec_file = NULL;
35995 ++ }
35996 ++ write_unlock(&grsec_exec_file_lock);
35997 ++#endif
35998 ++
35999 + ptrace_unlink(current);
36000 + /* Reparent to init */
36001 + remove_parent(current);
36002 + current->real_parent = current->parent = kthreadd_task;
36003 + add_parent(current);
36004 +
36005 ++ gr_set_kernel_label(current);
36006 ++
36007 + /* Set the exit signal to SIGCHLD so we signal init on exit */
36008 + current->exit_signal = SIGCHLD;
36009 +
36010 +@@ -402,6 +419,17 @@ void daemonize(const char *name, ...)
36011 + vsnprintf(current->comm, sizeof(current->comm), name, args);
36012 + va_end(args);
36013 +
36014 ++#ifdef CONFIG_GRKERNSEC
36015 ++ write_lock(&grsec_exec_file_lock);
36016 ++ if (current->exec_file) {
36017 ++ fput(current->exec_file);
36018 ++ current->exec_file = NULL;
36019 ++ }
36020 ++ write_unlock(&grsec_exec_file_lock);
36021 ++#endif
36022 ++
36023 ++ gr_set_kernel_label(current);
36024 ++
36025 + /*
36026 + * If we were started as result of loading a module, close all of the
36027 + * user space pages. We don't need them, and if we didn't close them
36028 +@@ -962,6 +990,9 @@ NORET_TYPE void do_exit(long code)
36029 + tsk->exit_code = code;
36030 + taskstats_exit(tsk, group_dead);
36031 +
36032 ++ gr_acl_handle_psacct(tsk, code);
36033 ++ gr_acl_handle_exit();
36034 ++
36035 + exit_mm(tsk);
36036 +
36037 + if (group_dead)
36038 +@@ -1171,7 +1202,7 @@ static int wait_task_zombie(struct task_
36039 + if (unlikely(noreap)) {
36040 + uid_t uid = p->uid;
36041 + int exit_code = p->exit_code;
36042 +- int why, status;
36043 ++ int why;
36044 +
36045 + get_task_struct(p);
36046 + read_unlock(&tasklist_lock);
36047 +diff -urNp a/kernel/fork.c b/kernel/fork.c
36048 +--- a/kernel/fork.c 2008-08-20 11:16:13.000000000 -0700
36049 ++++ b/kernel/fork.c 2008-08-20 18:36:57.000000000 -0700
36050 +@@ -53,6 +53,7 @@
36051 + #include <linux/tty.h>
36052 + #include <linux/proc_fs.h>
36053 + #include <linux/blkdev.h>
36054 ++#include <linux/grsecurity.h>
36055 +
36056 + #include <asm/pgtable.h>
36057 + #include <asm/pgalloc.h>
36058 +@@ -194,7 +195,7 @@ static struct task_struct *dup_task_stru
36059 + setup_thread_stack(tsk, orig);
36060 +
36061 + #ifdef CONFIG_CC_STACKPROTECTOR
36062 +- tsk->stack_canary = get_random_int();
36063 ++ tsk->stack_canary = pax_get_random_long();
36064 + #endif
36065 +
36066 + /* One for us, one for whoever does the "release_task()" (usually parent) */
36067 +@@ -226,8 +227,8 @@ static int dup_mmap(struct mm_struct *mm
36068 + mm->locked_vm = 0;
36069 + mm->mmap = NULL;
36070 + mm->mmap_cache = NULL;
36071 +- mm->free_area_cache = oldmm->mmap_base;
36072 +- mm->cached_hole_size = ~0UL;
36073 ++ mm->free_area_cache = oldmm->free_area_cache;
36074 ++ mm->cached_hole_size = oldmm->cached_hole_size;
36075 + mm->map_count = 0;
36076 + cpus_clear(mm->cpu_vm_mask);
36077 + mm->mm_rb = RB_ROOT;
36078 +@@ -264,6 +265,7 @@ static int dup_mmap(struct mm_struct *mm
36079 + tmp->vm_flags &= ~VM_LOCKED;
36080 + tmp->vm_mm = mm;
36081 + tmp->vm_next = NULL;
36082 ++ tmp->vm_mirror = NULL;
36083 + anon_vma_link(tmp);
36084 + file = tmp->vm_file;
36085 + if (file) {
36086 +@@ -300,6 +302,31 @@ static int dup_mmap(struct mm_struct *mm
36087 + if (retval)
36088 + goto out;
36089 + }
36090 ++
36091 ++#ifdef CONFIG_PAX_SEGMEXEC
36092 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
36093 ++ struct vm_area_struct *mpnt_m;
36094 ++
36095 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
36096 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
36097 ++
36098 ++ if (!mpnt->vm_mirror)
36099 ++ continue;
36100 ++
36101 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
36102 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
36103 ++ mpnt->vm_mirror = mpnt_m;
36104 ++ } else {
36105 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
36106 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
36107 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
36108 ++ mpnt->vm_mirror->vm_mirror = mpnt;
36109 ++ }
36110 ++ }
36111 ++ BUG_ON(mpnt_m);
36112 ++ }
36113 ++#endif
36114 ++
36115 + /* a new mm has just been created */
36116 + arch_dup_mmap(oldmm, mm);
36117 + retval = 0;
36118 +@@ -482,7 +509,7 @@ void mm_release(struct task_struct *tsk,
36119 + if (tsk->clear_child_tid
36120 + && !(tsk->flags & PF_SIGNALED)
36121 + && atomic_read(&mm->mm_users) > 1) {
36122 +- u32 __user * tidptr = tsk->clear_child_tid;
36123 ++ pid_t __user * tidptr = tsk->clear_child_tid;
36124 + tsk->clear_child_tid = NULL;
36125 +
36126 + /*
36127 +@@ -490,7 +517,7 @@ void mm_release(struct task_struct *tsk,
36128 + * not set up a proper pointer then tough luck.
36129 + */
36130 + put_user(0, tidptr);
36131 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
36132 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
36133 + }
36134 + }
36135 +
36136 +@@ -1046,6 +1073,9 @@ static struct task_struct *copy_process(
36137 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
36138 + #endif
36139 + retval = -EAGAIN;
36140 ++
36141 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
36142 ++
36143 + if (atomic_read(&p->user->processes) >=
36144 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
36145 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
36146 +@@ -1212,6 +1242,8 @@ static struct task_struct *copy_process(
36147 + if (clone_flags & CLONE_THREAD)
36148 + p->tgid = current->tgid;
36149 +
36150 ++ gr_copy_label(p);
36151 ++
36152 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
36153 + /*
36154 + * Clear TID on mm_release()?
36155 +@@ -1401,6 +1433,8 @@ bad_fork_cleanup_count:
36156 + bad_fork_free:
36157 + free_task(p);
36158 + fork_out:
36159 ++ gr_log_forkfail(retval);
36160 ++
36161 + return ERR_PTR(retval);
36162 + }
36163 +
36164 +@@ -1493,6 +1527,8 @@ long do_fork(unsigned long clone_flags,
36165 + if (clone_flags & CLONE_PARENT_SETTID)
36166 + put_user(nr, parent_tidptr);
36167 +
36168 ++ gr_handle_brute_check();
36169 ++
36170 + if (clone_flags & CLONE_VFORK) {
36171 + p->vfork_done = &vfork;
36172 + init_completion(&vfork);
36173 +diff -urNp a/kernel/futex.c b/kernel/futex.c
36174 +--- a/kernel/futex.c 2008-08-20 11:16:13.000000000 -0700
36175 ++++ b/kernel/futex.c 2008-08-20 18:36:57.000000000 -0700
36176 +@@ -195,6 +195,11 @@ static int get_futex_key(u32 __user *uad
36177 + struct page *page;
36178 + int err;
36179 +
36180 ++#ifdef CONFIG_PAX_SEGMEXEC
36181 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
36182 ++ return -EFAULT;
36183 ++#endif
36184 ++
36185 + /*
36186 + * The futex address must be "naturally" aligned.
36187 + */
36188 +@@ -221,8 +226,8 @@ static int get_futex_key(u32 __user *uad
36189 + * The futex is hashed differently depending on whether
36190 + * it's in a shared or private mapping. So check vma first.
36191 + */
36192 +- vma = find_extend_vma(mm, address);
36193 +- if (unlikely(!vma))
36194 ++ vma = find_vma(mm, address);
36195 ++ if (unlikely(!vma || address < vma->vm_start))
36196 + return -EFAULT;
36197 +
36198 + /*
36199 +@@ -2032,7 +2037,7 @@ retry:
36200 + */
36201 + static inline int fetch_robust_entry(struct robust_list __user **entry,
36202 + struct robust_list __user * __user *head,
36203 +- int *pi)
36204 ++ unsigned int *pi)
36205 + {
36206 + unsigned long uentry;
36207 +
36208 +diff -urNp a/kernel/irq/handle.c b/kernel/irq/handle.c
36209 +--- a/kernel/irq/handle.c 2008-08-20 11:16:13.000000000 -0700
36210 ++++ b/kernel/irq/handle.c 2008-08-20 18:36:57.000000000 -0700
36211 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
36212 + .depth = 1,
36213 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
36214 + #ifdef CONFIG_SMP
36215 +- .affinity = CPU_MASK_ALL
36216 ++ .affinity = CPU_MASK_ALL,
36217 ++ .cpu = 0,
36218 + #endif
36219 + }
36220 + };
36221 +diff -urNp a/kernel/kallsyms.c b/kernel/kallsyms.c
36222 +--- a/kernel/kallsyms.c 2008-08-20 11:16:13.000000000 -0700
36223 ++++ b/kernel/kallsyms.c 2008-08-20 18:36:57.000000000 -0700
36224 +@@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
36225 +
36226 + static inline int is_kernel(unsigned long addr)
36227 + {
36228 ++
36229 ++#ifdef CONFIG_PAX_KERNEXEC
36230 ++
36231 ++#ifdef CONFIG_MODULES
36232 ++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
36233 ++ ktla_ktva(addr) < (unsigned long)MODULES_END)
36234 ++ return 0;
36235 ++#endif
36236 ++
36237 ++ if (is_kernel_inittext(addr))
36238 ++ return 1;
36239 ++#endif
36240 ++
36241 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
36242 + return 1;
36243 + return in_gate_area_no_task(addr);
36244 +@@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
36245 +
36246 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
36247 + {
36248 +- iter->name[0] = '\0';
36249 + iter->nameoff = get_symbol_offset(new_pos);
36250 + iter->pos = new_pos;
36251 + }
36252 +@@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
36253 + struct kallsym_iter *iter;
36254 + int ret;
36255 +
36256 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
36257 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
36258 + if (!iter)
36259 + return -ENOMEM;
36260 + reset_iter(iter, 0);
36261 +@@ -474,7 +486,15 @@ static int __init kallsyms_init(void)
36262 + {
36263 + struct proc_dir_entry *entry;
36264 +
36265 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
36266 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
36267 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
36268 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36269 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
36270 ++#endif
36271 ++#else
36272 + entry = create_proc_entry("kallsyms", 0444, NULL);
36273 ++#endif
36274 + if (entry)
36275 + entry->proc_fops = &kallsyms_operations;
36276 + return 0;
36277 +diff -urNp a/kernel/kmod.c b/kernel/kmod.c
36278 +--- a/kernel/kmod.c 2008-08-20 11:16:13.000000000 -0700
36279 ++++ b/kernel/kmod.c 2008-08-20 18:36:57.000000000 -0700
36280 +@@ -107,7 +107,7 @@ int request_module(const char *fmt, ...)
36281 + return -ENOMEM;
36282 + }
36283 +
36284 +- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
36285 ++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
36286 + atomic_dec(&kmod_concurrent);
36287 + return ret;
36288 + }
36289 +diff -urNp a/kernel/kprobes.c b/kernel/kprobes.c
36290 +--- a/kernel/kprobes.c 2008-08-20 11:16:13.000000000 -0700
36291 ++++ b/kernel/kprobes.c 2008-08-20 18:36:57.000000000 -0700
36292 +@@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
36293 + * kernel image and loaded module images reside. This is required
36294 + * so x86_64 can correctly handle the %rip-relative fixups.
36295 + */
36296 +- kip->insns = module_alloc(PAGE_SIZE);
36297 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
36298 + if (!kip->insns) {
36299 + kfree(kip);
36300 + return NULL;
36301 +@@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
36302 + hlist_add_head(&kip->hlist,
36303 + &kprobe_insn_pages);
36304 + } else {
36305 +- module_free(NULL, kip->insns);
36306 ++ module_free_exec(NULL, kip->insns);
36307 + kfree(kip);
36308 + }
36309 + return 1;
36310 +diff -urNp a/kernel/lockdep.c b/kernel/lockdep.c
36311 +--- a/kernel/lockdep.c 2008-08-20 11:16:13.000000000 -0700
36312 ++++ b/kernel/lockdep.c 2008-08-20 18:36:57.000000000 -0700
36313 +@@ -598,6 +598,10 @@ static int static_obj(void *obj)
36314 + int i;
36315 + #endif
36316 +
36317 ++#ifdef CONFIG_PAX_KERNEXEC
36318 ++ start = (unsigned long )&_data;
36319 ++#endif
36320 ++
36321 + /*
36322 + * static variable?
36323 + */
36324 +@@ -609,9 +613,12 @@ static int static_obj(void *obj)
36325 + * percpu var?
36326 + */
36327 + for_each_possible_cpu(i) {
36328 ++#ifdef CONFIG_X86_32
36329 ++ start = per_cpu_offset(i);
36330 ++#else
36331 + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
36332 +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
36333 +- + per_cpu_offset(i);
36334 ++#endif
36335 ++ end = start + PERCPU_ENOUGH_ROOM;
36336 +
36337 + if ((addr >= start) && (addr < end))
36338 + return 1;
36339 +diff -urNp a/kernel/module.c b/kernel/module.c
36340 +--- a/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
36341 ++++ b/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
36342 +@@ -45,6 +45,11 @@
36343 + #include <asm/uaccess.h>
36344 + #include <asm/semaphore.h>
36345 + #include <asm/cacheflush.h>
36346 ++
36347 ++#ifdef CONFIG_PAX_KERNEXEC
36348 ++#include <asm/desc.h>
36349 ++#endif
36350 ++
36351 + #include <linux/license.h>
36352 + #include <asm/sections.h>
36353 +
36354 +@@ -71,6 +76,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
36355 +
36356 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
36357 +
36358 ++extern int gr_check_modstop(void);
36359 ++
36360 + int register_module_notifier(struct notifier_block * nb)
36361 + {
36362 + return blocking_notifier_chain_register(&module_notify_list, nb);
36363 +@@ -344,6 +351,8 @@ static inline unsigned int block_size(in
36364 + return val;
36365 + }
36366 +
36367 ++EXPORT_SYMBOL(__per_cpu_start);
36368 ++
36369 + static void *percpu_modalloc(unsigned long size, unsigned long align,
36370 + const char *name)
36371 + {
36372 +@@ -351,7 +360,7 @@ static void *percpu_modalloc(unsigned lo
36373 + unsigned int i;
36374 + void *ptr;
36375 +
36376 +- if (align > PAGE_SIZE) {
36377 ++ if (align-1 >= PAGE_SIZE) {
36378 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
36379 + name, align, PAGE_SIZE);
36380 + align = PAGE_SIZE;
36381 +@@ -433,7 +442,11 @@ static void percpu_modcopy(void *pcpudes
36382 + int cpu;
36383 +
36384 + for_each_possible_cpu(cpu)
36385 ++#ifdef CONFIG_X86_32
36386 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
36387 ++#else
36388 + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
36389 ++#endif
36390 + }
36391 +
36392 + static int percpu_modinit(void)
36393 +@@ -684,6 +697,9 @@ sys_delete_module(const char __user *nam
36394 + char name[MODULE_NAME_LEN];
36395 + int ret, forced = 0;
36396 +
36397 ++ if (gr_check_modstop())
36398 ++ return -EPERM;
36399 ++
36400 + if (!capable(CAP_SYS_MODULE))
36401 + return -EPERM;
36402 +
36403 +@@ -1347,16 +1363,19 @@ static void free_module(struct module *m
36404 + module_unload_free(mod);
36405 +
36406 + /* This may be NULL, but that's OK */
36407 +- module_free(mod, mod->module_init);
36408 ++ module_free(mod, mod->module_init_rw);
36409 ++ module_free_exec(mod, mod->module_init_rx);
36410 + kfree(mod->args);
36411 + if (mod->percpu)
36412 + percpu_modfree(mod->percpu);
36413 +
36414 + /* Free lock-classes: */
36415 +- lockdep_free_key_range(mod->module_core, mod->core_size);
36416 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
36417 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
36418 +
36419 + /* Finally, free the core (containing the module structure) */
36420 +- module_free(mod, mod->module_core);
36421 ++ module_free_exec(mod, mod->module_core_rx);
36422 ++ module_free(mod, mod->module_core_rw);
36423 + }
36424 +
36425 + void *__symbol_get(const char *symbol)
36426 +@@ -1421,10 +1440,14 @@ static int simplify_symbols(Elf_Shdr *se
36427 + struct module *mod)
36428 + {
36429 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
36430 +- unsigned long secbase;
36431 ++ unsigned long secbase, symbol;
36432 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
36433 + int ret = 0;
36434 +
36435 ++#ifdef CONFIG_PAX_KERNEXEC
36436 ++ unsigned long cr0;
36437 ++#endif
36438 ++
36439 + for (i = 1; i < n; i++) {
36440 + switch (sym[i].st_shndx) {
36441 + case SHN_COMMON:
36442 +@@ -1443,10 +1466,19 @@ static int simplify_symbols(Elf_Shdr *se
36443 + break;
36444 +
36445 + case SHN_UNDEF:
36446 +- sym[i].st_value
36447 +- = resolve_symbol(sechdrs, versindex,
36448 ++ symbol = resolve_symbol(sechdrs, versindex,
36449 + strtab + sym[i].st_name, mod);
36450 +
36451 ++#ifdef CONFIG_PAX_KERNEXEC
36452 ++ pax_open_kernel(cr0);
36453 ++#endif
36454 ++
36455 ++ sym[i].st_value = symbol;
36456 ++
36457 ++#ifdef CONFIG_PAX_KERNEXEC
36458 ++ pax_close_kernel(cr0);
36459 ++#endif
36460 ++
36461 + /* Ok if resolved. */
36462 + if (!IS_ERR_VALUE(sym[i].st_value))
36463 + break;
36464 +@@ -1461,11 +1493,27 @@ static int simplify_symbols(Elf_Shdr *se
36465 +
36466 + default:
36467 + /* Divert to percpu allocation if a percpu var. */
36468 +- if (sym[i].st_shndx == pcpuindex)
36469 ++ if (sym[i].st_shndx == pcpuindex) {
36470 ++
36471 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
36472 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
36473 ++#else
36474 + secbase = (unsigned long)mod->percpu;
36475 +- else
36476 ++#endif
36477 ++
36478 ++ } else
36479 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
36480 ++
36481 ++#ifdef CONFIG_PAX_KERNEXEC
36482 ++ pax_open_kernel(cr0);
36483 ++#endif
36484 ++
36485 + sym[i].st_value += secbase;
36486 ++
36487 ++#ifdef CONFIG_PAX_KERNEXEC
36488 ++ pax_close_kernel(cr0);
36489 ++#endif
36490 ++
36491 + break;
36492 + }
36493 + }
36494 +@@ -1517,11 +1565,14 @@ static void layout_sections(struct modul
36495 + || strncmp(secstrings + s->sh_name,
36496 + ".init", 5) == 0)
36497 + continue;
36498 +- s->sh_entsize = get_offset(&mod->core_size, s);
36499 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
36500 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
36501 ++ else
36502 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
36503 + DEBUGP("\t%s\n", secstrings + s->sh_name);
36504 + }
36505 + if (m == 0)
36506 +- mod->core_text_size = mod->core_size;
36507 ++ mod->core_size_rx = mod->core_size_rx;
36508 + }
36509 +
36510 + DEBUGP("Init section allocation order:\n");
36511 +@@ -1535,12 +1586,15 @@ static void layout_sections(struct modul
36512 + || strncmp(secstrings + s->sh_name,
36513 + ".init", 5) != 0)
36514 + continue;
36515 +- s->sh_entsize = (get_offset(&mod->init_size, s)
36516 +- | INIT_OFFSET_MASK);
36517 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
36518 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
36519 ++ else
36520 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
36521 ++ s->sh_entsize |= INIT_OFFSET_MASK;
36522 + DEBUGP("\t%s\n", secstrings + s->sh_name);
36523 + }
36524 + if (m == 0)
36525 +- mod->init_text_size = mod->init_size;
36526 ++ mod->init_size_rx = mod->init_size_rx;
36527 + }
36528 + }
36529 +
36530 +@@ -1667,14 +1721,31 @@ static void add_kallsyms(struct module *
36531 + {
36532 + unsigned int i;
36533 +
36534 ++#ifdef CONFIG_PAX_KERNEXEC
36535 ++ unsigned long cr0;
36536 ++#endif
36537 ++
36538 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
36539 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
36540 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
36541 +
36542 + /* Set types up while we still have access to sections. */
36543 +- for (i = 0; i < mod->num_symtab; i++)
36544 +- mod->symtab[i].st_info
36545 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
36546 ++
36547 ++ for (i = 0; i < mod->num_symtab; i++) {
36548 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
36549 ++
36550 ++#ifdef CONFIG_PAX_KERNEXEC
36551 ++ pax_open_kernel(cr0);
36552 ++#endif
36553 ++
36554 ++ mod->symtab[i].st_info = type;
36555 ++
36556 ++#ifdef CONFIG_PAX_KERNEXEC
36557 ++ pax_close_kernel(cr0);
36558 ++#endif
36559 ++
36560 ++ }
36561 ++
36562 + }
36563 + #else
36564 + static inline void add_kallsyms(struct module *mod,
36565 +@@ -1724,6 +1795,10 @@ static struct module *load_module(void _
36566 + struct exception_table_entry *extable;
36567 + mm_segment_t old_fs;
36568 +
36569 ++#ifdef CONFIG_PAX_KERNEXEC
36570 ++ unsigned long cr0;
36571 ++#endif
36572 ++
36573 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
36574 + umod, len, uargs);
36575 + if (len < sizeof(*hdr))
36576 +@@ -1882,21 +1957,57 @@ static struct module *load_module(void _
36577 + layout_sections(mod, hdr, sechdrs, secstrings);
36578 +
36579 + /* Do the allocs. */
36580 +- ptr = module_alloc(mod->core_size);
36581 ++ ptr = module_alloc(mod->core_size_rw);
36582 + if (!ptr) {
36583 + err = -ENOMEM;
36584 + goto free_percpu;
36585 + }
36586 +- memset(ptr, 0, mod->core_size);
36587 +- mod->module_core = ptr;
36588 ++ memset(ptr, 0, mod->core_size_rw);
36589 ++ mod->module_core_rw = ptr;
36590 ++
36591 ++ ptr = module_alloc(mod->init_size_rw);
36592 ++ if (!ptr && mod->init_size_rw) {
36593 ++ err = -ENOMEM;
36594 ++ goto free_core_rw;
36595 ++ }
36596 ++ memset(ptr, 0, mod->init_size_rw);
36597 ++ mod->module_init_rw = ptr;
36598 ++
36599 ++ ptr = module_alloc_exec(mod->core_size_rx);
36600 ++ if (!ptr) {
36601 ++ err = -ENOMEM;
36602 ++ goto free_init_rw;
36603 ++ }
36604 +
36605 +- ptr = module_alloc(mod->init_size);
36606 +- if (!ptr && mod->init_size) {
36607 ++#ifdef CONFIG_PAX_KERNEXEC
36608 ++ pax_open_kernel(cr0);
36609 ++#endif
36610 ++
36611 ++ memset(ptr, 0, mod->core_size_rx);
36612 ++
36613 ++#ifdef CONFIG_PAX_KERNEXEC
36614 ++ pax_close_kernel(cr0);
36615 ++#endif
36616 ++
36617 ++ mod->module_core_rx = ptr;
36618 ++
36619 ++ ptr = module_alloc_exec(mod->init_size_rx);
36620 ++ if (!ptr && mod->init_size_rx) {
36621 + err = -ENOMEM;
36622 +- goto free_core;
36623 ++ goto free_core_rx;
36624 + }
36625 +- memset(ptr, 0, mod->init_size);
36626 +- mod->module_init = ptr;
36627 ++
36628 ++#ifdef CONFIG_PAX_KERNEXEC
36629 ++ pax_open_kernel(cr0);
36630 ++#endif
36631 ++
36632 ++ memset(ptr, 0, mod->init_size_rx);
36633 ++
36634 ++#ifdef CONFIG_PAX_KERNEXEC
36635 ++ pax_close_kernel(cr0);
36636 ++#endif
36637 ++
36638 ++ mod->module_init_rx = ptr;
36639 +
36640 + /* Transfer each section which specifies SHF_ALLOC */
36641 + DEBUGP("final section addresses:\n");
36642 +@@ -1906,17 +2017,41 @@ static struct module *load_module(void _
36643 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
36644 + continue;
36645 +
36646 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
36647 +- dest = mod->module_init
36648 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36649 +- else
36650 +- dest = mod->module_core + sechdrs[i].sh_entsize;
36651 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
36652 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
36653 ++ dest = mod->module_init_rw
36654 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36655 ++ else
36656 ++ dest = mod->module_init_rx
36657 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36658 ++ } else {
36659 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
36660 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
36661 ++ else
36662 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
36663 ++ }
36664 ++
36665 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
36666 +
36667 +- if (sechdrs[i].sh_type != SHT_NOBITS)
36668 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
36669 +- sechdrs[i].sh_size);
36670 ++#ifdef CONFIG_PAX_KERNEXEC
36671 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
36672 ++ pax_open_kernel(cr0);
36673 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
36674 ++ pax_close_kernel(cr0);
36675 ++ } else
36676 ++#endif
36677 ++
36678 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
36679 ++ }
36680 + /* Update sh_addr to point to copy in image. */
36681 +- sechdrs[i].sh_addr = (unsigned long)dest;
36682 ++
36683 ++#ifdef CONFIG_PAX_KERNEXEC
36684 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
36685 ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
36686 ++ else
36687 ++#endif
36688 ++
36689 ++ sechdrs[i].sh_addr = (unsigned long)dest;
36690 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
36691 + }
36692 + /* Module has been moved. */
36693 +@@ -2057,12 +2192,12 @@ static struct module *load_module(void _
36694 + * Do it before processing of module parameters, so the module
36695 + * can provide parameter accessor functions of its own.
36696 + */
36697 +- if (mod->module_init)
36698 +- flush_icache_range((unsigned long)mod->module_init,
36699 +- (unsigned long)mod->module_init
36700 +- + mod->init_size);
36701 +- flush_icache_range((unsigned long)mod->module_core,
36702 +- (unsigned long)mod->module_core + mod->core_size);
36703 ++ if (mod->module_init_rx)
36704 ++ flush_icache_range((unsigned long)mod->module_init_rx,
36705 ++ (unsigned long)mod->module_init_rx
36706 ++ + mod->init_size_rx);
36707 ++ flush_icache_range((unsigned long)mod->module_core_rx,
36708 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
36709 +
36710 + set_fs(old_fs);
36711 +
36712 +@@ -2115,9 +2250,13 @@ static struct module *load_module(void _
36713 + kobject_put(&mod->mkobj.kobj);
36714 + free_unload:
36715 + module_unload_free(mod);
36716 +- module_free(mod, mod->module_init);
36717 +- free_core:
36718 +- module_free(mod, mod->module_core);
36719 ++ module_free_exec(mod, mod->module_init_rx);
36720 ++ free_core_rx:
36721 ++ module_free_exec(mod, mod->module_core_rx);
36722 ++ free_init_rw:
36723 ++ module_free(mod, mod->module_init_rw);
36724 ++ free_core_rw:
36725 ++ module_free(mod, mod->module_core_rw);
36726 + free_percpu:
36727 + if (percpu)
36728 + percpu_modfree(percpu);
36729 +@@ -2142,6 +2281,9 @@ sys_init_module(void __user *umod,
36730 + struct module *mod;
36731 + int ret = 0;
36732 +
36733 ++ if (gr_check_modstop())
36734 ++ return -EPERM;
36735 ++
36736 + /* Must have permission */
36737 + if (!capable(CAP_SYS_MODULE))
36738 + return -EPERM;
36739 +@@ -2195,10 +2337,12 @@ sys_init_module(void __user *umod,
36740 + /* Drop initial reference. */
36741 + module_put(mod);
36742 + unwind_remove_table(mod->unwind_info, 1);
36743 +- module_free(mod, mod->module_init);
36744 +- mod->module_init = NULL;
36745 +- mod->init_size = 0;
36746 +- mod->init_text_size = 0;
36747 ++ module_free(mod, mod->module_init_rw);
36748 ++ module_free_exec(mod, mod->module_init_rx);
36749 ++ mod->module_init_rw = NULL;
36750 ++ mod->module_init_rx = NULL;
36751 ++ mod->init_size_rw = 0;
36752 ++ mod->init_size_rx = 0;
36753 + mutex_unlock(&module_mutex);
36754 +
36755 + return 0;
36756 +@@ -2206,6 +2350,13 @@ sys_init_module(void __user *umod,
36757 +
36758 + static inline int within(unsigned long addr, void *start, unsigned long size)
36759 + {
36760 ++
36761 ++#ifdef CONFIG_PAX_KERNEXEC
36762 ++ if (ktla_ktva(addr) >= (unsigned long)start &&
36763 ++ ktla_ktva(addr) < (unsigned long)start + size)
36764 ++ return 1;
36765 ++#endif
36766 ++
36767 + return ((void *)addr >= start && (void *)addr < start + size);
36768 + }
36769 +
36770 +@@ -2229,10 +2380,14 @@ static const char *get_ksymbol(struct mo
36771 + unsigned long nextval;
36772 +
36773 + /* At worse, next value is at end of module */
36774 +- if (within(addr, mod->module_init, mod->init_size))
36775 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
36776 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
36777 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
36778 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
36779 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
36780 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
36781 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
36782 + else
36783 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
36784 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
36785 +
36786 + /* Scan for closest preceeding symbol, and next symbol. (ELF
36787 + starts real symbols at 1). */
36788 +@@ -2277,8 +2432,10 @@ const char *module_address_lookup(unsign
36789 +
36790 + preempt_disable();
36791 + list_for_each_entry(mod, &modules, list) {
36792 +- if (within(addr, mod->module_init, mod->init_size)
36793 +- || within(addr, mod->module_core, mod->core_size)) {
36794 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36795 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36796 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36797 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36798 + if (modname)
36799 + *modname = mod->name;
36800 + ret = get_ksymbol(mod, addr, size, offset);
36801 +@@ -2300,8 +2457,10 @@ int lookup_module_symbol_name(unsigned l
36802 +
36803 + preempt_disable();
36804 + list_for_each_entry(mod, &modules, list) {
36805 +- if (within(addr, mod->module_init, mod->init_size) ||
36806 +- within(addr, mod->module_core, mod->core_size)) {
36807 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36808 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36809 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36810 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36811 + const char *sym;
36812 +
36813 + sym = get_ksymbol(mod, addr, NULL, NULL);
36814 +@@ -2324,8 +2483,10 @@ int lookup_module_symbol_attrs(unsigned
36815 +
36816 + preempt_disable();
36817 + list_for_each_entry(mod, &modules, list) {
36818 +- if (within(addr, mod->module_init, mod->init_size) ||
36819 +- within(addr, mod->module_core, mod->core_size)) {
36820 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36821 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36822 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36823 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36824 + const char *sym;
36825 +
36826 + sym = get_ksymbol(mod, addr, size, offset);
36827 +@@ -2456,7 +2617,7 @@ static int m_show(struct seq_file *m, vo
36828 + char buf[8];
36829 +
36830 + seq_printf(m, "%s %lu",
36831 +- mod->name, mod->init_size + mod->core_size);
36832 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
36833 + print_unload_info(m, mod);
36834 +
36835 + /* Informative for users. */
36836 +@@ -2465,7 +2626,7 @@ static int m_show(struct seq_file *m, vo
36837 + mod->state == MODULE_STATE_COMING ? "Loading":
36838 + "Live");
36839 + /* Used by oprofile and other similar tools. */
36840 +- seq_printf(m, " 0x%p", mod->module_core);
36841 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
36842 +
36843 + /* Taints info */
36844 + if (mod->taints)
36845 +@@ -2521,7 +2682,8 @@ int is_module_address(unsigned long addr
36846 + preempt_disable();
36847 +
36848 + list_for_each_entry(mod, &modules, list) {
36849 +- if (within(addr, mod->module_core, mod->core_size)) {
36850 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
36851 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36852 + preempt_enable();
36853 + return 1;
36854 + }
36855 +@@ -2539,8 +2701,8 @@ struct module *__module_text_address(uns
36856 + struct module *mod;
36857 +
36858 + list_for_each_entry(mod, &modules, list)
36859 +- if (within(addr, mod->module_init, mod->init_text_size)
36860 +- || within(addr, mod->module_core, mod->core_text_size))
36861 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
36862 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
36863 + return mod;
36864 + return NULL;
36865 + }
36866 +diff -urNp a/kernel/mutex.c b/kernel/mutex.c
36867 +--- a/kernel/mutex.c 2008-08-20 11:16:13.000000000 -0700
36868 ++++ b/kernel/mutex.c 2008-08-20 18:36:57.000000000 -0700
36869 +@@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
36870 + *
36871 + * This function is similar to (but not equivalent to) down().
36872 + */
36873 +-void inline __sched mutex_lock(struct mutex *lock)
36874 ++inline void __sched mutex_lock(struct mutex *lock)
36875 + {
36876 + might_sleep();
36877 + /*
36878 +diff -urNp a/kernel/panic.c b/kernel/panic.c
36879 +--- a/kernel/panic.c 2008-08-20 11:16:13.000000000 -0700
36880 ++++ b/kernel/panic.c 2008-08-20 18:36:57.000000000 -0700
36881 +@@ -323,6 +323,8 @@ EXPORT_SYMBOL(warn_on_slowpath);
36882 + */
36883 + void __stack_chk_fail(void)
36884 + {
36885 ++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
36886 ++ dump_stack();
36887 + panic("stack-protector: Kernel stack is corrupted");
36888 + }
36889 + EXPORT_SYMBOL(__stack_chk_fail);
36890 +diff -urNp a/kernel/pid.c b/kernel/pid.c
36891 +--- a/kernel/pid.c 2008-08-20 11:16:13.000000000 -0700
36892 ++++ b/kernel/pid.c 2008-08-20 18:36:57.000000000 -0700
36893 +@@ -35,6 +35,7 @@
36894 + #include <linux/pid_namespace.h>
36895 + #include <linux/init_task.h>
36896 + #include <linux/syscalls.h>
36897 ++#include <linux/grsecurity.h>
36898 +
36899 + #define pid_hashfn(nr, ns) \
36900 + hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
36901 +@@ -44,7 +45,7 @@ struct pid init_struct_pid = INIT_STRUCT
36902 +
36903 + int pid_max = PID_MAX_DEFAULT;
36904 +
36905 +-#define RESERVED_PIDS 300
36906 ++#define RESERVED_PIDS 500
36907 +
36908 + int pid_max_min = RESERVED_PIDS + 1;
36909 + int pid_max_max = PID_MAX_LIMIT;
36910 +@@ -375,7 +376,14 @@ EXPORT_SYMBOL(pid_task);
36911 + struct task_struct *find_task_by_pid_type_ns(int type, int nr,
36912 + struct pid_namespace *ns)
36913 + {
36914 +- return pid_task(find_pid_ns(nr, ns), type);
36915 ++ struct task_struct *task;
36916 ++
36917 ++ task = pid_task(find_pid_ns(nr, ns), type);
36918 ++
36919 ++ if (gr_pid_is_chrooted(task))
36920 ++ return NULL;
36921 ++
36922 ++ return task;
36923 + }
36924 +
36925 + EXPORT_SYMBOL(find_task_by_pid_type_ns);
36926 +diff -urNp a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
36927 +--- a/kernel/posix-cpu-timers.c 2008-08-20 11:16:13.000000000 -0700
36928 ++++ b/kernel/posix-cpu-timers.c 2008-08-20 18:36:57.000000000 -0700
36929 +@@ -6,6 +6,7 @@
36930 + #include <linux/posix-timers.h>
36931 + #include <asm/uaccess.h>
36932 + #include <linux/errno.h>
36933 ++#include <linux/grsecurity.h>
36934 +
36935 + static int check_clock(const clockid_t which_clock)
36936 + {
36937 +@@ -1174,6 +1175,7 @@ static void check_process_timers(struct
36938 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
36939 + return;
36940 + }
36941 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
36942 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
36943 + /*
36944 + * At the soft limit, send a SIGXCPU every second.
36945 +diff -urNp a/kernel/power/poweroff.c b/kernel/power/poweroff.c
36946 +--- a/kernel/power/poweroff.c 2008-08-20 11:16:13.000000000 -0700
36947 ++++ b/kernel/power/poweroff.c 2008-08-20 18:36:57.000000000 -0700
36948 +@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
36949 + .enable_mask = SYSRQ_ENABLE_BOOT,
36950 + };
36951 +
36952 +-static int pm_sysrq_init(void)
36953 ++static int __init pm_sysrq_init(void)
36954 + {
36955 + register_sysrq_key('o', &sysrq_poweroff_op);
36956 + return 0;
36957 +diff -urNp a/kernel/printk.c b/kernel/printk.c
36958 +--- a/kernel/printk.c 2008-08-20 11:16:13.000000000 -0700
36959 ++++ b/kernel/printk.c 2008-08-20 18:36:57.000000000 -0700
36960 +@@ -32,6 +32,7 @@
36961 + #include <linux/security.h>
36962 + #include <linux/bootmem.h>
36963 + #include <linux/syscalls.h>
36964 ++#include <linux/grsecurity.h>
36965 +
36966 + #include <asm/uaccess.h>
36967 +
36968 +@@ -299,6 +300,11 @@ int do_syslog(int type, char __user *buf
36969 + char c;
36970 + int error = 0;
36971 +
36972 ++#ifdef CONFIG_GRKERNSEC_DMESG
36973 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
36974 ++ return -EPERM;
36975 ++#endif
36976 ++
36977 + error = security_syslog(type);
36978 + if (error)
36979 + return error;
36980 +diff -urNp a/kernel/ptrace.c b/kernel/ptrace.c
36981 +--- a/kernel/ptrace.c 2008-08-20 11:16:13.000000000 -0700
36982 ++++ b/kernel/ptrace.c 2008-08-20 18:36:57.000000000 -0700
36983 +@@ -21,6 +21,7 @@
36984 + #include <linux/audit.h>
36985 + #include <linux/pid_namespace.h>
36986 + #include <linux/syscalls.h>
36987 ++#include <linux/grsecurity.h>
36988 +
36989 + #include <asm/pgtable.h>
36990 + #include <asm/uaccess.h>
36991 +@@ -140,12 +141,12 @@ int __ptrace_may_attach(struct task_stru
36992 + (current->uid != task->uid) ||
36993 + (current->gid != task->egid) ||
36994 + (current->gid != task->sgid) ||
36995 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
36996 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
36997 + return -EPERM;
36998 + smp_rmb();
36999 + if (task->mm)
37000 + dumpable = get_dumpable(task->mm);
37001 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
37002 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
37003 + return -EPERM;
37004 +
37005 + return security_ptrace(current, task);
37006 +@@ -203,7 +204,7 @@ repeat:
37007 +
37008 + /* Go */
37009 + task->ptrace |= PT_PTRACED;
37010 +- if (capable(CAP_SYS_PTRACE))
37011 ++ if (capable_nolog(CAP_SYS_PTRACE))
37012 + task->ptrace |= PT_PTRACE_CAP;
37013 +
37014 + __ptrace_link(task, current);
37015 +@@ -577,6 +578,11 @@ asmlinkage long sys_ptrace(long request,
37016 + if (ret < 0)
37017 + goto out_put_task_struct;
37018 +
37019 ++ if (gr_handle_ptrace(child, request)) {
37020 ++ ret = -EPERM;
37021 ++ goto out_put_task_struct;
37022 ++ }
37023 ++
37024 + ret = arch_ptrace(child, request, addr, data);
37025 + if (ret < 0)
37026 + goto out_put_task_struct;
37027 +diff -urNp a/kernel/relay.c b/kernel/relay.c
37028 +--- a/kernel/relay.c 2008-08-20 11:16:13.000000000 -0700
37029 ++++ b/kernel/relay.c 2008-08-20 18:36:57.000000000 -0700
37030 +@@ -1150,7 +1150,7 @@ static int subbuf_splice_actor(struct fi
37031 + return 0;
37032 +
37033 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
37034 +- if (ret < 0 || ret < total_len)
37035 ++ if ((int)ret < 0 || ret < total_len)
37036 + return ret;
37037 +
37038 + if (read_start + ret == nonpad_end)
37039 +diff -urNp a/kernel/resource.c b/kernel/resource.c
37040 +--- a/kernel/resource.c 2008-08-20 11:16:13.000000000 -0700
37041 ++++ b/kernel/resource.c 2008-08-20 18:36:57.000000000 -0700
37042 +@@ -133,10 +133,27 @@ static int __init ioresources_init(void)
37043 + {
37044 + struct proc_dir_entry *entry;
37045 +
37046 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
37047 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
37048 ++ entry = create_proc_entry("ioports", S_IRUSR, NULL);
37049 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
37050 ++ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
37051 ++#endif
37052 ++#else
37053 + entry = create_proc_entry("ioports", 0, NULL);
37054 ++#endif
37055 + if (entry)
37056 + entry->proc_fops = &proc_ioports_operations;
37057 ++
37058 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
37059 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
37060 ++ entry = create_proc_entry("iomem", S_IRUSR, NULL);
37061 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
37062 ++ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
37063 ++#endif
37064 ++#else
37065 + entry = create_proc_entry("iomem", 0, NULL);
37066 ++#endif
37067 + if (entry)
37068 + entry->proc_fops = &proc_iomem_operations;
37069 + return 0;
37070 +diff -urNp a/kernel/sched.c b/kernel/sched.c
37071 +--- a/kernel/sched.c 2008-08-20 11:16:13.000000000 -0700
37072 ++++ b/kernel/sched.c 2008-08-20 18:36:57.000000000 -0700
37073 +@@ -66,6 +66,7 @@
37074 + #include <linux/unistd.h>
37075 + #include <linux/pagemap.h>
37076 + #include <linux/hrtimer.h>
37077 ++#include <linux/grsecurity.h>
37078 +
37079 + #include <asm/tlb.h>
37080 + #include <asm/irq_regs.h>
37081 +@@ -4499,7 +4500,8 @@ asmlinkage long sys_nice(int increment)
37082 + if (nice > 19)
37083 + nice = 19;
37084 +
37085 +- if (increment < 0 && !can_nice(current, nice))
37086 ++ if (increment < 0 && (!can_nice(current, nice) ||
37087 ++ gr_handle_chroot_nice()))
37088 + return -EPERM;
37089 +
37090 + retval = security_task_setnice(current, nice);
37091 +@@ -5742,7 +5744,7 @@ static struct ctl_table sd_ctl_dir[] = {
37092 + .procname = "sched_domain",
37093 + .mode = 0555,
37094 + },
37095 +- {0, },
37096 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37097 + };
37098 +
37099 + static struct ctl_table sd_ctl_root[] = {
37100 +@@ -5752,7 +5754,7 @@ static struct ctl_table sd_ctl_root[] =
37101 + .mode = 0555,
37102 + .child = sd_ctl_dir,
37103 + },
37104 +- {0, },
37105 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37106 + };
37107 +
37108 + static struct ctl_table *sd_alloc_ctl_entry(int n)
37109 +diff -urNp a/kernel/signal.c b/kernel/signal.c
37110 +--- a/kernel/signal.c 2008-08-20 11:16:13.000000000 -0700
37111 ++++ b/kernel/signal.c 2008-08-20 18:36:57.000000000 -0700
37112 +@@ -25,6 +25,7 @@
37113 + #include <linux/capability.h>
37114 + #include <linux/freezer.h>
37115 + #include <linux/pid_namespace.h>
37116 ++#include <linux/grsecurity.h>
37117 + #include <linux/nsproxy.h>
37118 +
37119 + #include <asm/param.h>
37120 +@@ -540,7 +541,9 @@ static int check_kill_permission(int sig
37121 + && (current->euid ^ t->suid) && (current->euid ^ t->uid)
37122 + && (current->uid ^ t->suid) && (current->uid ^ t->uid)
37123 + && !capable(CAP_KILL))
37124 +- return error;
37125 ++ return error;
37126 ++ if (gr_handle_signal(t, sig))
37127 ++ return error;
37128 + }
37129 +
37130 + return security_task_kill(t, info, sig, 0);
37131 +@@ -757,7 +760,7 @@ static int __init setup_print_fatal_sign
37132 +
37133 + __setup("print-fatal-signals=", setup_print_fatal_signals);
37134 +
37135 +-static int
37136 ++int
37137 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
37138 + {
37139 + int ret = 0;
37140 +@@ -811,8 +814,12 @@ force_sig_info(int sig, struct siginfo *
37141 + }
37142 + }
37143 + ret = specific_send_sig_info(sig, info, t);
37144 ++
37145 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
37146 +
37147 ++ gr_log_signal(sig, t);
37148 ++ gr_handle_crash(t, sig);
37149 ++
37150 + return ret;
37151 + }
37152 +
37153 +@@ -1012,6 +1019,8 @@ int group_send_sig_info(int sig, struct
37154 + ret = __group_send_sig_info(sig, info, p);
37155 + unlock_task_sighand(p, &flags);
37156 + }
37157 ++ if (!ret)
37158 ++ gr_log_signal(sig, p);
37159 + }
37160 +
37161 + return ret;
37162 +diff -urNp a/kernel/softirq.c b/kernel/softirq.c
37163 +--- a/kernel/softirq.c 2008-08-20 11:16:13.000000000 -0700
37164 ++++ b/kernel/softirq.c 2008-08-20 18:36:57.000000000 -0700
37165 +@@ -475,9 +475,9 @@ void tasklet_kill(struct tasklet_struct
37166 + printk("Attempt to kill tasklet from interrupt\n");
37167 +
37168 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
37169 +- do
37170 ++ do {
37171 + yield();
37172 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
37173 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
37174 + }
37175 + tasklet_unlock_wait(t);
37176 + clear_bit(TASKLET_STATE_SCHED, &t->state);
37177 +diff -urNp a/kernel/sys.c b/kernel/sys.c
37178 +--- a/kernel/sys.c 2008-08-20 11:16:13.000000000 -0700
37179 ++++ b/kernel/sys.c 2008-08-20 18:36:57.000000000 -0700
37180 +@@ -33,6 +33,7 @@
37181 + #include <linux/task_io_accounting_ops.h>
37182 + #include <linux/seccomp.h>
37183 + #include <linux/cpu.h>
37184 ++#include <linux/grsecurity.h>
37185 +
37186 + #include <linux/compat.h>
37187 + #include <linux/syscalls.h>
37188 +@@ -119,6 +120,12 @@ static int set_one_prio(struct task_stru
37189 + error = -EACCES;
37190 + goto out;
37191 + }
37192 ++
37193 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
37194 ++ error = -EACCES;
37195 ++ goto out;
37196 ++ }
37197 ++
37198 + no_nice = security_task_setnice(p, niceval);
37199 + if (no_nice) {
37200 + error = no_nice;
37201 +@@ -175,10 +182,10 @@ asmlinkage long sys_setpriority(int whic
37202 + if ((who != current->uid) && !(user = find_user(who)))
37203 + goto out_unlock; /* No processes for this user */
37204 +
37205 +- do_each_thread(g, p)
37206 ++ do_each_thread(g, p) {
37207 + if (p->uid == who)
37208 + error = set_one_prio(p, niceval, error);
37209 +- while_each_thread(g, p);
37210 ++ } while_each_thread(g, p);
37211 + if (who != current->uid)
37212 + free_uid(user); /* For find_user() */
37213 + break;
37214 +@@ -237,13 +244,13 @@ asmlinkage long sys_getpriority(int whic
37215 + if ((who != current->uid) && !(user = find_user(who)))
37216 + goto out_unlock; /* No processes for this user */
37217 +
37218 +- do_each_thread(g, p)
37219 ++ do_each_thread(g, p) {
37220 + if (p->uid == who) {
37221 + niceval = 20 - task_nice(p);
37222 + if (niceval > retval)
37223 + retval = niceval;
37224 + }
37225 +- while_each_thread(g, p);
37226 ++ } while_each_thread(g, p);
37227 + if (who != current->uid)
37228 + free_uid(user); /* for find_user() */
37229 + break;
37230 +@@ -508,6 +515,10 @@ asmlinkage long sys_setregid(gid_t rgid,
37231 + else
37232 + return -EPERM;
37233 + }
37234 ++
37235 ++ if (gr_check_group_change(new_rgid, new_egid, -1))
37236 ++ return -EPERM;
37237 ++
37238 + if (new_egid != old_egid) {
37239 + set_dumpable(current->mm, suid_dumpable);
37240 + smp_wmb();
37241 +@@ -515,6 +526,9 @@ asmlinkage long sys_setregid(gid_t rgid,
37242 + if (rgid != (gid_t) -1 ||
37243 + (egid != (gid_t) -1 && egid != old_rgid))
37244 + current->sgid = new_egid;
37245 ++
37246 ++ gr_set_role_label(current, current->uid, new_rgid);
37247 ++
37248 + current->fsgid = new_egid;
37249 + current->egid = new_egid;
37250 + current->gid = new_rgid;
37251 +@@ -537,11 +551,17 @@ asmlinkage long sys_setgid(gid_t gid)
37252 + if (retval)
37253 + return retval;
37254 +
37255 ++ if (gr_check_group_change(gid, gid, gid))
37256 ++ return -EPERM;
37257 ++
37258 + if (capable(CAP_SETGID)) {
37259 + if (old_egid != gid) {
37260 + set_dumpable(current->mm, suid_dumpable);
37261 + smp_wmb();
37262 + }
37263 ++
37264 ++ gr_set_role_label(current, current->uid, gid);
37265 ++
37266 + current->gid = current->egid = current->sgid = current->fsgid = gid;
37267 + } else if ((gid == current->gid) || (gid == current->sgid)) {
37268 + if (old_egid != gid) {
37269 +@@ -579,6 +599,9 @@ static int set_user(uid_t new_ruid, int
37270 + set_dumpable(current->mm, suid_dumpable);
37271 + smp_wmb();
37272 + }
37273 ++
37274 ++ gr_set_role_label(current, new_ruid, current->gid);
37275 ++
37276 + current->uid = new_ruid;
37277 + return 0;
37278 + }
37279 +@@ -628,6 +651,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
37280 + return -EPERM;
37281 + }
37282 +
37283 ++ if (gr_check_user_change(new_ruid, new_euid, -1))
37284 ++ return -EPERM;
37285 ++
37286 + if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
37287 + return -EAGAIN;
37288 +
37289 +@@ -674,6 +700,12 @@ asmlinkage long sys_setuid(uid_t uid)
37290 + old_suid = current->suid;
37291 + new_suid = old_suid;
37292 +
37293 ++ if (gr_check_crash_uid(uid))
37294 ++ return -EPERM;
37295 ++
37296 ++ if (gr_check_user_change(uid, uid, uid))
37297 ++ return -EPERM;
37298 ++
37299 + if (capable(CAP_SETUID)) {
37300 + if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
37301 + return -EAGAIN;
37302 +@@ -721,6 +753,10 @@ asmlinkage long sys_setresuid(uid_t ruid
37303 + (suid != current->euid) && (suid != current->suid))
37304 + return -EPERM;
37305 + }
37306 ++
37307 ++ if (gr_check_user_change(ruid, euid, -1))
37308 ++ return -EPERM;
37309 ++
37310 + if (ruid != (uid_t) -1) {
37311 + if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
37312 + return -EAGAIN;
37313 +@@ -775,6 +811,10 @@ asmlinkage long sys_setresgid(gid_t rgid
37314 + (sgid != current->egid) && (sgid != current->sgid))
37315 + return -EPERM;
37316 + }
37317 ++
37318 ++ if (gr_check_group_change(rgid, egid, -1))
37319 ++ return -EPERM;
37320 ++
37321 + if (egid != (gid_t) -1) {
37322 + if (egid != current->egid) {
37323 + set_dumpable(current->mm, suid_dumpable);
37324 +@@ -783,8 +823,10 @@ asmlinkage long sys_setresgid(gid_t rgid
37325 + current->egid = egid;
37326 + }
37327 + current->fsgid = current->egid;
37328 +- if (rgid != (gid_t) -1)
37329 ++ if (rgid != (gid_t) -1) {
37330 ++ gr_set_role_label(current, current->uid, rgid);
37331 + current->gid = rgid;
37332 ++ }
37333 + if (sgid != (gid_t) -1)
37334 + current->sgid = sgid;
37335 +
37336 +@@ -819,6 +861,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
37337 + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
37338 + return old_fsuid;
37339 +
37340 ++ if (gr_check_user_change(-1, -1, uid))
37341 ++ return old_fsuid;
37342 ++
37343 + if (uid == current->uid || uid == current->euid ||
37344 + uid == current->suid || uid == current->fsuid ||
37345 + capable(CAP_SETUID)) {
37346 +@@ -851,6 +896,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
37347 + if (gid == current->gid || gid == current->egid ||
37348 + gid == current->sgid || gid == current->fsgid ||
37349 + capable(CAP_SETGID)) {
37350 ++ if (gr_check_group_change(-1, -1, gid))
37351 ++ return old_fsgid;
37352 ++
37353 + if (gid != old_fsgid) {
37354 + set_dumpable(current->mm, suid_dumpable);
37355 + smp_wmb();
37356 +@@ -932,7 +980,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
37357 + write_lock_irq(&tasklist_lock);
37358 +
37359 + err = -ESRCH;
37360 +- p = find_task_by_vpid(pid);
37361 ++ /* grsec: replaced find_task_by_vpid with equivalent call which
37362 ++ lacks the chroot restriction
37363 ++ */
37364 ++ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
37365 + if (!p)
37366 + goto out;
37367 +
37368 +@@ -1647,7 +1698,7 @@ asmlinkage long sys_prctl(int option, un
37369 + error = get_dumpable(current->mm);
37370 + break;
37371 + case PR_SET_DUMPABLE:
37372 +- if (arg2 < 0 || arg2 > 1) {
37373 ++ if (arg2 > 1) {
37374 + error = -EINVAL;
37375 + break;
37376 + }
37377 +diff -urNp a/kernel/sysctl.c b/kernel/sysctl.c
37378 +--- a/kernel/sysctl.c 2008-08-20 11:16:13.000000000 -0700
37379 ++++ b/kernel/sysctl.c 2008-08-20 18:36:57.000000000 -0700
37380 +@@ -58,6 +58,13 @@
37381 + static int deprecated_sysctl_warning(struct __sysctl_args *args);
37382 +
37383 + #if defined(CONFIG_SYSCTL)
37384 ++#include <linux/grsecurity.h>
37385 ++#include <linux/grinternal.h>
37386 ++
37387 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
37388 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
37389 ++ const int op);
37390 ++extern int gr_handle_chroot_sysctl(const int op);
37391 +
37392 + /* External variables not in a header file. */
37393 + extern int C_A_D;
37394 +@@ -156,6 +163,7 @@ static int proc_do_cad_pid(struct ctl_ta
37395 + static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
37396 + void __user *buffer, size_t *lenp, loff_t *ppos);
37397 + #endif
37398 ++extern ctl_table grsecurity_table[];
37399 +
37400 + static struct ctl_table root_table[];
37401 + static struct ctl_table_root sysctl_table_root;
37402 +@@ -183,6 +191,21 @@ extern struct ctl_table inotify_table[];
37403 + int sysctl_legacy_va_layout;
37404 + #endif
37405 +
37406 ++#ifdef CONFIG_PAX_SOFTMODE
37407 ++static ctl_table pax_table[] = {
37408 ++ {
37409 ++ .ctl_name = CTL_UNNUMBERED,
37410 ++ .procname = "softmode",
37411 ++ .data = &pax_softmode,
37412 ++ .maxlen = sizeof(unsigned int),
37413 ++ .mode = 0600,
37414 ++ .proc_handler = &proc_dointvec,
37415 ++ },
37416 ++
37417 ++ { .ctl_name = 0 }
37418 ++};
37419 ++#endif
37420 ++
37421 + extern int prove_locking;
37422 + extern int lock_stat;
37423 +
37424 +@@ -219,6 +242,7 @@ static struct ctl_table root_table[] = {
37425 + .mode = 0555,
37426 + .child = dev_table,
37427 + },
37428 ++
37429 + /*
37430 + * NOTE: do not add new entries to this table unless you have read
37431 + * Documentation/sysctl/ctl_unnumbered.txt
37432 +@@ -820,6 +844,24 @@ static struct ctl_table kern_table[] = {
37433 + .proc_handler = &proc_dostring,
37434 + .strategy = &sysctl_string,
37435 + },
37436 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
37437 ++ {
37438 ++ .ctl_name = CTL_UNNUMBERED,
37439 ++ .procname = "grsecurity",
37440 ++ .mode = 0500,
37441 ++ .child = grsecurity_table,
37442 ++ },
37443 ++#endif
37444 ++
37445 ++#ifdef CONFIG_PAX_SOFTMODE
37446 ++ {
37447 ++ .ctl_name = CTL_UNNUMBERED,
37448 ++ .procname = "pax",
37449 ++ .mode = 0500,
37450 ++ .child = pax_table,
37451 ++ },
37452 ++#endif
37453 ++
37454 + /*
37455 + * NOTE: do not add new entries to this table unless you have read
37456 + * Documentation/sysctl/ctl_unnumbered.txt
37457 +@@ -1507,6 +1549,25 @@ static int test_perm(int mode, int op)
37458 + int sysctl_perm(struct ctl_table *table, int op)
37459 + {
37460 + int error;
37461 ++ if (table->parent != NULL && table->parent->procname != NULL &&
37462 ++ table->procname != NULL &&
37463 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
37464 ++ return -EACCES;
37465 ++ if (gr_handle_chroot_sysctl(op))
37466 ++ return -EACCES;
37467 ++ error = gr_handle_sysctl(table, op);
37468 ++ if (error)
37469 ++ return error;
37470 ++ error = security_sysctl(table, op);
37471 ++ if (error)
37472 ++ return error;
37473 ++ return test_perm(table->mode, op);
37474 ++}
37475 ++
37476 ++int sysctl_perm_nochk(ctl_table *table, int op)
37477 ++{
37478 ++ int error;
37479 ++
37480 + error = security_sysctl(table, op);
37481 + if (error)
37482 + return error;
37483 +@@ -1531,13 +1592,14 @@ repeat:
37484 + if (n == table->ctl_name) {
37485 + int error;
37486 + if (table->child) {
37487 +- if (sysctl_perm(table, 001))
37488 ++ if (sysctl_perm_nochk(table, 001))
37489 + return -EPERM;
37490 + name++;
37491 + nlen--;
37492 + table = table->child;
37493 + goto repeat;
37494 + }
37495 ++
37496 + error = do_sysctl_strategy(table, name, nlen,
37497 + oldval, oldlenp,
37498 + newval, newlen);
37499 +diff -urNp a/kernel/time.c b/kernel/time.c
37500 +--- a/kernel/time.c 2008-08-20 11:16:13.000000000 -0700
37501 ++++ b/kernel/time.c 2008-08-20 18:36:57.000000000 -0700
37502 +@@ -35,6 +35,7 @@
37503 + #include <linux/syscalls.h>
37504 + #include <linux/security.h>
37505 + #include <linux/fs.h>
37506 ++#include <linux/grsecurity.h>
37507 +
37508 + #include <asm/uaccess.h>
37509 + #include <asm/unistd.h>
37510 +@@ -90,6 +91,9 @@ asmlinkage long sys_stime(time_t __user
37511 + return err;
37512 +
37513 + do_settimeofday(&tv);
37514 ++
37515 ++ gr_log_timechange();
37516 ++
37517 + return 0;
37518 + }
37519 +
37520 +@@ -198,6 +202,8 @@ asmlinkage long sys_settimeofday(struct
37521 + return -EFAULT;
37522 + }
37523 +
37524 ++ gr_log_timechange();
37525 ++
37526 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
37527 + }
37528 +
37529 +@@ -236,7 +242,7 @@ EXPORT_SYMBOL(current_fs_time);
37530 + * Avoid unnecessary multiplications/divisions in the
37531 + * two most common HZ cases:
37532 + */
37533 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
37534 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
37535 + {
37536 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
37537 + return (MSEC_PER_SEC / HZ) * j;
37538 +@@ -252,7 +258,7 @@ unsigned int inline jiffies_to_msecs(con
37539 + }
37540 + EXPORT_SYMBOL(jiffies_to_msecs);
37541 +
37542 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
37543 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
37544 + {
37545 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
37546 + return (USEC_PER_SEC / HZ) * j;
37547 +diff -urNp a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c
37548 +--- a/kernel/utsname_sysctl.c 2008-08-20 11:16:13.000000000 -0700
37549 ++++ b/kernel/utsname_sysctl.c 2008-08-20 18:36:57.000000000 -0700
37550 +@@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
37551 + .proc_handler = proc_do_uts_string,
37552 + .strategy = sysctl_uts_string,
37553 + },
37554 +- {}
37555 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37556 + };
37557 +
37558 + static struct ctl_table uts_root_table[] = {
37559 +@@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
37560 + .mode = 0555,
37561 + .child = uts_kern_table,
37562 + },
37563 +- {}
37564 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37565 + };
37566 +
37567 + static int __init utsname_sysctl_init(void)
37568 +diff -urNp a/lib/radix-tree.c b/lib/radix-tree.c
37569 +--- a/lib/radix-tree.c 2008-08-20 11:16:13.000000000 -0700
37570 ++++ b/lib/radix-tree.c 2008-08-20 18:36:57.000000000 -0700
37571 +@@ -81,7 +81,7 @@ struct radix_tree_preload {
37572 + int nr;
37573 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
37574 + };
37575 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
37576 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
37577 +
37578 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
37579 + {
37580 +diff -urNp a/localversion-grsec b/localversion-grsec
37581 +--- a/localversion-grsec 1969-12-31 16:00:00.000000000 -0800
37582 ++++ b/localversion-grsec 2008-08-20 18:36:57.000000000 -0700
37583 +@@ -0,0 +1 @@
37584 ++-grsec
37585 +diff -urNp a/mm/filemap.c b/mm/filemap.c
37586 +--- a/mm/filemap.c 2008-08-20 11:16:13.000000000 -0700
37587 ++++ b/mm/filemap.c 2008-08-20 18:36:57.000000000 -0700
37588 +@@ -33,6 +33,7 @@
37589 + #include <linux/cpuset.h>
37590 + #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
37591 + #include <linux/memcontrol.h>
37592 ++#include <linux/grsecurity.h>
37593 + #include "internal.h"
37594 +
37595 + /*
37596 +@@ -1481,7 +1482,7 @@ int generic_file_mmap(struct file * file
37597 + struct address_space *mapping = file->f_mapping;
37598 +
37599 + if (!mapping->a_ops->readpage)
37600 +- return -ENOEXEC;
37601 ++ return -ENODEV;
37602 + file_accessed(file);
37603 + vma->vm_ops = &generic_file_vm_ops;
37604 + vma->vm_flags |= VM_CAN_NONLINEAR;
37605 +@@ -1841,6 +1842,7 @@ inline int generic_write_checks(struct f
37606 + *pos = i_size_read(inode);
37607 +
37608 + if (limit != RLIM_INFINITY) {
37609 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
37610 + if (*pos >= limit) {
37611 + send_sig(SIGXFSZ, current, 0);
37612 + return -EFBIG;
37613 +diff -urNp a/mm/fremap.c b/mm/fremap.c
37614 +--- a/mm/fremap.c 2008-08-20 11:16:13.000000000 -0700
37615 ++++ b/mm/fremap.c 2008-08-20 18:36:57.000000000 -0700
37616 +@@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
37617 + retry:
37618 + vma = find_vma(mm, start);
37619 +
37620 ++#ifdef CONFIG_PAX_SEGMEXEC
37621 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
37622 ++ up_read(&mm->mmap_sem);
37623 ++ return err;
37624 ++ }
37625 ++#endif
37626 ++
37627 + /*
37628 + * Make sure the vma is shared, that it supports prefaulting,
37629 + * and that the remapped range is valid and fully within
37630 +diff -urNp a/mm/hugetlb.c b/mm/hugetlb.c
37631 +--- a/mm/hugetlb.c 2008-08-20 11:16:13.000000000 -0700
37632 ++++ b/mm/hugetlb.c 2008-08-20 18:36:57.000000000 -0700
37633 +@@ -847,6 +847,26 @@ void unmap_hugepage_range(struct vm_area
37634 + }
37635 + }
37636 +
37637 ++#ifdef CONFIG_PAX_SEGMEXEC
37638 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
37639 ++{
37640 ++ struct mm_struct *mm = vma->vm_mm;
37641 ++ struct vm_area_struct *vma_m;
37642 ++ unsigned long address_m;
37643 ++ pte_t *ptep_m;
37644 ++
37645 ++ vma_m = pax_find_mirror_vma(vma);
37646 ++ if (!vma_m)
37647 ++ return;
37648 ++
37649 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37650 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37651 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
37652 ++ get_page(page_m);
37653 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
37654 ++}
37655 ++#endif
37656 ++
37657 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
37658 + unsigned long address, pte_t *ptep, pte_t pte)
37659 + {
37660 +@@ -881,6 +901,11 @@ static int hugetlb_cow(struct mm_struct
37661 + /* Break COW */
37662 + set_huge_pte_at(mm, address, ptep,
37663 + make_huge_pte(vma, new_page, 1));
37664 ++
37665 ++#ifdef CONFIG_PAX_SEGMEXEC
37666 ++ pax_mirror_huge_pte(vma, address, new_page);
37667 ++#endif
37668 ++
37669 + /* Make the old page be freed below */
37670 + new_page = old_page;
37671 + }
37672 +@@ -953,6 +978,10 @@ retry:
37673 + && (vma->vm_flags & VM_SHARED)));
37674 + set_huge_pte_at(mm, address, ptep, new_pte);
37675 +
37676 ++#ifdef CONFIG_PAX_SEGMEXEC
37677 ++ pax_mirror_huge_pte(vma, address, page);
37678 ++#endif
37679 ++
37680 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
37681 + /* Optimization, do the COW without a second fault */
37682 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
37683 +@@ -978,6 +1007,27 @@ int hugetlb_fault(struct mm_struct *mm,
37684 + int ret;
37685 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
37686 +
37687 ++#ifdef CONFIG_PAX_SEGMEXEC
37688 ++ struct vm_area_struct *vma_m;
37689 ++
37690 ++ vma_m = pax_find_mirror_vma(vma);
37691 ++ if (vma_m) {
37692 ++ unsigned long address_m;
37693 ++
37694 ++ if (vma->vm_start > vma_m->vm_start) {
37695 ++ address_m = address;
37696 ++ address -= SEGMEXEC_TASK_SIZE;
37697 ++ vma = vma_m;
37698 ++ } else
37699 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37700 ++
37701 ++ if (!huge_pte_alloc(mm, address_m))
37702 ++ return VM_FAULT_OOM;
37703 ++ address_m &= HPAGE_MASK;
37704 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
37705 ++ }
37706 ++#endif
37707 ++
37708 + ptep = huge_pte_alloc(mm, address);
37709 + if (!ptep)
37710 + return VM_FAULT_OOM;
37711 +diff -urNp a/mm/madvise.c b/mm/madvise.c
37712 +--- a/mm/madvise.c 2008-08-20 11:16:13.000000000 -0700
37713 ++++ b/mm/madvise.c 2008-08-20 18:36:57.000000000 -0700
37714 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
37715 + pgoff_t pgoff;
37716 + int new_flags = vma->vm_flags;
37717 +
37718 ++#ifdef CONFIG_PAX_SEGMEXEC
37719 ++ struct vm_area_struct *vma_m;
37720 ++#endif
37721 ++
37722 + switch (behavior) {
37723 + case MADV_NORMAL:
37724 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
37725 +@@ -92,6 +96,13 @@ success:
37726 + /*
37727 + * vm_flags is protected by the mmap_sem held in write mode.
37728 + */
37729 ++
37730 ++#ifdef CONFIG_PAX_SEGMEXEC
37731 ++ vma_m = pax_find_mirror_vma(vma);
37732 ++ if (vma_m)
37733 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
37734 ++#endif
37735 ++
37736 + vma->vm_flags = new_flags;
37737 +
37738 + out:
37739 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
37740 +
37741 + case MADV_DONTNEED:
37742 + error = madvise_dontneed(vma, prev, start, end);
37743 ++
37744 ++#ifdef CONFIG_PAX_SEGMEXEC
37745 ++ if (!error) {
37746 ++ struct vm_area_struct *vma_m, *prev_m;
37747 ++
37748 ++ vma_m = pax_find_mirror_vma(vma);
37749 ++ if (vma_m)
37750 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
37751 ++ }
37752 ++#endif
37753 ++
37754 + break;
37755 +
37756 + default:
37757 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
37758 + if (end < start)
37759 + goto out;
37760 +
37761 ++#ifdef CONFIG_PAX_SEGMEXEC
37762 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
37763 ++ if (end > SEGMEXEC_TASK_SIZE)
37764 ++ goto out;
37765 ++ } else
37766 ++#endif
37767 ++
37768 ++ if (end > TASK_SIZE)
37769 ++ goto out;
37770 ++
37771 + error = 0;
37772 + if (end == start)
37773 + goto out;
37774 +diff -urNp a/mm/memory.c b/mm/memory.c
37775 +--- a/mm/memory.c 2008-08-20 11:16:13.000000000 -0700
37776 ++++ b/mm/memory.c 2008-08-20 18:36:57.000000000 -0700
37777 +@@ -51,6 +51,7 @@
37778 + #include <linux/init.h>
37779 + #include <linux/writeback.h>
37780 + #include <linux/memcontrol.h>
37781 ++#include <linux/grsecurity.h>
37782 +
37783 + #include <asm/pgalloc.h>
37784 + #include <asm/uaccess.h>
37785 +@@ -1026,11 +1027,11 @@ int get_user_pages(struct task_struct *t
37786 + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
37787 + i = 0;
37788 +
37789 +- do {
37790 ++ while (len) {
37791 + struct vm_area_struct *vma;
37792 + unsigned int foll_flags;
37793 +
37794 +- vma = find_extend_vma(mm, start);
37795 ++ vma = find_vma(mm, start);
37796 + if (!vma && in_gate_area(tsk, start)) {
37797 + unsigned long pg = start & PAGE_MASK;
37798 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
37799 +@@ -1070,7 +1071,7 @@ int get_user_pages(struct task_struct *t
37800 + continue;
37801 + }
37802 +
37803 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
37804 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
37805 + || !(vm_flags & vma->vm_flags))
37806 + return i ? : -EFAULT;
37807 +
37808 +@@ -1143,7 +1144,7 @@ int get_user_pages(struct task_struct *t
37809 + start += PAGE_SIZE;
37810 + len--;
37811 + } while (len && start < vma->vm_end);
37812 +- } while (len);
37813 ++ }
37814 + return i;
37815 + }
37816 + EXPORT_SYMBOL(get_user_pages);
37817 +@@ -1569,6 +1570,186 @@ static inline void cow_user_page(struct
37818 + copy_user_highpage(dst, src, va, vma);
37819 + }
37820 +
37821 ++#ifdef CONFIG_PAX_SEGMEXEC
37822 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
37823 ++{
37824 ++ struct mm_struct *mm = vma->vm_mm;
37825 ++ spinlock_t *ptl;
37826 ++ pte_t *pte, entry;
37827 ++
37828 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
37829 ++ entry = *pte;
37830 ++ if (!pte_present(entry)) {
37831 ++ if (!pte_none(entry)) {
37832 ++ BUG_ON(pte_file(entry));
37833 ++ free_swap_and_cache(pte_to_swp_entry(entry));
37834 ++ pte_clear_not_present_full(mm, address, pte, 0);
37835 ++ }
37836 ++ } else {
37837 ++ struct page *page;
37838 ++
37839 ++ flush_cache_page(vma, address, pte_pfn(entry));
37840 ++ entry = ptep_clear_flush(vma, address, pte);
37841 ++ BUG_ON(pte_dirty(entry));
37842 ++ page = vm_normal_page(vma, address, entry);
37843 ++ if (page) {
37844 ++ update_hiwater_rss(mm);
37845 ++ if (PageAnon(page))
37846 ++ dec_mm_counter(mm, anon_rss);
37847 ++ else
37848 ++ dec_mm_counter(mm, file_rss);
37849 ++ page_remove_rmap(page, vma);
37850 ++ page_cache_release(page);
37851 ++ }
37852 ++ }
37853 ++ pte_unmap_unlock(pte, ptl);
37854 ++}
37855 ++
37856 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
37857 ++ *
37858 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
37859 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
37860 ++ */
37861 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
37862 ++{
37863 ++ struct mm_struct *mm = vma->vm_mm;
37864 ++ unsigned long address_m;
37865 ++ spinlock_t *ptl_m;
37866 ++ struct vm_area_struct *vma_m;
37867 ++ pmd_t *pmd_m;
37868 ++ pte_t *pte_m, entry_m;
37869 ++
37870 ++ BUG_ON(!page_m || !PageAnon(page_m));
37871 ++
37872 ++ vma_m = pax_find_mirror_vma(vma);
37873 ++ if (!vma_m)
37874 ++ return;
37875 ++
37876 ++ BUG_ON(!PageLocked(page_m));
37877 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37878 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37879 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37880 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37881 ++ ptl_m = pte_lockptr(mm, pmd_m);
37882 ++ if (ptl != ptl_m) {
37883 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37884 ++ if (!pte_none(*pte_m))
37885 ++ goto out;
37886 ++ }
37887 ++
37888 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
37889 ++ page_cache_get(page_m);
37890 ++ page_add_anon_rmap(page_m, vma_m, address_m);
37891 ++ inc_mm_counter(mm, anon_rss);
37892 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37893 ++ update_mmu_cache(vma_m, address_m, entry_m);
37894 ++out:
37895 ++ if (ptl != ptl_m)
37896 ++ spin_unlock(ptl_m);
37897 ++ pte_unmap_nested(pte_m);
37898 ++ unlock_page(page_m);
37899 ++}
37900 ++
37901 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
37902 ++{
37903 ++ struct mm_struct *mm = vma->vm_mm;
37904 ++ unsigned long address_m;
37905 ++ spinlock_t *ptl_m;
37906 ++ struct vm_area_struct *vma_m;
37907 ++ pmd_t *pmd_m;
37908 ++ pte_t *pte_m, entry_m;
37909 ++
37910 ++ BUG_ON(!page_m || PageAnon(page_m));
37911 ++
37912 ++ vma_m = pax_find_mirror_vma(vma);
37913 ++ if (!vma_m)
37914 ++ return;
37915 ++
37916 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37917 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37918 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37919 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37920 ++ ptl_m = pte_lockptr(mm, pmd_m);
37921 ++ if (ptl != ptl_m) {
37922 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37923 ++ if (!pte_none(*pte_m))
37924 ++ goto out;
37925 ++ }
37926 ++
37927 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
37928 ++ page_cache_get(page_m);
37929 ++ page_add_file_rmap(page_m);
37930 ++ inc_mm_counter(mm, file_rss);
37931 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37932 ++ update_mmu_cache(vma_m, address_m, entry_m);
37933 ++out:
37934 ++ if (ptl != ptl_m)
37935 ++ spin_unlock(ptl_m);
37936 ++ pte_unmap_nested(pte_m);
37937 ++}
37938 ++
37939 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
37940 ++{
37941 ++ struct mm_struct *mm = vma->vm_mm;
37942 ++ unsigned long address_m;
37943 ++ spinlock_t *ptl_m;
37944 ++ struct vm_area_struct *vma_m;
37945 ++ pmd_t *pmd_m;
37946 ++ pte_t *pte_m, entry_m;
37947 ++
37948 ++ vma_m = pax_find_mirror_vma(vma);
37949 ++ if (!vma_m)
37950 ++ return;
37951 ++
37952 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37953 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37954 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37955 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37956 ++ ptl_m = pte_lockptr(mm, pmd_m);
37957 ++ if (ptl != ptl_m) {
37958 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37959 ++ if (!pte_none(*pte_m))
37960 ++ goto out;
37961 ++ }
37962 ++
37963 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
37964 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37965 ++out:
37966 ++ if (ptl != ptl_m)
37967 ++ spin_unlock(ptl_m);
37968 ++ pte_unmap_nested(pte_m);
37969 ++}
37970 ++
37971 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
37972 ++{
37973 ++ struct page *page_m;
37974 ++ pte_t entry;
37975 ++
37976 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
37977 ++ goto out;
37978 ++
37979 ++ entry = *pte;
37980 ++ page_m = vm_normal_page(vma, address, entry);
37981 ++ if (!page_m)
37982 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
37983 ++ else if (PageAnon(page_m)) {
37984 ++ if (pax_find_mirror_vma(vma)) {
37985 ++ pte_unmap_unlock(pte, ptl);
37986 ++ lock_page(page_m);
37987 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
37988 ++ if (pte_same(entry, *pte))
37989 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
37990 ++ else
37991 ++ unlock_page(page_m);
37992 ++ }
37993 ++ } else
37994 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
37995 ++
37996 ++out:
37997 ++ pte_unmap_unlock(pte, ptl);
37998 ++}
37999 ++#endif
38000 ++
38001 + /*
38002 + * This routine handles present pages, when users try to write
38003 + * to a shared page. It is done by copying the page to a new address
38004 +@@ -1685,6 +1866,12 @@ gotten:
38005 + */
38006 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
38007 + if (likely(pte_same(*page_table, orig_pte))) {
38008 ++
38009 ++#ifdef CONFIG_PAX_SEGMEXEC
38010 ++ if (pax_find_mirror_vma(vma))
38011 ++ BUG_ON(TestSetPageLocked(new_page));
38012 ++#endif
38013 ++
38014 + if (old_page) {
38015 + page_remove_rmap(old_page, vma);
38016 + if (!PageAnon(old_page)) {
38017 +@@ -1708,6 +1895,10 @@ gotten:
38018 + lru_cache_add_active(new_page);
38019 + page_add_new_anon_rmap(new_page, vma, address);
38020 +
38021 ++#ifdef CONFIG_PAX_SEGMEXEC
38022 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
38023 ++#endif
38024 ++
38025 + /* Free the old page.. */
38026 + new_page = old_page;
38027 + ret |= VM_FAULT_WRITE;
38028 +@@ -1967,6 +2158,7 @@ int vmtruncate(struct inode * inode, lof
38029 + unsigned long limit;
38030 +
38031 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
38032 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
38033 + if (limit != RLIM_INFINITY && offset > limit)
38034 + goto out_sig;
38035 + if (offset > inode->i_sb->s_maxbytes)
38036 +@@ -2117,6 +2309,11 @@ static int do_swap_page(struct mm_struct
38037 + swap_free(entry);
38038 + if (vm_swap_full())
38039 + remove_exclusive_swap_page(page);
38040 ++
38041 ++#ifdef CONFIG_PAX_SEGMEXEC
38042 ++ if (write_access || !pax_find_mirror_vma(vma))
38043 ++#endif
38044 ++
38045 + unlock_page(page);
38046 +
38047 + if (write_access) {
38048 +@@ -2128,6 +2325,11 @@ static int do_swap_page(struct mm_struct
38049 +
38050 + /* No need to invalidate - it was non-present before */
38051 + update_mmu_cache(vma, address, pte);
38052 ++
38053 ++#ifdef CONFIG_PAX_SEGMEXEC
38054 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38055 ++#endif
38056 ++
38057 + unlock:
38058 + pte_unmap_unlock(page_table, ptl);
38059 + out:
38060 +@@ -2172,6 +2374,12 @@ static int do_anonymous_page(struct mm_s
38061 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
38062 + if (!pte_none(*page_table))
38063 + goto release;
38064 ++
38065 ++#ifdef CONFIG_PAX_SEGMEXEC
38066 ++ if (pax_find_mirror_vma(vma))
38067 ++ BUG_ON(TestSetPageLocked(page));
38068 ++#endif
38069 ++
38070 + inc_mm_counter(mm, anon_rss);
38071 + lru_cache_add_active(page);
38072 + page_add_new_anon_rmap(page, vma, address);
38073 +@@ -2179,6 +2387,11 @@ static int do_anonymous_page(struct mm_s
38074 +
38075 + /* No need to invalidate - it was non-present before */
38076 + update_mmu_cache(vma, address, entry);
38077 ++
38078 ++#ifdef CONFIG_PAX_SEGMEXEC
38079 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38080 ++#endif
38081 ++
38082 + unlock:
38083 + pte_unmap_unlock(page_table, ptl);
38084 + return 0;
38085 +@@ -2320,6 +2533,12 @@ static int __do_fault(struct mm_struct *
38086 + */
38087 + /* Only go through if we didn't race with anybody else... */
38088 + if (likely(pte_same(*page_table, orig_pte))) {
38089 ++
38090 ++#ifdef CONFIG_PAX_SEGMEXEC
38091 ++ if (anon && pax_find_mirror_vma(vma))
38092 ++ BUG_ON(TestSetPageLocked(page));
38093 ++#endif
38094 ++
38095 + flush_icache_page(vma, page);
38096 + entry = mk_pte(page, vma->vm_page_prot);
38097 + if (flags & FAULT_FLAG_WRITE)
38098 +@@ -2340,6 +2559,14 @@ static int __do_fault(struct mm_struct *
38099 +
38100 + /* no need to invalidate: a not-present page won't be cached */
38101 + update_mmu_cache(vma, address, entry);
38102 ++
38103 ++#ifdef CONFIG_PAX_SEGMEXEC
38104 ++ if (anon)
38105 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38106 ++ else
38107 ++ pax_mirror_file_pte(vma, address, page, ptl);
38108 ++#endif
38109 ++
38110 + } else {
38111 + mem_cgroup_uncharge_page(page);
38112 + if (anon)
38113 +@@ -2423,6 +2650,11 @@ static noinline int do_no_pfn(struct mm_
38114 + if (write_access)
38115 + entry = maybe_mkwrite(pte_mkdirty(entry), vma);
38116 + set_pte_at(mm, address, page_table, entry);
38117 ++
38118 ++#ifdef CONFIG_PAX_SEGMEXEC
38119 ++ pax_mirror_pfn_pte(vma, address, pfn, ptl);
38120 ++#endif
38121 ++
38122 + }
38123 + pte_unmap_unlock(page_table, ptl);
38124 + return 0;
38125 +@@ -2525,6 +2757,12 @@ static inline int handle_pte_fault(struc
38126 + if (write_access)
38127 + flush_tlb_page(vma, address);
38128 + }
38129 ++
38130 ++#ifdef CONFIG_PAX_SEGMEXEC
38131 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
38132 ++ return 0;
38133 ++#endif
38134 ++
38135 + unlock:
38136 + pte_unmap_unlock(pte, ptl);
38137 + return 0;
38138 +@@ -2541,6 +2779,10 @@ int handle_mm_fault(struct mm_struct *mm
38139 + pmd_t *pmd;
38140 + pte_t *pte;
38141 +
38142 ++#ifdef CONFIG_PAX_SEGMEXEC
38143 ++ struct vm_area_struct *vma_m;
38144 ++#endif
38145 ++
38146 + __set_current_state(TASK_RUNNING);
38147 +
38148 + count_vm_event(PGFAULT);
38149 +@@ -2548,6 +2790,34 @@ int handle_mm_fault(struct mm_struct *mm
38150 + if (unlikely(is_vm_hugetlb_page(vma)))
38151 + return hugetlb_fault(mm, vma, address, write_access);
38152 +
38153 ++#ifdef CONFIG_PAX_SEGMEXEC
38154 ++ vma_m = pax_find_mirror_vma(vma);
38155 ++ if (vma_m) {
38156 ++ unsigned long address_m;
38157 ++ pgd_t *pgd_m;
38158 ++ pud_t *pud_m;
38159 ++ pmd_t *pmd_m;
38160 ++
38161 ++ if (vma->vm_start > vma_m->vm_start) {
38162 ++ address_m = address;
38163 ++ address -= SEGMEXEC_TASK_SIZE;
38164 ++ vma = vma_m;
38165 ++ } else
38166 ++ address_m = address + SEGMEXEC_TASK_SIZE;
38167 ++
38168 ++ pgd_m = pgd_offset(mm, address_m);
38169 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
38170 ++ if (!pud_m)
38171 ++ return VM_FAULT_OOM;
38172 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
38173 ++ if (!pmd_m)
38174 ++ return VM_FAULT_OOM;
38175 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
38176 ++ return VM_FAULT_OOM;
38177 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
38178 ++ }
38179 ++#endif
38180 ++
38181 + pgd = pgd_offset(mm, address);
38182 + pud = pud_alloc(mm, pgd, address);
38183 + if (!pud)
38184 +@@ -2651,7 +2921,7 @@ static int __init gate_vma_init(void)
38185 + gate_vma.vm_start = FIXADDR_USER_START;
38186 + gate_vma.vm_end = FIXADDR_USER_END;
38187 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
38188 +- gate_vma.vm_page_prot = __P101;
38189 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
38190 + /*
38191 + * Make sure the vDSO gets into every core dump.
38192 + * Dumping its contents makes post-mortem fully interpretable later
38193 +diff -urNp a/mm/mempolicy.c b/mm/mempolicy.c
38194 +--- a/mm/mempolicy.c 2008-08-20 11:16:13.000000000 -0700
38195 ++++ b/mm/mempolicy.c 2008-08-20 18:36:57.000000000 -0700
38196 +@@ -433,6 +433,10 @@ static int mbind_range(struct vm_area_st
38197 + struct vm_area_struct *next;
38198 + int err;
38199 +
38200 ++#ifdef CONFIG_PAX_SEGMEXEC
38201 ++ struct vm_area_struct *vma_m;
38202 ++#endif
38203 ++
38204 + err = 0;
38205 + for (; vma && vma->vm_start < end; vma = next) {
38206 + next = vma->vm_next;
38207 +@@ -444,6 +448,16 @@ static int mbind_range(struct vm_area_st
38208 + err = policy_vma(vma, new);
38209 + if (err)
38210 + break;
38211 ++
38212 ++#ifdef CONFIG_PAX_SEGMEXEC
38213 ++ vma_m = pax_find_mirror_vma(vma);
38214 ++ if (vma_m) {
38215 ++ err = policy_vma(vma_m, new);
38216 ++ if (err)
38217 ++ break;
38218 ++ }
38219 ++#endif
38220 ++
38221 + }
38222 + return err;
38223 + }
38224 +@@ -809,6 +823,17 @@ static long do_mbind(unsigned long start
38225 +
38226 + if (end < start)
38227 + return -EINVAL;
38228 ++
38229 ++#ifdef CONFIG_PAX_SEGMEXEC
38230 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
38231 ++ if (end > SEGMEXEC_TASK_SIZE)
38232 ++ return -EINVAL;
38233 ++ } else
38234 ++#endif
38235 ++
38236 ++ if (end > TASK_SIZE)
38237 ++ return -EINVAL;
38238 ++
38239 + if (end == start)
38240 + return 0;
38241 +
38242 +diff -urNp a/mm/mlock.c b/mm/mlock.c
38243 +--- a/mm/mlock.c 2008-08-20 11:16:13.000000000 -0700
38244 ++++ b/mm/mlock.c 2008-08-20 18:36:57.000000000 -0700
38245 +@@ -12,6 +12,7 @@
38246 + #include <linux/syscalls.h>
38247 + #include <linux/sched.h>
38248 + #include <linux/module.h>
38249 ++#include <linux/grsecurity.h>
38250 +
38251 + int can_do_mlock(void)
38252 + {
38253 +@@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
38254 + return -EINVAL;
38255 + if (end == start)
38256 + return 0;
38257 ++
38258 ++#ifdef CONFIG_PAX_SEGMEXEC
38259 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
38260 ++ if (end > SEGMEXEC_TASK_SIZE)
38261 ++ return -EINVAL;
38262 ++ } else
38263 ++#endif
38264 ++
38265 ++ if (end > TASK_SIZE)
38266 ++ return -EINVAL;
38267 ++
38268 + vma = find_vma_prev(current->mm, start, &prev);
38269 + if (!vma || vma->vm_start > start)
38270 + return -ENOMEM;
38271 +@@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
38272 + lock_limit >>= PAGE_SHIFT;
38273 +
38274 + /* check against resource limits */
38275 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
38276 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
38277 + error = do_mlock(start, len, 1);
38278 + up_write(&current->mm->mmap_sem);
38279 +@@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
38280 + static int do_mlockall(int flags)
38281 + {
38282 + struct vm_area_struct * vma, * prev = NULL;
38283 +- unsigned int def_flags = 0;
38284 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
38285 +
38286 + if (flags & MCL_FUTURE)
38287 +- def_flags = VM_LOCKED;
38288 ++ def_flags |= VM_LOCKED;
38289 + current->mm->def_flags = def_flags;
38290 + if (flags == MCL_FUTURE)
38291 + goto out;
38292 +@@ -182,6 +195,12 @@ static int do_mlockall(int flags)
38293 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
38294 + unsigned int newflags;
38295 +
38296 ++#ifdef CONFIG_PAX_SEGMEXEC
38297 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
38298 ++ break;
38299 ++#endif
38300 ++
38301 ++ BUG_ON(vma->vm_end > TASK_SIZE);
38302 + newflags = vma->vm_flags | VM_LOCKED;
38303 + if (!(flags & MCL_CURRENT))
38304 + newflags &= ~VM_LOCKED;
38305 +@@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
38306 + lock_limit >>= PAGE_SHIFT;
38307 +
38308 + ret = -ENOMEM;
38309 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
38310 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
38311 + capable(CAP_IPC_LOCK))
38312 + ret = do_mlockall(flags);
38313 +diff -urNp a/mm/mmap.c b/mm/mmap.c
38314 +--- a/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
38315 ++++ b/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
38316 +@@ -26,6 +26,7 @@
38317 + #include <linux/mount.h>
38318 + #include <linux/mempolicy.h>
38319 + #include <linux/rmap.h>
38320 ++#include <linux/grsecurity.h>
38321 +
38322 + #include <asm/uaccess.h>
38323 + #include <asm/cacheflush.h>
38324 +@@ -40,6 +41,16 @@
38325 + #define arch_rebalance_pgtables(addr, len) (addr)
38326 + #endif
38327 +
38328 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
38329 ++{
38330 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
38331 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
38332 ++ up_read(&mm->mmap_sem);
38333 ++ BUG();
38334 ++ }
38335 ++#endif
38336 ++}
38337 ++
38338 + static void unmap_region(struct mm_struct *mm,
38339 + struct vm_area_struct *vma, struct vm_area_struct *prev,
38340 + unsigned long start, unsigned long end);
38341 +@@ -65,15 +76,23 @@ static void unmap_region(struct mm_struc
38342 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
38343 + *
38344 + */
38345 +-pgprot_t protection_map[16] = {
38346 ++pgprot_t protection_map[16] __read_only = {
38347 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
38348 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
38349 + };
38350 +
38351 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
38352 + {
38353 +- return protection_map[vm_flags &
38354 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38355 ++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38356 ++
38357 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38358 ++ if (!nx_enabled &&
38359 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
38360 ++ (vm_flags & (VM_READ | VM_WRITE)))
38361 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
38362 ++#endif
38363 ++
38364 ++ return prot;
38365 + }
38366 + EXPORT_SYMBOL(vm_get_page_prot);
38367 +
38368 +@@ -228,6 +247,7 @@ static struct vm_area_struct *remove_vma
38369 + struct vm_area_struct *next = vma->vm_next;
38370 +
38371 + might_sleep();
38372 ++ BUG_ON(vma->vm_mirror);
38373 + if (vma->vm_ops && vma->vm_ops->close)
38374 + vma->vm_ops->close(vma);
38375 + if (vma->vm_file)
38376 +@@ -261,6 +281,7 @@ asmlinkage unsigned long sys_brk(unsigne
38377 + * not page aligned -Ram Gupta
38378 + */
38379 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
38380 ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
38381 + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
38382 + (mm->end_data - mm->start_data) > rlim)
38383 + goto out;
38384 +@@ -362,8 +383,12 @@ find_vma_prepare(struct mm_struct *mm, u
38385 +
38386 + if (vma_tmp->vm_end > addr) {
38387 + vma = vma_tmp;
38388 +- if (vma_tmp->vm_start <= addr)
38389 +- return vma;
38390 ++ if (vma_tmp->vm_start <= addr) {
38391 ++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
38392 ++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
38393 ++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
38394 ++ break;
38395 ++ }
38396 + __rb_link = &__rb_parent->rb_left;
38397 + } else {
38398 + rb_prev = __rb_parent;
38399 +@@ -687,6 +712,12 @@ static int
38400 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
38401 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
38402 + {
38403 ++
38404 ++#ifdef CONFIG_PAX_SEGMEXEC
38405 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
38406 ++ return 0;
38407 ++#endif
38408 ++
38409 + if (is_mergeable_vma(vma, file, vm_flags) &&
38410 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
38411 + if (vma->vm_pgoff == vm_pgoff)
38412 +@@ -706,6 +737,12 @@ static int
38413 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
38414 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
38415 + {
38416 ++
38417 ++#ifdef CONFIG_PAX_SEGMEXEC
38418 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
38419 ++ return 0;
38420 ++#endif
38421 ++
38422 + if (is_mergeable_vma(vma, file, vm_flags) &&
38423 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
38424 + pgoff_t vm_pglen;
38425 +@@ -748,12 +785,19 @@ can_vma_merge_after(struct vm_area_struc
38426 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
38427 + struct vm_area_struct *prev, unsigned long addr,
38428 + unsigned long end, unsigned long vm_flags,
38429 +- struct anon_vma *anon_vma, struct file *file,
38430 ++ struct anon_vma *anon_vma, struct file *file,
38431 + pgoff_t pgoff, struct mempolicy *policy)
38432 + {
38433 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
38434 + struct vm_area_struct *area, *next;
38435 +
38436 ++#ifdef CONFIG_PAX_SEGMEXEC
38437 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
38438 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
38439 ++
38440 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
38441 ++#endif
38442 ++
38443 + /*
38444 + * We later require that vma->vm_flags == vm_flags,
38445 + * so this tests vma->vm_flags & VM_SPECIAL, too.
38446 +@@ -769,6 +813,15 @@ struct vm_area_struct *vma_merge(struct
38447 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
38448 + next = next->vm_next;
38449 +
38450 ++#ifdef CONFIG_PAX_SEGMEXEC
38451 ++ if (prev)
38452 ++ prev_m = pax_find_mirror_vma(prev);
38453 ++ if (area)
38454 ++ area_m = pax_find_mirror_vma(area);
38455 ++ if (next)
38456 ++ next_m = pax_find_mirror_vma(next);
38457 ++#endif
38458 ++
38459 + /*
38460 + * Can it merge with the predecessor?
38461 + */
38462 +@@ -788,9 +841,24 @@ struct vm_area_struct *vma_merge(struct
38463 + /* cases 1, 6 */
38464 + vma_adjust(prev, prev->vm_start,
38465 + next->vm_end, prev->vm_pgoff, NULL);
38466 +- } else /* cases 2, 5, 7 */
38467 ++
38468 ++#ifdef CONFIG_PAX_SEGMEXEC
38469 ++ if (prev_m)
38470 ++ vma_adjust(prev_m, prev_m->vm_start,
38471 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
38472 ++#endif
38473 ++
38474 ++ } else { /* cases 2, 5, 7 */
38475 + vma_adjust(prev, prev->vm_start,
38476 + end, prev->vm_pgoff, NULL);
38477 ++
38478 ++#ifdef CONFIG_PAX_SEGMEXEC
38479 ++ if (prev_m)
38480 ++ vma_adjust(prev_m, prev_m->vm_start,
38481 ++ end_m, prev_m->vm_pgoff, NULL);
38482 ++#endif
38483 ++
38484 ++ }
38485 + return prev;
38486 + }
38487 +
38488 +@@ -801,12 +869,27 @@ struct vm_area_struct *vma_merge(struct
38489 + mpol_equal(policy, vma_policy(next)) &&
38490 + can_vma_merge_before(next, vm_flags,
38491 + anon_vma, file, pgoff+pglen)) {
38492 +- if (prev && addr < prev->vm_end) /* case 4 */
38493 ++ if (prev && addr < prev->vm_end) { /* case 4 */
38494 + vma_adjust(prev, prev->vm_start,
38495 + addr, prev->vm_pgoff, NULL);
38496 +- else /* cases 3, 8 */
38497 ++
38498 ++#ifdef CONFIG_PAX_SEGMEXEC
38499 ++ if (prev_m)
38500 ++ vma_adjust(prev_m, prev_m->vm_start,
38501 ++ addr_m, prev_m->vm_pgoff, NULL);
38502 ++#endif
38503 ++
38504 ++ } else { /* cases 3, 8 */
38505 + vma_adjust(area, addr, next->vm_end,
38506 + next->vm_pgoff - pglen, NULL);
38507 ++
38508 ++#ifdef CONFIG_PAX_SEGMEXEC
38509 ++ if (area_m)
38510 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
38511 ++ next_m->vm_pgoff - pglen, NULL);
38512 ++#endif
38513 ++
38514 ++ }
38515 + return area;
38516 + }
38517 +
38518 +@@ -881,14 +964,11 @@ none:
38519 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
38520 + struct file *file, long pages)
38521 + {
38522 +- const unsigned long stack_flags
38523 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
38524 +-
38525 + if (file) {
38526 + mm->shared_vm += pages;
38527 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
38528 + mm->exec_vm += pages;
38529 +- } else if (flags & stack_flags)
38530 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
38531 + mm->stack_vm += pages;
38532 + if (flags & (VM_RESERVED|VM_IO))
38533 + mm->reserved_vm += pages;
38534 +@@ -916,7 +996,7 @@ unsigned long do_mmap_pgoff(struct file
38535 + * (the exception is when the underlying filesystem is noexec
38536 + * mounted, in which case we dont add PROT_EXEC.)
38537 + */
38538 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
38539 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
38540 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
38541 + prot |= PROT_EXEC;
38542 +
38543 +@@ -926,15 +1006,15 @@ unsigned long do_mmap_pgoff(struct file
38544 + if (!(flags & MAP_FIXED))
38545 + addr = round_hint_to_min(addr);
38546 +
38547 +- error = arch_mmap_check(addr, len, flags);
38548 +- if (error)
38549 +- return error;
38550 +-
38551 + /* Careful about overflows.. */
38552 + len = PAGE_ALIGN(len);
38553 + if (!len || len > TASK_SIZE)
38554 + return -ENOMEM;
38555 +
38556 ++ error = arch_mmap_check(addr, len, flags);
38557 ++ if (error)
38558 ++ return error;
38559 ++
38560 + /* offset overflow? */
38561 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
38562 + return -EOVERFLOW;
38563 +@@ -946,7 +1026,7 @@ unsigned long do_mmap_pgoff(struct file
38564 + /* Obtain the address to map to. we verify (or select) it and ensure
38565 + * that it represents a valid section of the address space.
38566 + */
38567 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
38568 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
38569 + if (addr & ~PAGE_MASK)
38570 + return addr;
38571 +
38572 +@@ -957,6 +1037,26 @@ unsigned long do_mmap_pgoff(struct file
38573 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
38574 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
38575 +
38576 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
38577 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
38578 ++
38579 ++#ifdef CONFIG_PAX_MPROTECT
38580 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
38581 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
38582 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
38583 ++ else
38584 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
38585 ++ }
38586 ++#endif
38587 ++
38588 ++ }
38589 ++#endif
38590 ++
38591 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38592 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
38593 ++ vm_flags &= ~VM_PAGEEXEC;
38594 ++#endif
38595 ++
38596 + if (flags & MAP_LOCKED) {
38597 + if (!can_do_mlock())
38598 + return -EPERM;
38599 +@@ -969,6 +1069,7 @@ unsigned long do_mmap_pgoff(struct file
38600 + locked += mm->locked_vm;
38601 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
38602 + lock_limit >>= PAGE_SHIFT;
38603 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
38604 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
38605 + return -EAGAIN;
38606 + }
38607 +@@ -1037,6 +1138,9 @@ unsigned long do_mmap_pgoff(struct file
38608 + if (error)
38609 + return error;
38610 +
38611 ++ if (!gr_acl_handle_mmap(file, prot))
38612 ++ return -EACCES;
38613 ++
38614 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
38615 + accountable);
38616 + }
38617 +@@ -1050,10 +1154,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
38618 + */
38619 + int vma_wants_writenotify(struct vm_area_struct *vma)
38620 + {
38621 +- unsigned int vm_flags = vma->vm_flags;
38622 ++ unsigned long vm_flags = vma->vm_flags;
38623 +
38624 + /* If it was private or non-writable, the write bit is already clear */
38625 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
38626 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
38627 + return 0;
38628 +
38629 + /* The backer wishes to know when pages are first written to? */
38630 +@@ -1088,14 +1192,24 @@ unsigned long mmap_region(struct file *f
38631 + unsigned long charged = 0;
38632 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
38633 +
38634 ++#ifdef CONFIG_PAX_SEGMEXEC
38635 ++ struct vm_area_struct *vma_m = NULL;
38636 ++#endif
38637 ++
38638 ++ /*
38639 ++ * mm->mmap_sem is required to protect against another thread
38640 ++ * changing the mappings in case we sleep.
38641 ++ */
38642 ++ verify_mm_writelocked(mm);
38643 ++
38644 + /* Clear old maps */
38645 + error = -ENOMEM;
38646 +-munmap_back:
38647 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
38648 + if (vma && vma->vm_start < addr + len) {
38649 + if (do_munmap(mm, addr, len))
38650 + return -ENOMEM;
38651 +- goto munmap_back;
38652 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
38653 ++ BUG_ON(vma && vma->vm_start < addr + len);
38654 + }
38655 +
38656 + /* Check against address space limit. */
38657 +@@ -1139,6 +1253,16 @@ munmap_back:
38658 + goto unacct_error;
38659 + }
38660 +
38661 ++#ifdef CONFIG_PAX_SEGMEXEC
38662 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
38663 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38664 ++ if (!vma_m) {
38665 ++ error = -ENOMEM;
38666 ++ goto free_vma;
38667 ++ }
38668 ++ }
38669 ++#endif
38670 ++
38671 + vma->vm_mm = mm;
38672 + vma->vm_start = addr;
38673 + vma->vm_end = addr + len;
38674 +@@ -1161,6 +1285,14 @@ munmap_back:
38675 + error = file->f_op->mmap(file, vma);
38676 + if (error)
38677 + goto unmap_and_free_vma;
38678 ++
38679 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38680 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
38681 ++ vma->vm_flags |= VM_PAGEEXEC;
38682 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
38683 ++ }
38684 ++#endif
38685 ++
38686 + } else if (vm_flags & VM_SHARED) {
38687 + error = shmem_zero_setup(vma);
38688 + if (error)
38689 +@@ -1191,6 +1323,12 @@ munmap_back:
38690 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
38691 + file = vma->vm_file;
38692 + vma_link(mm, vma, prev, rb_link, rb_parent);
38693 ++
38694 ++#ifdef CONFIG_PAX_SEGMEXEC
38695 ++ if (vma_m)
38696 ++ pax_mirror_vma(vma_m, vma);
38697 ++#endif
38698 ++
38699 + if (correct_wcount)
38700 + atomic_inc(&inode->i_writecount);
38701 + } else {
38702 +@@ -1201,10 +1339,18 @@ munmap_back:
38703 + }
38704 + mpol_free(vma_policy(vma));
38705 + kmem_cache_free(vm_area_cachep, vma);
38706 ++ vma = NULL;
38707 ++
38708 ++#ifdef CONFIG_PAX_SEGMEXEC
38709 ++ if (vma_m)
38710 ++ kmem_cache_free(vm_area_cachep, vma_m);
38711 ++#endif
38712 ++
38713 + }
38714 + out:
38715 + mm->total_vm += len >> PAGE_SHIFT;
38716 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
38717 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
38718 + if (vm_flags & VM_LOCKED) {
38719 + mm->locked_vm += len >> PAGE_SHIFT;
38720 + make_pages_present(addr, addr + len);
38721 +@@ -1223,6 +1369,12 @@ unmap_and_free_vma:
38722 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
38723 + charged = 0;
38724 + free_vma:
38725 ++
38726 ++#ifdef CONFIG_PAX_SEGMEXEC
38727 ++ if (vma_m)
38728 ++ kmem_cache_free(vm_area_cachep, vma_m);
38729 ++#endif
38730 ++
38731 + kmem_cache_free(vm_area_cachep, vma);
38732 + unacct_error:
38733 + if (charged)
38734 +@@ -1256,6 +1408,10 @@ arch_get_unmapped_area(struct file *filp
38735 + if (flags & MAP_FIXED)
38736 + return addr;
38737 +
38738 ++#ifdef CONFIG_PAX_RANDMMAP
38739 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
38740 ++#endif
38741 ++
38742 + if (addr) {
38743 + addr = PAGE_ALIGN(addr);
38744 + vma = find_vma(mm, addr);
38745 +@@ -1264,10 +1420,10 @@ arch_get_unmapped_area(struct file *filp
38746 + return addr;
38747 + }
38748 + if (len > mm->cached_hole_size) {
38749 +- start_addr = addr = mm->free_area_cache;
38750 ++ start_addr = addr = mm->free_area_cache;
38751 + } else {
38752 +- start_addr = addr = TASK_UNMAPPED_BASE;
38753 +- mm->cached_hole_size = 0;
38754 ++ start_addr = addr = mm->mmap_base;
38755 ++ mm->cached_hole_size = 0;
38756 + }
38757 +
38758 + full_search:
38759 +@@ -1278,9 +1434,8 @@ full_search:
38760 + * Start a new search - just in case we missed
38761 + * some holes.
38762 + */
38763 +- if (start_addr != TASK_UNMAPPED_BASE) {
38764 +- addr = TASK_UNMAPPED_BASE;
38765 +- start_addr = addr;
38766 ++ if (start_addr != mm->mmap_base) {
38767 ++ start_addr = addr = mm->mmap_base;
38768 + mm->cached_hole_size = 0;
38769 + goto full_search;
38770 + }
38771 +@@ -1302,10 +1457,16 @@ full_search:
38772 +
38773 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
38774 + {
38775 ++
38776 ++#ifdef CONFIG_PAX_SEGMEXEC
38777 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
38778 ++ return;
38779 ++#endif
38780 ++
38781 + /*
38782 + * Is this a new hole at the lowest possible address?
38783 + */
38784 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
38785 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
38786 + mm->free_area_cache = addr;
38787 + mm->cached_hole_size = ~0UL;
38788 + }
38789 +@@ -1323,7 +1484,7 @@ arch_get_unmapped_area_topdown(struct fi
38790 + {
38791 + struct vm_area_struct *vma;
38792 + struct mm_struct *mm = current->mm;
38793 +- unsigned long addr = addr0;
38794 ++ unsigned long base = mm->mmap_base, addr = addr0;
38795 +
38796 + /* requested length too big for entire address space */
38797 + if (len > TASK_SIZE)
38798 +@@ -1332,6 +1493,10 @@ arch_get_unmapped_area_topdown(struct fi
38799 + if (flags & MAP_FIXED)
38800 + return addr;
38801 +
38802 ++#ifdef CONFIG_PAX_RANDMMAP
38803 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
38804 ++#endif
38805 ++
38806 + /* requesting a specific address */
38807 + if (addr) {
38808 + addr = PAGE_ALIGN(addr);
38809 +@@ -1389,13 +1554,21 @@ bottomup:
38810 + * can happen with large stack limits and large mmap()
38811 + * allocations.
38812 + */
38813 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
38814 ++
38815 ++#ifdef CONFIG_PAX_RANDMMAP
38816 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
38817 ++ mm->mmap_base += mm->delta_mmap;
38818 ++#endif
38819 ++
38820 ++ mm->free_area_cache = mm->mmap_base;
38821 + mm->cached_hole_size = ~0UL;
38822 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
38823 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
38824 + /*
38825 + * Restore the topdown base:
38826 + */
38827 +- mm->free_area_cache = mm->mmap_base;
38828 ++ mm->mmap_base = base;
38829 ++ mm->free_area_cache = base;
38830 + mm->cached_hole_size = ~0UL;
38831 +
38832 + return addr;
38833 +@@ -1404,6 +1577,12 @@ bottomup:
38834 +
38835 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
38836 + {
38837 ++
38838 ++#ifdef CONFIG_PAX_SEGMEXEC
38839 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
38840 ++ return;
38841 ++#endif
38842 ++
38843 + /*
38844 + * Is this a new hole at the highest possible address?
38845 + */
38846 +@@ -1411,8 +1590,10 @@ void arch_unmap_area_topdown(struct mm_s
38847 + mm->free_area_cache = addr;
38848 +
38849 + /* dont allow allocations above current base */
38850 +- if (mm->free_area_cache > mm->mmap_base)
38851 ++ if (mm->free_area_cache > mm->mmap_base) {
38852 + mm->free_area_cache = mm->mmap_base;
38853 ++ mm->cached_hole_size = ~0UL;
38854 ++ }
38855 + }
38856 +
38857 + unsigned long
38858 +@@ -1512,6 +1693,33 @@ out:
38859 + return prev ? prev->vm_next : vma;
38860 + }
38861 +
38862 ++#ifdef CONFIG_PAX_SEGMEXEC
38863 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
38864 ++{
38865 ++ struct vm_area_struct *vma_m;
38866 ++
38867 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
38868 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
38869 ++ BUG_ON(vma->vm_mirror);
38870 ++ return NULL;
38871 ++ }
38872 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
38873 ++ vma_m = vma->vm_mirror;
38874 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
38875 ++ BUG_ON(vma->vm_file != vma_m->vm_file);
38876 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
38877 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
38878 ++
38879 ++#ifdef CONFIG_PAX_MPROTECT
38880 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
38881 ++#else
38882 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
38883 ++#endif
38884 ++
38885 ++ return vma_m;
38886 ++}
38887 ++#endif
38888 ++
38889 + /*
38890 + * Verify that the stack growth is acceptable and
38891 + * update accounting. This is shared with both the
38892 +@@ -1528,6 +1736,7 @@ static int acct_stack_growth(struct vm_a
38893 + return -ENOMEM;
38894 +
38895 + /* Stack limit test */
38896 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
38897 + if (size > rlim[RLIMIT_STACK].rlim_cur)
38898 + return -ENOMEM;
38899 +
38900 +@@ -1537,6 +1746,7 @@ static int acct_stack_growth(struct vm_a
38901 + unsigned long limit;
38902 + locked = mm->locked_vm + grow;
38903 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
38904 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
38905 + if (locked > limit && !capable(CAP_IPC_LOCK))
38906 + return -ENOMEM;
38907 + }
38908 +@@ -1551,7 +1761,7 @@ static int acct_stack_growth(struct vm_a
38909 + * Overcommit.. This must be the final test, as it will
38910 + * update security statistics.
38911 + */
38912 +- if (security_vm_enough_memory(grow))
38913 ++ if (security_vm_enough_memory_mm(mm, grow))
38914 + return -ENOMEM;
38915 +
38916 + /* Ok, everything looks good - let it rip */
38917 +@@ -1572,35 +1782,40 @@ static inline
38918 + #endif
38919 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
38920 + {
38921 +- int error;
38922 ++ int error, locknext;
38923 +
38924 + if (!(vma->vm_flags & VM_GROWSUP))
38925 + return -EFAULT;
38926 +
38927 ++ /* Also guard against wrapping around to address 0. */
38928 ++ if (address < PAGE_ALIGN(address+1))
38929 ++ address = PAGE_ALIGN(address+1);
38930 ++ else
38931 ++ return -ENOMEM;
38932 ++
38933 + /*
38934 + * We must make sure the anon_vma is allocated
38935 + * so that the anon_vma locking is not a noop.
38936 + */
38937 + if (unlikely(anon_vma_prepare(vma)))
38938 + return -ENOMEM;
38939 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
38940 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
38941 ++ return -ENOMEM;
38942 + anon_vma_lock(vma);
38943 ++ if (locknext)
38944 ++ anon_vma_lock(vma->vm_next);
38945 +
38946 + /*
38947 + * vma->vm_start/vm_end cannot change under us because the caller
38948 + * is required to hold the mmap_sem in read mode. We need the
38949 +- * anon_vma lock to serialize against concurrent expand_stacks.
38950 +- * Also guard against wrapping around to address 0.
38951 ++ * anon_vma locks to serialize against concurrent expand_stacks
38952 ++ * and expand_upwards.
38953 + */
38954 +- if (address < PAGE_ALIGN(address+4))
38955 +- address = PAGE_ALIGN(address+4);
38956 +- else {
38957 +- anon_vma_unlock(vma);
38958 +- return -ENOMEM;
38959 +- }
38960 + error = 0;
38961 +
38962 + /* Somebody else might have raced and expanded it already */
38963 +- if (address > vma->vm_end) {
38964 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
38965 + unsigned long size, grow;
38966 +
38967 + size = address - vma->vm_start;
38968 +@@ -1610,6 +1825,8 @@ int expand_upwards(struct vm_area_struct
38969 + if (!error)
38970 + vma->vm_end = address;
38971 + }
38972 ++ if (locknext)
38973 ++ anon_vma_unlock(vma->vm_next);
38974 + anon_vma_unlock(vma);
38975 + return error;
38976 + }
38977 +@@ -1621,7 +1838,8 @@ int expand_upwards(struct vm_area_struct
38978 + static inline int expand_downwards(struct vm_area_struct *vma,
38979 + unsigned long address)
38980 + {
38981 +- int error;
38982 ++ int error, lockprev = 0;
38983 ++ struct vm_area_struct *prev = NULL;
38984 +
38985 + /*
38986 + * We must make sure the anon_vma is allocated
38987 +@@ -1635,6 +1853,15 @@ static inline int expand_downwards(struc
38988 + if (error)
38989 + return error;
38990 +
38991 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
38992 ++ find_vma_prev(vma->vm_mm, address, &prev);
38993 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
38994 ++#endif
38995 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
38996 ++ return -ENOMEM;
38997 ++ if (lockprev)
38998 ++ anon_vma_lock(prev);
38999 ++
39000 + anon_vma_lock(vma);
39001 +
39002 + /*
39003 +@@ -1644,9 +1871,15 @@ static inline int expand_downwards(struc
39004 + */
39005 +
39006 + /* Somebody else might have raced and expanded it already */
39007 +- if (address < vma->vm_start) {
39008 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
39009 + unsigned long size, grow;
39010 +
39011 ++#ifdef CONFIG_PAX_SEGMEXEC
39012 ++ struct vm_area_struct *vma_m;
39013 ++
39014 ++ vma_m = pax_find_mirror_vma(vma);
39015 ++#endif
39016 ++
39017 + size = vma->vm_end - address;
39018 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
39019 +
39020 +@@ -1654,9 +1887,20 @@ static inline int expand_downwards(struc
39021 + if (!error) {
39022 + vma->vm_start = address;
39023 + vma->vm_pgoff -= grow;
39024 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
39025 ++
39026 ++#ifdef CONFIG_PAX_SEGMEXEC
39027 ++ if (vma_m) {
39028 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
39029 ++ vma_m->vm_pgoff -= grow;
39030 ++ }
39031 ++#endif
39032 ++
39033 + }
39034 + }
39035 + anon_vma_unlock(vma);
39036 ++ if (lockprev)
39037 ++ anon_vma_unlock(prev);
39038 + return error;
39039 + }
39040 +
39041 +@@ -1728,6 +1972,13 @@ static void remove_vma_list(struct mm_st
39042 + do {
39043 + long nrpages = vma_pages(vma);
39044 +
39045 ++#ifdef CONFIG_PAX_SEGMEXEC
39046 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
39047 ++ vma = remove_vma(vma);
39048 ++ continue;
39049 ++ }
39050 ++#endif
39051 ++
39052 + mm->total_vm -= nrpages;
39053 + if (vma->vm_flags & VM_LOCKED)
39054 + mm->locked_vm -= nrpages;
39055 +@@ -1774,6 +2025,16 @@ detach_vmas_to_be_unmapped(struct mm_str
39056 +
39057 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
39058 + do {
39059 ++
39060 ++#ifdef CONFIG_PAX_SEGMEXEC
39061 ++ if (vma->vm_mirror) {
39062 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
39063 ++ vma->vm_mirror->vm_mirror = NULL;
39064 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
39065 ++ vma->vm_mirror = NULL;
39066 ++ }
39067 ++#endif
39068 ++
39069 + rb_erase(&vma->vm_rb, &mm->mm_rb);
39070 + mm->map_count--;
39071 + tail_vma = vma;
39072 +@@ -1793,6 +2054,102 @@ detach_vmas_to_be_unmapped(struct mm_str
39073 + * Split a vma into two pieces at address 'addr', a new vma is allocated
39074 + * either for the first part or the tail.
39075 + */
39076 ++
39077 ++#ifdef CONFIG_PAX_SEGMEXEC
39078 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
39079 ++ unsigned long addr, int new_below)
39080 ++{
39081 ++ struct mempolicy *pol;
39082 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
39083 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
39084 ++
39085 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
39086 ++ return -EINVAL;
39087 ++
39088 ++ vma_m = pax_find_mirror_vma(vma);
39089 ++ if (vma_m) {
39090 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
39091 ++ if (mm->map_count >= sysctl_max_map_count-1)
39092 ++ return -ENOMEM;
39093 ++ } else if (mm->map_count >= sysctl_max_map_count)
39094 ++ return -ENOMEM;
39095 ++
39096 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
39097 ++ if (!new)
39098 ++ return -ENOMEM;
39099 ++
39100 ++ if (vma_m) {
39101 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
39102 ++ if (!new_m) {
39103 ++ kmem_cache_free(vm_area_cachep, new);
39104 ++ return -ENOMEM;
39105 ++ }
39106 ++ }
39107 ++
39108 ++ /* most fields are the same, copy all, and then fixup */
39109 ++ *new = *vma;
39110 ++
39111 ++ if (new_below)
39112 ++ new->vm_end = addr;
39113 ++ else {
39114 ++ new->vm_start = addr;
39115 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
39116 ++ }
39117 ++
39118 ++ if (vma_m) {
39119 ++ *new_m = *vma_m;
39120 ++ new_m->vm_mirror = new;
39121 ++ new->vm_mirror = new_m;
39122 ++
39123 ++ if (new_below)
39124 ++ new_m->vm_end = addr_m;
39125 ++ else {
39126 ++ new_m->vm_start = addr_m;
39127 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
39128 ++ }
39129 ++ }
39130 ++
39131 ++ pol = mpol_copy(vma_policy(vma));
39132 ++ if (IS_ERR(pol)) {
39133 ++ if (new_m)
39134 ++ kmem_cache_free(vm_area_cachep, new_m);
39135 ++ kmem_cache_free(vm_area_cachep, new);
39136 ++ return PTR_ERR(pol);
39137 ++ }
39138 ++ vma_set_policy(new, pol);
39139 ++
39140 ++ if (new->vm_file)
39141 ++ get_file(new->vm_file);
39142 ++
39143 ++ if (new->vm_ops && new->vm_ops->open)
39144 ++ new->vm_ops->open(new);
39145 ++
39146 ++ if (new_below)
39147 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
39148 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
39149 ++ else
39150 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
39151 ++
39152 ++ if (vma_m) {
39153 ++ mpol_get(pol);
39154 ++ vma_set_policy(new_m, pol);
39155 ++
39156 ++ if (new_m->vm_file)
39157 ++ get_file(new_m->vm_file);
39158 ++
39159 ++ if (new_m->vm_ops && new_m->vm_ops->open)
39160 ++ new_m->vm_ops->open(new_m);
39161 ++
39162 ++ if (new_below)
39163 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
39164 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
39165 ++ else
39166 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
39167 ++ }
39168 ++
39169 ++ return 0;
39170 ++}
39171 ++#else
39172 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
39173 + unsigned long addr, int new_below)
39174 + {
39175 +@@ -1840,17 +2197,37 @@ int split_vma(struct mm_struct * mm, str
39176 +
39177 + return 0;
39178 + }
39179 ++#endif
39180 +
39181 + /* Munmap is split into 2 main parts -- this part which finds
39182 + * what needs doing, and the areas themselves, which do the
39183 + * work. This now handles partial unmappings.
39184 + * Jeremy Fitzhardinge <jeremy@××××.org>
39185 + */
39186 ++#ifdef CONFIG_PAX_SEGMEXEC
39187 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39188 + {
39189 ++ int ret = __do_munmap(mm, start, len);
39190 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
39191 ++ return ret;
39192 ++
39193 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
39194 ++}
39195 ++
39196 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39197 ++#else
39198 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39199 ++#endif
39200 ++{
39201 + unsigned long end;
39202 + struct vm_area_struct *vma, *prev, *last;
39203 +
39204 ++ /*
39205 ++ * mm->mmap_sem is required to protect against another thread
39206 ++ * changing the mappings in case we sleep.
39207 ++ */
39208 ++ verify_mm_writelocked(mm);
39209 ++
39210 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
39211 + return -EINVAL;
39212 +
39213 +@@ -1900,6 +2277,8 @@ int do_munmap(struct mm_struct *mm, unsi
39214 + /* Fix up all other VM information */
39215 + remove_vma_list(mm, vma);
39216 +
39217 ++ track_exec_limit(mm, start, end, 0UL);
39218 ++
39219 + return 0;
39220 + }
39221 +
39222 +@@ -1912,22 +2291,18 @@ asmlinkage long sys_munmap(unsigned long
39223 +
39224 + profile_munmap(addr);
39225 +
39226 ++#ifdef CONFIG_PAX_SEGMEXEC
39227 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
39228 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
39229 ++ return -EINVAL;
39230 ++#endif
39231 ++
39232 + down_write(&mm->mmap_sem);
39233 + ret = do_munmap(mm, addr, len);
39234 + up_write(&mm->mmap_sem);
39235 + return ret;
39236 + }
39237 +
39238 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
39239 +-{
39240 +-#ifdef CONFIG_DEBUG_VM
39241 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
39242 +- WARN_ON(1);
39243 +- up_read(&mm->mmap_sem);
39244 +- }
39245 +-#endif
39246 +-}
39247 +-
39248 + /*
39249 + * this is really a simplified "do_mmap". it only handles
39250 + * anonymous maps. eventually we may be able to do some
39251 +@@ -1941,6 +2316,11 @@ unsigned long do_brk(unsigned long addr,
39252 + struct rb_node ** rb_link, * rb_parent;
39253 + pgoff_t pgoff = addr >> PAGE_SHIFT;
39254 + int error;
39255 ++ unsigned long charged;
39256 ++
39257 ++#ifdef CONFIG_PAX_SEGMEXEC
39258 ++ struct vm_area_struct *vma_m = NULL;
39259 ++#endif
39260 +
39261 + len = PAGE_ALIGN(len);
39262 + if (!len)
39263 +@@ -1958,19 +2338,34 @@ unsigned long do_brk(unsigned long addr,
39264 +
39265 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
39266 +
39267 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
39268 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
39269 ++ flags &= ~VM_EXEC;
39270 ++
39271 ++#ifdef CONFIG_PAX_MPROTECT
39272 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
39273 ++ flags &= ~VM_MAYEXEC;
39274 ++#endif
39275 ++
39276 ++ }
39277 ++#endif
39278 ++
39279 + error = arch_mmap_check(addr, len, flags);
39280 + if (error)
39281 + return error;
39282 +
39283 ++ charged = len >> PAGE_SHIFT;
39284 ++
39285 + /*
39286 + * mlock MCL_FUTURE?
39287 + */
39288 + if (mm->def_flags & VM_LOCKED) {
39289 + unsigned long locked, lock_limit;
39290 +- locked = len >> PAGE_SHIFT;
39291 ++ locked = charged;
39292 + locked += mm->locked_vm;
39293 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
39294 + lock_limit >>= PAGE_SHIFT;
39295 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
39296 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
39297 + return -EAGAIN;
39298 + }
39299 +@@ -1984,22 +2379,22 @@ unsigned long do_brk(unsigned long addr,
39300 + /*
39301 + * Clear old maps. this also does some error checking for us
39302 + */
39303 +- munmap_back:
39304 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
39305 + if (vma && vma->vm_start < addr + len) {
39306 + if (do_munmap(mm, addr, len))
39307 + return -ENOMEM;
39308 +- goto munmap_back;
39309 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
39310 ++ BUG_ON(vma && vma->vm_start < addr + len);
39311 + }
39312 +
39313 + /* Check against address space limits *after* clearing old maps... */
39314 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
39315 ++ if (!may_expand_vm(mm, charged))
39316 + return -ENOMEM;
39317 +
39318 + if (mm->map_count > sysctl_max_map_count)
39319 + return -ENOMEM;
39320 +
39321 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
39322 ++ if (security_vm_enough_memory(charged))
39323 + return -ENOMEM;
39324 +
39325 + /* Can we just expand an old private anonymous mapping? */
39326 +@@ -2012,10 +2407,21 @@ unsigned long do_brk(unsigned long addr,
39327 + */
39328 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39329 + if (!vma) {
39330 +- vm_unacct_memory(len >> PAGE_SHIFT);
39331 ++ vm_unacct_memory(charged);
39332 + return -ENOMEM;
39333 + }
39334 +
39335 ++#ifdef CONFIG_PAX_SEGMEXEC
39336 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
39337 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39338 ++ if (!vma_m) {
39339 ++ kmem_cache_free(vm_area_cachep, vma);
39340 ++ vm_unacct_memory(charged);
39341 ++ return -ENOMEM;
39342 ++ }
39343 ++ }
39344 ++#endif
39345 ++
39346 + vma->vm_mm = mm;
39347 + vma->vm_start = addr;
39348 + vma->vm_end = addr + len;
39349 +@@ -2023,12 +2429,19 @@ unsigned long do_brk(unsigned long addr,
39350 + vma->vm_flags = flags;
39351 + vma->vm_page_prot = vm_get_page_prot(flags);
39352 + vma_link(mm, vma, prev, rb_link, rb_parent);
39353 ++
39354 ++#ifdef CONFIG_PAX_SEGMEXEC
39355 ++ if (vma_m)
39356 ++ pax_mirror_vma(vma_m, vma);
39357 ++#endif
39358 ++
39359 + out:
39360 +- mm->total_vm += len >> PAGE_SHIFT;
39361 ++ mm->total_vm += charged;
39362 + if (flags & VM_LOCKED) {
39363 +- mm->locked_vm += len >> PAGE_SHIFT;
39364 ++ mm->locked_vm += charged;
39365 + make_pages_present(addr, addr + len);
39366 + }
39367 ++ track_exec_limit(mm, addr, addr + len, flags);
39368 + return addr;
39369 + }
39370 +
39371 +@@ -2059,8 +2472,10 @@ void exit_mmap(struct mm_struct *mm)
39372 + * Walk the list again, actually closing and freeing it,
39373 + * with preemption enabled, without holding any MM locks.
39374 + */
39375 +- while (vma)
39376 ++ while (vma) {
39377 ++ vma->vm_mirror = NULL;
39378 + vma = remove_vma(vma);
39379 ++ }
39380 +
39381 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
39382 + }
39383 +@@ -2074,6 +2489,10 @@ int insert_vm_struct(struct mm_struct *
39384 + struct vm_area_struct * __vma, * prev;
39385 + struct rb_node ** rb_link, * rb_parent;
39386 +
39387 ++#ifdef CONFIG_PAX_SEGMEXEC
39388 ++ struct vm_area_struct *vma_m = NULL;
39389 ++#endif
39390 ++
39391 + /*
39392 + * The vm_pgoff of a purely anonymous vma should be irrelevant
39393 + * until its first write fault, when page's anon_vma and index
39394 +@@ -2096,7 +2515,22 @@ int insert_vm_struct(struct mm_struct *
39395 + if ((vma->vm_flags & VM_ACCOUNT) &&
39396 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
39397 + return -ENOMEM;
39398 ++
39399 ++#ifdef CONFIG_PAX_SEGMEXEC
39400 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
39401 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39402 ++ if (!vma_m)
39403 ++ return -ENOMEM;
39404 ++ }
39405 ++#endif
39406 ++
39407 + vma_link(mm, vma, prev, rb_link, rb_parent);
39408 ++
39409 ++#ifdef CONFIG_PAX_SEGMEXEC
39410 ++ if (vma_m)
39411 ++ pax_mirror_vma(vma_m, vma);
39412 ++#endif
39413 ++
39414 + return 0;
39415 + }
39416 +
39417 +@@ -2114,6 +2548,8 @@ struct vm_area_struct *copy_vma(struct v
39418 + struct rb_node **rb_link, *rb_parent;
39419 + struct mempolicy *pol;
39420 +
39421 ++ BUG_ON(vma->vm_mirror);
39422 ++
39423 + /*
39424 + * If anonymous vma has not yet been faulted, update new pgoff
39425 + * to match new location, to increase its chance of merging.
39426 +@@ -2154,6 +2590,35 @@ struct vm_area_struct *copy_vma(struct v
39427 + return new_vma;
39428 + }
39429 +
39430 ++#ifdef CONFIG_PAX_SEGMEXEC
39431 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
39432 ++{
39433 ++ struct vm_area_struct *prev_m;
39434 ++ struct rb_node **rb_link_m, *rb_parent_m;
39435 ++ struct mempolicy *pol_m;
39436 ++
39437 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
39438 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
39439 ++ BUG_ON(!vma_mpol_equal(vma, vma_m));
39440 ++ *vma_m = *vma;
39441 ++ pol_m = vma_policy(vma);
39442 ++ mpol_get(pol_m);
39443 ++ vma_set_policy(vma_m, pol_m);
39444 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
39445 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
39446 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
39447 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
39448 ++ if (vma_m->vm_file)
39449 ++ get_file(vma_m->vm_file);
39450 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
39451 ++ vma_m->vm_ops->open(vma_m);
39452 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
39453 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
39454 ++ vma_m->vm_mirror = vma;
39455 ++ vma->vm_mirror = vma_m;
39456 ++}
39457 ++#endif
39458 ++
39459 + /*
39460 + * Return true if the calling process may expand its vm space by the passed
39461 + * number of pages
39462 +@@ -2164,7 +2629,7 @@ int may_expand_vm(struct mm_struct *mm,
39463 + unsigned long lim;
39464 +
39465 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
39466 +-
39467 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
39468 + if (cur + npages > lim)
39469 + return 0;
39470 + return 1;
39471 +@@ -2233,6 +2698,15 @@ int install_special_mapping(struct mm_st
39472 + vma->vm_start = addr;
39473 + vma->vm_end = addr + len;
39474 +
39475 ++#ifdef CONFIG_PAX_MPROTECT
39476 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
39477 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
39478 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
39479 ++ else
39480 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
39481 ++ }
39482 ++#endif
39483 ++
39484 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
39485 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
39486 +
39487 +diff -urNp a/mm/mprotect.c b/mm/mprotect.c
39488 +--- a/mm/mprotect.c 2008-08-20 11:16:13.000000000 -0700
39489 ++++ b/mm/mprotect.c 2008-08-20 18:36:57.000000000 -0700
39490 +@@ -21,10 +21,17 @@
39491 + #include <linux/syscalls.h>
39492 + #include <linux/swap.h>
39493 + #include <linux/swapops.h>
39494 ++#include <linux/grsecurity.h>
39495 ++
39496 ++#ifdef CONFIG_PAX_MPROTECT
39497 ++#include <linux/elf.h>
39498 ++#endif
39499 ++
39500 + #include <asm/uaccess.h>
39501 + #include <asm/pgtable.h>
39502 + #include <asm/cacheflush.h>
39503 + #include <asm/tlbflush.h>
39504 ++#include <asm/mmu_context.h>
39505 +
39506 + static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
39507 + unsigned long addr, unsigned long end, pgprot_t newprot,
39508 +@@ -127,6 +134,48 @@ static void change_protection(struct vm_
39509 + flush_tlb_range(vma, start, end);
39510 + }
39511 +
39512 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
39513 ++/* called while holding the mmap semaphor for writing except stack expansion */
39514 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
39515 ++{
39516 ++ unsigned long oldlimit, newlimit = 0UL;
39517 ++
39518 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
39519 ++ return;
39520 ++
39521 ++ spin_lock(&mm->page_table_lock);
39522 ++ oldlimit = mm->context.user_cs_limit;
39523 ++ if ((prot & VM_EXEC) && oldlimit < end)
39524 ++ /* USER_CS limit moved up */
39525 ++ newlimit = end;
39526 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
39527 ++ /* USER_CS limit moved down */
39528 ++ newlimit = start;
39529 ++
39530 ++ if (newlimit) {
39531 ++ mm->context.user_cs_limit = newlimit;
39532 ++
39533 ++#ifdef CONFIG_SMP
39534 ++ wmb();
39535 ++ cpus_clear(mm->context.cpu_user_cs_mask);
39536 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
39537 ++#endif
39538 ++
39539 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
39540 ++ }
39541 ++ spin_unlock(&mm->page_table_lock);
39542 ++ if (newlimit == end) {
39543 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
39544 ++
39545 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
39546 ++ if (is_vm_hugetlb_page(vma))
39547 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
39548 ++ else
39549 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
39550 ++ }
39551 ++}
39552 ++#endif
39553 ++
39554 + int
39555 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
39556 + unsigned long start, unsigned long end, unsigned long newflags)
39557 +@@ -139,6 +188,14 @@ mprotect_fixup(struct vm_area_struct *vm
39558 + int error;
39559 + int dirty_accountable = 0;
39560 +
39561 ++#ifdef CONFIG_PAX_SEGMEXEC
39562 ++ struct vm_area_struct *vma_m = NULL;
39563 ++ unsigned long start_m, end_m;
39564 ++
39565 ++ start_m = start + SEGMEXEC_TASK_SIZE;
39566 ++ end_m = end + SEGMEXEC_TASK_SIZE;
39567 ++#endif
39568 ++
39569 + if (newflags == oldflags) {
39570 + *pprev = vma;
39571 + return 0;
39572 +@@ -161,6 +218,38 @@ mprotect_fixup(struct vm_area_struct *vm
39573 + }
39574 + }
39575 +
39576 ++#ifdef CONFIG_PAX_SEGMEXEC
39577 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
39578 ++ if (start != vma->vm_start) {
39579 ++ error = split_vma(mm, vma, start, 1);
39580 ++ if (error)
39581 ++ goto fail;
39582 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
39583 ++ *pprev = (*pprev)->vm_next;
39584 ++ }
39585 ++
39586 ++ if (end != vma->vm_end) {
39587 ++ error = split_vma(mm, vma, end, 0);
39588 ++ if (error)
39589 ++ goto fail;
39590 ++ }
39591 ++
39592 ++ if (pax_find_mirror_vma(vma)) {
39593 ++ error = __do_munmap(mm, start_m, end_m - start_m);
39594 ++ if (error)
39595 ++ goto fail;
39596 ++ } else {
39597 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39598 ++ if (!vma_m) {
39599 ++ error = -ENOMEM;
39600 ++ goto fail;
39601 ++ }
39602 ++ vma->vm_flags = newflags;
39603 ++ pax_mirror_vma(vma_m, vma);
39604 ++ }
39605 ++ }
39606 ++#endif
39607 ++
39608 + /*
39609 + * First try to merge with previous and/or next vma.
39610 + */
39611 +@@ -211,6 +300,70 @@ fail:
39612 + return error;
39613 + }
39614 +
39615 ++#ifdef CONFIG_PAX_MPROTECT
39616 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
39617 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
39618 ++ *
39619 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
39620 ++ * basis because we want to allow the common case and not the special ones.
39621 ++ */
39622 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
39623 ++{
39624 ++ struct elfhdr elf_h;
39625 ++ struct elf_phdr elf_p;
39626 ++ elf_addr_t dyn_offset = 0UL;
39627 ++ elf_dyn dyn;
39628 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
39629 ++
39630 ++#ifndef CONFIG_PAX_NOELFRELOCS
39631 ++ if ((vma->vm_start != start) ||
39632 ++ !vma->vm_file ||
39633 ++ !(vma->vm_flags & VM_MAYEXEC) ||
39634 ++ (vma->vm_flags & VM_MAYNOTWRITE))
39635 ++#endif
39636 ++
39637 ++ return;
39638 ++
39639 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
39640 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
39641 ++
39642 ++#ifdef CONFIG_PAX_ETEXECRELOCS
39643 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
39644 ++#else
39645 ++ elf_h.e_type != ET_DYN ||
39646 ++#endif
39647 ++
39648 ++ !elf_check_arch(&elf_h) ||
39649 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
39650 ++ elf_h.e_phnum > j)
39651 ++ return;
39652 ++
39653 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
39654 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
39655 ++ return;
39656 ++ if (elf_p.p_type == PT_DYNAMIC) {
39657 ++ dyn_offset = elf_p.p_offset;
39658 ++ j = i;
39659 ++ }
39660 ++ }
39661 ++ if (elf_h.e_phnum <= j)
39662 ++ return;
39663 ++
39664 ++ i = 0UL;
39665 ++ do {
39666 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
39667 ++ return;
39668 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
39669 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
39670 ++ gr_log_textrel(vma);
39671 ++ return;
39672 ++ }
39673 ++ i++;
39674 ++ } while (dyn.d_tag != DT_NULL);
39675 ++ return;
39676 ++}
39677 ++#endif
39678 ++
39679 + asmlinkage long
39680 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39681 + {
39682 +@@ -230,6 +383,17 @@ sys_mprotect(unsigned long start, size_t
39683 + end = start + len;
39684 + if (end <= start)
39685 + return -ENOMEM;
39686 ++
39687 ++#ifdef CONFIG_PAX_SEGMEXEC
39688 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
39689 ++ if (end > SEGMEXEC_TASK_SIZE)
39690 ++ return -EINVAL;
39691 ++ } else
39692 ++#endif
39693 ++
39694 ++ if (end > TASK_SIZE)
39695 ++ return -EINVAL;
39696 ++
39697 + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
39698 + return -EINVAL;
39699 +
39700 +@@ -237,7 +401,7 @@ sys_mprotect(unsigned long start, size_t
39701 + /*
39702 + * Does the application expect PROT_READ to imply PROT_EXEC:
39703 + */
39704 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
39705 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
39706 + prot |= PROT_EXEC;
39707 +
39708 + vm_flags = calc_vm_prot_bits(prot);
39709 +@@ -269,6 +433,16 @@ sys_mprotect(unsigned long start, size_t
39710 + if (start > vma->vm_start)
39711 + prev = vma;
39712 +
39713 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
39714 ++ error = -EACCES;
39715 ++ goto out;
39716 ++ }
39717 ++
39718 ++#ifdef CONFIG_PAX_MPROTECT
39719 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
39720 ++ pax_handle_maywrite(vma, start);
39721 ++#endif
39722 ++
39723 + for (nstart = start ; ; ) {
39724 + unsigned long newflags;
39725 +
39726 +@@ -282,6 +456,12 @@ sys_mprotect(unsigned long start, size_t
39727 + goto out;
39728 + }
39729 +
39730 ++#ifdef CONFIG_PAX_MPROTECT
39731 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
39732 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
39733 ++ newflags &= ~VM_MAYWRITE;
39734 ++#endif
39735 ++
39736 + error = security_file_mprotect(vma, reqprot, prot);
39737 + if (error)
39738 + goto out;
39739 +@@ -292,6 +472,9 @@ sys_mprotect(unsigned long start, size_t
39740 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
39741 + if (error)
39742 + goto out;
39743 ++
39744 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
39745 ++
39746 + nstart = tmp;
39747 +
39748 + if (nstart < prev->vm_end)
39749 +diff -urNp a/mm/mremap.c b/mm/mremap.c
39750 +--- a/mm/mremap.c 2008-08-20 11:16:13.000000000 -0700
39751 ++++ b/mm/mremap.c 2008-08-20 18:36:57.000000000 -0700
39752 +@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
39753 + continue;
39754 + pte = ptep_clear_flush(vma, old_addr, old_pte);
39755 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
39756 ++
39757 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
39758 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
39759 ++ pte = pte_exprotect(pte);
39760 ++#endif
39761 ++
39762 + set_pte_at(mm, new_addr, new_pte, pte);
39763 + }
39764 +
39765 +@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
39766 + struct vm_area_struct *vma;
39767 + unsigned long ret = -EINVAL;
39768 + unsigned long charged = 0;
39769 ++ unsigned long pax_task_size = TASK_SIZE;
39770 +
39771 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
39772 + goto out;
39773 +@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
39774 + if (!new_len)
39775 + goto out;
39776 +
39777 ++#ifdef CONFIG_PAX_SEGMEXEC
39778 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
39779 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
39780 ++#endif
39781 ++
39782 ++ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
39783 ++ old_len > pax_task_size || addr > pax_task_size-old_len)
39784 ++ goto out;
39785 ++
39786 + /* new_addr is only valid if MREMAP_FIXED is specified */
39787 + if (flags & MREMAP_FIXED) {
39788 + if (new_addr & ~PAGE_MASK)
39789 +@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
39790 + if (!(flags & MREMAP_MAYMOVE))
39791 + goto out;
39792 +
39793 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
39794 ++ if (new_addr > pax_task_size - new_len)
39795 + goto out;
39796 +
39797 + /* Check if the location we're moving into overlaps the
39798 + * old location at all, and fail if it does.
39799 + */
39800 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
39801 +- goto out;
39802 +-
39803 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
39804 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
39805 + goto out;
39806 +
39807 + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
39808 +@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
39809 + ret = -EINVAL;
39810 + goto out;
39811 + }
39812 ++
39813 ++#ifdef CONFIG_PAX_SEGMEXEC
39814 ++ if (pax_find_mirror_vma(vma)) {
39815 ++ ret = -EINVAL;
39816 ++ goto out;
39817 ++ }
39818 ++#endif
39819 ++
39820 + /* We can't remap across vm area boundaries */
39821 + if (old_len > vma->vm_end - addr)
39822 + goto out;
39823 +@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
39824 + if (old_len == vma->vm_end - addr &&
39825 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
39826 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
39827 +- unsigned long max_addr = TASK_SIZE;
39828 ++ unsigned long max_addr = pax_task_size;
39829 + if (vma->vm_next)
39830 + max_addr = vma->vm_next->vm_start;
39831 + /* can we just expand the current mapping? */
39832 +@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
39833 + addr + new_len);
39834 + }
39835 + ret = addr;
39836 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
39837 + goto out;
39838 + }
39839 + }
39840 +@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
39841 + */
39842 + ret = -ENOMEM;
39843 + if (flags & MREMAP_MAYMOVE) {
39844 ++ unsigned long map_flags = 0;
39845 + if (!(flags & MREMAP_FIXED)) {
39846 +- unsigned long map_flags = 0;
39847 + if (vma->vm_flags & VM_MAYSHARE)
39848 + map_flags |= MAP_SHARED;
39849 +
39850 +@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
39851 + if (ret)
39852 + goto out;
39853 + }
39854 ++ map_flags = vma->vm_flags;
39855 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
39856 ++ if (!(ret & ~PAGE_MASK)) {
39857 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
39858 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
39859 ++ }
39860 + }
39861 + out:
39862 + if (ret & ~PAGE_MASK)
39863 +diff -urNp a/mm/nommu.c b/mm/nommu.c
39864 +--- a/mm/nommu.c 2008-08-20 11:16:13.000000000 -0700
39865 ++++ b/mm/nommu.c 2008-08-20 18:36:57.000000000 -0700
39866 +@@ -405,15 +405,6 @@ struct vm_area_struct *find_vma(struct m
39867 + }
39868 + EXPORT_SYMBOL(find_vma);
39869 +
39870 +-/*
39871 +- * find a VMA
39872 +- * - we don't extend stack VMAs under NOMMU conditions
39873 +- */
39874 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
39875 +-{
39876 +- return find_vma(mm, addr);
39877 +-}
39878 +-
39879 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
39880 + {
39881 + return -ENOMEM;
39882 +diff -urNp a/mm/page_alloc.c b/mm/page_alloc.c
39883 +--- a/mm/page_alloc.c 2008-08-20 11:16:13.000000000 -0700
39884 ++++ b/mm/page_alloc.c 2008-08-20 18:36:57.000000000 -0700
39885 +@@ -514,9 +514,20 @@ static void free_pages_bulk(struct zone
39886 +
39887 + static void free_one_page(struct zone *zone, struct page *page, int order)
39888 + {
39889 ++
39890 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39891 ++ unsigned long index = 1UL << order;
39892 ++#endif
39893 ++
39894 + spin_lock(&zone->lock);
39895 + zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
39896 + zone->pages_scanned = 0;
39897 ++
39898 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39899 ++ for (; index; --index)
39900 ++ sanitize_highpage(page + index - 1);
39901 ++#endif
39902 ++
39903 + __free_one_page(page, zone, order);
39904 + spin_unlock(&zone->lock);
39905 + }
39906 +@@ -641,8 +652,10 @@ static int prep_new_page(struct page *pa
39907 + arch_alloc_page(page, order);
39908 + kernel_map_pages(page, 1 << order, 1);
39909 +
39910 ++#ifndef CONFIG_PAX_MEMORY_SANITIZE
39911 + if (gfp_flags & __GFP_ZERO)
39912 + prep_zero_page(page, order, gfp_flags);
39913 ++#endif
39914 +
39915 + if (order && (gfp_flags & __GFP_COMP))
39916 + prep_compound_page(page, order);
39917 +@@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
39918 + list_add(&page->lru, &pcp->list);
39919 + set_page_private(page, get_pageblock_migratetype(page));
39920 + pcp->count++;
39921 ++
39922 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39923 ++ sanitize_highpage(page);
39924 ++#endif
39925 ++
39926 + if (pcp->count >= pcp->high) {
39927 + free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
39928 + pcp->count -= pcp->batch;
39929 +diff -urNp a/mm/rmap.c b/mm/rmap.c
39930 +--- a/mm/rmap.c 2008-08-20 11:16:13.000000000 -0700
39931 ++++ b/mm/rmap.c 2008-08-20 18:36:57.000000000 -0700
39932 +@@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
39933 + struct mm_struct *mm = vma->vm_mm;
39934 + struct anon_vma *allocated, *locked;
39935 +
39936 ++#ifdef CONFIG_PAX_SEGMEXEC
39937 ++ struct vm_area_struct *vma_m;
39938 ++#endif
39939 ++
39940 + anon_vma = find_mergeable_anon_vma(vma);
39941 + if (anon_vma) {
39942 + allocated = NULL;
39943 +@@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
39944 + /* page_table_lock to protect against threads */
39945 + spin_lock(&mm->page_table_lock);
39946 + if (likely(!vma->anon_vma)) {
39947 ++
39948 ++#ifdef CONFIG_PAX_SEGMEXEC
39949 ++ vma_m = pax_find_mirror_vma(vma);
39950 ++ if (vma_m) {
39951 ++ vma_m->anon_vma = anon_vma;
39952 ++ __anon_vma_link(vma_m);
39953 ++ }
39954 ++#endif
39955 ++
39956 + vma->anon_vma = anon_vma;
39957 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
39958 + allocated = NULL;
39959 +diff -urNp a/mm/shmem.c b/mm/shmem.c
39960 +--- a/mm/shmem.c 2008-08-20 11:16:13.000000000 -0700
39961 ++++ b/mm/shmem.c 2008-08-20 18:36:57.000000000 -0700
39962 +@@ -2518,7 +2518,7 @@ static struct file_system_type tmpfs_fs_
39963 + .get_sb = shmem_get_sb,
39964 + .kill_sb = kill_litter_super,
39965 + };
39966 +-static struct vfsmount *shm_mnt;
39967 ++struct vfsmount *shm_mnt;
39968 +
39969 + static int __init init_tmpfs(void)
39970 + {
39971 +diff -urNp a/mm/slab.c b/mm/slab.c
39972 +--- a/mm/slab.c 2008-08-20 11:16:13.000000000 -0700
39973 ++++ b/mm/slab.c 2008-08-20 18:36:57.000000000 -0700
39974 +@@ -305,7 +305,7 @@ struct kmem_list3 {
39975 + * Need this for bootstrapping a per node allocator.
39976 + */
39977 + #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
39978 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
39979 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
39980 + #define CACHE_CACHE 0
39981 + #define SIZE_AC MAX_NUMNODES
39982 + #define SIZE_L3 (2 * MAX_NUMNODES)
39983 +@@ -654,14 +654,14 @@ struct cache_names {
39984 + static struct cache_names __initdata cache_names[] = {
39985 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
39986 + #include <linux/kmalloc_sizes.h>
39987 +- {NULL,}
39988 ++ {NULL, NULL}
39989 + #undef CACHE
39990 + };
39991 +
39992 + static struct arraycache_init initarray_cache __initdata =
39993 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
39994 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
39995 + static struct arraycache_init initarray_generic =
39996 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
39997 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
39998 +
39999 + /* internal cache of cache description objs */
40000 + static struct kmem_cache cache_cache = {
40001 +@@ -3007,7 +3007,7 @@ retry:
40002 + * there must be at least one object available for
40003 + * allocation.
40004 + */
40005 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
40006 ++ BUG_ON(slabp->inuse >= cachep->num);
40007 +
40008 + while (slabp->inuse < cachep->num && batchcount--) {
40009 + STATS_INC_ALLOCED(cachep);
40010 +diff -urNp a/mm/swap.c b/mm/swap.c
40011 +--- a/mm/swap.c 2008-08-20 11:16:13.000000000 -0700
40012 ++++ b/mm/swap.c 2008-08-20 18:36:57.000000000 -0700
40013 +@@ -34,9 +34,9 @@
40014 + /* How many pages do we try to swap or page in/out together? */
40015 + int page_cluster;
40016 +
40017 +-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
40018 +-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
40019 +-static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
40020 ++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
40021 ++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
40022 ++static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
40023 +
40024 + /*
40025 + * This path almost never happens for VM activity - pages are normally
40026 +diff -urNp a/mm/tiny-shmem.c b/mm/tiny-shmem.c
40027 +--- a/mm/tiny-shmem.c 2008-08-20 11:16:13.000000000 -0700
40028 ++++ b/mm/tiny-shmem.c 2008-08-20 18:36:57.000000000 -0700
40029 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
40030 + .kill_sb = kill_litter_super,
40031 + };
40032 +
40033 +-static struct vfsmount *shm_mnt;
40034 ++struct vfsmount *shm_mnt;
40035 +
40036 + static int __init init_tmpfs(void)
40037 + {
40038 +diff -urNp a/mm/vmalloc.c b/mm/vmalloc.c
40039 +--- a/mm/vmalloc.c 2008-08-20 11:16:13.000000000 -0700
40040 ++++ b/mm/vmalloc.c 2008-08-20 18:36:57.000000000 -0700
40041 +@@ -246,20 +246,15 @@ static struct vm_struct *__get_vm_area_n
40042 + (unsigned long)tmp->addr, align);
40043 + continue;
40044 + }
40045 +- if ((size + addr) < addr)
40046 +- goto out;
40047 + if (size + addr <= (unsigned long)tmp->addr)
40048 +- goto found;
40049 ++ break;
40050 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
40051 +- if (addr > end - size)
40052 +- goto out;
40053 + }
40054 + if ((size + addr) < addr)
40055 + goto out;
40056 + if (addr > end - size)
40057 + goto out;
40058 +
40059 +-found:
40060 + area->next = *p;
40061 + *p = area;
40062 +
40063 +diff -urNp a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
40064 +--- a/net/bridge/br_stp_if.c 2008-08-20 11:16:13.000000000 -0700
40065 ++++ b/net/bridge/br_stp_if.c 2008-08-20 18:36:57.000000000 -0700
40066 +@@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
40067 + char *envp[] = { NULL };
40068 +
40069 + if (br->stp_enabled == BR_USER_STP) {
40070 +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
40071 ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
40072 + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
40073 + br->dev->name, r);
40074 +
40075 +diff -urNp a/net/core/flow.c b/net/core/flow.c
40076 +--- a/net/core/flow.c 2008-08-20 11:16:13.000000000 -0700
40077 ++++ b/net/core/flow.c 2008-08-20 18:36:57.000000000 -0700
40078 +@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
40079 +
40080 + static u32 flow_hash_shift;
40081 + #define flow_hash_size (1 << flow_hash_shift)
40082 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
40083 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
40084 +
40085 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
40086 +
40087 +@@ -53,7 +53,7 @@ struct flow_percpu_info {
40088 + u32 hash_rnd;
40089 + int count;
40090 + };
40091 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
40092 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
40093 +
40094 + #define flow_hash_rnd_recalc(cpu) \
40095 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
40096 +@@ -70,7 +70,7 @@ struct flow_flush_info {
40097 + atomic_t cpuleft;
40098 + struct completion completion;
40099 + };
40100 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
40101 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
40102 +
40103 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
40104 +
40105 +diff -urNp a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
40106 +--- a/net/dccp/ccids/ccid3.c 2008-08-20 11:16:13.000000000 -0700
40107 ++++ b/net/dccp/ccids/ccid3.c 2008-08-20 18:36:57.000000000 -0700
40108 +@@ -43,7 +43,7 @@
40109 + static int ccid3_debug;
40110 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
40111 + #else
40112 +-#define ccid3_pr_debug(format, a...)
40113 ++#define ccid3_pr_debug(format, a...) do {} while (0)
40114 + #endif
40115 +
40116 + /*
40117 +diff -urNp a/net/dccp/dccp.h b/net/dccp/dccp.h
40118 +--- a/net/dccp/dccp.h 2008-08-20 11:16:13.000000000 -0700
40119 ++++ b/net/dccp/dccp.h 2008-08-20 18:36:57.000000000 -0700
40120 +@@ -43,8 +43,8 @@ extern int dccp_debug;
40121 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
40122 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
40123 + #else
40124 +-#define dccp_pr_debug(format, a...)
40125 +-#define dccp_pr_debug_cat(format, a...)
40126 ++#define dccp_pr_debug(format, a...) do {} while (0)
40127 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
40128 + #endif
40129 +
40130 + extern struct inet_hashinfo dccp_hashinfo;
40131 +diff -urNp a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
40132 +--- a/net/ipv4/inet_connection_sock.c 2008-08-20 11:16:13.000000000 -0700
40133 ++++ b/net/ipv4/inet_connection_sock.c 2008-08-20 18:36:57.000000000 -0700
40134 +@@ -15,6 +15,7 @@
40135 +
40136 + #include <linux/module.h>
40137 + #include <linux/jhash.h>
40138 ++#include <linux/grsecurity.h>
40139 +
40140 + #include <net/inet_connection_sock.h>
40141 + #include <net/inet_hashtables.h>
40142 +diff -urNp a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
40143 +--- a/net/ipv4/inet_hashtables.c 2008-08-20 11:16:13.000000000 -0700
40144 ++++ b/net/ipv4/inet_hashtables.c 2008-08-20 18:36:57.000000000 -0700
40145 +@@ -18,11 +18,14 @@
40146 + #include <linux/sched.h>
40147 + #include <linux/slab.h>
40148 + #include <linux/wait.h>
40149 ++#include <linux/grsecurity.h>
40150 +
40151 + #include <net/inet_connection_sock.h>
40152 + #include <net/inet_hashtables.h>
40153 + #include <net/ip.h>
40154 +
40155 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
40156 ++
40157 + /*
40158 + * Allocate and initialize a new local port bind bucket.
40159 + * The bindhash mutex for snum's hash chain must be held here.
40160 +@@ -467,6 +470,8 @@ ok:
40161 + }
40162 + spin_unlock(&head->lock);
40163 +
40164 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
40165 ++
40166 + if (tw) {
40167 + inet_twsk_deschedule(tw, death_row);
40168 + inet_twsk_put(tw);
40169 +diff -urNp a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
40170 +--- a/net/ipv4/netfilter/Kconfig 2008-08-20 11:16:13.000000000 -0700
40171 ++++ b/net/ipv4/netfilter/Kconfig 2008-08-20 18:36:57.000000000 -0700
40172 +@@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
40173 + If you want to compile it as a module, say M here and read
40174 + <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
40175 +
40176 ++config IP_NF_MATCH_STEALTH
40177 ++ tristate "stealth match support"
40178 ++ depends on IP_NF_IPTABLES
40179 ++ help
40180 ++ Enabling this option will drop all syn packets coming to unserved tcp
40181 ++ ports as well as all packets coming to unserved udp ports. If you
40182 ++ are using your system to route any type of packets (ie. via NAT)
40183 ++ you should put this module at the end of your ruleset, since it will
40184 ++ drop packets that aren't going to ports that are listening on your
40185 ++ machine itself, it doesn't take into account that the packet might be
40186 ++ destined for someone on your internal network if you're using NAT for
40187 ++ instance.
40188 ++
40189 ++ To compile it as a module, choose M here. If unsure, say N.
40190 ++
40191 + # `filter', generic and specific targets
40192 + config IP_NF_FILTER
40193 + tristate "Packet filtering"
40194 +@@ -380,4 +395,3 @@ config IP_NF_ARP_MANGLE
40195 + hardware and network addresses.
40196 +
40197 + endmenu
40198 +-
40199 +diff -urNp a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
40200 +--- a/net/ipv4/netfilter/Makefile 2008-08-20 11:16:13.000000000 -0700
40201 ++++ b/net/ipv4/netfilter/Makefile 2008-08-20 18:36:57.000000000 -0700
40202 +@@ -55,6 +55,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
40203 + obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
40204 + obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
40205 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
40206 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
40207 + obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
40208 + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
40209 +
40210 +diff -urNp a/net/ipv4/netfilter/ipt_stealth.c b/net/ipv4/netfilter/ipt_stealth.c
40211 +--- a/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 16:00:00.000000000 -0800
40212 ++++ b/net/ipv4/netfilter/ipt_stealth.c 2008-08-20 18:36:57.000000000 -0700
40213 +@@ -0,0 +1,114 @@
40214 ++/* Kernel module to add stealth support.
40215 ++ *
40216 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
40217 ++ *
40218 ++ */
40219 ++
40220 ++#include <linux/kernel.h>
40221 ++#include <linux/module.h>
40222 ++#include <linux/skbuff.h>
40223 ++#include <linux/net.h>
40224 ++#include <linux/sched.h>
40225 ++#include <linux/inet.h>
40226 ++#include <linux/stddef.h>
40227 ++
40228 ++#include <net/ip.h>
40229 ++#include <net/sock.h>
40230 ++#include <net/tcp.h>
40231 ++#include <net/udp.h>
40232 ++#include <net/route.h>
40233 ++#include <net/inet_common.h>
40234 ++
40235 ++#include <linux/netfilter_ipv4/ip_tables.h>
40236 ++
40237 ++MODULE_LICENSE("GPL");
40238 ++
40239 ++extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
40240 ++
40241 ++static bool
40242 ++match(const struct sk_buff *skb,
40243 ++ const struct net_device *in,
40244 ++ const struct net_device *out,
40245 ++ const struct xt_match *match,
40246 ++ const void *matchinfo,
40247 ++ int offset,
40248 ++ unsigned int protoff,
40249 ++ bool *hotdrop)
40250 ++{
40251 ++ struct iphdr *ip = ip_hdr(skb);
40252 ++ struct tcphdr th;
40253 ++ struct udphdr uh;
40254 ++ struct sock *sk = NULL;
40255 ++
40256 ++ if (!ip || offset) return false;
40257 ++
40258 ++ switch(ip->protocol) {
40259 ++ case IPPROTO_TCP:
40260 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
40261 ++ *hotdrop = true;
40262 ++ return false;
40263 ++ }
40264 ++ if (!(th.syn && !th.ack)) return false;
40265 ++ sk = inet_lookup_listener(skb->dev->nd_net, &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
40266 ++ break;
40267 ++ case IPPROTO_UDP:
40268 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
40269 ++ *hotdrop = true;
40270 ++ return false;
40271 ++ }
40272 ++ sk = udp_v4_lookup(skb->dev->nd_net, ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
40273 ++ break;
40274 ++ default:
40275 ++ return false;
40276 ++ }
40277 ++
40278 ++ if(!sk) // port is being listened on, match this
40279 ++ return true;
40280 ++ else {
40281 ++ sock_put(sk);
40282 ++ return false;
40283 ++ }
40284 ++}
40285 ++
40286 ++/* Called when user tries to insert an entry of this type. */
40287 ++static bool
40288 ++checkentry(const char *tablename,
40289 ++ const void *nip,
40290 ++ const struct xt_match *match,
40291 ++ void *matchinfo,
40292 ++ unsigned int hook_mask)
40293 ++{
40294 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
40295 ++
40296 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
40297 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
40298 ++ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
40299 ++ return true;
40300 ++
40301 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
40302 ++
40303 ++ return false;
40304 ++}
40305 ++
40306 ++
40307 ++static struct xt_match stealth_match __read_mostly = {
40308 ++ .name = "stealth",
40309 ++ .family = AF_INET,
40310 ++ .match = match,
40311 ++ .checkentry = checkentry,
40312 ++ .destroy = NULL,
40313 ++ .me = THIS_MODULE
40314 ++};
40315 ++
40316 ++static int __init init(void)
40317 ++{
40318 ++ return xt_register_match(&stealth_match);
40319 ++}
40320 ++
40321 ++static void __exit fini(void)
40322 ++{
40323 ++ xt_unregister_match(&stealth_match);
40324 ++}
40325 ++
40326 ++module_init(init);
40327 ++module_exit(fini);
40328 +diff -urNp a/net/ipv4/tcp.c b/net/ipv4/tcp.c
40329 +--- a/net/ipv4/tcp.c 2008-08-20 11:16:13.000000000 -0700
40330 ++++ b/net/ipv4/tcp.c 2008-08-20 18:36:57.000000000 -0700
40331 +@@ -1206,7 +1206,8 @@ int tcp_read_sock(struct sock *sk, read_
40332 + return -ENOTCONN;
40333 + while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
40334 + if (offset < skb->len) {
40335 +- size_t used, len;
40336 ++ int used;
40337 ++ size_t len;
40338 +
40339 + len = skb->len - offset;
40340 + /* Stop reading if we hit a patch of urgent data */
40341 +diff -urNp a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
40342 +--- a/net/ipv4/tcp_ipv4.c 2008-08-20 11:16:13.000000000 -0700
40343 ++++ b/net/ipv4/tcp_ipv4.c 2008-08-20 18:36:57.000000000 -0700
40344 +@@ -61,6 +61,7 @@
40345 + #include <linux/jhash.h>
40346 + #include <linux/init.h>
40347 + #include <linux/times.h>
40348 ++#include <linux/grsecurity.h>
40349 +
40350 + #include <net/net_namespace.h>
40351 + #include <net/icmp.h>
40352 +diff -urNp a/net/ipv4/udp.c b/net/ipv4/udp.c
40353 +--- a/net/ipv4/udp.c 2008-08-20 11:16:13.000000000 -0700
40354 ++++ b/net/ipv4/udp.c 2008-08-20 18:36:57.000000000 -0700
40355 +@@ -99,6 +99,7 @@
40356 + #include <linux/skbuff.h>
40357 + #include <linux/proc_fs.h>
40358 + #include <linux/seq_file.h>
40359 ++#include <linux/grsecurity.h>
40360 + #include <net/net_namespace.h>
40361 + #include <net/icmp.h>
40362 + #include <net/route.h>
40363 +@@ -106,6 +107,11 @@
40364 + #include <net/xfrm.h>
40365 + #include "udp_impl.h"
40366 +
40367 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
40368 ++ const struct sk_buff *skb);
40369 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
40370 ++ const struct sockaddr_in *addr);
40371 ++
40372 + /*
40373 + * Snmp MIB for the UDP layer
40374 + */
40375 +@@ -314,6 +320,13 @@ static struct sock *__udp4_lib_lookup(st
40376 + return result;
40377 + }
40378 +
40379 ++struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
40380 ++ __be32 daddr, __be16 dport, int dif)
40381 ++{
40382 ++ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
40383 ++}
40384 ++
40385 ++
40386 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
40387 + __be16 loc_port, __be32 loc_addr,
40388 + __be16 rmt_port, __be32 rmt_addr,
40389 +@@ -600,9 +613,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
40390 + dport = usin->sin_port;
40391 + if (dport == 0)
40392 + return -EINVAL;
40393 ++
40394 ++ if (!gr_search_udp_sendmsg(sk, usin))
40395 ++ return -EPERM;
40396 + } else {
40397 + if (sk->sk_state != TCP_ESTABLISHED)
40398 + return -EDESTADDRREQ;
40399 ++
40400 ++ if (!gr_search_udp_sendmsg(sk, NULL))
40401 ++ return -EPERM;
40402 ++
40403 + daddr = inet->daddr;
40404 + dport = inet->dport;
40405 + /* Open fast path for connected socket.
40406 +@@ -864,6 +884,11 @@ try_again:
40407 + if (!skb)
40408 + goto out;
40409 +
40410 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
40411 ++ err = -EPERM;
40412 ++ goto out_free;
40413 ++ }
40414 ++
40415 + ulen = skb->len - sizeof(struct udphdr);
40416 + copied = len;
40417 + if (copied > ulen)
40418 +diff -urNp a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
40419 +--- a/net/ipv6/exthdrs.c 2008-08-20 11:16:13.000000000 -0700
40420 ++++ b/net/ipv6/exthdrs.c 2008-08-20 18:36:57.000000000 -0700
40421 +@@ -626,7 +626,7 @@ static struct tlvtype_proc tlvprochopopt
40422 + .type = IPV6_TLV_JUMBO,
40423 + .func = ipv6_hop_jumbo,
40424 + },
40425 +- { -1, }
40426 ++ { -1, NULL }
40427 + };
40428 +
40429 + int ipv6_parse_hopopts(struct sk_buff *skb)
40430 +diff -urNp a/net/ipv6/raw.c b/net/ipv6/raw.c
40431 +--- a/net/ipv6/raw.c 2008-08-20 11:16:13.000000000 -0700
40432 ++++ b/net/ipv6/raw.c 2008-08-20 18:36:57.000000000 -0700
40433 +@@ -617,7 +617,7 @@ out:
40434 + return err;
40435 + }
40436 +
40437 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
40438 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
40439 + struct flowi *fl, struct rt6_info *rt,
40440 + unsigned int flags)
40441 + {
40442 +diff -urNp a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
40443 +--- a/net/irda/ircomm/ircomm_tty.c 2008-08-20 11:16:13.000000000 -0700
40444 ++++ b/net/irda/ircomm/ircomm_tty.c 2008-08-20 18:36:57.000000000 -0700
40445 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
40446 + IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
40447 +
40448 + line = tty->index;
40449 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
40450 ++ if (line >= IRCOMM_TTY_PORTS) {
40451 + return -ENODEV;
40452 + }
40453 +
40454 +diff -urNp a/net/mac80211/regdomain.c b/net/mac80211/regdomain.c
40455 +--- a/net/mac80211/regdomain.c 2008-08-20 11:16:13.000000000 -0700
40456 ++++ b/net/mac80211/regdomain.c 2008-08-20 18:36:57.000000000 -0700
40457 +@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
40458 + { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
40459 + { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
40460 + { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
40461 +- { 0 }
40462 ++ { 0, 0, 0, 0 }
40463 + };
40464 +
40465 + static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
40466 + { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
40467 + { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
40468 + { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
40469 +- { 0 }
40470 ++ { 0, 0, 0, 0 }
40471 + };
40472 +
40473 +
40474 +diff -urNp a/net/sctp/socket.c b/net/sctp/socket.c
40475 +--- a/net/sctp/socket.c 2008-08-20 11:16:13.000000000 -0700
40476 ++++ b/net/sctp/socket.c 2008-08-20 18:36:57.000000000 -0700
40477 +@@ -1391,7 +1391,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
40478 + struct sctp_sndrcvinfo *sinfo;
40479 + struct sctp_initmsg *sinit;
40480 + sctp_assoc_t associd = 0;
40481 +- sctp_cmsgs_t cmsgs = { NULL };
40482 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
40483 + int err;
40484 + sctp_scope_t scope;
40485 + long timeo;
40486 +diff -urNp a/net/socket.c b/net/socket.c
40487 +--- a/net/socket.c 2008-08-20 11:16:13.000000000 -0700
40488 ++++ b/net/socket.c 2008-08-20 18:36:57.000000000 -0700
40489 +@@ -85,6 +85,7 @@
40490 + #include <linux/audit.h>
40491 + #include <linux/wireless.h>
40492 + #include <linux/nsproxy.h>
40493 ++#include <linux/in.h>
40494 +
40495 + #include <asm/uaccess.h>
40496 + #include <asm/unistd.h>
40497 +@@ -94,6 +95,21 @@
40498 + #include <net/sock.h>
40499 + #include <linux/netfilter.h>
40500 +
40501 ++extern void gr_attach_curr_ip(const struct sock *sk);
40502 ++extern int gr_handle_sock_all(const int family, const int type,
40503 ++ const int protocol);
40504 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
40505 ++extern int gr_handle_sock_server_other(const struct socket *sck);
40506 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
40507 ++extern int gr_search_connect(const struct socket * sock,
40508 ++ const struct sockaddr_in * addr);
40509 ++extern int gr_search_bind(const struct socket * sock,
40510 ++ const struct sockaddr_in * addr);
40511 ++extern int gr_search_listen(const struct socket * sock);
40512 ++extern int gr_search_accept(const struct socket * sock);
40513 ++extern int gr_search_socket(const int domain, const int type,
40514 ++ const int protocol);
40515 ++
40516 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
40517 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
40518 + unsigned long nr_segs, loff_t pos);
40519 +@@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
40520 + mnt);
40521 + }
40522 +
40523 +-static struct vfsmount *sock_mnt __read_mostly;
40524 ++struct vfsmount *sock_mnt __read_mostly;
40525 +
40526 + static struct file_system_type sock_fs_type = {
40527 + .name = "sockfs",
40528 +@@ -1218,6 +1234,16 @@ asmlinkage long sys_socket(int family, i
40529 + int retval;
40530 + struct socket *sock;
40531 +
40532 ++ if(!gr_search_socket(family, type, protocol)) {
40533 ++ retval = -EACCES;
40534 ++ goto out;
40535 ++ }
40536 ++
40537 ++ if (gr_handle_sock_all(family, type, protocol)) {
40538 ++ retval = -EACCES;
40539 ++ goto out;
40540 ++ }
40541 ++
40542 + retval = sock_create(family, type, protocol, &sock);
40543 + if (retval < 0)
40544 + goto out;
40545 +@@ -1348,6 +1374,12 @@ asmlinkage long sys_bind(int fd, struct
40546 + if (sock) {
40547 + err = move_addr_to_kernel(umyaddr, addrlen, address);
40548 + if (err >= 0) {
40549 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
40550 ++ gr_handle_sock_server((struct sockaddr *)address)) {
40551 ++ err = -EACCES;
40552 ++ goto error;
40553 ++ }
40554 ++
40555 + err = security_socket_bind(sock,
40556 + (struct sockaddr *)address,
40557 + addrlen);
40558 +@@ -1356,6 +1388,7 @@ asmlinkage long sys_bind(int fd, struct
40559 + (struct sockaddr *)
40560 + address, addrlen);
40561 + }
40562 ++error:
40563 + fput_light(sock->file, fput_needed);
40564 + }
40565 + return err;
40566 +@@ -1379,10 +1412,17 @@ asmlinkage long sys_listen(int fd, int b
40567 + if ((unsigned)backlog > somaxconn)
40568 + backlog = somaxconn;
40569 +
40570 ++ if (gr_handle_sock_server_other(sock) ||
40571 ++ !gr_search_listen(sock)) {
40572 ++ err = -EPERM;
40573 ++ goto error;
40574 ++ }
40575 ++
40576 + err = security_socket_listen(sock, backlog);
40577 + if (!err)
40578 + err = sock->ops->listen(sock, backlog);
40579 +
40580 ++error:
40581 + fput_light(sock->file, fput_needed);
40582 + }
40583 + return err;
40584 +@@ -1419,6 +1459,13 @@ asmlinkage long sys_accept(int fd, struc
40585 + newsock->type = sock->type;
40586 + newsock->ops = sock->ops;
40587 +
40588 ++ if (gr_handle_sock_server_other(sock) ||
40589 ++ !gr_search_accept(sock)) {
40590 ++ err = -EPERM;
40591 ++ sock_release(newsock);
40592 ++ goto out_put;
40593 ++ }
40594 ++
40595 + /*
40596 + * We don't need try_module_get here, as the listening socket (sock)
40597 + * has the protocol module (sock->ops->owner) held.
40598 +@@ -1462,6 +1509,7 @@ asmlinkage long sys_accept(int fd, struc
40599 + err = newfd;
40600 +
40601 + security_socket_post_accept(sock, newsock);
40602 ++ gr_attach_curr_ip(newsock->sk);
40603 +
40604 + out_put:
40605 + fput_light(sock->file, fput_needed);
40606 +@@ -1495,6 +1543,7 @@ asmlinkage long sys_connect(int fd, stru
40607 + {
40608 + struct socket *sock;
40609 + char address[MAX_SOCK_ADDR];
40610 ++ struct sockaddr *sck;
40611 + int err, fput_needed;
40612 +
40613 + sock = sockfd_lookup_light(fd, &err, &fput_needed);
40614 +@@ -1504,6 +1553,13 @@ asmlinkage long sys_connect(int fd, stru
40615 + if (err < 0)
40616 + goto out_put;
40617 +
40618 ++ sck = (struct sockaddr *)address;
40619 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
40620 ++ gr_handle_sock_client(sck)) {
40621 ++ err = -EACCES;
40622 ++ goto out_put;
40623 ++ }
40624 ++
40625 + err =
40626 + security_socket_connect(sock, (struct sockaddr *)address, addrlen);
40627 + if (err)
40628 +@@ -1770,6 +1826,7 @@ asmlinkage long sys_shutdown(int fd, int
40629 + err = sock->ops->shutdown(sock, how);
40630 + fput_light(sock->file, fput_needed);
40631 + }
40632 ++
40633 + return err;
40634 + }
40635 +
40636 +diff -urNp a/net/unix/af_unix.c b/net/unix/af_unix.c
40637 +--- a/net/unix/af_unix.c 2008-08-20 11:16:13.000000000 -0700
40638 ++++ b/net/unix/af_unix.c 2008-08-20 18:36:57.000000000 -0700
40639 +@@ -116,6 +116,7 @@
40640 + #include <linux/mount.h>
40641 + #include <net/checksum.h>
40642 + #include <linux/security.h>
40643 ++#include <linux/grsecurity.h>
40644 +
40645 + static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
40646 + static DEFINE_SPINLOCK(unix_table_lock);
40647 +@@ -720,6 +721,12 @@ static struct sock *unix_find_other(stru
40648 + err = -ECONNREFUSED;
40649 + if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
40650 + goto put_fail;
40651 ++
40652 ++ if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
40653 ++ err = -EACCES;
40654 ++ goto put_fail;
40655 ++ }
40656 ++
40657 + u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
40658 + if (!u)
40659 + goto put_fail;
40660 +@@ -740,6 +747,13 @@ static struct sock *unix_find_other(stru
40661 + if (u) {
40662 + struct dentry *dentry;
40663 + dentry = unix_sk(u)->dentry;
40664 ++
40665 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
40666 ++ err = -EPERM;
40667 ++ sock_put(u);
40668 ++ goto fail;
40669 ++ }
40670 ++
40671 + if (dentry)
40672 + touch_atime(unix_sk(u)->mnt, dentry);
40673 + } else
40674 +@@ -819,9 +833,18 @@ static int unix_bind(struct socket *sock
40675 + */
40676 + mode = S_IFSOCK |
40677 + (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
40678 ++
40679 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
40680 ++ err = -EACCES;
40681 ++ goto out_mknod_dput;
40682 ++ }
40683 ++
40684 + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
40685 + if (err)
40686 + goto out_mknod_dput;
40687 ++
40688 ++ gr_handle_create(dentry, nd.path.mnt);
40689 ++
40690 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
40691 + dput(nd.path.dentry);
40692 + nd.path.dentry = dentry;
40693 +@@ -839,6 +862,10 @@ static int unix_bind(struct socket *sock
40694 + goto out_unlock;
40695 + }
40696 +
40697 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
40698 ++ sk->sk_peercred.pid = current->pid;
40699 ++#endif
40700 ++
40701 + list = &unix_socket_table[addr->hash];
40702 + } else {
40703 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
40704 +diff -urNp a/scripts/pnmtologo.c b/scripts/pnmtologo.c
40705 +--- a/scripts/pnmtologo.c 2008-08-20 11:16:13.000000000 -0700
40706 ++++ b/scripts/pnmtologo.c 2008-08-20 18:36:57.000000000 -0700
40707 +@@ -237,14 +237,14 @@ static void write_header(void)
40708 + fprintf(out, " * Linux logo %s\n", logoname);
40709 + fputs(" */\n\n", out);
40710 + fputs("#include <linux/linux_logo.h>\n\n", out);
40711 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
40712 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
40713 + logoname);
40714 + }
40715 +
40716 + static void write_footer(void)
40717 + {
40718 + fputs("\n};\n\n", out);
40719 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
40720 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
40721 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
40722 + fprintf(out, " .width\t= %d,\n", logo_width);
40723 + fprintf(out, " .height\t= %d,\n", logo_height);
40724 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
40725 + fputs("\n};\n\n", out);
40726 +
40727 + /* write logo clut */
40728 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
40729 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
40730 + logoname);
40731 + write_hex_cnt = 0;
40732 + for (i = 0; i < logo_clutsize; i++) {
40733 +diff -urNp a/security/Kconfig b/security/Kconfig
40734 +--- a/security/Kconfig 2008-08-20 11:16:13.000000000 -0700
40735 ++++ b/security/Kconfig 2008-08-20 18:36:57.000000000 -0700
40736 +@@ -4,6 +4,429 @@
40737 +
40738 + menu "Security options"
40739 +
40740 ++source grsecurity/Kconfig
40741 ++
40742 ++menu "PaX"
40743 ++
40744 ++config PAX
40745 ++ bool "Enable various PaX features"
40746 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
40747 ++ help
40748 ++ This allows you to enable various PaX features. PaX adds
40749 ++ intrusion prevention mechanisms to the kernel that reduce
40750 ++ the risks posed by exploitable memory corruption bugs.
40751 ++
40752 ++menu "PaX Control"
40753 ++ depends on PAX
40754 ++
40755 ++config PAX_SOFTMODE
40756 ++ bool 'Support soft mode'
40757 ++ help
40758 ++ Enabling this option will allow you to run PaX in soft mode, that
40759 ++ is, PaX features will not be enforced by default, only on executables
40760 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
40761 ++ is the only way to mark executables for soft mode use.
40762 ++
40763 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
40764 ++ line option on boot. Furthermore you can control various PaX features
40765 ++ at runtime via the entries in /proc/sys/kernel/pax.
40766 ++
40767 ++config PAX_EI_PAX
40768 ++ bool 'Use legacy ELF header marking'
40769 ++ help
40770 ++ Enabling this option will allow you to control PaX features on
40771 ++ a per executable basis via the 'chpax' utility available at
40772 ++ http://pax.grsecurity.net/. The control flags will be read from
40773 ++ an otherwise reserved part of the ELF header. This marking has
40774 ++ numerous drawbacks (no support for soft-mode, toolchain does not
40775 ++ know about the non-standard use of the ELF header) therefore it
40776 ++ has been deprecated in favour of PT_PAX_FLAGS support.
40777 ++
40778 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
40779 ++ program header then you MUST enable this option otherwise they
40780 ++ will not get any protection.
40781 ++
40782 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
40783 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
40784 ++
40785 ++config PAX_PT_PAX_FLAGS
40786 ++ bool 'Use ELF program header marking'
40787 ++ help
40788 ++ Enabling this option will allow you to control PaX features on
40789 ++ a per executable basis via the 'paxctl' utility available at
40790 ++ http://pax.grsecurity.net/. The control flags will be read from
40791 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
40792 ++ has the benefits of supporting both soft mode and being fully
40793 ++ integrated into the toolchain (the binutils patch is available
40794 ++ from http://pax.grsecurity.net).
40795 ++
40796 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
40797 ++ program header then you MUST enable the EI_PAX marking support
40798 ++ otherwise they will not get any protection.
40799 ++
40800 ++ Note that if you enable the legacy EI_PAX marking support as well,
40801 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
40802 ++
40803 ++choice
40804 ++ prompt 'MAC system integration'
40805 ++ default PAX_HAVE_ACL_FLAGS
40806 ++ help
40807 ++ Mandatory Access Control systems have the option of controlling
40808 ++ PaX flags on a per executable basis, choose the method supported
40809 ++ by your particular system.
40810 ++
40811 ++ - "none": if your MAC system does not interact with PaX,
40812 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
40813 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
40814 ++
40815 ++ NOTE: this option is for developers/integrators only.
40816 ++
40817 ++ config PAX_NO_ACL_FLAGS
40818 ++ bool 'none'
40819 ++
40820 ++ config PAX_HAVE_ACL_FLAGS
40821 ++ bool 'direct'
40822 ++
40823 ++ config PAX_HOOK_ACL_FLAGS
40824 ++ bool 'hook'
40825 ++endchoice
40826 ++
40827 ++endmenu
40828 ++
40829 ++menu "Non-executable pages"
40830 ++ depends on PAX
40831 ++
40832 ++config PAX_NOEXEC
40833 ++ bool "Enforce non-executable pages"
40834 ++ depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
40835 ++ help
40836 ++ By design some architectures do not allow for protecting memory
40837 ++ pages against execution or even if they do, Linux does not make
40838 ++ use of this feature. In practice this means that if a page is
40839 ++ readable (such as the stack or heap) it is also executable.
40840 ++
40841 ++ There is a well known exploit technique that makes use of this
40842 ++ fact and a common programming mistake where an attacker can
40843 ++ introduce code of his choice somewhere in the attacked program's
40844 ++ memory (typically the stack or the heap) and then execute it.
40845 ++
40846 ++ If the attacked program was running with different (typically
40847 ++ higher) privileges than that of the attacker, then he can elevate
40848 ++ his own privilege level (e.g. get a root shell, write to files for
40849 ++ which he does not have write access to, etc).
40850 ++
40851 ++ Enabling this option will let you choose from various features
40852 ++ that prevent the injection and execution of 'foreign' code in
40853 ++ a program.
40854 ++
40855 ++ This will also break programs that rely on the old behaviour and
40856 ++ expect that dynamically allocated memory via the malloc() family
40857 ++ of functions is executable (which it is not). Notable examples
40858 ++ are the XFree86 4.x server, the java runtime and wine.
40859 ++
40860 ++config PAX_PAGEEXEC
40861 ++ bool "Paging based non-executable pages"
40862 ++ 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)
40863 ++ help
40864 ++ This implementation is based on the paging feature of the CPU.
40865 ++ On i386 without hardware non-executable bit support there is a
40866 ++ variable but usually low performance impact, however on Intel's
40867 ++ P4 core based CPUs it is very high so you should not enable this
40868 ++ for kernels meant to be used on such CPUs.
40869 ++
40870 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
40871 ++ with hardware non-executable bit support there is no performance
40872 ++ impact, on ppc the impact is negligible.
40873 ++
40874 ++ Note that several architectures require various emulations due to
40875 ++ badly designed userland ABIs, this will cause a performance impact
40876 ++ but will disappear as soon as userland is fixed (e.g., ppc users
40877 ++ can make use of the secure-plt feature found in binutils).
40878 ++
40879 ++config PAX_SEGMEXEC
40880 ++ bool "Segmentation based non-executable pages"
40881 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
40882 ++ help
40883 ++ This implementation is based on the segmentation feature of the
40884 ++ CPU and has a very small performance impact, however applications
40885 ++ will be limited to a 1.5 GB address space instead of the normal
40886 ++ 3 GB.
40887 ++
40888 ++config PAX_EMUTRAMP
40889 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
40890 ++ default y if PARISC || PPC32
40891 ++ help
40892 ++ There are some programs and libraries that for one reason or
40893 ++ another attempt to execute special small code snippets from
40894 ++ non-executable memory pages. Most notable examples are the
40895 ++ signal handler return code generated by the kernel itself and
40896 ++ the GCC trampolines.
40897 ++
40898 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
40899 ++ such programs will no longer work under your kernel.
40900 ++
40901 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
40902 ++ utilities to enable trampoline emulation for the affected programs
40903 ++ yet still have the protection provided by the non-executable pages.
40904 ++
40905 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
40906 ++ well, otherwise your system will not even boot.
40907 ++
40908 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
40909 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
40910 ++ for the affected files.
40911 ++
40912 ++ NOTE: enabling this feature *may* open up a loophole in the
40913 ++ protection provided by non-executable pages that an attacker
40914 ++ could abuse. Therefore the best solution is to not have any
40915 ++ files on your system that would require this option. This can
40916 ++ be achieved by not using libc5 (which relies on the kernel
40917 ++ signal handler return code) and not using or rewriting programs
40918 ++ that make use of the nested function implementation of GCC.
40919 ++ Skilled users can just fix GCC itself so that it implements
40920 ++ nested function calls in a way that does not interfere with PaX.
40921 ++
40922 ++config PAX_EMUSIGRT
40923 ++ bool "Automatically emulate sigreturn trampolines"
40924 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
40925 ++ default y
40926 ++ help
40927 ++ Enabling this option will have the kernel automatically detect
40928 ++ and emulate signal return trampolines executing on the stack
40929 ++ that would otherwise lead to task termination.
40930 ++
40931 ++ This solution is intended as a temporary one for users with
40932 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
40933 ++ Modula-3 runtime, etc) or executables linked to such, basically
40934 ++ everything that does not specify its own SA_RESTORER function in
40935 ++ normal executable memory like glibc 2.1+ does.
40936 ++
40937 ++ On parisc and ppc you MUST enable this option, otherwise your
40938 ++ system will not even boot.
40939 ++
40940 ++ NOTE: this feature cannot be disabled on a per executable basis
40941 ++ and since it *does* open up a loophole in the protection provided
40942 ++ by non-executable pages, the best solution is to not have any
40943 ++ files on your system that would require this option.
40944 ++
40945 ++config PAX_MPROTECT
40946 ++ bool "Restrict mprotect()"
40947 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
40948 ++ help
40949 ++ Enabling this option will prevent programs from
40950 ++ - changing the executable status of memory pages that were
40951 ++ not originally created as executable,
40952 ++ - making read-only executable pages writable again,
40953 ++ - creating executable pages from anonymous memory.
40954 ++
40955 ++ You should say Y here to complete the protection provided by
40956 ++ the enforcement of non-executable pages.
40957 ++
40958 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
40959 ++ this feature on a per file basis.
40960 ++
40961 ++config PAX_NOELFRELOCS
40962 ++ bool "Disallow ELF text relocations"
40963 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
40964 ++ help
40965 ++ Non-executable pages and mprotect() restrictions are effective
40966 ++ in preventing the introduction of new executable code into an
40967 ++ attacked task's address space. There remain only two venues
40968 ++ for this kind of attack: if the attacker can execute already
40969 ++ existing code in the attacked task then he can either have it
40970 ++ create and mmap() a file containing his code or have it mmap()
40971 ++ an already existing ELF library that does not have position
40972 ++ independent code in it and use mprotect() on it to make it
40973 ++ writable and copy his code there. While protecting against
40974 ++ the former approach is beyond PaX, the latter can be prevented
40975 ++ by having only PIC ELF libraries on one's system (which do not
40976 ++ need to relocate their code). If you are sure this is your case,
40977 ++ then enable this option otherwise be careful as you may not even
40978 ++ be able to boot or log on your system (for example, some PAM
40979 ++ modules are erroneously compiled as non-PIC by default).
40980 ++
40981 ++ NOTE: if you are using dynamic ELF executables (as suggested
40982 ++ when using ASLR) then you must have made sure that you linked
40983 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
40984 ++ referenced there has already been updated to support this).
40985 ++
40986 ++config PAX_ETEXECRELOCS
40987 ++ bool "Allow ELF ET_EXEC text relocations"
40988 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
40989 ++ default y
40990 ++ help
40991 ++ On some architectures there are incorrectly created applications
40992 ++ that require text relocations and would not work without enabling
40993 ++ this option. If you are an alpha, ia64 or parisc user, you should
40994 ++ enable this option and disable it once you have made sure that
40995 ++ none of your applications need it.
40996 ++
40997 ++config PAX_EMUPLT
40998 ++ bool "Automatically emulate ELF PLT"
40999 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41000 ++ default y
41001 ++ help
41002 ++ Enabling this option will have the kernel automatically detect
41003 ++ and emulate the Procedure Linkage Table entries in ELF files.
41004 ++ On some architectures such entries are in writable memory, and
41005 ++ become non-executable leading to task termination. Therefore
41006 ++ it is mandatory that you enable this option on alpha, parisc,
41007 ++ ppc (if secure-plt is not used throughout in userland), sparc
41008 ++ and sparc64, otherwise your system would not even boot.
41009 ++
41010 ++ NOTE: this feature *does* open up a loophole in the protection
41011 ++ provided by the non-executable pages, therefore the proper
41012 ++ solution is to modify the toolchain to produce a PLT that does
41013 ++ not need to be writable.
41014 ++
41015 ++config PAX_DLRESOLVE
41016 ++ bool
41017 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
41018 ++ default y
41019 ++
41020 ++config PAX_SYSCALL
41021 ++ bool
41022 ++ depends on PAX_PAGEEXEC && PPC32
41023 ++ default y
41024 ++
41025 ++config PAX_KERNEXEC
41026 ++ bool "Enforce non-executable kernel pages"
41027 ++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
41028 ++ help
41029 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
41030 ++ that is, enabling this option will make it harder to inject
41031 ++ and execute 'foreign' code in kernel memory itself.
41032 ++
41033 ++endmenu
41034 ++
41035 ++menu "Address Space Layout Randomization"
41036 ++ depends on PAX
41037 ++
41038 ++config PAX_ASLR
41039 ++ bool "Address Space Layout Randomization"
41040 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
41041 ++ help
41042 ++ Many if not most exploit techniques rely on the knowledge of
41043 ++ certain addresses in the attacked program. The following options
41044 ++ will allow the kernel to apply a certain amount of randomization
41045 ++ to specific parts of the program thereby forcing an attacker to
41046 ++ guess them in most cases. Any failed guess will most likely crash
41047 ++ the attacked program which allows the kernel to detect such attempts
41048 ++ and react on them. PaX itself provides no reaction mechanisms,
41049 ++ instead it is strongly encouraged that you make use of Nergal's
41050 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
41051 ++ (http://www.grsecurity.net/) built-in crash detection features or
41052 ++ develop one yourself.
41053 ++
41054 ++ By saying Y here you can choose to randomize the following areas:
41055 ++ - top of the task's kernel stack
41056 ++ - top of the task's userland stack
41057 ++ - base address for mmap() requests that do not specify one
41058 ++ (this includes all libraries)
41059 ++ - base address of the main executable
41060 ++
41061 ++ It is strongly recommended to say Y here as address space layout
41062 ++ randomization has negligible impact on performance yet it provides
41063 ++ a very effective protection.
41064 ++
41065 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
41066 ++ this feature on a per file basis.
41067 ++
41068 ++config PAX_RANDKSTACK
41069 ++ bool "Randomize kernel stack base"
41070 ++ depends on PAX_ASLR && X86_TSC && X86_32
41071 ++ help
41072 ++ By saying Y here the kernel will randomize every task's kernel
41073 ++ stack on every system call. This will not only force an attacker
41074 ++ to guess it but also prevent him from making use of possible
41075 ++ leaked information about it.
41076 ++
41077 ++ Since the kernel stack is a rather scarce resource, randomization
41078 ++ may cause unexpected stack overflows, therefore you should very
41079 ++ carefully test your system. Note that once enabled in the kernel
41080 ++ configuration, this feature cannot be disabled on a per file basis.
41081 ++
41082 ++config PAX_RANDUSTACK
41083 ++ bool "Randomize user stack base"
41084 ++ depends on PAX_ASLR
41085 ++ help
41086 ++ By saying Y here the kernel will randomize every task's userland
41087 ++ stack. The randomization is done in two steps where the second
41088 ++ one may apply a big amount of shift to the top of the stack and
41089 ++ cause problems for programs that want to use lots of memory (more
41090 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
41091 ++ For this reason the second step can be controlled by 'chpax' or
41092 ++ 'paxctl' on a per file basis.
41093 ++
41094 ++config PAX_RANDMMAP
41095 ++ bool "Randomize mmap() base"
41096 ++ depends on PAX_ASLR
41097 ++ help
41098 ++ By saying Y here the kernel will use a randomized base address for
41099 ++ mmap() requests that do not specify one themselves. As a result
41100 ++ all dynamically loaded libraries will appear at random addresses
41101 ++ and therefore be harder to exploit by a technique where an attacker
41102 ++ attempts to execute library code for his purposes (e.g. spawn a
41103 ++ shell from an exploited program that is running at an elevated
41104 ++ privilege level).
41105 ++
41106 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
41107 ++ base address will be randomized as well, completing the full
41108 ++ randomization of the address space layout. Attacking such programs
41109 ++ becomes a guess game. You can find an example of doing this at
41110 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
41111 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
41112 ++
41113 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
41114 ++ feature on a per file basis.
41115 ++
41116 ++endmenu
41117 ++
41118 ++menu "Miscellaneous hardening features"
41119 ++
41120 ++config PAX_MEMORY_SANITIZE
41121 ++ bool "Sanitize all freed memory"
41122 ++ help
41123 ++ By saying Y here the kernel will erase memory pages as soon as they
41124 ++ are freed. This in turn reduces the lifetime of data stored in the
41125 ++ pages, making it less likely that sensitive information such as
41126 ++ passwords, cryptographic secrets, etc stay in memory for too long.
41127 ++
41128 ++ This is especially useful for programs whose runtime is short, long
41129 ++ lived processes and the kernel itself benefit from this as long as
41130 ++ they operate on whole memory pages and ensure timely freeing of pages
41131 ++ that may hold sensitive information.
41132 ++
41133 ++ The tradeoff is performance impact, on a single CPU system kernel
41134 ++ compilation sees a 3% slowdown, other systems and workloads may vary
41135 ++ and you are advised to test this feature on your expected workload
41136 ++ before deploying it.
41137 ++
41138 ++ Note that this feature does not protect data stored in live pages,
41139 ++ e.g., process memory swapped to disk may stay there for a long time.
41140 ++
41141 ++config PAX_MEMORY_UDEREF
41142 ++ bool "Prevent invalid userland pointer dereference"
41143 ++ depends on X86_32 && !COMPAT_VDSO
41144 ++ help
41145 ++ By saying Y here the kernel will be prevented from dereferencing
41146 ++ userland pointers in contexts where the kernel expects only kernel
41147 ++ pointers. This is both a useful runtime debugging feature and a
41148 ++ security measure that prevents exploiting a class of kernel bugs.
41149 ++
41150 ++ The tradeoff is that some virtualization solutions may experience
41151 ++ a huge slowdown and therefore you should not enable this feature
41152 ++ for kernels meant to run in such environments. Whether a given VM
41153 ++ solution is affected or not is best determined by simply trying it
41154 ++ out, the performance impact will be obvious right on boot as this
41155 ++ mechanism engages from very early on. A good rule of thumb is that
41156 ++ VMs running on CPUs without hardware virtualization support (i.e.,
41157 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
41158 ++
41159 ++endmenu
41160 ++
41161 ++endmenu
41162 ++
41163 + config KEYS
41164 + bool "Enable access key retention support"
41165 + help
41166 +diff -urNp a/security/commoncap.c b/security/commoncap.c
41167 +--- a/security/commoncap.c 2008-08-20 11:16:13.000000000 -0700
41168 ++++ b/security/commoncap.c 2008-08-20 18:36:57.000000000 -0700
41169 +@@ -24,15 +24,18 @@
41170 + #include <linux/hugetlb.h>
41171 + #include <linux/mount.h>
41172 + #include <linux/sched.h>
41173 ++#include <linux/grsecurity.h>
41174 +
41175 + /* Global security state */
41176 +
41177 + unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
41178 + EXPORT_SYMBOL(securebits);
41179 +
41180 ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
41181 ++
41182 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
41183 + {
41184 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
41185 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
41186 + return 0;
41187 + }
41188 +
41189 +@@ -54,7 +57,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
41190 + int cap_capable (struct task_struct *tsk, int cap)
41191 + {
41192 + /* Derived from include/linux/sched.h:capable. */
41193 +- if (cap_raised(tsk->cap_effective, cap))
41194 ++ if (cap_raised (tsk->cap_effective, cap))
41195 ++ return 0;
41196 ++ return -EPERM;
41197 ++}
41198 ++
41199 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
41200 ++{
41201 ++ /* tsk = current for all callers */
41202 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
41203 + return 0;
41204 + return -EPERM;
41205 + }
41206 +@@ -352,8 +363,11 @@ void cap_bprm_apply_creds (struct linux_
41207 + }
41208 + }
41209 +
41210 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
41211 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
41212 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
41213 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
41214 ++
41215 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
41216 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
41217 +
41218 + /* For init, we want to retain the capabilities set
41219 + * in the init_task struct. Thus we skip the usual
41220 +@@ -366,6 +380,8 @@ void cap_bprm_apply_creds (struct linux_
41221 + cap_clear(current->cap_effective);
41222 + }
41223 +
41224 ++ gr_handle_chroot_caps(current);
41225 ++
41226 + /* AUD: Audit candidate if current->cap_effective is set */
41227 +
41228 + current->keep_capabilities = 0;
41229 +@@ -592,7 +608,7 @@ int cap_vm_enough_memory(struct mm_struc
41230 + {
41231 + int cap_sys_admin = 0;
41232 +
41233 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
41234 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
41235 + cap_sys_admin = 1;
41236 + return __vm_enough_memory(mm, pages, cap_sys_admin);
41237 + }
41238 +diff -urNp a/security/dummy.c b/security/dummy.c
41239 +--- a/security/dummy.c 2008-08-20 11:16:13.000000000 -0700
41240 ++++ b/security/dummy.c 2008-08-20 18:36:57.000000000 -0700
41241 +@@ -27,6 +27,7 @@
41242 + #include <linux/hugetlb.h>
41243 + #include <linux/ptrace.h>
41244 + #include <linux/file.h>
41245 ++#include <linux/grsecurity.h>
41246 +
41247 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
41248 + {
41249 +@@ -140,8 +141,11 @@ static void dummy_bprm_apply_creds (stru
41250 + }
41251 + }
41252 +
41253 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
41254 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
41255 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
41256 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
41257 ++
41258 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
41259 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
41260 +
41261 + dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
41262 + }
41263 +diff -urNp a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
41264 +--- a/sound/core/oss/pcm_oss.c 2008-08-20 11:16:13.000000000 -0700
41265 ++++ b/sound/core/oss/pcm_oss.c 2008-08-20 18:36:57.000000000 -0700
41266 +@@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
41267 + }
41268 + }
41269 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
41270 +-#define snd_pcm_oss_proc_init(pcm)
41271 +-#define snd_pcm_oss_proc_done(pcm)
41272 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
41273 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
41274 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
41275 +
41276 + /*
41277 +diff -urNp a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h
41278 +--- a/sound/core/seq/seq_lock.h 2008-08-20 11:16:13.000000000 -0700
41279 ++++ b/sound/core/seq/seq_lock.h 2008-08-20 18:36:57.000000000 -0700
41280 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
41281 + #else /* SMP || CONFIG_SND_DEBUG */
41282 +
41283 + typedef spinlock_t snd_use_lock_t; /* dummy */
41284 +-#define snd_use_lock_init(lockp) /**/
41285 +-#define snd_use_lock_use(lockp) /**/
41286 +-#define snd_use_lock_free(lockp) /**/
41287 +-#define snd_use_lock_sync(lockp) /**/
41288 ++#define snd_use_lock_init(lockp) do {} while (0)
41289 ++#define snd_use_lock_use(lockp) do {} while (0)
41290 ++#define snd_use_lock_free(lockp) do {} while (0)
41291 ++#define snd_use_lock_sync(lockp) do {} while (0)
41292 +
41293 + #endif /* SMP || CONFIG_SND_DEBUG */
41294 +
41295 +diff -urNp a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
41296 +--- a/sound/pci/ac97/ac97_patch.c 2008-08-20 11:16:13.000000000 -0700
41297 ++++ b/sound/pci/ac97/ac97_patch.c 2008-08-20 18:36:57.000000000 -0700
41298 +@@ -1486,7 +1486,7 @@ static const struct snd_ac97_res_table a
41299 + { AC97_VIDEO, 0x9f1f },
41300 + { AC97_AUX, 0x9f1f },
41301 + { AC97_PCM, 0x9f1f },
41302 +- { } /* terminator */
41303 ++ { 0, 0 } /* terminator */
41304 + };
41305 +
41306 + static int patch_ad1819(struct snd_ac97 * ac97)
41307 +@@ -3564,7 +3564,7 @@ static struct snd_ac97_res_table lm4550_
41308 + { AC97_AUX, 0x1f1f },
41309 + { AC97_PCM, 0x1f1f },
41310 + { AC97_REC_GAIN, 0x0f0f },
41311 +- { } /* terminator */
41312 ++ { 0, 0 } /* terminator */
41313 + };
41314 +
41315 + static int patch_lm4550(struct snd_ac97 *ac97)
41316 +diff -urNp a/sound/pci/ens1370.c b/sound/pci/ens1370.c
41317 +--- a/sound/pci/ens1370.c 2008-08-20 11:16:13.000000000 -0700
41318 ++++ b/sound/pci/ens1370.c 2008-08-20 18:36:57.000000000 -0700
41319 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
41320 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
41321 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
41322 + #endif
41323 +- { 0, }
41324 ++ { 0, 0, 0, 0, 0, 0, 0 }
41325 + };
41326 +
41327 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
41328 +diff -urNp a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
41329 +--- a/sound/pci/intel8x0.c 2008-08-20 11:16:13.000000000 -0700
41330 ++++ b/sound/pci/intel8x0.c 2008-08-20 18:36:57.000000000 -0700
41331 +@@ -435,7 +435,7 @@ static struct pci_device_id snd_intel8x0
41332 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
41333 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
41334 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
41335 +- { 0, }
41336 ++ { 0, 0, 0, 0, 0, 0, 0 }
41337 + };
41338 +
41339 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
41340 +@@ -2057,7 +2057,7 @@ static struct ac97_quirk ac97_quirks[] _
41341 + .type = AC97_TUNE_HP_ONLY
41342 + },
41343 + #endif
41344 +- { } /* terminator */
41345 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
41346 + };
41347 +
41348 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
41349 +diff -urNp a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
41350 +--- a/sound/pci/intel8x0m.c 2008-08-20 11:16:13.000000000 -0700
41351 ++++ b/sound/pci/intel8x0m.c 2008-08-20 18:36:57.000000000 -0700
41352 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
41353 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
41354 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
41355 + #endif
41356 +- { 0, }
41357 ++ { 0, 0, 0, 0, 0, 0, 0 }
41358 + };
41359 +
41360 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
41361 +@@ -1260,7 +1260,7 @@ static struct shortname_table {
41362 + { 0x5455, "ALi M5455" },
41363 + { 0x746d, "AMD AMD8111" },
41364 + #endif
41365 +- { 0 },
41366 ++ { 0, NULL },
41367 + };
41368 +
41369 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
41370 +diff -urNp a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
41371 +--- a/virt/kvm/kvm_main.c 2008-08-20 11:16:13.000000000 -0700
41372 ++++ b/virt/kvm/kvm_main.c 2008-08-20 18:36:57.000000000 -0700
41373 +@@ -1077,6 +1077,9 @@ static struct miscdevice kvm_dev = {
41374 + KVM_MINOR,
41375 + "kvm",
41376 + &kvm_chardev_ops,
41377 ++ {NULL, NULL},
41378 ++ NULL,
41379 ++ NULL
41380 + };
41381 +
41382 + static void hardware_enable(void *junk)
41383
41384 Added: hardened/2.6/tags/2.6.25-13/4421_grsec-remove-localversion-grsec.patch
41385 ===================================================================
41386 --- hardened/2.6/tags/2.6.25-13/4421_grsec-remove-localversion-grsec.patch (rev 0)
41387 +++ hardened/2.6/tags/2.6.25-13/4421_grsec-remove-localversion-grsec.patch 2009-01-20 21:27:53 UTC (rev 1478)
41388 @@ -0,0 +1,9 @@
41389 +From: Kerin Millar <kerframil@×××××.com>
41390 +
41391 +Remove grsecurity's localversion-grsec file as it is inconsistent with
41392 +Gentoo's kernel practices and naming scheme.
41393 +
41394 +--- a/localversion-grsec 2008-02-24 14:26:59.000000000 +0000
41395 ++++ b/localversion-grsec 1970-01-01 01:00:00.000000000 +0100
41396 +@@ -1 +0,0 @@
41397 +--grsec
41398
41399 Added: hardened/2.6/tags/2.6.25-13/4422_grsec-mute-warnings.patch
41400 ===================================================================
41401 --- hardened/2.6/tags/2.6.25-13/4422_grsec-mute-warnings.patch (rev 0)
41402 +++ hardened/2.6/tags/2.6.25-13/4422_grsec-mute-warnings.patch 2009-01-20 21:27:53 UTC (rev 1478)
41403 @@ -0,0 +1,28 @@
41404 +From: Gordon Malm <gengor@g.o>
41405 +
41406 +Updated patch for kernel series 2.6.24.
41407 +
41408 +The credits/description from the original version of this patch remain accurate
41409 +and are included below.
41410 +
41411 +---
41412 +From: Alexander Gabert <gaberta@××××××××.de>
41413 +
41414 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
41415 +It removes the -W options added by the patch and restores the original
41416 +warning flags of vanilla kernel versions.
41417 +
41418 +Acked-by: Christian Heim <phreak@g.o>
41419 +---
41420 +
41421 +--- a/Makefile
41422 ++++ b/Makefile
41423 +@@ -214,7 +214,7 @@
41424 +
41425 + HOSTCC = gcc
41426 + HOSTCXX = g++
41427 +-HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
41428 ++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
41429 + HOSTCXXFLAGS = -O2
41430 +
41431 + # Decide whether to build built-in, modular, or both.
41432
41433 Added: hardened/2.6/tags/2.6.25-13/4425_grsec-pax-without-grsec.patch
41434 ===================================================================
41435 --- hardened/2.6/tags/2.6.25-13/4425_grsec-pax-without-grsec.patch (rev 0)
41436 +++ hardened/2.6/tags/2.6.25-13/4425_grsec-pax-without-grsec.patch 2009-01-20 21:27:53 UTC (rev 1478)
41437 @@ -0,0 +1,47 @@
41438 +From: Gordon Malm <gengor@g.o>
41439 +
41440 +Allow PaX options to be selected without first selecting CONFIG_GRKERNSEC.
41441 +
41442 +This patch has been updated to keep current with newer kernel versions.
41443 +The original version of this patch contained no credits/description.
41444 +
41445 +--- a/security/Kconfig
41446 ++++ b/security/Kconfig
41447 +@@ -10,7 +10,7 @@ menu "PaX"
41448 +
41449 + config PAX
41450 + bool "Enable various PaX features"
41451 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
41452 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
41453 + help
41454 + This allows you to enable various PaX features. PaX adds
41455 + intrusion prevention mechanisms to the kernel that reduce
41456 +--- a/arch/x86/mm/fault.c
41457 ++++ b/arch/x86/mm/fault.c
41458 +@@ -422,10 +422,12 @@ static void show_fault_oops(struct pt_re
41459 + #else
41460 + if (init_mm.start_code <= address && address < init_mm.end_code)
41461 + #endif
41462 ++#ifdef CONFIG_GRKERNSEC
41463 + if (current->signal->curr_ip)
41464 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
41465 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
41466 + else
41467 ++#endif
41468 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
41469 + current->comm, task_pid_nr(current), current->uid, current->euid);
41470 + #endif
41471 +--- a/fs/exec.c
41472 ++++ b/fs/exec.c
41473 +@@ -1691,9 +1691,11 @@ void pax_report_fault(struct pt_regs *re
41474 + }
41475 + up_read(&mm->mmap_sem);
41476 + }
41477 ++#ifdef CONFIG_GRKERNSEC
41478 + if (tsk->signal->curr_ip)
41479 + 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);
41480 + else
41481 ++#endif
41482 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
41483 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
41484 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
41485
41486 Added: hardened/2.6/tags/2.6.25-13/4430_grsec-kconfig-default-gids.patch
41487 ===================================================================
41488 --- hardened/2.6/tags/2.6.25-13/4430_grsec-kconfig-default-gids.patch (rev 0)
41489 +++ hardened/2.6/tags/2.6.25-13/4430_grsec-kconfig-default-gids.patch 2009-01-20 21:27:53 UTC (rev 1478)
41490 @@ -0,0 +1,76 @@
41491 +From: Kerin Millar <kerframil@×××××.com>
41492 +
41493 +grsecurity contains a number of options which allow certain protections
41494 +to be applied to or exempted from members of a given group. However, the
41495 +default GIDs specified in the upstream patch are entirely arbitrary and
41496 +there is no telling which (if any) groups the GIDs will correlate with
41497 +on an end-user's system. Because some users don't pay a great deal of
41498 +attention to the finer points of kernel configuration, it is probably
41499 +wise to specify some reasonable defaults so as to stop careless users
41500 +from shooting themselves in the foot.
41501 +
41502 +--- a/grsecurity/Kconfig
41503 ++++ b/grsecurity/Kconfig
41504 +@@ -352,7 +564,7 @@
41505 + config GRKERNSEC_PROC_GID
41506 + int "GID for special group"
41507 + depends on GRKERNSEC_PROC_USERGROUP
41508 +- default 1001
41509 ++ default 10
41510 +
41511 + config GRKERNSEC_PROC_ADD
41512 + bool "Additional restrictions"
41513 +@@ -547,7 +759,7 @@
41514 + config GRKERNSEC_AUDIT_GID
41515 + int "GID for auditing"
41516 + depends on GRKERNSEC_AUDIT_GROUP
41517 +- default 1007
41518 ++ default 100
41519 +
41520 + config GRKERNSEC_EXECLOG
41521 + bool "Exec logging"
41522 +@@ -700,7 +912,7 @@
41523 + config GRKERNSEC_TPE_GID
41524 + int "GID for untrusted users"
41525 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
41526 +- default 1005
41527 ++ default 100
41528 + help
41529 + If you have selected the "Invert GID option" above, setting this
41530 + GID determines what group TPE restrictions will be *disabled* for.
41531 +@@ -712,7 +924,7 @@
41532 + config GRKERNSEC_TPE_GID
41533 + int "GID for trusted users"
41534 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
41535 +- default 1005
41536 ++ default 10
41537 + help
41538 + If you have selected the "Invert GID option" above, setting this
41539 + GID determines what group TPE restrictions will be *disabled* for.
41540 +@@ -754,7 +966,7 @@
41541 + config GRKERNSEC_SOCKET_ALL_GID
41542 + int "GID to deny all sockets for"
41543 + depends on GRKERNSEC_SOCKET_ALL
41544 +- default 1004
41545 ++ default 65534
41546 + help
41547 + Here you can choose the GID to disable socket access for. Remember to
41548 + add the users you want socket access disabled for to the GID
41549 +@@ -775,7 +987,7 @@
41550 + config GRKERNSEC_SOCKET_CLIENT_GID
41551 + int "GID to deny client sockets for"
41552 + depends on GRKERNSEC_SOCKET_CLIENT
41553 +- default 1003
41554 ++ default 65534
41555 + help
41556 + Here you can choose the GID to disable client socket access for.
41557 + Remember to add the users you want client socket access disabled for to
41558 +@@ -793,7 +1005,7 @@
41559 + config GRKERNSEC_SOCKET_SERVER_GID
41560 + int "GID to deny server sockets for"
41561 + depends on GRKERNSEC_SOCKET_SERVER
41562 +- default 1002
41563 ++ default 65534
41564 + help
41565 + Here you can choose the GID to disable server socket access for.
41566 + Remember to add the users you want server socket access disabled for to
41567
41568 Added: hardened/2.6/tags/2.6.25-13/4435_grsec-kconfig-gentoo.patch
41569 ===================================================================
41570 --- hardened/2.6/tags/2.6.25-13/4435_grsec-kconfig-gentoo.patch (rev 0)
41571 +++ hardened/2.6/tags/2.6.25-13/4435_grsec-kconfig-gentoo.patch 2009-01-20 21:27:53 UTC (rev 1478)
41572 @@ -0,0 +1,241 @@
41573 +From: Gordon Malm <gengor@g.o>
41574 +From: Kerin Millar <kerframil@×××××.com>
41575 +
41576 +Add Hardened Gentoo [server/workstation] predefined grsecurity
41577 +levels. They're designed to provide a comparitively high level of
41578 +security while remaining generally suitable for as great a majority
41579 +of the userbase as possible (particularly new users).
41580 +
41581 +Make Hardened Gentoo [workstation] predefined grsecurity level the
41582 +default. The Hardened Gentoo [server] level is more restrictive
41583 +and conflicts with some software and thus would be less suitable.
41584 +
41585 +The original version of this patch was conceived and created by:
41586 +Ned Ludd <solar@g.o>
41587 +
41588 +--- a/grsecurity/Kconfig
41589 ++++ b/grsecurity/Kconfig
41590 +@@ -20,7 +20,7 @@
41591 + choice
41592 + prompt "Security Level"
41593 + depends on GRKERNSEC
41594 +- default GRKERNSEC_CUSTOM
41595 ++ default GRKERNSEC_HARDENED_WORKSTATION
41596 +
41597 + config GRKERNSEC_LOW
41598 + bool "Low"
41599 +@@ -181,6 +181,214 @@
41600 + - Mount/unmount/remount logging
41601 + - Kernel symbol hiding
41602 + - Prevention of memory exhaustion-based exploits
41603 ++
41604 ++config GRKERNSEC_HARDENED_SERVER
41605 ++ bool "Hardened Gentoo [server]"
41606 ++ select GRKERNSEC_AUDIT_MOUNT
41607 ++ select GRKERNSEC_BRUTE
41608 ++ select GRKERNSEC_CHROOT
41609 ++ select GRKERNSEC_CHROOT_CAPS
41610 ++ select GRKERNSEC_CHROOT_CHDIR
41611 ++ select GRKERNSEC_CHROOT_CHMOD
41612 ++ select GRKERNSEC_CHROOT_DOUBLE
41613 ++ select GRKERNSEC_CHROOT_FCHDIR
41614 ++ select GRKERNSEC_CHROOT_FINDTASK
41615 ++ select GRKERNSEC_CHROOT_MKNOD
41616 ++ select GRKERNSEC_CHROOT_MOUNT
41617 ++ select GRKERNSEC_CHROOT_NICE
41618 ++ select GRKERNSEC_CHROOT_PIVOT
41619 ++ select GRKERNSEC_CHROOT_SHMAT
41620 ++ select GRKERNSEC_CHROOT_SYSCTL
41621 ++ select GRKERNSEC_CHROOT_UNIX
41622 ++ select GRKERNSEC_DMESG
41623 ++ select GRKERNSEC_EXECVE
41624 ++ select GRKERNSEC_FIFO
41625 ++ select GRKERNSEC_FORKFAIL
41626 ++ select GRKERNSEC_HIDESYM
41627 ++ select GRKERNSEC_IO if (X86)
41628 ++ select GRKERNSEC_KMEM
41629 ++ select GRKERNSEC_LINK
41630 ++ select GRKERNSEC_MODSTOP if (MODULES)
41631 ++ select GRKERNSEC_PROC
41632 ++ select GRKERNSEC_PROC_ADD
41633 ++ select GRKERNSEC_PROC_IPADDR
41634 ++ select GRKERNSEC_PROC_MEMMAP
41635 ++ select GRKERNSEC_PROC_USERGROUP
41636 ++ select GRKERNSEC_RANDNET
41637 ++ select GRKERNSEC_RESLOG
41638 ++ select GRKERNSEC_SIGNAL
41639 ++# select GRKERNSEC_SOCKET
41640 ++# select GRKERNSEC_SOCKET_SERVER
41641 ++ select GRKERNSEC_SYSCTL
41642 ++ select GRKERNSEC_SYSCTL_ON
41643 ++ select GRKERNSEC_TIME
41644 ++ select PAX
41645 ++ select PAX_ASLR
41646 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
41647 ++ select PAX_EI_PAX
41648 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41649 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
41650 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
41651 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
41652 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
41653 ++ select PAX_MEMORY_SANITIZE
41654 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO)
41655 ++ select PAX_MPROTECT if (!PPC64)
41656 ++ select PAX_HAVE_ACL_FLAGS
41657 ++ select PAX_NOELFRELOCS if (X86)
41658 ++ select PAX_NOEXEC
41659 ++ select PAX_PAGEEXEC
41660 ++ select PAX_PT_PAX_FLAGS
41661 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
41662 ++ select PAX_RANDMMAP
41663 ++ select PAX_RANDUSTACK
41664 ++ select PAX_SEGMEXEC if (X86_32)
41665 ++ select PAX_SYSCALL if (PPC32)
41666 ++ help
41667 ++ If you say Y here, a configuration will be used that is endorsed by
41668 ++ the Hardened Gentoo project. Therefore, many of the protections
41669 ++ made available by grsecurity and PaX will be enabled.
41670 ++
41671 ++ Hardened Gentoo's pre-defined security levels are designed to provide
41672 ++ a high level of security while minimizing incompatibilities with the
41673 ++ majority of available software. For further information, please
41674 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
41675 ++ well as the Hardened Gentoo Primer at
41676 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
41677 ++
41678 ++ This Hardened Gentoo [server] level is identical to the
41679 ++ Hardened Gentoo [workstation] level, but with the GRKERNSEC_IO,
41680 ++ PAX_KERNEXEC and PAX_NOELFRELOCS security features enabled.
41681 ++ Accordingly, this is the preferred security level if the system will
41682 ++ not be utilizing software incompatible with the aforementioned
41683 ++ grsecurity/PaX features.
41684 ++
41685 ++ You may wish to emerge paxctl, a utility which allows you to toggle
41686 ++ PaX features on problematic binaries on an individual basis. Note that
41687 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
41688 ++ Translated, this means that if you wish to toggle PaX features on
41689 ++ binaries provided by applications that are distributed only in binary
41690 ++ format (rather than being built locally from sources), you will need to
41691 ++ run paxctl -C on the binaries beforehand so as to inject the missing
41692 ++ headers.
41693 ++
41694 ++ When this level is selected, some options cannot be changed. However,
41695 ++ you may opt to fully customize the options that are selected by
41696 ++ choosing "Custom" in the Security Level menu. You may find it helpful
41697 ++ to inherit the options selected by the "Hardened Gentoo [server]"
41698 ++ security level as a starting point for further configuration. To
41699 ++ accomplish this, select this security level then exit the menuconfig
41700 ++ interface, saving changes when prompted. Then, run make menuconfig
41701 ++ again and select the "Custom" level.
41702 ++
41703 ++ Note that this security level probably should not be used if the
41704 ++ target system is a 32bit x86 virtualized guest. If you intend to run
41705 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
41706 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
41707 ++ impact on performance.
41708 ++
41709 ++config GRKERNSEC_HARDENED_WORKSTATION
41710 ++ bool "Hardened Gentoo [workstation]"
41711 ++ select GRKERNSEC_AUDIT_MOUNT
41712 ++ select GRKERNSEC_BRUTE
41713 ++ select GRKERNSEC_CHROOT
41714 ++ select GRKERNSEC_CHROOT_CAPS
41715 ++ select GRKERNSEC_CHROOT_CHDIR
41716 ++ select GRKERNSEC_CHROOT_CHMOD
41717 ++ select GRKERNSEC_CHROOT_DOUBLE
41718 ++ select GRKERNSEC_CHROOT_FCHDIR
41719 ++ select GRKERNSEC_CHROOT_FINDTASK
41720 ++ select GRKERNSEC_CHROOT_MKNOD
41721 ++ select GRKERNSEC_CHROOT_MOUNT
41722 ++ select GRKERNSEC_CHROOT_NICE
41723 ++ select GRKERNSEC_CHROOT_PIVOT
41724 ++ select GRKERNSEC_CHROOT_SHMAT
41725 ++ select GRKERNSEC_CHROOT_SYSCTL
41726 ++ select GRKERNSEC_CHROOT_UNIX
41727 ++ select GRKERNSEC_DMESG
41728 ++ select GRKERNSEC_EXECVE
41729 ++ select GRKERNSEC_FIFO
41730 ++ select GRKERNSEC_FORKFAIL
41731 ++ select GRKERNSEC_HIDESYM
41732 ++ select GRKERNSEC_KMEM
41733 ++ select GRKERNSEC_LINK
41734 ++ select GRKERNSEC_MODSTOP if (MODULES)
41735 ++ select GRKERNSEC_PROC
41736 ++ select GRKERNSEC_PROC_ADD
41737 ++ select GRKERNSEC_PROC_IPADDR
41738 ++ select GRKERNSEC_PROC_MEMMAP
41739 ++ select GRKERNSEC_PROC_USERGROUP
41740 ++ select GRKERNSEC_RANDNET
41741 ++ select GRKERNSEC_RESLOG
41742 ++ select GRKERNSEC_SIGNAL
41743 ++# select GRKERNSEC_SOCKET
41744 ++# select GRKERNSEC_SOCKET_SERVER
41745 ++ select GRKERNSEC_SYSCTL
41746 ++ select GRKERNSEC_SYSCTL_ON
41747 ++ select GRKERNSEC_TIME
41748 ++ select PAX
41749 ++ select PAX_ASLR
41750 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
41751 ++ select PAX_EI_PAX
41752 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41753 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
41754 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
41755 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
41756 ++ select PAX_MEMORY_SANITIZE
41757 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO)
41758 ++ select PAX_MPROTECT if (!PPC64)
41759 ++ select PAX_HAVE_ACL_FLAGS
41760 ++ select PAX_NOEXEC
41761 ++ select PAX_PAGEEXEC
41762 ++ select PAX_PT_PAX_FLAGS
41763 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
41764 ++ select PAX_RANDMMAP
41765 ++ select PAX_RANDUSTACK
41766 ++ select PAX_SEGMEXEC if (X86_32)
41767 ++ select PAX_SYSCALL if (PPC32)
41768 ++ help
41769 ++ If you say Y here, a configuration will be used that is endorsed by
41770 ++ the Hardened Gentoo project. Therefore, many of the protections
41771 ++ made available by grsecurity and PaX will be enabled.
41772 ++
41773 ++ Hardened Gentoo's pre-defined security levels are designed to provide
41774 ++ a high level of security while minimizing incompatibilities with the
41775 ++ majority of available software. For further information, please
41776 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
41777 ++ well as the Hardened Gentoo Primer at
41778 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
41779 ++
41780 ++ This Hardened Gentoo [workstation] level is designed for machines
41781 ++ which are intended to run software not compatible with the
41782 ++ GRKERNSEC_IO, PAX_KERNEXEC and PAX_NOELFRELOCS features of grsecurity.
41783 ++ Accordingly, this security level is suitable for use with the X server
41784 ++ "Xorg" and/or any system that will act as host OS to the virtualization
41785 ++ softwares vmware-server or virtualbox.
41786 ++
41787 ++ You may wish to emerge paxctl, a utility which allows you to toggle
41788 ++ PaX features on problematic binaries on an individual basis. Note that
41789 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
41790 ++ Translated, this means that if you wish to toggle PaX features on
41791 ++ binaries provided by applications that are distributed only in binary
41792 ++ format (rather than being built locally from sources), you will need to
41793 ++ run paxctl -C on the binaries beforehand so as to inject the missing
41794 ++ headers.
41795 ++
41796 ++ When this level is selected, some options cannot be changed. However,
41797 ++ you may opt to fully customize the options that are selected by
41798 ++ choosing "Custom" in the Security Level menu. You may find it helpful
41799 ++ to inherit the options selected by the "Hardened Gentoo [workstation]"
41800 ++ security level as a starting point for further configuration. To
41801 ++ accomplish this, select this security level then exit the menuconfig
41802 ++ interface, saving changes when prompted. Then, run make menuconfig
41803 ++ again and select the "Custom" level.
41804 ++
41805 ++ Note that this security level probably should not be used if the
41806 ++ target system is a 32bit x86 virtualized guest. If you intend to run
41807 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
41808 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
41809 ++ impact on performance.
41810 ++
41811 + config GRKERNSEC_CUSTOM
41812 + bool "Custom"
41813 + help
41814
41815 Added: hardened/2.6/tags/2.6.25-13/4440_selinux-avc_audit-log-curr_ip.patch
41816 ===================================================================
41817 --- hardened/2.6/tags/2.6.25-13/4440_selinux-avc_audit-log-curr_ip.patch (rev 0)
41818 +++ hardened/2.6/tags/2.6.25-13/4440_selinux-avc_audit-log-curr_ip.patch 2009-01-20 21:27:53 UTC (rev 1478)
41819 @@ -0,0 +1,65 @@
41820 +From: Gordon Malm <gengor@g.o>
41821 +
41822 +This is a reworked version of the original
41823 +*_selinux-avc_audit-log-curr_ip.patch carried in earlier releases of
41824 +hardened-sources.
41825 +
41826 +Dropping the patch, or simply fixing the #ifdef of the original patch
41827 +could break automated logging setups so this route was necessary.
41828 +
41829 +Suggestions for improving the help text are welcome.
41830 +
41831 +The original patch's description is still accurate and included below.
41832 +
41833 +---
41834 +Provides support for a new field ipaddr within the SELinux
41835 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
41836 +provided by grSecurity patch to be applied before.
41837 +
41838 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
41839 +---
41840 +
41841 +--- a/grsecurity/Kconfig
41842 ++++ b/grsecurity/Kconfig
41843 +@@ -1044,6 +1044,27 @@ endmenu
41844 + menu "Logging Options"
41845 + depends on GRKERNSEC
41846 +
41847 ++config GRKERNSEC_SELINUX_AVC_LOG_IPADDR
41848 ++ def_bool n
41849 ++ prompt "Add source IP address to SELinux AVC log messages"
41850 ++ depends on GRKERNSEC && SECURITY_SELINUX
41851 ++ help
41852 ++ If you say Y here, a new field "ipaddr=" will be added to many SELinux
41853 ++ AVC log messages. The value of this field in any given message
41854 ++ represents the source IP address of the remote machine/user that created
41855 ++ the offending process.
41856 ++
41857 ++ This information is sourced from task_struct->curr_ip provided by
41858 ++ grsecurity's GRKERNSEC top-level configuration option. One limitation
41859 ++ is that only IPv4 is supported.
41860 ++
41861 ++ In many instances SELinux AVC log messages already log a superior level
41862 ++ of information that also includes source port and destination ip/port.
41863 ++ Additionally, SELinux's AVC log code supports IPv6.
41864 ++
41865 ++ However, grsecurity's task_struct->curr_ip will sometimes (often?)
41866 ++ provide the offender's IP address where stock SELinux logging fails to.
41867 ++
41868 + config GRKERNSEC_FLOODTIME
41869 + int "Seconds in between log messages (minimum)"
41870 + default 10
41871 +--- a/security/selinux/avc.c
41872 ++++ b/security/selinux/avc.c
41873 +@@ -202,6 +202,11 @@ static void avc_dump_query(struct audit_
41874 + char *scontext;
41875 + u32 scontext_len;
41876 +
41877 ++#ifdef CONFIG_GRKERNSEC_SELINUX_AVC_LOG_IPADDR
41878 ++ if (current->signal->curr_ip)
41879 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
41880 ++#endif
41881 ++
41882 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
41883 + if (rc)
41884 + audit_log_format(ab, "ssid=%d", ssid);
41885
41886 Added: hardened/2.6/tags/2.6.25-13/4445_disable-compat_vdso.patch
41887 ===================================================================
41888 --- hardened/2.6/tags/2.6.25-13/4445_disable-compat_vdso.patch (rev 0)
41889 +++ hardened/2.6/tags/2.6.25-13/4445_disable-compat_vdso.patch 2009-01-20 21:27:53 UTC (rev 1478)
41890 @@ -0,0 +1,74 @@
41891 +From: Gordon Malm <gengor@g.o>
41892 +From: Kerin Millar <kerframil@×××××.com>
41893 +
41894 +COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It
41895 +conflicts with various parts of PaX, crashing the system if enabled
41896 +while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents
41897 +a number of important PaX options from appearing in the configuration
41898 +menu, including all PaX NOEXEC implementations. Unfortunately, the
41899 +reason for the disappearance of these PaX configuration options is
41900 +often far from obvious to inexperienced users.
41901 +
41902 +Therefore, we disable the COMPAT_VDSO menu entry entirely. However,
41903 +COMPAT_VDSO operation can still be enabled via bootparam and sysctl
41904 +interfaces. Consequently, we must also disable the ability to select
41905 +COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so
41906 +that selecting COMPAT_VDSO operation at boot/runtime has no effect if
41907 +conflicting PaX options are enabled, leaving VDSO_ENABLED operation
41908 +intact.
41909 +
41910 +Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138
41911 +
41912 +--- a/arch/x86/Kconfig
41913 ++++ b/arch/x86/Kconfig
41914 +@@ -1215,16 +1215,7 @@ config HOTPLUG_CPU
41915 +
41916 + config COMPAT_VDSO
41917 + def_bool n
41918 +- prompt "Compat VDSO support"
41919 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
41920 +- help
41921 +- Map the 32-bit VDSO to the predictable old-style address too.
41922 +- ---help---
41923 +- Say N here if you are running a sufficiently recent glibc
41924 +- version (2.3.3 or later), to remove the high-mapped
41925 +- VDSO mapping and to exclusively use the randomized VDSO.
41926 +-
41927 +- If unsure, say Y.
41928 +
41929 + endmenu
41930 +
41931 +--- a/arch/x86/vdso/vdso32-setup.c
41932 ++++ b/arch/x86/vdso/vdso32-setup.c
41933 +@@ -333,17 +333,21 @@ int arch_setup_additional_pages(struct l
41934 +
41935 + map_compat_vdso(compat);
41936 +
41937 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
41938 + if (compat)
41939 + addr = VDSO_HIGH_BASE;
41940 + else {
41941 ++#endif
41942 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
41943 + if (IS_ERR_VALUE(addr)) {
41944 + ret = addr;
41945 + goto up_fail;
41946 + }
41947 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
41948 + }
41949 +
41950 + if (compat_uses_vma || !compat) {
41951 ++#endif
41952 + /*
41953 + * MAYWRITE to allow gdb to COW and set breakpoints
41954 + *
41955 +@@ -361,7 +365,9 @@ int arch_setup_additional_pages(struct l
41956 +
41957 + if (ret)
41958 + goto up_fail;
41959 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
41960 + }
41961 ++#endif
41962 +
41963 + current->mm->context.vdso = addr;
41964 + current_thread_info()->sysenter_return =
41965
41966 Added: hardened/2.6/tags/2.6.25-13/4450_pax-remove-read_implies_exec-for-pax-binaries.patch
41967 ===================================================================
41968 --- hardened/2.6/tags/2.6.25-13/4450_pax-remove-read_implies_exec-for-pax-binaries.patch (rev 0)
41969 +++ hardened/2.6/tags/2.6.25-13/4450_pax-remove-read_implies_exec-for-pax-binaries.patch 2009-01-20 21:27:53 UTC (rev 1478)
41970 @@ -0,0 +1,30 @@
41971 +From: Gordon Malm <gengor@g.o>
41972 +
41973 +Remove READ_IMPLIES_EXEC personality for PaX controlled binaries.
41974 +
41975 +This fixes problems that can occur when a binary has neither PT_PAX or
41976 +GNU_STACK ELF program headers on a system without an EI_PAX enabled kernel.
41977 +
41978 +See also: http://forums.grsecurity.net/viewtopic.php?f=3&t=2023
41979 +
41980 +Thanks to nixnut <nixnut@g.o> and Kerin Millar <kerframil@×××××.com>
41981 +for bringing it to my attention.
41982 +
41983 +This patch is present in upstream grsecurity patches as of
41984 +pax-linux-2.6.26.3-test19.patch.
41985 +
41986 +--- a/fs/binfmt_elf.c
41987 ++++ b/fs/binfmt_elf.c
41988 +@@ -993,9 +993,10 @@ static int load_elf_binary(struct linux_
41989 + SET_PERSONALITY(loc->elf_ex, 0);
41990 +
41991 + #if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
41992 +- if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
41993 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
41994 + executable_stack = EXSTACK_DISABLE_X;
41995 +- else
41996 ++ current->personality &= ~READ_IMPLIES_EXEC;
41997 ++ } else
41998 + #endif
41999 +
42000 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
42001
42002 Added: hardened/2.6/tags/2.6.25-13/4455_pax-fix-uvesafb-compile-and-misc.patch
42003 ===================================================================
42004 --- hardened/2.6/tags/2.6.25-13/4455_pax-fix-uvesafb-compile-and-misc.patch (rev 0)
42005 +++ hardened/2.6/tags/2.6.25-13/4455_pax-fix-uvesafb-compile-and-misc.patch 2009-01-20 21:27:53 UTC (rev 1478)
42006 @@ -0,0 +1,112 @@
42007 +From: Gordon Malm <gengor@g.o>
42008 +
42009 +Fix compilation and miscellaneous other problems in uvesafb.
42010 +
42011 +Fixes bug #245427.
42012 +
42013 +More info @ http://forums.grsecurity.net/viewtopic.php?f=1&t=2016
42014 +
42015 +This patch is present in upstream grsecurity patches as of
42016 +pax-linux-2.6.26-test7.patch.
42017 +
42018 +--- a/drivers/video/uvesafb.c
42019 ++++ b/drivers/video/uvesafb.c
42020 +@@ -561,25 +561,25 @@ static int __devinit uvesafb_vbe_getpmi(
42021 + {
42022 + int i, err;
42023 +
42024 +-#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42025 +- u8 *pmi_code;
42026 +- unsigned long cr0;
42027 +-#endif
42028 +-
42029 + uvesafb_reset(task);
42030 + task->t.regs.eax = 0x4f0a;
42031 + task->t.regs.ebx = 0x0;
42032 + err = uvesafb_exec(task);
42033 +
42034 +- par->pmi_setpal = par->ypan = 0;
42035 +- if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000)
42036 +- return 0;
42037 ++ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
42038 ++ par->pmi_setpal = par->ypan = 0;
42039 ++ } else {
42040 +
42041 +-#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42042 +- pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
42043 +- if (pmi_code) {
42044 +-#elif !defined(CONFIG_PAX_KERNEXEC)
42045 +- if (1) {
42046 ++#ifdef CONFIG_PAX_KERNEXEC
42047 ++#ifdef CONFIG_MODULES
42048 ++ unsigned long cr0;
42049 ++
42050 ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
42051 ++#endif
42052 ++ if (!par->pmi_code) {
42053 ++ par->pmi_setpal = par->ypan = 0;
42054 ++ return 0;
42055 ++ }
42056 + #endif
42057 +
42058 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
42059 +@@ -587,18 +587,14 @@ static int __devinit uvesafb_vbe_getpmi(
42060 +
42061 + #if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42062 + pax_open_kernel(cr0);
42063 +- memcpy(pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
42064 ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
42065 + pax_close_kernel(cr0);
42066 +-#else
42067 +- pmi_code = par->pmi_base;
42068 +-#endif
42069 +-
42070 +- par->pmi_start = pmi_code + par->pmi_base[1];
42071 +- par->pmi_pal = pmi_code + par->pmi_base[2];
42072 +
42073 +-#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42074 +- par->pmi_start = ktva_ktla(par->pmi_start);
42075 +- par->pmi_pal = ktva_ktla(par->pmi_pal);
42076 ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
42077 ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
42078 ++#else
42079 ++ par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
42080 ++ par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
42081 + #endif
42082 +
42083 + printk(KERN_INFO "uvesafb: protected mode interface info at "
42084 +@@ -1855,6 +1851,11 @@ out:
42085 + if (par->vbe_modes)
42086 + kfree(par->vbe_modes);
42087 +
42088 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42089 ++ if (par->pmi_code)
42090 ++ module_free_exec(NULL, par->pmi_code);
42091 ++#endif
42092 ++
42093 + framebuffer_release(info);
42094 + return err;
42095 + }
42096 +@@ -1881,6 +1882,12 @@ static int uvesafb_remove(struct platfor
42097 + kfree(par->vbe_state_orig);
42098 + if (par->vbe_state_saved)
42099 + kfree(par->vbe_state_saved);
42100 ++
42101 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42102 ++ if (par->pmi_code)
42103 ++ module_free_exec(NULL, par->pmi_code);
42104 ++#endif
42105 ++
42106 + }
42107 +
42108 + framebuffer_release(info);
42109 +--- a/include/video/uvesafb.h
42110 ++++ b/include/video/uvesafb.h
42111 +@@ -175,6 +175,7 @@ struct uvesafb_par {
42112 + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
42113 + u8 pmi_setpal; /* PMI for palette changes */
42114 + u16 *pmi_base; /* protected mode interface location */
42115 ++ u8 *pmi_code; /* protected mode code location */
42116 + void *pmi_start;
42117 + void *pmi_pal;
42118 + u8 *vbe_state_orig; /*
42119
42120 Added: hardened/2.6/tags/2.6.25-13/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
42121 ===================================================================
42122 --- hardened/2.6/tags/2.6.25-13/4460_pax-fix-mmap-BUG_ON-task-size-check.patch (rev 0)
42123 +++ hardened/2.6/tags/2.6.25-13/4460_pax-fix-mmap-BUG_ON-task-size-check.patch 2009-01-20 21:27:53 UTC (rev 1478)
42124 @@ -0,0 +1,22 @@
42125 +From: Gordon Malm <gengor@g.o>
42126 +
42127 +Fix incorrect vma task size check under SEGMEXEC.
42128 +
42129 +Fixes bug #246607.
42130 +
42131 +Thanks to Hugo Mildenberger for reporting and PaX Team for the fix.
42132 +
42133 +This patch is present in upstream grsecurity patches as of
42134 +pax-linux-2.6.27.7-test22.patch.
42135 +
42136 +--- a/mm/mmap.c
42137 ++++ b/mm/mmap.c
42138 +@@ -1703,7 +1703,7 @@ struct vm_area_struct *pax_find_mirror_v
42139 + BUG_ON(vma->vm_mirror);
42140 + return NULL;
42141 + }
42142 +- BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
42143 ++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
42144 + vma_m = vma->vm_mirror;
42145 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
42146 + BUG_ON(vma->vm_file != vma_m->vm_file);
42147
42148 Added: hardened/2.6/tags/2.6.25-13/4465_pax-fix-false-RLIMIT_STACK-warnings.patch
42149 ===================================================================
42150 --- hardened/2.6/tags/2.6.25-13/4465_pax-fix-false-RLIMIT_STACK-warnings.patch (rev 0)
42151 +++ hardened/2.6/tags/2.6.25-13/4465_pax-fix-false-RLIMIT_STACK-warnings.patch 2009-01-20 21:27:53 UTC (rev 1478)
42152 @@ -0,0 +1,88 @@
42153 +From: Gordon Malm <gengor@g.o>
42154 +
42155 +Fix false-positive RLIMIT_STACK warnings.
42156 +
42157 +Thanks to PaX Team for the heads up.
42158 +
42159 +This patch is present in upstream grsecurity patches as of
42160 +pax-linux-2.6.27.7-test22.patch.
42161 +
42162 +--- a/arch/x86/mm/fault.c
42163 ++++ b/arch/x86/mm/fault.c
42164 +@@ -840,16 +840,14 @@ not_pax_fault:
42165 + goto good_area;
42166 + if (!(vma->vm_flags & VM_GROWSDOWN))
42167 + goto bad_area;
42168 +- if (error_code & PF_USER) {
42169 +- /*
42170 +- * Accessing the stack below %sp is always a bug.
42171 +- * The large cushion allows instructions like enter
42172 +- * and pusha to work. ("enter $65535,$31" pushes
42173 +- * 32 pointers and then decrements %sp by 65535.)
42174 +- */
42175 +- if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
42176 +- goto bad_area;
42177 +- }
42178 ++ /*
42179 ++ * Accessing the stack below %sp is always a bug.
42180 ++ * The large cushion allows instructions like enter
42181 ++ * and pusha to work. ("enter $65535,$31" pushes
42182 ++ * 32 pointers and then decrements %sp by 65535.)
42183 ++ */
42184 ++ if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
42185 ++ goto bad_area;
42186 +
42187 + #ifdef CONFIG_PAX_SEGMEXEC
42188 + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
42189 +--- a/kernel/exit.c
42190 ++++ b/kernel/exit.c
42191 +@@ -38,7 +38,6 @@
42192 + #include <linux/cn_proc.h>
42193 + #include <linux/mutex.h>
42194 + #include <linux/futex.h>
42195 +-#include <linux/compat.h>
42196 + #include <linux/pipe_fs_i.h>
42197 + #include <linux/audit.h> /* for audit_free() */
42198 + #include <linux/resource.h>
42199 +@@ -974,14 +973,6 @@ NORET_TYPE void do_exit(long code)
42200 + exit_itimers(tsk->signal);
42201 + }
42202 + acct_collect(code, group_dead);
42203 +-#ifdef CONFIG_FUTEX
42204 +- if (unlikely(tsk->robust_list))
42205 +- exit_robust_list(tsk);
42206 +-#ifdef CONFIG_COMPAT
42207 +- if (unlikely(tsk->compat_robust_list))
42208 +- compat_exit_robust_list(tsk);
42209 +-#endif
42210 +-#endif
42211 + if (group_dead)
42212 + tty_audit_exit();
42213 + if (unlikely(tsk->audit_context))
42214 +--- a/kernel/fork.c
42215 ++++ b/kernel/fork.c
42216 +@@ -35,6 +35,7 @@
42217 + #include <linux/syscalls.h>
42218 + #include <linux/jiffies.h>
42219 + #include <linux/futex.h>
42220 ++#include <linux/compat.h>
42221 + #include <linux/task_io_accounting_ops.h>
42222 + #include <linux/rcupdate.h>
42223 + #include <linux/ptrace.h>
42224 +@@ -491,6 +492,16 @@ void mm_release(struct task_struct *tsk,
42225 + {
42226 + struct completion *vfork_done = tsk->vfork_done;
42227 +
42228 ++ /* Get rid of any futexes when releasing the mm */
42229 ++#ifdef CONFIG_FUTEX
42230 ++ if (unlikely(tsk->robust_list))
42231 ++ exit_robust_list(tsk);
42232 ++#ifdef CONFIG_COMPAT
42233 ++ if (unlikely(tsk->compat_robust_list))
42234 ++ compat_exit_robust_list(tsk);
42235 ++#endif
42236 ++#endif
42237 ++
42238 + /* Get rid of any cached register state */
42239 + deactivate_mm(tsk, mm);
42240 +
42241 \ No newline at end of file