Gentoo Archives: gentoo-commits

From: "Gordon Malm (gengor)" <gengor@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] linux-patches r1481 - in hardened/2.6/tags: . 2.6.25-14
Date: Wed, 21 Jan 2009 00:11:44
Message-Id: E1LPQfD-0000Kl-JV@stork.gentoo.org
1 Author: gengor
2 Date: 2009-01-21 00:09:46 +0000 (Wed, 21 Jan 2009)
3 New Revision: 1481
4
5 Added:
6 hardened/2.6/tags/2.6.25-14/
7 hardened/2.6/tags/2.6.25-14/0000_README
8 hardened/2.6/tags/2.6.25-14/1017_linux-2.6.25.18.patch
9 hardened/2.6/tags/2.6.25-14/1018_linux-2.6.25.19.patch
10 hardened/2.6/tags/2.6.25-14/1019_linux-2.6.25.20.patch
11 hardened/2.6/tags/2.6.25-14/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
12 hardened/2.6/tags/2.6.25-14/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
13 hardened/2.6/tags/2.6.25-14/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
14 hardened/2.6/tags/2.6.25-14/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
15 hardened/2.6/tags/2.6.25-14/1405_i-oat-fix-async_tx.callback-checking.patch
16 hardened/2.6/tags/2.6.25-14/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
17 hardened/2.6/tags/2.6.25-14/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
18 hardened/2.6/tags/2.6.25-14/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
19 hardened/2.6/tags/2.6.25-14/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
20 hardened/2.6/tags/2.6.25-14/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
21 hardened/2.6/tags/2.6.25-14/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch
22 hardened/2.6/tags/2.6.25-14/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
23 hardened/2.6/tags/2.6.25-14/1413_block-fix-nr_phys_segments-miscalculation-bug.patch
24 hardened/2.6/tags/2.6.25-14/1414_dm-raid1-flush-workqueue-before-destruction.patch
25 hardened/2.6/tags/2.6.25-14/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch
26 hardened/2.6/tags/2.6.25-14/1416_touch_mnt_namespace-when-the-mount-flags-change.patch
27 hardened/2.6/tags/2.6.25-14/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch
28 hardened/2.6/tags/2.6.25-14/1418_usb-ehci-fix-handling-of-dead-controllers.patch
29 hardened/2.6/tags/2.6.25-14/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
30 hardened/2.6/tags/2.6.25-14/1420_usb-ehci-fix-divide-by-zero-bug.patch
31 hardened/2.6/tags/2.6.25-14/1421_usb-fix-ps3-usb-shutdown-problems.patch
32 hardened/2.6/tags/2.6.25-14/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
33 hardened/2.6/tags/2.6.25-14/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch
34 hardened/2.6/tags/2.6.25-14/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
35 hardened/2.6/tags/2.6.25-14/1425_enforce-a-minimum-sg_io-timeout.patch
36 hardened/2.6/tags/2.6.25-14/1503_hfsplus-check-read_mapping_page-return-value.patch
37 hardened/2.6/tags/2.6.25-14/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch
38 hardened/2.6/tags/2.6.25-14/1505_hfs-fix-namelength-memory-corruption.patch
39 hardened/2.6/tags/2.6.25-14/1506_inotify-fix-watch-removal-or-umount-races.patch
40 hardened/2.6/tags/2.6.25-14/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
41 hardened/2.6/tags/2.6.25-14/1800_sched-disable-hrtick.patch
42 hardened/2.6/tags/2.6.25-14/4420_grsec-2.1.12-2.6.25.16-200808201644.patch
43 hardened/2.6/tags/2.6.25-14/4421_grsec-remove-localversion-grsec.patch
44 hardened/2.6/tags/2.6.25-14/4422_grsec-mute-warnings.patch
45 hardened/2.6/tags/2.6.25-14/4425_grsec-pax-without-grsec.patch
46 hardened/2.6/tags/2.6.25-14/4430_grsec-kconfig-default-gids.patch
47 hardened/2.6/tags/2.6.25-14/4435_grsec-kconfig-gentoo.patch
48 hardened/2.6/tags/2.6.25-14/4440_selinux-avc_audit-log-curr_ip.patch
49 hardened/2.6/tags/2.6.25-14/4445_disable-compat_vdso.patch
50 hardened/2.6/tags/2.6.25-14/4450_pax-remove-read_implies_exec-for-pax-binaries.patch
51 hardened/2.6/tags/2.6.25-14/4455_pax-fix-uvesafb-compile-and-misc.patch
52 hardened/2.6/tags/2.6.25-14/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
53 Log:
54 Tag 2.6.25-14 hardened-extras patchset
55
56 Added: hardened/2.6/tags/2.6.25-14/0000_README
57 ===================================================================
58 --- hardened/2.6/tags/2.6.25-14/0000_README (rev 0)
59 +++ hardened/2.6/tags/2.6.25-14/0000_README 2009-01-21 00:09:46 UTC (rev 1481)
60 @@ -0,0 +1,113 @@
61 +README
62 +-----------------------------------------------------------------------------
63 +
64 +Individual Patch Descriptions:
65 +-----------------------------------------------------------------------------
66 +Patch: 1017_linux-2.6.25.18.patch
67 +From: http://www.kernel.org
68 +Desc: Linux 2.6.25.18
69 +
70 +Patch: 1018_linux-2.6.25.19.patch
71 +From: http://www.kernel.org
72 +Desc: Linux 2.6.25.19
73 +
74 +Patch: 1019_linux-2.6.25.20.patch
75 +From: http://www.kernel.org
76 +Desc: Linux 2.6.25.20
77 +
78 +Patch: 1401* -> 1412*
79 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
80 + a=commit;h=ff413e9814b3914ddf3d4634e9a6cc1c6b21e787
81 +Desc: Backported subset of 2.6.27.6 -stable release patches
82 +
83 +Patch: 1413* -> 1422*
84 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
85 + a=commit;h=526550b7f86d9d395ee1b27ed804e6ffc3feb17c
86 +Desc: Backported subset of 2.6.27.7 -stable release patches
87 +
88 +Patch: 1423*
89 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
90 + a=commit;h=1db886b63e735c3439e5c2f6813c5207c2206895
91 +Desc: Backported subset of 2.6.27.8 -stable release patches
92 +
93 +Patch: 1424* -> 1425*
94 +From: http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git;
95 + a=commit;h=2ef6627be7502193f7c42f694a651fa710507089
96 +Desc: Backported subset of 2.6.27.9 -stable release patches
97 +
98 +Patch: 1503_hfsplus-check-read_mapping_page-return-value.patch
99 +From: Eric Sesterhenn <snakebyte@×××.de>
100 +Desc: hfsplus: check return value of read_mapping_page()
101 +
102 +Patch: 1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch
103 +From: Eric Sesterhenn <snakebyte@×××.de>
104 +Desc: hfsplus: fix buffer overflow when mounting corrupted image
105 +
106 +Patch: 1505_hfs-fix-namelength-memory-corruption.patch
107 +From: Eric Sesterhenn <snakebyte@×××.de>
108 +Desc: hfsplug: Fix stack corruption due to corrupted hfs filesystem
109 +
110 +Patch: 1506_inotify-fix-watch-removal-or-umount-races.patch
111 +From: Al Viro <viro@×××××××××××××××.uk>
112 +Desc: Fix inotify watch removal/umount races (bug #248754)
113 +
114 +Patch: 1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
115 +From: Wei Yongjun <yjwei@××××××××××.com>
116 +Desc: Avoid memory overflow while FWD-TSN chunk received with bad stream ID
117 + (bug #254907)
118 +
119 +Patch: 1800_sched-disable-hrtick.patch
120 +From: Kerin Millar <kerframil@×××××.com>
121 +Desc: Disable high-resolution scheduler ticks (bug #247453)
122 +
123 +Patch: 4420_grsec-2.1.12-2.6.25.16-200808201644.patch
124 +From: http://www.grsecurity.net
125 +Desc: hardened-sources base patch from upstream grsecurity
126 +Note: Ported to 2.6.25.16, adding PaX -test27 through -test30, fixed
127 + missing check in arch/x86/kernel/ioport.c -> do_iopl()
128 +
129 +Patch: 4421_grsec-remove-localversion-grsec.patch
130 +From: Kerin Millar <kerframil@×××××.com>
131 +Desc: Removes grsecurity's localversion-grsec file
132 +
133 +Patch: 4422_grsec-mute-warnings.patch
134 +From: Alexander Gabert <gaberta@××××××××.de>
135 + Gordon Malm <gengor@g.o>
136 +Desc: Removes verbose compile warning settings from grsecurity, restores
137 + mainline Linux kernel behavior
138 +
139 +Patch: 4425_grsec-pax-without-grsec.patch
140 +From: Gordon Malm <gengor@g.o>
141 +Desc: Allows PaX features to be selected without enabling GRKERNSEC
142 +
143 +Patch: 4430_grsec-kconfig-default-gids.patch
144 +From: Kerin Millar <kerframil@×××××.com>
145 +Desc: Sets sane(r) default GIDs on various grsecurity group-dependent
146 + features
147 +
148 +Patch: 4435_grsec-kconfig-gentoo.patch
149 +From: Gordon Malm <gengor@g.o>
150 + Kerin Millar <kerframil@×××××.com>
151 +Desc: Adds Hardened Gentoo [server/workstation] security levels, sets
152 + Hardened Gentoo [workstation] as default
153 +
154 +Patch: 4440_selinux-avc_audit-log-curr_ip.patch
155 +From: Gordon Malm <gengor@g.o>
156 +Desc: Configurable option to add src IP address to SELinux log messages
157 +
158 +Patch: 4445_disable-compat_vdso.patch
159 +From: Gordon Malm <gengor@g.o>
160 + Kerin Millar <kerframil@×××××.com>
161 +Desc: Disables VDSO_COMPAT operation completely
162 +
163 +Patch: 4450_pax-remove-read_implies_exec-for-pax-binaries.patch
164 +From: Gordon Malm <gengor@g.o>
165 +Desc: Remove READ_IMPLIES_EXEC personality for PaX controlled binaries
166 +
167 +Patch: 4455_pax-fix-uvesafb-compile-and-misc.patch
168 +From: Gordon Malm <gengor@g.o>
169 +Desc: Fixes compilation and miscellaneous other problems in uvesafb
170 +
171 +Patch: 4460_pax-fix-mmap-BUG_ON-task-size-check.patch
172 +From: Gordon Malm <gengor@g.o>
173 +Desc: Fix incorrect vma task size check under SEGMEXEC
174
175 Added: hardened/2.6/tags/2.6.25-14/1017_linux-2.6.25.18.patch
176 ===================================================================
177 --- hardened/2.6/tags/2.6.25-14/1017_linux-2.6.25.18.patch (rev 0)
178 +++ hardened/2.6/tags/2.6.25-14/1017_linux-2.6.25.18.patch 2009-01-21 00:09:46 UTC (rev 1481)
179 @@ -0,0 +1,1023 @@
180 +diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
181 +index 36652ea..bec6496 100644
182 +--- a/arch/x86/kernel/hpet.c
183 ++++ b/arch/x86/kernel/hpet.c
184 +@@ -222,8 +222,8 @@ static void hpet_legacy_clockevent_register(void)
185 + /* Calculate the min / max delta */
186 + hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
187 + &hpet_clockevent);
188 +- hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
189 +- &hpet_clockevent);
190 ++ /* 5 usec minimum reprogramming delta. */
191 ++ hpet_clockevent.min_delta_ns = 5000;
192 +
193 + /*
194 + * Start hpet with the boot cpu mask and make it
195 +@@ -282,15 +282,22 @@ static void hpet_legacy_set_mode(enum clock_event_mode mode,
196 + }
197 +
198 + static int hpet_legacy_next_event(unsigned long delta,
199 +- struct clock_event_device *evt)
200 ++ struct clock_event_device *evt)
201 + {
202 +- unsigned long cnt;
203 ++ u32 cnt;
204 +
205 + cnt = hpet_readl(HPET_COUNTER);
206 +- cnt += delta;
207 ++ cnt += (u32) delta;
208 + hpet_writel(cnt, HPET_T0_CMP);
209 +
210 +- return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
211 ++ /*
212 ++ * We need to read back the CMP register to make sure that
213 ++ * what we wrote hit the chip before we compare it to the
214 ++ * counter.
215 ++ */
216 ++ WARN_ON((u32)hpet_readl(HPET_T0_CMP) != cnt);
217 ++
218 ++ return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
219 + }
220 +
221 + /*
222 +diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c
223 +index 5921e5f..84ec3cd 100644
224 +--- a/arch/x86/kernel/io_delay.c
225 ++++ b/arch/x86/kernel/io_delay.c
226 +@@ -92,6 +92,14 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
227 + DMI_MATCH(DMI_BOARD_NAME, "30BF")
228 + }
229 + },
230 ++ {
231 ++ .callback = dmi_io_delay_0xed_port,
232 ++ .ident = "Presario F700",
233 ++ .matches = {
234 ++ DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
235 ++ DMI_MATCH(DMI_BOARD_NAME, "30D3")
236 ++ }
237 ++ },
238 + { }
239 + };
240 +
241 +diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
242 +index 12affe1..72f9826 100644
243 +--- a/arch/x86/kernel/vmi_32.c
244 ++++ b/arch/x86/kernel/vmi_32.c
245 +@@ -234,7 +234,7 @@ static void vmi_write_ldt_entry(struct desc_struct *dt, int entry,
246 + const void *desc)
247 + {
248 + u32 *ldt_entry = (u32 *)desc;
249 +- vmi_ops.write_idt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
250 ++ vmi_ops.write_ldt_entry(dt, entry, ldt_entry[0], ldt_entry[1]);
251 + }
252 +
253 + static void vmi_load_sp0(struct tss_struct *tss,
254 +diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
255 +index 7222a18..a9b8796 100644
256 +--- a/drivers/acpi/ec.c
257 ++++ b/drivers/acpi/ec.c
258 +@@ -228,6 +228,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
259 + if (acpi_ec_check_status(ec, event))
260 + goto end;
261 + }
262 ++ if (acpi_ec_check_status(ec,event))
263 ++ return 0;
264 + }
265 + pr_err(PREFIX "acpi_ec_wait timeout,"
266 + " status = %d, expect_event = %d\n",
267 +diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
268 +index 42fb635..87b9a17 100644
269 +--- a/drivers/acpi/processor_perflib.c
270 ++++ b/drivers/acpi/processor_perflib.c
271 +@@ -70,7 +70,7 @@ static DEFINE_MUTEX(performance_mutex);
272 + * 0 -> cpufreq low level drivers initialized -> consider _PPC values
273 + * 1 -> ignore _PPC totally -> forced by user through boot param
274 + */
275 +-static unsigned int ignore_ppc = -1;
276 ++static int ignore_ppc = -1;
277 + module_param(ignore_ppc, uint, 0644);
278 + MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
279 + "limited by BIOS, this should help");
280 +diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
281 +index 393e679..342255b 100644
282 +--- a/drivers/i2c/i2c-dev.c
283 ++++ b/drivers/i2c/i2c-dev.c
284 +@@ -574,8 +574,10 @@ static int __init i2c_dev_init(void)
285 + goto out;
286 +
287 + i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
288 +- if (IS_ERR(i2c_dev_class))
289 ++ if (IS_ERR(i2c_dev_class)) {
290 ++ res = PTR_ERR(i2c_dev_class);
291 + goto out_unreg_chrdev;
292 ++ }
293 +
294 + res = i2c_add_driver(&i2cdev_driver);
295 + if (res)
296 +diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
297 +index 91ded3e..3318642 100644
298 +--- a/drivers/mmc/card/block.c
299 ++++ b/drivers/mmc/card/block.c
300 +@@ -103,8 +103,10 @@ static int mmc_blk_open(struct inode *inode, struct file *filp)
301 + check_disk_change(inode->i_bdev);
302 + ret = 0;
303 +
304 +- if ((filp->f_mode & FMODE_WRITE) && md->read_only)
305 ++ if ((filp->f_mode & FMODE_WRITE) && md->read_only) {
306 ++ mmc_blk_put(md);
307 + ret = -EROFS;
308 ++ }
309 + }
310 +
311 + return ret;
312 +diff --git a/drivers/net/niu.c b/drivers/net/niu.c
313 +index d11ba61..5fd6a65 100644
314 +--- a/drivers/net/niu.c
315 ++++ b/drivers/net/niu.c
316 +@@ -5230,6 +5230,56 @@ static void niu_netif_start(struct niu *np)
317 + niu_enable_interrupts(np, 1);
318 + }
319 +
320 ++static void niu_reset_buffers(struct niu *np)
321 ++{
322 ++ int i, j, k, err;
323 ++
324 ++ if (np->rx_rings) {
325 ++ for (i = 0; i < np->num_rx_rings; i++) {
326 ++ struct rx_ring_info *rp = &np->rx_rings[i];
327 ++
328 ++ for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
329 ++ struct page *page;
330 ++
331 ++ page = rp->rxhash[j];
332 ++ while (page) {
333 ++ struct page *next =
334 ++ (struct page *) page->mapping;
335 ++ u64 base = page->index;
336 ++ base = base >> RBR_DESCR_ADDR_SHIFT;
337 ++ rp->rbr[k++] = cpu_to_le32(base);
338 ++ page = next;
339 ++ }
340 ++ }
341 ++ for (; k < MAX_RBR_RING_SIZE; k++) {
342 ++ err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
343 ++ if (unlikely(err))
344 ++ break;
345 ++ }
346 ++
347 ++ rp->rbr_index = rp->rbr_table_size - 1;
348 ++ rp->rcr_index = 0;
349 ++ rp->rbr_pending = 0;
350 ++ rp->rbr_refill_pending = 0;
351 ++ }
352 ++ }
353 ++ if (np->tx_rings) {
354 ++ for (i = 0; i < np->num_tx_rings; i++) {
355 ++ struct tx_ring_info *rp = &np->tx_rings[i];
356 ++
357 ++ for (j = 0; j < MAX_TX_RING_SIZE; j++) {
358 ++ if (rp->tx_buffs[j].skb)
359 ++ (void) release_tx_packet(np, rp, j);
360 ++ }
361 ++
362 ++ rp->pending = MAX_TX_RING_SIZE;
363 ++ rp->prod = 0;
364 ++ rp->cons = 0;
365 ++ rp->wrap_bit = 0;
366 ++ }
367 ++ }
368 ++}
369 ++
370 + static void niu_reset_task(struct work_struct *work)
371 + {
372 + struct niu *np = container_of(work, struct niu, reset_task);
373 +@@ -5252,6 +5302,12 @@ static void niu_reset_task(struct work_struct *work)
374 +
375 + niu_stop_hw(np);
376 +
377 ++ spin_unlock_irqrestore(&np->lock, flags);
378 ++
379 ++ niu_reset_buffers(np);
380 ++
381 ++ spin_lock_irqsave(&np->lock, flags);
382 ++
383 + err = niu_init_hw(np);
384 + if (!err) {
385 + np->timer.expires = jiffies + HZ;
386 +diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
387 +index 147e26a..1dcc79f 100644
388 +--- a/drivers/spi/pxa2xx_spi.c
389 ++++ b/drivers/spi/pxa2xx_spi.c
390 +@@ -48,9 +48,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
391 +
392 + #define MAX_BUSES 3
393 +
394 +-#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
395 +-#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
396 +-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
397 ++#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
398 ++#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
399 ++#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0)
400 ++#define MAX_DMA_LEN 8191
401 +
402 + /*
403 + * for testing SSCR1 changes that require SSP restart, basically
404 +@@ -142,7 +143,6 @@ struct driver_data {
405 + size_t tx_map_len;
406 + u8 n_bytes;
407 + u32 dma_width;
408 +- int cs_change;
409 + int (*write)(struct driver_data *drv_data);
410 + int (*read)(struct driver_data *drv_data);
411 + irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
412 +@@ -404,8 +404,45 @@ static void giveback(struct driver_data *drv_data)
413 + struct spi_transfer,
414 + transfer_list);
415 +
416 ++ /* Delay if requested before any change in chip select */
417 ++ if (last_transfer->delay_usecs)
418 ++ udelay(last_transfer->delay_usecs);
419 ++
420 ++ /* Drop chip select UNLESS cs_change is true or we are returning
421 ++ * a message with an error, or next message is for another chip
422 ++ */
423 + if (!last_transfer->cs_change)
424 + drv_data->cs_control(PXA2XX_CS_DEASSERT);
425 ++ else {
426 ++ struct spi_message *next_msg;
427 ++
428 ++ /* Holding of cs was hinted, but we need to make sure
429 ++ * the next message is for the same chip. Don't waste
430 ++ * time with the following tests unless this was hinted.
431 ++ *
432 ++ * We cannot postpone this until pump_messages, because
433 ++ * after calling msg->complete (below) the driver that
434 ++ * sent the current message could be unloaded, which
435 ++ * could invalidate the cs_control() callback...
436 ++ */
437 ++
438 ++ /* get a pointer to the next message, if any */
439 ++ spin_lock_irqsave(&drv_data->lock, flags);
440 ++ if (list_empty(&drv_data->queue))
441 ++ next_msg = NULL;
442 ++ else
443 ++ next_msg = list_entry(drv_data->queue.next,
444 ++ struct spi_message, queue);
445 ++ spin_unlock_irqrestore(&drv_data->lock, flags);
446 ++
447 ++ /* see if the next and current messages point
448 ++ * to the same chip
449 ++ */
450 ++ if (next_msg && next_msg->spi != msg->spi)
451 ++ next_msg = NULL;
452 ++ if (!next_msg || msg->state == ERROR_STATE)
453 ++ drv_data->cs_control(PXA2XX_CS_DEASSERT);
454 ++ }
455 +
456 + msg->state = NULL;
457 + if (msg->complete)
458 +@@ -488,10 +525,9 @@ static void dma_transfer_complete(struct driver_data *drv_data)
459 + msg->actual_length += drv_data->len -
460 + (drv_data->rx_end - drv_data->rx);
461 +
462 +- /* Release chip select if requested, transfer delays are
463 +- * handled in pump_transfers */
464 +- if (drv_data->cs_change)
465 +- drv_data->cs_control(PXA2XX_CS_DEASSERT);
466 ++ /* Transfer delays and chip select release are
467 ++ * handled in pump_transfers or giveback
468 ++ */
469 +
470 + /* Move to next transfer */
471 + msg->state = next_transfer(drv_data);
472 +@@ -600,10 +636,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
473 + drv_data->cur_msg->actual_length += drv_data->len -
474 + (drv_data->rx_end - drv_data->rx);
475 +
476 +- /* Release chip select if requested, transfer delays are
477 +- * handled in pump_transfers */
478 +- if (drv_data->cs_change)
479 +- drv_data->cs_control(PXA2XX_CS_DEASSERT);
480 ++ /* Transfer delays and chip select release are
481 ++ * handled in pump_transfers or giveback
482 ++ */
483 +
484 + /* Move to next transfer */
485 + drv_data->cur_msg->state = next_transfer(drv_data);
486 +@@ -837,23 +872,40 @@ static void pump_transfers(unsigned long data)
487 + return;
488 + }
489 +
490 +- /* Delay if requested at end of transfer*/
491 ++ /* Delay if requested at end of transfer before CS change */
492 + if (message->state == RUNNING_STATE) {
493 + previous = list_entry(transfer->transfer_list.prev,
494 + struct spi_transfer,
495 + transfer_list);
496 + if (previous->delay_usecs)
497 + udelay(previous->delay_usecs);
498 ++
499 ++ /* Drop chip select only if cs_change is requested */
500 ++ if (previous->cs_change)
501 ++ drv_data->cs_control(PXA2XX_CS_DEASSERT);
502 + }
503 +
504 +- /* Check transfer length */
505 +- if (transfer->len > 8191)
506 +- {
507 +- dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
508 +- "length greater than 8191\n");
509 +- message->status = -EINVAL;
510 +- giveback(drv_data);
511 +- return;
512 ++ /* Check for transfers that need multiple DMA segments */
513 ++ if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
514 ++
515 ++ /* reject already-mapped transfers; PIO won't always work */
516 ++ if (message->is_dma_mapped
517 ++ || transfer->rx_dma || transfer->tx_dma) {
518 ++ dev_err(&drv_data->pdev->dev,
519 ++ "pump_transfers: mapped transfer length "
520 ++ "of %u is greater than %d\n",
521 ++ transfer->len, MAX_DMA_LEN);
522 ++ message->status = -EINVAL;
523 ++ giveback(drv_data);
524 ++ return;
525 ++ }
526 ++
527 ++ /* warn ... we force this to PIO mode */
528 ++ if (printk_ratelimit())
529 ++ dev_warn(&message->spi->dev, "pump_transfers: "
530 ++ "DMA disabled for transfer length %ld "
531 ++ "greater than %d\n",
532 ++ (long)drv_data->len, MAX_DMA_LEN);
533 + }
534 +
535 + /* Setup the transfer state based on the type of transfer */
536 +@@ -875,7 +927,6 @@ static void pump_transfers(unsigned long data)
537 + drv_data->len = transfer->len & DCMD_LENGTH;
538 + drv_data->write = drv_data->tx ? chip->write : null_writer;
539 + drv_data->read = drv_data->rx ? chip->read : null_reader;
540 +- drv_data->cs_change = transfer->cs_change;
541 +
542 + /* Change speed and bit per word on a per transfer */
543 + cr0 = chip->cr0;
544 +@@ -922,7 +973,7 @@ static void pump_transfers(unsigned long data)
545 + &dma_thresh))
546 + if (printk_ratelimit())
547 + dev_warn(&message->spi->dev,
548 +- "pump_transfer: "
549 ++ "pump_transfers: "
550 + "DMA burst size reduced to "
551 + "match bits_per_word\n");
552 + }
553 +@@ -936,8 +987,23 @@ static void pump_transfers(unsigned long data)
554 +
555 + message->state = RUNNING_STATE;
556 +
557 +- /* Try to map dma buffer and do a dma transfer if successful */
558 +- if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
559 ++ /* Try to map dma buffer and do a dma transfer if successful, but
560 ++ * only if the length is non-zero and less than MAX_DMA_LEN.
561 ++ *
562 ++ * Zero-length non-descriptor DMA is illegal on PXA2xx; force use
563 ++ * of PIO instead. Care is needed above because the transfer may
564 ++ * have have been passed with buffers that are already dma mapped.
565 ++ * A zero-length transfer in PIO mode will not try to write/read
566 ++ * to/from the buffers
567 ++ *
568 ++ * REVISIT large transfers are exactly where we most want to be
569 ++ * using DMA. If this happens much, split those transfers into
570 ++ * multiple DMA segments rather than forcing PIO.
571 ++ */
572 ++ drv_data->dma_mapped = 0;
573 ++ if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
574 ++ drv_data->dma_mapped = map_dma_buffers(drv_data);
575 ++ if (drv_data->dma_mapped) {
576 +
577 + /* Ensure we have the correct interrupt handler */
578 + drv_data->transfer_handler = dma_transfer;
579 +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
580 +index 27533b3..ed7b123 100644
581 +--- a/drivers/usb/core/hcd.c
582 ++++ b/drivers/usb/core/hcd.c
583 +@@ -1877,7 +1877,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
584 + * with IRQF_SHARED. As usb_hcd_irq() will always disable
585 + * interrupts we can remove it here.
586 + */
587 +- irqflags &= ~IRQF_DISABLED;
588 ++ if (irqflags & IRQF_SHARED)
589 ++ irqflags &= ~IRQF_DISABLED;
590 +
591 + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
592 + hcd->driver->description, hcd->self.busnum);
593 +diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
594 +index dd1bed8..85286fb 100644
595 +--- a/include/asm-generic/rtc.h
596 ++++ b/include/asm-generic/rtc.h
597 +@@ -17,6 +17,7 @@
598 + #include <linux/mc146818rtc.h>
599 + #include <linux/rtc.h>
600 + #include <linux/bcd.h>
601 ++#include <linux/delay.h>
602 +
603 + #define RTC_PIE 0x40 /* periodic interrupt enable */
604 + #define RTC_AIE 0x20 /* alarm interrupt enable */
605 +@@ -45,7 +46,6 @@ static inline unsigned char rtc_is_updating(void)
606 +
607 + static inline unsigned int get_rtc_time(struct rtc_time *time)
608 + {
609 +- unsigned long uip_watchdog = jiffies;
610 + unsigned char ctrl;
611 + unsigned long flags;
612 +
613 +@@ -55,19 +55,15 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
614 +
615 + /*
616 + * read RTC once any update in progress is done. The update
617 +- * can take just over 2ms. We wait 10 to 20ms. There is no need to
618 ++ * can take just over 2ms. We wait 20ms. There is no need to
619 + * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
620 + * If you need to know *exactly* when a second has started, enable
621 + * periodic update complete interrupts, (via ioctl) and then
622 + * immediately read /dev/rtc which will block until you get the IRQ.
623 + * Once the read clears, read the RTC time (again via ioctl). Easy.
624 + */
625 +-
626 +- if (rtc_is_updating() != 0)
627 +- while (jiffies - uip_watchdog < 2*HZ/100) {
628 +- barrier();
629 +- cpu_relax();
630 +- }
631 ++ if (rtc_is_updating())
632 ++ mdelay(20);
633 +
634 + /*
635 + * Only the values that we read from the RTC are set. We leave
636 +diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
637 +index c33b0dc..ed3a5d4 100644
638 +--- a/include/linux/clockchips.h
639 ++++ b/include/linux/clockchips.h
640 +@@ -127,6 +127,8 @@ extern int clockevents_register_notifier(struct notifier_block *nb);
641 + extern int clockevents_program_event(struct clock_event_device *dev,
642 + ktime_t expires, ktime_t now);
643 +
644 ++extern void clockevents_handle_noop(struct clock_event_device *dev);
645 ++
646 + #ifdef CONFIG_GENERIC_CLOCKEVENTS
647 + extern void clockevents_notify(unsigned long reason, void *arg);
648 + #else
649 +diff --git a/include/net/netlink.h b/include/net/netlink.h
650 +index 112dcdf..5383fdf 100644
651 +--- a/include/net/netlink.h
652 ++++ b/include/net/netlink.h
653 +@@ -704,7 +704,7 @@ static inline int nla_len(const struct nlattr *nla)
654 + */
655 + static inline int nla_ok(const struct nlattr *nla, int remaining)
656 + {
657 +- return remaining >= sizeof(*nla) &&
658 ++ return remaining >= (int) sizeof(*nla) &&
659 + nla->nla_len >= sizeof(*nla) &&
660 + nla->nla_len <= remaining;
661 + }
662 +diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
663 +index 3d1e3e1..1876b52 100644
664 +--- a/kernel/time/clockevents.c
665 ++++ b/kernel/time/clockevents.c
666 +@@ -177,7 +177,7 @@ void clockevents_register_device(struct clock_event_device *dev)
667 + /*
668 + * Noop handler when we shut down an event device
669 + */
670 +-static void clockevents_handle_noop(struct clock_event_device *dev)
671 ++void clockevents_handle_noop(struct clock_event_device *dev)
672 + {
673 + }
674 +
675 +@@ -199,7 +199,6 @@ void clockevents_exchange_device(struct clock_event_device *old,
676 + * released list and do a notify add later.
677 + */
678 + if (old) {
679 +- old->event_handler = clockevents_handle_noop;
680 + clockevents_set_mode(old, CLOCK_EVT_MODE_UNUSED);
681 + list_del(&old->list);
682 + list_add(&old->list, &clockevents_released);
683 +diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
684 +index 5fd9b94..a1dac40 100644
685 +--- a/kernel/time/ntp.c
686 ++++ b/kernel/time/ntp.c
687 +@@ -205,7 +205,7 @@ static void sync_cmos_clock(unsigned long dummy)
688 + if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
689 + fail = update_persistent_clock(now);
690 +
691 +- next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec;
692 ++ next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
693 + if (next.tv_nsec <= 0)
694 + next.tv_nsec += NSEC_PER_SEC;
695 +
696 +diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
697 +index e1bd50c..0edd345 100644
698 +--- a/kernel/time/tick-broadcast.c
699 ++++ b/kernel/time/tick-broadcast.c
700 +@@ -174,6 +174,8 @@ static void tick_do_periodic_broadcast(void)
701 + */
702 + static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
703 + {
704 ++ ktime_t next;
705 ++
706 + tick_do_periodic_broadcast();
707 +
708 + /*
709 +@@ -184,10 +186,13 @@ static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
710 +
711 + /*
712 + * Setup the next period for devices, which do not have
713 +- * periodic mode:
714 ++ * periodic mode. We read dev->next_event first and add to it
715 ++ * when the event alrady expired. clockevents_program_event()
716 ++ * sets dev->next_event only when the event is really
717 ++ * programmed to the device.
718 + */
719 +- for (;;) {
720 +- ktime_t next = ktime_add(dev->next_event, tick_period);
721 ++ for (next = dev->next_event; ;) {
722 ++ next = ktime_add(next, tick_period);
723 +
724 + if (!clockevents_program_event(dev, next, ktime_get()))
725 + return;
726 +@@ -204,7 +209,7 @@ static void tick_do_broadcast_on_off(void *why)
727 + struct clock_event_device *bc, *dev;
728 + struct tick_device *td;
729 + unsigned long flags, *reason = why;
730 +- int cpu;
731 ++ int cpu, bc_stopped;
732 +
733 + spin_lock_irqsave(&tick_broadcast_lock, flags);
734 +
735 +@@ -222,6 +227,8 @@ static void tick_do_broadcast_on_off(void *why)
736 + if (!tick_device_is_functional(dev))
737 + goto out;
738 +
739 ++ bc_stopped = cpus_empty(tick_broadcast_mask);
740 ++
741 + switch (*reason) {
742 + case CLOCK_EVT_NOTIFY_BROADCAST_ON:
743 + case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
744 +@@ -243,9 +250,10 @@ static void tick_do_broadcast_on_off(void *why)
745 + break;
746 + }
747 +
748 +- if (cpus_empty(tick_broadcast_mask))
749 +- clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
750 +- else {
751 ++ if (cpus_empty(tick_broadcast_mask)) {
752 ++ if (!bc_stopped)
753 ++ clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
754 ++ } else if (bc_stopped) {
755 + if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
756 + tick_broadcast_start_periodic(bc);
757 + else
758 +@@ -362,16 +370,8 @@ cpumask_t *tick_get_broadcast_oneshot_mask(void)
759 + static int tick_broadcast_set_event(ktime_t expires, int force)
760 + {
761 + struct clock_event_device *bc = tick_broadcast_device.evtdev;
762 +- ktime_t now = ktime_get();
763 +- int res;
764 +-
765 +- for(;;) {
766 +- res = clockevents_program_event(bc, expires, now);
767 +- if (!res || !force)
768 +- return res;
769 +- now = ktime_get();
770 +- expires = ktime_add(now, ktime_set(0, bc->min_delta_ns));
771 +- }
772 ++
773 ++ return tick_dev_program_event(bc, expires, force);
774 + }
775 +
776 + int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
777 +@@ -490,14 +490,52 @@ static void tick_broadcast_clear_oneshot(int cpu)
778 + cpu_clear(cpu, tick_broadcast_oneshot_mask);
779 + }
780 +
781 ++static void tick_broadcast_init_next_event(cpumask_t *mask, ktime_t expires)
782 ++{
783 ++ struct tick_device *td;
784 ++ int cpu;
785 ++
786 ++ for_each_cpu_mask(cpu, *mask) {
787 ++ td = &per_cpu(tick_cpu_device, cpu);
788 ++ if (td->evtdev)
789 ++ td->evtdev->next_event = expires;
790 ++ }
791 ++}
792 ++
793 + /**
794 + * tick_broadcast_setup_oneshot - setup the broadcast device
795 + */
796 + void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
797 + {
798 +- bc->event_handler = tick_handle_oneshot_broadcast;
799 +- clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
800 +- bc->next_event.tv64 = KTIME_MAX;
801 ++ /* Set it up only once ! */
802 ++ if (bc->event_handler != tick_handle_oneshot_broadcast) {
803 ++ int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC;
804 ++ int cpu = smp_processor_id();
805 ++ cpumask_t mask;
806 ++
807 ++ bc->event_handler = tick_handle_oneshot_broadcast;
808 ++ clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
809 ++
810 ++ /* Take the do_timer update */
811 ++ tick_do_timer_cpu = cpu;
812 ++
813 ++ /*
814 ++ * We must be careful here. There might be other CPUs
815 ++ * waiting for periodic broadcast. We need to set the
816 ++ * oneshot_mask bits for those and program the
817 ++ * broadcast device to fire.
818 ++ */
819 ++ mask = tick_broadcast_mask;
820 ++ cpu_clear(cpu, mask);
821 ++ cpus_or(tick_broadcast_oneshot_mask,
822 ++ tick_broadcast_oneshot_mask, mask);
823 ++
824 ++ if (was_periodic && !cpus_empty(mask)) {
825 ++ tick_broadcast_init_next_event(&mask, tick_next_period);
826 ++ tick_broadcast_set_event(tick_next_period, 1);
827 ++ } else
828 ++ bc->next_event.tv64 = KTIME_MAX;
829 ++ }
830 + }
831 +
832 + /*
833 +diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
834 +index 1bea399..d106d61 100644
835 +--- a/kernel/time/tick-common.c
836 ++++ b/kernel/time/tick-common.c
837 +@@ -159,6 +159,7 @@ static void tick_setup_device(struct tick_device *td,
838 + } else {
839 + handler = td->evtdev->event_handler;
840 + next_event = td->evtdev->next_event;
841 ++ td->evtdev->event_handler = clockevents_handle_noop;
842 + }
843 +
844 + td->evtdev = newdev;
845 +diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
846 +index f13f2b7..0ffc291 100644
847 +--- a/kernel/time/tick-internal.h
848 ++++ b/kernel/time/tick-internal.h
849 +@@ -17,6 +17,8 @@ extern void tick_handle_periodic(struct clock_event_device *dev);
850 + extern void tick_setup_oneshot(struct clock_event_device *newdev,
851 + void (*handler)(struct clock_event_device *),
852 + ktime_t nextevt);
853 ++extern int tick_dev_program_event(struct clock_event_device *dev,
854 ++ ktime_t expires, int force);
855 + extern int tick_program_event(ktime_t expires, int force);
856 + extern void tick_oneshot_notify(void);
857 + extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *));
858 +diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c
859 +index 0258d31..0737da0 100644
860 +--- a/kernel/time/tick-oneshot.c
861 ++++ b/kernel/time/tick-oneshot.c
862 +@@ -23,24 +23,56 @@
863 + #include "tick-internal.h"
864 +
865 + /**
866 +- * tick_program_event
867 ++ * tick_program_event internal worker function
868 + */
869 +-int tick_program_event(ktime_t expires, int force)
870 ++int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
871 ++ int force)
872 + {
873 +- struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
874 + ktime_t now = ktime_get();
875 ++ int i;
876 +
877 +- while (1) {
878 ++ for (i = 0;;) {
879 + int ret = clockevents_program_event(dev, expires, now);
880 +
881 + if (!ret || !force)
882 + return ret;
883 ++
884 ++ /*
885 ++ * We tried 2 times to program the device with the given
886 ++ * min_delta_ns. If that's not working then we double it
887 ++ * and emit a warning.
888 ++ */
889 ++ if (++i > 2) {
890 ++ /* Increase the min. delta and try again */
891 ++ if (!dev->min_delta_ns)
892 ++ dev->min_delta_ns = 5000;
893 ++ else
894 ++ dev->min_delta_ns += dev->min_delta_ns >> 1;
895 ++
896 ++ printk(KERN_WARNING
897 ++ "CE: %s increasing min_delta_ns to %lu nsec\n",
898 ++ dev->name ? dev->name : "?",
899 ++ dev->min_delta_ns << 1);
900 ++
901 ++ i = 0;
902 ++ }
903 ++
904 + now = ktime_get();
905 +- expires = ktime_add(now, ktime_set(0, dev->min_delta_ns));
906 ++ expires = ktime_add_ns(now, dev->min_delta_ns);
907 + }
908 + }
909 +
910 + /**
911 ++ * tick_program_event
912 ++ */
913 ++int tick_program_event(ktime_t expires, int force)
914 ++{
915 ++ struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
916 ++
917 ++ return tick_dev_program_event(dev, expires, force);
918 ++}
919 ++
920 ++/**
921 + * tick_resume_onshot - resume oneshot mode
922 + */
923 + void tick_resume_oneshot(void)
924 +@@ -61,7 +93,7 @@ void tick_setup_oneshot(struct clock_event_device *newdev,
925 + {
926 + newdev->event_handler = handler;
927 + clockevents_set_mode(newdev, CLOCK_EVT_MODE_ONESHOT);
928 +- clockevents_program_event(newdev, next_event, ktime_get());
929 ++ tick_dev_program_event(newdev, next_event, 1);
930 + }
931 +
932 + /**
933 +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
934 +index 9703c87..b924502 100644
935 +--- a/net/ipv4/udp.c
936 ++++ b/net/ipv4/udp.c
937 +@@ -956,6 +956,27 @@ int udp_disconnect(struct sock *sk, int flags)
938 + return 0;
939 + }
940 +
941 ++static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
942 ++{
943 ++ int is_udplite = IS_UDPLITE(sk);
944 ++ int rc;
945 ++
946 ++ if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
947 ++ /* Note that an ENOMEM error is charged twice */
948 ++ if (rc == -ENOMEM)
949 ++ UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS,
950 ++ is_udplite);
951 ++ goto drop;
952 ++ }
953 ++
954 ++ return 0;
955 ++
956 ++drop:
957 ++ UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
958 ++ kfree_skb(skb);
959 ++ return -1;
960 ++}
961 ++
962 + /* returns:
963 + * -1: error
964 + * 0: success
965 +@@ -1046,14 +1067,16 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
966 + goto drop;
967 + }
968 +
969 +- if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
970 +- /* Note that an ENOMEM error is charged twice */
971 +- if (rc == -ENOMEM)
972 +- UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite);
973 +- goto drop;
974 +- }
975 ++ rc = 0;
976 +
977 +- return 0;
978 ++ bh_lock_sock(sk);
979 ++ if (!sock_owned_by_user(sk))
980 ++ rc = __udp_queue_rcv_skb(sk, skb);
981 ++ else
982 ++ sk_add_backlog(sk, skb);
983 ++ bh_unlock_sock(sk);
984 ++
985 ++ return rc;
986 +
987 + drop:
988 + UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
989 +@@ -1091,15 +1114,7 @@ static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
990 + skb1 = skb_clone(skb, GFP_ATOMIC);
991 +
992 + if (skb1) {
993 +- int ret = 0;
994 +-
995 +- bh_lock_sock_nested(sk);
996 +- if (!sock_owned_by_user(sk))
997 +- ret = udp_queue_rcv_skb(sk, skb1);
998 +- else
999 +- sk_add_backlog(sk, skb1);
1000 +- bh_unlock_sock(sk);
1001 +-
1002 ++ int ret = udp_queue_rcv_skb(sk, skb1);
1003 + if (ret > 0)
1004 + /* we should probably re-process instead
1005 + * of dropping packets here. */
1006 +@@ -1192,13 +1207,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1007 + uh->dest, inet_iif(skb), udptable);
1008 +
1009 + if (sk != NULL) {
1010 +- int ret = 0;
1011 +- bh_lock_sock_nested(sk);
1012 +- if (!sock_owned_by_user(sk))
1013 +- ret = udp_queue_rcv_skb(sk, skb);
1014 +- else
1015 +- sk_add_backlog(sk, skb);
1016 +- bh_unlock_sock(sk);
1017 ++ int ret = udp_queue_rcv_skb(sk, skb);
1018 + sock_put(sk);
1019 +
1020 + /* a return value > 0 means to resubmit the input, but
1021 +@@ -1493,7 +1502,7 @@ struct proto udp_prot = {
1022 + .sendmsg = udp_sendmsg,
1023 + .recvmsg = udp_recvmsg,
1024 + .sendpage = udp_sendpage,
1025 +- .backlog_rcv = udp_queue_rcv_skb,
1026 ++ .backlog_rcv = __udp_queue_rcv_skb,
1027 + .hash = udp_lib_hash,
1028 + .unhash = udp_lib_unhash,
1029 + .get_port = udp_v4_get_port,
1030 +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
1031 +index fb1c192..d650e10 100644
1032 +--- a/net/ipv6/ip6_output.c
1033 ++++ b/net/ipv6/ip6_output.c
1034 +@@ -930,39 +930,39 @@ static int ip6_dst_lookup_tail(struct sock *sk,
1035 + }
1036 +
1037 + #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
1038 +- /*
1039 +- * Here if the dst entry we've looked up
1040 +- * has a neighbour entry that is in the INCOMPLETE
1041 +- * state and the src address from the flow is
1042 +- * marked as OPTIMISTIC, we release the found
1043 +- * dst entry and replace it instead with the
1044 +- * dst entry of the nexthop router
1045 +- */
1046 +- if (!((*dst)->neighbour->nud_state & NUD_VALID)) {
1047 +- struct inet6_ifaddr *ifp;
1048 +- struct flowi fl_gw;
1049 +- int redirect;
1050 +-
1051 +- ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src,
1052 +- (*dst)->dev, 1);
1053 +-
1054 +- redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
1055 +- if (ifp)
1056 +- in6_ifa_put(ifp);
1057 +-
1058 +- if (redirect) {
1059 +- /*
1060 +- * We need to get the dst entry for the
1061 +- * default router instead
1062 +- */
1063 +- dst_release(*dst);
1064 +- memcpy(&fl_gw, fl, sizeof(struct flowi));
1065 +- memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
1066 +- *dst = ip6_route_output(sk, &fl_gw);
1067 +- if ((err = (*dst)->error))
1068 +- goto out_err_release;
1069 +- }
1070 ++ /*
1071 ++ * Here if the dst entry we've looked up
1072 ++ * has a neighbour entry that is in the INCOMPLETE
1073 ++ * state and the src address from the flow is
1074 ++ * marked as OPTIMISTIC, we release the found
1075 ++ * dst entry and replace it instead with the
1076 ++ * dst entry of the nexthop router
1077 ++ */
1078 ++ if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
1079 ++ struct inet6_ifaddr *ifp;
1080 ++ struct flowi fl_gw;
1081 ++ int redirect;
1082 ++
1083 ++ ifp = ipv6_get_ifaddr(&init_net, &fl->fl6_src,
1084 ++ (*dst)->dev, 1);
1085 ++
1086 ++ redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
1087 ++ if (ifp)
1088 ++ in6_ifa_put(ifp);
1089 ++
1090 ++ if (redirect) {
1091 ++ /*
1092 ++ * We need to get the dst entry for the
1093 ++ * default router instead
1094 ++ */
1095 ++ dst_release(*dst);
1096 ++ memcpy(&fl_gw, fl, sizeof(struct flowi));
1097 ++ memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
1098 ++ *dst = ip6_route_output(sk, &fl_gw);
1099 ++ if ((err = (*dst)->error))
1100 ++ goto out_err_release;
1101 + }
1102 ++ }
1103 + #endif
1104 +
1105 + return 0;
1106 +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
1107 +index 53739de..4e36c57 100644
1108 +--- a/net/ipv6/udp.c
1109 ++++ b/net/ipv6/udp.c
1110 +@@ -373,7 +373,7 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
1111 + uh->source, saddr, dif))) {
1112 + struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC);
1113 + if (buff) {
1114 +- bh_lock_sock_nested(sk2);
1115 ++ bh_lock_sock(sk2);
1116 + if (!sock_owned_by_user(sk2))
1117 + udpv6_queue_rcv_skb(sk2, buff);
1118 + else
1119 +@@ -381,7 +381,7 @@ static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
1120 + bh_unlock_sock(sk2);
1121 + }
1122 + }
1123 +- bh_lock_sock_nested(sk);
1124 ++ bh_lock_sock(sk);
1125 + if (!sock_owned_by_user(sk))
1126 + udpv6_queue_rcv_skb(sk, skb);
1127 + else
1128 +@@ -499,7 +499,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1129 +
1130 + /* deliver */
1131 +
1132 +- bh_lock_sock_nested(sk);
1133 ++ bh_lock_sock(sk);
1134 + if (!sock_owned_by_user(sk))
1135 + udpv6_queue_rcv_skb(sk, skb);
1136 + else
1137 +diff --git a/net/sctp/associola.c b/net/sctp/associola.c
1138 +index d29f792..1eefac2 100644
1139 +--- a/net/sctp/associola.c
1140 ++++ b/net/sctp/associola.c
1141 +@@ -588,11 +588,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
1142 + /* Check to see if this is a duplicate. */
1143 + peer = sctp_assoc_lookup_paddr(asoc, addr);
1144 + if (peer) {
1145 ++ /* An UNKNOWN state is only set on transports added by
1146 ++ * user in sctp_connectx() call. Such transports should be
1147 ++ * considered CONFIRMED per RFC 4960, Section 5.4.
1148 ++ */
1149 + if (peer->state == SCTP_UNKNOWN) {
1150 +- if (peer_state == SCTP_ACTIVE)
1151 +- peer->state = SCTP_ACTIVE;
1152 +- if (peer_state == SCTP_UNCONFIRMED)
1153 +- peer->state = SCTP_UNCONFIRMED;
1154 ++ peer->state = SCTP_ACTIVE;
1155 + }
1156 + return peer;
1157 + }
1158 +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
1159 +index 36ebb39..d024fd0 100644
1160 +--- a/net/sctp/sm_make_chunk.c
1161 ++++ b/net/sctp/sm_make_chunk.c
1162 +@@ -1886,11 +1886,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
1163 + /* if the peer reports AUTH, assume that he
1164 + * supports AUTH.
1165 + */
1166 +- asoc->peer.auth_capable = 1;
1167 ++ if (sctp_auth_enable)
1168 ++ asoc->peer.auth_capable = 1;
1169 + break;
1170 + case SCTP_CID_ASCONF:
1171 + case SCTP_CID_ASCONF_ACK:
1172 +- asoc->peer.asconf_capable = 1;
1173 ++ if (sctp_addip_enable)
1174 ++ asoc->peer.asconf_capable = 1;
1175 + break;
1176 + default:
1177 + break;
1178 +@@ -2319,12 +2321,10 @@ clean_up:
1179 + /* Release the transport structures. */
1180 + list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
1181 + transport = list_entry(pos, struct sctp_transport, transports);
1182 +- list_del_init(pos);
1183 +- sctp_transport_free(transport);
1184 ++ if (transport->state != SCTP_ACTIVE)
1185 ++ sctp_assoc_rm_peer(asoc, transport);
1186 + }
1187 +
1188 +- asoc->peer.transport_count = 0;
1189 +-
1190 + nomem:
1191 + return 0;
1192 + }
1193 +@@ -2454,6 +2454,9 @@ static int sctp_process_param(struct sctp_association *asoc,
1194 + break;
1195 +
1196 + case SCTP_PARAM_SET_PRIMARY:
1197 ++ if (!sctp_addip_enable)
1198 ++ goto fall_through;
1199 ++
1200 + addr_param = param.v + sizeof(sctp_addip_param_t);
1201 +
1202 + af = sctp_get_af_specific(param_type2af(param.p->type));
1203
1204 Added: hardened/2.6/tags/2.6.25-14/1018_linux-2.6.25.19.patch
1205 ===================================================================
1206 --- hardened/2.6/tags/2.6.25-14/1018_linux-2.6.25.19.patch (rev 0)
1207 +++ hardened/2.6/tags/2.6.25-14/1018_linux-2.6.25.19.patch 2009-01-21 00:09:46 UTC (rev 1481)
1208 @@ -0,0 +1,461 @@
1209 +diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
1210 +index 5fed98c..2fb2dfe 100644
1211 +--- a/arch/x86/kernel/alternative.c
1212 ++++ b/arch/x86/kernel/alternative.c
1213 +@@ -457,7 +457,7 @@ void __init alternative_instructions(void)
1214 + _text, _etext);
1215 +
1216 + /* Only switch to UP mode if we don't immediately boot others */
1217 +- if (num_possible_cpus() == 1 || setup_max_cpus <= 1)
1218 ++ if (num_present_cpus() == 1 || setup_max_cpus <= 1)
1219 + alternatives_smp_switch(0);
1220 + }
1221 + #endif
1222 +diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
1223 +index f49c970..ca21808 100644
1224 +--- a/arch/x86/kernel/cpu/mtrr/generic.c
1225 ++++ b/arch/x86/kernel/cpu/mtrr/generic.c
1226 +@@ -251,7 +251,12 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
1227 + tmp |= ~((1<<(hi - 1)) - 1);
1228 +
1229 + if (tmp != mask_lo) {
1230 +- WARN_ON("mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
1231 ++ static int once = 1;
1232 ++
1233 ++ if (once) {
1234 ++ printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
1235 ++ once = 0;
1236 ++ }
1237 + mask_lo = tmp;
1238 + }
1239 + }
1240 +diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
1241 +index f239b30..0338d89 100644
1242 +--- a/arch/x86/kernel/io_apic_32.c
1243 ++++ b/arch/x86/kernel/io_apic_32.c
1244 +@@ -2305,6 +2305,9 @@ void __init setup_IO_APIC(void)
1245 + for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
1246 + set_bit(i, used_vectors);
1247 +
1248 ++ /* Mark FIRST_DEVICE_VECTOR which is assigned to IRQ0 as used. */
1249 ++ set_bit(FIRST_DEVICE_VECTOR, used_vectors);
1250 ++
1251 + enable_IO_APIC();
1252 +
1253 + if (acpi_ioapic)
1254 +diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
1255 +index f96b2e4..4f8b47e 100644
1256 +--- a/arch/x86/mm/ioremap.c
1257 ++++ b/arch/x86/mm/ioremap.c
1258 +@@ -438,7 +438,7 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size)
1259 + */
1260 + offset = phys_addr & ~PAGE_MASK;
1261 + phys_addr &= PAGE_MASK;
1262 +- size = PAGE_ALIGN(last_addr) - phys_addr;
1263 ++ size = PAGE_ALIGN(last_addr + 1) - phys_addr;
1264 +
1265 + /*
1266 + * Mappings have to fit in the FIX_BTMAP area.
1267 +diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
1268 +index a043bb1..ed2a83f 100644
1269 +--- a/drivers/char/drm/i915_dma.c
1270 ++++ b/drivers/char/drm/i915_dma.c
1271 +@@ -836,7 +836,7 @@ struct drm_ioctl_desc i915_ioctls[] = {
1272 + DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
1273 + DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1274 + DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1275 +- DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1276 ++ DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1277 + };
1278 +
1279 + int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1280 +diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
1281 +index 613ec81..31143e9 100644
1282 +--- a/drivers/char/tty_io.c
1283 ++++ b/drivers/char/tty_io.c
1284 +@@ -3373,7 +3373,7 @@ int tty_ioctl(struct inode *inode, struct file *file,
1285 + case TIOCSTI:
1286 + return tiocsti(tty, p);
1287 + case TIOCGWINSZ:
1288 +- return tiocgwinsz(tty, p);
1289 ++ return tiocgwinsz(real_tty, p);
1290 + case TIOCSWINSZ:
1291 + return tiocswinsz(tty, real_tty, p);
1292 + case TIOCCONS:
1293 +diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
1294 +index e12c132..48b9f28 100644
1295 +--- a/drivers/hwmon/it87.c
1296 ++++ b/drivers/hwmon/it87.c
1297 +@@ -46,6 +46,8 @@
1298 + #include <linux/err.h>
1299 + #include <linux/mutex.h>
1300 + #include <linux/sysfs.h>
1301 ++#include <linux/string.h>
1302 ++#include <linux/dmi.h>
1303 + #include <asm/io.h>
1304 +
1305 + #define DRVNAME "it87"
1306 +@@ -235,6 +237,8 @@ struct it87_sio_data {
1307 + enum chips type;
1308 + /* Values read from Super-I/O config space */
1309 + u8 vid_value;
1310 ++ /* Values set based on DMI strings */
1311 ++ u8 skip_pwm;
1312 + };
1313 +
1314 + /* For each registered chip, we need to keep some data in memory.
1315 +@@ -952,6 +956,7 @@ static int __init it87_find(unsigned short *address,
1316 + {
1317 + int err = -ENODEV;
1318 + u16 chip_type;
1319 ++ const char *board_vendor, *board_name;
1320 +
1321 + superio_enter();
1322 + chip_type = force_id ? force_id : superio_inw(DEVID);
1323 +@@ -1009,6 +1014,25 @@ static int __init it87_find(unsigned short *address,
1324 + pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
1325 + }
1326 +
1327 ++ sio_data->skip_pwm = 0;
1328 ++ /* Disable specific features based on DMI strings */
1329 ++ board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
1330 ++ board_name = dmi_get_system_info(DMI_BOARD_NAME);
1331 ++ if (board_vendor && board_name) {
1332 ++ if (strcmp(board_vendor, "nVIDIA") == 0
1333 ++ && strcmp(board_name, "FN68PT") == 0) {
1334 ++ /* On the Shuttle SN68PT, FAN_CTL2 is apparently not
1335 ++ connected to a fan, but to something else. One user
1336 ++ has reported instant system power-off when changing
1337 ++ the PWM2 duty cycle, so we disable it.
1338 ++ I use the board name string as the trigger in case
1339 ++ the same board is ever used in other systems. */
1340 ++ pr_info("it87: Disabling pwm2 due to "
1341 ++ "hardware constraints\n");
1342 ++ sio_data->skip_pwm = (1 << 1);
1343 ++ }
1344 ++ }
1345 ++
1346 + exit:
1347 + superio_exit();
1348 + return err;
1349 +@@ -1157,22 +1181,25 @@ static int __devinit it87_probe(struct platform_device *pdev)
1350 + if ((err = device_create_file(dev,
1351 + &sensor_dev_attr_pwm1_enable.dev_attr))
1352 + || (err = device_create_file(dev,
1353 +- &sensor_dev_attr_pwm2_enable.dev_attr))
1354 +- || (err = device_create_file(dev,
1355 + &sensor_dev_attr_pwm3_enable.dev_attr))
1356 + || (err = device_create_file(dev,
1357 + &sensor_dev_attr_pwm1.dev_attr))
1358 + || (err = device_create_file(dev,
1359 +- &sensor_dev_attr_pwm2.dev_attr))
1360 +- || (err = device_create_file(dev,
1361 + &sensor_dev_attr_pwm3.dev_attr))
1362 + || (err = device_create_file(dev,
1363 + &dev_attr_pwm1_freq))
1364 + || (err = device_create_file(dev,
1365 +- &dev_attr_pwm2_freq))
1366 +- || (err = device_create_file(dev,
1367 + &dev_attr_pwm3_freq)))
1368 + goto ERROR4;
1369 ++ if (!(sio_data->skip_pwm & (1 << 1))) {
1370 ++ if ((err = device_create_file(dev,
1371 ++ &sensor_dev_attr_pwm2_enable.dev_attr))
1372 ++ || (err = device_create_file(dev,
1373 ++ &sensor_dev_attr_pwm2.dev_attr))
1374 ++ || (err = device_create_file(dev,
1375 ++ &dev_attr_pwm2_freq)))
1376 ++ goto ERROR4;
1377 ++ }
1378 + }
1379 +
1380 + if (data->type == it8712 || data->type == it8716
1381 +diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
1382 +index 594522a..b1cca43 100644
1383 +--- a/drivers/media/video/bt8xx/bttv-driver.c
1384 ++++ b/drivers/media/video/bt8xx/bttv-driver.c
1385 +@@ -3422,7 +3422,7 @@ static int radio_open(struct inode *inode, struct file *file)
1386 + dprintk("bttv: open minor=%d\n",minor);
1387 +
1388 + for (i = 0; i < bttv_num; i++) {
1389 +- if (bttvs[i].radio_dev->minor == minor) {
1390 ++ if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
1391 + btv = &bttvs[i];
1392 + break;
1393 + }
1394 +diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
1395 +index 01ebcec..db55c5c 100644
1396 +--- a/drivers/media/video/tvaudio.c
1397 ++++ b/drivers/media/video/tvaudio.c
1398 +@@ -1804,7 +1804,7 @@ static int chip_command(struct i2c_client *client,
1399 + break;
1400 + case VIDIOC_S_FREQUENCY:
1401 + chip->mode = 0; /* automatic */
1402 +- if (desc->checkmode) {
1403 ++ if (desc->checkmode && desc->setmode) {
1404 + desc->setmode(chip,V4L2_TUNER_MODE_MONO);
1405 + if (chip->prevmode != V4L2_TUNER_MODE_MONO)
1406 + chip->prevmode = -1; /* reset previous mode */
1407 +diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
1408 +index fea4946..2e9a4e2 100644
1409 +--- a/drivers/media/video/zoran_driver.c
1410 ++++ b/drivers/media/video/zoran_driver.c
1411 +@@ -139,7 +139,7 @@ const struct zoran_format zoran_formats[] = {
1412 + }, {
1413 + .name = "16-bit RGB BE",
1414 + ZFMT(-1,
1415 +- V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
1416 ++ V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
1417 + .depth = 16,
1418 + .flags = ZORAN_FORMAT_CAPTURE |
1419 + ZORAN_FORMAT_OVERLAY,
1420 +diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
1421 +index d84408a..d7bd408 100644
1422 +--- a/drivers/net/wireless/b43legacy/xmit.c
1423 ++++ b/drivers/net/wireless/b43legacy/xmit.c
1424 +@@ -624,7 +624,7 @@ void b43legacy_handle_hwtxstatus(struct b43legacy_wldev *dev,
1425 + tmp = hw->count;
1426 + status.frame_count = (tmp >> 4);
1427 + status.rts_count = (tmp & 0x0F);
1428 +- tmp = hw->flags;
1429 ++ tmp = hw->flags << 1;
1430 + status.supp_reason = ((tmp & 0x1C) >> 2);
1431 + status.pm_indicated = !!(tmp & 0x80);
1432 + status.intermediate = !!(tmp & 0x40);
1433 +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
1434 +index 0222824..66fd680 100644
1435 +--- a/drivers/video/console/fbcon.c
1436 ++++ b/drivers/video/console/fbcon.c
1437 +@@ -2974,8 +2974,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
1438 + p = &fb_display[vc->vc_num];
1439 + set_blitting_type(vc, info);
1440 + var_to_display(p, &info->var, info);
1441 +- cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
1442 +- rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
1443 ++ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
1444 ++ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
1445 + cols /= vc->vc_font.width;
1446 + rows /= vc->vc_font.height;
1447 + vc_resize(vc, cols, rows);
1448 +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
1449 +index 69a2e19..9f341b8 100644
1450 +--- a/fs/cifs/cifsglob.h
1451 ++++ b/fs/cifs/cifsglob.h
1452 +@@ -315,6 +315,7 @@ struct cifs_search_info {
1453 + __u32 resume_key;
1454 + char *ntwrk_buf_start;
1455 + char *srch_entries_start;
1456 ++ char *last_entry;
1457 + char *presume_name;
1458 + unsigned int resume_name_len;
1459 + unsigned endOfSearch:1;
1460 +diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
1461 +index 30bbe44..6fe47f7 100644
1462 +--- a/fs/cifs/cifssmb.c
1463 ++++ b/fs/cifs/cifssmb.c
1464 +@@ -3598,6 +3598,8 @@ findFirstRetry:
1465 + le16_to_cpu(parms->SearchCount);
1466 + psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
1467 + psrch_inf->entries_in_buffer;
1468 ++ psrch_inf->last_entry = psrch_inf->srch_entries_start +
1469 ++ le16_to_cpu(parms->LastNameOffset);
1470 + *pnetfid = parms->SearchHandle;
1471 + } else {
1472 + cifs_buf_release(pSMB);
1473 +@@ -3712,6 +3714,8 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
1474 + le16_to_cpu(parms->SearchCount);
1475 + psrch_inf->index_of_last_entry +=
1476 + psrch_inf->entries_in_buffer;
1477 ++ psrch_inf->last_entry = psrch_inf->srch_entries_start +
1478 ++ le16_to_cpu(parms->LastNameOffset);
1479 + /* cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
1480 + psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */
1481 +
1482 +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
1483 +index 32b445e..2948aab 100644
1484 +--- a/fs/cifs/readdir.c
1485 ++++ b/fs/cifs/readdir.c
1486 +@@ -633,6 +633,70 @@ static int is_dir_changed(struct file *file)
1487 +
1488 + }
1489 +
1490 ++static int cifs_save_resume_key(const char *current_entry,
1491 ++ struct cifsFileInfo *cifsFile)
1492 ++{
1493 ++ int rc = 0;
1494 ++ unsigned int len = 0;
1495 ++ __u16 level;
1496 ++ char *filename;
1497 ++
1498 ++ if ((cifsFile == NULL) || (current_entry == NULL))
1499 ++ return -EINVAL;
1500 ++
1501 ++ level = cifsFile->srch_inf.info_level;
1502 ++
1503 ++ if (level == SMB_FIND_FILE_UNIX) {
1504 ++ FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
1505 ++
1506 ++ filename = &pFindData->FileName[0];
1507 ++ if (cifsFile->srch_inf.unicode) {
1508 ++ len = cifs_unicode_bytelen(filename);
1509 ++ } else {
1510 ++ /* BB should we make this strnlen of PATH_MAX? */
1511 ++ len = strnlen(filename, PATH_MAX);
1512 ++ }
1513 ++ cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1514 ++ } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
1515 ++ FILE_DIRECTORY_INFO *pFindData =
1516 ++ (FILE_DIRECTORY_INFO *)current_entry;
1517 ++ filename = &pFindData->FileName[0];
1518 ++ len = le32_to_cpu(pFindData->FileNameLength);
1519 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1520 ++ } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
1521 ++ FILE_FULL_DIRECTORY_INFO *pFindData =
1522 ++ (FILE_FULL_DIRECTORY_INFO *)current_entry;
1523 ++ filename = &pFindData->FileName[0];
1524 ++ len = le32_to_cpu(pFindData->FileNameLength);
1525 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1526 ++ } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
1527 ++ SEARCH_ID_FULL_DIR_INFO *pFindData =
1528 ++ (SEARCH_ID_FULL_DIR_INFO *)current_entry;
1529 ++ filename = &pFindData->FileName[0];
1530 ++ len = le32_to_cpu(pFindData->FileNameLength);
1531 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1532 ++ } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
1533 ++ FILE_BOTH_DIRECTORY_INFO *pFindData =
1534 ++ (FILE_BOTH_DIRECTORY_INFO *)current_entry;
1535 ++ filename = &pFindData->FileName[0];
1536 ++ len = le32_to_cpu(pFindData->FileNameLength);
1537 ++ cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1538 ++ } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
1539 ++ FIND_FILE_STANDARD_INFO *pFindData =
1540 ++ (FIND_FILE_STANDARD_INFO *)current_entry;
1541 ++ filename = &pFindData->FileName[0];
1542 ++ /* one byte length, no name conversion */
1543 ++ len = (unsigned int)pFindData->FileNameLength;
1544 ++ cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1545 ++ } else {
1546 ++ cFYI(1, ("Unknown findfirst level %d", level));
1547 ++ return -EINVAL;
1548 ++ }
1549 ++ cifsFile->srch_inf.resume_name_len = len;
1550 ++ cifsFile->srch_inf.presume_name = filename;
1551 ++ return rc;
1552 ++}
1553 ++
1554 + /* find the corresponding entry in the search */
1555 + /* Note that the SMB server returns search entries for . and .. which
1556 + complicates logic here if we choose to parse for them and we do not
1557 +@@ -694,6 +758,7 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
1558 + while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
1559 + (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)) {
1560 + cFYI(1, ("calling findnext2"));
1561 ++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);
1562 + rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,
1563 + &cifsFile->srch_inf);
1564 + if (rc)
1565 +@@ -910,69 +975,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
1566 + return rc;
1567 + }
1568 +
1569 +-static int cifs_save_resume_key(const char *current_entry,
1570 +- struct cifsFileInfo *cifsFile)
1571 +-{
1572 +- int rc = 0;
1573 +- unsigned int len = 0;
1574 +- __u16 level;
1575 +- char *filename;
1576 +-
1577 +- if ((cifsFile == NULL) || (current_entry == NULL))
1578 +- return -EINVAL;
1579 +-
1580 +- level = cifsFile->srch_inf.info_level;
1581 +-
1582 +- if (level == SMB_FIND_FILE_UNIX) {
1583 +- FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
1584 +-
1585 +- filename = &pFindData->FileName[0];
1586 +- if (cifsFile->srch_inf.unicode) {
1587 +- len = cifs_unicode_bytelen(filename);
1588 +- } else {
1589 +- /* BB should we make this strnlen of PATH_MAX? */
1590 +- len = strnlen(filename, PATH_MAX);
1591 +- }
1592 +- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1593 +- } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
1594 +- FILE_DIRECTORY_INFO *pFindData =
1595 +- (FILE_DIRECTORY_INFO *)current_entry;
1596 +- filename = &pFindData->FileName[0];
1597 +- len = le32_to_cpu(pFindData->FileNameLength);
1598 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1599 +- } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
1600 +- FILE_FULL_DIRECTORY_INFO *pFindData =
1601 +- (FILE_FULL_DIRECTORY_INFO *)current_entry;
1602 +- filename = &pFindData->FileName[0];
1603 +- len = le32_to_cpu(pFindData->FileNameLength);
1604 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1605 +- } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
1606 +- SEARCH_ID_FULL_DIR_INFO *pFindData =
1607 +- (SEARCH_ID_FULL_DIR_INFO *)current_entry;
1608 +- filename = &pFindData->FileName[0];
1609 +- len = le32_to_cpu(pFindData->FileNameLength);
1610 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1611 +- } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
1612 +- FILE_BOTH_DIRECTORY_INFO *pFindData =
1613 +- (FILE_BOTH_DIRECTORY_INFO *)current_entry;
1614 +- filename = &pFindData->FileName[0];
1615 +- len = le32_to_cpu(pFindData->FileNameLength);
1616 +- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
1617 +- } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
1618 +- FIND_FILE_STANDARD_INFO *pFindData =
1619 +- (FIND_FILE_STANDARD_INFO *)current_entry;
1620 +- filename = &pFindData->FileName[0];
1621 +- /* one byte length, no name conversion */
1622 +- len = (unsigned int)pFindData->FileNameLength;
1623 +- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
1624 +- } else {
1625 +- cFYI(1, ("Unknown findfirst level %d", level));
1626 +- return -EINVAL;
1627 +- }
1628 +- cifsFile->srch_inf.resume_name_len = len;
1629 +- cifsFile->srch_inf.presume_name = filename;
1630 +- return rc;
1631 +-}
1632 +
1633 + int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
1634 + {
1635 +diff --git a/fs/splice.c b/fs/splice.c
1636 +index eeb1a86..51d7c85 100644
1637 +--- a/fs/splice.c
1638 ++++ b/fs/splice.c
1639 +@@ -891,6 +891,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
1640 + if (unlikely(!(out->f_mode & FMODE_WRITE)))
1641 + return -EBADF;
1642 +
1643 ++ if (unlikely(out->f_flags & O_APPEND))
1644 ++ return -EINVAL;
1645 ++
1646 + ret = rw_verify_area(WRITE, out, ppos, len);
1647 + if (unlikely(ret < 0))
1648 + return ret;
1649 +diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
1650 +index 0a6d2e5..cdeaffe 100644
1651 +--- a/kernel/sched_rt.c
1652 ++++ b/kernel/sched_rt.c
1653 +@@ -91,12 +91,12 @@ static void dequeue_rt_entity(struct sched_rt_entity *rt_se);
1654 +
1655 + static void sched_rt_rq_enqueue(struct rt_rq *rt_rq)
1656 + {
1657 ++ struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
1658 + struct sched_rt_entity *rt_se = rt_rq->rt_se;
1659 +
1660 +- if (rt_se && !on_rt_rq(rt_se) && rt_rq->rt_nr_running) {
1661 +- struct task_struct *curr = rq_of_rt_rq(rt_rq)->curr;
1662 +-
1663 +- enqueue_rt_entity(rt_se);
1664 ++ if (rt_rq->rt_nr_running) {
1665 ++ if (rt_se && !on_rt_rq(rt_se))
1666 ++ enqueue_rt_entity(rt_se);
1667 + if (rt_rq->highest_prio < curr->prio)
1668 + resched_task(curr);
1669 + }
1670
1671 Added: hardened/2.6/tags/2.6.25-14/1019_linux-2.6.25.20.patch
1672 ===================================================================
1673 --- hardened/2.6/tags/2.6.25-14/1019_linux-2.6.25.20.patch (rev 0)
1674 +++ hardened/2.6/tags/2.6.25-14/1019_linux-2.6.25.20.patch 2009-01-21 00:09:46 UTC (rev 1481)
1675 @@ -0,0 +1,796 @@
1676 +diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
1677 +index 56ff552..d9f3f51 100644
1678 +--- a/arch/sparc64/kernel/trampoline.S
1679 ++++ b/arch/sparc64/kernel/trampoline.S
1680 +@@ -328,6 +328,12 @@ after_lock_tlb:
1681 +
1682 + wrpr %g0, 0, %wstate
1683 +
1684 ++ sethi %hi(prom_entry_lock), %g2
1685 ++1: ldstub [%g2 + %lo(prom_entry_lock)], %g1
1686 ++ membar #StoreLoad | #StoreStore
1687 ++ brnz,pn %g1, 1b
1688 ++ nop
1689 ++
1690 + /* As a hack, put &init_thread_union into %g6.
1691 + * prom_world() loads from here to restore the %asi
1692 + * register.
1693 +@@ -337,7 +343,7 @@ after_lock_tlb:
1694 +
1695 + sethi %hi(is_sun4v), %o0
1696 + lduw [%o0 + %lo(is_sun4v)], %o0
1697 +- brz,pt %o0, 1f
1698 ++ brz,pt %o0, 2f
1699 + nop
1700 +
1701 + TRAP_LOAD_TRAP_BLOCK(%g2, %g3)
1702 +@@ -369,10 +375,10 @@ after_lock_tlb:
1703 + call %o1
1704 + add %sp, (2047 + 128), %o0
1705 +
1706 +- ba,pt %xcc, 2f
1707 ++ ba,pt %xcc, 3f
1708 + nop
1709 +
1710 +-1: sethi %hi(sparc64_ttable_tl0), %o0
1711 ++2: sethi %hi(sparc64_ttable_tl0), %o0
1712 + set prom_set_trap_table_name, %g2
1713 + stx %g2, [%sp + 2047 + 128 + 0x00]
1714 + mov 1, %g2
1715 +@@ -386,7 +392,11 @@ after_lock_tlb:
1716 + call %o1
1717 + add %sp, (2047 + 128), %o0
1718 +
1719 +-2: ldx [%l0], %g6
1720 ++3: sethi %hi(prom_entry_lock), %g2
1721 ++ stb %g0, [%g2 + %lo(prom_entry_lock)]
1722 ++ membar #StoreStore | #StoreLoad
1723 ++
1724 ++ ldx [%l0], %g6
1725 + ldx [%g6 + TI_TASK], %g4
1726 +
1727 + mov 1, %g5
1728 +diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
1729 +index fa44fb9..4fdd886 100644
1730 +--- a/drivers/acpi/dock.c
1731 ++++ b/drivers/acpi/dock.c
1732 +@@ -599,14 +599,17 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
1733 + static void dock_notify(acpi_handle handle, u32 event, void *data)
1734 + {
1735 + struct dock_station *ds = data;
1736 ++ struct acpi_device *tmp;
1737 +
1738 + switch (event) {
1739 + case ACPI_NOTIFY_BUS_CHECK:
1740 +- if (!dock_in_progress(ds) && dock_present(ds)) {
1741 ++ if (!dock_in_progress(ds) && acpi_bus_get_device(ds->handle,
1742 ++ &tmp)) {
1743 + begin_dock(ds);
1744 + dock(ds);
1745 + if (!dock_present(ds)) {
1746 + printk(KERN_ERR PREFIX "Unable to dock!\n");
1747 ++ complete_dock(ds);
1748 + break;
1749 + }
1750 + atomic_notifier_call_chain(&dock_notifier_list,
1751 +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
1752 +index 980a741..4f65f59 100644
1753 +--- a/drivers/acpi/video.c
1754 ++++ b/drivers/acpi/video.c
1755 +@@ -624,6 +624,76 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
1756 + * device : video output device (LCD, CRT, ..)
1757 + *
1758 + * Return Value:
1759 ++ * Maximum brightness level
1760 ++ *
1761 ++ * Allocate and initialize device->brightness.
1762 ++ */
1763 ++
1764 ++static int
1765 ++acpi_video_init_brightness(struct acpi_video_device *device)
1766 ++{
1767 ++ union acpi_object *obj = NULL;
1768 ++ int i, max_level = 0, count = 0;
1769 ++ union acpi_object *o;
1770 ++ struct acpi_video_device_brightness *br = NULL;
1771 ++
1772 ++ if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
1773 ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
1774 ++ "LCD brightness level\n"));
1775 ++ goto out;
1776 ++ }
1777 ++
1778 ++ if (obj->package.count < 2)
1779 ++ goto out;
1780 ++
1781 ++ br = kzalloc(sizeof(*br), GFP_KERNEL);
1782 ++ if (!br) {
1783 ++ printk(KERN_ERR "can't allocate memory\n");
1784 ++ goto out;
1785 ++ }
1786 ++
1787 ++ br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
1788 ++ GFP_KERNEL);
1789 ++ if (!br->levels)
1790 ++ goto out_free;
1791 ++
1792 ++ for (i = 0; i < obj->package.count; i++) {
1793 ++ o = (union acpi_object *)&obj->package.elements[i];
1794 ++ if (o->type != ACPI_TYPE_INTEGER) {
1795 ++ printk(KERN_ERR PREFIX "Invalid data\n");
1796 ++ continue;
1797 ++ }
1798 ++ br->levels[count] = (u32) o->integer.value;
1799 ++
1800 ++ if (br->levels[count] > max_level)
1801 ++ max_level = br->levels[count];
1802 ++ count++;
1803 ++ }
1804 ++
1805 ++ if (count < 2)
1806 ++ goto out_free_levels;
1807 ++
1808 ++ br->count = count;
1809 ++ device->brightness = br;
1810 ++ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
1811 ++ kfree(obj);
1812 ++ return max_level;
1813 ++
1814 ++out_free_levels:
1815 ++ kfree(br->levels);
1816 ++out_free:
1817 ++ kfree(br);
1818 ++out:
1819 ++ device->brightness = NULL;
1820 ++ kfree(obj);
1821 ++ return 0;
1822 ++}
1823 ++
1824 ++/*
1825 ++ * Arg:
1826 ++ * device : video output device (LCD, CRT, ..)
1827 ++ *
1828 ++ * Return Value:
1829 + * None
1830 + *
1831 + * Find out all required AML methods defined under the output
1832 +@@ -633,10 +703,7 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag)
1833 + static void acpi_video_device_find_cap(struct acpi_video_device *device)
1834 + {
1835 + acpi_handle h_dummy1;
1836 +- int i;
1837 + u32 max_level = 0;
1838 +- union acpi_object *obj = NULL;
1839 +- struct acpi_video_device_brightness *br = NULL;
1840 +
1841 +
1842 + memset(&device->cap, 0, sizeof(device->cap));
1843 +@@ -665,53 +732,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
1844 + device->cap._DSS = 1;
1845 + }
1846 +
1847 +- if (ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
1848 +-
1849 +- if (obj->package.count >= 2) {
1850 +- int count = 0;
1851 +- union acpi_object *o;
1852 +-
1853 +- br = kzalloc(sizeof(*br), GFP_KERNEL);
1854 +- if (!br) {
1855 +- printk(KERN_ERR "can't allocate memory\n");
1856 +- } else {
1857 +- br->levels = kmalloc(obj->package.count *
1858 +- sizeof *(br->levels), GFP_KERNEL);
1859 +- if (!br->levels)
1860 +- goto out;
1861 +-
1862 +- for (i = 0; i < obj->package.count; i++) {
1863 +- o = (union acpi_object *)&obj->package.
1864 +- elements[i];
1865 +- if (o->type != ACPI_TYPE_INTEGER) {
1866 +- printk(KERN_ERR PREFIX "Invalid data\n");
1867 +- continue;
1868 +- }
1869 +- br->levels[count] = (u32) o->integer.value;
1870 +-
1871 +- if (br->levels[count] > max_level)
1872 +- max_level = br->levels[count];
1873 +- count++;
1874 +- }
1875 +- out:
1876 +- if (count < 2) {
1877 +- kfree(br->levels);
1878 +- kfree(br);
1879 +- } else {
1880 +- br->count = count;
1881 +- device->brightness = br;
1882 +- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1883 +- "found %d brightness levels\n",
1884 +- count));
1885 +- }
1886 +- }
1887 +- }
1888 +-
1889 +- } else {
1890 +- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available LCD brightness level\n"));
1891 +- }
1892 +-
1893 +- kfree(obj);
1894 ++ max_level = acpi_video_init_brightness(device);
1895 +
1896 + if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
1897 + int result;
1898 +@@ -1710,6 +1731,8 @@ static void
1899 + acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1900 + {
1901 + unsigned long level_current, level_next;
1902 ++ if (!device->brightness)
1903 ++ return;
1904 + acpi_video_device_lcd_get_level_current(device, &level_current);
1905 + level_next = acpi_video_get_next_level(device, level_current, event);
1906 + acpi_video_device_lcd_set_level(device, level_next);
1907 +diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
1908 +index b54112f..00b8539 100644
1909 +--- a/drivers/edac/cell_edac.c
1910 ++++ b/drivers/edac/cell_edac.c
1911 +@@ -141,7 +141,7 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
1912 + csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT;
1913 + csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
1914 + csrow->mtype = MEM_XDR;
1915 +- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
1916 ++ csrow->edac_mode = EDAC_SECDED;
1917 + dev_dbg(mci->dev,
1918 + "Initialized on node %d, chanmask=0x%x,"
1919 + " first_page=0x%lx, nr_pages=0x%x\n",
1920 +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
1921 +index d8db2f8..5ca1916 100644
1922 +--- a/drivers/gpio/gpiolib.c
1923 ++++ b/drivers/gpio/gpiolib.c
1924 +@@ -426,7 +426,7 @@ int gpio_get_value_cansleep(unsigned gpio)
1925 +
1926 + might_sleep_if(extra_checks);
1927 + chip = gpio_to_chip(gpio);
1928 +- return chip->get(chip, gpio - chip->base);
1929 ++ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
1930 + }
1931 + EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
1932 +
1933 +diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
1934 +index 69f94c9..9335d71 100644
1935 +--- a/drivers/net/wireless/libertas/scan.c
1936 ++++ b/drivers/net/wireless/libertas/scan.c
1937 +@@ -787,8 +787,8 @@ static int lbs_process_bss(struct bss_descriptor *bss,
1938 +
1939 + switch (elem->id) {
1940 + case MFIE_TYPE_SSID:
1941 +- bss->ssid_len = elem->len;
1942 +- memcpy(bss->ssid, elem->data, elem->len);
1943 ++ bss->ssid_len = min_t(int, 32, elem->len);
1944 ++ memcpy(bss->ssid, elem->data, bss->ssid_len);
1945 + lbs_deb_scan("got SSID IE: '%s', len %u\n",
1946 + escape_essid(bss->ssid, bss->ssid_len),
1947 + bss->ssid_len);
1948 +diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
1949 +index 8dededd..bd54e81 100644
1950 +--- a/fs/ext2/dir.c
1951 ++++ b/fs/ext2/dir.c
1952 +@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
1953 + return err;
1954 + }
1955 +
1956 +-static void ext2_check_page(struct page *page)
1957 ++static void ext2_check_page(struct page *page, int quiet)
1958 + {
1959 + struct inode *dir = page->mapping->host;
1960 + struct super_block *sb = dir->i_sb;
1961 +@@ -146,10 +146,10 @@ out:
1962 + /* Too bad, we had an error */
1963 +
1964 + Ebadsize:
1965 +- ext2_error(sb, "ext2_check_page",
1966 +- "size of directory #%lu is not a multiple of chunk size",
1967 +- dir->i_ino
1968 +- );
1969 ++ if (!quiet)
1970 ++ ext2_error(sb, __func__,
1971 ++ "size of directory #%lu is not a multiple "
1972 ++ "of chunk size", dir->i_ino);
1973 + goto fail;
1974 + Eshort:
1975 + error = "rec_len is smaller than minimal";
1976 +@@ -166,32 +166,36 @@ Espan:
1977 + Einumber:
1978 + error = "inode out of bounds";
1979 + bad_entry:
1980 +- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
1981 +- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
1982 +- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
1983 +- (unsigned long) le32_to_cpu(p->inode),
1984 +- rec_len, p->name_len);
1985 ++ if (!quiet)
1986 ++ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
1987 ++ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
1988 ++ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
1989 ++ (unsigned long) le32_to_cpu(p->inode),
1990 ++ rec_len, p->name_len);
1991 + goto fail;
1992 + Eend:
1993 +- p = (ext2_dirent *)(kaddr + offs);
1994 +- ext2_error (sb, "ext2_check_page",
1995 +- "entry in directory #%lu spans the page boundary"
1996 +- "offset=%lu, inode=%lu",
1997 +- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
1998 +- (unsigned long) le32_to_cpu(p->inode));
1999 ++ if (!quiet) {
2000 ++ p = (ext2_dirent *)(kaddr + offs);
2001 ++ ext2_error(sb, "ext2_check_page",
2002 ++ "entry in directory #%lu spans the page boundary"
2003 ++ "offset=%lu, inode=%lu",
2004 ++ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
2005 ++ (unsigned long) le32_to_cpu(p->inode));
2006 ++ }
2007 + fail:
2008 + SetPageChecked(page);
2009 + SetPageError(page);
2010 + }
2011 +
2012 +-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
2013 ++static struct page * ext2_get_page(struct inode *dir, unsigned long n,
2014 ++ int quiet)
2015 + {
2016 + struct address_space *mapping = dir->i_mapping;
2017 + struct page *page = read_mapping_page(mapping, n, NULL);
2018 + if (!IS_ERR(page)) {
2019 + kmap(page);
2020 + if (!PageChecked(page))
2021 +- ext2_check_page(page);
2022 ++ ext2_check_page(page, quiet);
2023 + if (PageError(page))
2024 + goto fail;
2025 + }
2026 +@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
2027 + for ( ; n < npages; n++, offset = 0) {
2028 + char *kaddr, *limit;
2029 + ext2_dirent *de;
2030 +- struct page *page = ext2_get_page(inode, n);
2031 ++ struct page *page = ext2_get_page(inode, n, 0);
2032 +
2033 + if (IS_ERR(page)) {
2034 + ext2_error(sb, __FUNCTION__,
2035 +@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
2036 + struct page *page = NULL;
2037 + struct ext2_inode_info *ei = EXT2_I(dir);
2038 + ext2_dirent * de;
2039 ++ int dir_has_error = 0;
2040 +
2041 + if (npages == 0)
2042 + goto out;
2043 +@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
2044 + n = start;
2045 + do {
2046 + char *kaddr;
2047 +- page = ext2_get_page(dir, n);
2048 ++ page = ext2_get_page(dir, n, dir_has_error);
2049 + if (!IS_ERR(page)) {
2050 + kaddr = page_address(page);
2051 + de = (ext2_dirent *) kaddr;
2052 +@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
2053 + de = ext2_next_entry(de);
2054 + }
2055 + ext2_put_page(page);
2056 +- }
2057 ++ } else
2058 ++ dir_has_error = 1;
2059 ++
2060 + if (++n >= npages)
2061 + n = 0;
2062 + /* next page is past the blocks we've got */
2063 +@@ -414,7 +421,7 @@ found:
2064 +
2065 + struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
2066 + {
2067 +- struct page *page = ext2_get_page(dir, 0);
2068 ++ struct page *page = ext2_get_page(dir, 0, 0);
2069 + ext2_dirent *de = NULL;
2070 +
2071 + if (!IS_ERR(page)) {
2072 +@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
2073 + for (n = 0; n <= npages; n++) {
2074 + char *dir_end;
2075 +
2076 +- page = ext2_get_page(dir, n);
2077 ++ page = ext2_get_page(dir, n, 0);
2078 + err = PTR_ERR(page);
2079 + if (IS_ERR(page))
2080 + goto out;
2081 +@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode)
2082 + {
2083 + struct page *page = NULL;
2084 + unsigned long i, npages = dir_pages(inode);
2085 ++ int dir_has_error = 0;
2086 +
2087 + for (i = 0; i < npages; i++) {
2088 + char *kaddr;
2089 + ext2_dirent * de;
2090 +- page = ext2_get_page(inode, i);
2091 ++ page = ext2_get_page(inode, i, dir_has_error);
2092 +
2093 +- if (IS_ERR(page))
2094 ++ if (IS_ERR(page)) {
2095 ++ dir_has_error = 1;
2096 + continue;
2097 ++ }
2098 +
2099 + kaddr = page_address(page);
2100 + de = (ext2_dirent *)kaddr;
2101 +diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
2102 +index 8ca3bfd..fba60c0 100644
2103 +--- a/fs/ext3/dir.c
2104 ++++ b/fs/ext3/dir.c
2105 +@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
2106 + int err;
2107 + struct inode *inode = filp->f_path.dentry->d_inode;
2108 + int ret = 0;
2109 ++ int dir_has_error = 0;
2110 +
2111 + sb = inode->i_sb;
2112 +
2113 +@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
2114 + * of recovering data when there's a bad sector
2115 + */
2116 + if (!bh) {
2117 +- ext3_error (sb, "ext3_readdir",
2118 +- "directory #%lu contains a hole at offset %lu",
2119 +- inode->i_ino, (unsigned long)filp->f_pos);
2120 ++ if (!dir_has_error) {
2121 ++ ext3_error(sb, __func__, "directory #%lu "
2122 ++ "contains a hole at offset %lld",
2123 ++ inode->i_ino, filp->f_pos);
2124 ++ dir_has_error = 1;
2125 ++ }
2126 + /* corrupt size? Maybe no more blocks to read */
2127 + if (filp->f_pos > inode->i_blocks << 9)
2128 + break;
2129 +diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
2130 +index 2c23bad..50ea8ed 100644
2131 +--- a/fs/ext4/dir.c
2132 ++++ b/fs/ext4/dir.c
2133 +@@ -102,6 +102,7 @@ static int ext4_readdir(struct file * filp,
2134 + int err;
2135 + struct inode *inode = filp->f_path.dentry->d_inode;
2136 + int ret = 0;
2137 ++ int dir_has_error = 0;
2138 +
2139 + sb = inode->i_sb;
2140 +
2141 +@@ -147,9 +148,13 @@ static int ext4_readdir(struct file * filp,
2142 + * of recovering data when there's a bad sector
2143 + */
2144 + if (!bh) {
2145 +- ext4_error (sb, "ext4_readdir",
2146 +- "directory #%lu contains a hole at offset %lu",
2147 +- inode->i_ino, (unsigned long)filp->f_pos);
2148 ++ if (!dir_has_error) {
2149 ++ ext4_error(sb, __func__, "directory #%lu "
2150 ++ "contains a hole at offset %Lu",
2151 ++ inode->i_ino,
2152 ++ (unsigned long long) filp->f_pos);
2153 ++ dir_has_error = 1;
2154 ++ }
2155 + /* corrupt size? Maybe no more blocks to read */
2156 + if (filp->f_pos > inode->i_blocks << 9)
2157 + break;
2158 +diff --git a/include/linux/sched.h b/include/linux/sched.h
2159 +index 6a1e7af..b9254bc 100644
2160 +--- a/include/linux/sched.h
2161 ++++ b/include/linux/sched.h
2162 +@@ -1256,6 +1256,8 @@ struct task_struct {
2163 + atomic_t fs_excl; /* holding fs exclusive resources */
2164 + struct rcu_head rcu;
2165 +
2166 ++ struct list_head *scm_work_list;
2167 ++
2168 + /*
2169 + * cache last used pipe for splice
2170 + */
2171 +diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h
2172 +index bb46e76..408f743 100644
2173 +--- a/include/math-emu/op-common.h
2174 ++++ b/include/math-emu/op-common.h
2175 +@@ -139,18 +139,27 @@ do { \
2176 + if (X##_e <= _FP_WFRACBITS_##fs) \
2177 + { \
2178 + _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
2179 +- _FP_ROUND(wc, X); \
2180 + if (_FP_FRAC_HIGH_##fs(X) \
2181 + & (_FP_OVERFLOW_##fs >> 1)) \
2182 + { \
2183 + X##_e = 1; \
2184 + _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
2185 +- FP_SET_EXCEPTION(FP_EX_INEXACT); \
2186 + } \
2187 + else \
2188 + { \
2189 +- X##_e = 0; \
2190 +- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
2191 ++ _FP_ROUND(wc, X); \
2192 ++ if (_FP_FRAC_HIGH_##fs(X) \
2193 ++ & (_FP_OVERFLOW_##fs >> 1)) \
2194 ++ { \
2195 ++ X##_e = 1; \
2196 ++ _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
2197 ++ FP_SET_EXCEPTION(FP_EX_INEXACT); \
2198 ++ } \
2199 ++ else \
2200 ++ { \
2201 ++ X##_e = 0; \
2202 ++ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
2203 ++ } \
2204 + } \
2205 + if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
2206 + (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
2207 +diff --git a/include/net/scm.h b/include/net/scm.h
2208 +index 06df126..33e9986 100644
2209 +--- a/include/net/scm.h
2210 ++++ b/include/net/scm.h
2211 +@@ -14,8 +14,9 @@
2212 +
2213 + struct scm_fp_list
2214 + {
2215 +- int count;
2216 +- struct file *fp[SCM_MAX_FD];
2217 ++ struct list_head list;
2218 ++ int count;
2219 ++ struct file *fp[SCM_MAX_FD];
2220 + };
2221 +
2222 + struct scm_cookie
2223 +diff --git a/net/core/dev.c b/net/core/dev.c
2224 +index 37ffd7a..bd08aa7 100644
2225 +--- a/net/core/dev.c
2226 ++++ b/net/core/dev.c
2227 +@@ -3593,14 +3593,11 @@ static int dev_new_index(struct net *net)
2228 + }
2229 +
2230 + /* Delayed registration/unregisteration */
2231 +-static DEFINE_SPINLOCK(net_todo_list_lock);
2232 + static LIST_HEAD(net_todo_list);
2233 +
2234 + static void net_set_todo(struct net_device *dev)
2235 + {
2236 +- spin_lock(&net_todo_list_lock);
2237 + list_add_tail(&dev->todo_list, &net_todo_list);
2238 +- spin_unlock(&net_todo_list_lock);
2239 + }
2240 +
2241 + static void rollback_registered(struct net_device *dev)
2242 +@@ -3909,33 +3906,24 @@ static void netdev_wait_allrefs(struct net_device *dev)
2243 + * free_netdev(y1);
2244 + * free_netdev(y2);
2245 + *
2246 +- * We are invoked by rtnl_unlock() after it drops the semaphore.
2247 ++ * We are invoked by rtnl_unlock().
2248 + * This allows us to deal with problems:
2249 + * 1) We can delete sysfs objects which invoke hotplug
2250 + * without deadlocking with linkwatch via keventd.
2251 + * 2) Since we run with the RTNL semaphore not held, we can sleep
2252 + * safely in order to wait for the netdev refcnt to drop to zero.
2253 ++ *
2254 ++ * We must not return until all unregister events added during
2255 ++ * the interval the lock was held have been completed.
2256 + */
2257 +-static DEFINE_MUTEX(net_todo_run_mutex);
2258 + void netdev_run_todo(void)
2259 + {
2260 + struct list_head list;
2261 +
2262 +- /* Need to guard against multiple cpu's getting out of order. */
2263 +- mutex_lock(&net_todo_run_mutex);
2264 +-
2265 +- /* Not safe to do outside the semaphore. We must not return
2266 +- * until all unregister events invoked by the local processor
2267 +- * have been completed (either by this todo run, or one on
2268 +- * another cpu).
2269 +- */
2270 +- if (list_empty(&net_todo_list))
2271 +- goto out;
2272 +-
2273 + /* Snapshot list, allow later requests */
2274 +- spin_lock(&net_todo_list_lock);
2275 + list_replace_init(&net_todo_list, &list);
2276 +- spin_unlock(&net_todo_list_lock);
2277 ++
2278 ++ __rtnl_unlock();
2279 +
2280 + while (!list_empty(&list)) {
2281 + struct net_device *dev
2282 +@@ -3965,9 +3953,6 @@ void netdev_run_todo(void)
2283 + /* Free network device */
2284 + kobject_put(&dev->dev.kobj);
2285 + }
2286 +-
2287 +-out:
2288 +- mutex_unlock(&net_todo_run_mutex);
2289 + }
2290 +
2291 + static struct net_device_stats *internal_stats(struct net_device *dev)
2292 +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
2293 +index 0cb2772..aa53778 100644
2294 +--- a/net/core/rtnetlink.c
2295 ++++ b/net/core/rtnetlink.c
2296 +@@ -73,7 +73,7 @@ void __rtnl_unlock(void)
2297 +
2298 + void rtnl_unlock(void)
2299 + {
2300 +- mutex_unlock(&rtnl_mutex);
2301 ++ /* This fellow will unlock it for us. */
2302 + netdev_run_todo();
2303 + }
2304 +
2305 +diff --git a/net/core/scm.c b/net/core/scm.c
2306 +index 10f5c65..ab242cc 100644
2307 +--- a/net/core/scm.c
2308 ++++ b/net/core/scm.c
2309 +@@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
2310 + if (!fpl)
2311 + return -ENOMEM;
2312 + *fplp = fpl;
2313 ++ INIT_LIST_HEAD(&fpl->list);
2314 + fpl->count = 0;
2315 + }
2316 + fpp = &fpl->fp[fpl->count];
2317 +@@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm)
2318 +
2319 + if (fpl) {
2320 + scm->fp = NULL;
2321 +- for (i=fpl->count-1; i>=0; i--)
2322 +- fput(fpl->fp[i]);
2323 +- kfree(fpl);
2324 ++ if (current->scm_work_list) {
2325 ++ list_add_tail(&fpl->list, current->scm_work_list);
2326 ++ } else {
2327 ++ LIST_HEAD(work_list);
2328 ++
2329 ++ current->scm_work_list = &work_list;
2330 ++
2331 ++ list_add(&fpl->list, &work_list);
2332 ++ while (!list_empty(&work_list)) {
2333 ++ fpl = list_first_entry(&work_list, struct scm_fp_list, list);
2334 ++
2335 ++ list_del(&fpl->list);
2336 ++ for (i=fpl->count-1; i>=0; i--)
2337 ++ fput(fpl->fp[i]);
2338 ++ kfree(fpl);
2339 ++ }
2340 ++
2341 ++ current->scm_work_list = NULL;
2342 ++ }
2343 + }
2344 + }
2345 +
2346 +@@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
2347 +
2348 + new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
2349 + if (new_fpl) {
2350 ++ INIT_LIST_HEAD(&new_fpl->list);
2351 + for (i=fpl->count-1; i>=0; i--)
2352 + get_file(fpl->fp[i]);
2353 + memcpy(new_fpl, fpl, sizeof(*fpl));
2354 +diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
2355 +index 50ad6ef..4618ea0 100644
2356 +--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
2357 ++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
2358 +@@ -138,10 +138,12 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
2359 + const struct net_device *out,
2360 + int (*okfn)(struct sk_buff *))
2361 + {
2362 ++#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
2363 + /* Previously seen (loopback)? Ignore. Do this before
2364 + fragment check. */
2365 + if (skb->nfct)
2366 + return NF_ACCEPT;
2367 ++#endif
2368 +
2369 + /* Gather fragments. */
2370 + if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
2371 +diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
2372 +index 8e4148d..1b0a738 100644
2373 +--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
2374 ++++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
2375 +@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
2376 + *obj = kmalloc(sizeof(struct snmp_object) + len,
2377 + GFP_ATOMIC);
2378 + if (*obj == NULL) {
2379 ++ kfree(p);
2380 + kfree(id);
2381 + if (net_ratelimit())
2382 + printk("OOM in bsalg (%d)\n", __LINE__);
2383 +diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
2384 +index 12750f2..4d18fd2 100644
2385 +--- a/net/ipv6/tcp_ipv6.c
2386 ++++ b/net/ipv6/tcp_ipv6.c
2387 +@@ -1130,7 +1130,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
2388 + *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
2389 + (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
2390 + *topt++ = htonl(tcp_time_stamp);
2391 +- *topt = htonl(ts);
2392 ++ *topt++ = htonl(ts);
2393 + }
2394 +
2395 + #ifdef CONFIG_TCP_MD5SIG
2396 +diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
2397 +index c63e933..4b5741b 100644
2398 +--- a/net/netfilter/xt_iprange.c
2399 ++++ b/net/netfilter/xt_iprange.c
2400 +@@ -67,7 +67,7 @@ iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
2401 + if (info->flags & IPRANGE_SRC) {
2402 + m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
2403 + m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
2404 +- m ^= info->flags & IPRANGE_SRC_INV;
2405 ++ m ^= !!(info->flags & IPRANGE_SRC_INV);
2406 + if (m) {
2407 + pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
2408 + NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
2409 +@@ -81,7 +81,7 @@ iprange_mt4(const struct sk_buff *skb, const struct net_device *in,
2410 + if (info->flags & IPRANGE_DST) {
2411 + m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
2412 + m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
2413 +- m ^= info->flags & IPRANGE_DST_INV;
2414 ++ m ^= !!(info->flags & IPRANGE_DST_INV);
2415 + if (m) {
2416 + pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
2417 + NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
2418 +@@ -123,14 +123,14 @@ iprange_mt6(const struct sk_buff *skb, const struct net_device *in,
2419 + if (info->flags & IPRANGE_SRC) {
2420 + m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
2421 + m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
2422 +- m ^= info->flags & IPRANGE_SRC_INV;
2423 ++ m ^= !!(info->flags & IPRANGE_SRC_INV);
2424 + if (m)
2425 + return false;
2426 + }
2427 + if (info->flags & IPRANGE_DST) {
2428 + m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
2429 + m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
2430 +- m ^= info->flags & IPRANGE_DST_INV;
2431 ++ m ^= !!(info->flags & IPRANGE_DST_INV);
2432 + if (m)
2433 + return false;
2434 + }
2435 +diff --git a/security/commoncap.c b/security/commoncap.c
2436 +index 06d5c94..37205a1 100644
2437 +--- a/security/commoncap.c
2438 ++++ b/security/commoncap.c
2439 +@@ -244,10 +244,10 @@ static int get_file_caps(struct linux_binprm *bprm)
2440 + struct vfs_cap_data vcaps;
2441 + struct inode *inode;
2442 +
2443 +- if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
2444 +- bprm_clear_caps(bprm);
2445 ++ bprm_clear_caps(bprm);
2446 ++
2447 ++ if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID)
2448 + return 0;
2449 +- }
2450 +
2451 + dentry = dget(bprm->file->f_dentry);
2452 + inode = dentry->d_inode;
2453 +diff --git a/sound/core/control.c b/sound/core/control.c
2454 +index 01a1a5a..7ac4bbb 100644
2455 +--- a/sound/core/control.c
2456 ++++ b/sound/core/control.c
2457 +@@ -1426,12 +1426,12 @@ static int snd_ctl_dev_disconnect(struct snd_device *device)
2458 + cardnum = card->number;
2459 + snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
2460 +
2461 +- down_read(&card->controls_rwsem);
2462 ++ read_lock(&card->ctl_files_rwlock);
2463 + list_for_each_entry(ctl, &card->ctl_files, list) {
2464 + wake_up(&ctl->change_sleep);
2465 + kill_fasync(&ctl->fasync, SIGIO, POLL_ERR);
2466 + }
2467 +- up_read(&card->controls_rwsem);
2468 ++ read_unlock(&card->ctl_files_rwlock);
2469 +
2470 + if ((err = snd_unregister_device(SNDRV_DEVICE_TYPE_CONTROL,
2471 + card, -1)) < 0)
2472
2473 Added: hardened/2.6/tags/2.6.25-14/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch
2474 ===================================================================
2475 --- hardened/2.6/tags/2.6.25-14/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch (rev 0)
2476 +++ hardened/2.6/tags/2.6.25-14/1401_cgroups-fix-invalid-cgrp-dentry-before-cgroup-has-been-completely-removed.patch 2009-01-21 00:09:46 UTC (rev 1481)
2477 @@ -0,0 +1,65 @@
2478 +Added-By: Gordon Malm <gengor@g.o>
2479 +
2480 +---
2481 +
2482 +From jejb@××××××.org Mon Nov 10 15:14:35 2008
2483 +From: Li Zefan <lizf@××××××××××.com>
2484 +Date: Fri, 7 Nov 2008 00:05:48 GMT
2485 +Subject: cgroups: fix invalid cgrp->dentry before cgroup has been completely removed
2486 +To: stable@××××××.org
2487 +Message-ID: <200811070005.mA705mbU003066@×××××××××××.org>
2488 +
2489 +From: Li Zefan <lizf@××××××××××.com>
2490 +
2491 +commit 24eb089950ce44603b30a3145a2c8520e2b55bb1 upstream
2492 +
2493 +This fixes an oops when reading /proc/sched_debug.
2494 +
2495 +A cgroup won't be removed completely until finishing cgroup_diput(), so we
2496 +shouldn't invalidate cgrp->dentry in cgroup_rmdir(). Otherwise, when a
2497 +group is being removed while cgroup_path() gets called, we may trigger
2498 +NULL dereference BUG.
2499 +
2500 +The bug can be reproduced:
2501 +
2502 + # cat test.sh
2503 + #!/bin/sh
2504 + mount -t cgroup -o cpu xxx /mnt
2505 + for (( ; ; ))
2506 + {
2507 + mkdir /mnt/sub
2508 + rmdir /mnt/sub
2509 + }
2510 + # ./test.sh &
2511 + # cat /proc/sched_debug
2512 +
2513 +BUG: unable to handle kernel NULL pointer dereference at 00000038
2514 +IP: [<c045a47f>] cgroup_path+0x39/0x90
2515 +..
2516 +Call Trace:
2517 + [<c0420344>] ? print_cfs_rq+0x6e/0x75d
2518 + [<c0421160>] ? sched_debug_show+0x72d/0xc1e
2519 +..
2520 +
2521 +Signed-off-by: Li Zefan <lizf@××××××××××.com>
2522 +Acked-by: Paul Menage <menage@××××××.com>
2523 +Cc: Peter Zijlstra <a.p.zijlstra@××××××.nl>
2524 +Cc: Ingo Molnar <mingo@××××.hu>
2525 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
2526 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2527 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2528 +
2529 +---
2530 + kernel/cgroup.c | 1 -
2531 + 1 file changed, 1 deletion(-)
2532 +
2533 +--- a/kernel/cgroup.c
2534 ++++ b/kernel/cgroup.c
2535 +@@ -2443,7 +2443,6 @@ static int cgroup_rmdir(struct inode *un
2536 + list_del(&cgrp->sibling);
2537 + spin_lock(&cgrp->dentry->d_lock);
2538 + d = dget(cgrp->dentry);
2539 +- cgrp->dentry = NULL;
2540 + spin_unlock(&d->d_lock);
2541 +
2542 + cgroup_d_remove_dir(d);
2543
2544 Added: hardened/2.6/tags/2.6.25-14/1402_cpqarry-fix-return-value-of-cpqarray_init.patch
2545 ===================================================================
2546 --- hardened/2.6/tags/2.6.25-14/1402_cpqarry-fix-return-value-of-cpqarray_init.patch (rev 0)
2547 +++ hardened/2.6/tags/2.6.25-14/1402_cpqarry-fix-return-value-of-cpqarray_init.patch 2009-01-21 00:09:46 UTC (rev 1481)
2548 @@ -0,0 +1,55 @@
2549 +Added-By: Gordon Malm <gengor@g.o>
2550 +
2551 +---
2552 +
2553 +From 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 Mon Sep 17 00:00:00 2001
2554 +From: Andrey Borzenkov <arvidjaar@××××.ru>
2555 +Date: Thu, 6 Nov 2008 12:53:15 -0800
2556 +Subject: cpqarry: fix return value of cpqarray_init()
2557 +
2558 +From: Andrey Borzenkov <arvidjaar@××××.ru>
2559 +
2560 +commit 2197d18ded232ef6eef63cce57b6b21eddf1b7b6 upstream.
2561 +
2562 +As reported by Dick Gevers on Compaq ProLiant:
2563 +
2564 +Oct 13 18:06:51 dvgcpl kernel: Compaq SMART2 Driver (v 2.6.0)
2565 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: 'cpqarray'->init
2566 +suspiciously returned 1, it should follow 0/-E convention
2567 +Oct 13 18:06:51 dvgcpl kernel: sys_init_module: loading module anyway...
2568 +Oct 13 18:06:51 dvgcpl kernel: Pid: 315, comm: modprobe Not tainted
2569 +2.6.27-desktop-0.rc8.2mnb #1
2570 +Oct 13 18:06:51 dvgcpl kernel: [<c0380612>] ? printk+0x18/0x1e
2571 +Oct 13 18:06:51 dvgcpl kernel: [<c0158f85>] sys_init_module+0x155/0x1c0
2572 +Oct 13 18:06:51 dvgcpl kernel: [<c0103f06>] syscall_call+0x7/0xb
2573 +Oct 13 18:06:51 dvgcpl kernel: =======================
2574 +
2575 +Make it return 0 on success and -ENODEV if no array was found.
2576 +
2577 +Reported-by: Dick Gevers <dvgevers@××××××.nl>
2578 +Signed-off-by: Andrey Borzenkov <arvidjaar@××××.ru>
2579 +Cc: Jens Axboe <jens.axboe@××××××.com>
2580 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
2581 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2582 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2583 +
2584 +---
2585 + drivers/block/cpqarray.c | 7 ++++++-
2586 + 1 file changed, 6 insertions(+), 1 deletion(-)
2587 +
2588 +--- a/drivers/block/cpqarray.c
2589 ++++ b/drivers/block/cpqarray.c
2590 +@@ -567,7 +567,12 @@ static int __init cpqarray_init(void)
2591 + num_cntlrs_reg++;
2592 + }
2593 +
2594 +- return(num_cntlrs_reg);
2595 ++ if (num_cntlrs_reg)
2596 ++ return 0;
2597 ++ else {
2598 ++ pci_unregister_driver(&cpqarray_pci_driver);
2599 ++ return -ENODEV;
2600 ++ }
2601 + }
2602 +
2603 + /* Function to find the first free pointer into our hba[] array */
2604
2605 Added: hardened/2.6/tags/2.6.25-14/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch
2606 ===================================================================
2607 --- hardened/2.6/tags/2.6.25-14/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch (rev 0)
2608 +++ hardened/2.6/tags/2.6.25-14/1403_ext3-wait-on-all-pending-commits-in-ext3_sync_fs.patch 2009-01-21 00:09:46 UTC (rev 1481)
2609 @@ -0,0 +1,82 @@
2610 +Added-By: Gordon Malm <gengor@g.o>
2611 +
2612 +---
2613 +
2614 +From jejb@××××××.org Mon Nov 10 15:08:55 2008
2615 +From: Arthur Jones <ajones@××××××××.com>
2616 +Date: Fri, 7 Nov 2008 00:05:17 GMT
2617 +Subject: ext3: wait on all pending commits in ext3_sync_fs
2618 +To: stable@××××××.org
2619 +Message-ID: <200811070005.mA705Htq002320@×××××××××××.org>
2620 +
2621 +From: Arthur Jones <ajones@××××××××.com>
2622 +
2623 +commit c87591b719737b4e91eb1a9fa8fd55a4ff1886d6 upstream
2624 +
2625 +In ext3_sync_fs, we only wait for a commit to finish if we started it, but
2626 +there may be one already in progress which will not be synced.
2627 +
2628 +In the case of a data=ordered umount with pending long symlinks which are
2629 +delayed due to a long list of other I/O on the backing block device, this
2630 +causes the buffer associated with the long symlinks to not be moved to the
2631 +inode dirty list in the second phase of fsync_super. Then, before they
2632 +can be dirtied again, kjournald exits, seeing the UMOUNT flag and the
2633 +dirty pages are never written to the backing block device, causing long
2634 +symlink corruption and exposing new or previously freed block data to
2635 +userspace.
2636 +
2637 +This can be reproduced with a script created
2638 +by Eric Sandeen <sandeen@××××××.com>:
2639 +
2640 + #!/bin/bash
2641 +
2642 + umount /mnt/test2
2643 + mount /dev/sdb4 /mnt/test2
2644 + rm -f /mnt/test2/*
2645 + dd if=/dev/zero of=/mnt/test2/bigfile bs=1M count=512
2646 + touch
2647 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
2648 + ln -s
2649 + /mnt/test2/thisisveryveryveryveryveryveryveryveryveryveryveryveryveryveryveryverylongfilename
2650 + /mnt/test2/link
2651 + umount /mnt/test2
2652 + mount /dev/sdb4 /mnt/test2
2653 + ls /mnt/test2/
2654 + umount /mnt/test2
2655 +
2656 +To ensure all commits are synced, we flush all journal commits now when
2657 +sync_fs'ing ext3.
2658 +
2659 +Signed-off-by: Arthur Jones <ajones@××××××××.com>
2660 +Cc: Eric Sandeen <sandeen@××××××.com>
2661 +Cc: Theodore Ts'o <tytso@×××.edu>
2662 +Cc: <linux-ext4@×××××××××××.org>
2663 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
2664 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
2665 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2666 +
2667 +---
2668 + fs/ext3/super.c | 11 +++++------
2669 + 1 file changed, 5 insertions(+), 6 deletions(-)
2670 +
2671 +--- a/fs/ext3/super.c
2672 ++++ b/fs/ext3/super.c
2673 +@@ -2365,13 +2365,12 @@ static void ext3_write_super (struct sup
2674 +
2675 + static int ext3_sync_fs(struct super_block *sb, int wait)
2676 + {
2677 +- tid_t target;
2678 +-
2679 + sb->s_dirt = 0;
2680 +- if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
2681 +- if (wait)
2682 +- log_wait_commit(EXT3_SB(sb)->s_journal, target);
2683 +- }
2684 ++ if (wait)
2685 ++ ext3_force_commit(sb);
2686 ++ else
2687 ++ journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
2688 ++
2689 + return 0;
2690 + }
2691 +
2692
2693 Added: hardened/2.6/tags/2.6.25-14/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch
2694 ===================================================================
2695 --- hardened/2.6/tags/2.6.25-14/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch (rev 0)
2696 +++ hardened/2.6/tags/2.6.25-14/1404_hid-fix-incorrent-length-condition-in-hidraw_write.patch 2009-01-21 00:09:46 UTC (rev 1481)
2697 @@ -0,0 +1,48 @@
2698 +Added-By: Gordon Malm <gengor@g.o>
2699 +
2700 +---
2701 +
2702 +From jkosina@××××.cz Tue Nov 11 15:52:41 2008
2703 +From: Jiri Kosina <jkosina@××××.cz>
2704 +Date: Tue, 11 Nov 2008 23:45:38 +0100 (CET)
2705 +Subject: HID: fix incorrent length condition in hidraw_write()
2706 +To: stable@××××××.org
2707 +Cc: Paul Stoffregen <paul@××××.com>
2708 +Message-ID: <alpine.LNX.1.10.0811112344180.24889@××××××××××.cz>
2709 +
2710 +From: Jiri Kosina <jkosina@××××.cz>
2711 +
2712 +upstream commit 2b107d629dc0c35de606bb7b010b829cd247a93a
2713 +
2714 +From: Jiri Kosina <jkosina@××××.cz>
2715 +
2716 +The bound check on the buffer length
2717 +
2718 + if (count > HID_MIN_BUFFER_SIZE)
2719 +
2720 +is of course incorrent, the proper check is
2721 +
2722 + if (count > HID_MAX_BUFFER_SIZE)
2723 +
2724 +Fix it.
2725 +
2726 +Reported-by: Jerry Ryle <jerry@×××××××××.com>
2727 +Signed-off-by: Jiri Kosina <jkosina@××××.cz>
2728 +Cc: Paul Stoffregen <paul@××××.com>
2729 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2730 +
2731 +---
2732 + drivers/hid/hidraw.c | 2 +-
2733 + 1 file changed, 1 insertion(+), 1 deletion(-)
2734 +
2735 +--- a/drivers/hid/hidraw.c
2736 ++++ b/drivers/hid/hidraw.c
2737 +@@ -113,7 +113,7 @@ static ssize_t hidraw_write(struct file
2738 + if (!dev->hid_output_raw_report)
2739 + return -ENODEV;
2740 +
2741 +- if (count > HID_MIN_BUFFER_SIZE) {
2742 ++ if (count > HID_MAX_BUFFER_SIZE) {
2743 + printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
2744 + task_pid_nr(current));
2745 + return -EINVAL;
2746
2747 Added: hardened/2.6/tags/2.6.25-14/1405_i-oat-fix-async_tx.callback-checking.patch
2748 ===================================================================
2749 --- hardened/2.6/tags/2.6.25-14/1405_i-oat-fix-async_tx.callback-checking.patch (rev 0)
2750 +++ hardened/2.6/tags/2.6.25-14/1405_i-oat-fix-async_tx.callback-checking.patch 2009-01-21 00:09:46 UTC (rev 1481)
2751 @@ -0,0 +1,48 @@
2752 +Added-By: Gordon Malm <gengor@g.o>
2753 +
2754 +Note: Backported to earlier kernels. Original message included below.
2755 +
2756 +---
2757 +
2758 +From jejb@××××××.org Tue Nov 11 10:17:05 2008
2759 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2760 +Date: Tue, 11 Nov 2008 17:50:05 GMT
2761 +Subject: I/OAT: fix async_tx.callback checking
2762 +To: jejb@××××××.org, stable@××××××.org
2763 +Message-ID: <200811111750.mABHo5Ai025612@×××××××××××.org>
2764 +
2765 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2766 +
2767 +commit 12ccea24e309d815d058cdc6ee8bf2c4b85f0c5f upstream
2768 +
2769 +async_tx.callback should be checked for the first
2770 +not the last descriptor in the chain.
2771 +
2772 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2773 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2774 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2775 +
2776 +---
2777 + drivers/dma/ioat_dma.c | 4 ++--
2778 + 1 file changed, 2 insertions(+), 2 deletions(-)
2779 +
2780 +--- a/drivers/dma/ioat_dma.c
2781 ++++ b/drivers/dma/ioat_dma.c
2782 +@@ -251,7 +251,7 @@ static dma_cookie_t ioat1_tx_submit(stru
2783 + } while (len && (new = ioat1_dma_get_next_descriptor(ioat_chan)));
2784 +
2785 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
2786 +- if (new->async_tx.callback) {
2787 ++ if (first->async_tx.callback) {
2788 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
2789 + if (first != new) {
2790 + /* move callback into to last desc */
2791 +@@ -336,7 +336,7 @@ static dma_cookie_t ioat2_tx_submit(stru
2792 + } while (len && (new = ioat2_dma_get_next_descriptor(ioat_chan)));
2793 +
2794 + hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS;
2795 +- if (new->async_tx.callback) {
2796 ++ if (first->async_tx.callback) {
2797 + hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN;
2798 + if (first != new) {
2799 + /* move callback into to last desc */
2800
2801 Added: hardened/2.6/tags/2.6.25-14/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch
2802 ===================================================================
2803 --- hardened/2.6/tags/2.6.25-14/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch (rev 0)
2804 +++ hardened/2.6/tags/2.6.25-14/1406_i-oat-fix-channel-resources-free-for-not-allocated-channels.patch 2009-01-21 00:09:46 UTC (rev 1481)
2805 @@ -0,0 +1,54 @@
2806 +Added-By: Gordon Malm <gengor@g.o>
2807 +
2808 +Note: Backported to earlier kernels. Original message below.
2809 +
2810 +---
2811 +
2812 +From jejb@××××××.org Tue Nov 11 10:15:37 2008
2813 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2814 +Date: Tue, 11 Nov 2008 17:50:09 GMT
2815 +Subject: I/OAT: fix channel resources free for not allocated channels
2816 +To: stable@××××××.org
2817 +Message-ID: <200811111750.mABHo9IU025655@×××××××××××.org>
2818 +
2819 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2820 +
2821 +commit c3d4f44f50b65b0b0290e357f8739cfb3f4bcaca upstream
2822 +
2823 +If the ioatdma driver is loaded but not used it does not allocate descriptors.
2824 +Before it frees channel resources it should first be sure
2825 +that they have been previously allocated.
2826 +
2827 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2828 +Tested-by: Tom Picard <tom.s.picard@×××××.com>
2829 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
2830 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2831 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2832 +
2833 +---
2834 + drivers/dma/ioat_dma.c | 7 +++++++
2835 + 1 file changed, 7 insertions(+)
2836 +
2837 +--- a/drivers/dma/ioat_dma.c
2838 ++++ b/drivers/dma/ioat_dma.c
2839 +@@ -524,6 +524,12 @@ static void ioat_dma_free_chan_resources
2840 + struct ioat_desc_sw *desc, *_desc;
2841 + int in_use_descs = 0;
2842 +
2843 ++ /* Before freeing channel resources first check
2844 ++ * if they have been previously allocated for this channel.
2845 ++ */
2846 ++ if (ioat_chan->desccount == 0)
2847 ++ return;
2848 ++
2849 + tasklet_disable(&ioat_chan->cleanup_task);
2850 + ioat_dma_memcpy_cleanup(ioat_chan);
2851 +
2852 +@@ -585,6 +591,7 @@ static void ioat_dma_free_chan_resources
2853 + ioat_chan->last_completion = ioat_chan->completion_addr = 0;
2854 + ioat_chan->pending = 0;
2855 + ioat_chan->dmacount = 0;
2856 ++ ioat_chan->desccount = 0;
2857 + }
2858 +
2859 + /**
2860
2861 Added: hardened/2.6/tags/2.6.25-14/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch
2862 ===================================================================
2863 --- hardened/2.6/tags/2.6.25-14/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch (rev 0)
2864 +++ hardened/2.6/tags/2.6.25-14/1407_i-oat-fix-dma_pin_iovec_pages-error-handling.patch 2009-01-21 00:09:46 UTC (rev 1481)
2865 @@ -0,0 +1,89 @@
2866 +Added-By: Gordon Malm <gengor@g.o>
2867 +
2868 +---
2869 +
2870 +From jejb@××××××.org Tue Nov 11 10:16:31 2008
2871 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2872 +Date: Tue, 11 Nov 2008 17:50:07 GMT
2873 +Subject: I/OAT: fix dma_pin_iovec_pages() error handling
2874 +To: stable@××××××.org
2875 +Message-ID: <200811111750.mABHo7v5025633@×××××××××××.org>
2876 +
2877 +From: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2878 +
2879 +commit c2c0b4c5434c0a25f7f7796b29155d53805909f5 upstream
2880 +
2881 +Error handling needs to be modified in dma_pin_iovec_pages().
2882 +It should return NULL instead of ERR_PTR
2883 +(pinned_list is checked for NULL in tcp_recvmsg() to determine
2884 +if iovec pages have been successfully pinned down).
2885 +In case of error for the first iovec,
2886 +local_list->nr_iovecs needs to be initialized.
2887 +
2888 +Signed-off-by: Maciej Sosnowski <maciej.sosnowski@×××××.com>
2889 +Signed-off-by: David S. Miller <davem@×××××××××.net>
2890 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2891 +
2892 +---
2893 + drivers/dma/iovlock.c | 17 ++++++-----------
2894 + 1 file changed, 6 insertions(+), 11 deletions(-)
2895 +
2896 +--- a/drivers/dma/iovlock.c
2897 ++++ b/drivers/dma/iovlock.c
2898 +@@ -55,7 +55,6 @@ struct dma_pinned_list *dma_pin_iovec_pa
2899 + int nr_iovecs = 0;
2900 + int iovec_len_used = 0;
2901 + int iovec_pages_used = 0;
2902 +- long err;
2903 +
2904 + /* don't pin down non-user-based iovecs */
2905 + if (segment_eq(get_fs(), KERNEL_DS))
2906 +@@ -72,23 +71,21 @@ struct dma_pinned_list *dma_pin_iovec_pa
2907 + local_list = kmalloc(sizeof(*local_list)
2908 + + (nr_iovecs * sizeof (struct dma_page_list))
2909 + + (iovec_pages_used * sizeof (struct page*)), GFP_KERNEL);
2910 +- if (!local_list) {
2911 +- err = -ENOMEM;
2912 ++ if (!local_list)
2913 + goto out;
2914 +- }
2915 +
2916 + /* list of pages starts right after the page list array */
2917 + pages = (struct page **) &local_list->page_list[nr_iovecs];
2918 +
2919 ++ local_list->nr_iovecs = 0;
2920 ++
2921 + for (i = 0; i < nr_iovecs; i++) {
2922 + struct dma_page_list *page_list = &local_list->page_list[i];
2923 +
2924 + len -= iov[i].iov_len;
2925 +
2926 +- if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len)) {
2927 +- err = -EFAULT;
2928 ++ if (!access_ok(VERIFY_WRITE, iov[i].iov_base, iov[i].iov_len))
2929 + goto unpin;
2930 +- }
2931 +
2932 + page_list->nr_pages = num_pages_spanned(&iov[i]);
2933 + page_list->base_address = iov[i].iov_base;
2934 +@@ -109,10 +106,8 @@ struct dma_pinned_list *dma_pin_iovec_pa
2935 + NULL);
2936 + up_read(&current->mm->mmap_sem);
2937 +
2938 +- if (ret != page_list->nr_pages) {
2939 +- err = -ENOMEM;
2940 ++ if (ret != page_list->nr_pages)
2941 + goto unpin;
2942 +- }
2943 +
2944 + local_list->nr_iovecs = i + 1;
2945 + }
2946 +@@ -122,7 +117,7 @@ struct dma_pinned_list *dma_pin_iovec_pa
2947 + unpin:
2948 + dma_unpin_iovec_pages(local_list);
2949 + out:
2950 +- return ERR_PTR(err);
2951 ++ return NULL;
2952 + }
2953 +
2954 + void dma_unpin_iovec_pages(struct dma_pinned_list *pinned_list)
2955
2956 Added: hardened/2.6/tags/2.6.25-14/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch
2957 ===================================================================
2958 --- hardened/2.6/tags/2.6.25-14/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch (rev 0)
2959 +++ hardened/2.6/tags/2.6.25-14/1408_jffs2-fix-lack-of-locking-in-thread_should_wake.patch 2009-01-21 00:09:46 UTC (rev 1481)
2960 @@ -0,0 +1,51 @@
2961 +Added-By: Gordon Malm <gengor@g.o>
2962 +
2963 +---
2964 +
2965 +From jejb@××××××.org Tue Nov 11 09:53:44 2008
2966 +From: David Woodhouse <David.Woodhouse@×××××.com>
2967 +Date: Fri, 7 Nov 2008 00:08:59 GMT
2968 +Subject: JFFS2: Fix lack of locking in thread_should_wake()
2969 +To: stable@××××××.org
2970 +Message-ID: <200811070008.mA708xQE008191@×××××××××××.org>
2971 +
2972 +From: David Woodhouse <David.Woodhouse@×××××.com>
2973 +
2974 +commit b27cf88e9592953ae292d05324887f2f44979433 upstream
2975 +
2976 +The thread_should_wake() function trawls through the list of 'very
2977 +dirty' eraseblocks, determining whether the background GC thread should
2978 +wake. Doing this without holding the appropriate locks is a bad idea.
2979 +
2980 +OLPC Trac #8615
2981 +
2982 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
2983 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
2984 +
2985 +---
2986 + fs/jffs2/background.c | 10 +++++-----
2987 + 1 file changed, 5 insertions(+), 5 deletions(-)
2988 +
2989 +--- a/fs/jffs2/background.c
2990 ++++ b/fs/jffs2/background.c
2991 +@@ -85,15 +85,15 @@ static int jffs2_garbage_collect_thread(
2992 + for (;;) {
2993 + allow_signal(SIGHUP);
2994 + again:
2995 ++ spin_lock(&c->erase_completion_lock);
2996 + if (!jffs2_thread_should_wake(c)) {
2997 + set_current_state (TASK_INTERRUPTIBLE);
2998 ++ spin_unlock(&c->erase_completion_lock);
2999 + D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
3000 +- /* Yes, there's a race here; we checked jffs2_thread_should_wake()
3001 +- before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
3002 +- matter - We don't care if we miss a wakeup, because the GC thread
3003 +- is only an optimisation anyway. */
3004 + schedule();
3005 +- }
3006 ++ } else
3007 ++ spin_unlock(&c->erase_completion_lock);
3008 ++
3009 +
3010 + /* This thread is purely an optimisation. But if it runs when
3011 + other things could be running, it actually makes things a
3012
3013 Added: hardened/2.6/tags/2.6.25-14/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch
3014 ===================================================================
3015 --- hardened/2.6/tags/2.6.25-14/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch (rev 0)
3016 +++ hardened/2.6/tags/2.6.25-14/1409_jffs2-fix-race-condition-in-jffs2_lzo_compress.patch 2009-01-21 00:09:46 UTC (rev 1481)
3017 @@ -0,0 +1,70 @@
3018 +Added-By: Gordon Malm <gengor@g.o>
3019 +
3020 +---
3021 +
3022 +From jejb@××××××.org Tue Nov 11 09:53:08 2008
3023 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
3024 +Date: Fri, 7 Nov 2008 00:08:19 GMT
3025 +Subject: JFFS2: fix race condition in jffs2_lzo_compress()
3026 +To: stable@××××××.org
3027 +Message-ID: <200811070008.mA708Jdo007031@×××××××××××.org>
3028 +
3029 +From: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
3030 +
3031 +commit dc8a0843a435b2c0891e7eaea64faaf1ebec9b11 upstream
3032 +
3033 +deflate_mutex protects the globals lzo_mem and lzo_compress_buf. However,
3034 +jffs2_lzo_compress() unlocks deflate_mutex _before_ it has copied out the
3035 +compressed data from lzo_compress_buf. Correct this by moving the mutex
3036 +unlock after the copy.
3037 +
3038 +In addition, document what deflate_mutex actually protects.
3039 +
3040 +Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@×××××××.com>
3041 +Acked-by: Richard Purdie <rpurdie@××××××××××.com>
3042 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
3043 +Signed-off-by: David Woodhouse <David.Woodhouse@×××××.com>
3044 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3045 +
3046 +---
3047 + fs/jffs2/compr_lzo.c | 15 +++++++++------
3048 + 1 file changed, 9 insertions(+), 6 deletions(-)
3049 +
3050 +--- a/fs/jffs2/compr_lzo.c
3051 ++++ b/fs/jffs2/compr_lzo.c
3052 +@@ -19,7 +19,7 @@
3053 +
3054 + static void *lzo_mem;
3055 + static void *lzo_compress_buf;
3056 +-static DEFINE_MUTEX(deflate_mutex);
3057 ++static DEFINE_MUTEX(deflate_mutex); /* for lzo_mem and lzo_compress_buf */
3058 +
3059 + static void free_workspace(void)
3060 + {
3061 +@@ -49,18 +49,21 @@ static int jffs2_lzo_compress(unsigned c
3062 +
3063 + mutex_lock(&deflate_mutex);
3064 + ret = lzo1x_1_compress(data_in, *sourcelen, lzo_compress_buf, &compress_size, lzo_mem);
3065 +- mutex_unlock(&deflate_mutex);
3066 +-
3067 + if (ret != LZO_E_OK)
3068 +- return -1;
3069 ++ goto fail;
3070 +
3071 + if (compress_size > *dstlen)
3072 +- return -1;
3073 ++ goto fail;
3074 +
3075 + memcpy(cpage_out, lzo_compress_buf, compress_size);
3076 +- *dstlen = compress_size;
3077 ++ mutex_unlock(&deflate_mutex);
3078 +
3079 ++ *dstlen = compress_size;
3080 + return 0;
3081 ++
3082 ++ fail:
3083 ++ mutex_unlock(&deflate_mutex);
3084 ++ return -1;
3085 + }
3086 +
3087 + static int jffs2_lzo_decompress(unsigned char *data_in, unsigned char *cpage_out,
3088
3089 Added: hardened/2.6/tags/2.6.25-14/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch
3090 ===================================================================
3091 --- hardened/2.6/tags/2.6.25-14/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch (rev 0)
3092 +++ hardened/2.6/tags/2.6.25-14/1410_md-linear-fix-a-division-by-zero-bug-for-very-small-arrays.patch 2009-01-21 00:09:46 UTC (rev 1481)
3093 @@ -0,0 +1,51 @@
3094 +Added-By: Gordon Malm <gengor@g.o>
3095 +
3096 +Note: Changed patch slightly to eliminate fuzz.
3097 +
3098 +---
3099 +
3100 +From jejb@××××××.org Tue Nov 11 09:47:32 2008
3101 +From: Andre Noll <maan@×××××××××××.org>
3102 +Date: Fri, 7 Nov 2008 00:07:46 GMT
3103 +Subject: md: linear: Fix a division by zero bug for very small arrays.
3104 +To: stable@××××××.org
3105 +Message-ID: <200811070007.mA707k6d006270@×××××××××××.org>
3106 +
3107 +From: Andre Noll <maan@×××××××××××.org>
3108 +
3109 +commit f1cd14ae52985634d0389e934eba25b5ecf24565 upstream
3110 +
3111 +Date: Thu, 6 Nov 2008 19:41:24 +1100
3112 +Subject: md: linear: Fix a division by zero bug for very small arrays.
3113 +
3114 +We currently oops with a divide error on starting a linear software
3115 +raid array consisting of at least two very small (< 500K) devices.
3116 +
3117 +The bug is caused by the calculation of the hash table size which
3118 +tries to compute sector_div(sz, base) with "base" being zero due to
3119 +the small size of the component devices of the array.
3120 +
3121 +Fix this by requiring the hash spacing to be at least one which
3122 +implies that also "base" is non-zero.
3123 +
3124 +This bug has existed since about 2.6.14.
3125 +
3126 +Signed-off-by: Andre Noll <maan@×××××××××××.org>
3127 +Signed-off-by: NeilBrown <neilb@××××.de>
3128 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3129 +
3130 +---
3131 + drivers/md/linear.c | 2 ++
3132 + 1 file changed, 2 insertions(+)
3133 +
3134 +--- a/drivers/md/linear.c
3135 ++++ b/drivers/md/linear.c
3136 +@@ -157,6 +157,8 @@ static linear_conf_t *linear_conf(mddev_
3137 +
3138 + min_spacing = conf->array_size;
3139 + sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
3140 ++ if (min_spacing == 0)
3141 ++ min_spacing = 1;
3142 +
3143 + /* min_spacing is the minimum spacing that will fit the hash
3144 + * table in one PAGE. This may be much smaller than needed.
3145
3146 Added: hardened/2.6/tags/2.6.25-14/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch
3147 ===================================================================
3148 --- hardened/2.6/tags/2.6.25-14/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch (rev 0)
3149 +++ hardened/2.6/tags/2.6.25-14/1411_mmc-increase-sd-write-timeout-for-crappy-cards.patch 2009-01-21 00:09:46 UTC (rev 1481)
3150 @@ -0,0 +1,42 @@
3151 +Added-By: Gordon Malm <gengor@g.o>
3152 +
3153 +---
3154 +
3155 +From 493890e75d98810a3470b4aae23be628ee5e9667 Mon Sep 17 00:00:00 2001
3156 +From: Pierre Ossman <drzeus@××××××.cx>
3157 +Date: Sun, 26 Oct 2008 12:37:25 +0100
3158 +Subject: mmc: increase SD write timeout for crappy cards
3159 +
3160 +From: Pierre Ossman <drzeus@××××××.cx>
3161 +
3162 +commit 493890e75d98810a3470b4aae23be628ee5e9667 upstream.
3163 +
3164 +It seems that some cards are slightly out of spec and occasionally
3165 +will not be able to complete a write in the alloted 250 ms [1].
3166 +Incease the timeout slightly to allow even these cards to function
3167 +properly.
3168 +
3169 +[1] http://lkml.org/lkml/2008/9/23/390
3170 +
3171 +Signed-off-by: Pierre Ossman <drzeus@××××××.cx>
3172 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3173 +
3174 +---
3175 + drivers/mmc/core/core.c | 6 +++++-
3176 + 1 file changed, 5 insertions(+), 1 deletion(-)
3177 +
3178 +--- a/drivers/mmc/core/core.c
3179 ++++ b/drivers/mmc/core/core.c
3180 +@@ -280,7 +280,11 @@ void mmc_set_data_timeout(struct mmc_dat
3181 + (card->host->ios.clock / 1000);
3182 +
3183 + if (data->flags & MMC_DATA_WRITE)
3184 +- limit_us = 250000;
3185 ++ /*
3186 ++ * The limit is really 250 ms, but that is
3187 ++ * insufficient for some crappy cards.
3188 ++ */
3189 ++ limit_us = 300000;
3190 + else
3191 + limit_us = 100000;
3192 +
3193
3194 Added: hardened/2.6/tags/2.6.25-14/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch
3195 ===================================================================
3196 --- hardened/2.6/tags/2.6.25-14/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch (rev 0)
3197 +++ hardened/2.6/tags/2.6.25-14/1412_net-unix-fix-inflight-counting-bug-in-garbage-collector.patch 2009-01-21 00:09:46 UTC (rev 1481)
3198 @@ -0,0 +1,213 @@
3199 +Added-By: Gordon Malm <gengor@g.o>
3200 +
3201 +Note: Backported to ealier kernels. Original message included below.
3202 +
3203 +---
3204 +
3205 +From jejb@××××××.org Tue Nov 11 09:59:05 2008
3206 +From: Miklos Szeredi <mszeredi@××××.cz>
3207 +Date: Sun, 9 Nov 2008 19:50:02 GMT
3208 +Subject: net: unix: fix inflight counting bug in garbage collector
3209 +To: stable@××××××.org
3210 +Message-ID: <200811091950.mA9Jo2iL003804@×××××××××××.org>
3211 +
3212 +From: Miklos Szeredi <mszeredi@××××.cz>
3213 +
3214 +commit 6209344f5a3795d34b7f2c0061f49802283b6bdd upstream
3215 +
3216 +Previously I assumed that the receive queues of candidates don't
3217 +change during the GC. This is only half true, nothing can be received
3218 +from the queues (see comment in unix_gc()), but buffers could be added
3219 +through the other half of the socket pair, which may still have file
3220 +descriptors referring to it.
3221 +
3222 +This can result in inc_inflight_move_tail() erronously increasing the
3223 +"inflight" counter for a unix socket for which dec_inflight() wasn't
3224 +previously called. This in turn can trigger the "BUG_ON(total_refs <
3225 +inflight_refs)" in a later garbage collection run.
3226 +
3227 +Fix this by only manipulating the "inflight" counter for sockets which
3228 +are candidates themselves. Duplicating the file references in
3229 +unix_attach_fds() is also needed to prevent a socket becoming a
3230 +candidate for GC while the skb that contains it is not yet queued.
3231 +
3232 +Reported-by: Andrea Bittau <a.bittau@×××××××××.uk>
3233 +Signed-off-by: Miklos Szeredi <mszeredi@××××.cz>
3234 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
3235 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3236 +
3237 +---
3238 + include/net/af_unix.h | 1 +
3239 + net/unix/af_unix.c | 31 ++++++++++++++++++++++++-------
3240 + net/unix/garbage.c | 49 +++++++++++++++++++++++++++++++++++++------------
3241 + 3 files changed, 62 insertions(+), 19 deletions(-)
3242 +
3243 +--- a/include/net/af_unix.h
3244 ++++ b/include/net/af_unix.h
3245 +@@ -54,6 +54,7 @@ struct unix_sock {
3246 + atomic_t inflight;
3247 + spinlock_t lock;
3248 + unsigned int gc_candidate : 1;
3249 ++ unsigned int gc_maybe_cycle : 1;
3250 + wait_queue_head_t peer_wait;
3251 + };
3252 + #define unix_sk(__sk) ((struct unix_sock *)__sk)
3253 +--- a/net/unix/af_unix.c
3254 ++++ b/net/unix/af_unix.c
3255 +@@ -1302,14 +1302,23 @@ static void unix_destruct_fds(struct sk_
3256 + sock_wfree(skb);
3257 + }
3258 +
3259 +-static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
3260 ++static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
3261 + {
3262 + int i;
3263 ++
3264 ++ /*
3265 ++ * Need to duplicate file references for the sake of garbage
3266 ++ * collection. Otherwise a socket in the fps might become a
3267 ++ * candidate for GC while the skb is not yet queued.
3268 ++ */
3269 ++ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
3270 ++ if (!UNIXCB(skb).fp)
3271 ++ return -ENOMEM;
3272 ++
3273 + for (i=scm->fp->count-1; i>=0; i--)
3274 + unix_inflight(scm->fp->fp[i]);
3275 +- UNIXCB(skb).fp = scm->fp;
3276 + skb->destructor = unix_destruct_fds;
3277 +- scm->fp = NULL;
3278 ++ return 0;
3279 + }
3280 +
3281 + /*
3282 +@@ -1368,8 +1377,11 @@ static int unix_dgram_sendmsg(struct kio
3283 + goto out;
3284 +
3285 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
3286 +- if (siocb->scm->fp)
3287 +- unix_attach_fds(siocb->scm, skb);
3288 ++ if (siocb->scm->fp) {
3289 ++ err = unix_attach_fds(siocb->scm, skb);
3290 ++ if (err)
3291 ++ goto out_free;
3292 ++ }
3293 + unix_get_secdata(siocb->scm, skb);
3294 +
3295 + skb_reset_transport_header(skb);
3296 +@@ -1538,8 +1550,13 @@ static int unix_stream_sendmsg(struct ki
3297 + size = min_t(int, size, skb_tailroom(skb));
3298 +
3299 + memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
3300 +- if (siocb->scm->fp)
3301 +- unix_attach_fds(siocb->scm, skb);
3302 ++ if (siocb->scm->fp) {
3303 ++ err = unix_attach_fds(siocb->scm, skb);
3304 ++ if (err) {
3305 ++ kfree_skb(skb);
3306 ++ goto out_err;
3307 ++ }
3308 ++ }
3309 +
3310 + if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
3311 + kfree_skb(skb);
3312 +--- a/net/unix/garbage.c
3313 ++++ b/net/unix/garbage.c
3314 +@@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x
3315 + */
3316 + struct sock *sk = unix_get_socket(*fp++);
3317 + if (sk) {
3318 +- hit = true;
3319 +- func(unix_sk(sk));
3320 ++ struct unix_sock *u = unix_sk(sk);
3321 ++
3322 ++ /*
3323 ++ * Ignore non-candidates, they could
3324 ++ * have been added to the queues after
3325 ++ * starting the garbage collection
3326 ++ */
3327 ++ if (u->gc_candidate) {
3328 ++ hit = true;
3329 ++ func(u);
3330 ++ }
3331 + }
3332 + }
3333 + if (hit && hitlist != NULL) {
3334 +@@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struc
3335 + {
3336 + atomic_inc(&u->inflight);
3337 + /*
3338 +- * If this is still a candidate, move it to the end of the
3339 +- * list, so that it's checked even if it was already passed
3340 +- * over
3341 ++ * If this still might be part of a cycle, move it to the end
3342 ++ * of the list, so that it's checked even if it was already
3343 ++ * passed over
3344 + */
3345 +- if (u->gc_candidate)
3346 ++ if (u->gc_maybe_cycle)
3347 + list_move_tail(&u->link, &gc_candidates);
3348 + }
3349 +
3350 +@@ -267,6 +276,7 @@ void unix_gc(void)
3351 + struct unix_sock *next;
3352 + struct sk_buff_head hitlist;
3353 + struct list_head cursor;
3354 ++ LIST_HEAD(not_cycle_list);
3355 +
3356 + spin_lock(&unix_gc_lock);
3357 +
3358 +@@ -282,10 +292,14 @@ void unix_gc(void)
3359 + *
3360 + * Holding unix_gc_lock will protect these candidates from
3361 + * being detached, and hence from gaining an external
3362 +- * reference. This also means, that since there are no
3363 +- * possible receivers, the receive queues of these sockets are
3364 +- * static during the GC, even though the dequeue is done
3365 +- * before the detach without atomicity guarantees.
3366 ++ * reference. Since there are no possible receivers, all
3367 ++ * buffers currently on the candidates' queues stay there
3368 ++ * during the garbage collection.
3369 ++ *
3370 ++ * We also know that no new candidate can be added onto the
3371 ++ * receive queues. Other, non candidate sockets _can_ be
3372 ++ * added to queue, so we must make sure only to touch
3373 ++ * candidates.
3374 + */
3375 + list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
3376 + int total_refs;
3377 +@@ -299,6 +313,7 @@ void unix_gc(void)
3378 + if (total_refs == inflight_refs) {
3379 + list_move_tail(&u->link, &gc_candidates);
3380 + u->gc_candidate = 1;
3381 ++ u->gc_maybe_cycle = 1;
3382 + }
3383 + }
3384 +
3385 +@@ -325,14 +340,24 @@ void unix_gc(void)
3386 + list_move(&cursor, &u->link);
3387 +
3388 + if (atomic_read(&u->inflight) > 0) {
3389 +- list_move_tail(&u->link, &gc_inflight_list);
3390 +- u->gc_candidate = 0;
3391 ++ list_move_tail(&u->link, &not_cycle_list);
3392 ++ u->gc_maybe_cycle = 0;
3393 + scan_children(&u->sk, inc_inflight_move_tail, NULL);
3394 + }
3395 + }
3396 + list_del(&cursor);
3397 +
3398 + /*
3399 ++ * not_cycle_list contains those sockets which do not make up a
3400 ++ * cycle. Restore these to the inflight list.
3401 ++ */
3402 ++ while (!list_empty(&not_cycle_list)) {
3403 ++ u = list_entry(not_cycle_list.next, struct unix_sock, link);
3404 ++ u->gc_candidate = 0;
3405 ++ list_move_tail(&u->link, &gc_inflight_list);
3406 ++ }
3407 ++
3408 ++ /*
3409 + * Now gc_candidates contains only garbage. Restore original
3410 + * inflight counters for these as well, and remove the skbuffs
3411 + * which are creating the cycle(s).
3412
3413 Added: hardened/2.6/tags/2.6.25-14/1413_block-fix-nr_phys_segments-miscalculation-bug.patch
3414 ===================================================================
3415 --- hardened/2.6/tags/2.6.25-14/1413_block-fix-nr_phys_segments-miscalculation-bug.patch (rev 0)
3416 +++ hardened/2.6/tags/2.6.25-14/1413_block-fix-nr_phys_segments-miscalculation-bug.patch 2009-01-21 00:09:46 UTC (rev 1481)
3417 @@ -0,0 +1,126 @@
3418 +Added-By: Gordon Malm <gengor@g.o>
3419 +
3420 +---
3421 +
3422 +From knikanth@××××.de Thu Nov 13 14:07:47 2008
3423 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3424 +Date: Wed, 12 Nov 2008 11:33:54 +0530
3425 +Subject: block: fix nr_phys_segments miscalculation bug
3426 +To: Greg KH <greg@×××××.com>
3427 +Cc: stable@××××××.org, FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3428 +Message-ID: <200811121133.55404.knikanth@××××.de>
3429 +Content-Disposition: inline
3430 +
3431 +From: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3432 +
3433 +commit 8677142710516d986d932d6f1fba7be8382c1fec upstream
3434 +backported by Nikanth Karthikesan <knikanth@××××.de> to the 2.6.27.y tree.
3435 +
3436 +block: fix nr_phys_segments miscalculation bug
3437 +
3438 +This fixes the bug reported by Nikanth Karthikesan <knikanth@××××.de>:
3439 +
3440 +http://lkml.org/lkml/2008/10/2/203
3441 +
3442 +The root cause of the bug is that blk_phys_contig_segment
3443 +miscalculates q->max_segment_size.
3444 +
3445 +blk_phys_contig_segment checks:
3446 +
3447 +req->biotail->bi_size + next_req->bio->bi_size > q->max_segment_size
3448 +
3449 +But blk_recalc_rq_segments might expect that req->biotail and the
3450 +previous bio in the req are supposed be merged into one
3451 +segment. blk_recalc_rq_segments might also expect that next_req->bio
3452 +and the next bio in the next_req are supposed be merged into one
3453 +segment. In such case, we merge two requests that can't be merged
3454 +here. Later, blk_rq_map_sg gives more segments than it should.
3455 +
3456 +We need to keep track of segment size in blk_recalc_rq_segments and
3457 +use it to see if two requests can be merged. This patch implements it
3458 +in the similar way that we used to do for hw merging (virtual
3459 +merging).
3460 +
3461 +Signed-off-by: FUJITA Tomonori <fujita.tomonori@××××××××××.jp>
3462 +Signed-off-by: Jens Axboe <jens.axboe@××××××.com>
3463 +Cc: Nikanth Karthikesan <knikanth@××××.de>
3464 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3465 +
3466 +---
3467 + block/blk-merge.c | 19 +++++++++++++++++--
3468 + include/linux/bio.h | 7 +++++++
3469 + 2 files changed, 24 insertions(+), 2 deletions(-)
3470 +
3471 +--- a/block/blk-merge.c
3472 ++++ b/block/blk-merge.c
3473 +@@ -95,6 +95,9 @@ new_hw_segment:
3474 + nr_hw_segs++;
3475 + }
3476 +
3477 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
3478 ++ rq->bio->bi_seg_front_size = seg_size;
3479 ++
3480 + nr_phys_segs++;
3481 + bvprv = bv;
3482 + seg_size = bv->bv_len;
3483 +@@ -106,6 +109,10 @@ new_hw_segment:
3484 + rq->bio->bi_hw_front_size = hw_seg_size;
3485 + if (hw_seg_size > rq->biotail->bi_hw_back_size)
3486 + rq->biotail->bi_hw_back_size = hw_seg_size;
3487 ++ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
3488 ++ rq->bio->bi_seg_front_size = seg_size;
3489 ++ if (seg_size > rq->biotail->bi_seg_back_size)
3490 ++ rq->biotail->bi_seg_back_size = seg_size;
3491 + rq->nr_phys_segments = nr_phys_segs;
3492 + rq->nr_hw_segments = nr_hw_segs;
3493 + }
3494 +@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struc
3495 +
3496 + if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
3497 + return 0;
3498 +- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
3499 ++ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
3500 ++ q->max_segment_size)
3501 + return 0;
3502 +
3503 + /*
3504 +@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct r
3505 + {
3506 + int total_phys_segments;
3507 + int total_hw_segments;
3508 ++ unsigned int seg_size =
3509 ++ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
3510 +
3511 + /*
3512 + * First check if the either of the requests are re-queued
3513 +@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct r
3514 + return 0;
3515 +
3516 + total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
3517 +- if (blk_phys_contig_segment(q, req->biotail, next->bio))
3518 ++ if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
3519 ++ if (req->nr_phys_segments == 1)
3520 ++ req->bio->bi_seg_front_size = seg_size;
3521 ++ if (next->nr_phys_segments == 1)
3522 ++ next->biotail->bi_seg_back_size = seg_size;
3523 + total_phys_segments--;
3524 ++ }
3525 +
3526 + if (total_phys_segments > q->max_phys_segments)
3527 + return 0;
3528 +--- a/include/linux/bio.h
3529 ++++ b/include/linux/bio.h
3530 +@@ -98,6 +98,13 @@ struct bio {
3531 + unsigned int bi_size; /* residual I/O count */
3532 +
3533 + /*
3534 ++ * To keep track of the max segment size, we account for the
3535 ++ * sizes of the first and last mergeable segments in this bio.
3536 ++ */
3537 ++ unsigned int bi_seg_front_size;
3538 ++ unsigned int bi_seg_back_size;
3539 ++
3540 ++ /*
3541 + * To keep track of the max hw size, we account for the
3542 + * sizes of the first and last virtually mergeable segments
3543 + * in this bio
3544
3545 Added: hardened/2.6/tags/2.6.25-14/1414_dm-raid1-flush-workqueue-before-destruction.patch
3546 ===================================================================
3547 --- hardened/2.6/tags/2.6.25-14/1414_dm-raid1-flush-workqueue-before-destruction.patch (rev 0)
3548 +++ hardened/2.6/tags/2.6.25-14/1414_dm-raid1-flush-workqueue-before-destruction.patch 2009-01-21 00:09:46 UTC (rev 1481)
3549 @@ -0,0 +1,36 @@
3550 +Added-By: Gordon Malm <gengor@g.o>
3551 +
3552 +Note: Backported to 2.6.25. Original message included below.
3553 +
3554 +---
3555 +
3556 +From 18776c7316545482a02bfaa2629a2aa1afc48357 Mon Sep 17 00:00:00 2001
3557 +From: Mikulas Patocka <mpatocka@××××××.com>
3558 +Date: Thu, 13 Nov 2008 23:38:52 +0000
3559 +Subject: dm raid1: flush workqueue before destruction
3560 +
3561 +From: Mikulas Patocka <mpatocka@××××××.com>
3562 +
3563 +commit 18776c7316545482a02bfaa2629a2aa1afc48357 upstream.
3564 +
3565 +We queue work on keventd queue --- so this queue must be flushed in the
3566 +destructor. Otherwise, keventd could access mirror_set after it was freed.
3567 +
3568 +Signed-off-by: Mikulas Patocka <mpatocka@××××××.com>
3569 +Signed-off-by: Alasdair G Kergon <agk@××××××.com>
3570 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3571 +
3572 +---
3573 + drivers/md/dm-raid1.c | 1 +
3574 + 1 file changed, 1 insertion(+)
3575 +
3576 +--- a/drivers/md/dm-raid1.c
3577 ++++ b/drivers/md/dm-raid1.c
3578 +@@ -1590,6 +1590,7 @@ static void mirror_dtr(struct dm_target
3579 + struct mirror_set *ms = (struct mirror_set *) ti->private;
3580 +
3581 + flush_workqueue(ms->kmirrord_wq);
3582 ++ flush_scheduled_work();
3583 + kcopyd_client_destroy(ms->kcopyd_client);
3584 + destroy_workqueue(ms->kmirrord_wq);
3585 + free_context(ms, ti, ms->nr_mirrors);
3586
3587 Added: hardened/2.6/tags/2.6.25-14/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch
3588 ===================================================================
3589 --- hardened/2.6/tags/2.6.25-14/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch (rev 0)
3590 +++ hardened/2.6/tags/2.6.25-14/1415_net-fix-proc-net-snmp-as-memory-corruptor.patch 2009-01-21 00:09:46 UTC (rev 1481)
3591 @@ -0,0 +1,104 @@
3592 +Added-By: Gordon Malm <gengor@g.o>
3593 +
3594 +Note: Backported to earlier kernels. Original message included below.
3595 +
3596 +---
3597 +
3598 +From b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 Mon Sep 17 00:00:00 2001
3599 +From: Eric Dumazet <dada1@×××××××××.com>
3600 +Date: Mon, 10 Nov 2008 21:43:08 -0800
3601 +Subject: net: fix /proc/net/snmp as memory corruptor
3602 +
3603 +From: Eric Dumazet <dada1@×××××××××.com>
3604 +
3605 +commit b971e7ac834e9f4bda96d5a96ae9abccd01c1dd8 upstream.
3606 +
3607 +icmpmsg_put() can happily corrupt kernel memory, using a static
3608 +table and forgetting to reset an array index in a loop.
3609 +
3610 +Remove the static array since its not safe without proper locking.
3611 +
3612 +Signed-off-by: Alexey Dobriyan <adobriyan@×××××.com>
3613 +Signed-off-by: Eric Dumazet <dada1@×××××××××.com>
3614 +Signed-off-by: David S. Miller <davem@×××××××××.net>
3615 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3616 +
3617 +---
3618 + net/ipv4/proc.c | 58 ++++++++++++++++++++++++++++----------------------------
3619 + 1 file changed, 30 insertions(+), 28 deletions(-)
3620 +
3621 +--- a/net/ipv4/proc.c
3622 ++++ b/net/ipv4/proc.c
3623 +@@ -262,42 +262,44 @@ static const struct snmp_mib snmp4_net_l
3624 + SNMP_MIB_SENTINEL
3625 + };
3626 +
3627 +-static void icmpmsg_put(struct seq_file *seq)
3628 ++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
3629 ++ unsigned short *type, int count)
3630 + {
3631 +-#define PERLINE 16
3632 +-
3633 +- int j, i, count;
3634 +- static int out[PERLINE];
3635 +-
3636 +- count = 0;
3637 +- for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
3638 +-
3639 +- if (snmp_fold_field((void **) icmpmsg_statistics, i))
3640 +- out[count++] = i;
3641 +- if (count < PERLINE)
3642 +- continue;
3643 ++ int j;
3644 +
3645 +- seq_printf(seq, "\nIcmpMsg:");
3646 +- for (j = 0; j < PERLINE; ++j)
3647 +- seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In",
3648 +- i & 0xff);
3649 +- seq_printf(seq, "\nIcmpMsg: ");
3650 +- for (j = 0; j < PERLINE; ++j)
3651 +- seq_printf(seq, " %lu",
3652 +- snmp_fold_field((void **) icmpmsg_statistics,
3653 +- out[j]));
3654 +- seq_putc(seq, '\n');
3655 +- }
3656 + if (count) {
3657 + seq_printf(seq, "\nIcmpMsg:");
3658 + for (j = 0; j < count; ++j)
3659 +- seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" :
3660 +- "In", out[j] & 0xff);
3661 ++ seq_printf(seq, " %sType%u",
3662 ++ type[j] & 0x100 ? "Out" : "In",
3663 ++ type[j] & 0xff);
3664 + seq_printf(seq, "\nIcmpMsg:");
3665 + for (j = 0; j < count; ++j)
3666 +- seq_printf(seq, " %lu", snmp_fold_field((void **)
3667 +- icmpmsg_statistics, out[j]));
3668 ++ seq_printf(seq, " %lu", vals[j]);
3669 ++ }
3670 ++}
3671 ++
3672 ++static void icmpmsg_put(struct seq_file *seq)
3673 ++{
3674 ++#define PERLINE 16
3675 ++
3676 ++ int i, count;
3677 ++ unsigned short type[PERLINE];
3678 ++ unsigned long vals[PERLINE], val;
3679 ++
3680 ++ count = 0;
3681 ++ for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
3682 ++ val = snmp_fold_field((void **) icmpmsg_statistics, i);
3683 ++ if (val) {
3684 ++ type[count] = i;
3685 ++ vals[count++] = val;
3686 ++ }
3687 ++ if (count == PERLINE) {
3688 ++ icmpmsg_put_line(seq, vals, type, count);
3689 ++ count = 0;
3690 ++ }
3691 + }
3692 ++ icmpmsg_put_line(seq, vals, type, count);
3693 +
3694 + #undef PERLINE
3695 + }
3696
3697 Added: hardened/2.6/tags/2.6.25-14/1416_touch_mnt_namespace-when-the-mount-flags-change.patch
3698 ===================================================================
3699 --- hardened/2.6/tags/2.6.25-14/1416_touch_mnt_namespace-when-the-mount-flags-change.patch (rev 0)
3700 +++ hardened/2.6/tags/2.6.25-14/1416_touch_mnt_namespace-when-the-mount-flags-change.patch 2009-01-21 00:09:46 UTC (rev 1481)
3701 @@ -0,0 +1,43 @@
3702 +Added-By: Gordon Malm <gengor@g.o>
3703 +
3704 +---
3705 +
3706 +From 0e55a7cca4b66f625d67b292f80b6a976e77c51b Mon Sep 17 00:00:00 2001
3707 +From: Dan Williams <dan.j.williams@×××××.com>
3708 +Date: Fri, 26 Sep 2008 19:01:20 -0700
3709 +Subject: touch_mnt_namespace when the mount flags change
3710 +
3711 +From: Dan Williams <dan.j.williams@×××××.com>
3712 +
3713 +commit 0e55a7cca4b66f625d67b292f80b6a976e77c51b upstream
3714 +
3715 +Daemons that need to be launched while the rootfs is read-only can now
3716 +poll /proc/mounts to be notified when their O_RDWR requests may no
3717 +longer end in EROFS.
3718 +
3719 +Cc: Kay Sievers <kay.sievers@××××.org>
3720 +Cc: Neil Brown <neilb@××××.de>
3721 +Signed-off-by: Dan Williams <dan.j.williams@×××××.com>
3722 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3723 +
3724 +---
3725 + fs/namespace.c | 7 ++++++-
3726 + 1 file changed, 6 insertions(+), 1 deletion(-)
3727 +
3728 +--- a/fs/namespace.c
3729 ++++ b/fs/namespace.c
3730 +@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct na
3731 + if (!err)
3732 + nd->path.mnt->mnt_flags = mnt_flags;
3733 + up_write(&sb->s_umount);
3734 +- if (!err)
3735 ++ if (!err) {
3736 + security_sb_post_remount(nd->path.mnt, flags, data);
3737 ++
3738 ++ spin_lock(&vfsmount_lock);
3739 ++ touch_mnt_namespace(nd->path.mnt->mnt_ns);
3740 ++ spin_unlock(&vfsmount_lock);
3741 ++ }
3742 + return err;
3743 + }
3744 +
3745
3746 Added: hardened/2.6/tags/2.6.25-14/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch
3747 ===================================================================
3748 --- hardened/2.6/tags/2.6.25-14/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch (rev 0)
3749 +++ hardened/2.6/tags/2.6.25-14/1417_usb-ehci-remove-obsolete-workaround-for-bogus-IRQs.patch 2009-01-21 00:09:46 UTC (rev 1481)
3750 @@ -0,0 +1,54 @@
3751 +Added-By: Gordon Malm <gengor@g.o>
3752 +
3753 +---
3754 +
3755 +From: David Brownell <david-b@×××××××.net>
3756 +Date: Thu, 6 Mar 2008 07:37:52 +0000 (-0800)
3757 +Subject: USB: ehci: remove obsolete workaround for bogus IRQs
3758 +X-Git-Tag: v2.6.26-rc1~1061^2~74
3759 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=d1b1842c393cf322712b669ec887397b89ed2312
3760 +
3761 +USB: ehci: remove obsolete workaround for bogus IRQs
3762 +
3763 +It was pointed out that we found and fixed the cause of the "bogus"
3764 +fatal IRQ reports some time ago ... this patch removes the code
3765 +which was working around that bug ("status" got clobbered), and a
3766 +comment which needlessly confused folk reading this code.
3767 +
3768 +This also includes a minor cleanup to the code which fixed that bug.
3769 +
3770 +Signed-off-by: David Brownell <dbrownell@×××××××××××××××××.net>
3771 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3772 +---
3773 +
3774 +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
3775 +index 40f7391..8c3e860 100644
3776 +--- a/drivers/usb/host/ehci-hcd.c
3777 ++++ b/drivers/usb/host/ehci-hcd.c
3778 +@@ -686,6 +686,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
3779 + /* remote wakeup [4.3.1] */
3780 + if (status & STS_PCD) {
3781 + unsigned i = HCS_N_PORTS (ehci->hcs_params);
3782 ++
3783 ++ /* kick root hub later */
3784 + pcd_status = status;
3785 +
3786 + /* resume root hub? */
3787 +@@ -714,8 +716,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
3788 +
3789 + /* PCI errors [4.15.2.4] */
3790 + if (unlikely ((status & STS_FATAL) != 0)) {
3791 +- /* bogus "fatal" IRQs appear on some chips... why? */
3792 +- status = ehci_readl(ehci, &ehci->regs->status);
3793 + dbg_cmd (ehci, "fatal", ehci_readl(ehci,
3794 + &ehci->regs->command));
3795 + dbg_status (ehci, "fatal", status);
3796 +@@ -734,7 +734,7 @@ dead:
3797 + if (bh)
3798 + ehci_work (ehci);
3799 + spin_unlock (&ehci->lock);
3800 +- if (pcd_status & STS_PCD)
3801 ++ if (pcd_status)
3802 + usb_hcd_poll_rh_status(hcd);
3803 + return IRQ_HANDLED;
3804 + }
3805
3806 Added: hardened/2.6/tags/2.6.25-14/1418_usb-ehci-fix-handling-of-dead-controllers.patch
3807 ===================================================================
3808 --- hardened/2.6/tags/2.6.25-14/1418_usb-ehci-fix-handling-of-dead-controllers.patch (rev 0)
3809 +++ hardened/2.6/tags/2.6.25-14/1418_usb-ehci-fix-handling-of-dead-controllers.patch 2009-01-21 00:09:46 UTC (rev 1481)
3810 @@ -0,0 +1,93 @@
3811 +Added-By: Gordon Malm <gengor@g.o>
3812 +
3813 +---
3814 +
3815 +From 67b2e029743a52670d77864723b4d0d40f7733b5 Mon Sep 17 00:00:00 2001
3816 +From: Alan Stern <stern@×××××××××××××××.edu>
3817 +Date: Wed, 12 Nov 2008 17:04:53 -0500
3818 +Subject: USB: EHCI: fix handling of dead controllers
3819 +
3820 +From: Alan Stern <stern@×××××××××××××××.edu>
3821 +
3822 +commit 67b2e029743a52670d77864723b4d0d40f7733b5 upstream.
3823 +
3824 +This patch (as1165) makes a few small changes in the logic used by
3825 +ehci-hcd when it encounters a controller error:
3826 +
3827 + Instead of printing out the masked status, it prints the
3828 + original status as read directly from the hardware.
3829 +
3830 + It doesn't check for the STS_HALT status bit before taking
3831 + action. The mere fact that the STS_FATAL bit is set means
3832 + that something bad has happened and the controller needs to
3833 + be reset. With the old code this test could never succeed
3834 + because the STS_HALT bit was masked out from the status.
3835 +
3836 +I anticipate that this will prevent the occasional "irq X: nobody cared"
3837 +problem people encounter when their EHCI controllers die.
3838 +
3839 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
3840 +Cc: David Brownell <david-b@×××××××.net>
3841 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3842 +
3843 +---
3844 + drivers/usb/host/ehci-hcd.c | 25 ++++++++++++-------------
3845 + 1 file changed, 12 insertions(+), 13 deletions(-)
3846 +
3847 +--- a/drivers/usb/host/ehci-hcd.c
3848 ++++ b/drivers/usb/host/ehci-hcd.c
3849 +@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd
3850 + static irqreturn_t ehci_irq (struct usb_hcd *hcd)
3851 + {
3852 + struct ehci_hcd *ehci = hcd_to_ehci (hcd);
3853 +- u32 status, pcd_status = 0, cmd;
3854 ++ u32 status, masked_status, pcd_status = 0, cmd;
3855 + int bh;
3856 +
3857 + spin_lock (&ehci->lock);
3858 +@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_
3859 + goto dead;
3860 + }
3861 +
3862 +- status &= INTR_MASK;
3863 +- if (!status) { /* irq sharing? */
3864 ++ masked_status = status & INTR_MASK;
3865 ++ if (!masked_status) { /* irq sharing? */
3866 + spin_unlock(&ehci->lock);
3867 + return IRQ_NONE;
3868 + }
3869 +
3870 + /* clear (just) interrupts */
3871 +- ehci_writel(ehci, status, &ehci->regs->status);
3872 ++ ehci_writel(ehci, masked_status, &ehci->regs->status);
3873 + cmd = ehci_readl(ehci, &ehci->regs->command);
3874 + bh = 0;
3875 +
3876 +@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_
3877 +
3878 + /* PCI errors [4.15.2.4] */
3879 + if (unlikely ((status & STS_FATAL) != 0)) {
3880 ++ ehci_err(ehci, "fatal error\n");
3881 + dbg_cmd (ehci, "fatal", ehci_readl(ehci,
3882 + &ehci->regs->command));
3883 + dbg_status (ehci, "fatal", status);
3884 +- if (status & STS_HALT) {
3885 +- ehci_err (ehci, "fatal error\n");
3886 ++ ehci_halt(ehci);
3887 + dead:
3888 +- ehci_reset (ehci);
3889 +- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
3890 +- /* generic layer kills/unlinks all urbs, then
3891 +- * uses ehci_stop to clean up the rest
3892 +- */
3893 +- bh = 1;
3894 +- }
3895 ++ ehci_reset(ehci);
3896 ++ ehci_writel(ehci, 0, &ehci->regs->configured_flag);
3897 ++ /* generic layer kills/unlinks all urbs, then
3898 ++ * uses ehci_stop to clean up the rest
3899 ++ */
3900 ++ bh = 1;
3901 + }
3902 +
3903 + if (bh)
3904
3905 Added: hardened/2.6/tags/2.6.25-14/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch
3906 ===================================================================
3907 --- hardened/2.6/tags/2.6.25-14/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch (rev 0)
3908 +++ hardened/2.6/tags/2.6.25-14/1419_usb-don-t-register-endpoints-for-interfaces-that-are-going-away.patch 2009-01-21 00:09:46 UTC (rev 1481)
3909 @@ -0,0 +1,75 @@
3910 +Added-By: Gordon Malm <gengor@g.o>
3911 +
3912 +Note: Backported to kernel 2.6.25. Original message included below.
3913 +
3914 +---
3915 +
3916 +From 352d026338378b1f13f044e33c1047da6e470056 Mon Sep 17 00:00:00 2001
3917 +From: Alan Stern <stern@×××××××××××××××.edu>
3918 +Date: Wed, 29 Oct 2008 15:16:58 -0400
3919 +Subject: USB: don't register endpoints for interfaces that are going away
3920 +
3921 +From: Alan Stern <stern@×××××××××××××××.edu>
3922 +
3923 +commit 352d026338378b1f13f044e33c1047da6e470056 upstream.
3924 +
3925 +This patch (as1155) fixes a bug in usbcore. When interfaces are
3926 +deleted, either because the device was disconnected or because of a
3927 +configuration change, the extra attribute files and child endpoint
3928 +devices may get left behind. This is because the core removes them
3929 +before calling device_del(). But during device_del(), after the
3930 +driver is unbound the core will reinstall altsetting 0 and recreate
3931 +those extra attributes and children.
3932 +
3933 +The patch prevents this by adding a flag to record when the interface
3934 +is in the midst of being unregistered. When the flag is set, the
3935 +attribute files and child devices will not be created.
3936 +
3937 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
3938 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
3939 +
3940 +---
3941 + drivers/usb/core/message.c | 1 +
3942 + drivers/usb/core/sysfs.c | 2 +-
3943 + include/linux/usb.h | 2 ++
3944 + 3 files changed, 4 insertions(+), 1 deletion(-)
3945 +
3946 +--- a/drivers/usb/core/message.c
3947 ++++ b/drivers/usb/core/message.c
3948 +@@ -1089,6 +1089,7 @@ void usb_disable_device(struct usb_devic
3949 + continue;
3950 + dev_dbg(&dev->dev, "unregistering interface %s\n",
3951 + interface->dev.bus_id);
3952 ++ interface->unregistering = 1;
3953 + usb_remove_sysfs_intf_files(interface);
3954 + device_del(&interface->dev);
3955 + }
3956 +--- a/drivers/usb/core/sysfs.c
3957 ++++ b/drivers/usb/core/sysfs.c
3958 +@@ -784,7 +784,7 @@ int usb_create_sysfs_intf_files(struct u
3959 + struct usb_host_interface *alt = intf->cur_altsetting;
3960 + int retval;
3961 +
3962 +- if (intf->sysfs_files_created)
3963 ++ if (intf->sysfs_files_created || intf->unregistering)
3964 + return 0;
3965 + retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
3966 + if (retval)
3967 +--- a/include/linux/usb.h
3968 ++++ b/include/linux/usb.h
3969 +@@ -107,6 +107,7 @@ enum usb_interface_condition {
3970 + * (in probe()), bound to a driver, or unbinding (in disconnect())
3971 + * @is_active: flag set when the interface is bound and not suspended.
3972 + * @sysfs_files_created: sysfs attributes exist
3973 ++ * @unregistering: flag set when the interface is being unregistered
3974 + * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
3975 + * capability during autosuspend.
3976 + * @dev: driver model's view of this device
3977 +@@ -158,6 +159,7 @@ struct usb_interface {
3978 + enum usb_interface_condition condition; /* state of binding */
3979 + unsigned is_active:1; /* the interface is not suspended */
3980 + unsigned sysfs_files_created:1; /* the sysfs attributes exist */
3981 ++ unsigned unregistering:1; /* unregistration is in progress */
3982 + unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
3983 +
3984 + struct device dev; /* interface specific device info */
3985
3986 Added: hardened/2.6/tags/2.6.25-14/1420_usb-ehci-fix-divide-by-zero-bug.patch
3987 ===================================================================
3988 --- hardened/2.6/tags/2.6.25-14/1420_usb-ehci-fix-divide-by-zero-bug.patch (rev 0)
3989 +++ hardened/2.6/tags/2.6.25-14/1420_usb-ehci-fix-divide-by-zero-bug.patch 2009-01-21 00:09:46 UTC (rev 1481)
3990 @@ -0,0 +1,46 @@
3991 +Added-By: Gordon Malm <gengor@g.o>
3992 +
3993 +---
3994 +
3995 +From 372dd6e8ed924e876f3beb598721e813ad7fa323 Mon Sep 17 00:00:00 2001
3996 +From: Alan Stern <stern@×××××××××××××××.edu>
3997 +Date: Wed, 12 Nov 2008 17:02:57 -0500
3998 +Subject: USB: EHCI: fix divide-by-zero bug
3999 +
4000 +From: Alan Stern <stern@×××××××××××××××.edu>
4001 +
4002 +commit 372dd6e8ed924e876f3beb598721e813ad7fa323 upstream.
4003 +
4004 +This patch (as1164) fixes a bug in the EHCI scheduler. The interval
4005 +value it uses is already in linear format, not logarithmically coded.
4006 +The existing code can sometimes crash the system by trying to divide
4007 +by zero.
4008 +
4009 +Signed-off-by: Alan Stern <stern@×××××××××××××××.edu>
4010 +Cc: David Brownell <david-b@×××××××.net>
4011 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4012 +
4013 +---
4014 + drivers/usb/host/ehci-sched.c | 4 ++--
4015 + 1 file changed, 2 insertions(+), 2 deletions(-)
4016 +
4017 +--- a/drivers/usb/host/ehci-sched.c
4018 ++++ b/drivers/usb/host/ehci-sched.c
4019 +@@ -918,7 +918,7 @@ iso_stream_init (
4020 + */
4021 + stream->usecs = HS_USECS_ISO (maxp);
4022 + bandwidth = stream->usecs * 8;
4023 +- bandwidth /= 1 << (interval - 1);
4024 ++ bandwidth /= interval;
4025 +
4026 + } else {
4027 + u32 addr;
4028 +@@ -951,7 +951,7 @@ iso_stream_init (
4029 + } else
4030 + stream->raw_mask = smask_out [hs_transfers - 1];
4031 + bandwidth = stream->usecs + stream->c_usecs;
4032 +- bandwidth /= 1 << (interval + 2);
4033 ++ bandwidth /= interval << 3;
4034 +
4035 + /* stream->splits gets created from raw_mask later */
4036 + stream->address = cpu_to_hc32(ehci, addr);
4037
4038 Added: hardened/2.6/tags/2.6.25-14/1421_usb-fix-ps3-usb-shutdown-problems.patch
4039 ===================================================================
4040 --- hardened/2.6/tags/2.6.25-14/1421_usb-fix-ps3-usb-shutdown-problems.patch (rev 0)
4041 +++ hardened/2.6/tags/2.6.25-14/1421_usb-fix-ps3-usb-shutdown-problems.patch 2009-01-21 00:09:46 UTC (rev 1481)
4042 @@ -0,0 +1,64 @@
4043 +Added-By: Gordon Malm <gengor@g.o>
4044 +
4045 +---
4046 +
4047 +From ddcb01ff9bf49c4dbbb058423559f7bc90b89374 Mon Sep 17 00:00:00 2001
4048 +From: Geoff Levand <geoffrey.levand@×××××××.com>
4049 +Date: Fri, 31 Oct 2008 13:52:54 -0700
4050 +Subject: USB: Fix PS3 USB shutdown problems
4051 +
4052 +From: Geoff Levand <geoffrey.levand@×××××××.com>
4053 +
4054 +commit ddcb01ff9bf49c4dbbb058423559f7bc90b89374 upstream.
4055 +
4056 +Add ehci_shutdown() or ohci_shutdown() calls to the USB
4057 +PS3 bus glue. ehci_shutdown() and ohci_shutdown() do some
4058 +controller specific cleanups not done by usb_remove_hcd().
4059 +
4060 +Fixes errors on shutdown or reboot similar to these:
4061 +
4062 + ps3-ehci-driver sb_07: HC died; cleaning up
4063 + irq 51: nobody cared (try booting with the "irqpoll" option)
4064 +
4065 +Related bugzilla reports:
4066 +
4067 + http://bugzilla.kernel.org/show_bug.cgi?id=11819
4068 + http://bugzilla.terrasoftsolutions.com/show_bug.cgi?id=317
4069 +
4070 +Signed-off-by: Geoff Levand <geoffrey.levand@×××××××.com>
4071 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4072 +
4073 +---
4074 + drivers/usb/host/ehci-ps3.c | 1 +
4075 + drivers/usb/host/ohci-ps3.c | 3 ++-
4076 + 2 files changed, 3 insertions(+), 1 deletion(-)
4077 +
4078 +--- a/drivers/usb/host/ehci-ps3.c
4079 ++++ b/drivers/usb/host/ehci-ps3.c
4080 +@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_sy
4081 +
4082 + tmp = hcd->irq;
4083 +
4084 ++ ehci_shutdown(hcd);
4085 + usb_remove_hcd(hcd);
4086 +
4087 + ps3_system_bus_set_driver_data(dev, NULL);
4088 +--- a/drivers/usb/host/ohci-ps3.c
4089 ++++ b/drivers/usb/host/ohci-ps3.c
4090 +@@ -192,7 +192,7 @@ fail_start:
4091 + return result;
4092 + }
4093 +
4094 +-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
4095 ++static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
4096 + {
4097 + unsigned int tmp;
4098 + struct usb_hcd *hcd =
4099 +@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_s
4100 +
4101 + tmp = hcd->irq;
4102 +
4103 ++ ohci_shutdown(hcd);
4104 + usb_remove_hcd(hcd);
4105 +
4106 + ps3_system_bus_set_driver_data(dev, NULL);
4107
4108 Added: hardened/2.6/tags/2.6.25-14/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch
4109 ===================================================================
4110 --- hardened/2.6/tags/2.6.25-14/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch (rev 0)
4111 +++ hardened/2.6/tags/2.6.25-14/1422_v4l-dvb-cve-2008-5033-fix-oops-on-tvaudio-when-controlling-bass-treble.patch 2009-01-21 00:09:46 UTC (rev 1481)
4112 @@ -0,0 +1,135 @@
4113 +Added-By: Gordon Malm <gengor@g.o>
4114 +
4115 +---
4116 +
4117 +From 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 Mon Sep 17 00:00:00 2001
4118 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
4119 +Date: Fri, 14 Nov 2008 10:46:59 -0300
4120 +Subject: V4L/DVB (9624): CVE-2008-5033: fix OOPS on tvaudio when controlling bass/treble
4121 +
4122 +From: Mauro Carvalho Chehab <mchehab@××××××.com>
4123 +
4124 +commit 01a1a3cc1e3fbe718bd06a2a5d4d1a2d0fb4d7d9 upstream.
4125 +
4126 +This bug were supposed to be fixed by 5ba2f67afb02c5302b2898949ed6fc3b3d37dcf1,
4127 +where a call to NULL happens.
4128 +
4129 +Not all tvaudio chips allow controlling bass/treble. So, the driver
4130 +has a table with a flag to indicate if the chip does support it.
4131 +
4132 +Unfortunately, the handling of this logic were broken for a very long
4133 +time (probably since the first module version). Due to that, an OOPS
4134 +were generated for devices that don't support bass/treble.
4135 +
4136 +This were the resulting OOPS message before the patch, with debug messages
4137 +enabled:
4138 +
4139 +tvaudio' 1-005b: VIDIOC_S_CTRL
4140 +BUG: unable to handle kernel NULL pointer dereference at 00000000
4141 +IP: [<00000000>]
4142 +*pde = 22fda067 *pte = 00000000
4143 +Oops: 0000 [#1] SMP
4144 +Modules linked in: snd_hda_intel snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device
4145 +snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_hwdep snd soundcore tuner_simple tuner_types tea5767 tuner
4146 +tvaudio bttv bridgebnep rfcomm l2cap bluetooth it87 hwmon_vid hwmon fuse sunrpc ipt_REJECT
4147 +nf_conntrack_ipv4 iptable_filter ip_tables ip6t_REJECT xt_tcpudp nf_conntrack_ipv6 xt_state nf_conntrack
4148 +ip6table_filter ip6_tables x_tables ipv6 dm_mirrordm_multipath dm_mod configfs videodev v4l1_compat
4149 +ir_common 8139cp compat_ioctl32 v4l2_common 8139too videobuf_dma_sg videobuf_core mii btcx_risc tveeprom
4150 +i915 button snd_page_alloc serio_raw drm pcspkr i2c_algo_bit i2c_i801 i2c_core iTCO_wdt
4151 +iTCO_vendor_support sr_mod cdrom sg ata_generic pata_acpi ata_piix libata sd_mod scsi_mod ext3 jbdmbcache
4152 +uhci_hcd ohci_hcd ehci_hcd [last unloaded: soundcore]
4153 +
4154 +Pid: 15413, comm: qv4l2 Not tainted (2.6.25.14-108.fc9.i686 #1)
4155 +EIP: 0060:[<00000000>] EFLAGS: 00210246 CPU: 0
4156 +EIP is at 0x0
4157 +EAX: 00008000 EBX: ebd21600 ECX: e2fd9ec4 EDX: 00200046
4158 +ESI: f8c0f0c4 EDI: f8c0f0c4 EBP: e2fd9d50 ESP: e2fd9d2c
4159 + DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
4160 +Process qv4l2 (pid: 15413, ti=e2fd9000 task=ebe44000 task.ti=e2fd9000)
4161 +Stack: f8c0c6ae e2ff2a00 00000d00 e2fd9ec4 ebc4e000 e2fd9d5c f8c0c448 00000000
4162 + f899c12a e2fd9d5c f899c154 e2fd9d68 e2fd9d80 c0560185 e2fd9d88 f8f3e1d8
4163 + f8f3e1dc ebc4e034 f8f3e18c e2fd9ec4 00000000 e2fd9d90 f899c286 c008561c
4164 +Call Trace:
4165 + [<f8c0c6ae>] ? chip_command+0x266/0x4b6 [tvaudio]
4166 + [<f8c0c448>] ? chip_command+0x0/0x4b6 [tvaudio]
4167 + [<f899c12a>] ? i2c_cmd+0x0/0x2f [i2c_core]
4168 + [<f899c154>] ? i2c_cmd+0x2a/0x2f [i2c_core]
4169 + [<c0560185>] ? device_for_each_child+0x21/0x49
4170 + [<f899c286>] ? i2c_clients_command+0x1c/0x1e [i2c_core]
4171 + [<f8f283d8>] ? bttv_call_i2c_clients+0x14/0x16 [bttv]
4172 + [<f8f23601>] ? bttv_s_ctrl+0x1bc/0x313 [bttv]
4173 + [<f8f23445>] ? bttv_s_ctrl+0x0/0x313 [bttv]
4174 + [<f8b6096d>] ? __video_do_ioctl+0x1f84/0x3726 [videodev]
4175 + [<c05abb4e>] ? sock_aio_write+0x100/0x10d
4176 + [<c041b23e>] ? kmap_atomic_prot+0x1dd/0x1df
4177 + [<c043a0c9>] ? enqueue_hrtimer+0xc2/0xcd
4178 + [<c04f4fa4>] ? copy_from_user+0x39/0x121
4179 + [<f8b622b9>] ? __video_ioctl2+0x1aa/0x24a [videodev]
4180 + [<c04054fd>] ? do_notify_resume+0x768/0x795
4181 + [<c043c0f7>] ? getnstimeofday+0x34/0xd1
4182 + [<c0437b77>] ? autoremove_wake_function+0x0/0x33
4183 + [<f8b62368>] ? video_ioctl2+0xf/0x13 [videodev]
4184 + [<c048c6f0>] ? vfs_ioctl+0x50/0x69
4185 + [<c048c942>] ? do_vfs_ioctl+0x239/0x24c
4186 + [<c048c995>] ? sys_ioctl+0x40/0x5b
4187 + [<c0405bf2>] ? syscall_call+0x7/0xb
4188 + [<c0620000>] ? cpuid4_cache_sysfs_exit+0x3d/0x69
4189 + =======================
4190 +Code: Bad EIP value.
4191 +EIP: [<00000000>] 0x0 SS:ESP 0068:e2fd9d2c
4192 +
4193 +Signed-off-by: Mauro Carvalho Chehab <mchehab@××××××.com>
4194 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4195 +
4196 +---
4197 + drivers/media/video/tvaudio.c | 15 +++++++--------
4198 + 1 file changed, 7 insertions(+), 8 deletions(-)
4199 +
4200 +--- a/drivers/media/video/tvaudio.c
4201 ++++ b/drivers/media/video/tvaudio.c
4202 +@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPS
4203 + return 0;
4204 + }
4205 + case V4L2_CID_AUDIO_BASS:
4206 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4207 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4208 + break;
4209 + ctrl->value = chip->bass;
4210 + return 0;
4211 + case V4L2_CID_AUDIO_TREBLE:
4212 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4213 +- return -EINVAL;
4214 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4215 ++ break;
4216 + ctrl->value = chip->treble;
4217 + return 0;
4218 + }
4219 +@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPS
4220 + return 0;
4221 + }
4222 + case V4L2_CID_AUDIO_BASS:
4223 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4224 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4225 + break;
4226 + chip->bass = ctrl->value;
4227 + chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
4228 +
4229 + return 0;
4230 + case V4L2_CID_AUDIO_TREBLE:
4231 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4232 +- return -EINVAL;
4233 +-
4234 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4235 ++ break;
4236 + chip->treble = ctrl->value;
4237 + chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
4238 +
4239 +@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_clien
4240 + break;
4241 + case V4L2_CID_AUDIO_BASS:
4242 + case V4L2_CID_AUDIO_TREBLE:
4243 +- if (desc->flags & CHIP_HAS_BASSTREBLE)
4244 ++ if (!(desc->flags & CHIP_HAS_BASSTREBLE))
4245 + return -EINVAL;
4246 + break;
4247 + default:
4248
4249 Added: hardened/2.6/tags/2.6.25-14/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch
4250 ===================================================================
4251 --- hardened/2.6/tags/2.6.25-14/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch (rev 0)
4252 +++ hardened/2.6/tags/2.6.25-14/1423_net-fix-soft-lockups-oom-issues-w-unix-garbage-collector.patch 2009-01-21 00:09:46 UTC (rev 1481)
4253 @@ -0,0 +1,105 @@
4254 +Added-By: Gordon Malm <gengor@g.o>
4255 +
4256 +---
4257 +
4258 +From 5f23b734963ec7eaa3ebcd9050da0c9b7d143dd3 Mon Sep 17 00:00:00 2001
4259 +From: dann frazier <dannf@××.com>
4260 +Date: Wed, 26 Nov 2008 15:32:27 -0800
4261 +Subject: net: Fix soft lockups/OOM issues w/ unix garbage collector (CVE-2008-5300)
4262 +
4263 +From: dann frazier <dannf@××.com>
4264 +
4265 +commit 5f23b734963ec7eaa3ebcd9050da0c9b7d143dd3 upstream.
4266 +
4267 +This is an implementation of David Miller's suggested fix in:
4268 + https://bugzilla.redhat.com/show_bug.cgi?id=470201
4269 +
4270 +It has been updated to use wait_event() instead of
4271 +wait_event_interruptible().
4272 +
4273 +Paraphrasing the description from the above report, it makes sendmsg()
4274 +block while UNIX garbage collection is in progress. This avoids a
4275 +situation where child processes continue to queue new FDs over a
4276 +AF_UNIX socket to a parent which is in the exit path and running
4277 +garbage collection on these FDs. This contention can result in soft
4278 +lockups and oom-killing of unrelated processes.
4279 +
4280 +Signed-off-by: dann frazier <dannf@××.com>
4281 +Signed-off-by: David S. Miller <davem@×××××××××.net>
4282 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4283 +---
4284 +
4285 +--- a/include/net/af_unix.h
4286 ++++ b/include/net/af_unix.h
4287 +@@ -9,6 +9,7 @@
4288 + extern void unix_inflight(struct file *fp);
4289 + extern void unix_notinflight(struct file *fp);
4290 + extern void unix_gc(void);
4291 ++extern void wait_for_unix_gc(void);
4292 +
4293 + #define UNIX_HASH_SIZE 256
4294 +
4295 +--- a/net/unix/af_unix.c
4296 ++++ b/net/unix/af_unix.c
4297 +@@ -1341,6 +1341,7 @@ static int unix_dgram_sendmsg(struct kio
4298 +
4299 + if (NULL == siocb->scm)
4300 + siocb->scm = &tmp_scm;
4301 ++ wait_for_unix_gc();
4302 + err = scm_send(sock, msg, siocb->scm);
4303 + if (err < 0)
4304 + return err;
4305 +@@ -1491,6 +1492,7 @@ static int unix_stream_sendmsg(struct ki
4306 +
4307 + if (NULL == siocb->scm)
4308 + siocb->scm = &tmp_scm;
4309 ++ wait_for_unix_gc();
4310 + err = scm_send(sock, msg, siocb->scm);
4311 + if (err < 0)
4312 + return err;
4313 +--- a/net/unix/garbage.c
4314 ++++ b/net/unix/garbage.c
4315 +@@ -80,6 +80,7 @@
4316 + #include <linux/file.h>
4317 + #include <linux/proc_fs.h>
4318 + #include <linux/mutex.h>
4319 ++#include <linux/wait.h>
4320 +
4321 + #include <net/sock.h>
4322 + #include <net/af_unix.h>
4323 +@@ -91,6 +92,7 @@
4324 + static LIST_HEAD(gc_inflight_list);
4325 + static LIST_HEAD(gc_candidates);
4326 + static DEFINE_SPINLOCK(unix_gc_lock);
4327 ++static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
4328 +
4329 + unsigned int unix_tot_inflight;
4330 +
4331 +@@ -266,12 +268,16 @@ static void inc_inflight_move_tail(struc
4332 + list_move_tail(&u->link, &gc_candidates);
4333 + }
4334 +
4335 +-/* The external entry point: unix_gc() */
4336 ++static bool gc_in_progress = false;
4337 +
4338 +-void unix_gc(void)
4339 ++void wait_for_unix_gc(void)
4340 + {
4341 +- static bool gc_in_progress = false;
4342 ++ wait_event(unix_gc_wait, gc_in_progress == false);
4343 ++}
4344 +
4345 ++/* The external entry point: unix_gc() */
4346 ++void unix_gc(void)
4347 ++{
4348 + struct unix_sock *u;
4349 + struct unix_sock *next;
4350 + struct sk_buff_head hitlist;
4351 +@@ -376,6 +382,7 @@ void unix_gc(void)
4352 + /* All candidates should have been detached by now. */
4353 + BUG_ON(!list_empty(&gc_candidates));
4354 + gc_in_progress = false;
4355 ++ wake_up(&unix_gc_wait);
4356 +
4357 + out:
4358 + spin_unlock(&unix_gc_lock);
4359
4360 Added: hardened/2.6/tags/2.6.25-14/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch
4361 ===================================================================
4362 --- hardened/2.6/tags/2.6.25-14/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch (rev 0)
4363 +++ hardened/2.6/tags/2.6.25-14/1424_atm-cve-2008-5079-duplicate-listen-on-socket-corrupts-the-vcc-table.patch 2009-01-21 00:09:46 UTC (rev 1481)
4364 @@ -0,0 +1,45 @@
4365 +Added-By: Gordon Malm <gengor@g.o>
4366 +
4367 +---
4368 +
4369 +From 17b24b3c97498935a2ef9777370b1151dfed3f6f Mon Sep 17 00:00:00 2001
4370 +From: Chas Williams <chas@××××××××××××.mil>
4371 +Date: Thu, 4 Dec 2008 14:58:13 -0800
4372 +Subject: ATM: CVE-2008-5079: duplicate listen() on socket corrupts the vcc table
4373 +
4374 +From: Chas Williams <chas@××××××××××××.mil>
4375 +
4376 +commit 17b24b3c97498935a2ef9777370b1151dfed3f6f upstream.
4377 +
4378 +As reported by Hugo Dias that it is possible to cause a local denial
4379 +of service attack by calling the svc_listen function twice on the same
4380 +socket and reading /proc/net/atm/*vc
4381 +
4382 +Signed-off-by: Chas Williams <chas@××××××××××××.mil>
4383 +Signed-off-by: David S. Miller <davem@×××××××××.net>
4384 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4385 +
4386 +---
4387 +
4388 +--- a/net/atm/svc.c
4389 ++++ b/net/atm/svc.c
4390 +@@ -293,7 +293,10 @@ static int svc_listen(struct socket *soc
4391 + error = -EINVAL;
4392 + goto out;
4393 + }
4394 +- vcc_insert_socket(sk);
4395 ++ if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
4396 ++ error = -EADDRINUSE;
4397 ++ goto out;
4398 ++ }
4399 + set_bit(ATM_VF_WAITING, &vcc->flags);
4400 + prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
4401 + sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
4402 +@@ -307,6 +310,7 @@ static int svc_listen(struct socket *soc
4403 + goto out;
4404 + }
4405 + set_bit(ATM_VF_LISTEN,&vcc->flags);
4406 ++ vcc_insert_socket(sk);
4407 + sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
4408 + error = -sk->sk_err;
4409 + out:
4410
4411 Added: hardened/2.6/tags/2.6.25-14/1425_enforce-a-minimum-sg_io-timeout.patch
4412 ===================================================================
4413 --- hardened/2.6/tags/2.6.25-14/1425_enforce-a-minimum-sg_io-timeout.patch (rev 0)
4414 +++ hardened/2.6/tags/2.6.25-14/1425_enforce-a-minimum-sg_io-timeout.patch 2009-01-21 00:09:46 UTC (rev 1481)
4415 @@ -0,0 +1,64 @@
4416 +Added-By: Gordon Malm <gengor@g.o>
4417 +
4418 +---
4419 +
4420 +From f2f1fa78a155524b849edf359e42a3001ea652c0 Mon Sep 17 00:00:00 2001
4421 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
4422 +Date: Fri, 5 Dec 2008 14:49:18 -0800
4423 +Subject: Enforce a minimum SG_IO timeout
4424 +
4425 +From: Linus Torvalds <torvalds@××××××××××××××××.org>
4426 +
4427 +commit f2f1fa78a155524b849edf359e42a3001ea652c0 upstream.
4428 +
4429 +There's no point in having too short SG_IO timeouts, since if the
4430 +command does end up timing out, we'll end up through the reset sequence
4431 +that is several seconds long in order to abort the command that timed
4432 +out.
4433 +
4434 +As a result, shorter timeouts than a few seconds simply do not make
4435 +sense, as the recovery would be longer than the timeout itself.
4436 +
4437 +Add a BLK_MIN_SG_TIMEOUT to match the existign BLK_DEFAULT_SG_TIMEOUT.
4438 +
4439 +Suggested-by: Alan Cox <alan@××××××××××××××××.uk>
4440 +Acked-by: Tejun Heo <tj@××××××.org>
4441 +Acked-by: Jens Axboe <jens.axboe@××××××.com>
4442 +Cc: Jeff Garzik <jeff@××××××.org>
4443 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4444 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4445 +
4446 +---
4447 +
4448 +--- a/block/bsg.c
4449 ++++ b/block/bsg.c
4450 +@@ -202,6 +202,8 @@ static int blk_fill_sgv4_hdr_rq(struct r
4451 + rq->timeout = q->sg_timeout;
4452 + if (!rq->timeout)
4453 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
4454 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
4455 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
4456 +
4457 + return 0;
4458 + }
4459 +--- a/block/scsi_ioctl.c
4460 ++++ b/block/scsi_ioctl.c
4461 +@@ -208,6 +208,8 @@ static int blk_fill_sghdr_rq(struct requ
4462 + rq->timeout = q->sg_timeout;
4463 + if (!rq->timeout)
4464 + rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
4465 ++ if (rq->timeout < BLK_MIN_SG_TIMEOUT)
4466 ++ rq->timeout = BLK_MIN_SG_TIMEOUT;
4467 +
4468 + return 0;
4469 + }
4470 +--- a/include/linux/blkdev.h
4471 ++++ b/include/linux/blkdev.h
4472 +@@ -623,6 +623,7 @@ extern unsigned long blk_max_low_pfn, bl
4473 + * default timeout for SG_IO if none specified
4474 + */
4475 + #define BLK_DEFAULT_SG_TIMEOUT (60 * HZ)
4476 ++#define BLK_MIN_SG_TIMEOUT (7 * HZ)
4477 +
4478 + #ifdef CONFIG_BOUNCE
4479 + extern int init_emergency_isa_pool(void);
4480
4481 Added: hardened/2.6/tags/2.6.25-14/1503_hfsplus-check-read_mapping_page-return-value.patch
4482 ===================================================================
4483 --- hardened/2.6/tags/2.6.25-14/1503_hfsplus-check-read_mapping_page-return-value.patch (rev 0)
4484 +++ hardened/2.6/tags/2.6.25-14/1503_hfsplus-check-read_mapping_page-return-value.patch 2009-01-21 00:09:46 UTC (rev 1481)
4485 @@ -0,0 +1,110 @@
4486 +Added-By: Gordon Malm <gengor@g.o>
4487 +
4488 +---
4489 +
4490 +From 649f1ee6c705aab644035a7998d7b574193a598a Mon Sep 17 00:00:00 2001
4491 +From: Eric Sesterhenn <snakebyte@×××.de>
4492 +Date: Wed, 15 Oct 2008 22:04:10 -0700
4493 +Subject: hfsplus: check read_mapping_page() return value
4494 +
4495 +From: Eric Sesterhenn <snakebyte@×××.de>
4496 +
4497 +While testing more corrupted images with hfsplus, i came across
4498 +one which triggered the following bug:
4499 +
4500 +[15840.675016] BUG: unable to handle kernel paging request at fffffffb
4501 +[15840.675016] IP: [<c0116a4f>] kmap+0x15/0x56
4502 +[15840.675016] *pde = 00008067 *pte = 00000000
4503 +[15840.675016] Oops: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
4504 +[15840.675016] Modules linked in:
4505 +[15840.675016]
4506 +[15840.675016] Pid: 11575, comm: ln Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #29)
4507 +[15840.675016] EIP: 0060:[<c0116a4f>] EFLAGS: 00010202 CPU: 0
4508 +[15840.675016] EIP is at kmap+0x15/0x56
4509 +[15840.675016] EAX: 00000246 EBX: fffffffb ECX: 00000000 EDX: cab919c0
4510 +[15840.675016] ESI: 000007dd EDI: cab0bcf4 EBP: cab0bc98 ESP: cab0bc94
4511 +[15840.675016] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
4512 +[15840.675016] Process ln (pid: 11575, ti=cab0b000 task=cab919c0 task.ti=cab0b000)
4513 +[15840.675016] Stack: 00000000 cab0bcdc c0231cfb 00000000 cab0bce0 00000800 ca9290c0 fffffffb
4514 +[15840.675016] cab145d0 cab919c0 cab15998 22222222 22222222 22222222 00000001 cab15960
4515 +[15840.675016] 000007dd cab0bcf4 cab0bd04 c022cb3a cab0bcf4 cab15a6c ca9290c0 00000000
4516 +[15840.675016] Call Trace:
4517 +[15840.675016] [<c0231cfb>] ? hfsplus_block_allocate+0x6f/0x2d3
4518 +[15840.675016] [<c022cb3a>] ? hfsplus_file_extend+0xc4/0x1db
4519 +[15840.675016] [<c022ce41>] ? hfsplus_get_block+0x8c/0x19d
4520 +[15840.675016] [<c06adde4>] ? sub_preempt_count+0x9d/0xab
4521 +[15840.675016] [<c019ece6>] ? __block_prepare_write+0x147/0x311
4522 +[15840.675016] [<c0161934>] ? __grab_cache_page+0x52/0x73
4523 +[15840.675016] [<c019ef4f>] ? block_write_begin+0x79/0xd5
4524 +[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
4525 +[15840.675016] [<c019f22a>] ? cont_write_begin+0x27f/0x2af
4526 +[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
4527 +[15840.675016] [<c0139ebe>] ? tick_program_event+0x28/0x4c
4528 +[15840.675016] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4529 +[15840.675016] [<c022b723>] ? hfsplus_write_begin+0x2d/0x32
4530 +[15840.675016] [<c022cdb5>] ? hfsplus_get_block+0x0/0x19d
4531 +[15840.675016] [<c0161988>] ? pagecache_write_begin+0x33/0x107
4532 +[15840.675016] [<c01879e5>] ? __page_symlink+0x3c/0xae
4533 +[15840.675016] [<c019ad34>] ? __mark_inode_dirty+0x12f/0x137
4534 +[15840.675016] [<c0187a70>] ? page_symlink+0x19/0x1e
4535 +[15840.675016] [<c022e6eb>] ? hfsplus_symlink+0x41/0xa6
4536 +[15840.675016] [<c01886a9>] ? vfs_symlink+0x99/0x101
4537 +[15840.675016] [<c018a2f6>] ? sys_symlinkat+0x6b/0xad
4538 +[15840.675016] [<c018a348>] ? sys_symlink+0x10/0x12
4539 +[15840.675016] [<c01038bd>] ? sysenter_do_call+0x12/0x31
4540 +[15840.675016] =======================
4541 +[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
4542 +[15840.675016] EIP: [<c0116a4f>] kmap+0x15/0x56 SS:ESP 0068:cab0bc94
4543 +[15840.675016] ---[ end trace 4fea40dad6b70e5f ]---
4544 +
4545 +This happens because the return value of read_mapping_page() is passed on
4546 +to kmap unchecked. The bug is triggered after the first
4547 +read_mapping_page() in hfsplus_block_allocate(), this patch fixes all
4548 +three usages in this functions but leaves the ones further down in the
4549 +file unchanged.
4550 +
4551 +Signed-off-by: Eric Sesterhenn <snakebyte@×××.de>
4552 +Cc: Roman Zippel <zippel@××××××××××.org>
4553 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
4554 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4555 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4556 +
4557 +---
4558 + fs/hfsplus/bitmap.c | 12 ++++++++++++
4559 + 1 file changed, 12 insertions(+)
4560 +
4561 +--- a/fs/hfsplus/bitmap.c
4562 ++++ b/fs/hfsplus/bitmap.c
4563 +@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_
4564 + mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
4565 + mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
4566 + page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
4567 ++ if (IS_ERR(page)) {
4568 ++ start = size;
4569 ++ goto out;
4570 ++ }
4571 + pptr = kmap(page);
4572 + curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
4573 + i = offset % 32;
4574 +@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_
4575 + break;
4576 + page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
4577 + NULL);
4578 ++ if (IS_ERR(page)) {
4579 ++ start = size;
4580 ++ goto out;
4581 ++ }
4582 + curr = pptr = kmap(page);
4583 + if ((size ^ offset) / PAGE_CACHE_BITS)
4584 + end = pptr + PAGE_CACHE_BITS / 32;
4585 +@@ -120,6 +128,10 @@ found:
4586 + offset += PAGE_CACHE_BITS;
4587 + page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
4588 + NULL);
4589 ++ if (IS_ERR(page)) {
4590 ++ start = size;
4591 ++ goto out;
4592 ++ }
4593 + pptr = kmap(page);
4594 + curr = pptr;
4595 + end = pptr + PAGE_CACHE_BITS / 32;
4596
4597 Added: hardened/2.6/tags/2.6.25-14/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch
4598 ===================================================================
4599 --- hardened/2.6/tags/2.6.25-14/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch (rev 0)
4600 +++ hardened/2.6/tags/2.6.25-14/1504_hfsplus-fix-buffer-overflow-with-a-corrupted-image.patch 2009-01-21 00:09:46 UTC (rev 1481)
4601 @@ -0,0 +1,129 @@
4602 +Added-By: Gordon Malm <gengor@g.o>
4603 +
4604 +---
4605 +
4606 +From efc7ffcb4237f8cb9938909041c4ed38f6e1bf40 Mon Sep 17 00:00:00 2001
4607 +From: Eric Sesterhenn <snakebyte@×××.de>
4608 +Date: Wed, 15 Oct 2008 22:04:08 -0700
4609 +Subject: hfsplus: fix Buffer overflow with a corrupted image
4610 +
4611 +From: Eric Sesterhenn <snakebyte@×××.de>
4612 +
4613 +commit efc7ffcb4237f8cb9938909041c4ed38f6e1bf40 upstream
4614 +
4615 +When an hfsplus image gets corrupted it might happen that the catalog
4616 +namelength field gets b0rked. If we mount such an image the memcpy() in
4617 +hfsplus_cat_build_key_uni() writes more than the 255 that fit in the name
4618 +field. Depending on the size of the overwritten data, we either only get
4619 +memory corruption or also trigger an oops like this:
4620 +
4621 +[ 221.628020] BUG: unable to handle kernel paging request at c82b0000
4622 +[ 221.629066] IP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151
4623 +[ 221.629066] *pde = 0ea29163 *pte = 082b0160
4624 +[ 221.629066] Oops: 0002 [#1] PREEMPT DEBUG_PAGEALLOC
4625 +[ 221.629066] Modules linked in:
4626 +[ 221.629066]
4627 +[ 221.629066] Pid: 4845, comm: mount Not tainted (2.6.27-rc4-00123-gd3ee1b4-dirty #28)
4628 +[ 221.629066] EIP: 0060:[<c022d4b1>] EFLAGS: 00010206 CPU: 0
4629 +[ 221.629066] EIP is at hfsplus_find_cat+0x10d/0x151
4630 +[ 221.629066] EAX: 00000029 EBX: 00016210 ECX: 000042c2 EDX: 00000002
4631 +[ 221.629066] ESI: c82d70ca EDI: c82b0000 EBP: c82d1bcc ESP: c82d199c
4632 +[ 221.629066] DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
4633 +[ 221.629066] Process mount (pid: 4845, ti=c82d1000 task=c8224060 task.ti=c82d1000)
4634 +[ 221.629066] Stack: c080b3c4 c82aa8f8 c82d19c2 00016210 c080b3be c82d1bd4 c82aa8f0 00000300
4635 +[ 221.629066] 01000000 750008b1 74006e00 74006900 65006c00 c82d6400 c013bd35 c8224060
4636 +[ 221.629066] 00000036 00000046 c82d19f0 00000082 c8224548 c8224060 00000036 c0d653cc
4637 +[ 221.629066] Call Trace:
4638 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4639 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4640 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4641 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4642 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4643 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4644 +[ 221.629066] [<c01302d2>] ? __kernel_text_address+0x1b/0x27
4645 +[ 221.629066] [<c010487a>] ? dump_trace+0xca/0xd6
4646 +[ 221.629066] [<c0109e32>] ? save_stack_address+0x0/0x2c
4647 +[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
4648 +[ 221.629066] [<c013b571>] ? save_trace+0x37/0x8d
4649 +[ 221.629066] [<c013b62e>] ? add_lock_to_list+0x67/0x8d
4650 +[ 221.629066] [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
4651 +[ 221.629066] [<c013553d>] ? down+0xc/0x2f
4652 +[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
4653 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4654 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4655 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4656 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4657 +[ 221.629066] [<c013da5d>] ? mark_held_locks+0x43/0x5a
4658 +[ 221.629066] [<c013dc3a>] ? trace_hardirqs_on+0xb/0xd
4659 +[ 221.629066] [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
4660 +[ 221.629066] [<c06abec8>] ? _spin_unlock_irqrestore+0x42/0x58
4661 +[ 221.629066] [<c013555c>] ? down+0x2b/0x2f
4662 +[ 221.629066] [<c022aa68>] ? hfsplus_iget+0xa0/0x154
4663 +[ 221.629066] [<c022b0b9>] ? hfsplus_fill_super+0x280/0x447
4664 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4665 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4666 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4667 +[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
4668 +[ 221.629066] [<c041c9e4>] ? string+0x2b/0x74
4669 +[ 221.629066] [<c041cd16>] ? vsnprintf+0x2e9/0x512
4670 +[ 221.629066] [<c010487a>] ? dump_trace+0xca/0xd6
4671 +[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
4672 +[ 221.629066] [<c0109eaf>] ? save_stack_trace+0x1c/0x3a
4673 +[ 221.629066] [<c013b571>] ? save_trace+0x37/0x8d
4674 +[ 221.629066] [<c013b62e>] ? add_lock_to_list+0x67/0x8d
4675 +[ 221.629066] [<c013ea1c>] ? validate_chain+0x8a4/0x9f4
4676 +[ 221.629066] [<c01354d3>] ? up+0xc/0x2f
4677 +[ 221.629066] [<c013f1f6>] ? __lock_acquire+0x68a/0x6e0
4678 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4679 +[ 221.629066] [<c013bca3>] ? trace_hardirqs_off_caller+0x14/0x9b
4680 +[ 221.629066] [<c013bd35>] ? trace_hardirqs_off+0xb/0xd
4681 +[ 221.629066] [<c0107aa3>] ? native_sched_clock+0x82/0x96
4682 +[ 221.629066] [<c041cfb7>] ? snprintf+0x1b/0x1d
4683 +[ 221.629066] [<c01ba466>] ? disk_name+0x25/0x67
4684 +[ 221.629066] [<c0183960>] ? get_sb_bdev+0xcd/0x10b
4685 +[ 221.629066] [<c016ad92>] ? kstrdup+0x2a/0x4c
4686 +[ 221.629066] [<c022a7b3>] ? hfsplus_get_sb+0x13/0x15
4687 +[ 221.629066] [<c022ae39>] ? hfsplus_fill_super+0x0/0x447
4688 +[ 221.629066] [<c0183583>] ? vfs_kern_mount+0x3b/0x76
4689 +[ 221.629066] [<c0183602>] ? do_kern_mount+0x32/0xba
4690 +[ 221.629066] [<c01960d4>] ? do_new_mount+0x46/0x74
4691 +[ 221.629066] [<c0196277>] ? do_mount+0x175/0x193
4692 +[ 221.629066] [<c013dbf4>] ? trace_hardirqs_on_caller+0xf4/0x12f
4693 +[ 221.629066] [<c01663b2>] ? __get_free_pages+0x1e/0x24
4694 +[ 221.629066] [<c06ac07b>] ? lock_kernel+0x19/0x8c
4695 +[ 221.629066] [<c01962e6>] ? sys_mount+0x51/0x9b
4696 +[ 221.629066] [<c01962f9>] ? sys_mount+0x64/0x9b
4697 +[ 221.629066] [<c01038bd>] ? sysenter_do_call+0x12/0x31
4698 +[ 221.629066] =======================
4699 +[ 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
4700 +[ 221.629066] EIP: [<c022d4b1>] hfsplus_find_cat+0x10d/0x151 SS:ESP 0068:c82d199c
4701 +[ 221.629066] ---[ end trace e417a1d67f0d0066 ]---
4702 +
4703 +Since hfsplus_cat_build_key_uni() returns void and only has one callsite,
4704 +the check is performed at the callsite.
4705 +
4706 +Signed-off-by: Eric Sesterhenn <snakebyte@×××.de>
4707 +Reviewed-by: Pekka Enberg <penberg@×××××××××××.fi>
4708 +Cc: Roman Zippel <zippel@××××××××××.org>
4709 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
4710 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4711 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4712 +
4713 +---
4714 + fs/hfsplus/catalog.c | 5 +++++
4715 + 1 file changed, 5 insertions(+)
4716 +
4717 +--- a/fs/hfsplus/catalog.c
4718 ++++ b/fs/hfsplus/catalog.c
4719 +@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block
4720 + return -EIO;
4721 + }
4722 +
4723 ++ if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
4724 ++ printk(KERN_ERR "hfs: catalog name length corrupted\n");
4725 ++ return -EIO;
4726 ++ }
4727 ++
4728 + hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
4729 + &tmp.thread.nodeName);
4730 + return hfs_brec_find(fd);
4731
4732 Added: hardened/2.6/tags/2.6.25-14/1505_hfs-fix-namelength-memory-corruption.patch
4733 ===================================================================
4734 --- hardened/2.6/tags/2.6.25-14/1505_hfs-fix-namelength-memory-corruption.patch (rev 0)
4735 +++ hardened/2.6/tags/2.6.25-14/1505_hfs-fix-namelength-memory-corruption.patch 2009-01-21 00:09:46 UTC (rev 1481)
4736 @@ -0,0 +1,41 @@
4737 +Added-By: Gordon Malm <gengor@g.o>
4738 +
4739 +---
4740 +
4741 +From d38b7aa7fc3371b52d036748028db50b585ade2e Mon Sep 17 00:00:00 2001
4742 +From: Eric Sesterhenn <snakebyte@×××.de>
4743 +Date: Wed, 15 Oct 2008 22:04:11 -0700
4744 +Subject: hfs: fix namelength memory corruption (CVE-2008-5025)
4745 +
4746 +From: Eric Sesterhenn <snakebyte@×××.de>
4747 +
4748 +commit d38b7aa7fc3371b52d036748028db50b585ade2e upstream
4749 +
4750 +Fix a stack corruption caused by a corrupted hfs filesystem. If the
4751 +catalog name length is corrupted the memcpy overwrites the catalog btree
4752 +structure. Since the field is limited to HFS_NAMELEN bytes in the
4753 +structure and the file format, we throw an error if it is too long.
4754 +
4755 +Cc: Roman Zippel <zippel@××××××××××.org>
4756 +Signed-off-by: Eric Sesterhenn <snakebyte@×××.de>
4757 +Signed-off-by: Andrew Morton <akpm@××××××××××××××××.org>
4758 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4759 +Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de>
4760 +
4761 +---
4762 + fs/hfs/catalog.c | 4 ++++
4763 + 1 file changed, 4 insertions(+)
4764 +
4765 +--- a/fs/hfs/catalog.c
4766 ++++ b/fs/hfs/catalog.c
4767 +@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block
4768 +
4769 + fd->search_key->cat.ParID = rec.thread.ParID;
4770 + len = fd->search_key->cat.CName.len = rec.thread.CName.len;
4771 ++ if (len > HFS_NAMELEN) {
4772 ++ printk(KERN_ERR "hfs: bad catalog namelength\n");
4773 ++ return -EIO;
4774 ++ }
4775 + memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
4776 + return hfs_brec_find(fd);
4777 + }
4778
4779 Added: hardened/2.6/tags/2.6.25-14/1506_inotify-fix-watch-removal-or-umount-races.patch
4780 ===================================================================
4781 --- hardened/2.6/tags/2.6.25-14/1506_inotify-fix-watch-removal-or-umount-races.patch (rev 0)
4782 +++ hardened/2.6/tags/2.6.25-14/1506_inotify-fix-watch-removal-or-umount-races.patch 2009-01-21 00:09:46 UTC (rev 1481)
4783 @@ -0,0 +1,565 @@
4784 +Added-By: Gordon Malm <gengor@g.o>
4785 +
4786 +Note: Modified slightly to eliminate patch fuzz.
4787 +
4788 +---
4789 +
4790 +From: Al Viro <viro@×××××××××××××××.uk>
4791 +Date: Sat, 15 Nov 2008 01:15:43 +0000 (+0000)
4792 +Subject: Fix inotify watch removal/umount races
4793 +X-Git-Tag: v2.6.28-rc5~1
4794 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=8f7b0ba1c853919b85b54774775f567f30006107
4795 +
4796 +Fix inotify watch removal/umount races
4797 +
4798 +Inotify watch removals suck violently.
4799 +
4800 +To kick the watch out we need (in this order) inode->inotify_mutex and
4801 +ih->mutex. That's fine if we have a hold on inode; however, for all
4802 +other cases we need to make damn sure we don't race with umount. We can
4803 +*NOT* just grab a reference to a watch - inotify_unmount_inodes() will
4804 +happily sail past it and we'll end with reference to inode potentially
4805 +outliving its superblock.
4806 +
4807 +Ideally we just want to grab an active reference to superblock if we
4808 +can; that will make sure we won't go into inotify_umount_inodes() until
4809 +we are done. Cleanup is just deactivate_super().
4810 +
4811 +However, that leaves a messy case - what if we *are* racing with
4812 +umount() and active references to superblock can't be acquired anymore?
4813 +We can bump ->s_count, grab ->s_umount, which will almost certainly wait
4814 +until the superblock is shut down and the watch in question is pining
4815 +for fjords. That's fine, but there is a problem - we might have hit the
4816 +window between ->s_active getting to 0 / ->s_count - below S_BIAS (i.e.
4817 +the moment when superblock is past the point of no return and is heading
4818 +for shutdown) and the moment when deactivate_super() acquires
4819 +->s_umount.
4820 +
4821 +We could just do drop_super() yield() and retry, but that's rather
4822 +antisocial and this stuff is luser-triggerable. OTOH, having grabbed
4823 +->s_umount and having found that we'd got there first (i.e. that
4824 +->s_root is non-NULL) we know that we won't race with
4825 +inotify_umount_inodes().
4826 +
4827 +So we could grab a reference to watch and do the rest as above, just
4828 +with drop_super() instead of deactivate_super(), right? Wrong. We had
4829 +to drop ih->mutex before we could grab ->s_umount. So the watch
4830 +could've been gone already.
4831 +
4832 +That still can be dealt with - we need to save watch->wd, do idr_find()
4833 +and compare its result with our pointer. If they match, we either have
4834 +the damn thing still alive or we'd lost not one but two races at once,
4835 +the watch had been killed and a new one got created with the same ->wd
4836 +at the same address. That couldn't have happened in inotify_destroy(),
4837 +but inotify_rm_wd() could run into that. Still, "new one got created"
4838 +is not a problem - we have every right to kill it or leave it alone,
4839 +whatever's more convenient.
4840 +
4841 +So we can use idr_find(...) == watch && watch->inode->i_sb == sb as
4842 +"grab it and kill it" check. If it's been our original watch, we are
4843 +fine, if it's a newcomer - nevermind, just pretend that we'd won the
4844 +race and kill the fscker anyway; we are safe since we know that its
4845 +superblock won't be going away.
4846 +
4847 +And yes, this is far beyond mere "not very pretty"; so's the entire
4848 +concept of inotify to start with.
4849 +
4850 +Signed-off-by: Al Viro <viro@×××××××××××××××.uk>
4851 +Acked-by: Greg KH <greg@×××××.com>
4852 +Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org>
4853 +---
4854 +
4855 +--- a/fs/inotify.c
4856 ++++ b/fs/inotify.c
4857 +@@ -106,6 +106,20 @@ void get_inotify_watch(struct inotify_wa
4858 + }
4859 + EXPORT_SYMBOL_GPL(get_inotify_watch);
4860 +
4861 ++int pin_inotify_watch(struct inotify_watch *watch)
4862 ++{
4863 ++ struct super_block *sb = watch->inode->i_sb;
4864 ++ spin_lock(&sb_lock);
4865 ++ if (sb->s_count >= S_BIAS) {
4866 ++ atomic_inc(&sb->s_active);
4867 ++ spin_unlock(&sb_lock);
4868 ++ atomic_inc(&watch->count);
4869 ++ return 1;
4870 ++ }
4871 ++ spin_unlock(&sb_lock);
4872 ++ return 0;
4873 ++}
4874 ++
4875 + /**
4876 + * put_inotify_watch - decrements the ref count on a given watch. cleans up
4877 + * watch references if the count reaches zero. inotify_watch is freed by
4878 +@@ -124,6 +138,13 @@ void put_inotify_watch(struct inotify_wa
4879 + }
4880 + EXPORT_SYMBOL_GPL(put_inotify_watch);
4881 +
4882 ++void unpin_inotify_watch(struct inotify_watch *watch)
4883 ++{
4884 ++ struct super_block *sb = watch->inode->i_sb;
4885 ++ put_inotify_watch(watch);
4886 ++ deactivate_super(sb);
4887 ++}
4888 ++
4889 + /*
4890 + * inotify_handle_get_wd - returns the next WD for use by the given handle
4891 + *
4892 +@@ -479,6 +500,112 @@ void inotify_init_watch(struct inotify_w
4893 + }
4894 + EXPORT_SYMBOL_GPL(inotify_init_watch);
4895 +
4896 ++/*
4897 ++ * Watch removals suck violently. To kick the watch out we need (in this
4898 ++ * order) inode->inotify_mutex and ih->mutex. That's fine if we have
4899 ++ * a hold on inode; however, for all other cases we need to make damn sure
4900 ++ * we don't race with umount. We can *NOT* just grab a reference to a
4901 ++ * watch - inotify_unmount_inodes() will happily sail past it and we'll end
4902 ++ * with reference to inode potentially outliving its superblock. Ideally
4903 ++ * we just want to grab an active reference to superblock if we can; that
4904 ++ * will make sure we won't go into inotify_umount_inodes() until we are
4905 ++ * done. Cleanup is just deactivate_super(). However, that leaves a messy
4906 ++ * case - what if we *are* racing with umount() and active references to
4907 ++ * superblock can't be acquired anymore? We can bump ->s_count, grab
4908 ++ * ->s_umount, which will almost certainly wait until the superblock is shut
4909 ++ * down and the watch in question is pining for fjords. That's fine, but
4910 ++ * there is a problem - we might have hit the window between ->s_active
4911 ++ * getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock
4912 ++ * is past the point of no return and is heading for shutdown) and the
4913 ++ * moment when deactivate_super() acquires ->s_umount. We could just do
4914 ++ * drop_super() yield() and retry, but that's rather antisocial and this
4915 ++ * stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having
4916 ++ * found that we'd got there first (i.e. that ->s_root is non-NULL) we know
4917 ++ * that we won't race with inotify_umount_inodes(). So we could grab a
4918 ++ * reference to watch and do the rest as above, just with drop_super() instead
4919 ++ * of deactivate_super(), right? Wrong. We had to drop ih->mutex before we
4920 ++ * could grab ->s_umount. So the watch could've been gone already.
4921 ++ *
4922 ++ * That still can be dealt with - we need to save watch->wd, do idr_find()
4923 ++ * and compare its result with our pointer. If they match, we either have
4924 ++ * the damn thing still alive or we'd lost not one but two races at once,
4925 ++ * the watch had been killed and a new one got created with the same ->wd
4926 ++ * at the same address. That couldn't have happened in inotify_destroy(),
4927 ++ * but inotify_rm_wd() could run into that. Still, "new one got created"
4928 ++ * is not a problem - we have every right to kill it or leave it alone,
4929 ++ * whatever's more convenient.
4930 ++ *
4931 ++ * So we can use idr_find(...) == watch && watch->inode->i_sb == sb as
4932 ++ * "grab it and kill it" check. If it's been our original watch, we are
4933 ++ * fine, if it's a newcomer - nevermind, just pretend that we'd won the
4934 ++ * race and kill the fscker anyway; we are safe since we know that its
4935 ++ * superblock won't be going away.
4936 ++ *
4937 ++ * And yes, this is far beyond mere "not very pretty"; so's the entire
4938 ++ * concept of inotify to start with.
4939 ++ */
4940 ++
4941 ++/**
4942 ++ * pin_to_kill - pin the watch down for removal
4943 ++ * @ih: inotify handle
4944 ++ * @watch: watch to kill
4945 ++ *
4946 ++ * Called with ih->mutex held, drops it. Possible return values:
4947 ++ * 0 - nothing to do, it has died
4948 ++ * 1 - remove it, drop the reference and deactivate_super()
4949 ++ * 2 - remove it, drop the reference and drop_super(); we tried hard to avoid
4950 ++ * that variant, since it involved a lot of PITA, but that's the best that
4951 ++ * could've been done.
4952 ++ */
4953 ++static int pin_to_kill(struct inotify_handle *ih, struct inotify_watch *watch)
4954 ++{
4955 ++ struct super_block *sb = watch->inode->i_sb;
4956 ++ s32 wd = watch->wd;
4957 ++
4958 ++ spin_lock(&sb_lock);
4959 ++ if (sb->s_count >= S_BIAS) {
4960 ++ atomic_inc(&sb->s_active);
4961 ++ spin_unlock(&sb_lock);
4962 ++ get_inotify_watch(watch);
4963 ++ mutex_unlock(&ih->mutex);
4964 ++ return 1; /* the best outcome */
4965 ++ }
4966 ++ sb->s_count++;
4967 ++ spin_unlock(&sb_lock);
4968 ++ mutex_unlock(&ih->mutex); /* can't grab ->s_umount under it */
4969 ++ down_read(&sb->s_umount);
4970 ++ if (likely(!sb->s_root)) {
4971 ++ /* fs is already shut down; the watch is dead */
4972 ++ drop_super(sb);
4973 ++ return 0;
4974 ++ }
4975 ++ /* raced with the final deactivate_super() */
4976 ++ mutex_lock(&ih->mutex);
4977 ++ if (idr_find(&ih->idr, wd) != watch || watch->inode->i_sb != sb) {
4978 ++ /* the watch is dead */
4979 ++ mutex_unlock(&ih->mutex);
4980 ++ drop_super(sb);
4981 ++ return 0;
4982 ++ }
4983 ++ /* still alive or freed and reused with the same sb and wd; kill */
4984 ++ get_inotify_watch(watch);
4985 ++ mutex_unlock(&ih->mutex);
4986 ++ return 2;
4987 ++}
4988 ++
4989 ++static void unpin_and_kill(struct inotify_watch *watch, int how)
4990 ++{
4991 ++ struct super_block *sb = watch->inode->i_sb;
4992 ++ put_inotify_watch(watch);
4993 ++ switch (how) {
4994 ++ case 1:
4995 ++ deactivate_super(sb);
4996 ++ break;
4997 ++ case 2:
4998 ++ drop_super(sb);
4999 ++ }
5000 ++}
5001 ++
5002 + /**
5003 + * inotify_destroy - clean up and destroy an inotify instance
5004 + * @ih: inotify handle
5005 +@@ -490,11 +617,15 @@ void inotify_destroy(struct inotify_hand
5006 + * pretty. We cannot do a simple iteration over the list, because we
5007 + * do not know the inode until we iterate to the watch. But we need to
5008 + * hold inode->inotify_mutex before ih->mutex. The following works.
5009 ++ *
5010 ++ * AV: it had to become even uglier to start working ;-/
5011 + */
5012 + while (1) {
5013 + struct inotify_watch *watch;
5014 + struct list_head *watches;
5015 ++ struct super_block *sb;
5016 + struct inode *inode;
5017 ++ int how;
5018 +
5019 + mutex_lock(&ih->mutex);
5020 + watches = &ih->watches;
5021 +@@ -503,8 +634,10 @@ void inotify_destroy(struct inotify_hand
5022 + break;
5023 + }
5024 + watch = list_first_entry(watches, struct inotify_watch, h_list);
5025 +- get_inotify_watch(watch);
5026 +- mutex_unlock(&ih->mutex);
5027 ++ sb = watch->inode->i_sb;
5028 ++ how = pin_to_kill(ih, watch);
5029 ++ if (!how)
5030 ++ continue;
5031 +
5032 + inode = watch->inode;
5033 + mutex_lock(&inode->inotify_mutex);
5034 +@@ -518,7 +651,7 @@ void inotify_destroy(struct inotify_hand
5035 +
5036 + mutex_unlock(&ih->mutex);
5037 + mutex_unlock(&inode->inotify_mutex);
5038 +- put_inotify_watch(watch);
5039 ++ unpin_and_kill(watch, how);
5040 + }
5041 +
5042 + /* free this handle: the put matching the get in inotify_init() */
5043 +@@ -719,7 +852,9 @@ void inotify_evict_watch(struct inotify_
5044 + int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
5045 + {
5046 + struct inotify_watch *watch;
5047 ++ struct super_block *sb;
5048 + struct inode *inode;
5049 ++ int how;
5050 +
5051 + mutex_lock(&ih->mutex);
5052 + watch = idr_find(&ih->idr, wd);
5053 +@@ -727,9 +862,12 @@ int inotify_rm_wd(struct inotify_handle
5054 + mutex_unlock(&ih->mutex);
5055 + return -EINVAL;
5056 + }
5057 +- get_inotify_watch(watch);
5058 ++ sb = watch->inode->i_sb;
5059 ++ how = pin_to_kill(ih, watch);
5060 ++ if (!how)
5061 ++ return 0;
5062 ++
5063 + inode = watch->inode;
5064 +- mutex_unlock(&ih->mutex);
5065 +
5066 + mutex_lock(&inode->inotify_mutex);
5067 + mutex_lock(&ih->mutex);
5068 +@@ -740,7 +878,7 @@ int inotify_rm_wd(struct inotify_handle
5069 +
5070 + mutex_unlock(&ih->mutex);
5071 + mutex_unlock(&inode->inotify_mutex);
5072 +- put_inotify_watch(watch);
5073 ++ unpin_and_kill(watch, how);
5074 +
5075 + return 0;
5076 + }
5077 +--- a/include/linux/inotify.h
5078 ++++ b/include/linux/inotify.h
5079 +@@ -128,6 +128,8 @@ extern void inotify_remove_watch_locked(
5080 + struct inotify_watch *);
5081 + extern void get_inotify_watch(struct inotify_watch *);
5082 + extern void put_inotify_watch(struct inotify_watch *);
5083 ++extern int pin_inotify_watch(struct inotify_watch *);
5084 ++extern void unpin_inotify_watch(struct inotify_watch *);
5085 +
5086 + #else
5087 +
5088 +@@ -222,6 +224,15 @@ static inline void put_inotify_watch(str
5089 + {
5090 + }
5091 +
5092 ++extern inline int pin_inotify_watch(struct inotify_watch *watch)
5093 ++{
5094 ++ return 0;
5095 ++}
5096 ++
5097 ++extern inline void unpin_inotify_watch(struct inotify_watch *watch)
5098 ++{
5099 ++}
5100 ++
5101 + #endif /* CONFIG_INOTIFY */
5102 +
5103 + #endif /* __KERNEL __ */
5104 +--- a/kernel/audit_tree.c
5105 ++++ b/kernel/audit_tree.c
5106 +@@ -24,6 +24,7 @@ struct audit_chunk {
5107 + struct list_head trees; /* with root here */
5108 + int dead;
5109 + int count;
5110 ++ atomic_long_t refs;
5111 + struct rcu_head head;
5112 + struct node {
5113 + struct list_head list;
5114 +@@ -56,7 +57,8 @@ static LIST_HEAD(prune_list);
5115 + * tree is refcounted; one reference for "some rules on rules_list refer to
5116 + * it", one for each chunk with pointer to it.
5117 + *
5118 +- * chunk is refcounted by embedded inotify_watch.
5119 ++ * chunk is refcounted by embedded inotify_watch + .refs (non-zero refcount
5120 ++ * of watch contributes 1 to .refs).
5121 + *
5122 + * node.index allows to get from node.list to containing chunk.
5123 + * MSB of that sucker is stolen to mark taggings that we might have to
5124 +@@ -121,6 +123,7 @@ static struct audit_chunk *alloc_chunk(i
5125 + INIT_LIST_HEAD(&chunk->hash);
5126 + INIT_LIST_HEAD(&chunk->trees);
5127 + chunk->count = count;
5128 ++ atomic_long_set(&chunk->refs, 1);
5129 + for (i = 0; i < count; i++) {
5130 + INIT_LIST_HEAD(&chunk->owners[i].list);
5131 + chunk->owners[i].index = i;
5132 +@@ -129,9 +132,8 @@ static struct audit_chunk *alloc_chunk(i
5133 + return chunk;
5134 + }
5135 +
5136 +-static void __free_chunk(struct rcu_head *rcu)
5137 ++static void free_chunk(struct audit_chunk *chunk)
5138 + {
5139 +- struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
5140 + int i;
5141 +
5142 + for (i = 0; i < chunk->count; i++) {
5143 +@@ -141,14 +143,16 @@ static void __free_chunk(struct rcu_head
5144 + kfree(chunk);
5145 + }
5146 +
5147 +-static inline void free_chunk(struct audit_chunk *chunk)
5148 ++void audit_put_chunk(struct audit_chunk *chunk)
5149 + {
5150 +- call_rcu(&chunk->head, __free_chunk);
5151 ++ if (atomic_long_dec_and_test(&chunk->refs))
5152 ++ free_chunk(chunk);
5153 + }
5154 +
5155 +-void audit_put_chunk(struct audit_chunk *chunk)
5156 ++static void __put_chunk(struct rcu_head *rcu)
5157 + {
5158 +- put_inotify_watch(&chunk->watch);
5159 ++ struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
5160 ++ audit_put_chunk(chunk);
5161 + }
5162 +
5163 + enum {HASH_SIZE = 128};
5164 +@@ -177,7 +181,7 @@ struct audit_chunk *audit_tree_lookup(co
5165 + list_for_each_rcu(pos, list) {
5166 + struct audit_chunk *p = container_of(pos, struct audit_chunk, hash);
5167 + if (p->watch.inode == inode) {
5168 +- get_inotify_watch(&p->watch);
5169 ++ atomic_long_inc(&p->refs);
5170 + return p;
5171 + }
5172 + }
5173 +@@ -195,17 +199,49 @@ int audit_tree_match(struct audit_chunk
5174 +
5175 + /* tagging and untagging inodes with trees */
5176 +
5177 +-static void untag_chunk(struct audit_chunk *chunk, struct node *p)
5178 ++static struct audit_chunk *find_chunk(struct node *p)
5179 ++{
5180 ++ int index = p->index & ~(1U<<31);
5181 ++ p -= index;
5182 ++ return container_of(p, struct audit_chunk, owners[0]);
5183 ++}
5184 ++
5185 ++static void untag_chunk(struct node *p)
5186 + {
5187 ++ struct audit_chunk *chunk = find_chunk(p);
5188 + struct audit_chunk *new;
5189 + struct audit_tree *owner;
5190 + int size = chunk->count - 1;
5191 + int i, j;
5192 +
5193 ++ if (!pin_inotify_watch(&chunk->watch)) {
5194 ++ /*
5195 ++ * Filesystem is shutting down; all watches are getting
5196 ++ * evicted, just take it off the node list for this
5197 ++ * tree and let the eviction logics take care of the
5198 ++ * rest.
5199 ++ */
5200 ++ owner = p->owner;
5201 ++ if (owner->root == chunk) {
5202 ++ list_del_init(&owner->same_root);
5203 ++ owner->root = NULL;
5204 ++ }
5205 ++ list_del_init(&p->list);
5206 ++ p->owner = NULL;
5207 ++ put_tree(owner);
5208 ++ return;
5209 ++ }
5210 ++
5211 ++ spin_unlock(&hash_lock);
5212 ++
5213 ++ /*
5214 ++ * pin_inotify_watch() succeeded, so the watch won't go away
5215 ++ * from under us.
5216 ++ */
5217 + mutex_lock(&chunk->watch.inode->inotify_mutex);
5218 + if (chunk->dead) {
5219 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5220 +- return;
5221 ++ goto out;
5222 + }
5223 +
5224 + owner = p->owner;
5225 +@@ -222,7 +258,7 @@ static void untag_chunk(struct audit_chu
5226 + inotify_evict_watch(&chunk->watch);
5227 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5228 + put_inotify_watch(&chunk->watch);
5229 +- return;
5230 ++ goto out;
5231 + }
5232 +
5233 + new = alloc_chunk(size);
5234 +@@ -264,7 +300,7 @@ static void untag_chunk(struct audit_chu
5235 + inotify_evict_watch(&chunk->watch);
5236 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5237 + put_inotify_watch(&chunk->watch);
5238 +- return;
5239 ++ goto out;
5240 +
5241 + Fallback:
5242 + // do the best we can
5243 +@@ -278,6 +314,9 @@ Fallback:
5244 + put_tree(owner);
5245 + spin_unlock(&hash_lock);
5246 + mutex_unlock(&chunk->watch.inode->inotify_mutex);
5247 ++out:
5248 ++ unpin_inotify_watch(&chunk->watch);
5249 ++ spin_lock(&hash_lock);
5250 + }
5251 +
5252 + static int create_chunk(struct inode *inode, struct audit_tree *tree)
5253 +@@ -388,13 +427,6 @@ static int tag_chunk(struct inode *inode
5254 + return 0;
5255 + }
5256 +
5257 +-static struct audit_chunk *find_chunk(struct node *p)
5258 +-{
5259 +- int index = p->index & ~(1U<<31);
5260 +- p -= index;
5261 +- return container_of(p, struct audit_chunk, owners[0]);
5262 +-}
5263 +-
5264 + static void kill_rules(struct audit_tree *tree)
5265 + {
5266 + struct audit_krule *rule, *next;
5267 +@@ -432,17 +464,10 @@ static void prune_one(struct audit_tree
5268 + spin_lock(&hash_lock);
5269 + while (!list_empty(&victim->chunks)) {
5270 + struct node *p;
5271 +- struct audit_chunk *chunk;
5272 +
5273 + p = list_entry(victim->chunks.next, struct node, list);
5274 +- chunk = find_chunk(p);
5275 +- get_inotify_watch(&chunk->watch);
5276 +- spin_unlock(&hash_lock);
5277 +-
5278 +- untag_chunk(chunk, p);
5279 +
5280 +- put_inotify_watch(&chunk->watch);
5281 +- spin_lock(&hash_lock);
5282 ++ untag_chunk(p);
5283 + }
5284 + spin_unlock(&hash_lock);
5285 + put_tree(victim);
5286 +@@ -470,7 +495,6 @@ static void trim_marked(struct audit_tre
5287 +
5288 + while (!list_empty(&tree->chunks)) {
5289 + struct node *node;
5290 +- struct audit_chunk *chunk;
5291 +
5292 + node = list_entry(tree->chunks.next, struct node, list);
5293 +
5294 +@@ -478,14 +502,7 @@ static void trim_marked(struct audit_tre
5295 + if (!(node->index & (1U<<31)))
5296 + break;
5297 +
5298 +- chunk = find_chunk(node);
5299 +- get_inotify_watch(&chunk->watch);
5300 +- spin_unlock(&hash_lock);
5301 +-
5302 +- untag_chunk(chunk, node);
5303 +-
5304 +- put_inotify_watch(&chunk->watch);
5305 +- spin_lock(&hash_lock);
5306 ++ untag_chunk(node);
5307 + }
5308 + if (!tree->root && !tree->goner) {
5309 + tree->goner = 1;
5310 +@@ -879,7 +896,7 @@ static void handle_event(struct inotify_
5311 + static void destroy_watch(struct inotify_watch *watch)
5312 + {
5313 + struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
5314 +- free_chunk(chunk);
5315 ++ call_rcu(&chunk->head, __put_chunk);
5316 + }
5317 +
5318 + static const struct inotify_operations rtree_inotify_ops = {
5319 +--- a/kernel/auditfilter.c
5320 ++++ b/kernel/auditfilter.c
5321 +@@ -1085,8 +1085,8 @@ static void audit_inotify_unregister(str
5322 + list_for_each_entry_safe(p, n, in_list, ilist) {
5323 + list_del(&p->ilist);
5324 + inotify_rm_watch(audit_ih, &p->wdata);
5325 +- /* the put matching the get in audit_do_del_rule() */
5326 +- put_inotify_watch(&p->wdata);
5327 ++ /* the unpin matching the pin in audit_do_del_rule() */
5328 ++ unpin_inotify_watch(&p->wdata);
5329 + }
5330 + }
5331 +
5332 +@@ -1380,9 +1380,13 @@ static inline int audit_del_rule(struct
5333 + /* Put parent on the inotify un-registration
5334 + * list. Grab a reference before releasing
5335 + * audit_filter_mutex, to be released in
5336 +- * audit_inotify_unregister(). */
5337 +- list_add(&parent->ilist, &inotify_list);
5338 +- get_inotify_watch(&parent->wdata);
5339 ++ * audit_inotify_unregister().
5340 ++ * If filesystem is going away, just leave
5341 ++ * the sucker alone, eviction will take
5342 ++ * care of it.
5343 ++ */
5344 ++ if (pin_inotify_watch(&parent->wdata))
5345 ++ list_add(&parent->ilist, &inotify_list);
5346 + }
5347 + }
5348 + }
5349
5350 Added: hardened/2.6/tags/2.6.25-14/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch
5351 ===================================================================
5352 --- hardened/2.6/tags/2.6.25-14/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch (rev 0)
5353 +++ hardened/2.6/tags/2.6.25-14/1507_sctp-avoid_memory_overflow_with_bad_stream_ID.patch 2009-01-21 00:09:46 UTC (rev 1481)
5354 @@ -0,0 +1,80 @@
5355 +Added-By: Gordon Malm <gengor@g.o>
5356 +
5357 +Note: Re-diffed to eliminate failed hunks.
5358 +
5359 +---
5360 +
5361 +From: Wei Yongjun <yjwei@××××××××××.com>
5362 +Date: Fri, 26 Dec 2008 00:58:11 +0000 (-0800)
5363 +Subject: sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
5364 +X-Git-Tag: v2.6.29-rc1~581^2~75
5365 +X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9fcb95a105758b81ef0131cd18e2db5149f13e95
5366 +
5367 +sctp: Avoid memory overflow while FWD-TSN chunk is received with bad stream ID
5368 +
5369 +If FWD-TSN chunk is received with bad stream ID, the sctp will not do the
5370 +validity check, this may cause memory overflow when overwrite the TSN of
5371 +the stream ID.
5372 +
5373 +The FORWARD-TSN chunk is like this:
5374 +
5375 +FORWARD-TSN chunk
5376 + Type = 192
5377 + Flags = 0
5378 + Length = 172
5379 + NewTSN = 99
5380 + Stream = 10000
5381 + StreamSequence = 0xFFFF
5382 +
5383 +This patch fix this problem by discard the chunk if stream ID is not
5384 +less than MIS.
5385 +
5386 +Signed-off-by: Wei Yongjun <yjwei@××××××××××.com>
5387 +Signed-off-by: Vlad Yasevich <vladislav.yasevich@××.com>
5388 +Signed-off-by: David S. Miller <davem@×××××××××.net>
5389 +---
5390 +
5391 +--- a/net/sctp/sm_statefuns.c
5392 ++++ b/net/sctp/sm_statefuns.c
5393 +@@ -3641,6 +3641,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
5394 + {
5395 + struct sctp_chunk *chunk = arg;
5396 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
5397 ++ struct sctp_fwdtsn_skip *skip;
5398 + __u16 len;
5399 + __u32 tsn;
5400 +
5401 +@@ -3670,6 +3671,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(c
5402 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
5403 + goto discard_noforce;
5404 +
5405 ++ /* Silently discard the chunk if stream-id is not valid */
5406 ++ sctp_walk_fwdtsn(skip, chunk) {
5407 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
5408 ++ goto discard_noforce;
5409 ++ }
5410 ++
5411 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
5412 + if (len > sizeof(struct sctp_fwdtsn_hdr))
5413 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
5414 +@@ -3701,6 +3708,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
5415 + {
5416 + struct sctp_chunk *chunk = arg;
5417 + struct sctp_fwdtsn_hdr *fwdtsn_hdr;
5418 ++ struct sctp_fwdtsn_skip *skip;
5419 + __u16 len;
5420 + __u32 tsn;
5421 +
5422 +@@ -3730,6 +3738,12 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_f
5423 + if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
5424 + goto gen_shutdown;
5425 +
5426 ++ /* Silently discard the chunk if stream-id is not valid */
5427 ++ sctp_walk_fwdtsn(skip, chunk) {
5428 ++ if (ntohs(skip->stream) >= asoc->c.sinit_max_instreams)
5429 ++ goto gen_shutdown;
5430 ++ }
5431 ++
5432 + sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
5433 + if (len > sizeof(struct sctp_fwdtsn_hdr))
5434 + sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
5435
5436 Added: hardened/2.6/tags/2.6.25-14/1800_sched-disable-hrtick.patch
5437 ===================================================================
5438 --- hardened/2.6/tags/2.6.25-14/1800_sched-disable-hrtick.patch (rev 0)
5439 +++ hardened/2.6/tags/2.6.25-14/1800_sched-disable-hrtick.patch 2009-01-21 00:09:46 UTC (rev 1481)
5440 @@ -0,0 +1,17 @@
5441 +From: Kerin Millar <kerframil@×××××.com>
5442 +
5443 +This is a backport to 2.6.25 of commit 612f39d5e7baeb0518cfe50d53e37e14c0ca1475
5444 +from Ingo Molnar, which disables hrtick (high-resolution preemption ticks). For
5445 +further information, please refer to Gentoo Bug #247453.
5446 +
5447 +--- a/kernel/sched.c 2008-04-17 03:49:44.000000000 +0100
5448 ++++ b/kernel/sched.c 2008-11-18 20:30:33.000000000 +0000
5449 +@@ -602,7 +602,7 @@
5450 + SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 |
5451 + SCHED_FEAT_WAKEUP_PREEMPT * 1 |
5452 + SCHED_FEAT_START_DEBIT * 1 |
5453 +- SCHED_FEAT_HRTICK * 1 |
5454 ++ SCHED_FEAT_HRTICK * 0 |
5455 + SCHED_FEAT_DOUBLE_TICK * 0;
5456 +
5457 + #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x)
5458
5459 Added: hardened/2.6/tags/2.6.25-14/4420_grsec-2.1.12-2.6.25.16-200808201644.patch
5460 ===================================================================
5461 --- hardened/2.6/tags/2.6.25-14/4420_grsec-2.1.12-2.6.25.16-200808201644.patch (rev 0)
5462 +++ hardened/2.6/tags/2.6.25-14/4420_grsec-2.1.12-2.6.25.16-200808201644.patch 2009-01-21 00:09:46 UTC (rev 1481)
5463 @@ -0,0 +1,35914 @@
5464 +diff -urNp a/Documentation/dontdiff b/Documentation/dontdiff
5465 +--- a/Documentation/dontdiff 2008-08-20 11:16:13.000000000 -0700
5466 ++++ b/Documentation/dontdiff 2008-08-20 18:36:57.000000000 -0700
5467 +@@ -3,6 +3,7 @@
5468 + *.bin
5469 + *.cpio
5470 + *.css
5471 ++*.dbg
5472 + *.dvi
5473 + *.eps
5474 + *.gif
5475 +@@ -55,6 +56,7 @@ ChangeSet
5476 + Image
5477 + Kerntypes
5478 + MODS.txt
5479 ++Module.markers
5480 + Module.symvers
5481 + PENDING
5482 + SCCS
5483 +@@ -89,6 +91,7 @@ config_data.gz*
5484 + conmakehash
5485 + consolemap_deftbl.c*
5486 + crc32table.h*
5487 ++cpustr.h
5488 + cscope.*
5489 + defkeymap.c*
5490 + devlist.h*
5491 +@@ -137,11 +140,13 @@ miboot*
5492 + mk_elfconfig
5493 + mkboot
5494 + mkbugboot
5495 ++mkcpustr
5496 + mkdep
5497 + mkprep
5498 + mktables
5499 + mktree
5500 + modpost
5501 ++modules.order
5502 + modversions.h*
5503 + offset.h
5504 + offsets.h
5505 +@@ -172,20 +177,24 @@ sm_tbl*
5506 + split-include
5507 + tags
5508 + tftpboot.img
5509 ++timeconst.h
5510 + times.h*
5511 + tkparse
5512 + trix_boot.h
5513 + utsrelease.h*
5514 +-vdso.lds
5515 ++vdso*.lds
5516 + version.h*
5517 + vmlinux
5518 + vmlinux-*
5519 + vmlinux.aout
5520 +-vmlinux*.lds*
5521 ++vmlinux.bin.all
5522 ++vmlinux*.lds
5523 ++vmlinux.relocs
5524 + vmlinux*.scr
5525 +-vsyscall.lds
5526 ++vsyscall*.lds
5527 + wanxlfw.inc
5528 + uImage
5529 + unifdef
5530 ++utsrelease.h
5531 + zImage*
5532 + zconf.hash.c
5533 +diff -urNp a/Makefile b/Makefile
5534 +--- a/Makefile 2008-08-20 11:16:13.000000000 -0700
5535 ++++ b/Makefile 2008-08-20 18:36:57.000000000 -0700
5536 +@@ -214,7 +214,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
5537 +
5538 + HOSTCC = gcc
5539 + HOSTCXX = g++
5540 +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
5541 ++HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
5542 + HOSTCXXFLAGS = -O2
5543 +
5544 + # Decide whether to build built-in, modular, or both.
5545 +@@ -603,7 +603,7 @@ export mod_strip_cmd
5546 +
5547 +
5548 + ifeq ($(KBUILD_EXTMOD),)
5549 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
5550 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
5551 +
5552 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
5553 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
5554 +diff -urNp a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c
5555 +--- a/arch/alpha/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
5556 ++++ b/arch/alpha/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
5557 +@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
5558 +
5559 + /* The small sections were sorted to the end of the segment.
5560 + The following should definitely cover them. */
5561 +- gp = (u64)me->module_core + me->core_size - 0x8000;
5562 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
5563 + got = sechdrs[me->arch.gotsecindex].sh_addr;
5564 +
5565 + for (i = 0; i < n; i++) {
5566 +diff -urNp a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
5567 +--- a/arch/alpha/kernel/osf_sys.c 2008-08-20 11:16:13.000000000 -0700
5568 ++++ b/arch/alpha/kernel/osf_sys.c 2008-08-20 18:36:57.000000000 -0700
5569 +@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
5570 + merely specific addresses, but regions of memory -- perhaps
5571 + this feature should be incorporated into all ports? */
5572 +
5573 ++#ifdef CONFIG_PAX_RANDMMAP
5574 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5575 ++#endif
5576 ++
5577 + if (addr) {
5578 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
5579 + if (addr != (unsigned long) -ENOMEM)
5580 +@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
5581 + }
5582 +
5583 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
5584 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
5585 +- len, limit);
5586 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
5587 ++
5588 + if (addr != (unsigned long) -ENOMEM)
5589 + return addr;
5590 +
5591 +diff -urNp a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
5592 +--- a/arch/alpha/kernel/ptrace.c 2008-08-20 11:16:13.000000000 -0700
5593 ++++ b/arch/alpha/kernel/ptrace.c 2008-08-20 18:36:57.000000000 -0700
5594 +@@ -15,6 +15,7 @@
5595 + #include <linux/slab.h>
5596 + #include <linux/security.h>
5597 + #include <linux/signal.h>
5598 ++#include <linux/grsecurity.h>
5599 +
5600 + #include <asm/uaccess.h>
5601 + #include <asm/pgtable.h>
5602 +@@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
5603 + size_t copied;
5604 + long ret;
5605 +
5606 ++ if (gr_handle_ptrace(child, request))
5607 ++ return -EPERM;
5608 ++
5609 + switch (request) {
5610 + /* When I and D space are separate, these will need to be fixed. */
5611 + case PTRACE_PEEKTEXT: /* read word at location addr. */
5612 +diff -urNp a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
5613 +--- a/arch/alpha/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
5614 ++++ b/arch/alpha/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
5615 +@@ -23,6 +23,7 @@
5616 + #include <linux/smp.h>
5617 + #include <linux/interrupt.h>
5618 + #include <linux/module.h>
5619 ++#include <linux/binfmts.h>
5620 +
5621 + #include <asm/system.h>
5622 + #include <asm/uaccess.h>
5623 +@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
5624 + __reload_thread(pcb);
5625 + }
5626 +
5627 ++#ifdef CONFIG_PAX_PAGEEXEC
5628 ++/*
5629 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
5630 ++ *
5631 ++ * returns 1 when task should be killed
5632 ++ * 2 when patched PLT trampoline was detected
5633 ++ * 3 when unpatched PLT trampoline was detected
5634 ++ */
5635 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
5636 ++{
5637 ++
5638 ++#ifdef CONFIG_PAX_EMUPLT
5639 ++ int err;
5640 ++
5641 ++ do { /* PaX: patched PLT emulation #1 */
5642 ++ unsigned int ldah, ldq, jmp;
5643 ++
5644 ++ err = get_user(ldah, (unsigned int *)regs->pc);
5645 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
5646 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
5647 ++
5648 ++ if (err)
5649 ++ break;
5650 ++
5651 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
5652 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
5653 ++ jmp == 0x6BFB0000U)
5654 ++ {
5655 ++ unsigned long r27, addr;
5656 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
5657 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
5658 ++
5659 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
5660 ++ err = get_user(r27, (unsigned long *)addr);
5661 ++ if (err)
5662 ++ break;
5663 ++
5664 ++ regs->r27 = r27;
5665 ++ regs->pc = r27;
5666 ++ return 2;
5667 ++ }
5668 ++ } while (0);
5669 ++
5670 ++ do { /* PaX: patched PLT emulation #2 */
5671 ++ unsigned int ldah, lda, br;
5672 ++
5673 ++ err = get_user(ldah, (unsigned int *)regs->pc);
5674 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
5675 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
5676 ++
5677 ++ if (err)
5678 ++ break;
5679 ++
5680 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
5681 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
5682 ++ (br & 0xFFE00000U) == 0xC3E00000U)
5683 ++ {
5684 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
5685 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
5686 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
5687 ++
5688 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
5689 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
5690 ++ return 2;
5691 ++ }
5692 ++ } while (0);
5693 ++
5694 ++ do { /* PaX: unpatched PLT emulation */
5695 ++ unsigned int br;
5696 ++
5697 ++ err = get_user(br, (unsigned int *)regs->pc);
5698 ++
5699 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
5700 ++ unsigned int br2, ldq, nop, jmp;
5701 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
5702 ++
5703 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
5704 ++ err = get_user(br2, (unsigned int *)addr);
5705 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
5706 ++ err |= get_user(nop, (unsigned int *)(addr+8));
5707 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
5708 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
5709 ++
5710 ++ if (err)
5711 ++ break;
5712 ++
5713 ++ if (br2 == 0xC3600000U &&
5714 ++ ldq == 0xA77B000CU &&
5715 ++ nop == 0x47FF041FU &&
5716 ++ jmp == 0x6B7B0000U)
5717 ++ {
5718 ++ regs->r28 = regs->pc+4;
5719 ++ regs->r27 = addr+16;
5720 ++ regs->pc = resolver;
5721 ++ return 3;
5722 ++ }
5723 ++ }
5724 ++ } while (0);
5725 ++#endif
5726 ++
5727 ++ return 1;
5728 ++}
5729 ++
5730 ++void pax_report_insns(void *pc, void *sp)
5731 ++{
5732 ++ unsigned long i;
5733 ++
5734 ++ printk(KERN_ERR "PAX: bytes at PC: ");
5735 ++ for (i = 0; i < 5; i++) {
5736 ++ unsigned int c;
5737 ++ if (get_user(c, (unsigned int *)pc+i))
5738 ++ printk(KERN_CONT "???????? ");
5739 ++ else
5740 ++ printk(KERN_CONT "%08x ", c);
5741 ++ }
5742 ++ printk("\n");
5743 ++}
5744 ++#endif
5745 +
5746 + /*
5747 + * This routine handles page faults. It determines the address,
5748 +@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
5749 + good_area:
5750 + si_code = SEGV_ACCERR;
5751 + if (cause < 0) {
5752 +- if (!(vma->vm_flags & VM_EXEC))
5753 ++ if (!(vma->vm_flags & VM_EXEC)) {
5754 ++
5755 ++#ifdef CONFIG_PAX_PAGEEXEC
5756 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
5757 ++ goto bad_area;
5758 ++
5759 ++ up_read(&mm->mmap_sem);
5760 ++ switch (pax_handle_fetch_fault(regs)) {
5761 ++
5762 ++#ifdef CONFIG_PAX_EMUPLT
5763 ++ case 2:
5764 ++ case 3:
5765 ++ return;
5766 ++#endif
5767 ++
5768 ++ }
5769 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
5770 ++ do_group_exit(SIGKILL);
5771 ++#else
5772 + goto bad_area;
5773 ++#endif
5774 ++
5775 ++ }
5776 + } else if (!cause) {
5777 + /* Allow reads even for write-only mappings */
5778 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
5779 +diff -urNp a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
5780 +--- a/arch/arm/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
5781 ++++ b/arch/arm/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
5782 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
5783 + if (len > TASK_SIZE)
5784 + return -ENOMEM;
5785 +
5786 ++#ifdef CONFIG_PAX_RANDMMAP
5787 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5788 ++#endif
5789 ++
5790 + if (addr) {
5791 + if (do_align)
5792 + addr = COLOUR_ALIGN(addr, pgoff);
5793 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
5794 + return addr;
5795 + }
5796 + if (len > mm->cached_hole_size) {
5797 +- start_addr = addr = mm->free_area_cache;
5798 ++ start_addr = addr = mm->free_area_cache;
5799 + } else {
5800 +- start_addr = addr = TASK_UNMAPPED_BASE;
5801 +- mm->cached_hole_size = 0;
5802 ++ start_addr = addr = mm->mmap_base;
5803 ++ mm->cached_hole_size = 0;
5804 + }
5805 +
5806 + full_search:
5807 +@@ -91,8 +95,8 @@ full_search:
5808 + * Start a new search - just in case we missed
5809 + * some holes.
5810 + */
5811 +- if (start_addr != TASK_UNMAPPED_BASE) {
5812 +- start_addr = addr = TASK_UNMAPPED_BASE;
5813 ++ if (start_addr != mm->mmap_base) {
5814 ++ start_addr = addr = mm->mmap_base;
5815 + mm->cached_hole_size = 0;
5816 + goto full_search;
5817 + }
5818 +diff -urNp a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
5819 +--- a/arch/avr32/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
5820 ++++ b/arch/avr32/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
5821 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
5822 +
5823 + int exception_trace = 1;
5824 +
5825 ++#ifdef CONFIG_PAX_PAGEEXEC
5826 ++void pax_report_insns(void *pc, void *sp)
5827 ++{
5828 ++ unsigned long i;
5829 ++
5830 ++ printk(KERN_ERR "PAX: bytes at PC: ");
5831 ++ for (i = 0; i < 20; i++) {
5832 ++ unsigned char c;
5833 ++ if (get_user(c, (unsigned char *)pc+i))
5834 ++ printk(KERN_CONT "???????? ");
5835 ++ else
5836 ++ printk(KERN_CONT "%02x ", c);
5837 ++ }
5838 ++ printk("\n");
5839 ++}
5840 ++#endif
5841 ++
5842 + /*
5843 + * This routine handles page faults. It determines the address and the
5844 + * problem, and then passes it off to one of the appropriate routines.
5845 +@@ -157,6 +174,16 @@ bad_area:
5846 + up_read(&mm->mmap_sem);
5847 +
5848 + if (user_mode(regs)) {
5849 ++
5850 ++#ifdef CONFIG_PAX_PAGEEXEC
5851 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
5852 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
5853 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
5854 ++ do_group_exit(SIGKILL);
5855 ++ }
5856 ++ }
5857 ++#endif
5858 ++
5859 + if (exception_trace && printk_ratelimit())
5860 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
5861 + "sp %08lx ecr %lu\n",
5862 +diff -urNp a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
5863 +--- a/arch/ia64/ia32/binfmt_elf32.c 2008-08-20 11:16:13.000000000 -0700
5864 ++++ b/arch/ia64/ia32/binfmt_elf32.c 2008-08-20 18:36:57.000000000 -0700
5865 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
5866 +
5867 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
5868 +
5869 ++#ifdef CONFIG_PAX_ASLR
5870 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
5871 ++
5872 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
5873 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
5874 ++#endif
5875 ++
5876 + /* Ugly but avoids duplication */
5877 + #include "../../../fs/binfmt_elf.c"
5878 +
5879 +diff -urNp a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
5880 +--- a/arch/ia64/ia32/ia32priv.h 2008-08-20 11:16:13.000000000 -0700
5881 ++++ b/arch/ia64/ia32/ia32priv.h 2008-08-20 18:36:57.000000000 -0700
5882 +@@ -303,7 +303,14 @@ struct old_linux32_dirent {
5883 + #define ELF_DATA ELFDATA2LSB
5884 + #define ELF_ARCH EM_386
5885 +
5886 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
5887 ++#ifdef CONFIG_PAX_RANDUSTACK
5888 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
5889 ++#else
5890 ++#define __IA32_DELTA_STACK 0UL
5891 ++#endif
5892 ++
5893 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
5894 ++
5895 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
5896 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
5897 +
5898 +diff -urNp a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
5899 +--- a/arch/ia64/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
5900 ++++ b/arch/ia64/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
5901 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
5902 + void
5903 + module_free (struct module *mod, void *module_region)
5904 + {
5905 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
5906 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
5907 + unw_remove_unwind_table(mod->arch.init_unw_table);
5908 + mod->arch.init_unw_table = NULL;
5909 + }
5910 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
5911 + }
5912 +
5913 + static inline int
5914 ++in_init_rx (const struct module *mod, uint64_t addr)
5915 ++{
5916 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
5917 ++}
5918 ++
5919 ++static inline int
5920 ++in_init_rw (const struct module *mod, uint64_t addr)
5921 ++{
5922 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
5923 ++}
5924 ++
5925 ++static inline int
5926 + in_init (const struct module *mod, uint64_t addr)
5927 + {
5928 +- return addr - (uint64_t) mod->module_init < mod->init_size;
5929 ++ return in_init_rx(mod, addr) || in_init_rw(mod, addr);
5930 ++}
5931 ++
5932 ++static inline int
5933 ++in_core_rx (const struct module *mod, uint64_t addr)
5934 ++{
5935 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
5936 ++}
5937 ++
5938 ++static inline int
5939 ++in_core_rw (const struct module *mod, uint64_t addr)
5940 ++{
5941 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
5942 + }
5943 +
5944 + static inline int
5945 + in_core (const struct module *mod, uint64_t addr)
5946 + {
5947 +- return addr - (uint64_t) mod->module_core < mod->core_size;
5948 ++ return in_core_rx(mod, addr) || in_core_rw(mod, addr);
5949 + }
5950 +
5951 + static inline int
5952 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
5953 + break;
5954 +
5955 + case RV_BDREL:
5956 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
5957 ++ if (in_init_rx(mod, val))
5958 ++ val -= (uint64_t) mod->module_init_rx;
5959 ++ else if (in_init_rw(mod, val))
5960 ++ val -= (uint64_t) mod->module_init_rw;
5961 ++ else if (in_core_rx(mod, val))
5962 ++ val -= (uint64_t) mod->module_core_rx;
5963 ++ else if (in_core_rw(mod, val))
5964 ++ val -= (uint64_t) mod->module_core_rw;
5965 + break;
5966 +
5967 + case RV_LTV:
5968 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
5969 + * addresses have been selected...
5970 + */
5971 + uint64_t gp;
5972 +- if (mod->core_size > MAX_LTOFF)
5973 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
5974 + /*
5975 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
5976 + * at the end of the module.
5977 + */
5978 +- gp = mod->core_size - MAX_LTOFF / 2;
5979 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
5980 + else
5981 +- gp = mod->core_size / 2;
5982 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
5983 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
5984 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
5985 + mod->arch.gp = gp;
5986 + DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
5987 + }
5988 +diff -urNp a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
5989 +--- a/arch/ia64/kernel/sys_ia64.c 2008-08-20 11:16:13.000000000 -0700
5990 ++++ b/arch/ia64/kernel/sys_ia64.c 2008-08-20 18:36:57.000000000 -0700
5991 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
5992 + if (REGION_NUMBER(addr) == RGN_HPAGE)
5993 + addr = 0;
5994 + #endif
5995 ++
5996 ++#ifdef CONFIG_PAX_RANDMMAP
5997 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
5998 ++ addr = mm->free_area_cache;
5999 ++ else
6000 ++#endif
6001 ++
6002 + if (!addr)
6003 + addr = mm->free_area_cache;
6004 +
6005 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
6006 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6007 + /* At this point: (!vma || addr < vma->vm_end). */
6008 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
6009 +- if (start_addr != TASK_UNMAPPED_BASE) {
6010 ++ if (start_addr != mm->mmap_base) {
6011 + /* Start a new search --- just in case we missed some holes. */
6012 +- addr = TASK_UNMAPPED_BASE;
6013 ++ addr = mm->mmap_base;
6014 + goto full_search;
6015 + }
6016 + return -ENOMEM;
6017 +diff -urNp a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
6018 +--- a/arch/ia64/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6019 ++++ b/arch/ia64/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6020 +@@ -10,6 +10,7 @@
6021 + #include <linux/interrupt.h>
6022 + #include <linux/kprobes.h>
6023 + #include <linux/kdebug.h>
6024 ++#include <linux/binfmts.h>
6025 +
6026 + #include <asm/pgtable.h>
6027 + #include <asm/processor.h>
6028 +@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
6029 + return pte_present(pte);
6030 + }
6031 +
6032 ++#ifdef CONFIG_PAX_PAGEEXEC
6033 ++void pax_report_insns(void *pc, void *sp)
6034 ++{
6035 ++ unsigned long i;
6036 ++
6037 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6038 ++ for (i = 0; i < 8; i++) {
6039 ++ unsigned int c;
6040 ++ if (get_user(c, (unsigned int *)pc+i))
6041 ++ printk(KERN_CONT "???????? ");
6042 ++ else
6043 ++ printk(KERN_CONT "%08x ", c);
6044 ++ }
6045 ++ printk("\n");
6046 ++}
6047 ++#endif
6048 ++
6049 + void __kprobes
6050 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
6051 + {
6052 +@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
6053 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
6054 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
6055 +
6056 +- if ((vma->vm_flags & mask) != mask)
6057 ++ if ((vma->vm_flags & mask) != mask) {
6058 ++
6059 ++#ifdef CONFIG_PAX_PAGEEXEC
6060 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
6061 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
6062 ++ goto bad_area;
6063 ++
6064 ++ up_read(&mm->mmap_sem);
6065 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
6066 ++ do_group_exit(SIGKILL);
6067 ++ }
6068 ++#endif
6069 ++
6070 + goto bad_area;
6071 +
6072 ++ }
6073 ++
6074 + survive:
6075 + /*
6076 + * If for any reason at all we couldn't handle the fault, make
6077 +diff -urNp a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
6078 +--- a/arch/ia64/mm/init.c 2008-08-20 11:16:13.000000000 -0700
6079 ++++ b/arch/ia64/mm/init.c 2008-08-20 18:36:57.000000000 -0700
6080 +@@ -128,6 +128,19 @@ ia64_init_addr_space (void)
6081 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
6082 + vma->vm_end = vma->vm_start + PAGE_SIZE;
6083 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
6084 ++
6085 ++#ifdef CONFIG_PAX_PAGEEXEC
6086 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
6087 ++ vma->vm_flags &= ~VM_EXEC;
6088 ++
6089 ++#ifdef CONFIG_PAX_MPROTECT
6090 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
6091 ++ vma->vm_flags &= ~VM_MAYEXEC;
6092 ++#endif
6093 ++
6094 ++ }
6095 ++#endif
6096 ++
6097 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
6098 + down_write(&current->mm->mmap_sem);
6099 + if (insert_vm_struct(current->mm, vma)) {
6100 +diff -urNp a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c
6101 +--- a/arch/mips/kernel/binfmt_elfn32.c 2008-08-20 11:16:13.000000000 -0700
6102 ++++ b/arch/mips/kernel/binfmt_elfn32.c 2008-08-20 18:36:57.000000000 -0700
6103 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6104 + #undef ELF_ET_DYN_BASE
6105 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6106 +
6107 ++#ifdef CONFIG_PAX_ASLR
6108 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6109 ++
6110 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6111 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6112 ++#endif
6113 ++
6114 + #include <asm/processor.h>
6115 + #include <linux/module.h>
6116 + #include <linux/elfcore.h>
6117 +diff -urNp a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c
6118 +--- a/arch/mips/kernel/binfmt_elfo32.c 2008-08-20 11:16:13.000000000 -0700
6119 ++++ b/arch/mips/kernel/binfmt_elfo32.c 2008-08-20 18:36:57.000000000 -0700
6120 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6121 + #undef ELF_ET_DYN_BASE
6122 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6123 +
6124 ++#ifdef CONFIG_PAX_ASLR
6125 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6126 ++
6127 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6128 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6129 ++#endif
6130 ++
6131 + #include <asm/processor.h>
6132 + #include <linux/module.h>
6133 + #include <linux/elfcore.h>
6134 +diff -urNp a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
6135 +--- a/arch/mips/kernel/syscall.c 2008-08-20 11:16:13.000000000 -0700
6136 ++++ b/arch/mips/kernel/syscall.c 2008-08-20 18:36:57.000000000 -0700
6137 +@@ -93,6 +93,11 @@ unsigned long arch_get_unmapped_area(str
6138 + do_color_align = 0;
6139 + if (filp || (flags & MAP_SHARED))
6140 + do_color_align = 1;
6141 ++
6142 ++#ifdef CONFIG_PAX_RANDMMAP
6143 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6144 ++#endif
6145 ++
6146 + if (addr) {
6147 + if (do_color_align)
6148 + addr = COLOUR_ALIGN(addr, pgoff);
6149 +@@ -103,7 +108,7 @@ unsigned long arch_get_unmapped_area(str
6150 + (!vmm || addr + len <= vmm->vm_start))
6151 + return addr;
6152 + }
6153 +- addr = TASK_UNMAPPED_BASE;
6154 ++ addr = current->mm->mmap_base;
6155 + if (do_color_align)
6156 + addr = COLOUR_ALIGN(addr, pgoff);
6157 + else
6158 +diff -urNp a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
6159 +--- a/arch/mips/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6160 ++++ b/arch/mips/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6161 +@@ -26,6 +26,23 @@
6162 + #include <asm/ptrace.h>
6163 + #include <asm/highmem.h> /* For VMALLOC_END */
6164 +
6165 ++#ifdef CONFIG_PAX_PAGEEXEC
6166 ++void pax_report_insns(void *pc)
6167 ++{
6168 ++ unsigned long i;
6169 ++
6170 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6171 ++ for (i = 0; i < 5; i++) {
6172 ++ unsigned int c;
6173 ++ if (get_user(c, (unsigned int *)pc+i))
6174 ++ printk(KERN_CONT "???????? ");
6175 ++ else
6176 ++ printk(KERN_CONT "%08x ", c);
6177 ++ }
6178 ++ printk("\n");
6179 ++}
6180 ++#endif
6181 ++
6182 + /*
6183 + * This routine handles page faults. It determines the address,
6184 + * and the problem, and then passes it off to one of the appropriate
6185 +diff -urNp a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
6186 +--- a/arch/parisc/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
6187 ++++ b/arch/parisc/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
6188 +@@ -73,16 +73,38 @@
6189 +
6190 + /* three functions to determine where in the module core
6191 + * or init pieces the location is */
6192 ++static inline int in_init_rx(struct module *me, void *loc)
6193 ++{
6194 ++ return (loc >= me->module_init_rx &&
6195 ++ loc < (me->module_init_rx + me->init_size_rx));
6196 ++}
6197 ++
6198 ++static inline int in_init_rw(struct module *me, void *loc)
6199 ++{
6200 ++ return (loc >= me->module_init_rw &&
6201 ++ loc < (me->module_init_rw + me->init_size_rw));
6202 ++}
6203 ++
6204 + static inline int in_init(struct module *me, void *loc)
6205 + {
6206 +- return (loc >= me->module_init &&
6207 +- loc <= (me->module_init + me->init_size));
6208 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
6209 ++}
6210 ++
6211 ++static inline int in_core_rx(struct module *me, void *loc)
6212 ++{
6213 ++ return (loc >= me->module_core_rx &&
6214 ++ loc < (me->module_core_rx + me->core_size_rx));
6215 ++}
6216 ++
6217 ++static inline int in_core_rw(struct module *me, void *loc)
6218 ++{
6219 ++ return (loc >= me->module_core_rw &&
6220 ++ loc < (me->module_core_rw + me->core_size_rw));
6221 + }
6222 +
6223 + static inline int in_core(struct module *me, void *loc)
6224 + {
6225 +- return (loc >= me->module_core &&
6226 +- loc <= (me->module_core + me->core_size));
6227 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
6228 + }
6229 +
6230 + static inline int in_local(struct module *me, void *loc)
6231 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
6232 + }
6233 +
6234 + /* align things a bit */
6235 +- me->core_size = ALIGN(me->core_size, 16);
6236 +- me->arch.got_offset = me->core_size;
6237 +- me->core_size += gots * sizeof(struct got_entry);
6238 +-
6239 +- me->core_size = ALIGN(me->core_size, 16);
6240 +- me->arch.fdesc_offset = me->core_size;
6241 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
6242 +-
6243 +- me->core_size = ALIGN(me->core_size, 16);
6244 +- me->arch.stub_offset = me->core_size;
6245 +- me->core_size += stubs * sizeof(struct stub_entry);
6246 +-
6247 +- me->init_size = ALIGN(me->init_size, 16);
6248 +- me->arch.init_stub_offset = me->init_size;
6249 +- me->init_size += init_stubs * sizeof(struct stub_entry);
6250 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
6251 ++ me->arch.got_offset = me->core_size_rw;
6252 ++ me->core_size_rw += gots * sizeof(struct got_entry);
6253 ++
6254 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
6255 ++ me->arch.fdesc_offset = me->core_size_rw;
6256 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
6257 ++
6258 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
6259 ++ me->arch.stub_offset = me->core_size_rx;
6260 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
6261 ++
6262 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
6263 ++ me->arch.init_stub_offset = me->init_size_rx;
6264 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
6265 +
6266 + me->arch.got_max = gots;
6267 + me->arch.fdesc_max = fdescs;
6268 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
6269 +
6270 + BUG_ON(value == 0);
6271 +
6272 +- got = me->module_core + me->arch.got_offset;
6273 ++ got = me->module_core_rw + me->arch.got_offset;
6274 + for (i = 0; got[i].addr; i++)
6275 + if (got[i].addr == value)
6276 + goto out;
6277 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
6278 + #ifdef CONFIG_64BIT
6279 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
6280 + {
6281 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
6282 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
6283 +
6284 + if (!value) {
6285 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
6286 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
6287 +
6288 + /* Create new one */
6289 + fdesc->addr = value;
6290 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6291 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6292 + return (Elf_Addr)fdesc;
6293 + }
6294 + #endif /* CONFIG_64BIT */
6295 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
6296 + if(init_section) {
6297 + i = me->arch.init_stub_count++;
6298 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
6299 +- stub = me->module_init + me->arch.init_stub_offset +
6300 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
6301 + i * sizeof(struct stub_entry);
6302 + } else {
6303 + i = me->arch.stub_count++;
6304 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
6305 +- stub = me->module_core + me->arch.stub_offset +
6306 ++ stub = me->module_core_rx + me->arch.stub_offset +
6307 + i * sizeof(struct stub_entry);
6308 + }
6309 +
6310 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
6311 +
6312 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
6313 + end = table + sechdrs[me->arch.unwind_section].sh_size;
6314 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6315 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6316 +
6317 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
6318 + me->arch.unwind_section, table, end, gp);
6319 +diff -urNp a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
6320 +--- a/arch/parisc/kernel/sys_parisc.c 2008-08-20 11:16:13.000000000 -0700
6321 ++++ b/arch/parisc/kernel/sys_parisc.c 2008-08-20 18:36:57.000000000 -0700
6322 +@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
6323 + if (flags & MAP_FIXED)
6324 + return addr;
6325 + if (!addr)
6326 +- addr = TASK_UNMAPPED_BASE;
6327 ++ addr = current->mm->mmap_base;
6328 +
6329 + if (filp) {
6330 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
6331 +diff -urNp a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
6332 +--- a/arch/parisc/kernel/traps.c 2008-08-20 11:16:13.000000000 -0700
6333 ++++ b/arch/parisc/kernel/traps.c 2008-08-20 18:36:57.000000000 -0700
6334 +@@ -732,9 +732,7 @@ void handle_interruption(int code, struc
6335 +
6336 + down_read(&current->mm->mmap_sem);
6337 + vma = find_vma(current->mm,regs->iaoq[0]);
6338 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
6339 +- && (vma->vm_flags & VM_EXEC)) {
6340 +-
6341 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
6342 + fault_address = regs->iaoq[0];
6343 + fault_space = regs->iasq[0];
6344 +
6345 +diff -urNp a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
6346 +--- a/arch/parisc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6347 ++++ b/arch/parisc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6348 +@@ -16,6 +16,8 @@
6349 + #include <linux/sched.h>
6350 + #include <linux/interrupt.h>
6351 + #include <linux/module.h>
6352 ++#include <linux/unistd.h>
6353 ++#include <linux/binfmts.h>
6354 +
6355 + #include <asm/uaccess.h>
6356 + #include <asm/traps.h>
6357 +@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
6358 + static unsigned long
6359 + parisc_acctyp(unsigned long code, unsigned int inst)
6360 + {
6361 +- if (code == 6 || code == 16)
6362 ++ if (code == 6 || code == 7 || code == 16)
6363 + return VM_EXEC;
6364 +
6365 + switch (inst & 0xf0000000) {
6366 +@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
6367 + }
6368 + #endif
6369 +
6370 ++#ifdef CONFIG_PAX_PAGEEXEC
6371 ++/*
6372 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
6373 ++ *
6374 ++ * returns 1 when task should be killed
6375 ++ * 2 when rt_sigreturn trampoline was detected
6376 ++ * 3 when unpatched PLT trampoline was detected
6377 ++ */
6378 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
6379 ++{
6380 ++
6381 ++#ifdef CONFIG_PAX_EMUPLT
6382 ++ int err;
6383 ++
6384 ++ do { /* PaX: unpatched PLT emulation */
6385 ++ unsigned int bl, depwi;
6386 ++
6387 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
6388 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
6389 ++
6390 ++ if (err)
6391 ++ break;
6392 ++
6393 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
6394 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
6395 ++
6396 ++ err = get_user(ldw, (unsigned int *)addr);
6397 ++ err |= get_user(bv, (unsigned int *)(addr+4));
6398 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
6399 ++
6400 ++ if (err)
6401 ++ break;
6402 ++
6403 ++ if (ldw == 0x0E801096U &&
6404 ++ bv == 0xEAC0C000U &&
6405 ++ ldw2 == 0x0E881095U)
6406 ++ {
6407 ++ unsigned int resolver, map;
6408 ++
6409 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
6410 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
6411 ++ if (err)
6412 ++ break;
6413 ++
6414 ++ regs->gr[20] = instruction_pointer(regs)+8;
6415 ++ regs->gr[21] = map;
6416 ++ regs->gr[22] = resolver;
6417 ++ regs->iaoq[0] = resolver | 3UL;
6418 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
6419 ++ return 3;
6420 ++ }
6421 ++ }
6422 ++ } while (0);
6423 ++#endif
6424 ++
6425 ++#ifdef CONFIG_PAX_EMUTRAMP
6426 ++
6427 ++#ifndef CONFIG_PAX_EMUSIGRT
6428 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6429 ++ return 1;
6430 ++#endif
6431 ++
6432 ++ do { /* PaX: rt_sigreturn emulation */
6433 ++ unsigned int ldi1, ldi2, bel, nop;
6434 ++
6435 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
6436 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
6437 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
6438 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
6439 ++
6440 ++ if (err)
6441 ++ break;
6442 ++
6443 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
6444 ++ ldi2 == 0x3414015AU &&
6445 ++ bel == 0xE4008200U &&
6446 ++ nop == 0x08000240U)
6447 ++ {
6448 ++ regs->gr[25] = (ldi1 & 2) >> 1;
6449 ++ regs->gr[20] = __NR_rt_sigreturn;
6450 ++ regs->gr[31] = regs->iaoq[1] + 16;
6451 ++ regs->sr[0] = regs->iasq[1];
6452 ++ regs->iaoq[0] = 0x100UL;
6453 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
6454 ++ regs->iasq[0] = regs->sr[2];
6455 ++ regs->iasq[1] = regs->sr[2];
6456 ++ return 2;
6457 ++ }
6458 ++ } while (0);
6459 ++#endif
6460 ++
6461 ++ return 1;
6462 ++}
6463 ++
6464 ++void pax_report_insns(void *pc, void *sp)
6465 ++{
6466 ++ unsigned long i;
6467 ++
6468 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6469 ++ for (i = 0; i < 5; i++) {
6470 ++ unsigned int c;
6471 ++ if (get_user(c, (unsigned int *)pc+i))
6472 ++ printk(KERN_CONT "???????? ");
6473 ++ else
6474 ++ printk(KERN_CONT "%08x ", c);
6475 ++ }
6476 ++ printk("\n");
6477 ++}
6478 ++#endif
6479 ++
6480 + void do_page_fault(struct pt_regs *regs, unsigned long code,
6481 + unsigned long address)
6482 + {
6483 +@@ -165,8 +277,33 @@ good_area:
6484 +
6485 + acc_type = parisc_acctyp(code,regs->iir);
6486 +
6487 +- if ((vma->vm_flags & acc_type) != acc_type)
6488 ++ if ((vma->vm_flags & acc_type) != acc_type) {
6489 ++
6490 ++#ifdef CONFIG_PAX_PAGEEXEC
6491 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
6492 ++ (address & ~3UL) == instruction_pointer(regs))
6493 ++ {
6494 ++ up_read(&mm->mmap_sem);
6495 ++ switch (pax_handle_fetch_fault(regs)) {
6496 ++
6497 ++#ifdef CONFIG_PAX_EMUPLT
6498 ++ case 3:
6499 ++ return;
6500 ++#endif
6501 ++
6502 ++#ifdef CONFIG_PAX_EMUTRAMP
6503 ++ case 2:
6504 ++ return;
6505 ++#endif
6506 ++
6507 ++ }
6508 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
6509 ++ do_group_exit(SIGKILL);
6510 ++ }
6511 ++#endif
6512 ++
6513 + goto bad_area;
6514 ++ }
6515 +
6516 + /*
6517 + * If for any reason at all we couldn't handle the fault, make
6518 +diff -urNp a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
6519 +--- a/arch/powerpc/kernel/module_32.c 2008-08-20 11:16:13.000000000 -0700
6520 ++++ b/arch/powerpc/kernel/module_32.c 2008-08-20 18:36:57.000000000 -0700
6521 +@@ -175,7 +175,7 @@ int module_frob_arch_sections(Elf32_Ehdr
6522 + me->arch.core_plt_section = i;
6523 + }
6524 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
6525 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
6526 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
6527 + return -ENOEXEC;
6528 + }
6529 +
6530 +@@ -216,11 +216,16 @@ static uint32_t do_plt_call(void *locati
6531 +
6532 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
6533 + /* Init, or core PLT? */
6534 +- if (location >= mod->module_core
6535 +- && location < mod->module_core + mod->core_size)
6536 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
6537 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
6538 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
6539 +- else
6540 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
6541 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
6542 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
6543 ++ else {
6544 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
6545 ++ return ~0UL;
6546 ++ }
6547 +
6548 + /* Find this entry, or if that fails, the next avail. entry */
6549 + while (entry->jump[0]) {
6550 +diff -urNp a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
6551 +--- a/arch/powerpc/kernel/signal_32.c 2008-08-20 11:16:13.000000000 -0700
6552 ++++ b/arch/powerpc/kernel/signal_32.c 2008-08-20 18:36:57.000000000 -0700
6553 +@@ -730,7 +730,7 @@ int handle_rt_signal32(unsigned long sig
6554 + /* Save user registers on the stack */
6555 + frame = &rt_sf->uc.uc_mcontext;
6556 + addr = frame;
6557 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
6558 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
6559 + if (save_user_regs(regs, frame, 0))
6560 + goto badframe;
6561 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
6562 +diff -urNp a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
6563 +--- a/arch/powerpc/kernel/signal_64.c 2008-08-20 11:16:13.000000000 -0700
6564 ++++ b/arch/powerpc/kernel/signal_64.c 2008-08-20 18:36:57.000000000 -0700
6565 +@@ -369,7 +369,7 @@ int handle_rt_signal64(int signr, struct
6566 + current->thread.fpscr.val = 0;
6567 +
6568 + /* Set up to return from userspace. */
6569 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
6570 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
6571 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
6572 + } else {
6573 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
6574 +diff -urNp a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
6575 +--- a/arch/powerpc/kernel/vdso.c 2008-08-20 11:16:13.000000000 -0700
6576 ++++ b/arch/powerpc/kernel/vdso.c 2008-08-20 18:36:57.000000000 -0700
6577 +@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
6578 + vdso_base = VDSO32_MBASE;
6579 + #endif
6580 +
6581 +- current->mm->context.vdso_base = 0;
6582 ++ current->mm->context.vdso_base = ~0UL;
6583 +
6584 + /* vDSO has a problem and was disabled, just don't "enable" it for the
6585 + * process
6586 +@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
6587 + */
6588 + down_write(&mm->mmap_sem);
6589 + vdso_base = get_unmapped_area(NULL, vdso_base,
6590 +- vdso_pages << PAGE_SHIFT, 0, 0);
6591 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
6592 + if (IS_ERR_VALUE(vdso_base)) {
6593 + rc = vdso_base;
6594 + goto fail_mmapsem;
6595 +diff -urNp a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
6596 +--- a/arch/powerpc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
6597 ++++ b/arch/powerpc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
6598 +@@ -29,6 +29,12 @@
6599 + #include <linux/module.h>
6600 + #include <linux/kprobes.h>
6601 + #include <linux/kdebug.h>
6602 ++#include <linux/binfmts.h>
6603 ++#include <linux/slab.h>
6604 ++#include <linux/pagemap.h>
6605 ++#include <linux/compiler.h>
6606 ++#include <linux/binfmts.h>
6607 ++#include <linux/unistd.h>
6608 +
6609 + #include <asm/page.h>
6610 + #include <asm/pgtable.h>
6611 +@@ -62,6 +68,366 @@ static inline int notify_page_fault(stru
6612 + }
6613 + #endif
6614 +
6615 ++#ifdef CONFIG_PAX_EMUSIGRT
6616 ++void pax_syscall_close(struct vm_area_struct *vma)
6617 ++{
6618 ++ vma->vm_mm->call_syscall = 0UL;
6619 ++}
6620 ++
6621 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6622 ++{
6623 ++ struct page *page;
6624 ++ unsigned int *kaddr;
6625 ++
6626 ++ page = alloc_page(GFP_HIGHUSER);
6627 ++ if (!page)
6628 ++ return NOPAGE_OOM;
6629 ++
6630 ++ kaddr = kmap(page);
6631 ++ memset(kaddr, 0, PAGE_SIZE);
6632 ++ kaddr[0] = 0x44000002U; /* sc */
6633 ++ __flush_dcache_icache(kaddr);
6634 ++ kunmap(page);
6635 ++ if (type)
6636 ++ *type = VM_FAULT_MAJOR;
6637 ++ return page;
6638 ++}
6639 ++
6640 ++static struct vm_operations_struct pax_vm_ops = {
6641 ++ .close = pax_syscall_close,
6642 ++ .nopage = pax_syscall_nopage,
6643 ++};
6644 ++
6645 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6646 ++{
6647 ++ int ret;
6648 ++
6649 ++ vma->vm_mm = current->mm;
6650 ++ vma->vm_start = addr;
6651 ++ vma->vm_end = addr + PAGE_SIZE;
6652 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6653 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
6654 ++ vma->vm_ops = &pax_vm_ops;
6655 ++
6656 ++ ret = insert_vm_struct(current->mm, vma);
6657 ++ if (ret)
6658 ++ return ret;
6659 ++
6660 ++ ++current->mm->total_vm;
6661 ++ return 0;
6662 ++}
6663 ++#endif
6664 ++
6665 ++#ifdef CONFIG_PAX_PAGEEXEC
6666 ++/*
6667 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
6668 ++ *
6669 ++ * returns 1 when task should be killed
6670 ++ * 2 when patched GOT trampoline was detected
6671 ++ * 3 when patched PLT trampoline was detected
6672 ++ * 4 when unpatched PLT trampoline was detected
6673 ++ * 5 when sigreturn trampoline was detected
6674 ++ * 6 when rt_sigreturn trampoline was detected
6675 ++ */
6676 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
6677 ++{
6678 ++
6679 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6680 ++ int err;
6681 ++#endif
6682 ++
6683 ++#ifdef CONFIG_PAX_EMUPLT
6684 ++ do { /* PaX: patched GOT emulation */
6685 ++ unsigned int blrl;
6686 ++
6687 ++ err = get_user(blrl, (unsigned int *)regs->nip);
6688 ++
6689 ++ if (!err && blrl == 0x4E800021U) {
6690 ++ unsigned long temp = regs->nip;
6691 ++
6692 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
6693 ++ regs->link = temp + 4UL;
6694 ++ return 2;
6695 ++ }
6696 ++ } while (0);
6697 ++
6698 ++ do { /* PaX: patched PLT emulation #1 */
6699 ++ unsigned int b;
6700 ++
6701 ++ err = get_user(b, (unsigned int *)regs->nip);
6702 ++
6703 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
6704 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
6705 ++ return 3;
6706 ++ }
6707 ++ } while (0);
6708 ++
6709 ++ do { /* PaX: unpatched PLT emulation #1 */
6710 ++ unsigned int li, b;
6711 ++
6712 ++ err = get_user(li, (unsigned int *)regs->nip);
6713 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
6714 ++
6715 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6716 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6717 ++ unsigned long addr = b | 0xFC000000UL;
6718 ++
6719 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6720 ++ err = get_user(rlwinm, (unsigned int *)addr);
6721 ++ err |= get_user(add, (unsigned int *)(addr+4));
6722 ++ err |= get_user(li2, (unsigned int *)(addr+8));
6723 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
6724 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
6725 ++ err |= get_user(li3, (unsigned int *)(addr+20));
6726 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
6727 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
6728 ++
6729 ++ if (err)
6730 ++ break;
6731 ++
6732 ++ if (rlwinm == 0x556C083CU &&
6733 ++ add == 0x7D6C5A14U &&
6734 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
6735 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6736 ++ mtctr == 0x7D8903A6U &&
6737 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
6738 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6739 ++ bctr == 0x4E800420U)
6740 ++ {
6741 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6742 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6743 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6744 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6745 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
6746 ++ regs->nip = regs->ctr;
6747 ++ return 4;
6748 ++ }
6749 ++ }
6750 ++ } while (0);
6751 ++
6752 ++#if 0
6753 ++ do { /* PaX: unpatched PLT emulation #2 */
6754 ++ unsigned int lis, lwzu, b, bctr;
6755 ++
6756 ++ err = get_user(lis, (unsigned int *)regs->nip);
6757 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
6758 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
6759 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
6760 ++
6761 ++ if (err)
6762 ++ break;
6763 ++
6764 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
6765 ++ (lwzu & 0xU) == 0xU &&
6766 ++ (b & 0xFC000003U) == 0x48000000U &&
6767 ++ bctr == 0x4E800420U)
6768 ++ {
6769 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6770 ++ unsigned long addr = b | 0xFC000000UL;
6771 ++
6772 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6773 ++ err = get_user(addis, (unsigned int *)addr);
6774 ++ err |= get_user(addi, (unsigned int *)(addr+4));
6775 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
6776 ++ err |= get_user(add, (unsigned int *)(addr+12));
6777 ++ err |= get_user(li2, (unsigned int *)(addr+16));
6778 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
6779 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
6780 ++ err |= get_user(li3, (unsigned int *)(addr+28));
6781 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
6782 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
6783 ++
6784 ++ if (err)
6785 ++ break;
6786 ++
6787 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6788 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
6789 ++ rlwinm == 0x556C083CU &&
6790 ++ add == 0x7D6C5A14U &&
6791 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
6792 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6793 ++ mtctr == 0x7D8903A6U &&
6794 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
6795 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6796 ++ bctr == 0x4E800420U)
6797 ++ {
6798 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6799 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6800 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6801 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6802 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
6803 ++ regs->nip = regs->ctr;
6804 ++ return 4;
6805 ++ }
6806 ++ }
6807 ++ } while (0);
6808 ++#endif
6809 ++
6810 ++ do { /* PaX: unpatched PLT emulation #3 */
6811 ++ unsigned int li, b;
6812 ++
6813 ++ err = get_user(li, (unsigned int *)regs->nip);
6814 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
6815 ++
6816 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6817 ++ unsigned int addis, lwz, mtctr, bctr;
6818 ++ unsigned long addr = b | 0xFC000000UL;
6819 ++
6820 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6821 ++ err = get_user(addis, (unsigned int *)addr);
6822 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
6823 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
6824 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
6825 ++
6826 ++ if (err)
6827 ++ break;
6828 ++
6829 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6830 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
6831 ++ mtctr == 0x7D6903A6U &&
6832 ++ bctr == 0x4E800420U)
6833 ++ {
6834 ++ unsigned int r11;
6835 ++
6836 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6837 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6838 ++
6839 ++ err = get_user(r11, (unsigned int *)addr);
6840 ++ if (err)
6841 ++ break;
6842 ++
6843 ++ regs->gpr[PT_R11] = r11;
6844 ++ regs->ctr = r11;
6845 ++ regs->nip = r11;
6846 ++ return 4;
6847 ++ }
6848 ++ }
6849 ++ } while (0);
6850 ++#endif
6851 ++
6852 ++#ifdef CONFIG_PAX_EMUSIGRT
6853 ++ do { /* PaX: sigreturn emulation */
6854 ++ unsigned int li, sc;
6855 ++
6856 ++ err = get_user(li, (unsigned int *)regs->nip);
6857 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
6858 ++
6859 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
6860 ++ struct vm_area_struct *vma;
6861 ++ unsigned long call_syscall;
6862 ++
6863 ++ down_read(&current->mm->mmap_sem);
6864 ++ call_syscall = current->mm->call_syscall;
6865 ++ up_read(&current->mm->mmap_sem);
6866 ++ if (likely(call_syscall))
6867 ++ goto emulate;
6868 ++
6869 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
6870 ++
6871 ++ down_write(&current->mm->mmap_sem);
6872 ++ if (current->mm->call_syscall) {
6873 ++ call_syscall = current->mm->call_syscall;
6874 ++ up_write(&current->mm->mmap_sem);
6875 ++ if (vma)
6876 ++ kmem_cache_free(vm_area_cachep, vma);
6877 ++ goto emulate;
6878 ++ }
6879 ++
6880 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6881 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
6882 ++ up_write(&current->mm->mmap_sem);
6883 ++ if (vma)
6884 ++ kmem_cache_free(vm_area_cachep, vma);
6885 ++ return 1;
6886 ++ }
6887 ++
6888 ++ if (pax_insert_vma(vma, call_syscall)) {
6889 ++ up_write(&current->mm->mmap_sem);
6890 ++ kmem_cache_free(vm_area_cachep, vma);
6891 ++ return 1;
6892 ++ }
6893 ++
6894 ++ current->mm->call_syscall = call_syscall;
6895 ++ up_write(&current->mm->mmap_sem);
6896 ++
6897 ++emulate:
6898 ++ regs->gpr[PT_R0] = __NR_sigreturn;
6899 ++ regs->nip = call_syscall;
6900 ++ return 5;
6901 ++ }
6902 ++ } while (0);
6903 ++
6904 ++ do { /* PaX: rt_sigreturn emulation */
6905 ++ unsigned int li, sc;
6906 ++
6907 ++ err = get_user(li, (unsigned int *)regs->nip);
6908 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
6909 ++
6910 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6911 ++ struct vm_area_struct *vma;
6912 ++ unsigned int call_syscall;
6913 ++
6914 ++ down_read(&current->mm->mmap_sem);
6915 ++ call_syscall = current->mm->call_syscall;
6916 ++ up_read(&current->mm->mmap_sem);
6917 ++ if (likely(call_syscall))
6918 ++ goto rt_emulate;
6919 ++
6920 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
6921 ++
6922 ++ down_write(&current->mm->mmap_sem);
6923 ++ if (current->mm->call_syscall) {
6924 ++ call_syscall = current->mm->call_syscall;
6925 ++ up_write(&current->mm->mmap_sem);
6926 ++ if (vma)
6927 ++ kmem_cache_free(vm_area_cachep, vma);
6928 ++ goto rt_emulate;
6929 ++ }
6930 ++
6931 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6932 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
6933 ++ up_write(&current->mm->mmap_sem);
6934 ++ if (vma)
6935 ++ kmem_cache_free(vm_area_cachep, vma);
6936 ++ return 1;
6937 ++ }
6938 ++
6939 ++ if (pax_insert_vma(vma, call_syscall)) {
6940 ++ up_write(&current->mm->mmap_sem);
6941 ++ kmem_cache_free(vm_area_cachep, vma);
6942 ++ return 1;
6943 ++ }
6944 ++
6945 ++ current->mm->call_syscall = call_syscall;
6946 ++ up_write(&current->mm->mmap_sem);
6947 ++
6948 ++rt_emulate:
6949 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
6950 ++ regs->nip = call_syscall;
6951 ++ return 6;
6952 ++ }
6953 ++ } while (0);
6954 ++#endif
6955 ++
6956 ++ return 1;
6957 ++}
6958 ++
6959 ++void pax_report_insns(void *pc, void *sp)
6960 ++{
6961 ++ unsigned long i;
6962 ++
6963 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6964 ++ for (i = 0; i < 5; i++) {
6965 ++ unsigned int c;
6966 ++ if (get_user(c, (unsigned int *)pc+i))
6967 ++ printk(KERN_CONT "???????? ");
6968 ++ else
6969 ++ printk(KERN_CONT "%08x ", c);
6970 ++ }
6971 ++ printk("\n");
6972 ++}
6973 ++#endif
6974 ++
6975 + /*
6976 + * Check whether the instruction at regs->nip is a store using
6977 + * an update addressing form which will update r1.
6978 +@@ -157,7 +523,7 @@ int __kprobes do_page_fault(struct pt_re
6979 + * indicate errors in DSISR but can validly be set in SRR1.
6980 + */
6981 + if (trap == 0x400)
6982 +- error_code &= 0x48200000;
6983 ++ error_code &= 0x58200000;
6984 + else
6985 + is_write = error_code & DSISR_ISSTORE;
6986 + #else
6987 +@@ -355,6 +721,37 @@ bad_area:
6988 + bad_area_nosemaphore:
6989 + /* User mode accesses cause a SIGSEGV */
6990 + if (user_mode(regs)) {
6991 ++
6992 ++#ifdef CONFIG_PAX_PAGEEXEC
6993 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6994 ++#ifdef CONFIG_PPC64
6995 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
6996 ++#else
6997 ++ if (is_exec && regs->nip == address) {
6998 ++#endif
6999 ++ switch (pax_handle_fetch_fault(regs)) {
7000 ++
7001 ++#ifdef CONFIG_PAX_EMUPLT
7002 ++ case 2:
7003 ++ case 3:
7004 ++ case 4:
7005 ++ return 0;
7006 ++#endif
7007 ++
7008 ++#ifdef CONFIG_PAX_EMUSIGRT
7009 ++ case 5:
7010 ++ case 6:
7011 ++ return 0;
7012 ++#endif
7013 ++
7014 ++ }
7015 ++
7016 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
7017 ++ do_group_exit(SIGKILL);
7018 ++ }
7019 ++ }
7020 ++#endif
7021 ++
7022 + _exception(SIGSEGV, regs, code, address);
7023 + return 0;
7024 + }
7025 +diff -urNp a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
7026 +--- a/arch/powerpc/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
7027 ++++ b/arch/powerpc/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
7028 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
7029 + */
7030 + if (mmap_is_legacy()) {
7031 + mm->mmap_base = TASK_UNMAPPED_BASE;
7032 ++
7033 ++#ifdef CONFIG_PAX_RANDMMAP
7034 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7035 ++ mm->mmap_base += mm->delta_mmap;
7036 ++#endif
7037 ++
7038 + mm->get_unmapped_area = arch_get_unmapped_area;
7039 + mm->unmap_area = arch_unmap_area;
7040 + } else {
7041 + mm->mmap_base = mmap_base();
7042 ++
7043 ++#ifdef CONFIG_PAX_RANDMMAP
7044 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
7045 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7046 ++#endif
7047 ++
7048 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7049 + mm->unmap_area = arch_unmap_area_topdown;
7050 + }
7051 +diff -urNp a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
7052 +--- a/arch/ppc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
7053 ++++ b/arch/ppc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
7054 +@@ -25,6 +25,11 @@
7055 + #include <linux/interrupt.h>
7056 + #include <linux/highmem.h>
7057 + #include <linux/module.h>
7058 ++#include <linux/slab.h>
7059 ++#include <linux/pagemap.h>
7060 ++#include <linux/compiler.h>
7061 ++#include <linux/binfmts.h>
7062 ++#include <linux/unistd.h>
7063 +
7064 + #include <asm/page.h>
7065 + #include <asm/pgtable.h>
7066 +@@ -48,6 +53,366 @@ unsigned long pte_misses; /* updated by
7067 + unsigned long pte_errors; /* updated by do_page_fault() */
7068 + unsigned int probingmem;
7069 +
7070 ++#ifdef CONFIG_PAX_EMUSIGRT
7071 ++void pax_syscall_close(struct vm_area_struct *vma)
7072 ++{
7073 ++ vma->vm_mm->call_syscall = 0UL;
7074 ++}
7075 ++
7076 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7077 ++{
7078 ++ struct page *page;
7079 ++ unsigned int *kaddr;
7080 ++
7081 ++ page = alloc_page(GFP_HIGHUSER);
7082 ++ if (!page)
7083 ++ return NOPAGE_OOM;
7084 ++
7085 ++ kaddr = kmap(page);
7086 ++ memset(kaddr, 0, PAGE_SIZE);
7087 ++ kaddr[0] = 0x44000002U; /* sc */
7088 ++ __flush_dcache_icache(kaddr);
7089 ++ kunmap(page);
7090 ++ if (type)
7091 ++ *type = VM_FAULT_MAJOR;
7092 ++ return page;
7093 ++}
7094 ++
7095 ++static struct vm_operations_struct pax_vm_ops = {
7096 ++ .close = pax_syscall_close,
7097 ++ .nopage = pax_syscall_nopage,
7098 ++};
7099 ++
7100 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7101 ++{
7102 ++ int ret;
7103 ++
7104 ++ vma->vm_mm = current->mm;
7105 ++ vma->vm_start = addr;
7106 ++ vma->vm_end = addr + PAGE_SIZE;
7107 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7108 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
7109 ++ vma->vm_ops = &pax_vm_ops;
7110 ++
7111 ++ ret = insert_vm_struct(current->mm, vma);
7112 ++ if (ret)
7113 ++ return ret;
7114 ++
7115 ++ ++current->mm->total_vm;
7116 ++ return 0;
7117 ++}
7118 ++#endif
7119 ++
7120 ++#ifdef CONFIG_PAX_PAGEEXEC
7121 ++/*
7122 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
7123 ++ *
7124 ++ * returns 1 when task should be killed
7125 ++ * 2 when patched GOT trampoline was detected
7126 ++ * 3 when patched PLT trampoline was detected
7127 ++ * 4 when unpatched PLT trampoline was detected
7128 ++ * 5 when sigreturn trampoline was detected
7129 ++ * 6 when rt_sigreturn trampoline was detected
7130 ++ */
7131 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
7132 ++{
7133 ++
7134 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7135 ++ int err;
7136 ++#endif
7137 ++
7138 ++#ifdef CONFIG_PAX_EMUPLT
7139 ++ do { /* PaX: patched GOT emulation */
7140 ++ unsigned int blrl;
7141 ++
7142 ++ err = get_user(blrl, (unsigned int *)regs->nip);
7143 ++
7144 ++ if (!err && blrl == 0x4E800021U) {
7145 ++ unsigned long temp = regs->nip;
7146 ++
7147 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
7148 ++ regs->link = temp + 4UL;
7149 ++ return 2;
7150 ++ }
7151 ++ } while (0);
7152 ++
7153 ++ do { /* PaX: patched PLT emulation #1 */
7154 ++ unsigned int b;
7155 ++
7156 ++ err = get_user(b, (unsigned int *)regs->nip);
7157 ++
7158 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
7159 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
7160 ++ return 3;
7161 ++ }
7162 ++ } while (0);
7163 ++
7164 ++ do { /* PaX: unpatched PLT emulation #1 */
7165 ++ unsigned int li, b;
7166 ++
7167 ++ err = get_user(li, (unsigned int *)regs->nip);
7168 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
7169 ++
7170 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7171 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7172 ++ unsigned long addr = b | 0xFC000000UL;
7173 ++
7174 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7175 ++ err = get_user(rlwinm, (unsigned int *)addr);
7176 ++ err |= get_user(add, (unsigned int *)(addr+4));
7177 ++ err |= get_user(li2, (unsigned int *)(addr+8));
7178 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
7179 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
7180 ++ err |= get_user(li3, (unsigned int *)(addr+20));
7181 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
7182 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
7183 ++
7184 ++ if (err)
7185 ++ break;
7186 ++
7187 ++ if (rlwinm == 0x556C083CU &&
7188 ++ add == 0x7D6C5A14U &&
7189 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
7190 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7191 ++ mtctr == 0x7D8903A6U &&
7192 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
7193 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7194 ++ bctr == 0x4E800420U)
7195 ++ {
7196 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7197 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7198 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7199 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7200 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
7201 ++ regs->nip = regs->ctr;
7202 ++ return 4;
7203 ++ }
7204 ++ }
7205 ++ } while (0);
7206 ++
7207 ++#if 0
7208 ++ do { /* PaX: unpatched PLT emulation #2 */
7209 ++ unsigned int lis, lwzu, b, bctr;
7210 ++
7211 ++ err = get_user(lis, (unsigned int *)regs->nip);
7212 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
7213 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
7214 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
7215 ++
7216 ++ if (err)
7217 ++ break;
7218 ++
7219 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
7220 ++ (lwzu & 0xU) == 0xU &&
7221 ++ (b & 0xFC000003U) == 0x48000000U &&
7222 ++ bctr == 0x4E800420U)
7223 ++ {
7224 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7225 ++ unsigned long addr = b | 0xFC000000UL;
7226 ++
7227 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7228 ++ err = get_user(addis, (unsigned int *)addr);
7229 ++ err |= get_user(addi, (unsigned int *)(addr+4));
7230 ++ err |= get_user(rlwinm, (unsigned int *)(addr+8));
7231 ++ err |= get_user(add, (unsigned int *)(addr+12));
7232 ++ err |= get_user(li2, (unsigned int *)(addr+16));
7233 ++ err |= get_user(addis2, (unsigned int *)(addr+20));
7234 ++ err |= get_user(mtctr, (unsigned int *)(addr+24));
7235 ++ err |= get_user(li3, (unsigned int *)(addr+28));
7236 ++ err |= get_user(addis3, (unsigned int *)(addr+32));
7237 ++ err |= get_user(bctr, (unsigned int *)(addr+36));
7238 ++
7239 ++ if (err)
7240 ++ break;
7241 ++
7242 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7243 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
7244 ++ rlwinm == 0x556C083CU &&
7245 ++ add == 0x7D6C5A14U &&
7246 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
7247 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7248 ++ mtctr == 0x7D8903A6U &&
7249 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
7250 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7251 ++ bctr == 0x4E800420U)
7252 ++ {
7253 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7254 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7255 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7256 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7257 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
7258 ++ regs->nip = regs->ctr;
7259 ++ return 4;
7260 ++ }
7261 ++ }
7262 ++ } while (0);
7263 ++#endif
7264 ++
7265 ++ do { /* PaX: unpatched PLT emulation #3 */
7266 ++ unsigned int li, b;
7267 ++
7268 ++ err = get_user(li, (unsigned int *)regs->nip);
7269 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
7270 ++
7271 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7272 ++ unsigned int addis, lwz, mtctr, bctr;
7273 ++ unsigned long addr = b | 0xFC000000UL;
7274 ++
7275 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7276 ++ err = get_user(addis, (unsigned int *)addr);
7277 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
7278 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
7279 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
7280 ++
7281 ++ if (err)
7282 ++ break;
7283 ++
7284 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7285 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
7286 ++ mtctr == 0x7D6903A6U &&
7287 ++ bctr == 0x4E800420U)
7288 ++ {
7289 ++ unsigned int r11;
7290 ++
7291 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7292 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7293 ++
7294 ++ err = get_user(r11, (unsigned int *)addr);
7295 ++ if (err)
7296 ++ break;
7297 ++
7298 ++ regs->gpr[PT_R11] = r11;
7299 ++ regs->ctr = r11;
7300 ++ regs->nip = r11;
7301 ++ return 4;
7302 ++ }
7303 ++ }
7304 ++ } while (0);
7305 ++#endif
7306 ++
7307 ++#ifdef CONFIG_PAX_EMUSIGRT
7308 ++ do { /* PaX: sigreturn emulation */
7309 ++ unsigned int li, sc;
7310 ++
7311 ++ err = get_user(li, (unsigned int *)regs->nip);
7312 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
7313 ++
7314 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
7315 ++ struct vm_area_struct *vma;
7316 ++ unsigned long call_syscall;
7317 ++
7318 ++ down_read(&current->mm->mmap_sem);
7319 ++ call_syscall = current->mm->call_syscall;
7320 ++ up_read(&current->mm->mmap_sem);
7321 ++ if (likely(call_syscall))
7322 ++ goto emulate;
7323 ++
7324 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
7325 ++
7326 ++ down_write(&current->mm->mmap_sem);
7327 ++ if (current->mm->call_syscall) {
7328 ++ call_syscall = current->mm->call_syscall;
7329 ++ up_write(&current->mm->mmap_sem);
7330 ++ if (vma)
7331 ++ kmem_cache_free(vm_area_cachep, vma);
7332 ++ goto emulate;
7333 ++ }
7334 ++
7335 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7336 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
7337 ++ up_write(&current->mm->mmap_sem);
7338 ++ if (vma)
7339 ++ kmem_cache_free(vm_area_cachep, vma);
7340 ++ return 1;
7341 ++ }
7342 ++
7343 ++ if (pax_insert_vma(vma, call_syscall)) {
7344 ++ up_write(&current->mm->mmap_sem);
7345 ++ kmem_cache_free(vm_area_cachep, vma);
7346 ++ return 1;
7347 ++ }
7348 ++
7349 ++ current->mm->call_syscall = call_syscall;
7350 ++ up_write(&current->mm->mmap_sem);
7351 ++
7352 ++emulate:
7353 ++ regs->gpr[PT_R0] = __NR_sigreturn;
7354 ++ regs->nip = call_syscall;
7355 ++ return 5;
7356 ++ }
7357 ++ } while (0);
7358 ++
7359 ++ do { /* PaX: rt_sigreturn emulation */
7360 ++ unsigned int li, sc;
7361 ++
7362 ++ err = get_user(li, (unsigned int *)regs->nip);
7363 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
7364 ++
7365 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
7366 ++ struct vm_area_struct *vma;
7367 ++ unsigned int call_syscall;
7368 ++
7369 ++ down_read(&current->mm->mmap_sem);
7370 ++ call_syscall = current->mm->call_syscall;
7371 ++ up_read(&current->mm->mmap_sem);
7372 ++ if (likely(call_syscall))
7373 ++ goto rt_emulate;
7374 ++
7375 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
7376 ++
7377 ++ down_write(&current->mm->mmap_sem);
7378 ++ if (current->mm->call_syscall) {
7379 ++ call_syscall = current->mm->call_syscall;
7380 ++ up_write(&current->mm->mmap_sem);
7381 ++ if (vma)
7382 ++ kmem_cache_free(vm_area_cachep, vma);
7383 ++ goto rt_emulate;
7384 ++ }
7385 ++
7386 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7387 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
7388 ++ up_write(&current->mm->mmap_sem);
7389 ++ if (vma)
7390 ++ kmem_cache_free(vm_area_cachep, vma);
7391 ++ return 1;
7392 ++ }
7393 ++
7394 ++ if (pax_insert_vma(vma, call_syscall)) {
7395 ++ up_write(&current->mm->mmap_sem);
7396 ++ kmem_cache_free(vm_area_cachep, vma);
7397 ++ return 1;
7398 ++ }
7399 ++
7400 ++ current->mm->call_syscall = call_syscall;
7401 ++ up_write(&current->mm->mmap_sem);
7402 ++
7403 ++rt_emulate:
7404 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
7405 ++ regs->nip = call_syscall;
7406 ++ return 6;
7407 ++ }
7408 ++ } while (0);
7409 ++#endif
7410 ++
7411 ++ return 1;
7412 ++}
7413 ++
7414 ++void pax_report_insns(void *pc, void *sp)
7415 ++{
7416 ++ unsigned long i;
7417 ++
7418 ++ printk(KERN_ERR "PAX: bytes at PC: ");
7419 ++ for (i = 0; i < 5; i++) {
7420 ++ unsigned int c;
7421 ++ if (get_user(c, (unsigned int *)pc+i))
7422 ++ printk(KERN_CONT "???????? ");
7423 ++ else
7424 ++ printk(KERN_CONT "%08x ", c);
7425 ++ }
7426 ++ printk("\n");
7427 ++}
7428 ++#endif
7429 ++
7430 + /*
7431 + * Check whether the instruction at regs->nip is a store using
7432 + * an update addressing form which will update r1.
7433 +@@ -109,7 +474,7 @@ int do_page_fault(struct pt_regs *regs,
7434 + * indicate errors in DSISR but can validly be set in SRR1.
7435 + */
7436 + if (TRAP(regs) == 0x400)
7437 +- error_code &= 0x48200000;
7438 ++ error_code &= 0x58200000;
7439 + else
7440 + is_write = error_code & 0x02000000;
7441 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
7442 +@@ -204,15 +569,14 @@ good_area:
7443 + pte_t *ptep;
7444 + pmd_t *pmdp;
7445 +
7446 +-#if 0
7447 ++#if 1
7448 + /* It would be nice to actually enforce the VM execute
7449 + permission on CPUs which can do so, but far too
7450 + much stuff in userspace doesn't get the permissions
7451 + right, so we let any page be executed for now. */
7452 + if (! (vma->vm_flags & VM_EXEC))
7453 + goto bad_area;
7454 +-#endif
7455 +-
7456 ++#else
7457 + /* Since 4xx/Book-E supports per-page execute permission,
7458 + * we lazily flush dcache to icache. */
7459 + ptep = NULL;
7460 +@@ -235,6 +599,7 @@ good_area:
7461 + pte_unmap_unlock(ptep, ptl);
7462 + }
7463 + #endif
7464 ++#endif
7465 + /* a read */
7466 + } else {
7467 + /* protection fault */
7468 +@@ -278,6 +643,33 @@ bad_area:
7469 +
7470 + /* User mode accesses cause a SIGSEGV */
7471 + if (user_mode(regs)) {
7472 ++
7473 ++#ifdef CONFIG_PAX_PAGEEXEC
7474 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
7475 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
7476 ++ switch (pax_handle_fetch_fault(regs)) {
7477 ++
7478 ++#ifdef CONFIG_PAX_EMUPLT
7479 ++ case 2:
7480 ++ case 3:
7481 ++ case 4:
7482 ++ return 0;
7483 ++#endif
7484 ++
7485 ++#ifdef CONFIG_PAX_EMUSIGRT
7486 ++ case 5:
7487 ++ case 6:
7488 ++ return 0;
7489 ++#endif
7490 ++
7491 ++ }
7492 ++
7493 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
7494 ++ do_group_exit(SIGKILL);
7495 ++ }
7496 ++ }
7497 ++#endif
7498 ++
7499 + _exception(SIGSEGV, regs, code, address);
7500 + return 0;
7501 + }
7502 +diff -urNp a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
7503 +--- a/arch/s390/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
7504 ++++ b/arch/s390/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
7505 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
7506 +
7507 + /* Increase core size by size of got & plt and set start
7508 + offsets for got and plt. */
7509 +- me->core_size = ALIGN(me->core_size, 4);
7510 +- me->arch.got_offset = me->core_size;
7511 +- me->core_size += me->arch.got_size;
7512 +- me->arch.plt_offset = me->core_size;
7513 +- me->core_size += me->arch.plt_size;
7514 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
7515 ++ me->arch.got_offset = me->core_size_rw;
7516 ++ me->core_size_rw += me->arch.got_size;
7517 ++ me->arch.plt_offset = me->core_size_rx;
7518 ++ me->core_size_rx += me->arch.plt_size;
7519 + return 0;
7520 + }
7521 +
7522 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7523 + if (info->got_initialized == 0) {
7524 + Elf_Addr *gotent;
7525 +
7526 +- gotent = me->module_core + me->arch.got_offset +
7527 ++ gotent = me->module_core_rw + me->arch.got_offset +
7528 + info->got_offset;
7529 + *gotent = val;
7530 + info->got_initialized = 1;
7531 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7532 + else if (r_type == R_390_GOTENT ||
7533 + r_type == R_390_GOTPLTENT)
7534 + *(unsigned int *) loc =
7535 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
7536 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
7537 + else if (r_type == R_390_GOT64 ||
7538 + r_type == R_390_GOTPLT64)
7539 + *(unsigned long *) loc = val;
7540 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7541 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
7542 + if (info->plt_initialized == 0) {
7543 + unsigned int *ip;
7544 +- ip = me->module_core + me->arch.plt_offset +
7545 ++ ip = me->module_core_rx + me->arch.plt_offset +
7546 + info->plt_offset;
7547 + #ifndef CONFIG_64BIT
7548 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
7549 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7550 + val = me->arch.plt_offset - me->arch.got_offset +
7551 + info->plt_offset + rela->r_addend;
7552 + else
7553 +- val = (Elf_Addr) me->module_core +
7554 ++ val = (Elf_Addr) me->module_core_rx +
7555 + me->arch.plt_offset + info->plt_offset +
7556 + rela->r_addend - loc;
7557 + if (r_type == R_390_PLT16DBL)
7558 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7559 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
7560 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
7561 + val = val + rela->r_addend -
7562 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
7563 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
7564 + if (r_type == R_390_GOTOFF16)
7565 + *(unsigned short *) loc = val;
7566 + else if (r_type == R_390_GOTOFF32)
7567 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7568 + break;
7569 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
7570 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
7571 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
7572 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
7573 + rela->r_addend - loc;
7574 + if (r_type == R_390_GOTPC)
7575 + *(unsigned int *) loc = val;
7576 +diff -urNp a/arch/sparc/Makefile b/arch/sparc/Makefile
7577 +--- a/arch/sparc/Makefile 2008-08-20 11:16:13.000000000 -0700
7578 ++++ b/arch/sparc/Makefile 2008-08-20 18:36:57.000000000 -0700
7579 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
7580 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
7581 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
7582 + CORE_Y := $(core-y)
7583 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
7584 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
7585 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
7586 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
7587 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
7588 +diff -urNp a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
7589 +--- a/arch/sparc/kernel/sys_sparc.c 2008-08-20 11:16:13.000000000 -0700
7590 ++++ b/arch/sparc/kernel/sys_sparc.c 2008-08-20 18:36:57.000000000 -0700
7591 +@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
7592 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
7593 + return -ENOMEM;
7594 + if (!addr)
7595 +- addr = TASK_UNMAPPED_BASE;
7596 ++ addr = current->mm->mmap_base;
7597 +
7598 + if (flags & MAP_SHARED)
7599 + addr = COLOUR_ALIGN(addr);
7600 +diff -urNp a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
7601 +--- a/arch/sparc/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
7602 ++++ b/arch/sparc/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
7603 +@@ -21,6 +21,10 @@
7604 + #include <linux/interrupt.h>
7605 + #include <linux/module.h>
7606 + #include <linux/kdebug.h>
7607 ++#include <linux/slab.h>
7608 ++#include <linux/pagemap.h>
7609 ++#include <linux/compiler.h>
7610 ++#include <linux/binfmts.h>
7611 +
7612 + #include <asm/system.h>
7613 + #include <asm/page.h>
7614 +@@ -216,6 +220,253 @@ static unsigned long compute_si_addr(str
7615 + return safe_compute_effective_address(regs, insn);
7616 + }
7617 +
7618 ++#ifdef CONFIG_PAX_PAGEEXEC
7619 ++void pax_emuplt_close(struct vm_area_struct *vma)
7620 ++{
7621 ++ vma->vm_mm->call_dl_resolve = 0UL;
7622 ++}
7623 ++
7624 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7625 ++{
7626 ++ struct page *page;
7627 ++ unsigned int *kaddr;
7628 ++
7629 ++ page = alloc_page(GFP_HIGHUSER);
7630 ++ if (!page)
7631 ++ return NOPAGE_OOM;
7632 ++
7633 ++ kaddr = kmap(page);
7634 ++ memset(kaddr, 0, PAGE_SIZE);
7635 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
7636 ++ flush_dcache_page(page);
7637 ++ kunmap(page);
7638 ++ if (type)
7639 ++ *type = VM_FAULT_MAJOR;
7640 ++
7641 ++ return page;
7642 ++}
7643 ++
7644 ++static struct vm_operations_struct pax_vm_ops = {
7645 ++ .close = pax_emuplt_close,
7646 ++ .nopage = pax_emuplt_nopage,
7647 ++};
7648 ++
7649 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7650 ++{
7651 ++ int ret;
7652 ++
7653 ++ vma->vm_mm = current->mm;
7654 ++ vma->vm_start = addr;
7655 ++ vma->vm_end = addr + PAGE_SIZE;
7656 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7657 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
7658 ++ vma->vm_ops = &pax_vm_ops;
7659 ++
7660 ++ ret = insert_vm_struct(current->mm, vma);
7661 ++ if (ret)
7662 ++ return ret;
7663 ++
7664 ++ ++current->mm->total_vm;
7665 ++ return 0;
7666 ++}
7667 ++
7668 ++/*
7669 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
7670 ++ *
7671 ++ * returns 1 when task should be killed
7672 ++ * 2 when patched PLT trampoline was detected
7673 ++ * 3 when unpatched PLT trampoline was detected
7674 ++ */
7675 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
7676 ++{
7677 ++
7678 ++#ifdef CONFIG_PAX_EMUPLT
7679 ++ int err;
7680 ++
7681 ++ do { /* PaX: patched PLT emulation #1 */
7682 ++ unsigned int sethi1, sethi2, jmpl;
7683 ++
7684 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
7685 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
7686 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
7687 ++
7688 ++ if (err)
7689 ++ break;
7690 ++
7691 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7692 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
7693 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
7694 ++ {
7695 ++ unsigned int addr;
7696 ++
7697 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
7698 ++ addr = regs->u_regs[UREG_G1];
7699 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7700 ++ regs->pc = addr;
7701 ++ regs->npc = addr+4;
7702 ++ return 2;
7703 ++ }
7704 ++ } while (0);
7705 ++
7706 ++ { /* PaX: patched PLT emulation #2 */
7707 ++ unsigned int ba;
7708 ++
7709 ++ err = get_user(ba, (unsigned int *)regs->pc);
7710 ++
7711 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
7712 ++ unsigned int addr;
7713 ++
7714 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7715 ++ regs->pc = addr;
7716 ++ regs->npc = addr+4;
7717 ++ return 2;
7718 ++ }
7719 ++ }
7720 ++
7721 ++ do { /* PaX: patched PLT emulation #3 */
7722 ++ unsigned int sethi, jmpl, nop;
7723 ++
7724 ++ err = get_user(sethi, (unsigned int *)regs->pc);
7725 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
7726 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
7727 ++
7728 ++ if (err)
7729 ++ break;
7730 ++
7731 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
7732 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
7733 ++ nop == 0x01000000U)
7734 ++ {
7735 ++ unsigned int addr;
7736 ++
7737 ++ addr = (sethi & 0x003FFFFFU) << 10;
7738 ++ regs->u_regs[UREG_G1] = addr;
7739 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7740 ++ regs->pc = addr;
7741 ++ regs->npc = addr+4;
7742 ++ return 2;
7743 ++ }
7744 ++ } while (0);
7745 ++
7746 ++ do { /* PaX: unpatched PLT emulation step 1 */
7747 ++ unsigned int sethi, ba, nop;
7748 ++
7749 ++ err = get_user(sethi, (unsigned int *)regs->pc);
7750 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
7751 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
7752 ++
7753 ++ if (err)
7754 ++ break;
7755 ++
7756 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
7757 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
7758 ++ nop == 0x01000000U)
7759 ++ {
7760 ++ unsigned int addr, save, call;
7761 ++
7762 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
7763 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7764 ++ else
7765 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
7766 ++
7767 ++ err = get_user(save, (unsigned int *)addr);
7768 ++ err |= get_user(call, (unsigned int *)(addr+4));
7769 ++ err |= get_user(nop, (unsigned int *)(addr+8));
7770 ++ if (err)
7771 ++ break;
7772 ++
7773 ++ if (save == 0x9DE3BFA8U &&
7774 ++ (call & 0xC0000000U) == 0x40000000U &&
7775 ++ nop == 0x01000000U)
7776 ++ {
7777 ++ struct vm_area_struct *vma;
7778 ++ unsigned long call_dl_resolve;
7779 ++
7780 ++ down_read(&current->mm->mmap_sem);
7781 ++ call_dl_resolve = current->mm->call_dl_resolve;
7782 ++ up_read(&current->mm->mmap_sem);
7783 ++ if (likely(call_dl_resolve))
7784 ++ goto emulate;
7785 ++
7786 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
7787 ++
7788 ++ down_write(&current->mm->mmap_sem);
7789 ++ if (current->mm->call_dl_resolve) {
7790 ++ call_dl_resolve = current->mm->call_dl_resolve;
7791 ++ up_write(&current->mm->mmap_sem);
7792 ++ if (vma)
7793 ++ kmem_cache_free(vm_area_cachep, vma);
7794 ++ goto emulate;
7795 ++ }
7796 ++
7797 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7798 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7799 ++ up_write(&current->mm->mmap_sem);
7800 ++ if (vma)
7801 ++ kmem_cache_free(vm_area_cachep, vma);
7802 ++ return 1;
7803 ++ }
7804 ++
7805 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
7806 ++ up_write(&current->mm->mmap_sem);
7807 ++ kmem_cache_free(vm_area_cachep, vma);
7808 ++ return 1;
7809 ++ }
7810 ++
7811 ++ current->mm->call_dl_resolve = call_dl_resolve;
7812 ++ up_write(&current->mm->mmap_sem);
7813 ++
7814 ++emulate:
7815 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7816 ++ regs->pc = call_dl_resolve;
7817 ++ regs->npc = addr+4;
7818 ++ return 3;
7819 ++ }
7820 ++ }
7821 ++ } while (0);
7822 ++
7823 ++ do { /* PaX: unpatched PLT emulation step 2 */
7824 ++ unsigned int save, call, nop;
7825 ++
7826 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
7827 ++ err |= get_user(call, (unsigned int *)regs->pc);
7828 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
7829 ++ if (err)
7830 ++ break;
7831 ++
7832 ++ if (save == 0x9DE3BFA8U &&
7833 ++ (call & 0xC0000000U) == 0x40000000U &&
7834 ++ nop == 0x01000000U)
7835 ++ {
7836 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
7837 ++
7838 ++ regs->u_regs[UREG_RETPC] = regs->pc;
7839 ++ regs->pc = dl_resolve;
7840 ++ regs->npc = dl_resolve+4;
7841 ++ return 3;
7842 ++ }
7843 ++ } while (0);
7844 ++#endif
7845 ++
7846 ++ return 1;
7847 ++}
7848 ++
7849 ++void pax_report_insns(void *pc, void *sp)
7850 ++{
7851 ++ unsigned long i;
7852 ++
7853 ++ printk(KERN_ERR "PAX: bytes at PC: ");
7854 ++ for (i = 0; i < 5; i++) {
7855 ++ unsigned int c;
7856 ++ if (get_user(c, (unsigned int *)pc+i))
7857 ++ printk(KERN_CONT "???????? ");
7858 ++ else
7859 ++ printk(KERN_CONT "%08x ", c);
7860 ++ }
7861 ++ printk("\n");
7862 ++}
7863 ++#endif
7864 ++
7865 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
7866 + unsigned long address)
7867 + {
7868 +@@ -280,6 +531,24 @@ good_area:
7869 + if(!(vma->vm_flags & VM_WRITE))
7870 + goto bad_area;
7871 + } else {
7872 ++
7873 ++#ifdef CONFIG_PAX_PAGEEXEC
7874 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
7875 ++ up_read(&mm->mmap_sem);
7876 ++ switch (pax_handle_fetch_fault(regs)) {
7877 ++
7878 ++#ifdef CONFIG_PAX_EMUPLT
7879 ++ case 2:
7880 ++ case 3:
7881 ++ return;
7882 ++#endif
7883 ++
7884 ++ }
7885 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
7886 ++ do_group_exit(SIGKILL);
7887 ++ }
7888 ++#endif
7889 ++
7890 + /* Allow reads even for write-only mappings */
7891 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
7892 + goto bad_area;
7893 +diff -urNp a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
7894 +--- a/arch/sparc/mm/init.c 2008-08-20 11:16:13.000000000 -0700
7895 ++++ b/arch/sparc/mm/init.c 2008-08-20 18:36:57.000000000 -0700
7896 +@@ -311,6 +311,9 @@ extern void device_scan(void);
7897 + pgprot_t PAGE_SHARED __read_mostly;
7898 + EXPORT_SYMBOL(PAGE_SHARED);
7899 +
7900 ++pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
7901 ++EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
7902 ++
7903 + void __init paging_init(void)
7904 + {
7905 + switch(sparc_cpu_model) {
7906 +@@ -336,17 +339,17 @@ void __init paging_init(void)
7907 +
7908 + /* Initialize the protection map with non-constant, MMU dependent values. */
7909 + protection_map[0] = PAGE_NONE;
7910 +- protection_map[1] = PAGE_READONLY;
7911 +- protection_map[2] = PAGE_COPY;
7912 +- protection_map[3] = PAGE_COPY;
7913 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
7914 ++ protection_map[2] = PAGE_COPY_NOEXEC;
7915 ++ protection_map[3] = PAGE_COPY_NOEXEC;
7916 + protection_map[4] = PAGE_READONLY;
7917 + protection_map[5] = PAGE_READONLY;
7918 + protection_map[6] = PAGE_COPY;
7919 + protection_map[7] = PAGE_COPY;
7920 + protection_map[8] = PAGE_NONE;
7921 +- protection_map[9] = PAGE_READONLY;
7922 +- protection_map[10] = PAGE_SHARED;
7923 +- protection_map[11] = PAGE_SHARED;
7924 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
7925 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
7926 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
7927 + protection_map[12] = PAGE_READONLY;
7928 + protection_map[13] = PAGE_READONLY;
7929 + protection_map[14] = PAGE_SHARED;
7930 +diff -urNp a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
7931 +--- a/arch/sparc/mm/srmmu.c 2008-08-20 11:16:13.000000000 -0700
7932 ++++ b/arch/sparc/mm/srmmu.c 2008-08-20 18:36:57.000000000 -0700
7933 +@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
7934 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
7935 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
7936 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
7937 ++
7938 ++#ifdef CONFIG_PAX_PAGEEXEC
7939 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
7940 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
7941 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
7942 ++#endif
7943 ++
7944 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
7945 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
7946 +
7947 +diff -urNp a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
7948 +--- a/arch/sparc64/kernel/Makefile 2008-08-20 11:16:13.000000000 -0700
7949 ++++ b/arch/sparc64/kernel/Makefile 2008-08-20 18:36:57.000000000 -0700
7950 +@@ -3,7 +3,7 @@
7951 + #
7952 +
7953 + EXTRA_AFLAGS := -ansi
7954 +-EXTRA_CFLAGS := -Werror
7955 ++#EXTRA_CFLAGS := -Werror
7956 +
7957 + extra-y := head.o init_task.o vmlinux.lds
7958 +
7959 +diff -urNp a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
7960 +--- a/arch/sparc64/kernel/sys_sparc.c 2008-08-20 11:16:13.000000000 -0700
7961 ++++ b/arch/sparc64/kernel/sys_sparc.c 2008-08-20 18:36:57.000000000 -0700
7962 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
7963 + /* We do not accept a shared mapping if it would violate
7964 + * cache aliasing constraints.
7965 + */
7966 +- if ((flags & MAP_SHARED) &&
7967 ++ if ((filp || (flags & MAP_SHARED)) &&
7968 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
7969 + return -EINVAL;
7970 + return addr;
7971 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
7972 + if (filp || (flags & MAP_SHARED))
7973 + do_color_align = 1;
7974 +
7975 ++#ifdef CONFIG_PAX_RANDMMAP
7976 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7977 ++#endif
7978 ++
7979 + if (addr) {
7980 + if (do_color_align)
7981 + addr = COLOUR_ALIGN(addr, pgoff);
7982 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
7983 + }
7984 +
7985 + if (len > mm->cached_hole_size) {
7986 +- start_addr = addr = mm->free_area_cache;
7987 ++ start_addr = addr = mm->free_area_cache;
7988 + } else {
7989 +- start_addr = addr = TASK_UNMAPPED_BASE;
7990 ++ start_addr = addr = mm->mmap_base;
7991 + mm->cached_hole_size = 0;
7992 + }
7993 +
7994 +@@ -174,8 +178,8 @@ full_search:
7995 + vma = find_vma(mm, VA_EXCLUDE_END);
7996 + }
7997 + if (unlikely(task_size < addr)) {
7998 +- if (start_addr != TASK_UNMAPPED_BASE) {
7999 +- start_addr = addr = TASK_UNMAPPED_BASE;
8000 ++ if (start_addr != mm->mmap_base) {
8001 ++ start_addr = addr = mm->mmap_base;
8002 + mm->cached_hole_size = 0;
8003 + goto full_search;
8004 + }
8005 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
8006 + /* We do not accept a shared mapping if it would violate
8007 + * cache aliasing constraints.
8008 + */
8009 +- if ((flags & MAP_SHARED) &&
8010 ++ if ((filp || (flags & MAP_SHARED)) &&
8011 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
8012 + return -EINVAL;
8013 + return addr;
8014 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
8015 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
8016 + sysctl_legacy_va_layout) {
8017 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
8018 ++
8019 ++#ifdef CONFIG_PAX_RANDMMAP
8020 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
8021 ++ mm->mmap_base += mm->delta_mmap;
8022 ++#endif
8023 ++
8024 + mm->get_unmapped_area = arch_get_unmapped_area;
8025 + mm->unmap_area = arch_unmap_area;
8026 + } else {
8027 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
8028 + gap = (task_size / 6 * 5);
8029 +
8030 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
8031 ++
8032 ++#ifdef CONFIG_PAX_RANDMMAP
8033 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
8034 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8035 ++#endif
8036 ++
8037 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8038 + mm->unmap_area = arch_unmap_area_topdown;
8039 + }
8040 +diff -urNp a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile
8041 +--- a/arch/sparc64/mm/Makefile 2008-08-20 11:16:13.000000000 -0700
8042 ++++ b/arch/sparc64/mm/Makefile 2008-08-20 18:36:57.000000000 -0700
8043 +@@ -3,7 +3,7 @@
8044 + #
8045 +
8046 + EXTRA_AFLAGS := -ansi
8047 +-EXTRA_CFLAGS := -Werror
8048 ++#EXTRA_CFLAGS := -Werror
8049 +
8050 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
8051 +
8052 +diff -urNp a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
8053 +--- a/arch/sparc64/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
8054 ++++ b/arch/sparc64/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
8055 +@@ -20,6 +20,10 @@
8056 + #include <linux/kprobes.h>
8057 + #include <linux/kallsyms.h>
8058 + #include <linux/kdebug.h>
8059 ++#include <linux/slab.h>
8060 ++#include <linux/pagemap.h>
8061 ++#include <linux/compiler.h>
8062 ++#include <linux/binfmts.h>
8063 +
8064 + #include <asm/page.h>
8065 + #include <asm/pgtable.h>
8066 +@@ -262,6 +266,370 @@ cannot_handle:
8067 + unhandled_fault (address, current, regs);
8068 + }
8069 +
8070 ++#ifdef CONFIG_PAX_PAGEEXEC
8071 ++#ifdef CONFIG_PAX_EMUPLT
8072 ++static void pax_emuplt_close(struct vm_area_struct *vma)
8073 ++{
8074 ++ vma->vm_mm->call_dl_resolve = 0UL;
8075 ++}
8076 ++
8077 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8078 ++{
8079 ++ struct page *page;
8080 ++ unsigned int *kaddr;
8081 ++
8082 ++ page = alloc_page(GFP_HIGHUSER);
8083 ++ if (!page)
8084 ++ return NOPAGE_OOM;
8085 ++
8086 ++ kaddr = kmap(page);
8087 ++ memset(kaddr, 0, PAGE_SIZE);
8088 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
8089 ++ flush_dcache_page(page);
8090 ++ kunmap(page);
8091 ++ if (type)
8092 ++ *type = VM_FAULT_MAJOR;
8093 ++ return page;
8094 ++}
8095 ++
8096 ++static struct vm_operations_struct pax_vm_ops = {
8097 ++ .close = pax_emuplt_close,
8098 ++ .nopage = pax_emuplt_nopage,
8099 ++};
8100 ++
8101 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8102 ++{
8103 ++ int ret;
8104 ++
8105 ++ vma->vm_mm = current->mm;
8106 ++ vma->vm_start = addr;
8107 ++ vma->vm_end = addr + PAGE_SIZE;
8108 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8109 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8110 ++ vma->vm_ops = &pax_vm_ops;
8111 ++
8112 ++ ret = insert_vm_struct(current->mm, vma);
8113 ++ if (ret)
8114 ++ return ret;
8115 ++
8116 ++ ++current->mm->total_vm;
8117 ++ return 0;
8118 ++}
8119 ++#endif
8120 ++
8121 ++/*
8122 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
8123 ++ *
8124 ++ * returns 1 when task should be killed
8125 ++ * 2 when patched PLT trampoline was detected
8126 ++ * 3 when unpatched PLT trampoline was detected
8127 ++ */
8128 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
8129 ++{
8130 ++
8131 ++#ifdef CONFIG_PAX_EMUPLT
8132 ++ int err;
8133 ++
8134 ++ do { /* PaX: patched PLT emulation #1 */
8135 ++ unsigned int sethi1, sethi2, jmpl;
8136 ++
8137 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
8138 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
8139 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
8140 ++
8141 ++ if (err)
8142 ++ break;
8143 ++
8144 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8145 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
8146 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
8147 ++ {
8148 ++ unsigned long addr;
8149 ++
8150 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
8151 ++ addr = regs->u_regs[UREG_G1];
8152 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8153 ++ regs->tpc = addr;
8154 ++ regs->tnpc = addr+4;
8155 ++ return 2;
8156 ++ }
8157 ++ } while (0);
8158 ++
8159 ++ { /* PaX: patched PLT emulation #2 */
8160 ++ unsigned int ba;
8161 ++
8162 ++ err = get_user(ba, (unsigned int *)regs->tpc);
8163 ++
8164 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
8165 ++ unsigned long addr;
8166 ++
8167 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8168 ++ regs->tpc = addr;
8169 ++ regs->tnpc = addr+4;
8170 ++ return 2;
8171 ++ }
8172 ++ }
8173 ++
8174 ++ do { /* PaX: patched PLT emulation #3 */
8175 ++ unsigned int sethi, jmpl, nop;
8176 ++
8177 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
8178 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
8179 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
8180 ++
8181 ++ if (err)
8182 ++ break;
8183 ++
8184 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8185 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
8186 ++ nop == 0x01000000U)
8187 ++ {
8188 ++ unsigned long addr;
8189 ++
8190 ++ addr = (sethi & 0x003FFFFFU) << 10;
8191 ++ regs->u_regs[UREG_G1] = addr;
8192 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8193 ++ regs->tpc = addr;
8194 ++ regs->tnpc = addr+4;
8195 ++ return 2;
8196 ++ }
8197 ++ } while (0);
8198 ++
8199 ++ do { /* PaX: patched PLT emulation #4 */
8200 ++ unsigned int mov1, call, mov2;
8201 ++
8202 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
8203 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
8204 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
8205 ++
8206 ++ if (err)
8207 ++ break;
8208 ++
8209 ++ if (mov1 == 0x8210000FU &&
8210 ++ (call & 0xC0000000U) == 0x40000000U &&
8211 ++ mov2 == 0x9E100001U)
8212 ++ {
8213 ++ unsigned long addr;
8214 ++
8215 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
8216 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8217 ++ regs->tpc = addr;
8218 ++ regs->tnpc = addr+4;
8219 ++ return 2;
8220 ++ }
8221 ++ } while (0);
8222 ++
8223 ++ do { /* PaX: patched PLT emulation #5 */
8224 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
8225 ++
8226 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
8227 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
8228 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
8229 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
8230 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
8231 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
8232 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
8233 ++
8234 ++ if (err)
8235 ++ break;
8236 ++
8237 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8238 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8239 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
8240 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
8241 ++ sllx == 0x83287020 &&
8242 ++ jmpl == 0x81C04005U &&
8243 ++ nop == 0x01000000U)
8244 ++ {
8245 ++ unsigned long addr;
8246 ++
8247 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
8248 ++ regs->u_regs[UREG_G1] <<= 32;
8249 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
8250 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8251 ++ regs->tpc = addr;
8252 ++ regs->tnpc = addr+4;
8253 ++ return 2;
8254 ++ }
8255 ++ } while (0);
8256 ++
8257 ++ do { /* PaX: patched PLT emulation #6 */
8258 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
8259 ++
8260 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
8261 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
8262 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
8263 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
8264 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
8265 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
8266 ++
8267 ++ if (err)
8268 ++ break;
8269 ++
8270 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8271 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8272 ++ sllx == 0x83287020 &&
8273 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
8274 ++ jmpl == 0x81C04005U &&
8275 ++ nop == 0x01000000U)
8276 ++ {
8277 ++ unsigned long addr;
8278 ++
8279 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
8280 ++ regs->u_regs[UREG_G1] <<= 32;
8281 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
8282 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8283 ++ regs->tpc = addr;
8284 ++ regs->tnpc = addr+4;
8285 ++ return 2;
8286 ++ }
8287 ++ } while (0);
8288 ++
8289 ++ do { /* PaX: patched PLT emulation #7 */
8290 ++ unsigned int sethi, ba, nop;
8291 ++
8292 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
8293 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
8294 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
8295 ++
8296 ++ if (err)
8297 ++ break;
8298 ++
8299 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8300 ++ (ba & 0xFFF00000U) == 0x30600000U &&
8301 ++ nop == 0x01000000U)
8302 ++ {
8303 ++ unsigned long addr;
8304 ++
8305 ++ addr = (sethi & 0x003FFFFFU) << 10;
8306 ++ regs->u_regs[UREG_G1] = addr;
8307 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8308 ++ regs->tpc = addr;
8309 ++ regs->tnpc = addr+4;
8310 ++ return 2;
8311 ++ }
8312 ++ } while (0);
8313 ++
8314 ++ do { /* PaX: unpatched PLT emulation step 1 */
8315 ++ unsigned int sethi, ba, nop;
8316 ++
8317 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
8318 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
8319 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
8320 ++
8321 ++ if (err)
8322 ++ break;
8323 ++
8324 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8325 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
8326 ++ nop == 0x01000000U)
8327 ++ {
8328 ++ unsigned long addr;
8329 ++ unsigned int save, call;
8330 ++
8331 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
8332 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8333 ++ else
8334 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8335 ++
8336 ++ err = get_user(save, (unsigned int *)addr);
8337 ++ err |= get_user(call, (unsigned int *)(addr+4));
8338 ++ err |= get_user(nop, (unsigned int *)(addr+8));
8339 ++ if (err)
8340 ++ break;
8341 ++
8342 ++ if (save == 0x9DE3BFA8U &&
8343 ++ (call & 0xC0000000U) == 0x40000000U &&
8344 ++ nop == 0x01000000U)
8345 ++ {
8346 ++ struct vm_area_struct *vma;
8347 ++ unsigned long call_dl_resolve;
8348 ++
8349 ++ down_read(&current->mm->mmap_sem);
8350 ++ call_dl_resolve = current->mm->call_dl_resolve;
8351 ++ up_read(&current->mm->mmap_sem);
8352 ++ if (likely(call_dl_resolve))
8353 ++ goto emulate;
8354 ++
8355 ++ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
8356 ++
8357 ++ down_write(&current->mm->mmap_sem);
8358 ++ if (current->mm->call_dl_resolve) {
8359 ++ call_dl_resolve = current->mm->call_dl_resolve;
8360 ++ up_write(&current->mm->mmap_sem);
8361 ++ if (vma)
8362 ++ kmem_cache_free(vm_area_cachep, vma);
8363 ++ goto emulate;
8364 ++ }
8365 ++
8366 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8367 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
8368 ++ up_write(&current->mm->mmap_sem);
8369 ++ if (vma)
8370 ++ kmem_cache_free(vm_area_cachep, vma);
8371 ++ return 1;
8372 ++ }
8373 ++
8374 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
8375 ++ up_write(&current->mm->mmap_sem);
8376 ++ kmem_cache_free(vm_area_cachep, vma);
8377 ++ return 1;
8378 ++ }
8379 ++
8380 ++ current->mm->call_dl_resolve = call_dl_resolve;
8381 ++ up_write(&current->mm->mmap_sem);
8382 ++
8383 ++emulate:
8384 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
8385 ++ regs->tpc = call_dl_resolve;
8386 ++ regs->tnpc = addr+4;
8387 ++ return 3;
8388 ++ }
8389 ++ }
8390 ++ } while (0);
8391 ++
8392 ++ do { /* PaX: unpatched PLT emulation step 2 */
8393 ++ unsigned int save, call, nop;
8394 ++
8395 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
8396 ++ err |= get_user(call, (unsigned int *)regs->tpc);
8397 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
8398 ++ if (err)
8399 ++ break;
8400 ++
8401 ++ if (save == 0x9DE3BFA8U &&
8402 ++ (call & 0xC0000000U) == 0x40000000U &&
8403 ++ nop == 0x01000000U)
8404 ++ {
8405 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8406 ++
8407 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
8408 ++ regs->tpc = dl_resolve;
8409 ++ regs->tnpc = dl_resolve+4;
8410 ++ return 3;
8411 ++ }
8412 ++ } while (0);
8413 ++#endif
8414 ++
8415 ++ return 1;
8416 ++}
8417 ++
8418 ++void pax_report_insns(void *pc, void *sp)
8419 ++{
8420 ++ unsigned long i;
8421 ++
8422 ++ printk(KERN_ERR "PAX: bytes at PC: ");
8423 ++ for (i = 0; i < 5; i++) {
8424 ++ unsigned int c;
8425 ++ if (get_user(c, (unsigned int *)pc+i))
8426 ++ printk(KERN_CONT "???????? ");
8427 ++ else
8428 ++ printk(KERN_CONT "%08x ", c);
8429 ++ }
8430 ++ printk("\n");
8431 ++}
8432 ++#endif
8433 ++
8434 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
8435 + {
8436 + struct mm_struct *mm = current->mm;
8437 +@@ -303,8 +671,10 @@ asmlinkage void __kprobes do_sparc64_fau
8438 + goto intr_or_no_mm;
8439 +
8440 + if (test_thread_flag(TIF_32BIT)) {
8441 +- if (!(regs->tstate & TSTATE_PRIV))
8442 ++ if (!(regs->tstate & TSTATE_PRIV)) {
8443 + regs->tpc &= 0xffffffff;
8444 ++ regs->tnpc &= 0xffffffff;
8445 ++ }
8446 + address &= 0xffffffff;
8447 + }
8448 +
8449 +@@ -321,6 +691,29 @@ asmlinkage void __kprobes do_sparc64_fau
8450 + if (!vma)
8451 + goto bad_area;
8452 +
8453 ++#ifdef CONFIG_PAX_PAGEEXEC
8454 ++ /* PaX: detect ITLB misses on non-exec pages */
8455 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
8456 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
8457 ++ {
8458 ++ if (address != regs->tpc)
8459 ++ goto good_area;
8460 ++
8461 ++ up_read(&mm->mmap_sem);
8462 ++ switch (pax_handle_fetch_fault(regs)) {
8463 ++
8464 ++#ifdef CONFIG_PAX_EMUPLT
8465 ++ case 2:
8466 ++ case 3:
8467 ++ return;
8468 ++#endif
8469 ++
8470 ++ }
8471 ++ pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
8472 ++ do_group_exit(SIGKILL);
8473 ++ }
8474 ++#endif
8475 ++
8476 + /* Pure DTLB misses do not tell us whether the fault causing
8477 + * load/store/atomic was a write or not, it only says that there
8478 + * was no match. So in such a case we (carefully) read the
8479 +diff -urNp a/arch/v850/kernel/module.c b/arch/v850/kernel/module.c
8480 +--- a/arch/v850/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
8481 ++++ b/arch/v850/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
8482 +@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
8483 + tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
8484 +
8485 + /* Init, or core PLT? */
8486 +- if (location >= mod->module_core
8487 +- && location < mod->module_core + mod->core_size)
8488 ++ if (location >= mod->module_core_rx
8489 ++ && location < mod->module_core_rx + mod->core_size_rx)
8490 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
8491 + else
8492 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
8493 +diff -urNp a/arch/x86/Kconfig b/arch/x86/Kconfig
8494 +--- a/arch/x86/Kconfig 2008-08-20 11:16:13.000000000 -0700
8495 ++++ b/arch/x86/Kconfig 2008-08-20 18:36:57.000000000 -0700
8496 +@@ -819,7 +819,7 @@ config PAGE_OFFSET
8497 + hex
8498 + default 0xB0000000 if VMSPLIT_3G_OPT
8499 + default 0x80000000 if VMSPLIT_2G
8500 +- default 0x78000000 if VMSPLIT_2G_OPT
8501 ++ default 0x70000000 if VMSPLIT_2G_OPT
8502 + default 0x40000000 if VMSPLIT_1G
8503 + default 0xC0000000
8504 + depends on X86_32
8505 +@@ -1113,8 +1113,7 @@ config CRASH_DUMP
8506 + config PHYSICAL_START
8507 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
8508 + default "0x1000000" if X86_NUMAQ
8509 +- default "0x200000" if X86_64
8510 +- default "0x100000"
8511 ++ default "0x200000"
8512 + help
8513 + This gives the physical address where the kernel is loaded.
8514 +
8515 +@@ -1206,9 +1205,9 @@ config HOTPLUG_CPU
8516 + suspend.
8517 +
8518 + config COMPAT_VDSO
8519 +- def_bool y
8520 ++ def_bool n
8521 + prompt "Compat VDSO support"
8522 +- depends on X86_32 || IA32_EMULATION
8523 ++ depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
8524 + help
8525 + Map the 32-bit VDSO to the predictable old-style address too.
8526 + ---help---
8527 +@@ -1395,7 +1394,7 @@ config PCI
8528 + choice
8529 + prompt "PCI access mode"
8530 + depends on X86_32 && PCI && !X86_VISWS
8531 +- default PCI_GOANY
8532 ++ default PCI_GODIRECT
8533 + ---help---
8534 + On PCI systems, the BIOS can be used to detect the PCI devices and
8535 + determine their configuration. However, some old PCI motherboards
8536 +diff -urNp a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
8537 +--- a/arch/x86/Kconfig.cpu 2008-08-20 11:16:13.000000000 -0700
8538 ++++ b/arch/x86/Kconfig.cpu 2008-08-20 18:36:57.000000000 -0700
8539 +@@ -335,7 +335,7 @@ config X86_PPRO_FENCE
8540 +
8541 + config X86_F00F_BUG
8542 + def_bool y
8543 +- depends on M586MMX || M586TSC || M586 || M486 || M386
8544 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
8545 +
8546 + config X86_WP_WORKS_OK
8547 + def_bool y
8548 +@@ -355,7 +355,7 @@ config X86_POPAD_OK
8549 +
8550 + config X86_ALIGNMENT_16
8551 + def_bool y
8552 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
8553 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
8554 +
8555 + config X86_GOOD_APIC
8556 + def_bool y
8557 +@@ -398,7 +398,7 @@ config X86_TSC
8558 + # generates cmov.
8559 + config X86_CMOV
8560 + def_bool y
8561 +- depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
8562 ++ depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7)
8563 +
8564 + config X86_MINIMUM_CPU_FAMILY
8565 + int
8566 +diff -urNp a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
8567 +--- a/arch/x86/Kconfig.debug 2008-08-20 11:16:13.000000000 -0700
8568 ++++ b/arch/x86/Kconfig.debug 2008-08-20 18:36:57.000000000 -0700
8569 +@@ -57,7 +57,7 @@ config DEBUG_PER_CPU_MAPS
8570 + config DEBUG_RODATA
8571 + bool "Write protect kernel read-only data structures"
8572 + default y
8573 +- depends on DEBUG_KERNEL
8574 ++ depends on DEBUG_KERNEL && BROKEN
8575 + help
8576 + Mark the kernel read-only data as write-protected in the pagetables,
8577 + in order to catch accidental (and incorrect) writes to such const
8578 +diff -urNp a/arch/x86/boot/bitops.h b/arch/x86/boot/bitops.h
8579 +--- a/arch/x86/boot/bitops.h 2008-08-20 11:16:13.000000000 -0700
8580 ++++ b/arch/x86/boot/bitops.h 2008-08-20 18:36:57.000000000 -0700
8581 +@@ -28,7 +28,7 @@ static inline int variable_test_bit(int
8582 + u8 v;
8583 + const u32 *p = (const u32 *)addr;
8584 +
8585 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
8586 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
8587 + return v;
8588 + }
8589 +
8590 +@@ -39,7 +39,7 @@ static inline int variable_test_bit(int
8591 +
8592 + static inline void set_bit(int nr, void *addr)
8593 + {
8594 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
8595 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
8596 + }
8597 +
8598 + #endif /* BOOT_BITOPS_H */
8599 +diff -urNp a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
8600 +--- a/arch/x86/boot/boot.h 2008-08-20 11:16:13.000000000 -0700
8601 ++++ b/arch/x86/boot/boot.h 2008-08-20 18:36:57.000000000 -0700
8602 +@@ -80,7 +80,7 @@ static inline void io_delay(void)
8603 + static inline u16 ds(void)
8604 + {
8605 + u16 seg;
8606 +- asm("movw %%ds,%0" : "=rm" (seg));
8607 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
8608 + return seg;
8609 + }
8610 +
8611 +@@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t
8612 + static inline int memcmp(const void *s1, const void *s2, size_t len)
8613 + {
8614 + u8 diff;
8615 +- asm("repe; cmpsb; setnz %0"
8616 ++ asm volatile("repe; cmpsb; setnz %0"
8617 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
8618 + return diff;
8619 + }
8620 +diff -urNp a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
8621 +--- a/arch/x86/boot/compressed/head_32.S 2008-08-20 11:16:13.000000000 -0700
8622 ++++ b/arch/x86/boot/compressed/head_32.S 2008-08-20 18:36:57.000000000 -0700
8623 +@@ -70,7 +70,7 @@ startup_32:
8624 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
8625 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
8626 + #else
8627 +- movl $LOAD_PHYSICAL_ADDR, %ebx
8628 ++ movl $____LOAD_PHYSICAL_ADDR, %ebx
8629 + #endif
8630 +
8631 + /* Replace the compressed data size with the uncompressed size */
8632 +@@ -105,7 +105,7 @@ startup_32:
8633 + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
8634 + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
8635 + #else
8636 +- movl $LOAD_PHYSICAL_ADDR, %ebp
8637 ++ movl $____LOAD_PHYSICAL_ADDR, %ebp
8638 + #endif
8639 +
8640 + /*
8641 +@@ -159,16 +159,15 @@ relocated:
8642 + * and where it was actually loaded.
8643 + */
8644 + movl %ebp, %ebx
8645 +- subl $LOAD_PHYSICAL_ADDR, %ebx
8646 ++ subl $____LOAD_PHYSICAL_ADDR, %ebx
8647 + jz 2f /* Nothing to be done if loaded at compiled addr. */
8648 + /*
8649 + * Process relocations.
8650 + */
8651 +
8652 + 1: subl $4, %edi
8653 +- movl 0(%edi), %ecx
8654 +- testl %ecx, %ecx
8655 +- jz 2f
8656 ++ movl (%edi), %ecx
8657 ++ jecxz 2f
8658 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
8659 + jmp 1b
8660 + 2:
8661 +diff -urNp a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
8662 +--- a/arch/x86/boot/compressed/misc.c 2008-08-20 11:16:13.000000000 -0700
8663 ++++ b/arch/x86/boot/compressed/misc.c 2008-08-20 18:36:57.000000000 -0700
8664 +@@ -122,7 +122,8 @@ typedef unsigned char uch;
8665 + typedef unsigned short ush;
8666 + typedef unsigned long ulg;
8667 +
8668 +-#define WSIZE 0x80000000 /* Window size must be at least 32k,
8669 ++#define WSIZE 0x80000000
8670 ++ /* Window size must be at least 32k,
8671 + * and a power of two
8672 + * We don't actually have a window just
8673 + * a huge output buffer so I report
8674 +@@ -400,7 +401,7 @@ asmlinkage void decompress_kernel(void *
8675 + if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
8676 + error("Destination address too large");
8677 + #ifndef CONFIG_RELOCATABLE
8678 +- if ((u32)output != LOAD_PHYSICAL_ADDR)
8679 ++ if ((u32)output != ____LOAD_PHYSICAL_ADDR)
8680 + error("Wrong destination address");
8681 + #endif
8682 + #endif
8683 +diff -urNp a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c
8684 +--- a/arch/x86/boot/compressed/relocs.c 2008-08-20 11:16:13.000000000 -0700
8685 ++++ b/arch/x86/boot/compressed/relocs.c 2008-08-20 18:36:57.000000000 -0700
8686 +@@ -10,9 +10,13 @@
8687 + #define USE_BSD
8688 + #include <endian.h>
8689 +
8690 ++#include "../../../../include/linux/autoconf.h"
8691 ++
8692 ++#define MAX_PHDRS 100
8693 + #define MAX_SHDRS 100
8694 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
8695 + static Elf32_Ehdr ehdr;
8696 ++static Elf32_Phdr phdr[MAX_PHDRS];
8697 + static Elf32_Shdr shdr[MAX_SHDRS];
8698 + static Elf32_Sym *symtab[MAX_SHDRS];
8699 + static Elf32_Rel *reltab[MAX_SHDRS];
8700 +@@ -241,6 +245,34 @@ static void read_ehdr(FILE *fp)
8701 + }
8702 + }
8703 +
8704 ++static void read_phdrs(FILE *fp)
8705 ++{
8706 ++ int i;
8707 ++ if (ehdr.e_phnum > MAX_PHDRS) {
8708 ++ die("%d program headers supported: %d\n",
8709 ++ ehdr.e_phnum, MAX_PHDRS);
8710 ++ }
8711 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
8712 ++ die("Seek to %d failed: %s\n",
8713 ++ ehdr.e_phoff, strerror(errno));
8714 ++ }
8715 ++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
8716 ++ die("Cannot read ELF program headers: %s\n",
8717 ++ strerror(errno));
8718 ++ }
8719 ++ for(i = 0; i < ehdr.e_phnum; i++) {
8720 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
8721 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
8722 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
8723 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
8724 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
8725 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
8726 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
8727 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
8728 ++ }
8729 ++
8730 ++}
8731 ++
8732 + static void read_shdrs(FILE *fp)
8733 + {
8734 + int i;
8735 +@@ -327,6 +359,8 @@ static void read_symtabs(FILE *fp)
8736 + static void read_relocs(FILE *fp)
8737 + {
8738 + int i,j;
8739 ++ uint32_t base;
8740 ++
8741 + for(i = 0; i < ehdr.e_shnum; i++) {
8742 + if (shdr[i].sh_type != SHT_REL) {
8743 + continue;
8744 +@@ -344,8 +378,17 @@ static void read_relocs(FILE *fp)
8745 + die("Cannot read symbol table: %s\n",
8746 + strerror(errno));
8747 + }
8748 ++ base = 0;
8749 ++ for (j = 0; j < ehdr.e_phnum; j++) {
8750 ++ if (phdr[j].p_type != PT_LOAD )
8751 ++ continue;
8752 ++ 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)
8753 ++ continue;
8754 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
8755 ++ break;
8756 ++ }
8757 + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
8758 +- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
8759 ++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
8760 + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
8761 + }
8762 + }
8763 +@@ -482,6 +525,23 @@ static void walk_relocs(void (*visit)(El
8764 + if (sym->st_shndx == SHN_ABS) {
8765 + continue;
8766 + }
8767 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
8768 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
8769 ++ continue;
8770 ++#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
8771 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
8772 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
8773 ++ continue;
8774 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
8775 ++ continue;
8776 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
8777 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
8778 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
8779 ++ continue;
8780 ++ }
8781 ++ if (!strcmp(sec_name(sym->st_shndx), ".text"))
8782 ++ continue;
8783 ++#endif
8784 + if (r_type == R_386_PC32) {
8785 + /* PC relative relocations don't need to be adjusted */
8786 + }
8787 +@@ -609,6 +669,7 @@ int main(int argc, char **argv)
8788 + fname, strerror(errno));
8789 + }
8790 + read_ehdr(fp);
8791 ++ read_phdrs(fp);
8792 + read_shdrs(fp);
8793 + read_strtabs(fp);
8794 + read_symtabs(fp);
8795 +diff -urNp a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
8796 +--- a/arch/x86/boot/cpucheck.c 2008-08-20 11:16:13.000000000 -0700
8797 ++++ b/arch/x86/boot/cpucheck.c 2008-08-20 18:36:57.000000000 -0700
8798 +@@ -78,7 +78,7 @@ static int has_fpu(void)
8799 + u16 fcw = -1, fsw = -1;
8800 + u32 cr0;
8801 +
8802 +- asm("movl %%cr0,%0" : "=r" (cr0));
8803 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
8804 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
8805 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
8806 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
8807 +@@ -94,7 +94,7 @@ static int has_eflag(u32 mask)
8808 + {
8809 + u32 f0, f1;
8810 +
8811 +- asm("pushfl ; "
8812 ++ asm volatile("pushfl ; "
8813 + "pushfl ; "
8814 + "popl %0 ; "
8815 + "movl %0,%1 ; "
8816 +@@ -119,7 +119,7 @@ static void get_flags(void)
8817 + set_bit(X86_FEATURE_FPU, cpu.flags);
8818 +
8819 + if (has_eflag(X86_EFLAGS_ID)) {
8820 +- asm("cpuid"
8821 ++ asm volatile("cpuid"
8822 + : "=a" (max_intel_level),
8823 + "=b" (cpu_vendor[0]),
8824 + "=d" (cpu_vendor[1]),
8825 +@@ -128,7 +128,7 @@ static void get_flags(void)
8826 +
8827 + if (max_intel_level >= 0x00000001 &&
8828 + max_intel_level <= 0x0000ffff) {
8829 +- asm("cpuid"
8830 ++ asm volatile("cpuid"
8831 + : "=a" (tfms),
8832 + "=c" (cpu.flags[4]),
8833 + "=d" (cpu.flags[0])
8834 +@@ -140,7 +140,7 @@ static void get_flags(void)
8835 + cpu.model += ((tfms >> 16) & 0xf) << 4;
8836 + }
8837 +
8838 +- asm("cpuid"
8839 ++ asm volatile("cpuid"
8840 + : "=a" (max_amd_level)
8841 + : "a" (0x80000000)
8842 + : "ebx", "ecx", "edx");
8843 +@@ -148,7 +148,7 @@ static void get_flags(void)
8844 + if (max_amd_level >= 0x80000001 &&
8845 + max_amd_level <= 0x8000ffff) {
8846 + u32 eax = 0x80000001;
8847 +- asm("cpuid"
8848 ++ asm volatile("cpuid"
8849 + : "+a" (eax),
8850 + "=c" (cpu.flags[6]),
8851 + "=d" (cpu.flags[1])
8852 +@@ -207,9 +207,9 @@ int check_cpu(int *cpu_level_ptr, int *r
8853 + u32 ecx = MSR_K7_HWCR;
8854 + u32 eax, edx;
8855 +
8856 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8857 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8858 + eax &= ~(1 << 15);
8859 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8860 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8861 +
8862 + get_flags(); /* Make sure it really did something */
8863 + err = check_flags();
8864 +@@ -222,9 +222,9 @@ int check_cpu(int *cpu_level_ptr, int *r
8865 + u32 ecx = MSR_VIA_FCR;
8866 + u32 eax, edx;
8867 +
8868 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8869 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8870 + eax |= (1<<1)|(1<<7);
8871 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8872 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8873 +
8874 + set_bit(X86_FEATURE_CX8, cpu.flags);
8875 + err = check_flags();
8876 +@@ -235,12 +235,12 @@ int check_cpu(int *cpu_level_ptr, int *r
8877 + u32 eax, edx;
8878 + u32 level = 1;
8879 +
8880 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8881 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
8882 +- asm("cpuid"
8883 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
8884 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
8885 ++ asm volatile("cpuid"
8886 + : "+a" (level), "=d" (cpu.flags[0])
8887 + : : "ecx", "ebx");
8888 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8889 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
8890 +
8891 + err = check_flags();
8892 + }
8893 +diff -urNp a/arch/x86/boot/edd.c b/arch/x86/boot/edd.c
8894 +--- a/arch/x86/boot/edd.c 2008-08-20 11:16:13.000000000 -0700
8895 ++++ b/arch/x86/boot/edd.c 2008-08-20 18:36:57.000000000 -0700
8896 +@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
8897 + ax = 0x4100;
8898 + bx = EDDMAGIC1;
8899 + dx = devno;
8900 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
8901 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
8902 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
8903 + : : "esi", "edi");
8904 +
8905 +@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
8906 + ei->params.length = sizeof(ei->params);
8907 + ax = 0x4800;
8908 + dx = devno;
8909 +- asm("pushfl; int $0x13; popfl"
8910 ++ asm volatile("pushfl; int $0x13; popfl"
8911 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
8912 + : "S" (&ei->params)
8913 + : "ebx", "ecx", "edi");
8914 +@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
8915 + ax = 0x0800;
8916 + dx = devno;
8917 + di = 0;
8918 +- asm("pushw %%es; "
8919 ++ asm volatile("pushw %%es; "
8920 + "movw %%di,%%es; "
8921 + "pushfl; stc; int $0x13; setc %%al; popfl; "
8922 + "popw %%es"
8923 +diff -urNp a/arch/x86/boot/main.c b/arch/x86/boot/main.c
8924 +--- a/arch/x86/boot/main.c 2008-08-20 11:16:13.000000000 -0700
8925 ++++ b/arch/x86/boot/main.c 2008-08-20 18:38:51.000000000 -0700
8926 +@@ -79,7 +79,7 @@ static void query_ist(void)
8927 + if (cpu.level < 6)
8928 + return;
8929 +
8930 +- asm("int $0x15"
8931 ++ asm volatile("int $0x15"
8932 + : "=a" (boot_params.ist_info.signature),
8933 + "=b" (boot_params.ist_info.command),
8934 + "=c" (boot_params.ist_info.event),
8935 +diff -urNp a/arch/x86/boot/mca.c b/arch/x86/boot/mca.c
8936 +--- a/arch/x86/boot/mca.c 2008-08-20 11:16:13.000000000 -0700
8937 ++++ b/arch/x86/boot/mca.c 2008-08-20 18:36:57.000000000 -0700
8938 +@@ -21,7 +21,7 @@ int query_mca(void)
8939 + u8 err;
8940 + u16 es, bx, len;
8941 +
8942 +- asm("pushw %%es ; "
8943 ++ asm volatile("pushw %%es ; "
8944 + "int $0x15 ; "
8945 + "setc %0 ; "
8946 + "movw %%es, %1 ; "
8947 +diff -urNp a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
8948 +--- a/arch/x86/boot/memory.c 2008-08-20 11:16:13.000000000 -0700
8949 ++++ b/arch/x86/boot/memory.c 2008-08-20 18:36:57.000000000 -0700
8950 +@@ -32,7 +32,7 @@ static int detect_memory_e820(void)
8951 + /* Important: %edx is clobbered by some BIOSes,
8952 + so it must be either used for the error output
8953 + or explicitly marked clobbered. */
8954 +- asm("int $0x15; setc %0"
8955 ++ asm volatile("int $0x15; setc %0"
8956 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
8957 + "=m" (*desc)
8958 + : "D" (desc), "d" (SMAP), "a" (0xe820));
8959 +@@ -67,7 +67,7 @@ static int detect_memory_e801(void)
8960 +
8961 + bx = cx = dx = 0;
8962 + ax = 0xe801;
8963 +- asm("stc; int $0x15; setc %0"
8964 ++ asm volatile("stc; int $0x15; setc %0"
8965 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
8966 +
8967 + if (err)
8968 +@@ -97,7 +97,7 @@ static int detect_memory_88(void)
8969 + u8 err;
8970 +
8971 + ax = 0x8800;
8972 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
8973 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
8974 +
8975 + boot_params.screen_info.ext_mem_k = ax;
8976 +
8977 +diff -urNp a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
8978 +--- a/arch/x86/boot/video-vesa.c 2008-08-20 11:16:13.000000000 -0700
8979 ++++ b/arch/x86/boot/video-vesa.c 2008-08-20 18:36:57.000000000 -0700
8980 +@@ -39,7 +39,7 @@ static int vesa_probe(void)
8981 +
8982 + ax = 0x4f00;
8983 + di = (size_t)&vginfo;
8984 +- asm(INT10
8985 ++ asm volatile(INT10
8986 + : "+a" (ax), "+D" (di), "=m" (vginfo)
8987 + : : "ebx", "ecx", "edx", "esi");
8988 +
8989 +@@ -66,7 +66,7 @@ static int vesa_probe(void)
8990 + ax = 0x4f01;
8991 + cx = mode;
8992 + di = (size_t)&vminfo;
8993 +- asm(INT10
8994 ++ asm volatile(INT10
8995 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
8996 + : : "ebx", "edx", "esi");
8997 +
8998 +@@ -121,7 +121,7 @@ static int vesa_set_mode(struct mode_inf
8999 + ax = 0x4f01;
9000 + cx = vesa_mode;
9001 + di = (size_t)&vminfo;
9002 +- asm(INT10
9003 ++ asm volatile(INT10
9004 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
9005 + : : "ebx", "edx", "esi");
9006 +
9007 +@@ -199,19 +199,20 @@ static void vesa_dac_set_8bits(void)
9008 + /* Save the VESA protected mode info */
9009 + static void vesa_store_pm_info(void)
9010 + {
9011 +- u16 ax, bx, di, es;
9012 ++ u16 ax, bx, cx, di, es;
9013 +
9014 + ax = 0x4f0a;
9015 +- bx = di = 0;
9016 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
9017 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
9018 +- : : "ecx", "esi");
9019 ++ bx = cx = di = 0;
9020 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
9021 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
9022 ++ : : "esi");
9023 +
9024 + if (ax != 0x004f)
9025 + return;
9026 +
9027 + boot_params.screen_info.vesapm_seg = es;
9028 + boot_params.screen_info.vesapm_off = di;
9029 ++ boot_params.screen_info.vesapm_size = cx;
9030 + }
9031 +
9032 + /*
9033 +@@ -265,7 +266,7 @@ void vesa_store_edid(void)
9034 + /* Note: The VBE DDC spec is different from the main VESA spec;
9035 + we genuinely have to assume all registers are destroyed here. */
9036 +
9037 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
9038 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
9039 + : "+a" (ax), "+b" (bx)
9040 + : "c" (cx), "D" (di)
9041 + : "esi");
9042 +@@ -281,7 +282,7 @@ void vesa_store_edid(void)
9043 + cx = 0; /* Controller 0 */
9044 + dx = 0; /* EDID block number */
9045 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
9046 +- asm(INT10
9047 ++ asm volatile(INT10
9048 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
9049 + : "c" (cx), "D" (di)
9050 + : "esi");
9051 +diff -urNp a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c
9052 +--- a/arch/x86/boot/video-vga.c 2008-08-20 11:16:13.000000000 -0700
9053 ++++ b/arch/x86/boot/video-vga.c 2008-08-20 18:36:57.000000000 -0700
9054 +@@ -225,7 +225,7 @@ static int vga_probe(void)
9055 + };
9056 + u8 vga_flag;
9057 +
9058 +- asm(INT10
9059 ++ asm volatile(INT10
9060 + : "=b" (boot_params.screen_info.orig_video_ega_bx)
9061 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
9062 + : "ecx", "edx", "esi", "edi");
9063 +@@ -233,7 +233,7 @@ static int vga_probe(void)
9064 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
9065 + if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
9066 + /* EGA/VGA */
9067 +- asm(INT10
9068 ++ asm volatile(INT10
9069 + : "=a" (vga_flag)
9070 + : "a" (0x1a00)
9071 + : "ebx", "ecx", "edx", "esi", "edi");
9072 +diff -urNp a/arch/x86/boot/video.c b/arch/x86/boot/video.c
9073 +--- a/arch/x86/boot/video.c 2008-08-20 11:16:13.000000000 -0700
9074 ++++ b/arch/x86/boot/video.c 2008-08-20 18:36:57.000000000 -0700
9075 +@@ -40,7 +40,7 @@ static void store_cursor_position(void)
9076 +
9077 + ax = 0x0300;
9078 + bx = 0;
9079 +- asm(INT10
9080 ++ asm volatile(INT10
9081 + : "=d" (curpos), "+a" (ax), "+b" (bx)
9082 + : : "ecx", "esi", "edi");
9083 +
9084 +@@ -55,7 +55,7 @@ static void store_video_mode(void)
9085 + /* N.B.: the saving of the video page here is a bit silly,
9086 + since we pretty much assume page 0 everywhere. */
9087 + ax = 0x0f00;
9088 +- asm(INT10
9089 ++ asm volatile(INT10
9090 + : "+a" (ax), "=b" (page)
9091 + : : "ecx", "edx", "esi", "edi");
9092 +
9093 +diff -urNp a/arch/x86/boot/voyager.c b/arch/x86/boot/voyager.c
9094 +--- a/arch/x86/boot/voyager.c 2008-08-20 11:16:13.000000000 -0700
9095 ++++ b/arch/x86/boot/voyager.c 2008-08-20 18:36:57.000000000 -0700
9096 +@@ -25,7 +25,7 @@ int query_voyager(void)
9097 +
9098 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
9099 +
9100 +- asm("pushw %%es ; "
9101 ++ asm volatile("pushw %%es ; "
9102 + "int $0x15 ; "
9103 + "setc %0 ; "
9104 + "movw %%es, %1 ; "
9105 +diff -urNp a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
9106 +--- a/arch/x86/ia32/ia32_signal.c 2008-08-20 11:16:13.000000000 -0700
9107 ++++ b/arch/x86/ia32/ia32_signal.c 2008-08-20 18:36:57.000000000 -0700
9108 +@@ -536,6 +536,7 @@ int ia32_setup_rt_frame(int sig, struct
9109 + __NR_ia32_rt_sigreturn,
9110 + 0x80cd,
9111 + 0,
9112 ++ 0
9113 + };
9114 +
9115 + frame = get_sigframe(ka, regs, sizeof(*frame));
9116 +diff -urNp a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
9117 +--- a/arch/x86/kernel/acpi/boot.c 2008-08-20 11:16:13.000000000 -0700
9118 ++++ b/arch/x86/kernel/acpi/boot.c 2008-08-20 18:36:57.000000000 -0700
9119 +@@ -1119,7 +1119,7 @@ static struct dmi_system_id __initdata a
9120 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
9121 + },
9122 + },
9123 +- {}
9124 ++ { NULL, NULL, {{0, NULL}}, NULL}
9125 + };
9126 +
9127 + #endif /* __i386__ */
9128 +diff -urNp a/arch/x86/kernel/acpi/sleep_32.c b/arch/x86/kernel/acpi/sleep_32.c
9129 +--- a/arch/x86/kernel/acpi/sleep_32.c 2008-08-20 11:16:13.000000000 -0700
9130 ++++ b/arch/x86/kernel/acpi/sleep_32.c 2008-08-20 18:36:57.000000000 -0700
9131 +@@ -28,7 +28,7 @@ static __initdata struct dmi_system_id a
9132 + DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
9133 + },
9134 + },
9135 +- {}
9136 ++ { NULL, NULL, {{0, NULL}}, NULL}
9137 + };
9138 +
9139 + static int __init acpisleep_dmi_init(void)
9140 +diff -urNp a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S
9141 +--- a/arch/x86/kernel/acpi/wakeup_32.S 2008-08-20 11:16:13.000000000 -0700
9142 ++++ b/arch/x86/kernel/acpi/wakeup_32.S 2008-08-20 18:36:57.000000000 -0700
9143 +@@ -2,6 +2,7 @@
9144 + #include <linux/linkage.h>
9145 + #include <asm/segment.h>
9146 + #include <asm/page.h>
9147 ++#include <asm/msr-index.h>
9148 +
9149 + #
9150 + # wakeup_code runs in real mode, and at unknown address (determined at run-time).
9151 +@@ -79,7 +80,7 @@ wakeup_code:
9152 + # restore efer setting
9153 + movl real_save_efer_edx - wakeup_code, %edx
9154 + movl real_save_efer_eax - wakeup_code, %eax
9155 +- mov $0xc0000080, %ecx
9156 ++ mov $MSR_EFER, %ecx
9157 + wrmsr
9158 + 4:
9159 + # make sure %cr4 is set correctly (features, etc)
9160 +@@ -196,13 +197,11 @@ wakeup_pmode_return:
9161 + # and restore the stack ... but you need gdt for this to work
9162 + movl saved_context_esp, %esp
9163 +
9164 +- movl %cs:saved_magic, %eax
9165 +- cmpl $0x12345678, %eax
9166 ++ cmpl $0x12345678, saved_magic
9167 + jne bogus_magic
9168 +
9169 + # jump to place where we left off
9170 +- movl saved_eip,%eax
9171 +- jmp *%eax
9172 ++ jmp *(saved_eip)
9173 +
9174 + bogus_magic:
9175 + jmp bogus_magic
9176 +@@ -233,7 +232,7 @@ ENTRY(acpi_copy_wakeup_routine)
9177 + # save efer setting
9178 + pushl %eax
9179 + movl %eax, %ebx
9180 +- mov $0xc0000080, %ecx
9181 ++ mov $MSR_EFER, %ecx
9182 + rdmsr
9183 + movl %edx, real_save_efer_edx - wakeup_start (%ebx)
9184 + movl %eax, real_save_efer_eax - wakeup_start (%ebx)
9185 +diff -urNp a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
9186 +--- a/arch/x86/kernel/alternative.c 2008-08-20 11:16:13.000000000 -0700
9187 ++++ b/arch/x86/kernel/alternative.c 2008-08-20 18:36:57.000000000 -0700
9188 +@@ -403,7 +403,7 @@ void apply_paravirt(struct paravirt_patc
9189 +
9190 + BUG_ON(p->len > MAX_PATCH_LEN);
9191 + /* prep the buffer with the original instructions */
9192 +- memcpy(insnbuf, p->instr, p->len);
9193 ++ memcpy(insnbuf, ktla_ktva(p->instr), p->len);
9194 + used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
9195 + (unsigned long)p->instr, p->len);
9196 +
9197 +@@ -485,7 +485,19 @@ void __init alternative_instructions(voi
9198 + */
9199 + void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
9200 + {
9201 +- memcpy(addr, opcode, len);
9202 ++
9203 ++#ifdef CONFIG_PAX_KERNEXEC
9204 ++ unsigned long cr0;
9205 ++
9206 ++ pax_open_kernel(cr0);
9207 ++#endif
9208 ++
9209 ++ memcpy(ktla_ktva(addr), opcode, len);
9210 ++
9211 ++#ifdef CONFIG_PAX_KERNEXEC
9212 ++ pax_close_kernel(cr0);
9213 ++#endif
9214 ++
9215 + sync_core();
9216 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
9217 + that causes hangs on some VIA CPUs. */
9218 +diff -urNp a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
9219 +--- a/arch/x86/kernel/apm_32.c 2008-08-20 11:16:13.000000000 -0700
9220 ++++ b/arch/x86/kernel/apm_32.c 2008-08-20 18:36:57.000000000 -0700
9221 +@@ -406,7 +406,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
9222 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
9223 + static struct apm_user *user_list;
9224 + static DEFINE_SPINLOCK(user_list_lock);
9225 +-static const struct desc_struct bad_bios_desc = { { { 0, 0x00409200 } } };
9226 ++static const struct desc_struct bad_bios_desc = { { { 0, 0x00409300 } } };
9227 +
9228 + static const char driver_version[] = "1.16ac"; /* no spaces */
9229 +
9230 +@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
9231 + struct desc_struct save_desc_40;
9232 + struct desc_struct *gdt;
9233 +
9234 ++#ifdef CONFIG_PAX_KERNEXEC
9235 ++ unsigned long cr0;
9236 ++#endif
9237 ++
9238 + cpus = apm_save_cpus();
9239 +
9240 + cpu = get_cpu();
9241 + gdt = get_cpu_gdt_table(cpu);
9242 + save_desc_40 = gdt[0x40 / 8];
9243 ++
9244 ++#ifdef CONFIG_PAX_KERNEXEC
9245 ++ pax_open_kernel(cr0);
9246 ++#endif
9247 ++
9248 + gdt[0x40 / 8] = bad_bios_desc;
9249 +
9250 ++#ifdef CONFIG_PAX_KERNEXEC
9251 ++ pax_close_kernel(cr0);
9252 ++#endif
9253 ++
9254 + apm_irq_save(flags);
9255 + APM_DO_SAVE_SEGS;
9256 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
9257 + APM_DO_RESTORE_SEGS;
9258 + apm_irq_restore(flags);
9259 ++
9260 ++#ifdef CONFIG_PAX_KERNEXEC
9261 ++ pax_open_kernel(cr0);
9262 ++#endif
9263 ++
9264 + gdt[0x40 / 8] = save_desc_40;
9265 ++
9266 ++#ifdef CONFIG_PAX_KERNEXEC
9267 ++ pax_close_kernel(cr0);
9268 ++#endif
9269 ++
9270 + put_cpu();
9271 + apm_restore_cpus(cpus);
9272 +
9273 +@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
9274 + struct desc_struct save_desc_40;
9275 + struct desc_struct *gdt;
9276 +
9277 ++#ifdef CONFIG_PAX_KERNEXEC
9278 ++ unsigned long cr0;
9279 ++#endif
9280 ++
9281 + cpus = apm_save_cpus();
9282 +
9283 + cpu = get_cpu();
9284 + gdt = get_cpu_gdt_table(cpu);
9285 + save_desc_40 = gdt[0x40 / 8];
9286 ++
9287 ++#ifdef CONFIG_PAX_KERNEXEC
9288 ++ pax_open_kernel(cr0);
9289 ++#endif
9290 ++
9291 + gdt[0x40 / 8] = bad_bios_desc;
9292 +
9293 ++#ifdef CONFIG_PAX_KERNEXEC
9294 ++ pax_close_kernel(cr0);
9295 ++#endif
9296 ++
9297 + apm_irq_save(flags);
9298 + APM_DO_SAVE_SEGS;
9299 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
9300 + APM_DO_RESTORE_SEGS;
9301 + apm_irq_restore(flags);
9302 ++
9303 ++#ifdef CONFIG_PAX_KERNEXEC
9304 ++ pax_open_kernel(cr0);
9305 ++#endif
9306 ++
9307 + gdt[0x40 / 8] = save_desc_40;
9308 ++
9309 ++#ifdef CONFIG_PAX_KERNEXEC
9310 ++ pax_close_kernel(cr0);
9311 ++#endif
9312 ++
9313 + put_cpu();
9314 + apm_restore_cpus(cpus);
9315 + return error;
9316 +@@ -925,7 +971,7 @@ recalc:
9317 +
9318 + static void apm_power_off(void)
9319 + {
9320 +- unsigned char po_bios_call[] = {
9321 ++ const unsigned char po_bios_call[] = {
9322 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
9323 + 0x8e, 0xd0, /* movw ax,ss */
9324 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
9325 +@@ -1881,7 +1927,10 @@ static const struct file_operations apm_
9326 + static struct miscdevice apm_device = {
9327 + APM_MINOR_DEV,
9328 + "apm_bios",
9329 +- &apm_bios_fops
9330 ++ &apm_bios_fops,
9331 ++ {NULL, NULL},
9332 ++ NULL,
9333 ++ NULL
9334 + };
9335 +
9336 +
9337 +@@ -2202,7 +2251,7 @@ static struct dmi_system_id __initdata a
9338 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
9339 + },
9340 +
9341 +- { }
9342 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
9343 + };
9344 +
9345 + /*
9346 +@@ -2221,6 +2270,10 @@ static int __init apm_init(void)
9347 + struct desc_struct *gdt;
9348 + int err;
9349 +
9350 ++#ifdef CONFIG_PAX_KERNEXEC
9351 ++ unsigned long cr0;
9352 ++#endif
9353 ++
9354 + dmi_check_system(apm_dmi_table);
9355 +
9356 + if (apm_info.bios.version == 0 || paravirt_enabled()) {
9357 +@@ -2294,9 +2347,18 @@ static int __init apm_init(void)
9358 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
9359 + * even though they are called in protected mode.
9360 + */
9361 ++
9362 ++#ifdef CONFIG_PAX_KERNEXEC
9363 ++ pax_open_kernel(cr0);
9364 ++#endif
9365 ++
9366 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
9367 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
9368 +
9369 ++#ifdef CONFIG_PAX_KERNEXEC
9370 ++ pax_close_kernel(cr0);
9371 ++#endif
9372 ++
9373 + /*
9374 + * Set up the long jump entry point to the APM BIOS, which is called
9375 + * from inline assembly.
9376 +@@ -2315,6 +2377,11 @@ static int __init apm_init(void)
9377 + * code to that CPU.
9378 + */
9379 + gdt = get_cpu_gdt_table(0);
9380 ++
9381 ++#ifdef CONFIG_PAX_KERNEXEC
9382 ++ pax_open_kernel(cr0);
9383 ++#endif
9384 ++
9385 + set_base(gdt[APM_CS >> 3],
9386 + __va((unsigned long)apm_info.bios.cseg << 4));
9387 + set_base(gdt[APM_CS_16 >> 3],
9388 +@@ -2322,6 +2389,10 @@ static int __init apm_init(void)
9389 + set_base(gdt[APM_DS >> 3],
9390 + __va((unsigned long)apm_info.bios.dseg << 4));
9391 +
9392 ++#ifdef CONFIG_PAX_KERNEXEC
9393 ++ pax_close_kernel(cr0);
9394 ++#endif
9395 ++
9396 + apm_proc = create_proc_entry("apm", 0, NULL);
9397 + if (apm_proc)
9398 + apm_proc->proc_fops = &apm_file_ops;
9399 +diff -urNp a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
9400 +--- a/arch/x86/kernel/asm-offsets_32.c 2008-08-20 11:16:13.000000000 -0700
9401 ++++ b/arch/x86/kernel/asm-offsets_32.c 2008-08-20 18:36:57.000000000 -0700
9402 +@@ -107,6 +107,7 @@ void foo(void)
9403 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
9404 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
9405 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
9406 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
9407 +
9408 + OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
9409 +
9410 +@@ -120,6 +121,7 @@ void foo(void)
9411 + OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
9412 + OFFSET(PV_CPU_irq_enable_syscall_ret, pv_cpu_ops, irq_enable_syscall_ret);
9413 + OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
9414 ++ OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
9415 + #endif
9416 +
9417 + #ifdef CONFIG_XEN
9418 +diff -urNp a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
9419 +--- a/arch/x86/kernel/asm-offsets_64.c 2008-08-20 11:16:13.000000000 -0700
9420 ++++ b/arch/x86/kernel/asm-offsets_64.c 2008-08-20 18:36:57.000000000 -0700
9421 +@@ -124,6 +124,7 @@ int main(void)
9422 + ENTRY(cr8);
9423 + BLANK();
9424 + #undef ENTRY
9425 ++ DEFINE(TSS_size, sizeof(struct tss_struct));
9426 + DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
9427 + BLANK();
9428 + DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
9429 +diff -urNp a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
9430 +--- a/arch/x86/kernel/cpu/common.c 2008-08-20 11:16:13.000000000 -0700
9431 ++++ b/arch/x86/kernel/cpu/common.c 2008-08-20 18:36:57.000000000 -0700
9432 +@@ -4,7 +4,6 @@
9433 + #include <linux/smp.h>
9434 + #include <linux/module.h>
9435 + #include <linux/percpu.h>
9436 +-#include <linux/bootmem.h>
9437 + #include <asm/semaphore.h>
9438 + #include <asm/processor.h>
9439 + #include <asm/i387.h>
9440 +@@ -21,42 +20,6 @@
9441 +
9442 + #include "cpu.h"
9443 +
9444 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
9445 +- [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
9446 +- [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
9447 +- [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
9448 +- [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
9449 +- /*
9450 +- * Segments used for calling PnP BIOS have byte granularity.
9451 +- * They code segments and data segments have fixed 64k limits,
9452 +- * the transfer segment sizes are set at run time.
9453 +- */
9454 +- /* 32-bit code */
9455 +- [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
9456 +- /* 16-bit code */
9457 +- [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
9458 +- /* 16-bit data */
9459 +- [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
9460 +- /* 16-bit data */
9461 +- [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
9462 +- /* 16-bit data */
9463 +- [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
9464 +- /*
9465 +- * The APM segments have byte granularity and their bases
9466 +- * are set at run time. All have 64k limits.
9467 +- */
9468 +- /* 32-bit code */
9469 +- [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
9470 +- /* 16-bit code */
9471 +- [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
9472 +- /* data */
9473 +- [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
9474 +-
9475 +- [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
9476 +- [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
9477 +-} };
9478 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
9479 +-
9480 + __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
9481 +
9482 + static int cachesize_override __cpuinitdata = -1;
9483 +@@ -478,6 +441,10 @@ void __cpuinit identify_cpu(struct cpuin
9484 + * we do "generic changes."
9485 + */
9486 +
9487 ++#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
9488 ++ setup_clear_cpu_cap(X86_FEATURE_SEP);
9489 ++#endif
9490 ++
9491 + /* If the model name is still unset, do table lookup. */
9492 + if ( !c->x86_model_id[0] ) {
9493 + char *p;
9494 +@@ -614,7 +581,7 @@ static __init int setup_disablecpuid(cha
9495 + }
9496 + __setup("clearcpuid=", setup_disablecpuid);
9497 +
9498 +-cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
9499 ++cpumask_t cpu_initialized = CPU_MASK_NONE;
9500 +
9501 + /* This is hacky. :)
9502 + * We're emulating future behavior.
9503 +@@ -650,7 +617,7 @@ void switch_to_new_gdt(void)
9504 + {
9505 + struct desc_ptr gdt_descr;
9506 +
9507 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
9508 ++ gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
9509 + gdt_descr.size = GDT_SIZE - 1;
9510 + load_gdt(&gdt_descr);
9511 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
9512 +@@ -666,7 +633,7 @@ void __cpuinit cpu_init(void)
9513 + {
9514 + int cpu = smp_processor_id();
9515 + struct task_struct *curr = current;
9516 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
9517 ++ struct tss_struct *t = init_tss + cpu;
9518 + struct thread_struct *thread = &curr->thread;
9519 +
9520 + if (cpu_test_and_set(cpu, cpu_initialized)) {
9521 +@@ -721,7 +688,7 @@ void __cpuinit cpu_init(void)
9522 + }
9523 +
9524 + #ifdef CONFIG_HOTPLUG_CPU
9525 +-void __cpuinit cpu_uninit(void)
9526 ++void cpu_uninit(void)
9527 + {
9528 + int cpu = raw_smp_processor_id();
9529 + cpu_clear(cpu, cpu_initialized);
9530 +diff -urNp a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
9531 +--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-08-20 11:16:13.000000000 -0700
9532 ++++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-08-20 18:36:57.000000000 -0700
9533 +@@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
9534 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
9535 + },
9536 + },
9537 +- { }
9538 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
9539 + };
9540 + #endif
9541 +
9542 +diff -urNp a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
9543 +--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-08-20 11:16:13.000000000 -0700
9544 ++++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c 2008-08-20 18:36:57.000000000 -0700
9545 +@@ -223,7 +223,7 @@ static struct cpu_model models[] =
9546 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
9547 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
9548 +
9549 +- { NULL, }
9550 ++ { NULL, NULL, 0, NULL}
9551 + };
9552 + #undef _BANIAS
9553 + #undef BANIAS
9554 +diff -urNp a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
9555 +--- a/arch/x86/kernel/cpu/intel.c 2008-08-20 11:16:13.000000000 -0700
9556 ++++ b/arch/x86/kernel/cpu/intel.c 2008-08-20 18:36:57.000000000 -0700
9557 +@@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
9558 + * Update the IDT descriptor and reload the IDT so that
9559 + * it uses the read-only mapped virtual address.
9560 + */
9561 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
9562 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
9563 + load_idt(&idt_descr);
9564 + }
9565 + #endif
9566 +diff -urNp a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
9567 +--- a/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-08-20 11:16:13.000000000 -0700
9568 ++++ b/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-08-20 18:36:57.000000000 -0700
9569 +@@ -670,6 +670,7 @@ static struct miscdevice mce_log_device
9570 + MISC_MCELOG_MINOR,
9571 + "mcelog",
9572 + &mce_chrdev_ops,
9573 ++ {NULL, NULL}, NULL, NULL
9574 + };
9575 +
9576 + static unsigned long old_cr4 __initdata;
9577 +diff -urNp a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
9578 +--- a/arch/x86/kernel/cpu/mtrr/generic.c 2008-08-20 11:16:13.000000000 -0700
9579 ++++ b/arch/x86/kernel/cpu/mtrr/generic.c 2008-08-20 18:36:57.000000000 -0700
9580 +@@ -30,11 +30,11 @@ static struct fixed_range_block fixed_ra
9581 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
9582 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
9583 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
9584 +- {}
9585 ++ { 0, 0 }
9586 + };
9587 +
9588 + static unsigned long smp_changes_mask;
9589 +-static struct mtrr_state mtrr_state = {};
9590 ++static struct mtrr_state mtrr_state;
9591 +
9592 + #undef MODULE_PARAM_PREFIX
9593 + #define MODULE_PARAM_PREFIX "mtrr."
9594 +diff -urNp a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
9595 +--- a/arch/x86/kernel/crash.c 2008-08-20 11:16:13.000000000 -0700
9596 ++++ b/arch/x86/kernel/crash.c 2008-08-20 18:36:57.000000000 -0700
9597 +@@ -62,7 +62,7 @@ static int crash_nmi_callback(struct not
9598 + local_irq_disable();
9599 +
9600 + #ifdef CONFIG_X86_32
9601 +- if (!user_mode_vm(regs)) {
9602 ++ if (!user_mode(regs)) {
9603 + crash_fixup_ss_esp(&fixed_regs, regs);
9604 + regs = &fixed_regs;
9605 + }
9606 +diff -urNp a/arch/x86/kernel/doublefault_32.c b/arch/x86/kernel/doublefault_32.c
9607 +--- a/arch/x86/kernel/doublefault_32.c 2008-08-20 11:16:13.000000000 -0700
9608 ++++ b/arch/x86/kernel/doublefault_32.c 2008-08-20 18:36:57.000000000 -0700
9609 +@@ -11,7 +11,7 @@
9610 +
9611 + #define DOUBLEFAULT_STACKSIZE (1024)
9612 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
9613 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
9614 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
9615 +
9616 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
9617 +
9618 +@@ -21,7 +21,7 @@ static void doublefault_fn(void)
9619 + unsigned long gdt, tss;
9620 +
9621 + store_gdt(&gdt_desc);
9622 +- gdt = gdt_desc.address;
9623 ++ gdt = (unsigned long)gdt_desc.address;
9624 +
9625 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
9626 +
9627 +@@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
9628 + /* 0x2 bit is always set */
9629 + .flags = X86_EFLAGS_SF | 0x2,
9630 + .sp = STACK_START,
9631 +- .es = __USER_DS,
9632 ++ .es = __KERNEL_DS,
9633 + .cs = __KERNEL_CS,
9634 + .ss = __KERNEL_DS,
9635 +- .ds = __USER_DS,
9636 ++ .ds = __KERNEL_DS,
9637 + .fs = __KERNEL_PERCPU,
9638 +
9639 + .__cr3 = __pa(swapper_pg_dir)
9640 +diff -urNp a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
9641 +--- a/arch/x86/kernel/efi_32.c 2008-08-20 11:16:13.000000000 -0700
9642 ++++ b/arch/x86/kernel/efi_32.c 2008-08-20 18:36:57.000000000 -0700
9643 +@@ -38,70 +38,37 @@
9644 + */
9645 +
9646 + static unsigned long efi_rt_eflags;
9647 +-static pgd_t efi_bak_pg_dir_pointer[2];
9648 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
9649 +
9650 +-void efi_call_phys_prelog(void)
9651 ++void __init efi_call_phys_prelog(void)
9652 + {
9653 +- unsigned long cr4;
9654 +- unsigned long temp;
9655 + struct desc_ptr gdt_descr;
9656 +
9657 + local_irq_save(efi_rt_eflags);
9658 +
9659 +- /*
9660 +- * If I don't have PSE, I should just duplicate two entries in page
9661 +- * directory. If I have PSE, I just need to duplicate one entry in
9662 +- * page directory.
9663 +- */
9664 +- cr4 = read_cr4();
9665 +-
9666 +- if (cr4 & X86_CR4_PSE) {
9667 +- efi_bak_pg_dir_pointer[0].pgd =
9668 +- swapper_pg_dir[pgd_index(0)].pgd;
9669 +- swapper_pg_dir[0].pgd =
9670 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
9671 +- } else {
9672 +- efi_bak_pg_dir_pointer[0].pgd =
9673 +- swapper_pg_dir[pgd_index(0)].pgd;
9674 +- efi_bak_pg_dir_pointer[1].pgd =
9675 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
9676 +- swapper_pg_dir[pgd_index(0)].pgd =
9677 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
9678 +- temp = PAGE_OFFSET + 0x400000;
9679 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
9680 +- swapper_pg_dir[pgd_index(temp)].pgd;
9681 +- }
9682 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
9683 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
9684 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
9685 +
9686 + /*
9687 + * After the lock is released, the original page table is restored.
9688 + */
9689 + __flush_tlb_all();
9690 +
9691 +- gdt_descr.address = __pa(get_cpu_gdt_table(0));
9692 ++ gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
9693 + gdt_descr.size = GDT_SIZE - 1;
9694 + load_gdt(&gdt_descr);
9695 + }
9696 +
9697 +-void efi_call_phys_epilog(void)
9698 ++void __init efi_call_phys_epilog(void)
9699 + {
9700 +- unsigned long cr4;
9701 + struct desc_ptr gdt_descr;
9702 +
9703 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
9704 ++ gdt_descr.address = get_cpu_gdt_table(0);
9705 + gdt_descr.size = GDT_SIZE - 1;
9706 + load_gdt(&gdt_descr);
9707 +
9708 +- cr4 = read_cr4();
9709 +-
9710 +- if (cr4 & X86_CR4_PSE) {
9711 +- swapper_pg_dir[pgd_index(0)].pgd =
9712 +- efi_bak_pg_dir_pointer[0].pgd;
9713 +- } else {
9714 +- swapper_pg_dir[pgd_index(0)].pgd =
9715 +- efi_bak_pg_dir_pointer[0].pgd;
9716 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
9717 +- efi_bak_pg_dir_pointer[1].pgd;
9718 +- }
9719 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
9720 +
9721 + /*
9722 + * After the lock is released, the original page table is restored.
9723 +diff -urNp a/arch/x86/kernel/efi_stub_32.S b/arch/x86/kernel/efi_stub_32.S
9724 +--- a/arch/x86/kernel/efi_stub_32.S 2008-08-20 11:16:13.000000000 -0700
9725 ++++ b/arch/x86/kernel/efi_stub_32.S 2008-08-20 18:36:57.000000000 -0700
9726 +@@ -6,6 +6,7 @@
9727 + */
9728 +
9729 + #include <linux/linkage.h>
9730 ++#include <linux/init.h>
9731 + #include <asm/page.h>
9732 +
9733 + /*
9734 +@@ -20,7 +21,7 @@
9735 + * service functions will comply with gcc calling convention, too.
9736 + */
9737 +
9738 +-.text
9739 ++__INIT
9740 + ENTRY(efi_call_phys)
9741 + /*
9742 + * 0. The function can only be called in Linux kernel. So CS has been
9743 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
9744 + * The mapping of lower virtual memory has been created in prelog and
9745 + * epilog.
9746 + */
9747 +- movl $1f, %edx
9748 +- subl $__PAGE_OFFSET, %edx
9749 +- jmp *%edx
9750 ++ jmp 1f-__PAGE_OFFSET
9751 + 1:
9752 +
9753 + /*
9754 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
9755 + * parameter 2, ..., param n. To make things easy, we save the return
9756 + * address of efi_call_phys in a global variable.
9757 + */
9758 +- popl %edx
9759 +- movl %edx, saved_return_addr
9760 +- /* get the function pointer into ECX*/
9761 +- popl %ecx
9762 +- movl %ecx, efi_rt_function_ptr
9763 +- movl $2f, %edx
9764 +- subl $__PAGE_OFFSET, %edx
9765 +- pushl %edx
9766 ++ popl (saved_return_addr)
9767 ++ popl (efi_rt_function_ptr)
9768 +
9769 + /*
9770 + * 3. Clear PG bit in %CR0.
9771 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
9772 + /*
9773 + * 5. Call the physical function.
9774 + */
9775 +- jmp *%ecx
9776 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
9777 +
9778 +-2:
9779 + /*
9780 + * 6. After EFI runtime service returns, control will return to
9781 + * following instruction. We'd better readjust stack pointer first.
9782 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
9783 + movl %cr0, %edx
9784 + orl $0x80000000, %edx
9785 + movl %edx, %cr0
9786 +- jmp 1f
9787 +-1:
9788 ++
9789 + /*
9790 + * 8. Now restore the virtual mode from flat mode by
9791 + * adding EIP with PAGE_OFFSET.
9792 + */
9793 +- movl $1f, %edx
9794 +- jmp *%edx
9795 ++ jmp 1f+__PAGE_OFFSET
9796 + 1:
9797 +
9798 + /*
9799 + * 9. Balance the stack. And because EAX contain the return value,
9800 + * we'd better not clobber it.
9801 + */
9802 +- leal efi_rt_function_ptr, %edx
9803 +- movl (%edx), %ecx
9804 +- pushl %ecx
9805 ++ pushl (efi_rt_function_ptr)
9806 +
9807 + /*
9808 +- * 10. Push the saved return address onto the stack and return.
9809 ++ * 10. Return to the saved return address.
9810 + */
9811 +- leal saved_return_addr, %edx
9812 +- movl (%edx), %ecx
9813 +- pushl %ecx
9814 +- ret
9815 ++ jmpl *(saved_return_addr)
9816 + .previous
9817 +
9818 +-.data
9819 ++__INITDATA
9820 + saved_return_addr:
9821 + .long 0
9822 + efi_rt_function_ptr:
9823 +diff -urNp a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
9824 +--- a/arch/x86/kernel/entry_32.S 2008-08-20 11:16:13.000000000 -0700
9825 ++++ b/arch/x86/kernel/entry_32.S 2008-08-20 18:36:57.000000000 -0700
9826 +@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
9827 + #define resume_userspace_sig resume_userspace
9828 + #endif
9829 +
9830 +-#define SAVE_ALL \
9831 ++#define __SAVE_ALL(_DS) \
9832 + cld; \
9833 + pushl %fs; \
9834 + CFI_ADJUST_CFA_OFFSET 4;\
9835 +@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
9836 + pushl %ebx; \
9837 + CFI_ADJUST_CFA_OFFSET 4;\
9838 + CFI_REL_OFFSET ebx, 0;\
9839 +- movl $(__USER_DS), %edx; \
9840 ++ movl $(_DS), %edx; \
9841 + movl %edx, %ds; \
9842 + movl %edx, %es; \
9843 + movl $(__KERNEL_PERCPU), %edx; \
9844 + movl %edx, %fs
9845 +
9846 ++#ifdef CONFIG_PAX_KERNEXEC
9847 ++#define SAVE_ALL \
9848 ++ __SAVE_ALL(__KERNEL_DS); \
9849 ++ GET_CR0_INTO_EDX; \
9850 ++ movl %edx, %esi; \
9851 ++ orl $X86_CR0_WP, %edx; \
9852 ++ xorl %edx, %esi; \
9853 ++ SET_CR0_FROM_EDX
9854 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
9855 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
9856 ++#else
9857 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
9858 ++#endif
9859 ++
9860 + #define RESTORE_INT_REGS \
9861 + popl %ebx; \
9862 + CFI_ADJUST_CFA_OFFSET -4;\
9863 +@@ -225,6 +239,11 @@ ENTRY(ret_from_fork)
9864 + CFI_ADJUST_CFA_OFFSET 4
9865 + popfl
9866 + CFI_ADJUST_CFA_OFFSET -4
9867 ++
9868 ++#ifdef CONFIG_PAX_KERNEXEC
9869 ++ xorl %esi, %esi
9870 ++#endif
9871 ++
9872 + jmp syscall_exit
9873 + CFI_ENDPROC
9874 + END(ret_from_fork)
9875 +@@ -248,7 +267,17 @@ check_userspace:
9876 + movb PT_CS(%esp), %al
9877 + andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
9878 + cmpl $USER_RPL, %eax
9879 ++
9880 ++#ifdef CONFIG_PAX_KERNEXEC
9881 ++ jae resume_userspace
9882 ++
9883 ++ GET_CR0_INTO_EDX
9884 ++ xorl %esi, %edx
9885 ++ SET_CR0_FROM_EDX
9886 ++ jmp resume_kernel
9887 ++#else
9888 + jb resume_kernel # not returning to v8086 or userspace
9889 ++#endif
9890 +
9891 + ENTRY(resume_userspace)
9892 + LOCKDEP_SYS_EXIT
9893 +@@ -308,10 +337,9 @@ sysenter_past_esp:
9894 + /*CFI_REL_OFFSET cs, 0*/
9895 + /*
9896 + * Push current_thread_info()->sysenter_return to the stack.
9897 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
9898 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
9899 + */
9900 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
9901 ++ GET_THREAD_INFO(%ebp)
9902 ++ pushl TI_sysenter_return(%ebp)
9903 + CFI_ADJUST_CFA_OFFSET 4
9904 + CFI_REL_OFFSET eip, 0
9905 +
9906 +@@ -319,9 +347,17 @@ sysenter_past_esp:
9907 + * Load the potential sixth argument from user stack.
9908 + * Careful about security.
9909 + */
9910 ++ movl 12(%esp),%ebp
9911 ++
9912 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
9913 ++ mov 16(%esp),%ds
9914 ++1: movl %ds:(%ebp),%ebp
9915 ++#else
9916 + cmpl $__PAGE_OFFSET-3,%ebp
9917 + jae syscall_fault
9918 + 1: movl (%ebp),%ebp
9919 ++#endif
9920 ++
9921 + .section __ex_table,"a"
9922 + .align 4
9923 + .long 1b,syscall_fault
9924 +@@ -345,20 +381,37 @@ sysenter_past_esp:
9925 + movl TI_flags(%ebp), %ecx
9926 + testw $_TIF_ALLWORK_MASK, %cx
9927 + jne syscall_exit_work
9928 ++
9929 ++#ifdef CONFIG_PAX_RANDKSTACK
9930 ++ pushl %eax
9931 ++ CFI_ADJUST_CFA_OFFSET 4
9932 ++ call pax_randomize_kstack
9933 ++ popl %eax
9934 ++ CFI_ADJUST_CFA_OFFSET -4
9935 ++#endif
9936 ++
9937 + /* if something modifies registers it must also disable sysexit */
9938 + movl PT_EIP(%esp), %edx
9939 + movl PT_OLDESP(%esp), %ecx
9940 + xorl %ebp,%ebp
9941 + TRACE_IRQS_ON
9942 + 1: mov PT_FS(%esp), %fs
9943 ++2: mov PT_DS(%esp), %ds
9944 ++3: mov PT_ES(%esp), %es
9945 + ENABLE_INTERRUPTS_SYSCALL_RET
9946 + CFI_ENDPROC
9947 + .pushsection .fixup,"ax"
9948 +-2: movl $0,PT_FS(%esp)
9949 ++4: movl $0,PT_FS(%esp)
9950 ++ jmp 1b
9951 ++5: movl $0,PT_DS(%esp)
9952 ++ jmp 1b
9953 ++6: movl $0,PT_ES(%esp)
9954 + jmp 1b
9955 + .section __ex_table,"a"
9956 + .align 4
9957 +- .long 1b,2b
9958 ++ .long 1b,4b
9959 ++ .long 2b,5b
9960 ++ .long 3b,6b
9961 + .popsection
9962 + ENDPROC(ia32_sysenter_target)
9963 +
9964 +@@ -392,6 +445,10 @@ no_singlestep:
9965 + testw $_TIF_ALLWORK_MASK, %cx # current->work
9966 + jne syscall_exit_work
9967 +
9968 ++#ifdef CONFIG_PAX_RANDKSTACK
9969 ++ call pax_randomize_kstack
9970 ++#endif
9971 ++
9972 + restore_all:
9973 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
9974 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
9975 +@@ -485,25 +542,19 @@ work_resched:
9976 +
9977 + work_notifysig: # deal with pending signals and
9978 + # notify-resume requests
9979 ++ movl %esp, %eax
9980 + #ifdef CONFIG_VM86
9981 + testl $VM_MASK, PT_EFLAGS(%esp)
9982 +- movl %esp, %eax
9983 +- jne work_notifysig_v86 # returning to kernel-space or
9984 ++ jz 1f # returning to kernel-space or
9985 + # vm86-space
9986 +- xorl %edx, %edx
9987 +- call do_notify_resume
9988 +- jmp resume_userspace_sig
9989 +
9990 +- ALIGN
9991 +-work_notifysig_v86:
9992 + pushl %ecx # save ti_flags for do_notify_resume
9993 + CFI_ADJUST_CFA_OFFSET 4
9994 + call save_v86_state # %eax contains pt_regs pointer
9995 + popl %ecx
9996 + CFI_ADJUST_CFA_OFFSET -4
9997 + movl %eax, %esp
9998 +-#else
9999 +- movl %esp, %eax
10000 ++1:
10001 + #endif
10002 + xorl %edx, %edx
10003 + call do_notify_resume
10004 +@@ -557,17 +608,24 @@ syscall_badsys:
10005 + END(syscall_badsys)
10006 + CFI_ENDPROC
10007 +
10008 +-#define FIXUP_ESPFIX_STACK \
10009 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
10010 +- PER_CPU(gdt_page, %ebx); \
10011 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
10012 +- addl %esp, %eax; \
10013 +- pushl $__KERNEL_DS; \
10014 +- CFI_ADJUST_CFA_OFFSET 4; \
10015 +- pushl %eax; \
10016 +- CFI_ADJUST_CFA_OFFSET 4; \
10017 +- lss (%esp), %esp; \
10018 ++.macro FIXUP_ESPFIX_STACK
10019 ++ /* since we are on a wrong stack, we cant make it a C code :( */
10020 ++#ifdef CONFIG_SMP
10021 ++ movl PER_CPU_VAR(cpu_number), %ebx;
10022 ++ shll $PAGE_SHIFT_asm, %ebx;
10023 ++ addl $cpu_gdt_table, %ebx;
10024 ++#else
10025 ++ movl $cpu_gdt_table, %ebx;
10026 ++#endif
10027 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
10028 ++ addl %esp, %eax;
10029 ++ pushl $__KERNEL_DS;
10030 ++ CFI_ADJUST_CFA_OFFSET 4;
10031 ++ pushl %eax;
10032 ++ CFI_ADJUST_CFA_OFFSET 4;
10033 ++ lss (%esp), %esp;
10034 + CFI_ADJUST_CFA_OFFSET -8;
10035 ++.endm
10036 + #define UNWIND_ESPFIX_STACK \
10037 + movl %ss, %eax; \
10038 + /* see if on espfix stack */ \
10039 +@@ -584,7 +642,7 @@ END(syscall_badsys)
10040 + * Build the entry stubs and pointer table with
10041 + * some assembler magic.
10042 + */
10043 +-.section .rodata,"a"
10044 ++.section .rodata,"a",@progbits
10045 + ENTRY(interrupt)
10046 + .text
10047 +
10048 +@@ -684,12 +742,21 @@ error_code:
10049 + popl %ecx
10050 + CFI_ADJUST_CFA_OFFSET -4
10051 + /*CFI_REGISTER es, ecx*/
10052 ++
10053 ++#ifdef CONFIG_PAX_KERNEXEC
10054 ++ GET_CR0_INTO_EDX
10055 ++ movl %edx, %esi
10056 ++ orl $X86_CR0_WP, %edx
10057 ++ xorl %edx, %esi
10058 ++ SET_CR0_FROM_EDX
10059 ++#endif
10060 ++
10061 + movl PT_FS(%esp), %edi # get the function address
10062 + movl PT_ORIG_EAX(%esp), %edx # get the error code
10063 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
10064 + mov %ecx, PT_FS(%esp)
10065 + /*CFI_REL_OFFSET fs, ES*/
10066 +- movl $(__USER_DS), %ecx
10067 ++ movl $(__KERNEL_DS), %ecx
10068 + movl %ecx, %ds
10069 + movl %ecx, %es
10070 + movl %esp,%eax # pt_regs pointer
10071 +@@ -823,6 +890,13 @@ nmi_stack_correct:
10072 + xorl %edx,%edx # zero error code
10073 + movl %esp,%eax # pt_regs pointer
10074 + call do_nmi
10075 ++
10076 ++#ifdef CONFIG_PAX_KERNEXEC
10077 ++ GET_CR0_INTO_EDX
10078 ++ xorl %esi, %edx
10079 ++ SET_CR0_FROM_EDX
10080 ++#endif
10081 ++
10082 + jmp restore_nocheck_notrace
10083 + CFI_ENDPROC
10084 +
10085 +@@ -863,6 +937,13 @@ nmi_espfix_stack:
10086 + FIXUP_ESPFIX_STACK # %eax == %esp
10087 + xorl %edx,%edx # zero error code
10088 + call do_nmi
10089 ++
10090 ++#ifdef CONFIG_PAX_KERNEXEC
10091 ++ GET_CR0_INTO_EDX
10092 ++ xorl %esi, %edx
10093 ++ SET_CR0_FROM_EDX
10094 ++#endif
10095 ++
10096 + RESTORE_REGS
10097 + lss 12+4(%esp), %esp # back to espfix stack
10098 + CFI_ADJUST_CFA_OFFSET -24
10099 +@@ -1107,7 +1188,6 @@ ENDPROC(xen_failsafe_callback)
10100 +
10101 + #endif /* CONFIG_XEN */
10102 +
10103 +-.section .rodata,"a"
10104 + #include "syscall_table_32.S"
10105 +
10106 + syscall_table_size=(.-sys_call_table)
10107 +diff -urNp a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
10108 +--- a/arch/x86/kernel/entry_64.S 2008-08-20 11:16:13.000000000 -0700
10109 ++++ b/arch/x86/kernel/entry_64.S 2008-08-20 18:36:57.000000000 -0700
10110 +@@ -769,17 +769,18 @@ END(spurious_interrupt)
10111 + xorl %ebx,%ebx
10112 + 1:
10113 + .if \ist
10114 +- movq %gs:pda_data_offset, %rbp
10115 ++ imul $TSS_size, %gs:pda_cpunumber, %ebp
10116 ++ lea init_tss(%rbp), %rbp
10117 + .endif
10118 + movq %rsp,%rdi
10119 + movq ORIG_RAX(%rsp),%rsi
10120 + movq $-1,ORIG_RAX(%rsp)
10121 + .if \ist
10122 +- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
10123 ++ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
10124 + .endif
10125 + call \sym
10126 + .if \ist
10127 +- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
10128 ++ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
10129 + .endif
10130 + DISABLE_INTERRUPTS(CLBR_NONE)
10131 + .if \irqtrace
10132 +diff -urNp a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
10133 +--- a/arch/x86/kernel/head64.c 2008-08-20 11:16:13.000000000 -0700
10134 ++++ b/arch/x86/kernel/head64.c 2008-08-20 18:36:57.000000000 -0700
10135 +@@ -88,6 +88,11 @@ void __init x86_64_start_kernel(char * r
10136 + /* Make NULL pointers segfault */
10137 + zap_identity_mappings();
10138 +
10139 ++ for (i = 0; i < NR_CPUS; i++)
10140 ++ cpu_pda(i) = &boot_cpu_pda[i];
10141 ++
10142 ++ pda_init(0);
10143 ++
10144 + /* Cleanup the over mapped high alias */
10145 + cleanup_highmap();
10146 +
10147 +@@ -102,10 +107,6 @@ void __init x86_64_start_kernel(char * r
10148 +
10149 + early_printk("Kernel alive\n");
10150 +
10151 +- for (i = 0; i < NR_CPUS; i++)
10152 +- cpu_pda(i) = &boot_cpu_pda[i];
10153 +-
10154 +- pda_init(0);
10155 + copy_bootdata(__va(real_mode_data));
10156 +
10157 + reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
10158 +diff -urNp a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
10159 +--- a/arch/x86/kernel/head_32.S 2008-08-20 11:16:13.000000000 -0700
10160 ++++ b/arch/x86/kernel/head_32.S 2008-08-20 18:36:57.000000000 -0700
10161 +@@ -20,6 +20,7 @@
10162 + #include <asm/asm-offsets.h>
10163 + #include <asm/setup.h>
10164 + #include <asm/processor-flags.h>
10165 ++#include <asm/msr-index.h>
10166 +
10167 + /* Physical address */
10168 + #define pa(X) ((X) - __PAGE_OFFSET)
10169 +@@ -65,17 +66,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
10170 + LOW_PAGES = LOW_PAGES + 0x1000000
10171 + #endif
10172 +
10173 +-#if PTRS_PER_PMD > 1
10174 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
10175 +-#else
10176 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
10177 +-#endif
10178 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
10179 + BOOTBITMAP_SIZE = LOW_PAGES / 8
10180 + ALLOCATOR_SLOP = 4
10181 +
10182 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
10183 +
10184 + /*
10185 ++ * Real beginning of normal "text" segment
10186 ++ */
10187 ++ENTRY(stext)
10188 ++ENTRY(_stext)
10189 ++
10190 ++.section .text.startup,"ax",@progbits
10191 ++ ljmp $(__BOOT_CS),$phys_startup_32
10192 ++
10193 ++/*
10194 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
10195 + * %esi points to the real-mode code as a 32-bit pointer.
10196 + * CS and DS must be 4 GB flat segments, but we don't depend on
10197 +@@ -83,6 +89,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
10198 + * can.
10199 + */
10200 + .section .text.head,"ax",@progbits
10201 ++
10202 ++#ifdef CONFIG_PAX_KERNEXEC
10203 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
10204 ++.fill 4096,1,0xcc
10205 ++#endif
10206 ++
10207 + ENTRY(startup_32)
10208 + /* test KEEP_SEGMENTS flag to see if the bootloader is asking
10209 + us to not reload segments */
10210 +@@ -100,6 +112,43 @@ ENTRY(startup_32)
10211 + movl %eax,%gs
10212 + 2:
10213 +
10214 ++ movl $__per_cpu_start,%eax
10215 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
10216 ++ rorl $16,%eax
10217 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
10218 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
10219 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
10220 ++ subl $__per_cpu_start,%eax
10221 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
10222 ++
10223 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
10224 ++ /* check for VMware */
10225 ++ movl $0x564d5868,%eax
10226 ++ xorl %ebx,%ebx
10227 ++ movl $0xa,%ecx
10228 ++ movl $0x5658,%edx
10229 ++ in (%dx),%eax
10230 ++ cmpl $0x564d5868,%ebx
10231 ++ jz 1f
10232 ++
10233 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
10234 ++ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
10235 ++1:
10236 ++#endif
10237 ++
10238 ++#ifdef CONFIG_PAX_KERNEXEC
10239 ++ movl $KERNEL_TEXT_OFFSET,%eax
10240 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
10241 ++ rorl $16,%eax
10242 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
10243 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
10244 ++
10245 ++ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
10246 ++ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
10247 ++ rorl $16,%eax
10248 ++ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
10249 ++#endif
10250 ++
10251 + /*
10252 + * Clear BSS first so that there are no surprises...
10253 + */
10254 +@@ -143,9 +192,7 @@ ENTRY(startup_32)
10255 + cmpl $num_subarch_entries, %eax
10256 + jae bad_subarch
10257 +
10258 +- movl pa(subarch_entries)(,%eax,4), %eax
10259 +- subl $__PAGE_OFFSET, %eax
10260 +- jmp *%eax
10261 ++ jmp *pa(subarch_entries)(,%eax,4)
10262 +
10263 + bad_subarch:
10264 + WEAK(lguest_entry)
10265 +@@ -157,9 +204,9 @@ WEAK(xen_entry)
10266 + __INITDATA
10267 +
10268 + subarch_entries:
10269 +- .long default_entry /* normal x86/PC */
10270 +- .long lguest_entry /* lguest hypervisor */
10271 +- .long xen_entry /* Xen hypervisor */
10272 ++ .long pa(default_entry) /* normal x86/PC */
10273 ++ .long pa(lguest_entry) /* lguest hypervisor */
10274 ++ .long pa(xen_entry) /* Xen hypervisor */
10275 + num_subarch_entries = (. - subarch_entries) / 4
10276 + .previous
10277 + #endif /* CONFIG_PARAVIRT */
10278 +@@ -173,7 +220,7 @@ num_subarch_entries = (. - subarch_entri
10279 + *
10280 + * Note that the stack is not yet set up!
10281 + */
10282 +-#define PTE_ATTR 0x007 /* PRESENT+RW+USER */
10283 ++#define PTE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
10284 + #define PDE_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
10285 + #define PGD_ATTR 0x001 /* PRESENT (no other attributes) */
10286 +
10287 +@@ -222,8 +269,7 @@ default_entry:
10288 + movl %edi,pa(init_pg_tables_end)
10289 +
10290 + /* Do early initialization of the fixmap area */
10291 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
10292 +- movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
10293 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
10294 + #else /* Not PAE */
10295 +
10296 + page_pde_offset = (__PAGE_OFFSET >> 20);
10297 +@@ -252,8 +298,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
10298 + movl %edi,pa(init_pg_tables_end)
10299 +
10300 + /* Do early initialization of the fixmap area */
10301 +- movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
10302 +- movl %eax,pa(swapper_pg_dir+0xffc)
10303 ++ movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
10304 + #endif
10305 + jmp 3f
10306 + /*
10307 +@@ -317,13 +362,16 @@ ENTRY(startup_32_smp)
10308 + jnc 6f
10309 +
10310 + /* Setup EFER (Extended Feature Enable Register) */
10311 +- movl $0xc0000080, %ecx
10312 ++ movl $MSR_EFER, %ecx
10313 + rdmsr
10314 +
10315 + btsl $11, %eax
10316 + /* Make changes effective */
10317 + wrmsr
10318 +
10319 ++ btsl $63-32,pa(__supported_pte_mask+4)
10320 ++ movl $1,pa(nx_enabled)
10321 ++
10322 + 6:
10323 +
10324 + /*
10325 +@@ -349,9 +397,7 @@ ENTRY(startup_32_smp)
10326 +
10327 + #ifdef CONFIG_SMP
10328 + cmpb $0, ready
10329 +- jz 1f /* Initial CPU cleans BSS */
10330 +- jmp checkCPUtype
10331 +-1:
10332 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
10333 + #endif /* CONFIG_SMP */
10334 +
10335 + /*
10336 +@@ -428,12 +474,12 @@ is386: movl $2,%ecx # set MP
10337 + ljmp $(__KERNEL_CS),$1f
10338 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
10339 + movl %eax,%ss # after changing gdt.
10340 +- movl %eax,%fs # gets reset once there's real percpu
10341 +-
10342 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
10343 + movl %eax,%ds
10344 + movl %eax,%es
10345 +
10346 ++ movl $(__KERNEL_PERCPU), %eax
10347 ++ movl %eax,%fs # set this cpu's percpu
10348 ++
10349 + xorl %eax,%eax # Clear GS and LDT
10350 + movl %eax,%gs
10351 + lldt %ax
10352 +@@ -444,11 +490,7 @@ is386: movl $2,%ecx # set MP
10353 + movb ready, %cl
10354 + movb $1, ready
10355 + cmpb $0,%cl # the first CPU calls start_kernel
10356 +- je 1f
10357 +- movl $(__KERNEL_PERCPU), %eax
10358 +- movl %eax,%fs # set this cpu's percpu
10359 +- jmp initialize_secondary # all other CPUs call initialize_secondary
10360 +-1:
10361 ++ jne initialize_secondary # all other CPUs call initialize_secondary
10362 + #endif /* CONFIG_SMP */
10363 + jmp start_kernel
10364 +
10365 +@@ -534,15 +576,15 @@ early_page_fault:
10366 + jmp early_fault
10367 +
10368 + early_fault:
10369 +- cld
10370 + #ifdef CONFIG_PRINTK
10371 ++ cmpl $2,%ss:early_recursion_flag
10372 ++ je hlt_loop
10373 ++ incl %ss:early_recursion_flag
10374 ++ cld
10375 + pusha
10376 + movl $(__KERNEL_DS),%eax
10377 + movl %eax,%ds
10378 + movl %eax,%es
10379 +- cmpl $2,early_recursion_flag
10380 +- je hlt_loop
10381 +- incl early_recursion_flag
10382 + movl %cr2,%eax
10383 + pushl %eax
10384 + pushl %edx /* trapno */
10385 +@@ -552,8 +594,8 @@ early_fault:
10386 + #else
10387 + call printk
10388 + #endif
10389 +-#endif
10390 + call dump_stack
10391 ++#endif
10392 + hlt_loop:
10393 + hlt
10394 + jmp hlt_loop
10395 +@@ -561,8 +603,11 @@ hlt_loop:
10396 + /* This is the default interrupt "handler" :-) */
10397 + ALIGN
10398 + ignore_int:
10399 +- cld
10400 + #ifdef CONFIG_PRINTK
10401 ++ cmpl $2,%ss:early_recursion_flag
10402 ++ je hlt_loop
10403 ++ incl %ss:early_recursion_flag
10404 ++ cld
10405 + pushl %eax
10406 + pushl %ecx
10407 + pushl %edx
10408 +@@ -571,9 +616,6 @@ ignore_int:
10409 + movl $(__KERNEL_DS),%eax
10410 + movl %eax,%ds
10411 + movl %eax,%es
10412 +- cmpl $2,early_recursion_flag
10413 +- je hlt_loop
10414 +- incl early_recursion_flag
10415 + pushl 16(%esp)
10416 + pushl 24(%esp)
10417 + pushl 32(%esp)
10418 +@@ -593,36 +635,41 @@ ignore_int:
10419 + #endif
10420 + iret
10421 +
10422 +-.section .text
10423 +-/*
10424 +- * Real beginning of normal "text" segment
10425 +- */
10426 +-ENTRY(stext)
10427 +-ENTRY(_stext)
10428 +-
10429 + /*
10430 + * BSS section
10431 + */
10432 +-.section ".bss.page_aligned","wa"
10433 +- .align PAGE_SIZE_asm
10434 + #ifdef CONFIG_X86_PAE
10435 ++.section .swapper_pg_pmd,"a",@progbits
10436 + swapper_pg_pmd:
10437 + .fill 1024*KPMDS,4,0
10438 + #else
10439 ++.section .swapper_pg_dir,"a",@progbits
10440 + ENTRY(swapper_pg_dir)
10441 + .fill 1024,4,0
10442 + #endif
10443 + swapper_pg_fixmap:
10444 + .fill 1024,4,0
10445 ++
10446 ++.section .empty_zero_page,"a",@progbits
10447 + ENTRY(empty_zero_page)
10448 + .fill 4096,1,0
10449 ++
10450 ++/*
10451 ++ * The IDT has to be page-aligned to simplify the Pentium
10452 ++ * F0 0F bug workaround.. We have a special link segment
10453 ++ * for this.
10454 ++ */
10455 ++.section .idt,"a",@progbits
10456 ++ENTRY(idt_table)
10457 ++ .fill 256,8,0
10458 ++
10459 + /*
10460 + * This starts the data section.
10461 + */
10462 ++.data
10463 ++
10464 + #ifdef CONFIG_X86_PAE
10465 +-.section ".data.page_aligned","wa"
10466 +- /* Page-aligned for the benefit of paravirt? */
10467 +- .align PAGE_SIZE_asm
10468 ++.section .swapper_pg_dir,"a",@progbits
10469 + ENTRY(swapper_pg_dir)
10470 + .long pa(swapper_pg_pmd+PGD_ATTR),0 /* low identity map */
10471 + # if KPMDS == 3
10472 +@@ -645,11 +692,12 @@ ENTRY(swapper_pg_dir)
10473 +
10474 + .data
10475 + ENTRY(stack_start)
10476 +- .long init_thread_union+THREAD_SIZE
10477 ++ .long init_thread_union+THREAD_SIZE-8
10478 + .long __BOOT_DS
10479 +
10480 + ready: .byte 0
10481 +
10482 ++.section .rodata,"a",@progbits
10483 + early_recursion_flag:
10484 + .long 0
10485 +
10486 +@@ -695,7 +743,7 @@ idt_descr:
10487 + .word 0 # 32 bit align gdt_desc.address
10488 + ENTRY(early_gdt_descr)
10489 + .word GDT_ENTRIES*8-1
10490 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
10491 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
10492 +
10493 + /*
10494 + * The boot_gdt must mirror the equivalent in setup.S and is
10495 +@@ -704,5 +752,61 @@ ENTRY(early_gdt_descr)
10496 + .align L1_CACHE_BYTES
10497 + ENTRY(boot_gdt)
10498 + .fill GDT_ENTRY_BOOT_CS,8,0
10499 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
10500 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
10501 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
10502 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
10503 ++
10504 ++ .align PAGE_SIZE_asm
10505 ++ENTRY(cpu_gdt_table)
10506 ++ .quad 0x0000000000000000 /* NULL descriptor */
10507 ++ .quad 0x0000000000000000 /* 0x0b reserved */
10508 ++ .quad 0x0000000000000000 /* 0x13 reserved */
10509 ++ .quad 0x0000000000000000 /* 0x1b reserved */
10510 ++ .quad 0x0000000000000000 /* 0x20 unused */
10511 ++ .quad 0x0000000000000000 /* 0x28 unused */
10512 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
10513 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
10514 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
10515 ++ .quad 0x0000000000000000 /* 0x4b reserved */
10516 ++ .quad 0x0000000000000000 /* 0x53 reserved */
10517 ++ .quad 0x0000000000000000 /* 0x5b reserved */
10518 ++
10519 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
10520 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
10521 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
10522 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
10523 ++
10524 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
10525 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
10526 ++
10527 ++ /*
10528 ++ * Segments used for calling PnP BIOS have byte granularity.
10529 ++ * The code segments and data segments have fixed 64k limits,
10530 ++ * the transfer segment sizes are set at run time.
10531 ++ */
10532 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
10533 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
10534 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
10535 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
10536 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
10537 ++
10538 ++ /*
10539 ++ * The APM segments have byte granularity and their bases
10540 ++ * are set at run time. All have 64k limits.
10541 ++ */
10542 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
10543 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
10544 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
10545 ++
10546 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
10547 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
10548 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
10549 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
10550 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
10551 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
10552 ++
10553 ++ /* Be sure this is zeroed to avoid false validations in Xen */
10554 ++ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
10555 ++
10556 ++#ifdef CONFIG_SMP
10557 ++ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
10558 ++#endif
10559 +diff -urNp a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
10560 +--- a/arch/x86/kernel/head_64.S 2008-08-20 11:16:13.000000000 -0700
10561 ++++ b/arch/x86/kernel/head_64.S 2008-08-20 18:36:57.000000000 -0700
10562 +@@ -185,6 +185,10 @@ ENTRY(secondary_startup_64)
10563 + btl $20,%edi /* No Execute supported? */
10564 + jnc 1f
10565 + btsl $_EFER_NX, %eax
10566 ++ movq $(init_level4_pgt), %rdi
10567 ++ addq phys_base(%rip), %rdi
10568 ++ btsq $_PAGE_BIT_NX, 8*258(%rdi)
10569 ++ btsq $_PAGE_BIT_NX, 8*388(%rdi)
10570 + 1: wrmsr /* Make changes effective */
10571 +
10572 + /* Setup cr0 */
10573 +@@ -254,6 +258,9 @@ ENTRY(secondary_startup_64)
10574 + pushq %rax # target address in negative space
10575 + lretq
10576 +
10577 ++bad_address:
10578 ++ jmp bad_address
10579 ++
10580 + /* SMP bootup changes these two */
10581 + __REFDATA
10582 + .align 8
10583 +@@ -264,9 +271,7 @@ ENTRY(secondary_startup_64)
10584 + ENTRY(init_rsp)
10585 + .quad init_thread_union+THREAD_SIZE-8
10586 +
10587 +-bad_address:
10588 +- jmp bad_address
10589 +-
10590 ++ __INIT
10591 + #ifdef CONFIG_EARLY_PRINTK
10592 + .macro early_idt_tramp first, last
10593 + .ifgt \last-\first
10594 +@@ -319,15 +324,18 @@ ENTRY(early_idt_handler)
10595 + jmp 1b
10596 +
10597 + #ifdef CONFIG_EARLY_PRINTK
10598 ++ __INITDATA
10599 + early_recursion_flag:
10600 + .long 0
10601 +
10602 ++ .section .rodata,"a",@progbits
10603 + early_idt_msg:
10604 + .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
10605 + early_idt_ripmsg:
10606 + .asciz "RIP %s\n"
10607 + #endif /* CONFIG_EARLY_PRINTK */
10608 +
10609 ++ .section .rodata,"a",@progbits
10610 + .balign PAGE_SIZE
10611 +
10612 + #define NEXT_PAGE(name) \
10613 +@@ -352,7 +360,9 @@ NEXT_PAGE(init_level4_pgt)
10614 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10615 + .fill 257,8,0
10616 + .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10617 +- .fill 252,8,0
10618 ++ .fill 129,8,0
10619 ++ .quad level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
10620 ++ .fill 122,8,0
10621 + /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
10622 + .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
10623 +
10624 +@@ -360,6 +370,9 @@ NEXT_PAGE(level3_ident_pgt)
10625 + .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
10626 + .fill 511,8,0
10627 +
10628 ++NEXT_PAGE(level3_vmalloc_pgt)
10629 ++ .fill 512,8,0
10630 ++
10631 + NEXT_PAGE(level3_kernel_pgt)
10632 + .fill 510,8,0
10633 + /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
10634 +@@ -401,19 +414,12 @@ NEXT_PAGE(level2_spare_pgt)
10635 + #undef PMDS
10636 + #undef NEXT_PAGE
10637 +
10638 +- .data
10639 + .align 16
10640 + .globl cpu_gdt_descr
10641 + cpu_gdt_descr:
10642 +- .word gdt_end-cpu_gdt_table-1
10643 ++ .word GDT_SIZE-1
10644 + gdt:
10645 + .quad cpu_gdt_table
10646 +-#ifdef CONFIG_SMP
10647 +- .rept NR_CPUS-1
10648 +- .word 0
10649 +- .quad 0
10650 +- .endr
10651 +-#endif
10652 +
10653 + ENTRY(phys_base)
10654 + /* This must match the first entry in level2_kernel_pgt */
10655 +@@ -423,8 +429,7 @@ ENTRY(phys_base)
10656 + * IRET will check the segment types kkeil 2000/10/28
10657 + * Also sysret mandates a special GDT layout
10658 + */
10659 +-
10660 +- .section .data.page_aligned, "aw"
10661 ++
10662 + .align PAGE_SIZE
10663 +
10664 + /* The TLS descriptors are currently at a different place compared to i386.
10665 +@@ -443,15 +448,15 @@ ENTRY(cpu_gdt_table)
10666 + .quad 0,0 /* LDT */
10667 + .quad 0,0,0 /* three TLS descriptors */
10668 + .quad 0x0000f40000000000 /* node/CPU stored in limit */
10669 +-gdt_end:
10670 + /* asm/segment.h:GDT_ENTRIES must match this */
10671 + /* This should be a multiple of the cache line size */
10672 +- /* GDTs of other CPUs are now dynamically allocated */
10673 +
10674 + /* zero the remaining page */
10675 + .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
10676 ++#ifdef CONFIG_SMP
10677 ++ .fill (NR_CPUS-1) * (PAGE_SIZE),1,0 /* other CPU's GDT */
10678 ++#endif
10679 +
10680 +- .section .bss, "aw", @nobits
10681 + .align L1_CACHE_BYTES
10682 + ENTRY(idt_table)
10683 + .skip 256 * 16
10684 +diff -urNp a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
10685 +--- a/arch/x86/kernel/hpet.c 2008-08-20 11:16:13.000000000 -0700
10686 ++++ b/arch/x86/kernel/hpet.c 2008-08-20 18:36:57.000000000 -0700
10687 +@@ -138,7 +138,7 @@ static void hpet_reserve_platform_timers
10688 + hd.hd_irq[1] = HPET_LEGACY_RTC;
10689 +
10690 + for (i = 2; i < nrtimers; timer++, i++)
10691 +- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
10692 ++ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
10693 + Tn_INT_ROUTE_CNF_SHIFT;
10694 +
10695 + hpet_alloc(&hd);
10696 +diff -urNp a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
10697 +--- a/arch/x86/kernel/i386_ksyms_32.c 2008-08-20 11:16:13.000000000 -0700
10698 ++++ b/arch/x86/kernel/i386_ksyms_32.c 2008-08-20 18:36:57.000000000 -0700
10699 +@@ -4,12 +4,16 @@
10700 + #include <asm/desc.h>
10701 + #include <asm/pgtable.h>
10702 +
10703 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
10704 ++
10705 + EXPORT_SYMBOL(__down_failed);
10706 + EXPORT_SYMBOL(__down_failed_interruptible);
10707 + EXPORT_SYMBOL(__down_failed_trylock);
10708 + EXPORT_SYMBOL(__up_wakeup);
10709 + /* Networking helper routines. */
10710 + EXPORT_SYMBOL(csum_partial_copy_generic);
10711 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
10712 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
10713 +
10714 + EXPORT_SYMBOL(__get_user_1);
10715 + EXPORT_SYMBOL(__get_user_2);
10716 +@@ -24,3 +28,7 @@ EXPORT_SYMBOL(strstr);
10717 +
10718 + EXPORT_SYMBOL(csum_partial);
10719 + EXPORT_SYMBOL(empty_zero_page);
10720 ++
10721 ++#ifdef CONFIG_PAX_KERNEXEC
10722 ++EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
10723 ++#endif
10724 +diff -urNp a/arch/x86/kernel/init_task.c b/arch/x86/kernel/init_task.c
10725 +--- a/arch/x86/kernel/init_task.c 2008-08-20 11:16:13.000000000 -0700
10726 ++++ b/arch/x86/kernel/init_task.c 2008-08-20 18:36:57.000000000 -0700
10727 +@@ -43,5 +43,5 @@ EXPORT_SYMBOL(init_task);
10728 + * section. Since TSS's are completely CPU-local, we want them
10729 + * on exact cacheline boundaries, to eliminate cacheline ping-pong.
10730 + */
10731 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
10732 +-
10733 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
10734 ++EXPORT_SYMBOL(init_tss);
10735 +diff -urNp a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
10736 +--- a/arch/x86/kernel/ioport.c 2008-08-20 11:16:13.000000000 -0700
10737 ++++ b/arch/x86/kernel/ioport.c 2008-08-20 18:36:57.000000000 -0700
10738 +@@ -14,6 +14,7 @@
10739 + #include <linux/slab.h>
10740 + #include <linux/thread_info.h>
10741 + #include <linux/syscalls.h>
10742 ++#include <linux/grsecurity.h>
10743 +
10744 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
10745 + static void set_bitmap(unsigned long *bitmap, unsigned int base,
10746 +@@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
10747 +
10748 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
10749 + return -EINVAL;
10750 ++#ifdef CONFIG_GRKERNSEC_IO
10751 ++ if (turn_on) {
10752 ++ gr_handle_ioperm();
10753 ++ return -EPERM;
10754 ++ }
10755 ++#endif
10756 + if (turn_on && !capable(CAP_SYS_RAWIO))
10757 + return -EPERM;
10758 +
10759 +@@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
10760 + * because the ->io_bitmap_max value must match the bitmap
10761 + * contents:
10762 + */
10763 +- tss = &per_cpu(init_tss, get_cpu());
10764 ++ tss = init_tss + get_cpu();
10765 +
10766 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
10767 +
10768 +@@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
10769 + return -EINVAL;
10770 + /* Trying to gain more privileges? */
10771 + if (level > old) {
10772 ++#ifdef CONFIG_GRKERNSEC_IO
10773 ++ gr_handle_iopl();
10774 ++ return -EPERM;
10775 ++#else
10776 + if (!capable(CAP_SYS_RAWIO))
10777 + return -EPERM;
10778 ++#endif
10779 + }
10780 + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
10781 +
10782 +diff -urNp a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
10783 +--- a/arch/x86/kernel/irq_32.c 2008-08-20 11:16:13.000000000 -0700
10784 ++++ b/arch/x86/kernel/irq_32.c 2008-08-20 18:36:57.000000000 -0700
10785 +@@ -115,7 +115,7 @@ unsigned int do_IRQ(struct pt_regs *regs
10786 + int arg1, arg2, bx;
10787 +
10788 + /* build the stack frame on the IRQ stack */
10789 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
10790 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
10791 + irqctx->tinfo.task = curctx->tinfo.task;
10792 + irqctx->tinfo.previous_esp = current_stack_pointer;
10793 +
10794 +@@ -211,7 +211,7 @@ asmlinkage void do_softirq(void)
10795 + irqctx->tinfo.previous_esp = current_stack_pointer;
10796 +
10797 + /* build the stack frame on the softirq stack */
10798 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
10799 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
10800 +
10801 + asm volatile(
10802 + " xchgl %%ebx,%%esp \n"
10803 +diff -urNp a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
10804 +--- a/arch/x86/kernel/kprobes.c 2008-08-20 11:16:13.000000000 -0700
10805 ++++ b/arch/x86/kernel/kprobes.c 2008-08-20 18:36:57.000000000 -0700
10806 +@@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
10807 + char op;
10808 + s32 raddr;
10809 + } __attribute__((packed)) * jop;
10810 +- jop = (struct __arch_jmp_op *)from;
10811 ++
10812 ++#ifdef CONFIG_PAX_KERNEXEC
10813 ++ unsigned long cr0;
10814 ++#endif
10815 ++
10816 ++ jop = (struct __arch_jmp_op *)(ktla_ktva(from));
10817 ++
10818 ++#ifdef CONFIG_PAX_KERNEXEC
10819 ++ pax_open_kernel(cr0);
10820 ++#endif
10821 ++
10822 + jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
10823 + jop->op = RELATIVEJUMP_INSTRUCTION;
10824 ++
10825 ++#ifdef CONFIG_PAX_KERNEXEC
10826 ++ pax_close_kernel(cr0);
10827 ++#endif
10828 ++
10829 + }
10830 +
10831 + /*
10832 +@@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct
10833 +
10834 + static void __kprobes arch_copy_kprobe(struct kprobe *p)
10835 + {
10836 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
10837 ++
10838 ++#ifdef CONFIG_PAX_KERNEXEC
10839 ++ unsigned long cr0;
10840 ++#endif
10841 ++
10842 ++#ifdef CONFIG_PAX_KERNEXEC
10843 ++ pax_open_kernel(cr0);
10844 ++#endif
10845 ++
10846 ++ memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
10847 ++
10848 ++#ifdef CONFIG_PAX_KERNEXEC
10849 ++ pax_close_kernel(cr0);
10850 ++#endif
10851 +
10852 + fix_riprel(p);
10853 +
10854 +- if (can_boost(p->addr))
10855 ++ if (can_boost(ktla_ktva(p->addr)))
10856 + p->ainsn.boostable = 0;
10857 + else
10858 + p->ainsn.boostable = -1;
10859 +
10860 +- p->opcode = *p->addr;
10861 ++ p->opcode = *(ktla_ktva(p->addr));
10862 + }
10863 +
10864 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
10865 +@@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
10866 + if (p->opcode == BREAKPOINT_INSTRUCTION)
10867 + regs->ip = (unsigned long)p->addr;
10868 + else
10869 +- regs->ip = (unsigned long)p->ainsn.insn;
10870 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
10871 + }
10872 +
10873 + /* Called with kretprobe_lock held */
10874 +@@ -450,7 +478,7 @@ static void __kprobes setup_singlestep(s
10875 + if (p->ainsn.boostable == 1 && !p->post_handler) {
10876 + /* Boost up -- we can execute copied instructions directly */
10877 + reset_current_kprobe();
10878 +- regs->ip = (unsigned long)p->ainsn.insn;
10879 ++ regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
10880 + preempt_enable_no_resched();
10881 + return;
10882 + }
10883 +@@ -772,7 +800,7 @@ static void __kprobes resume_execution(s
10884 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
10885 + {
10886 + unsigned long *tos = stack_addr(regs);
10887 +- unsigned long copy_ip = (unsigned long)p->ainsn.insn;
10888 ++ unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
10889 + unsigned long orig_ip = (unsigned long)p->addr;
10890 + kprobe_opcode_t *insn = p->ainsn.insn;
10891 +
10892 +@@ -956,7 +984,7 @@ int __kprobes kprobe_exceptions_notify(s
10893 + struct die_args *args = data;
10894 + int ret = NOTIFY_DONE;
10895 +
10896 +- if (args->regs && user_mode_vm(args->regs))
10897 ++ if (args->regs && user_mode(args->regs))
10898 + return ret;
10899 +
10900 + switch (val) {
10901 +diff -urNp a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
10902 +--- a/arch/x86/kernel/ldt.c 2008-08-20 11:16:13.000000000 -0700
10903 ++++ b/arch/x86/kernel/ldt.c 2008-08-20 18:36:57.000000000 -0700
10904 +@@ -65,7 +65,7 @@ static int alloc_ldt(mm_context_t *pc, i
10905 + cpumask_t mask;
10906 +
10907 + preempt_disable();
10908 +- load_LDT(pc);
10909 ++ load_LDT_nolock(pc);
10910 + mask = cpumask_of_cpu(smp_processor_id());
10911 + if (!cpus_equal(current->mm->cpu_vm_mask, mask))
10912 + smp_call_function(flush_ldt, NULL, 1, 1);
10913 +@@ -110,6 +110,24 @@ int init_new_context(struct task_struct
10914 + retval = copy_ldt(&mm->context, &old_mm->context);
10915 + mutex_unlock(&old_mm->context.lock);
10916 + }
10917 ++
10918 ++ if (tsk == current) {
10919 ++ mm->context.vdso = ~0UL;
10920 ++
10921 ++#ifdef CONFIG_X86_32
10922 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10923 ++ mm->context.user_cs_base = 0UL;
10924 ++ mm->context.user_cs_limit = ~0UL;
10925 ++
10926 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
10927 ++ cpus_clear(mm->context.cpu_user_cs_mask);
10928 ++#endif
10929 ++
10930 ++#endif
10931 ++#endif
10932 ++
10933 ++ }
10934 ++
10935 + return retval;
10936 + }
10937 +
10938 +@@ -223,6 +241,13 @@ static int write_ldt(void __user *ptr, u
10939 + }
10940 + }
10941 +
10942 ++#ifdef CONFIG_PAX_SEGMEXEC
10943 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
10944 ++ error = -EINVAL;
10945 ++ goto out_unlock;
10946 ++ }
10947 ++#endif
10948 ++
10949 + fill_ldt(&ldt, &ldt_info);
10950 + if (oldmode)
10951 + ldt.avl = 0;
10952 +diff -urNp a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
10953 +--- a/arch/x86/kernel/machine_kexec_32.c 2008-08-20 11:16:13.000000000 -0700
10954 ++++ b/arch/x86/kernel/machine_kexec_32.c 2008-08-20 18:36:57.000000000 -0700
10955 +@@ -30,7 +30,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
10956 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
10957 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
10958 +
10959 +-static void set_idt(void *newidt, __u16 limit)
10960 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
10961 + {
10962 + struct desc_ptr curidt;
10963 +
10964 +@@ -42,7 +42,7 @@ static void set_idt(void *newidt, __u16
10965 + };
10966 +
10967 +
10968 +-static void set_gdt(void *newgdt, __u16 limit)
10969 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
10970 + {
10971 + struct desc_ptr curgdt;
10972 +
10973 +@@ -111,10 +111,10 @@ NORET_TYPE void machine_kexec(struct kim
10974 + local_irq_disable();
10975 +
10976 + control_page = page_address(image->control_code_page);
10977 +- memcpy(control_page, relocate_kernel, PAGE_SIZE);
10978 ++ memcpy(control_page, ktla_ktva(relocate_kernel), PAGE_SIZE);
10979 +
10980 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
10981 +- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
10982 ++ page_list[VA_CONTROL_PAGE] = ktla_ktva((unsigned long)relocate_kernel);
10983 + page_list[PA_PGD] = __pa(kexec_pgd);
10984 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
10985 + #ifdef CONFIG_X86_PAE
10986 +diff -urNp a/arch/x86/kernel/module_32.c b/arch/x86/kernel/module_32.c
10987 +--- a/arch/x86/kernel/module_32.c 2008-08-20 11:16:13.000000000 -0700
10988 ++++ b/arch/x86/kernel/module_32.c 2008-08-20 18:36:57.000000000 -0700
10989 +@@ -23,6 +23,8 @@
10990 + #include <linux/kernel.h>
10991 + #include <linux/bug.h>
10992 +
10993 ++#include <asm/desc.h>
10994 ++
10995 + #if 0
10996 + #define DEBUGP printk
10997 + #else
10998 +@@ -33,9 +35,31 @@ void *module_alloc(unsigned long size)
10999 + {
11000 + if (size == 0)
11001 + return NULL;
11002 ++
11003 ++#ifdef CONFIG_PAX_KERNEXEC
11004 ++ return vmalloc(size);
11005 ++#else
11006 + return vmalloc_exec(size);
11007 ++#endif
11008 ++
11009 + }
11010 +
11011 ++#ifdef CONFIG_PAX_KERNEXEC
11012 ++void *module_alloc_exec(unsigned long size)
11013 ++{
11014 ++ struct vm_struct *area;
11015 ++
11016 ++ if (size == 0)
11017 ++ return NULL;
11018 ++
11019 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
11020 ++ if (area)
11021 ++ return area->addr;
11022 ++
11023 ++ return NULL;
11024 ++}
11025 ++EXPORT_SYMBOL(module_alloc_exec);
11026 ++#endif
11027 +
11028 + /* Free memory returned from module_alloc */
11029 + void module_free(struct module *mod, void *module_region)
11030 +@@ -45,6 +69,45 @@ void module_free(struct module *mod, voi
11031 + table entries. */
11032 + }
11033 +
11034 ++#ifdef CONFIG_PAX_KERNEXEC
11035 ++void module_free_exec(struct module *mod, void *module_region)
11036 ++{
11037 ++ struct vm_struct **p, *tmp;
11038 ++
11039 ++ if (!module_region)
11040 ++ return;
11041 ++
11042 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
11043 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
11044 ++ WARN_ON(1);
11045 ++ return;
11046 ++ }
11047 ++
11048 ++ write_lock(&vmlist_lock);
11049 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
11050 ++ if (tmp->addr == module_region)
11051 ++ break;
11052 ++
11053 ++ if (tmp) {
11054 ++ unsigned long cr0;
11055 ++
11056 ++ pax_open_kernel(cr0);
11057 ++ memset(tmp->addr, 0xCC, tmp->size);
11058 ++ pax_close_kernel(cr0);
11059 ++
11060 ++ *p = tmp->next;
11061 ++ kfree(tmp);
11062 ++ }
11063 ++ write_unlock(&vmlist_lock);
11064 ++
11065 ++ if (!tmp) {
11066 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
11067 ++ module_region);
11068 ++ WARN_ON(1);
11069 ++ }
11070 ++}
11071 ++#endif
11072 ++
11073 + /* We don't need anything special. */
11074 + int module_frob_arch_sections(Elf_Ehdr *hdr,
11075 + Elf_Shdr *sechdrs,
11076 +@@ -63,14 +126,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
11077 + unsigned int i;
11078 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
11079 + Elf32_Sym *sym;
11080 +- uint32_t *location;
11081 ++ uint32_t *plocation, location;
11082 ++
11083 ++#ifdef CONFIG_PAX_KERNEXEC
11084 ++ unsigned long cr0;
11085 ++#endif
11086 +
11087 + DEBUGP("Applying relocate section %u to %u\n", relsec,
11088 + sechdrs[relsec].sh_info);
11089 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
11090 + /* This is where to make the change */
11091 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
11092 +- + rel[i].r_offset;
11093 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
11094 ++ location = (uint32_t)plocation;
11095 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
11096 ++ plocation = ktla_ktva((void *)plocation);
11097 + /* This is the symbol it is referring to. Note that all
11098 + undefined symbols have been resolved. */
11099 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
11100 +@@ -78,12 +147,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
11101 +
11102 + switch (ELF32_R_TYPE(rel[i].r_info)) {
11103 + case R_386_32:
11104 ++
11105 ++#ifdef CONFIG_PAX_KERNEXEC
11106 ++ pax_open_kernel(cr0);
11107 ++#endif
11108 ++
11109 + /* We add the value into the location given */
11110 +- *location += sym->st_value;
11111 ++ *plocation += sym->st_value;
11112 ++
11113 ++#ifdef CONFIG_PAX_KERNEXEC
11114 ++ pax_close_kernel(cr0);
11115 ++#endif
11116 ++
11117 + break;
11118 + case R_386_PC32:
11119 ++
11120 ++#ifdef CONFIG_PAX_KERNEXEC
11121 ++ pax_open_kernel(cr0);
11122 ++#endif
11123 ++
11124 + /* Add the value, subtract its postition */
11125 +- *location += sym->st_value - (uint32_t)location;
11126 ++ *plocation += sym->st_value - location;
11127 ++
11128 ++#ifdef CONFIG_PAX_KERNEXEC
11129 ++ pax_close_kernel(cr0);
11130 ++#endif
11131 ++
11132 + break;
11133 + default:
11134 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
11135 +diff -urNp a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module_64.c
11136 +--- a/arch/x86/kernel/module_64.c 2008-08-20 11:16:13.000000000 -0700
11137 ++++ b/arch/x86/kernel/module_64.c 2008-08-20 18:36:57.000000000 -0700
11138 +@@ -39,7 +39,7 @@ void module_free(struct module *mod, voi
11139 + table entries. */
11140 + }
11141 +
11142 +-void *module_alloc(unsigned long size)
11143 ++static void *__module_alloc(unsigned long size, pgprot_t prot)
11144 + {
11145 + struct vm_struct *area;
11146 +
11147 +@@ -53,8 +53,31 @@ void *module_alloc(unsigned long size)
11148 + if (!area)
11149 + return NULL;
11150 +
11151 +- return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
11152 ++ return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
11153 ++}
11154 ++
11155 ++#ifdef CONFIG_PAX_KERNEXEC
11156 ++void *module_alloc(unsigned long size)
11157 ++{
11158 ++ return __module_alloc(size, PAGE_KERNEL);
11159 ++}
11160 ++
11161 ++void module_free_exec(struct module *mod, void *module_region)
11162 ++{
11163 ++ module_free(mod, module_region);
11164 ++}
11165 ++
11166 ++void *module_alloc_exec(unsigned long size)
11167 ++{
11168 ++ return __module_alloc(size, PAGE_KERNEL_RX);
11169 + }
11170 ++#else
11171 ++void *module_alloc(unsigned long size)
11172 ++{
11173 ++ return __module_alloc(size, PAGE_KERNEL_EXEC);
11174 ++}
11175 ++#endif
11176 ++
11177 + #endif
11178 +
11179 + /* We don't need anything special. */
11180 +@@ -76,7 +99,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
11181 + Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
11182 + Elf64_Sym *sym;
11183 + void *loc;
11184 +- u64 val;
11185 ++ u64 val;
11186 ++
11187 ++#ifdef CONFIG_PAX_KERNEXEC
11188 ++ unsigned long cr0;
11189 ++#endif
11190 +
11191 + DEBUGP("Applying relocate section %u to %u\n", relsec,
11192 + sechdrs[relsec].sh_info);
11193 +@@ -100,21 +127,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
11194 + case R_X86_64_NONE:
11195 + break;
11196 + case R_X86_64_64:
11197 ++
11198 ++#ifdef CONFIG_PAX_KERNEXEC
11199 ++ pax_open_kernel(cr0);
11200 ++#endif
11201 ++
11202 + *(u64 *)loc = val;
11203 ++
11204 ++#ifdef CONFIG_PAX_KERNEXEC
11205 ++ pax_close_kernel(cr0);
11206 ++#endif
11207 ++
11208 + break;
11209 + case R_X86_64_32:
11210 ++
11211 ++#ifdef CONFIG_PAX_KERNEXEC
11212 ++ pax_open_kernel(cr0);
11213 ++#endif
11214 ++
11215 + *(u32 *)loc = val;
11216 ++
11217 ++#ifdef CONFIG_PAX_KERNEXEC
11218 ++ pax_close_kernel(cr0);
11219 ++#endif
11220 ++
11221 + if (val != *(u32 *)loc)
11222 + goto overflow;
11223 + break;
11224 + case R_X86_64_32S:
11225 ++
11226 ++#ifdef CONFIG_PAX_KERNEXEC
11227 ++ pax_open_kernel(cr0);
11228 ++#endif
11229 ++
11230 + *(s32 *)loc = val;
11231 ++
11232 ++#ifdef CONFIG_PAX_KERNEXEC
11233 ++ pax_close_kernel(cr0);
11234 ++#endif
11235 ++
11236 + if ((s64)val != *(s32 *)loc)
11237 + goto overflow;
11238 + break;
11239 + case R_X86_64_PC32:
11240 + val -= (u64)loc;
11241 ++
11242 ++#ifdef CONFIG_PAX_KERNEXEC
11243 ++ pax_open_kernel(cr0);
11244 ++#endif
11245 ++
11246 + *(u32 *)loc = val;
11247 ++
11248 ++#ifdef CONFIG_PAX_KERNEXEC
11249 ++ pax_close_kernel(cr0);
11250 ++#endif
11251 ++
11252 + #if 0
11253 + if ((s64)val != *(s32 *)loc)
11254 + goto overflow;
11255 +diff -urNp a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
11256 +--- a/arch/x86/kernel/paravirt.c 2008-08-20 11:16:13.000000000 -0700
11257 ++++ b/arch/x86/kernel/paravirt.c 2008-08-20 18:36:57.000000000 -0700
11258 +@@ -42,7 +42,7 @@ void _paravirt_nop(void)
11259 + {
11260 + }
11261 +
11262 +-static void __init default_banner(void)
11263 ++static void default_banner(void)
11264 + {
11265 + printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
11266 + pv_info.name);
11267 +@@ -159,7 +159,7 @@ unsigned paravirt_patch_insns(void *insn
11268 + if (insn_len > len || start == NULL)
11269 + insn_len = len;
11270 + else
11271 +- memcpy(insnbuf, start, insn_len);
11272 ++ memcpy(insnbuf, ktla_ktva(start), insn_len);
11273 +
11274 + return insn_len;
11275 + }
11276 +@@ -277,21 +277,21 @@ enum paravirt_lazy_mode paravirt_get_laz
11277 + return __get_cpu_var(paravirt_lazy_mode);
11278 + }
11279 +
11280 +-struct pv_info pv_info = {
11281 ++struct pv_info pv_info __read_only = {
11282 + .name = "bare hardware",
11283 + .paravirt_enabled = 0,
11284 + .kernel_rpl = 0,
11285 + .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
11286 + };
11287 +
11288 +-struct pv_init_ops pv_init_ops = {
11289 ++struct pv_init_ops pv_init_ops __read_only = {
11290 + .patch = native_patch,
11291 + .banner = default_banner,
11292 + .arch_setup = paravirt_nop,
11293 + .memory_setup = machine_specific_memory_setup,
11294 + };
11295 +
11296 +-struct pv_time_ops pv_time_ops = {
11297 ++struct pv_time_ops pv_time_ops __read_only = {
11298 + .time_init = hpet_time_init,
11299 + .get_wallclock = native_get_wallclock,
11300 + .set_wallclock = native_set_wallclock,
11301 +@@ -299,7 +299,7 @@ struct pv_time_ops pv_time_ops = {
11302 + .get_cpu_khz = native_calculate_cpu_khz,
11303 + };
11304 +
11305 +-struct pv_irq_ops pv_irq_ops = {
11306 ++struct pv_irq_ops pv_irq_ops __read_only = {
11307 + .init_IRQ = native_init_IRQ,
11308 + .save_fl = native_save_fl,
11309 + .restore_fl = native_restore_fl,
11310 +@@ -309,7 +309,7 @@ struct pv_irq_ops pv_irq_ops = {
11311 + .halt = native_halt,
11312 + };
11313 +
11314 +-struct pv_cpu_ops pv_cpu_ops = {
11315 ++struct pv_cpu_ops pv_cpu_ops __read_only = {
11316 + .cpuid = native_cpuid,
11317 + .get_debugreg = native_get_debugreg,
11318 + .set_debugreg = native_set_debugreg,
11319 +@@ -355,7 +355,7 @@ struct pv_cpu_ops pv_cpu_ops = {
11320 + },
11321 + };
11322 +
11323 +-struct pv_apic_ops pv_apic_ops = {
11324 ++struct pv_apic_ops pv_apic_ops __read_only = {
11325 + #ifdef CONFIG_X86_LOCAL_APIC
11326 + .apic_write = native_apic_write,
11327 + .apic_write_atomic = native_apic_write_atomic,
11328 +@@ -366,7 +366,7 @@ struct pv_apic_ops pv_apic_ops = {
11329 + #endif
11330 + };
11331 +
11332 +-struct pv_mmu_ops pv_mmu_ops = {
11333 ++struct pv_mmu_ops pv_mmu_ops __read_only = {
11334 + #ifndef CONFIG_X86_64
11335 + .pagetable_setup_start = native_pagetable_setup_start,
11336 + .pagetable_setup_done = native_pagetable_setup_done,
11337 +diff -urNp a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
11338 +--- a/arch/x86/kernel/process_32.c 2008-08-20 11:16:13.000000000 -0700
11339 ++++ b/arch/x86/kernel/process_32.c 2008-08-20 18:36:57.000000000 -0700
11340 +@@ -66,8 +66,10 @@ EXPORT_SYMBOL(boot_option_idle_override)
11341 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
11342 + EXPORT_PER_CPU_SYMBOL(current_task);
11343 +
11344 ++#ifdef CONFIG_SMP
11345 + DEFINE_PER_CPU(int, cpu_number);
11346 + EXPORT_PER_CPU_SYMBOL(cpu_number);
11347 ++#endif
11348 +
11349 + /*
11350 + * Return saved PC of a blocked thread.
11351 +@@ -75,6 +77,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
11352 + unsigned long thread_saved_pc(struct task_struct *tsk)
11353 + {
11354 + return ((unsigned long *)tsk->thread.sp)[3];
11355 ++//XXX return tsk->thread.eip;
11356 + }
11357 +
11358 + /*
11359 +@@ -333,7 +336,7 @@ void __show_registers(struct pt_regs *re
11360 + unsigned long sp;
11361 + unsigned short ss, gs;
11362 +
11363 +- if (user_mode_vm(regs)) {
11364 ++ if (user_mode(regs)) {
11365 + sp = regs->sp;
11366 + ss = regs->ss & 0xffff;
11367 + savesegment(gs, gs);
11368 +@@ -411,8 +414,8 @@ int kernel_thread(int (*fn)(void *), voi
11369 + regs.bx = (unsigned long) fn;
11370 + regs.dx = (unsigned long) arg;
11371 +
11372 +- regs.ds = __USER_DS;
11373 +- regs.es = __USER_DS;
11374 ++ regs.ds = __KERNEL_DS;
11375 ++ regs.es = __KERNEL_DS;
11376 + regs.fs = __KERNEL_PERCPU;
11377 + regs.orig_ax = -1;
11378 + regs.ip = (unsigned long) kernel_thread_helper;
11379 +@@ -434,7 +437,7 @@ void exit_thread(void)
11380 + struct task_struct *tsk = current;
11381 + struct thread_struct *t = &tsk->thread;
11382 + int cpu = get_cpu();
11383 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11384 ++ struct tss_struct *tss = init_tss + cpu;
11385 +
11386 + kfree(t->io_bitmap_ptr);
11387 + t->io_bitmap_ptr = NULL;
11388 +@@ -455,6 +458,7 @@ void flush_thread(void)
11389 + {
11390 + struct task_struct *tsk = current;
11391 +
11392 ++ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
11393 + tsk->thread.debugreg0 = 0;
11394 + tsk->thread.debugreg1 = 0;
11395 + tsk->thread.debugreg2 = 0;
11396 +@@ -493,7 +497,7 @@ int copy_thread(int nr, unsigned long cl
11397 + struct task_struct *tsk;
11398 + int err;
11399 +
11400 +- childregs = task_pt_regs(p);
11401 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
11402 + *childregs = *regs;
11403 + childregs->ax = 0;
11404 + childregs->sp = sp;
11405 +@@ -522,6 +526,7 @@ int copy_thread(int nr, unsigned long cl
11406 + * Set a new TLS for the child thread?
11407 + */
11408 + if (clone_flags & CLONE_SETTLS)
11409 ++//XXX needs set_fs()?
11410 + err = do_set_thread_area(p, -1,
11411 + (struct user_desc __user *)childregs->si, 0);
11412 +
11413 +@@ -668,7 +673,7 @@ struct task_struct * __switch_to(struct
11414 + struct thread_struct *prev = &prev_p->thread,
11415 + *next = &next_p->thread;
11416 + int cpu = smp_processor_id();
11417 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11418 ++ struct tss_struct *tss = init_tss + cpu;
11419 +
11420 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
11421 +
11422 +@@ -696,6 +701,11 @@ struct task_struct * __switch_to(struct
11423 + */
11424 + savesegment(gs, prev->gs);
11425 +
11426 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
11427 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
11428 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
11429 ++#endif
11430 ++
11431 + /*
11432 + * Load the per-thread Thread-Local Storage descriptor.
11433 + */
11434 +@@ -834,15 +844,27 @@ unsigned long get_wchan(struct task_stru
11435 + return 0;
11436 + }
11437 +
11438 +-unsigned long arch_align_stack(unsigned long sp)
11439 ++#ifdef CONFIG_PAX_RANDKSTACK
11440 ++asmlinkage void pax_randomize_kstack(void)
11441 + {
11442 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
11443 +- sp -= get_random_int() % 8192;
11444 +- return sp & ~0xf;
11445 +-}
11446 ++ struct thread_struct *thread = &current->thread;
11447 ++ unsigned long time;
11448 +
11449 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
11450 +-{
11451 +- unsigned long range_end = mm->brk + 0x02000000;
11452 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
11453 ++ if (!randomize_va_space)
11454 ++ return;
11455 ++
11456 ++ rdtscl(time);
11457 ++
11458 ++ /* P4 seems to return a 0 LSB, ignore it */
11459 ++#ifdef CONFIG_MPENTIUM4
11460 ++ time &= 0x1EUL;
11461 ++ time <<= 2;
11462 ++#else
11463 ++ time &= 0xFUL;
11464 ++ time <<= 3;
11465 ++#endif
11466 ++
11467 ++ thread->sp0 ^= time;
11468 ++ load_sp0(init_tss + smp_processor_id(), thread);
11469 + }
11470 ++#endif
11471 +diff -urNp a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
11472 +--- a/arch/x86/kernel/process_64.c 2008-08-20 11:16:13.000000000 -0700
11473 ++++ b/arch/x86/kernel/process_64.c 2008-08-20 18:36:57.000000000 -0700
11474 +@@ -166,6 +166,8 @@ static inline void play_dead(void)
11475 + void cpu_idle(void)
11476 + {
11477 + current_thread_info()->status |= TS_POLLING;
11478 ++ current->stack_canary = pax_get_random_long();
11479 ++ write_pda(stack_canary, current->stack_canary);
11480 + /* endless idle loop with no priority at all */
11481 + while (1) {
11482 + tick_nohz_stop_sched_tick();
11483 +@@ -397,7 +399,7 @@ void exit_thread(void)
11484 + struct thread_struct *t = &me->thread;
11485 +
11486 + if (me->thread.io_bitmap_ptr) {
11487 +- struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
11488 ++ struct tss_struct *tss = init_tss + get_cpu();
11489 +
11490 + kfree(t->io_bitmap_ptr);
11491 + t->io_bitmap_ptr = NULL;
11492 +@@ -621,7 +623,7 @@ __switch_to(struct task_struct *prev_p,
11493 + struct thread_struct *prev = &prev_p->thread,
11494 + *next = &next_p->thread;
11495 + int cpu = smp_processor_id();
11496 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
11497 ++ struct tss_struct *tss = init_tss + cpu;
11498 +
11499 + /* we're going to use this soon, after a few expensive things */
11500 + if (next_p->fpu_counter>5)
11501 +@@ -696,7 +698,6 @@ __switch_to(struct task_struct *prev_p,
11502 + write_pda(kernelstack,
11503 + (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
11504 + #ifdef CONFIG_CC_STACKPROTECTOR
11505 +- write_pda(stack_canary, next_p->stack_canary);
11506 + /*
11507 + * Build time only check to make sure the stack_canary is at
11508 + * offset 40 in the pda; this is a gcc ABI requirement
11509 +@@ -910,16 +911,3 @@ long sys_arch_prctl(int code, unsigned l
11510 + {
11511 + return do_arch_prctl(current, code, addr);
11512 + }
11513 +-
11514 +-unsigned long arch_align_stack(unsigned long sp)
11515 +-{
11516 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
11517 +- sp -= get_random_int() % 8192;
11518 +- return sp & ~0xf;
11519 +-}
11520 +-
11521 +-unsigned long arch_randomize_brk(struct mm_struct *mm)
11522 +-{
11523 +- unsigned long range_end = mm->brk + 0x02000000;
11524 +- return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
11525 +-}
11526 +diff -urNp a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
11527 +--- a/arch/x86/kernel/ptrace.c 2008-08-20 11:16:13.000000000 -0700
11528 ++++ b/arch/x86/kernel/ptrace.c 2008-08-20 18:36:57.000000000 -0700
11529 +@@ -1457,7 +1457,7 @@ void send_sigtrap(struct task_struct *ts
11530 + info.si_code = TRAP_BRKPT;
11531 +
11532 + /* User-mode ip? */
11533 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
11534 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
11535 +
11536 + /* Send us the fake SIGTRAP */
11537 + force_sig_info(SIGTRAP, &info, tsk);
11538 +diff -urNp a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
11539 +--- a/arch/x86/kernel/reboot.c 2008-08-20 11:16:13.000000000 -0700
11540 ++++ b/arch/x86/kernel/reboot.c 2008-08-20 18:36:57.000000000 -0700
11541 +@@ -28,7 +28,7 @@ void (*pm_power_off)(void);
11542 + EXPORT_SYMBOL(pm_power_off);
11543 +
11544 + static long no_idt[3];
11545 +-static int reboot_mode;
11546 ++static unsigned short reboot_mode;
11547 + enum reboot_type reboot_type = BOOT_KBD;
11548 + int reboot_force;
11549 +
11550 +@@ -186,7 +186,7 @@ static struct dmi_system_id __initdata r
11551 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
11552 + },
11553 + },
11554 +- { }
11555 ++ { NULL, NULL, {{0, NULL}}, NULL}
11556 + };
11557 +
11558 + static int __init reboot_init(void)
11559 +@@ -202,15 +202,15 @@ core_initcall(reboot_init);
11560 + controller to pulse the CPU reset line, which is more thorough, but
11561 + doesn't work with at least one type of 486 motherboard. It is easy
11562 + to stop this code working; hence the copious comments. */
11563 +-static unsigned long long
11564 +-real_mode_gdt_entries [3] =
11565 ++static struct desc_struct
11566 ++real_mode_gdt_entries [3] __read_only =
11567 + {
11568 +- 0x0000000000000000ULL, /* Null descriptor */
11569 +- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
11570 +- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
11571 ++ {{{0x00000000, 0x00000000}}}, /* Null descriptor */
11572 ++ {{{0x0000ffff, 0x00009b00}}}, /* 16-bit real-mode 64k code at 0x00000000 */
11573 ++ {{{0x0100ffff, 0x00009300}}} /* 16-bit real-mode 64k data at 0x00000100 */
11574 + };
11575 +
11576 +-static struct desc_ptr
11577 ++static const struct desc_ptr
11578 + real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
11579 + real_mode_idt = { 0x3ff, 0 };
11580 +
11581 +@@ -232,7 +232,7 @@ real_mode_idt = { 0x3ff, 0 };
11582 +
11583 + More could be done here to set up the registers as if a CPU reset had
11584 + occurred; hopefully real BIOSs don't assume much. */
11585 +-static unsigned char real_mode_switch [] =
11586 ++static const unsigned char real_mode_switch [] =
11587 + {
11588 + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
11589 + 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
11590 +@@ -246,7 +246,7 @@ static unsigned char real_mode_switch []
11591 + 0x24, 0x10, /* f: andb $0x10,al */
11592 + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
11593 + };
11594 +-static unsigned char jump_to_bios [] =
11595 ++static const unsigned char jump_to_bios [] =
11596 + {
11597 + 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
11598 + };
11599 +@@ -256,7 +256,7 @@ static unsigned char jump_to_bios [] =
11600 + * specified by the code and length parameters.
11601 + * We assume that length will aways be less that 100!
11602 + */
11603 +-void machine_real_restart(unsigned char *code, int length)
11604 ++void machine_real_restart(const unsigned char *code, unsigned int length)
11605 + {
11606 + local_irq_disable();
11607 +
11608 +@@ -276,8 +276,8 @@ void machine_real_restart(unsigned char
11609 + /* Remap the kernel at virtual address zero, as well as offset zero
11610 + from the kernel segment. This assumes the kernel segment starts at
11611 + virtual address PAGE_OFFSET. */
11612 +- memcpy(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
11613 +- sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
11614 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
11615 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
11616 +
11617 + /*
11618 + * Use `swapper_pg_dir' as our page directory.
11619 +@@ -289,16 +289,15 @@ void machine_real_restart(unsigned char
11620 + boot)". This seems like a fairly standard thing that gets set by
11621 + REBOOT.COM programs, and the previous reset routine did this
11622 + too. */
11623 +- *((unsigned short *)0x472) = reboot_mode;
11624 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
11625 +
11626 + /* For the switch to real mode, copy some code to low memory. It has
11627 + to be in the first 64k because it is running in 16-bit mode, and it
11628 + has to have the same physical and virtual address, because it turns
11629 + off paging. Copy it near the end of the first page, out of the way
11630 + of BIOS variables. */
11631 +- memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
11632 +- real_mode_switch, sizeof (real_mode_switch));
11633 +- memcpy((void *)(0x1000 - 100), code, length);
11634 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
11635 ++ memcpy(__va(0x1000 - 100), code, length);
11636 +
11637 + /* Set up the IDT for real mode. */
11638 + load_idt(&real_mode_idt);
11639 +diff -urNp a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
11640 +--- a/arch/x86/kernel/setup64.c 2008-08-20 11:16:13.000000000 -0700
11641 ++++ b/arch/x86/kernel/setup64.c 2008-08-20 18:36:57.000000000 -0700
11642 +@@ -36,15 +36,13 @@ struct x8664_pda *_cpu_pda[NR_CPUS] __re
11643 + EXPORT_SYMBOL(_cpu_pda);
11644 + struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned;
11645 +
11646 +-struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
11647 ++struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
11648 +
11649 + char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
11650 +
11651 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
11652 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
11653 +
11654 +-static int do_not_nx __cpuinitdata = 0;
11655 +-
11656 + /* noexec=on|off
11657 + Control non executable mappings for 64bit processes.
11658 +
11659 +@@ -57,16 +55,14 @@ static int __init nonx_setup(char *str)
11660 + return -EINVAL;
11661 + if (!strncmp(str, "on", 2)) {
11662 + __supported_pte_mask |= _PAGE_NX;
11663 +- do_not_nx = 0;
11664 + } else if (!strncmp(str, "off", 3)) {
11665 +- do_not_nx = 1;
11666 + __supported_pte_mask &= ~_PAGE_NX;
11667 + }
11668 + return 0;
11669 + }
11670 + early_param("noexec", nonx_setup);
11671 +
11672 +-int force_personality32 = 0;
11673 ++int force_personality32;
11674 +
11675 + /* noexec32=on|off
11676 + Control non executable heap for 32bit processes.
11677 +@@ -226,7 +222,7 @@ void __cpuinit check_efer(void)
11678 + unsigned long efer;
11679 +
11680 + rdmsrl(MSR_EFER, efer);
11681 +- if (!(efer & EFER_NX) || do_not_nx) {
11682 ++ if (!(efer & EFER_NX)) {
11683 + __supported_pte_mask &= ~_PAGE_NX;
11684 + }
11685 + }
11686 +@@ -249,12 +245,13 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
11687 + void __cpuinit cpu_init (void)
11688 + {
11689 + int cpu = stack_smp_processor_id();
11690 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
11691 ++ struct tss_struct *t = init_tss + cpu;
11692 + struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
11693 + unsigned long v;
11694 + char *estacks = NULL;
11695 + struct task_struct *me;
11696 + int i;
11697 ++ struct desc_ptr cpu_gdt_descr = { .size = GDT_SIZE - 1, .address = (unsigned long)get_cpu_gdt_table(cpu)};
11698 +
11699 + /* CPU 0 is initialised in head64.c */
11700 + if (cpu != 0) {
11701 +@@ -272,14 +269,12 @@ void __cpuinit cpu_init (void)
11702 + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
11703 +
11704 + /*
11705 +- * Initialize the per-CPU GDT with the boot GDT,
11706 +- * and set up the GDT descriptor:
11707 ++ * Initialize the per-CPU GDT with the boot GDT:
11708 + */
11709 + if (cpu)
11710 +- memcpy(get_cpu_gdt_table(cpu), cpu_gdt_table, GDT_SIZE);
11711 ++ memcpy(get_cpu_gdt_table(cpu), get_cpu_gdt_table(0), GDT_SIZE);
11712 +
11713 +- cpu_gdt_descr[cpu].size = GDT_SIZE;
11714 +- load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
11715 ++ load_gdt(&cpu_gdt_descr);
11716 + load_idt((const struct desc_ptr *)&idt_descr);
11717 +
11718 + memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
11719 +diff -urNp a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
11720 +--- a/arch/x86/kernel/setup_32.c 2008-08-20 11:16:13.000000000 -0700
11721 ++++ b/arch/x86/kernel/setup_32.c 2008-08-20 18:36:57.000000000 -0700
11722 +@@ -64,6 +64,7 @@
11723 + #include <setup_arch.h>
11724 + #include <bios_ebda.h>
11725 + #include <asm/cacheflush.h>
11726 ++#include <asm/boot.h>
11727 +
11728 + /* This value is set up by the early boot code to point to the value
11729 + immediately after the boot time page tables. It contains a *physical*
11730 +@@ -613,8 +614,8 @@ void __init setup_bootmem_allocator(void
11731 + * the (very unlikely) case of us accidentally initializing the
11732 + * bootmem allocator with an invalid RAM area.
11733 + */
11734 +- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
11735 +- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text),
11736 ++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
11737 ++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR,
11738 + BOOTMEM_DEFAULT);
11739 +
11740 + /*
11741 +@@ -743,14 +744,14 @@ void __init setup_arch(char **cmdline_p)
11742 +
11743 + if (!boot_params.hdr.root_flags)
11744 + root_mountflags &= ~MS_RDONLY;
11745 +- init_mm.start_code = (unsigned long) _text;
11746 +- init_mm.end_code = (unsigned long) _etext;
11747 ++ init_mm.start_code = ktla_ktva((unsigned long) _text);
11748 ++ init_mm.end_code = ktla_ktva((unsigned long) _etext);
11749 + init_mm.end_data = (unsigned long) _edata;
11750 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
11751 +
11752 +- code_resource.start = virt_to_phys(_text);
11753 +- code_resource.end = virt_to_phys(_etext)-1;
11754 +- data_resource.start = virt_to_phys(_etext);
11755 ++ code_resource.start = virt_to_phys(ktla_ktva(_text));
11756 ++ code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
11757 ++ data_resource.start = virt_to_phys(_data);
11758 + data_resource.end = virt_to_phys(_edata)-1;
11759 + bss_resource.start = virt_to_phys(&__bss_start);
11760 + bss_resource.end = virt_to_phys(&__bss_stop)-1;
11761 +diff -urNp a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
11762 +--- a/arch/x86/kernel/signal_32.c 2008-08-20 11:16:13.000000000 -0700
11763 ++++ b/arch/x86/kernel/signal_32.c 2008-08-20 18:36:57.000000000 -0700
11764 +@@ -366,9 +366,9 @@ static int setup_frame(int sig, struct k
11765 + }
11766 +
11767 + if (current->binfmt->hasvdso)
11768 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
11769 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
11770 + else
11771 +- restorer = &frame->retcode;
11772 ++ restorer = (void __user *)&frame->retcode;
11773 + if (ka->sa.sa_flags & SA_RESTORER)
11774 + restorer = ka->sa.sa_restorer;
11775 +
11776 +@@ -463,7 +463,7 @@ static int setup_rt_frame(int sig, struc
11777 + goto give_sigsegv;
11778 +
11779 + /* Set up to return from userspace. */
11780 +- restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
11781 ++ restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
11782 + if (ka->sa.sa_flags & SA_RESTORER)
11783 + restorer = ka->sa.sa_restorer;
11784 + err |= __put_user(restorer, &frame->pretcode);
11785 +@@ -593,7 +593,7 @@ static void do_signal(struct pt_regs *re
11786 + * before reaching here, so testing against kernel
11787 + * CS suffices.
11788 + */
11789 +- if (!user_mode(regs))
11790 ++ if (!user_mode_novm(regs))
11791 + return;
11792 +
11793 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
11794 +diff -urNp a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
11795 +--- a/arch/x86/kernel/signal_64.c 2008-08-20 11:16:13.000000000 -0700
11796 ++++ b/arch/x86/kernel/signal_64.c 2008-08-20 18:36:57.000000000 -0700
11797 +@@ -252,8 +252,8 @@ static int setup_rt_frame(int sig, struc
11798 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
11799 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
11800 + if (sizeof(*set) == 16) {
11801 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
11802 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
11803 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
11804 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
11805 + } else
11806 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
11807 +
11808 +diff -urNp a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
11809 +--- a/arch/x86/kernel/smp_32.c 2008-08-20 11:16:13.000000000 -0700
11810 ++++ b/arch/x86/kernel/smp_32.c 2008-08-20 18:36:57.000000000 -0700
11811 +@@ -104,7 +104,7 @@
11812 + * about nothing of note with C stepping upwards.
11813 + */
11814 +
11815 +-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
11816 ++DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
11817 +
11818 + /*
11819 + * the following functions deal with sending IPIs between CPUs.
11820 +diff -urNp a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
11821 +--- a/arch/x86/kernel/smpboot_32.c 2008-08-20 11:16:13.000000000 -0700
11822 ++++ b/arch/x86/kernel/smpboot_32.c 2008-08-20 18:36:57.000000000 -0700
11823 +@@ -768,6 +768,10 @@ static int __cpuinit do_boot_cpu(int api
11824 + unsigned long start_eip;
11825 + unsigned short nmi_high = 0, nmi_low = 0;
11826 +
11827 ++#ifdef CONFIG_PAX_KERNEXEC
11828 ++ unsigned long cr0;
11829 ++#endif
11830 ++
11831 + /*
11832 + * Save current MTRR state in case it was changed since early boot
11833 + * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
11834 +@@ -784,8 +788,17 @@ static int __cpuinit do_boot_cpu(int api
11835 +
11836 + init_gdt(cpu);
11837 + per_cpu(current_task, cpu) = idle;
11838 ++
11839 ++#ifdef CONFIG_PAX_KERNEXEC
11840 ++ pax_open_kernel(cr0);
11841 ++#endif
11842 ++
11843 + early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
11844 +
11845 ++#ifdef CONFIG_PAX_KERNEXEC
11846 ++ pax_close_kernel(cr0);
11847 ++#endif
11848 ++
11849 + idle->thread.ip = (unsigned long) start_secondary;
11850 + /* start_eip had better be page-aligned! */
11851 + start_eip = setup_trampoline();
11852 +diff -urNp a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
11853 +--- a/arch/x86/kernel/smpboot_64.c 2008-08-20 11:16:13.000000000 -0700
11854 ++++ b/arch/x86/kernel/smpboot_64.c 2008-08-20 18:36:57.000000000 -0700
11855 +@@ -559,13 +559,6 @@ static int __cpuinit do_boot_cpu(int cpu
11856 + };
11857 + INIT_WORK(&c_idle.work, do_fork_idle);
11858 +
11859 +- /* allocate memory for gdts of secondary cpus. Hotplug is considered */
11860 +- if (!cpu_gdt_descr[cpu].address &&
11861 +- !(cpu_gdt_descr[cpu].address = get_zeroed_page(GFP_KERNEL))) {
11862 +- printk(KERN_ERR "Failed to allocate GDT for CPU %d\n", cpu);
11863 +- return -1;
11864 +- }
11865 +-
11866 + /* Allocate node local memory for AP pdas */
11867 + if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) {
11868 + struct x8664_pda *newpda, *pda;
11869 +@@ -624,7 +617,7 @@ do_rest:
11870 + start_rip = setup_trampoline();
11871 +
11872 + init_rsp = c_idle.idle->thread.sp;
11873 +- load_sp0(&per_cpu(init_tss, cpu), &c_idle.idle->thread);
11874 ++ load_sp0(init_tss + cpu, &c_idle.idle->thread);
11875 + initial_code = start_secondary;
11876 + clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
11877 +
11878 +diff -urNp a/arch/x86/kernel/smpcommon_32.c b/arch/x86/kernel/smpcommon_32.c
11879 +--- a/arch/x86/kernel/smpcommon_32.c 2008-08-20 11:16:13.000000000 -0700
11880 ++++ b/arch/x86/kernel/smpcommon_32.c 2008-08-20 18:36:57.000000000 -0700
11881 +@@ -3,8 +3,9 @@
11882 + */
11883 + #include <linux/module.h>
11884 + #include <asm/smp.h>
11885 ++#include <asm/sections.h>
11886 +
11887 +-DEFINE_PER_CPU(unsigned long, this_cpu_off);
11888 ++DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
11889 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
11890 +
11891 + /* Initialize the CPU's GDT. This is either the boot CPU doing itself
11892 +@@ -12,15 +13,32 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
11893 + secondary which will soon come up. */
11894 + __cpuinit void init_gdt(int cpu)
11895 + {
11896 +- struct desc_struct *gdt = get_cpu_gdt_table(cpu);
11897 ++ struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
11898 ++ unsigned long base, limit;
11899 +
11900 +- pack_descriptor(&gdt[GDT_ENTRY_PERCPU],
11901 +- __per_cpu_offset[cpu], 0xFFFFF,
11902 +- 0x2 | DESCTYPE_S, 0x8);
11903 ++#ifdef CONFIG_PAX_KERNEXEC
11904 ++ unsigned long cr0;
11905 +
11906 +- gdt[GDT_ENTRY_PERCPU].s = 1;
11907 ++ pax_open_kernel(cr0);
11908 ++#endif
11909 +
11910 +- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
11911 ++ if (cpu)
11912 ++ memcpy(gdt, get_cpu_gdt_table(0), GDT_SIZE);
11913 ++
11914 ++#ifdef CONFIG_PAX_KERNEXEC
11915 ++ pax_close_kernel(cr0);
11916 ++#endif
11917 ++
11918 ++ base = __per_cpu_offset[cpu] + (unsigned long)__per_cpu_start;
11919 ++ limit = PERCPU_ENOUGH_ROOM - 1;
11920 ++ if (limit < 64*1024)
11921 ++ pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
11922 ++ else
11923 ++ pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
11924 ++
11925 ++ write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
11926 ++
11927 ++ per_cpu(this_cpu_off, cpu) = base;
11928 + per_cpu(cpu_number, cpu) = cpu;
11929 + }
11930 +
11931 +diff -urNp a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c
11932 +--- a/arch/x86/kernel/step.c 2008-08-20 11:16:13.000000000 -0700
11933 ++++ b/arch/x86/kernel/step.c 2008-08-20 18:36:57.000000000 -0700
11934 +@@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
11935 + * and APM bios ones we just ignore here.
11936 + */
11937 + if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
11938 +- u32 *desc;
11939 ++ struct desc_struct *desc;
11940 + unsigned long base;
11941 +
11942 +- seg &= ~7UL;
11943 ++ seg >>= 3;
11944 +
11945 + mutex_lock(&child->mm->context.lock);
11946 +- if (unlikely((seg >> 3) >= child->mm->context.size))
11947 +- addr = -1L; /* bogus selector, access would fault */
11948 ++ if (unlikely(seg >= child->mm->context.size))
11949 ++ addr = -EINVAL;
11950 + else {
11951 +- desc = child->mm->context.ldt + seg;
11952 +- base = ((desc[0] >> 16) |
11953 +- ((desc[1] & 0xff) << 16) |
11954 +- (desc[1] & 0xff000000));
11955 ++ desc = &child->mm->context.ldt[seg];
11956 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
11957 +
11958 + /* 16-bit code segment? */
11959 +- if (!((desc[1] >> 22) & 1))
11960 ++ if (!((desc->b >> 22) & 1))
11961 + addr &= 0xffff;
11962 + addr += base;
11963 + }
11964 +@@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
11965 + unsigned char opcode[15];
11966 + unsigned long addr = convert_ip_to_linear(child, regs);
11967 +
11968 ++ if (addr == -EINVAL)
11969 ++ return 0;
11970 ++
11971 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
11972 + for (i = 0; i < copied; i++) {
11973 + switch (opcode[i]) {
11974 +diff -urNp a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
11975 +--- a/arch/x86/kernel/sys_i386_32.c 2008-08-20 11:16:13.000000000 -0700
11976 ++++ b/arch/x86/kernel/sys_i386_32.c 2008-08-20 18:36:57.000000000 -0700
11977 +@@ -39,6 +39,21 @@ asmlinkage int sys_pipe(unsigned long __
11978 + return error;
11979 + }
11980 +
11981 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
11982 ++{
11983 ++ unsigned long pax_task_size = TASK_SIZE;
11984 ++
11985 ++#ifdef CONFIG_PAX_SEGMEXEC
11986 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
11987 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
11988 ++#endif
11989 ++
11990 ++ if (len > pax_task_size || addr > pax_task_size - len)
11991 ++ return -EINVAL;
11992 ++
11993 ++ return 0;
11994 ++}
11995 ++
11996 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
11997 + unsigned long prot, unsigned long flags,
11998 + unsigned long fd, unsigned long pgoff)
11999 +@@ -98,6 +113,205 @@ out:
12000 + return err;
12001 + }
12002 +
12003 ++unsigned long
12004 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
12005 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
12006 ++{
12007 ++ struct mm_struct *mm = current->mm;
12008 ++ struct vm_area_struct *vma;
12009 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
12010 ++
12011 ++#ifdef CONFIG_PAX_SEGMEXEC
12012 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12013 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12014 ++#endif
12015 ++
12016 ++ if (len > pax_task_size)
12017 ++ return -ENOMEM;
12018 ++
12019 ++ if (flags & MAP_FIXED)
12020 ++ return addr;
12021 ++
12022 ++#ifdef CONFIG_PAX_RANDMMAP
12023 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
12024 ++#endif
12025 ++
12026 ++ if (addr) {
12027 ++ addr = PAGE_ALIGN(addr);
12028 ++ vma = find_vma(mm, addr);
12029 ++ if (pax_task_size - len >= addr &&
12030 ++ (!vma || addr + len <= vma->vm_start))
12031 ++ return addr;
12032 ++ }
12033 ++ if (len > mm->cached_hole_size) {
12034 ++ start_addr = addr = mm->free_area_cache;
12035 ++ } else {
12036 ++ start_addr = addr = mm->mmap_base;
12037 ++ mm->cached_hole_size = 0;
12038 ++ }
12039 ++
12040 ++#ifdef CONFIG_PAX_PAGEEXEC
12041 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
12042 ++ start_addr = 0x00110000UL;
12043 ++
12044 ++#ifdef CONFIG_PAX_RANDMMAP
12045 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12046 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
12047 ++#endif
12048 ++
12049 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
12050 ++ start_addr = addr = mm->mmap_base;
12051 ++ else
12052 ++ addr = start_addr;
12053 ++ }
12054 ++#endif
12055 ++
12056 ++full_search:
12057 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
12058 ++ /* At this point: (!vma || addr < vma->vm_end). */
12059 ++ if (pax_task_size - len < addr) {
12060 ++ /*
12061 ++ * Start a new search - just in case we missed
12062 ++ * some holes.
12063 ++ */
12064 ++ if (start_addr != mm->mmap_base) {
12065 ++ start_addr = addr = mm->mmap_base;
12066 ++ mm->cached_hole_size = 0;
12067 ++ goto full_search;
12068 ++ }
12069 ++ return -ENOMEM;
12070 ++ }
12071 ++ if (!vma || addr + len <= vma->vm_start) {
12072 ++ /*
12073 ++ * Remember the place where we stopped the search:
12074 ++ */
12075 ++ mm->free_area_cache = addr + len;
12076 ++ return addr;
12077 ++ }
12078 ++ if (addr + mm->cached_hole_size < vma->vm_start)
12079 ++ mm->cached_hole_size = vma->vm_start - addr;
12080 ++ addr = vma->vm_end;
12081 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
12082 ++ start_addr = addr = mm->mmap_base;
12083 ++ mm->cached_hole_size = 0;
12084 ++ goto full_search;
12085 ++ }
12086 ++ }
12087 ++}
12088 ++
12089 ++unsigned long
12090 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
12091 ++ const unsigned long len, const unsigned long pgoff,
12092 ++ const unsigned long flags)
12093 ++{
12094 ++ struct vm_area_struct *vma;
12095 ++ struct mm_struct *mm = current->mm;
12096 ++ unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
12097 ++
12098 ++#ifdef CONFIG_PAX_SEGMEXEC
12099 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12100 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
12101 ++#endif
12102 ++
12103 ++ /* requested length too big for entire address space */
12104 ++ if (len > pax_task_size)
12105 ++ return -ENOMEM;
12106 ++
12107 ++ if (flags & MAP_FIXED)
12108 ++ return addr;
12109 ++
12110 ++#ifdef CONFIG_PAX_PAGEEXEC
12111 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
12112 ++ goto bottomup;
12113 ++#endif
12114 ++
12115 ++#ifdef CONFIG_PAX_RANDMMAP
12116 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
12117 ++#endif
12118 ++
12119 ++ /* requesting a specific address */
12120 ++ if (addr) {
12121 ++ addr = PAGE_ALIGN(addr);
12122 ++ vma = find_vma(mm, addr);
12123 ++ if (pax_task_size - len >= addr &&
12124 ++ (!vma || addr + len <= vma->vm_start))
12125 ++ return addr;
12126 ++ }
12127 ++
12128 ++ /* check if free_area_cache is useful for us */
12129 ++ if (len <= mm->cached_hole_size) {
12130 ++ mm->cached_hole_size = 0;
12131 ++ mm->free_area_cache = mm->mmap_base;
12132 ++ }
12133 ++
12134 ++ /* either no address requested or can't fit in requested address hole */
12135 ++ addr = mm->free_area_cache;
12136 ++
12137 ++ /* make sure it can fit in the remaining address space */
12138 ++ if (addr > len) {
12139 ++ vma = find_vma(mm, addr-len);
12140 ++ if (!vma || addr <= vma->vm_start)
12141 ++ /* remember the address as a hint for next time */
12142 ++ return (mm->free_area_cache = addr-len);
12143 ++ }
12144 ++
12145 ++ if (mm->mmap_base < len)
12146 ++ goto bottomup;
12147 ++
12148 ++ addr = mm->mmap_base-len;
12149 ++
12150 ++ do {
12151 ++ /*
12152 ++ * Lookup failure means no vma is above this address,
12153 ++ * else if new region fits below vma->vm_start,
12154 ++ * return with success:
12155 ++ */
12156 ++ vma = find_vma(mm, addr);
12157 ++ if (!vma || addr+len <= vma->vm_start)
12158 ++ /* remember the address as a hint for next time */
12159 ++ return (mm->free_area_cache = addr);
12160 ++
12161 ++ /* remember the largest hole we saw so far */
12162 ++ if (addr + mm->cached_hole_size < vma->vm_start)
12163 ++ mm->cached_hole_size = vma->vm_start - addr;
12164 ++
12165 ++ /* try just below the current vma->vm_start */
12166 ++ addr = vma->vm_start-len;
12167 ++ } while (len < vma->vm_start);
12168 ++
12169 ++bottomup:
12170 ++ /*
12171 ++ * A failed mmap() very likely causes application failure,
12172 ++ * so fall back to the bottom-up function here. This scenario
12173 ++ * can happen with large stack limits and large mmap()
12174 ++ * allocations.
12175 ++ */
12176 ++
12177 ++#ifdef CONFIG_PAX_SEGMEXEC
12178 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12179 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
12180 ++ else
12181 ++#endif
12182 ++
12183 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12184 ++
12185 ++#ifdef CONFIG_PAX_RANDMMAP
12186 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12187 ++ mm->mmap_base += mm->delta_mmap;
12188 ++#endif
12189 ++
12190 ++ mm->free_area_cache = mm->mmap_base;
12191 ++ mm->cached_hole_size = ~0UL;
12192 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
12193 ++ /*
12194 ++ * Restore the topdown base:
12195 ++ */
12196 ++ mm->mmap_base = base;
12197 ++ mm->free_area_cache = base;
12198 ++ mm->cached_hole_size = ~0UL;
12199 ++
12200 ++ return addr;
12201 ++}
12202 +
12203 + struct sel_arg_struct {
12204 + unsigned long n;
12205 +diff -urNp a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
12206 +--- a/arch/x86/kernel/sys_x86_64.c 2008-08-20 11:16:13.000000000 -0700
12207 ++++ b/arch/x86/kernel/sys_x86_64.c 2008-08-20 18:36:57.000000000 -0700
12208 +@@ -62,8 +62,8 @@ out:
12209 + return error;
12210 + }
12211 +
12212 +-static void find_start_end(unsigned long flags, unsigned long *begin,
12213 +- unsigned long *end)
12214 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
12215 ++ unsigned long *begin, unsigned long *end)
12216 + {
12217 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
12218 + unsigned long new_begin;
12219 +@@ -82,7 +82,7 @@ static void find_start_end(unsigned long
12220 + *begin = new_begin;
12221 + }
12222 + } else {
12223 +- *begin = TASK_UNMAPPED_BASE;
12224 ++ *begin = mm->mmap_base;
12225 + *end = TASK_SIZE;
12226 + }
12227 + }
12228 +@@ -99,11 +99,15 @@ arch_get_unmapped_area(struct file *filp
12229 + if (flags & MAP_FIXED)
12230 + return addr;
12231 +
12232 +- find_start_end(flags, &begin, &end);
12233 ++ find_start_end(mm, flags, &begin, &end);
12234 +
12235 + if (len > end)
12236 + return -ENOMEM;
12237 +
12238 ++#ifdef CONFIG_PAX_RANDMMAP
12239 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
12240 ++#endif
12241 ++
12242 + if (addr) {
12243 + addr = PAGE_ALIGN(addr);
12244 + vma = find_vma(mm, addr);
12245 +@@ -158,7 +162,7 @@ arch_get_unmapped_area_topdown(struct fi
12246 + {
12247 + struct vm_area_struct *vma;
12248 + struct mm_struct *mm = current->mm;
12249 +- unsigned long addr = addr0;
12250 ++ unsigned long base = mm->mmap_base, addr = addr0;
12251 +
12252 + /* requested length too big for entire address space */
12253 + if (len > TASK_SIZE)
12254 +@@ -171,6 +175,10 @@ arch_get_unmapped_area_topdown(struct fi
12255 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
12256 + goto bottomup;
12257 +
12258 ++#ifdef CONFIG_PAX_RANDMMAP
12259 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
12260 ++#endif
12261 ++
12262 + /* requesting a specific address */
12263 + if (addr) {
12264 + addr = PAGE_ALIGN(addr);
12265 +@@ -228,13 +236,21 @@ bottomup:
12266 + * can happen with large stack limits and large mmap()
12267 + * allocations.
12268 + */
12269 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12270 ++
12271 ++#ifdef CONFIG_PAX_RANDMMAP
12272 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12273 ++ mm->mmap_base += mm->delta_mmap;
12274 ++#endif
12275 ++
12276 ++ mm->free_area_cache = mm->mmap_base;
12277 + mm->cached_hole_size = ~0UL;
12278 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
12279 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
12280 + /*
12281 + * Restore the topdown base:
12282 + */
12283 +- mm->free_area_cache = mm->mmap_base;
12284 ++ mm->mmap_base = base;
12285 ++ mm->free_area_cache = base;
12286 + mm->cached_hole_size = ~0UL;
12287 +
12288 + return addr;
12289 +diff -urNp a/arch/x86/kernel/syscall_table_32.S b/arch/x86/kernel/syscall_table_32.S
12290 +--- a/arch/x86/kernel/syscall_table_32.S 2008-08-20 11:16:13.000000000 -0700
12291 ++++ b/arch/x86/kernel/syscall_table_32.S 2008-08-20 18:36:57.000000000 -0700
12292 +@@ -1,3 +1,4 @@
12293 ++.section .rodata,"a",@progbits
12294 + ENTRY(sys_call_table)
12295 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
12296 + .long sys_exit
12297 +diff -urNp a/arch/x86/kernel/time_32.c b/arch/x86/kernel/time_32.c
12298 +--- a/arch/x86/kernel/time_32.c 2008-08-20 11:16:13.000000000 -0700
12299 ++++ b/arch/x86/kernel/time_32.c 2008-08-20 18:36:57.000000000 -0700
12300 +@@ -52,20 +52,30 @@ unsigned long profile_pc(struct pt_regs
12301 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
12302 + in_lock_functions(pc)) {
12303 + #ifdef CONFIG_FRAME_POINTER
12304 +- return *(unsigned long *)(regs->bp + 4);
12305 ++ return ktla_ktva(*(unsigned long *)(regs->bp + 4));
12306 + #else
12307 + unsigned long *sp = (unsigned long *)&regs->sp;
12308 +
12309 + /* Return address is either directly at stack pointer
12310 + or above a saved flags. Eflags has bits 22-31 zero,
12311 + kernel addresses don't. */
12312 ++
12313 ++#ifdef CONFIG_PAX_KERNEXEC
12314 ++ return ktla_ktva(sp[0]);
12315 ++#else
12316 + if (sp[0] >> 22)
12317 + return sp[0];
12318 + if (sp[1] >> 22)
12319 + return sp[1];
12320 + #endif
12321 ++
12322 ++#endif
12323 + }
12324 + #endif
12325 ++
12326 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
12327 ++ pc = ktla_ktva(pc);
12328 ++
12329 + return pc;
12330 + }
12331 + EXPORT_SYMBOL(profile_pc);
12332 +diff -urNp a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
12333 +--- a/arch/x86/kernel/tls.c 2008-08-20 11:16:13.000000000 -0700
12334 ++++ b/arch/x86/kernel/tls.c 2008-08-20 18:36:57.000000000 -0700
12335 +@@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
12336 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
12337 + return -EINVAL;
12338 +
12339 ++#ifdef CONFIG_PAX_SEGMEXEC
12340 ++ if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
12341 ++ return -EINVAL;
12342 ++#endif
12343 ++
12344 + set_tls_desc(p, idx, &info, 1);
12345 +
12346 + return 0;
12347 +diff -urNp a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
12348 +--- a/arch/x86/kernel/traps_32.c 2008-08-20 11:16:13.000000000 -0700
12349 ++++ b/arch/x86/kernel/traps_32.c 2008-08-20 18:36:57.000000000 -0700
12350 +@@ -29,6 +29,7 @@
12351 + #include <linux/uaccess.h>
12352 + #include <linux/nmi.h>
12353 + #include <linux/bug.h>
12354 ++#include <linux/binfmts.h>
12355 +
12356 + #ifdef CONFIG_EISA
12357 + #include <linux/ioport.h>
12358 +@@ -71,14 +72,6 @@ asmlinkage int system_call(void);
12359 + /* Do we ignore FPU interrupts ? */
12360 + char ignore_fpu_irq = 0;
12361 +
12362 +-/*
12363 +- * The IDT has to be page-aligned to simplify the Pentium
12364 +- * F0 0F bug workaround.. We have a special link segment
12365 +- * for this.
12366 +- */
12367 +-gate_desc idt_table[256]
12368 +- __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
12369 +-
12370 + asmlinkage void divide_error(void);
12371 + asmlinkage void debug(void);
12372 + asmlinkage void nmi(void);
12373 +@@ -330,22 +323,23 @@ void show_registers(struct pt_regs *regs
12374 + * When in-kernel, we also print out the stack and code at the
12375 + * time of the fault..
12376 + */
12377 +- if (!user_mode_vm(regs)) {
12378 ++ if (!user_mode(regs)) {
12379 + u8 *ip;
12380 + unsigned int code_prologue = code_bytes * 43 / 64;
12381 + unsigned int code_len = code_bytes;
12382 + unsigned char c;
12383 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
12384 +
12385 + printk("\n" KERN_EMERG "Stack: ");
12386 + show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
12387 +
12388 + printk(KERN_EMERG "Code: ");
12389 +
12390 +- ip = (u8 *)regs->ip - code_prologue;
12391 ++ ip = (u8 *)regs->ip - code_prologue + cs_base;
12392 + if (ip < (u8 *)PAGE_OFFSET ||
12393 + probe_kernel_address(ip, c)) {
12394 + /* try starting at EIP */
12395 +- ip = (u8 *)regs->ip;
12396 ++ ip = (u8 *)regs->ip + cs_base;
12397 + code_len = code_len - code_prologue + 1;
12398 + }
12399 + for (i = 0; i < code_len; i++, ip++) {
12400 +@@ -354,7 +348,7 @@ void show_registers(struct pt_regs *regs
12401 + printk(" Bad EIP value.");
12402 + break;
12403 + }
12404 +- if (ip == (u8 *)regs->ip)
12405 ++ if (ip == (u8 *)regs->ip + cs_base)
12406 + printk("<%02x> ", c);
12407 + else
12408 + printk("%02x ", c);
12409 +@@ -367,6 +361,7 @@ int is_valid_bugaddr(unsigned long ip)
12410 + {
12411 + unsigned short ud2;
12412 +
12413 ++ ip = ktla_ktva(ip);
12414 + if (ip < PAGE_OFFSET)
12415 + return 0;
12416 + if (probe_kernel_address((unsigned short *)ip, ud2))
12417 +@@ -476,7 +471,7 @@ void die(const char * str, struct pt_reg
12418 +
12419 + static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
12420 + {
12421 +- if (!user_mode_vm(regs))
12422 ++ if (!user_mode(regs))
12423 + die(str, regs, err);
12424 + }
12425 +
12426 +@@ -492,7 +487,7 @@ static void __kprobes do_trap(int trapnr
12427 + goto trap_signal;
12428 + }
12429 +
12430 +- if (!user_mode(regs))
12431 ++ if (!user_mode_novm(regs))
12432 + goto kernel_trap;
12433 +
12434 + trap_signal: {
12435 +@@ -598,7 +593,7 @@ void __kprobes do_general_protection(str
12436 + long error_code)
12437 + {
12438 + int cpu = get_cpu();
12439 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
12440 ++ struct tss_struct *tss = &init_tss[cpu];
12441 + struct thread_struct *thread = &current->thread;
12442 +
12443 + /*
12444 +@@ -631,9 +626,25 @@ void __kprobes do_general_protection(str
12445 + if (regs->flags & VM_MASK)
12446 + goto gp_in_vm86;
12447 +
12448 +- if (!user_mode(regs))
12449 ++ if (!user_mode_novm(regs))
12450 + goto gp_in_kernel;
12451 +
12452 ++#ifdef CONFIG_PAX_PAGEEXEC
12453 ++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
12454 ++ struct mm_struct *mm = current->mm;
12455 ++ unsigned long limit;
12456 ++
12457 ++ down_write(&mm->mmap_sem);
12458 ++ limit = mm->context.user_cs_limit;
12459 ++ if (limit < TASK_SIZE) {
12460 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
12461 ++ up_write(&mm->mmap_sem);
12462 ++ return;
12463 ++ }
12464 ++ up_write(&mm->mmap_sem);
12465 ++ }
12466 ++#endif
12467 ++
12468 + current->thread.error_code = error_code;
12469 + current->thread.trap_no = 13;
12470 + if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
12471 +@@ -661,6 +672,13 @@ gp_in_kernel:
12472 + if (notify_die(DIE_GPF, "general protection fault", regs,
12473 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
12474 + return;
12475 ++
12476 ++#ifdef CONFIG_PAX_KERNEXEC
12477 ++ if ((regs->cs & 0xFFFF) == __KERNEL_CS)
12478 ++ die("PAX: suspicious general protection fault", regs, error_code);
12479 ++ else
12480 ++#endif
12481 ++
12482 + die("general protection fault", regs, error_code);
12483 + }
12484 + }
12485 +@@ -750,7 +768,7 @@ void __kprobes die_nmi(struct pt_regs *r
12486 + /* If we are in kernel we are probably nested up pretty bad
12487 + * and might aswell get out now while we still can.
12488 + */
12489 +- if (!user_mode_vm(regs)) {
12490 ++ if (!user_mode(regs)) {
12491 + current->thread.trap_no = 2;
12492 + crash_kexec(regs);
12493 + }
12494 +@@ -907,7 +925,7 @@ void __kprobes do_debug(struct pt_regs *
12495 + * check for kernel mode by just checking the CPL
12496 + * of CS.
12497 + */
12498 +- if (!user_mode(regs))
12499 ++ if (!user_mode_novm(regs))
12500 + goto clear_TF_reenable;
12501 + }
12502 +
12503 +@@ -1085,18 +1103,14 @@ void do_spurious_interrupt_bug(struct pt
12504 + unsigned long patch_espfix_desc(unsigned long uesp,
12505 + unsigned long kesp)
12506 + {
12507 +- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
12508 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
12509 + unsigned long new_kesp = kesp - base;
12510 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
12511 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
12512 ++ struct desc_struct ss;
12513 ++
12514 + /* Set up base for espfix segment */
12515 +- desc &= 0x00f0ff0000000000ULL;
12516 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
12517 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
12518 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
12519 +- (lim_pages & 0xffff);
12520 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
12521 ++ pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
12522 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
12523 + return new_kesp;
12524 + }
12525 +
12526 +diff -urNp a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
12527 +--- a/arch/x86/kernel/tsc_32.c 2008-08-20 11:16:13.000000000 -0700
12528 ++++ b/arch/x86/kernel/tsc_32.c 2008-08-20 18:36:57.000000000 -0700
12529 +@@ -338,7 +338,7 @@ static struct dmi_system_id __initdata b
12530 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
12531 + },
12532 + },
12533 +- {}
12534 ++ { NULL, NULL, {{0, NULL}}, NULL}
12535 + };
12536 +
12537 + /*
12538 +diff -urNp a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
12539 +--- a/arch/x86/kernel/vm86_32.c 2008-08-20 11:16:13.000000000 -0700
12540 ++++ b/arch/x86/kernel/vm86_32.c 2008-08-20 18:36:57.000000000 -0700
12541 +@@ -145,7 +145,7 @@ struct pt_regs * save_v86_state(struct k
12542 + do_exit(SIGSEGV);
12543 + }
12544 +
12545 +- tss = &per_cpu(init_tss, get_cpu());
12546 ++ tss = init_tss + get_cpu();
12547 + current->thread.sp0 = current->thread.saved_sp0;
12548 + current->thread.sysenter_cs = __KERNEL_CS;
12549 + load_sp0(tss, &current->thread);
12550 +@@ -321,7 +321,7 @@ static void do_sys_vm86(struct kernel_vm
12551 + tsk->thread.saved_fs = info->regs32->fs;
12552 + savesegment(gs, tsk->thread.saved_gs);
12553 +
12554 +- tss = &per_cpu(init_tss, get_cpu());
12555 ++ tss = init_tss + get_cpu();
12556 + tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
12557 + if (cpu_has_sep)
12558 + tsk->thread.sysenter_cs = 0;
12559 +diff -urNp a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
12560 +--- a/arch/x86/kernel/vmi_32.c 2008-08-20 11:16:13.000000000 -0700
12561 ++++ b/arch/x86/kernel/vmi_32.c 2008-08-20 18:36:57.000000000 -0700
12562 +@@ -101,18 +101,43 @@ static unsigned patch_internal(int call,
12563 + {
12564 + u64 reloc;
12565 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
12566 ++
12567 ++#ifdef CONFIG_PAX_KERNEXEC
12568 ++ unsigned long cr0;
12569 ++#endif
12570 ++
12571 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
12572 + switch(rel->type) {
12573 + case VMI_RELOCATION_CALL_REL:
12574 + BUG_ON(len < 5);
12575 ++
12576 ++#ifdef CONFIG_PAX_KERNEXEC
12577 ++ pax_open_kernel(cr0);
12578 ++#endif
12579 ++
12580 + *(char *)insnbuf = MNEM_CALL;
12581 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
12582 ++
12583 ++#ifdef CONFIG_PAX_KERNEXEC
12584 ++ pax_close_kernel(cr0);
12585 ++#endif
12586 ++
12587 + return 5;
12588 +
12589 + case VMI_RELOCATION_JUMP_REL:
12590 + BUG_ON(len < 5);
12591 ++
12592 ++#ifdef CONFIG_PAX_KERNEXEC
12593 ++ pax_open_kernel(cr0);
12594 ++#endif
12595 ++
12596 + *(char *)insnbuf = MNEM_JMP;
12597 + patch_offset(insnbuf, ip, (unsigned long)rel->eip);
12598 ++
12599 ++#ifdef CONFIG_PAX_KERNEXEC
12600 ++ pax_close_kernel(cr0);
12601 ++#endif
12602 ++
12603 + return 5;
12604 +
12605 + case VMI_RELOCATION_NOP:
12606 +@@ -515,14 +540,14 @@ static void vmi_set_pud(pud_t *pudp, pud
12607 +
12608 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
12609 + {
12610 +- const pte_t pte = { .pte = 0 };
12611 ++ const pte_t pte = __pte(0ULL);
12612 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
12613 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
12614 + }
12615 +
12616 + static void vmi_pmd_clear(pmd_t *pmd)
12617 + {
12618 +- const pte_t pte = { .pte = 0 };
12619 ++ const pte_t pte = __pte(0ULL);
12620 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
12621 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
12622 + }
12623 +@@ -551,8 +576,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
12624 + ap.ss = __KERNEL_DS;
12625 + ap.esp = (unsigned long) start_esp;
12626 +
12627 +- ap.ds = __USER_DS;
12628 +- ap.es = __USER_DS;
12629 ++ ap.ds = __KERNEL_DS;
12630 ++ ap.es = __KERNEL_DS;
12631 + ap.fs = __KERNEL_PERCPU;
12632 + ap.gs = 0;
12633 +
12634 +@@ -747,12 +772,20 @@ static inline int __init activate_vmi(vo
12635 + u64 reloc;
12636 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
12637 +
12638 ++#ifdef CONFIG_PAX_KERNEXEC
12639 ++ unsigned long cr0;
12640 ++#endif
12641 ++
12642 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
12643 + printk(KERN_ERR "VMI ROM failed to initialize!");
12644 + return 0;
12645 + }
12646 + savesegment(cs, kernel_cs);
12647 +
12648 ++#ifdef CONFIG_PAX_KERNEXEC
12649 ++ pax_open_kernel(cr0);
12650 ++#endif
12651 ++
12652 + pv_info.paravirt_enabled = 1;
12653 + pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
12654 + pv_info.name = "vmi";
12655 +@@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
12656 +
12657 + para_fill(pv_irq_ops.safe_halt, Halt);
12658 +
12659 ++#ifdef CONFIG_PAX_KERNEXEC
12660 ++ pax_close_kernel(cr0);
12661 ++#endif
12662 ++
12663 + /*
12664 + * Alternative instruction rewriting doesn't happen soon enough
12665 + * to convert VMI_IRET to a call instead of a jump; so we have
12666 +diff -urNp a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
12667 +--- a/arch/x86/kernel/vmlinux_32.lds.S 2008-08-20 11:16:13.000000000 -0700
12668 ++++ b/arch/x86/kernel/vmlinux_32.lds.S 2008-08-20 18:36:57.000000000 -0700
12669 +@@ -15,6 +15,20 @@
12670 + #include <asm/page.h>
12671 + #include <asm/cache.h>
12672 + #include <asm/boot.h>
12673 ++#include <asm/segment.h>
12674 ++
12675 ++#ifdef CONFIG_X86_PAE
12676 ++#define PMD_SHIFT 21
12677 ++#else
12678 ++#define PMD_SHIFT 22
12679 ++#endif
12680 ++#define PMD_SIZE (1 << PMD_SHIFT)
12681 ++
12682 ++#ifdef CONFIG_PAX_KERNEXEC
12683 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
12684 ++#else
12685 ++#define __KERNEL_TEXT_OFFSET 0
12686 ++#endif
12687 +
12688 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
12689 + OUTPUT_ARCH(i386)
12690 +@@ -22,90 +36,23 @@ ENTRY(phys_startup_32)
12691 + jiffies = jiffies_64;
12692 +
12693 + PHDRS {
12694 +- text PT_LOAD FLAGS(5); /* R_E */
12695 +- data PT_LOAD FLAGS(7); /* RWE */
12696 +- note PT_NOTE FLAGS(0); /* ___ */
12697 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
12698 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
12699 ++ inittext PT_LOAD FLAGS(5); /* R_E */
12700 ++ text PT_LOAD FLAGS(5); /* R_E */
12701 ++ rodata PT_LOAD FLAGS(4); /* R__ */
12702 ++ data PT_LOAD FLAGS(6); /* RW_ */
12703 ++ note PT_NOTE FLAGS(0); /* ___ */
12704 + }
12705 + SECTIONS
12706 + {
12707 +- . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
12708 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
12709 +-
12710 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
12711 +- _text = .; /* Text and read-only data */
12712 +- *(.text.head)
12713 +- } :text = 0x9090
12714 +-
12715 +- /* read-only */
12716 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
12717 +- . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
12718 +- *(.text.page_aligned)
12719 +- TEXT_TEXT
12720 +- SCHED_TEXT
12721 +- LOCK_TEXT
12722 +- KPROBES_TEXT
12723 +- *(.fixup)
12724 +- *(.gnu.warning)
12725 +- _etext = .; /* End of text section */
12726 +- } :text = 0x9090
12727 +-
12728 +- . = ALIGN(16); /* Exception table */
12729 +- __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
12730 +- __start___ex_table = .;
12731 +- *(__ex_table)
12732 +- __stop___ex_table = .;
12733 +- }
12734 +-
12735 +- NOTES :text :note
12736 +-
12737 +- BUG_TABLE :text
12738 +-
12739 +- . = ALIGN(4);
12740 +- .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
12741 +- __tracedata_start = .;
12742 +- *(.tracedata)
12743 +- __tracedata_end = .;
12744 +- }
12745 ++ . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
12746 +
12747 +- RODATA
12748 +-
12749 +- /* writeable */
12750 +- . = ALIGN(PAGE_SIZE);
12751 +- .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
12752 +- DATA_DATA
12753 +- CONSTRUCTORS
12754 +- } :data
12755 +-
12756 +- . = ALIGN(PAGE_SIZE);
12757 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
12758 +- __nosave_begin = .;
12759 +- *(.data.nosave)
12760 +- . = ALIGN(PAGE_SIZE);
12761 +- __nosave_end = .;
12762 +- }
12763 +-
12764 +- . = ALIGN(PAGE_SIZE);
12765 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
12766 +- *(.data.page_aligned)
12767 +- *(.data.idt)
12768 +- }
12769 +-
12770 +- . = ALIGN(32);
12771 +- .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
12772 +- *(.data.cacheline_aligned)
12773 +- }
12774 +-
12775 +- /* rarely changed data like cpu maps */
12776 +- . = ALIGN(32);
12777 +- .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
12778 +- *(.data.read_mostly)
12779 +- _edata = .; /* End of data section */
12780 +- }
12781 +-
12782 +- . = ALIGN(THREAD_SIZE); /* init_task */
12783 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
12784 +- *(.data.init_task)
12785 +- }
12786 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
12787 ++ __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
12788 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
12789 ++ *(.text.startup)
12790 ++ } :initdata
12791 +
12792 + /* might get freed after init */
12793 + . = ALIGN(PAGE_SIZE);
12794 +@@ -123,14 +70,8 @@ SECTIONS
12795 + . = ALIGN(PAGE_SIZE);
12796 +
12797 + /* will be freed after init */
12798 +- . = ALIGN(PAGE_SIZE); /* Init code and data */
12799 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
12800 +- __init_begin = .;
12801 +- _sinittext = .;
12802 +- INIT_TEXT
12803 +- _einittext = .;
12804 +- }
12805 + .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
12806 ++ __init_begin = .;
12807 + INIT_DATA
12808 + }
12809 + . = ALIGN(16);
12810 +@@ -165,11 +106,6 @@ SECTIONS
12811 + *(.parainstructions)
12812 + __parainstructions_end = .;
12813 + }
12814 +- /* .exit.text is discard at runtime, not link time, to deal with references
12815 +- from .altinstructions and .eh_frame */
12816 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
12817 +- EXIT_TEXT
12818 +- }
12819 + .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
12820 + EXIT_DATA
12821 + }
12822 +@@ -182,17 +118,144 @@ SECTIONS
12823 + }
12824 + #endif
12825 + . = ALIGN(PAGE_SIZE);
12826 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
12827 +- __per_cpu_start = .;
12828 ++ per_cpu_start = .;
12829 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
12830 ++ __per_cpu_start = . + per_cpu_start;
12831 ++ LONG(0)
12832 + *(.data.percpu)
12833 + *(.data.percpu.shared_aligned)
12834 +- __per_cpu_end = .;
12835 +- }
12836 ++ __per_cpu_end = . + per_cpu_start;
12837 ++ } :percpu
12838 ++ . += per_cpu_start;
12839 + . = ALIGN(PAGE_SIZE);
12840 + /* freed after init ends here */
12841 +
12842 ++ . = ALIGN(PAGE_SIZE); /* Init code and data */
12843 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12844 ++ _sinittext = .;
12845 ++ INIT_TEXT
12846 ++ _einittext = .;
12847 ++ } :inittext
12848 ++
12849 ++ /* .exit.text is discard at runtime, not link time, to deal with references
12850 ++ from .altinstructions and .eh_frame */
12851 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12852 ++ EXIT_TEXT
12853 ++ }
12854 ++
12855 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12856 ++ BYTE(0)
12857 ++ . = ALIGN(2*PMD_SIZE) - 1;
12858 ++ }
12859 ++
12860 ++ /* freed after init ends here */
12861 ++
12862 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12863 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
12864 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
12865 ++ _text = .; /* Text and read-only data */
12866 ++ *(.text.head)
12867 ++ } :text = 0x9090
12868 ++
12869 ++ /* read-only */
12870 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
12871 ++ . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
12872 ++ *(.text.page_aligned)
12873 ++ TEXT_TEXT
12874 ++ SCHED_TEXT
12875 ++ LOCK_TEXT
12876 ++ KPROBES_TEXT
12877 ++ *(.fixup)
12878 ++ *(.gnu.warning)
12879 ++ _etext = .; /* End of text section */
12880 ++ } :text = 0x9090
12881 ++
12882 ++ . += __KERNEL_TEXT_OFFSET;
12883 ++ . = ALIGN(4096); /* Exception table */
12884 ++ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
12885 ++ __start___ex_table = .;
12886 ++ *(__ex_table)
12887 ++ __stop___ex_table = .;
12888 ++ } :rodata
12889 ++
12890 ++ NOTES :rodata :note
12891 ++
12892 ++ BUG_TABLE :rodata
12893 ++
12894 ++ . = ALIGN(4);
12895 ++ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
12896 ++ __tracedata_start = .;
12897 ++ *(.tracedata)
12898 ++ __tracedata_end = .;
12899 ++ }
12900 ++
12901 ++ RO_DATA(PAGE_SIZE)
12902 ++
12903 ++ . = ALIGN(PAGE_SIZE);
12904 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
12905 ++ *(.idt)
12906 ++ . = ALIGN(PAGE_SIZE);
12907 ++ *(.empty_zero_page)
12908 ++ *(.swapper_pg_pmd)
12909 ++ *(.swapper_pg_dir)
12910 ++ }
12911 ++
12912 ++#ifdef CONFIG_PAX_KERNEXEC
12913 ++
12914 ++#ifdef CONFIG_MODULES
12915 ++ . = ALIGN(PAGE_SIZE);
12916 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
12917 ++ MODULES_VADDR = .;
12918 ++ BYTE(0)
12919 ++ . += (6 * 1024 * 1024);
12920 ++ . = ALIGN( PMD_SIZE) - 1;
12921 ++ MODULES_END = .;
12922 ++ }
12923 ++#else
12924 ++ . = ALIGN(PMD_SIZE) - 1;
12925 ++#endif
12926 ++
12927 ++#endif
12928 ++
12929 ++ /* writeable */
12930 ++ . = ALIGN(PAGE_SIZE);
12931 ++ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
12932 ++ _data = .;
12933 ++ DATA_DATA
12934 ++ CONSTRUCTORS
12935 ++ } :data
12936 ++
12937 ++ . = ALIGN(PAGE_SIZE);
12938 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
12939 ++ __nosave_begin = .;
12940 ++ *(.data.nosave)
12941 ++ . = ALIGN(PAGE_SIZE);
12942 ++ __nosave_end = .;
12943 ++ }
12944 ++
12945 ++ . = ALIGN(PAGE_SIZE);
12946 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
12947 ++ *(.data.page_aligned)
12948 ++ }
12949 ++
12950 ++ . = ALIGN(32);
12951 ++ .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
12952 ++ *(.data.cacheline_aligned)
12953 ++ }
12954 ++
12955 ++ /* rarely changed data like cpu maps */
12956 ++ . = ALIGN(32);
12957 ++ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
12958 ++ *(.data.read_mostly)
12959 ++ _edata = .; /* End of data section */
12960 ++ }
12961 ++
12962 ++ . = ALIGN(THREAD_SIZE); /* init_task */
12963 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
12964 ++ *(.data.init_task)
12965 ++ }
12966 ++
12967 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
12968 +- __init_end = .;
12969 + __bss_start = .; /* BSS */
12970 + *(.bss.page_aligned)
12971 + *(.bss)
12972 +diff -urNp a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
12973 +--- a/arch/x86/kernel/vmlinux_64.lds.S 2008-08-20 11:16:13.000000000 -0700
12974 ++++ b/arch/x86/kernel/vmlinux_64.lds.S 2008-08-20 18:36:57.000000000 -0700
12975 +@@ -16,8 +16,8 @@ jiffies_64 = jiffies;
12976 + _proxy_pda = 1;
12977 + PHDRS {
12978 + text PT_LOAD FLAGS(5); /* R_E */
12979 +- data PT_LOAD FLAGS(7); /* RWE */
12980 +- user PT_LOAD FLAGS(7); /* RWE */
12981 ++ data PT_LOAD FLAGS(6); /* RW_ */
12982 ++ user PT_LOAD FLAGS(7); /* RWX */
12983 + data.init PT_LOAD FLAGS(7); /* RWE */
12984 + note PT_NOTE FLAGS(4); /* R__ */
12985 + }
12986 +@@ -51,7 +51,7 @@ SECTIONS
12987 +
12988 + BUG_TABLE :text
12989 +
12990 +- RODATA
12991 ++ RO_DATA(PAGE_SIZE)
12992 +
12993 + . = ALIGN(4);
12994 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
12995 +@@ -60,15 +60,18 @@ SECTIONS
12996 + __tracedata_end = .;
12997 + }
12998 +
12999 ++#ifdef CONFIG_PAX_KERNEXEC
13000 ++ . = ALIGN(2*1024*1024); /* Align data segment to PMD size boundary */
13001 ++#else
13002 + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
13003 ++#endif
13004 + /* Data */
13005 ++ _data = .;
13006 + .data : AT(ADDR(.data) - LOAD_OFFSET) {
13007 + DATA_DATA
13008 + CONSTRUCTORS
13009 + } :data
13010 +
13011 +- _edata = .; /* End of data section */
13012 +-
13013 + . = ALIGN(PAGE_SIZE);
13014 + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
13015 + .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
13016 +@@ -79,9 +82,27 @@ SECTIONS
13017 + *(.data.read_mostly)
13018 + }
13019 +
13020 ++ . = ALIGN(THREAD_SIZE); /* init_task */
13021 ++ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
13022 ++ *(.data.init_task)
13023 ++ }
13024 ++
13025 ++ . = ALIGN(PAGE_SIZE);
13026 ++ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
13027 ++ *(.data.page_aligned)
13028 ++ }
13029 ++
13030 ++ . = ALIGN(PAGE_SIZE);
13031 ++ __nosave_begin = .;
13032 ++ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
13033 ++ . = ALIGN(PAGE_SIZE);
13034 ++ __nosave_end = .;
13035 ++
13036 ++ _edata = .; /* End of data section */
13037 ++
13038 + #define VSYSCALL_ADDR (-10*1024*1024)
13039 +-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
13040 +-#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
13041 ++#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
13042 ++#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
13043 +
13044 + #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
13045 + #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
13046 +@@ -129,23 +150,13 @@ SECTIONS
13047 + #undef VVIRT_OFFSET
13048 + #undef VVIRT
13049 +
13050 +- . = ALIGN(THREAD_SIZE); /* init_task */
13051 +- .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
13052 +- *(.data.init_task)
13053 +- }:data.init
13054 +-
13055 +- . = ALIGN(PAGE_SIZE);
13056 +- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
13057 +- *(.data.page_aligned)
13058 +- }
13059 +-
13060 + /* might get freed after init */
13061 + . = ALIGN(PAGE_SIZE);
13062 + __smp_alt_begin = .;
13063 + __smp_locks = .;
13064 + .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
13065 + *(.smp_locks)
13066 +- }
13067 ++ } :data.init
13068 + __smp_locks_end = .;
13069 + . = ALIGN(PAGE_SIZE);
13070 + __smp_alt_end = .;
13071 +@@ -222,12 +233,6 @@ SECTIONS
13072 + . = ALIGN(PAGE_SIZE);
13073 + __init_end = .;
13074 +
13075 +- . = ALIGN(PAGE_SIZE);
13076 +- __nosave_begin = .;
13077 +- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
13078 +- . = ALIGN(PAGE_SIZE);
13079 +- __nosave_end = .;
13080 +-
13081 + __bss_start = .; /* BSS */
13082 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
13083 + *(.bss.page_aligned)
13084 +@@ -235,6 +240,7 @@ SECTIONS
13085 + }
13086 + __bss_stop = .;
13087 +
13088 ++ . = ALIGN(2*1024*1024);
13089 + _end = . ;
13090 +
13091 + /* Sections to be discarded */
13092 +diff -urNp a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
13093 +--- a/arch/x86/kernel/vsyscall_64.c 2008-08-20 11:16:13.000000000 -0700
13094 ++++ b/arch/x86/kernel/vsyscall_64.c 2008-08-20 18:36:57.000000000 -0700
13095 +@@ -235,13 +235,13 @@ static ctl_table kernel_table2[] = {
13096 + .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
13097 + .mode = 0644,
13098 + .proc_handler = vsyscall_sysctl_change },
13099 +- {}
13100 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
13101 + };
13102 +
13103 + static ctl_table kernel_root_table2[] = {
13104 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
13105 + .child = kernel_table2 },
13106 +- {}
13107 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
13108 + };
13109 + #endif
13110 +
13111 +@@ -251,6 +251,11 @@ static void __cpuinit vsyscall_set_cpu(i
13112 + {
13113 + unsigned long *d;
13114 + unsigned long node = 0;
13115 ++
13116 ++#ifdef CONFIG_PAX_KERNEXEC
13117 ++ unsigned long cr0;
13118 ++#endif
13119 ++
13120 + #ifdef CONFIG_NUMA
13121 + node = cpu_to_node(cpu);
13122 + #endif
13123 +@@ -261,10 +266,20 @@ static void __cpuinit vsyscall_set_cpu(i
13124 + in user space in vgetcpu.
13125 + 12 bits for the CPU and 8 bits for the node. */
13126 + d = (unsigned long *)(get_cpu_gdt_table(cpu) + GDT_ENTRY_PER_CPU);
13127 ++
13128 ++#ifdef CONFIG_PAX_KERNEXEC
13129 ++ pax_open_kernel(cr0);
13130 ++#endif
13131 ++
13132 + *d = 0x0f40000000000ULL;
13133 + *d |= cpu;
13134 + *d |= (node & 0xf) << 12;
13135 + *d |= (node >> 4) << 48;
13136 ++
13137 ++#ifdef CONFIG_PAX_KERNEXEC
13138 ++ pax_close_kernel(cr0);
13139 ++#endif
13140 ++
13141 + }
13142 +
13143 + static void __cpuinit cpu_vsyscall_init(void *arg)
13144 +diff -urNp a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
13145 +--- a/arch/x86/kernel/x8664_ksyms_64.c 2008-08-20 11:16:13.000000000 -0700
13146 ++++ b/arch/x86/kernel/x8664_ksyms_64.c 2008-08-20 18:36:57.000000000 -0700
13147 +@@ -54,8 +54,3 @@ EXPORT_SYMBOL(init_level4_pgt);
13148 + EXPORT_SYMBOL(load_gs_index);
13149 +
13150 + EXPORT_SYMBOL(_proxy_pda);
13151 +-
13152 +-#ifdef CONFIG_PARAVIRT
13153 +-/* Virtualized guests may want to use it */
13154 +-EXPORT_SYMBOL_GPL(cpu_gdt_descr);
13155 +-#endif
13156 +diff -urNp a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
13157 +--- a/arch/x86/kvm/svm.c 2008-08-20 11:16:13.000000000 -0700
13158 ++++ b/arch/x86/kvm/svm.c 2008-08-20 18:36:57.000000000 -0700
13159 +@@ -1329,7 +1329,19 @@ static void reload_tss(struct kvm_vcpu *
13160 + int cpu = raw_smp_processor_id();
13161 +
13162 + struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
13163 ++
13164 ++#ifdef CONFIG_PAX_KERNEXEC
13165 ++ unsigned long cr0;
13166 ++
13167 ++ pax_open_kernel(cr0);
13168 ++#endif
13169 ++
13170 + svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
13171 ++
13172 ++#ifdef CONFIG_PAX_KERNEXEC
13173 ++ pax_close_kernel(cr0);
13174 ++#endif
13175 ++
13176 + load_TR_desc();
13177 + }
13178 +
13179 +diff -urNp a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
13180 +--- a/arch/x86/kvm/vmx.c 2008-08-20 11:16:13.000000000 -0700
13181 ++++ b/arch/x86/kvm/vmx.c 2008-08-20 18:36:57.000000000 -0700
13182 +@@ -355,9 +355,23 @@ static void reload_tss(void)
13183 + struct descriptor_table gdt;
13184 + struct segment_descriptor *descs;
13185 +
13186 ++#ifdef CONFIG_PAX_KERNEXEC
13187 ++ unsigned long cr0;
13188 ++#endif
13189 ++
13190 + get_gdt(&gdt);
13191 + descs = (void *)gdt.base;
13192 ++
13193 ++#ifdef CONFIG_PAX_KERNEXEC
13194 ++ pax_open_kernel(cr0);
13195 ++#endif
13196 ++
13197 + descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
13198 ++
13199 ++#ifdef CONFIG_PAX_KERNEXEC
13200 ++ pax_close_kernel(cr0);
13201 ++#endif
13202 ++
13203 + load_TR_desc();
13204 + }
13205 +
13206 +@@ -2464,7 +2478,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
13207 + vcpu->arch.interrupt_window_open =
13208 + (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
13209 +
13210 +- asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
13211 ++ asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
13212 + vmx->launched = 1;
13213 +
13214 + intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
13215 +diff -urNp a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
13216 +--- a/arch/x86/kvm/x86.c 2008-08-20 11:16:13.000000000 -0700
13217 ++++ b/arch/x86/kvm/x86.c 2008-08-20 18:36:57.000000000 -0700
13218 +@@ -52,33 +52,33 @@ static int kvm_dev_ioctl_get_supported_c
13219 + struct kvm_x86_ops *kvm_x86_ops;
13220 +
13221 + struct kvm_stats_debugfs_item debugfs_entries[] = {
13222 +- { "pf_fixed", VCPU_STAT(pf_fixed) },
13223 +- { "pf_guest", VCPU_STAT(pf_guest) },
13224 +- { "tlb_flush", VCPU_STAT(tlb_flush) },
13225 +- { "invlpg", VCPU_STAT(invlpg) },
13226 +- { "exits", VCPU_STAT(exits) },
13227 +- { "io_exits", VCPU_STAT(io_exits) },
13228 +- { "mmio_exits", VCPU_STAT(mmio_exits) },
13229 +- { "signal_exits", VCPU_STAT(signal_exits) },
13230 +- { "irq_window", VCPU_STAT(irq_window_exits) },
13231 +- { "halt_exits", VCPU_STAT(halt_exits) },
13232 +- { "halt_wakeup", VCPU_STAT(halt_wakeup) },
13233 +- { "request_irq", VCPU_STAT(request_irq_exits) },
13234 +- { "irq_exits", VCPU_STAT(irq_exits) },
13235 +- { "host_state_reload", VCPU_STAT(host_state_reload) },
13236 +- { "efer_reload", VCPU_STAT(efer_reload) },
13237 +- { "fpu_reload", VCPU_STAT(fpu_reload) },
13238 +- { "insn_emulation", VCPU_STAT(insn_emulation) },
13239 +- { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
13240 +- { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
13241 +- { "mmu_pte_write", VM_STAT(mmu_pte_write) },
13242 +- { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
13243 +- { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
13244 +- { "mmu_flooded", VM_STAT(mmu_flooded) },
13245 +- { "mmu_recycled", VM_STAT(mmu_recycled) },
13246 +- { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
13247 +- { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
13248 +- { NULL }
13249 ++ { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
13250 ++ { "pf_guest", VCPU_STAT(pf_guest), NULL },
13251 ++ { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
13252 ++ { "invlpg", VCPU_STAT(invlpg), NULL },
13253 ++ { "exits", VCPU_STAT(exits), NULL },
13254 ++ { "io_exits", VCPU_STAT(io_exits), NULL },
13255 ++ { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
13256 ++ { "signal_exits", VCPU_STAT(signal_exits), NULL },
13257 ++ { "irq_window", VCPU_STAT(irq_window_exits), NULL },
13258 ++ { "halt_exits", VCPU_STAT(halt_exits), NULL },
13259 ++ { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
13260 ++ { "request_irq", VCPU_STAT(request_irq_exits), NULL },
13261 ++ { "irq_exits", VCPU_STAT(irq_exits), NULL },
13262 ++ { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
13263 ++ { "efer_reload", VCPU_STAT(efer_reload), NULL },
13264 ++ { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
13265 ++ { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
13266 ++ { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
13267 ++ { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
13268 ++ { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
13269 ++ { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
13270 ++ { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
13271 ++ { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
13272 ++ { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
13273 ++ { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
13274 ++ { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
13275 ++ { NULL, 0, KVM_STAT_VM, NULL }
13276 + };
13277 +
13278 +
13279 +@@ -1065,7 +1065,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
13280 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
13281 + struct kvm_interrupt *irq)
13282 + {
13283 +- if (irq->irq < 0 || irq->irq >= 256)
13284 ++ if (irq->irq >= 256)
13285 + return -EINVAL;
13286 + if (irqchip_in_kernel(vcpu->kvm))
13287 + return -ENXIO;
13288 +diff -urNp a/arch/x86/lib/checksum_32.S b/arch/x86/lib/checksum_32.S
13289 +--- a/arch/x86/lib/checksum_32.S 2008-08-20 11:16:13.000000000 -0700
13290 ++++ b/arch/x86/lib/checksum_32.S 2008-08-20 18:36:57.000000000 -0700
13291 +@@ -28,7 +28,8 @@
13292 + #include <linux/linkage.h>
13293 + #include <asm/dwarf2.h>
13294 + #include <asm/errno.h>
13295 +-
13296 ++#include <asm/segment.h>
13297 ++
13298 + /*
13299 + * computes a partial checksum, e.g. for TCP/UDP fragments
13300 + */
13301 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
13302 +
13303 + #define ARGBASE 16
13304 + #define FP 12
13305 +-
13306 +-ENTRY(csum_partial_copy_generic)
13307 ++
13308 ++ENTRY(csum_partial_copy_generic_to_user)
13309 + CFI_STARTPROC
13310 ++ pushl $(__USER_DS)
13311 ++ CFI_ADJUST_CFA_OFFSET 4
13312 ++ popl %es
13313 ++ CFI_ADJUST_CFA_OFFSET -4
13314 ++ jmp csum_partial_copy_generic
13315 ++
13316 ++ENTRY(csum_partial_copy_generic_from_user)
13317 ++ pushl $(__USER_DS)
13318 ++ CFI_ADJUST_CFA_OFFSET 4
13319 ++ popl %ds
13320 ++ CFI_ADJUST_CFA_OFFSET -4
13321 ++
13322 ++ENTRY(csum_partial_copy_generic)
13323 + subl $4,%esp
13324 + CFI_ADJUST_CFA_OFFSET 4
13325 + pushl %edi
13326 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
13327 + jmp 4f
13328 + SRC(1: movw (%esi), %bx )
13329 + addl $2, %esi
13330 +-DST( movw %bx, (%edi) )
13331 ++DST( movw %bx, %es:(%edi) )
13332 + addl $2, %edi
13333 + addw %bx, %ax
13334 + adcl $0, %eax
13335 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
13336 + SRC(1: movl (%esi), %ebx )
13337 + SRC( movl 4(%esi), %edx )
13338 + adcl %ebx, %eax
13339 +-DST( movl %ebx, (%edi) )
13340 ++DST( movl %ebx, %es:(%edi) )
13341 + adcl %edx, %eax
13342 +-DST( movl %edx, 4(%edi) )
13343 ++DST( movl %edx, %es:4(%edi) )
13344 +
13345 + SRC( movl 8(%esi), %ebx )
13346 + SRC( movl 12(%esi), %edx )
13347 + adcl %ebx, %eax
13348 +-DST( movl %ebx, 8(%edi) )
13349 ++DST( movl %ebx, %es:8(%edi) )
13350 + adcl %edx, %eax
13351 +-DST( movl %edx, 12(%edi) )
13352 ++DST( movl %edx, %es:12(%edi) )
13353 +
13354 + SRC( movl 16(%esi), %ebx )
13355 + SRC( movl 20(%esi), %edx )
13356 + adcl %ebx, %eax
13357 +-DST( movl %ebx, 16(%edi) )
13358 ++DST( movl %ebx, %es:16(%edi) )
13359 + adcl %edx, %eax
13360 +-DST( movl %edx, 20(%edi) )
13361 ++DST( movl %edx, %es:20(%edi) )
13362 +
13363 + SRC( movl 24(%esi), %ebx )
13364 + SRC( movl 28(%esi), %edx )
13365 + adcl %ebx, %eax
13366 +-DST( movl %ebx, 24(%edi) )
13367 ++DST( movl %ebx, %es:24(%edi) )
13368 + adcl %edx, %eax
13369 +-DST( movl %edx, 28(%edi) )
13370 ++DST( movl %edx, %es:28(%edi) )
13371 +
13372 + lea 32(%esi), %esi
13373 + lea 32(%edi), %edi
13374 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
13375 + shrl $2, %edx # This clears CF
13376 + SRC(3: movl (%esi), %ebx )
13377 + adcl %ebx, %eax
13378 +-DST( movl %ebx, (%edi) )
13379 ++DST( movl %ebx, %es:(%edi) )
13380 + lea 4(%esi), %esi
13381 + lea 4(%edi), %edi
13382 + dec %edx
13383 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
13384 + jb 5f
13385 + SRC( movw (%esi), %cx )
13386 + leal 2(%esi), %esi
13387 +-DST( movw %cx, (%edi) )
13388 ++DST( movw %cx, %es:(%edi) )
13389 + leal 2(%edi), %edi
13390 + je 6f
13391 + shll $16,%ecx
13392 + SRC(5: movb (%esi), %cl )
13393 +-DST( movb %cl, (%edi) )
13394 ++DST( movb %cl, %es:(%edi) )
13395 + 6: addl %ecx, %eax
13396 + adcl $0, %eax
13397 + 7:
13398 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
13399 +
13400 + 6001:
13401 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
13402 +- movl $-EFAULT, (%ebx)
13403 ++ movl $-EFAULT, %ss:(%ebx)
13404 +
13405 + # zero the complete destination - computing the rest
13406 + # is too much work
13407 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
13408 +
13409 + 6002:
13410 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
13411 +- movl $-EFAULT,(%ebx)
13412 ++ movl $-EFAULT,%ss:(%ebx)
13413 + jmp 5000b
13414 +
13415 + .previous
13416 +
13417 ++ pushl %ss
13418 ++ CFI_ADJUST_CFA_OFFSET 4
13419 ++ popl %ds
13420 ++ CFI_ADJUST_CFA_OFFSET -4
13421 ++ pushl %ss
13422 ++ CFI_ADJUST_CFA_OFFSET 4
13423 ++ popl %es
13424 ++ CFI_ADJUST_CFA_OFFSET -4
13425 + popl %ebx
13426 + CFI_ADJUST_CFA_OFFSET -4
13427 + CFI_RESTORE ebx
13428 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
13429 + CFI_ADJUST_CFA_OFFSET -4
13430 + ret
13431 + CFI_ENDPROC
13432 +-ENDPROC(csum_partial_copy_generic)
13433 ++ENDPROC(csum_partial_copy_generic_to_user)
13434 +
13435 + #else
13436 +
13437 + /* Version for PentiumII/PPro */
13438 +
13439 + #define ROUND1(x) \
13440 ++ nop; nop; nop; \
13441 + SRC(movl x(%esi), %ebx ) ; \
13442 + addl %ebx, %eax ; \
13443 +- DST(movl %ebx, x(%edi) ) ;
13444 ++ DST(movl %ebx, %es:x(%edi)) ;
13445 +
13446 + #define ROUND(x) \
13447 ++ nop; nop; nop; \
13448 + SRC(movl x(%esi), %ebx ) ; \
13449 + adcl %ebx, %eax ; \
13450 +- DST(movl %ebx, x(%edi) ) ;
13451 ++ DST(movl %ebx, %es:x(%edi)) ;
13452 +
13453 + #define ARGBASE 12
13454 +-
13455 +-ENTRY(csum_partial_copy_generic)
13456 ++
13457 ++ENTRY(csum_partial_copy_generic_to_user)
13458 + CFI_STARTPROC
13459 ++ pushl $(__USER_DS)
13460 ++ CFI_ADJUST_CFA_OFFSET 4
13461 ++ popl %es
13462 ++ CFI_ADJUST_CFA_OFFSET -4
13463 ++ jmp csum_partial_copy_generic
13464 ++
13465 ++ENTRY(csum_partial_copy_generic_from_user)
13466 ++ pushl $(__USER_DS)
13467 ++ CFI_ADJUST_CFA_OFFSET 4
13468 ++ popl %ds
13469 ++ CFI_ADJUST_CFA_OFFSET -4
13470 ++
13471 ++ENTRY(csum_partial_copy_generic)
13472 + pushl %ebx
13473 + CFI_ADJUST_CFA_OFFSET 4
13474 + CFI_REL_OFFSET ebx, 0
13475 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
13476 + subl %ebx, %edi
13477 + lea -1(%esi),%edx
13478 + andl $-32,%edx
13479 +- lea 3f(%ebx,%ebx), %ebx
13480 ++ lea 3f(%ebx,%ebx,2), %ebx
13481 + testl %esi, %esi
13482 + jmp *%ebx
13483 + 1: addl $64,%esi
13484 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
13485 + jb 5f
13486 + SRC( movw (%esi), %dx )
13487 + leal 2(%esi), %esi
13488 +-DST( movw %dx, (%edi) )
13489 ++DST( movw %dx, %es:(%edi) )
13490 + leal 2(%edi), %edi
13491 + je 6f
13492 + shll $16,%edx
13493 + 5:
13494 + SRC( movb (%esi), %dl )
13495 +-DST( movb %dl, (%edi) )
13496 ++DST( movb %dl, %es:(%edi) )
13497 + 6: addl %edx, %eax
13498 + adcl $0, %eax
13499 + 7:
13500 + .section .fixup, "ax"
13501 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
13502 +- movl $-EFAULT, (%ebx)
13503 ++ movl $-EFAULT, %ss:(%ebx)
13504 + # zero the complete destination (computing the rest is too much work)
13505 + movl ARGBASE+8(%esp),%edi # dst
13506 + movl ARGBASE+12(%esp),%ecx # len
13507 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
13508 + rep; stosb
13509 + jmp 7b
13510 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
13511 +- movl $-EFAULT, (%ebx)
13512 ++ movl $-EFAULT, %ss:(%ebx)
13513 + jmp 7b
13514 + .previous
13515 +
13516 ++ pushl %ss
13517 ++ CFI_ADJUST_CFA_OFFSET 4
13518 ++ popl %ds
13519 ++ CFI_ADJUST_CFA_OFFSET -4
13520 ++ pushl %ss
13521 ++ CFI_ADJUST_CFA_OFFSET 4
13522 ++ popl %es
13523 ++ CFI_ADJUST_CFA_OFFSET -4
13524 + popl %esi
13525 + CFI_ADJUST_CFA_OFFSET -4
13526 + CFI_RESTORE esi
13527 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
13528 + CFI_RESTORE ebx
13529 + ret
13530 + CFI_ENDPROC
13531 +-ENDPROC(csum_partial_copy_generic)
13532 ++ENDPROC(csum_partial_copy_generic_to_user)
13533 +
13534 + #undef ROUND
13535 + #undef ROUND1
13536 +diff -urNp a/arch/x86/lib/clear_page_64.S b/arch/x86/lib/clear_page_64.S
13537 +--- a/arch/x86/lib/clear_page_64.S 2008-08-20 11:16:13.000000000 -0700
13538 ++++ b/arch/x86/lib/clear_page_64.S 2008-08-20 18:36:57.000000000 -0700
13539 +@@ -44,7 +44,7 @@ ENDPROC(clear_page)
13540 +
13541 + #include <asm/cpufeature.h>
13542 +
13543 +- .section .altinstr_replacement,"ax"
13544 ++ .section .altinstr_replacement,"a"
13545 + 1: .byte 0xeb /* jmp <disp8> */
13546 + .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */
13547 + 2:
13548 +diff -urNp a/arch/x86/lib/copy_page_64.S b/arch/x86/lib/copy_page_64.S
13549 +--- a/arch/x86/lib/copy_page_64.S 2008-08-20 11:16:13.000000000 -0700
13550 ++++ b/arch/x86/lib/copy_page_64.S 2008-08-20 18:36:57.000000000 -0700
13551 +@@ -104,7 +104,7 @@ ENDPROC(copy_page)
13552 +
13553 + #include <asm/cpufeature.h>
13554 +
13555 +- .section .altinstr_replacement,"ax"
13556 ++ .section .altinstr_replacement,"a"
13557 + 1: .byte 0xeb /* jmp <disp8> */
13558 + .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */
13559 + 2:
13560 +diff -urNp a/arch/x86/lib/copy_user_64.S b/arch/x86/lib/copy_user_64.S
13561 +--- a/arch/x86/lib/copy_user_64.S 2008-08-20 11:16:13.000000000 -0700
13562 ++++ b/arch/x86/lib/copy_user_64.S 2008-08-20 18:36:57.000000000 -0700
13563 +@@ -19,7 +19,7 @@
13564 + .byte 0xe9 /* 32bit jump */
13565 + .long \orig-1f /* by default jump to orig */
13566 + 1:
13567 +- .section .altinstr_replacement,"ax"
13568 ++ .section .altinstr_replacement,"a"
13569 + 2: .byte 0xe9 /* near jump with 32bit immediate */
13570 + .long \alt-1b /* offset */ /* or alternatively to alt */
13571 + .previous
13572 +@@ -76,6 +76,8 @@ ENDPROC(copy_from_user)
13573 + /* must zero dest */
13574 + bad_from_user:
13575 + CFI_STARTPROC
13576 ++ testl %edx,%edx
13577 ++ js bad_to_user
13578 + movl %edx,%ecx
13579 + xorl %eax,%eax
13580 + rep
13581 +diff -urNp a/arch/x86/lib/getuser_32.S b/arch/x86/lib/getuser_32.S
13582 +--- a/arch/x86/lib/getuser_32.S 2008-08-20 11:16:13.000000000 -0700
13583 ++++ b/arch/x86/lib/getuser_32.S 2008-08-20 18:36:57.000000000 -0700
13584 +@@ -11,7 +11,7 @@
13585 + #include <linux/linkage.h>
13586 + #include <asm/dwarf2.h>
13587 + #include <asm/thread_info.h>
13588 +-
13589 ++#include <asm/segment.h>
13590 +
13591 + /*
13592 + * __get_user_X
13593 +@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
13594 + GET_THREAD_INFO(%edx)
13595 + cmpl TI_addr_limit(%edx),%eax
13596 + jae bad_get_user
13597 ++ pushl $(__USER_DS)
13598 ++ popl %ds
13599 + 1: movzbl (%eax),%edx
13600 ++ pushl %ss
13601 ++ pop %ds
13602 + xorl %eax,%eax
13603 + ret
13604 + CFI_ENDPROC
13605 +@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
13606 + GET_THREAD_INFO(%edx)
13607 + cmpl TI_addr_limit(%edx),%eax
13608 + jae bad_get_user
13609 ++ pushl $(__USER_DS)
13610 ++ popl %ds
13611 + 2: movzwl -1(%eax),%edx
13612 ++ pushl %ss
13613 ++ pop %ds
13614 + xorl %eax,%eax
13615 + ret
13616 + CFI_ENDPROC
13617 +@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
13618 + GET_THREAD_INFO(%edx)
13619 + cmpl TI_addr_limit(%edx),%eax
13620 + jae bad_get_user
13621 ++ pushl $(__USER_DS)
13622 ++ popl %ds
13623 + 3: movl -3(%eax),%edx
13624 ++ pushl %ss
13625 ++ pop %ds
13626 + xorl %eax,%eax
13627 + ret
13628 + CFI_ENDPROC
13629 +@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
13630 +
13631 + bad_get_user:
13632 + CFI_STARTPROC
13633 ++ pushl %ss
13634 ++ pop %ds
13635 + xorl %edx,%edx
13636 + movl $-14,%eax
13637 + ret
13638 +diff -urNp a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
13639 +--- a/arch/x86/lib/memcpy_64.S 2008-08-20 11:16:13.000000000 -0700
13640 ++++ b/arch/x86/lib/memcpy_64.S 2008-08-20 18:36:57.000000000 -0700
13641 +@@ -114,7 +114,7 @@ ENDPROC(__memcpy)
13642 + /* Some CPUs run faster using the string copy instructions.
13643 + It is also a lot simpler. Use this when possible */
13644 +
13645 +- .section .altinstr_replacement,"ax"
13646 ++ .section .altinstr_replacement,"a"
13647 + 1: .byte 0xeb /* jmp <disp8> */
13648 + .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */
13649 + 2:
13650 +diff -urNp a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
13651 +--- a/arch/x86/lib/memset_64.S 2008-08-20 11:16:13.000000000 -0700
13652 ++++ b/arch/x86/lib/memset_64.S 2008-08-20 18:36:57.000000000 -0700
13653 +@@ -118,7 +118,7 @@ ENDPROC(__memset)
13654 +
13655 + #include <asm/cpufeature.h>
13656 +
13657 +- .section .altinstr_replacement,"ax"
13658 ++ .section .altinstr_replacement,"a"
13659 + 1: .byte 0xeb /* jmp <disp8> */
13660 + .byte (memset_c - memset) - (2f - 1b) /* offset */
13661 + 2:
13662 +diff -urNp a/arch/x86/lib/mmx_32.c b/arch/x86/lib/mmx_32.c
13663 +--- a/arch/x86/lib/mmx_32.c 2008-08-20 11:16:13.000000000 -0700
13664 ++++ b/arch/x86/lib/mmx_32.c 2008-08-20 18:36:57.000000000 -0700
13665 +@@ -31,6 +31,7 @@ void *_mmx_memcpy(void *to, const void *
13666 + {
13667 + void *p;
13668 + int i;
13669 ++ unsigned long cr0;
13670 +
13671 + if (unlikely(in_interrupt()))
13672 + return __memcpy(to, from, len);
13673 +@@ -41,46 +42,74 @@ void *_mmx_memcpy(void *to, const void *
13674 + kernel_fpu_begin();
13675 +
13676 + __asm__ __volatile__ (
13677 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
13678 +- " prefetch 64(%0)\n"
13679 +- " prefetch 128(%0)\n"
13680 +- " prefetch 192(%0)\n"
13681 +- " prefetch 256(%0)\n"
13682 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
13683 ++ " prefetch 64(%1)\n"
13684 ++ " prefetch 128(%1)\n"
13685 ++ " prefetch 192(%1)\n"
13686 ++ " prefetch 256(%1)\n"
13687 + "2: \n"
13688 + ".section .fixup, \"ax\"\n"
13689 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13690 ++ "3: \n"
13691 ++
13692 ++#ifdef CONFIG_PAX_KERNEXEC
13693 ++ " movl %%cr0, %0\n"
13694 ++ " movl %0, %%eax\n"
13695 ++ " andl $0xFFFEFFFF, %%eax\n"
13696 ++ " movl %%eax, %%cr0\n"
13697 ++#endif
13698 ++
13699 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13700 ++
13701 ++#ifdef CONFIG_PAX_KERNEXEC
13702 ++ " movl %0, %%cr0\n"
13703 ++#endif
13704 ++
13705 + " jmp 2b\n"
13706 + ".previous\n"
13707 + _ASM_EXTABLE(1b,3b)
13708 +- : : "r" (from) );
13709 ++ : "=&r" (cr0) : "r" (from) : "ax");
13710 +
13711 +
13712 + for(; i>5; i--)
13713 + {
13714 + __asm__ __volatile__ (
13715 +- "1: prefetch 320(%0)\n"
13716 +- "2: movq (%0), %%mm0\n"
13717 +- " movq 8(%0), %%mm1\n"
13718 +- " movq 16(%0), %%mm2\n"
13719 +- " movq 24(%0), %%mm3\n"
13720 +- " movq %%mm0, (%1)\n"
13721 +- " movq %%mm1, 8(%1)\n"
13722 +- " movq %%mm2, 16(%1)\n"
13723 +- " movq %%mm3, 24(%1)\n"
13724 +- " movq 32(%0), %%mm0\n"
13725 +- " movq 40(%0), %%mm1\n"
13726 +- " movq 48(%0), %%mm2\n"
13727 +- " movq 56(%0), %%mm3\n"
13728 +- " movq %%mm0, 32(%1)\n"
13729 +- " movq %%mm1, 40(%1)\n"
13730 +- " movq %%mm2, 48(%1)\n"
13731 +- " movq %%mm3, 56(%1)\n"
13732 ++ "1: prefetch 320(%1)\n"
13733 ++ "2: movq (%1), %%mm0\n"
13734 ++ " movq 8(%1), %%mm1\n"
13735 ++ " movq 16(%1), %%mm2\n"
13736 ++ " movq 24(%1), %%mm3\n"
13737 ++ " movq %%mm0, (%2)\n"
13738 ++ " movq %%mm1, 8(%2)\n"
13739 ++ " movq %%mm2, 16(%2)\n"
13740 ++ " movq %%mm3, 24(%2)\n"
13741 ++ " movq 32(%1), %%mm0\n"
13742 ++ " movq 40(%1), %%mm1\n"
13743 ++ " movq 48(%1), %%mm2\n"
13744 ++ " movq 56(%1), %%mm3\n"
13745 ++ " movq %%mm0, 32(%2)\n"
13746 ++ " movq %%mm1, 40(%2)\n"
13747 ++ " movq %%mm2, 48(%2)\n"
13748 ++ " movq %%mm3, 56(%2)\n"
13749 + ".section .fixup, \"ax\"\n"
13750 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13751 ++ "3:\n"
13752 ++
13753 ++#ifdef CONFIG_PAX_KERNEXEC
13754 ++ " movl %%cr0, %0\n"
13755 ++ " movl %0, %%eax\n"
13756 ++ " andl $0xFFFEFFFF, %%eax\n"
13757 ++ " movl %%eax, %%cr0\n"
13758 ++#endif
13759 ++
13760 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13761 ++
13762 ++#ifdef CONFIG_PAX_KERNEXEC
13763 ++ " movl %0, %%cr0\n"
13764 ++#endif
13765 ++
13766 + " jmp 2b\n"
13767 + ".previous\n"
13768 + _ASM_EXTABLE(1b,3b)
13769 +- : : "r" (from), "r" (to) : "memory");
13770 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13771 + from+=64;
13772 + to+=64;
13773 + }
13774 +@@ -159,6 +188,7 @@ static void fast_clear_page(void *page)
13775 + static void fast_copy_page(void *to, void *from)
13776 + {
13777 + int i;
13778 ++ unsigned long cr0;
13779 +
13780 + kernel_fpu_begin();
13781 +
13782 +@@ -166,45 +196,73 @@ static void fast_copy_page(void *to, voi
13783 + * but that is for later. -AV
13784 + */
13785 + __asm__ __volatile__ (
13786 +- "1: prefetch (%0)\n"
13787 +- " prefetch 64(%0)\n"
13788 +- " prefetch 128(%0)\n"
13789 +- " prefetch 192(%0)\n"
13790 +- " prefetch 256(%0)\n"
13791 ++ "1: prefetch (%1)\n"
13792 ++ " prefetch 64(%1)\n"
13793 ++ " prefetch 128(%1)\n"
13794 ++ " prefetch 192(%1)\n"
13795 ++ " prefetch 256(%1)\n"
13796 + "2: \n"
13797 + ".section .fixup, \"ax\"\n"
13798 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13799 ++ "3: \n"
13800 ++
13801 ++#ifdef CONFIG_PAX_KERNEXEC
13802 ++ " movl %%cr0, %0\n"
13803 ++ " movl %0, %%eax\n"
13804 ++ " andl $0xFFFEFFFF, %%eax\n"
13805 ++ " movl %%eax, %%cr0\n"
13806 ++#endif
13807 ++
13808 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13809 ++
13810 ++#ifdef CONFIG_PAX_KERNEXEC
13811 ++ " movl %0, %%cr0\n"
13812 ++#endif
13813 ++
13814 + " jmp 2b\n"
13815 + ".previous\n"
13816 + _ASM_EXTABLE(1b,3b)
13817 +- : : "r" (from) );
13818 ++ : "=&r" (cr0) : "r" (from) : "ax");
13819 +
13820 + for(i=0; i<(4096-320)/64; i++)
13821 + {
13822 + __asm__ __volatile__ (
13823 +- "1: prefetch 320(%0)\n"
13824 +- "2: movq (%0), %%mm0\n"
13825 +- " movntq %%mm0, (%1)\n"
13826 +- " movq 8(%0), %%mm1\n"
13827 +- " movntq %%mm1, 8(%1)\n"
13828 +- " movq 16(%0), %%mm2\n"
13829 +- " movntq %%mm2, 16(%1)\n"
13830 +- " movq 24(%0), %%mm3\n"
13831 +- " movntq %%mm3, 24(%1)\n"
13832 +- " movq 32(%0), %%mm4\n"
13833 +- " movntq %%mm4, 32(%1)\n"
13834 +- " movq 40(%0), %%mm5\n"
13835 +- " movntq %%mm5, 40(%1)\n"
13836 +- " movq 48(%0), %%mm6\n"
13837 +- " movntq %%mm6, 48(%1)\n"
13838 +- " movq 56(%0), %%mm7\n"
13839 +- " movntq %%mm7, 56(%1)\n"
13840 ++ "1: prefetch 320(%1)\n"
13841 ++ "2: movq (%1), %%mm0\n"
13842 ++ " movntq %%mm0, (%2)\n"
13843 ++ " movq 8(%1), %%mm1\n"
13844 ++ " movntq %%mm1, 8(%2)\n"
13845 ++ " movq 16(%1), %%mm2\n"
13846 ++ " movntq %%mm2, 16(%2)\n"
13847 ++ " movq 24(%1), %%mm3\n"
13848 ++ " movntq %%mm3, 24(%2)\n"
13849 ++ " movq 32(%1), %%mm4\n"
13850 ++ " movntq %%mm4, 32(%2)\n"
13851 ++ " movq 40(%1), %%mm5\n"
13852 ++ " movntq %%mm5, 40(%2)\n"
13853 ++ " movq 48(%1), %%mm6\n"
13854 ++ " movntq %%mm6, 48(%2)\n"
13855 ++ " movq 56(%1), %%mm7\n"
13856 ++ " movntq %%mm7, 56(%2)\n"
13857 + ".section .fixup, \"ax\"\n"
13858 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13859 ++ "3:\n"
13860 ++
13861 ++#ifdef CONFIG_PAX_KERNEXEC
13862 ++ " movl %%cr0, %0\n"
13863 ++ " movl %0, %%eax\n"
13864 ++ " andl $0xFFFEFFFF, %%eax\n"
13865 ++ " movl %%eax, %%cr0\n"
13866 ++#endif
13867 ++
13868 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13869 ++
13870 ++#ifdef CONFIG_PAX_KERNEXEC
13871 ++ " movl %0, %%cr0\n"
13872 ++#endif
13873 ++
13874 + " jmp 2b\n"
13875 + ".previous\n"
13876 + _ASM_EXTABLE(1b,3b)
13877 +- : : "r" (from), "r" (to) : "memory");
13878 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13879 + from+=64;
13880 + to+=64;
13881 + }
13882 +@@ -285,50 +343,78 @@ static void fast_clear_page(void *page)
13883 + static void fast_copy_page(void *to, void *from)
13884 + {
13885 + int i;
13886 +-
13887 +-
13888 ++ unsigned long cr0;
13889 ++
13890 + kernel_fpu_begin();
13891 +
13892 + __asm__ __volatile__ (
13893 +- "1: prefetch (%0)\n"
13894 +- " prefetch 64(%0)\n"
13895 +- " prefetch 128(%0)\n"
13896 +- " prefetch 192(%0)\n"
13897 +- " prefetch 256(%0)\n"
13898 ++ "1: prefetch (%1)\n"
13899 ++ " prefetch 64(%1)\n"
13900 ++ " prefetch 128(%1)\n"
13901 ++ " prefetch 192(%1)\n"
13902 ++ " prefetch 256(%1)\n"
13903 + "2: \n"
13904 + ".section .fixup, \"ax\"\n"
13905 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13906 ++ "3: \n"
13907 ++
13908 ++#ifdef CONFIG_PAX_KERNEXEC
13909 ++ " movl %%cr0, %0\n"
13910 ++ " movl %0, %%eax\n"
13911 ++ " andl $0xFFFEFFFF, %%eax\n"
13912 ++ " movl %%eax, %%cr0\n"
13913 ++#endif
13914 ++
13915 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
13916 ++
13917 ++#ifdef CONFIG_PAX_KERNEXEC
13918 ++ " movl %0, %%cr0\n"
13919 ++#endif
13920 ++
13921 + " jmp 2b\n"
13922 + ".previous\n"
13923 + _ASM_EXTABLE(1b,3b)
13924 +- : : "r" (from) );
13925 ++ : "=&r" (cr0) : "r" (from) : "ax");
13926 +
13927 + for(i=0; i<4096/64; i++)
13928 + {
13929 + __asm__ __volatile__ (
13930 +- "1: prefetch 320(%0)\n"
13931 +- "2: movq (%0), %%mm0\n"
13932 +- " movq 8(%0), %%mm1\n"
13933 +- " movq 16(%0), %%mm2\n"
13934 +- " movq 24(%0), %%mm3\n"
13935 +- " movq %%mm0, (%1)\n"
13936 +- " movq %%mm1, 8(%1)\n"
13937 +- " movq %%mm2, 16(%1)\n"
13938 +- " movq %%mm3, 24(%1)\n"
13939 +- " movq 32(%0), %%mm0\n"
13940 +- " movq 40(%0), %%mm1\n"
13941 +- " movq 48(%0), %%mm2\n"
13942 +- " movq 56(%0), %%mm3\n"
13943 +- " movq %%mm0, 32(%1)\n"
13944 +- " movq %%mm1, 40(%1)\n"
13945 +- " movq %%mm2, 48(%1)\n"
13946 +- " movq %%mm3, 56(%1)\n"
13947 ++ "1: prefetch 320(%1)\n"
13948 ++ "2: movq (%1), %%mm0\n"
13949 ++ " movq 8(%1), %%mm1\n"
13950 ++ " movq 16(%1), %%mm2\n"
13951 ++ " movq 24(%1), %%mm3\n"
13952 ++ " movq %%mm0, (%2)\n"
13953 ++ " movq %%mm1, 8(%2)\n"
13954 ++ " movq %%mm2, 16(%2)\n"
13955 ++ " movq %%mm3, 24(%2)\n"
13956 ++ " movq 32(%1), %%mm0\n"
13957 ++ " movq 40(%1), %%mm1\n"
13958 ++ " movq 48(%1), %%mm2\n"
13959 ++ " movq 56(%1), %%mm3\n"
13960 ++ " movq %%mm0, 32(%2)\n"
13961 ++ " movq %%mm1, 40(%2)\n"
13962 ++ " movq %%mm2, 48(%2)\n"
13963 ++ " movq %%mm3, 56(%2)\n"
13964 + ".section .fixup, \"ax\"\n"
13965 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13966 ++ "3:\n"
13967 ++
13968 ++#ifdef CONFIG_PAX_KERNEXEC
13969 ++ " movl %%cr0, %0\n"
13970 ++ " movl %0, %%eax\n"
13971 ++ " andl $0xFFFEFFFF, %%eax\n"
13972 ++ " movl %%eax, %%cr0\n"
13973 ++#endif
13974 ++
13975 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
13976 ++
13977 ++#ifdef CONFIG_PAX_KERNEXEC
13978 ++ " movl %0, %%cr0\n"
13979 ++#endif
13980 ++
13981 + " jmp 2b\n"
13982 + ".previous\n"
13983 + _ASM_EXTABLE(1b,3b)
13984 +- : : "r" (from), "r" (to) : "memory");
13985 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
13986 + from+=64;
13987 + to+=64;
13988 + }
13989 +diff -urNp a/arch/x86/lib/putuser_32.S b/arch/x86/lib/putuser_32.S
13990 +--- a/arch/x86/lib/putuser_32.S 2008-08-20 11:16:13.000000000 -0700
13991 ++++ b/arch/x86/lib/putuser_32.S 2008-08-20 18:36:57.000000000 -0700
13992 +@@ -11,7 +11,7 @@
13993 + #include <linux/linkage.h>
13994 + #include <asm/dwarf2.h>
13995 + #include <asm/thread_info.h>
13996 +-
13997 ++#include <asm/segment.h>
13998 +
13999 + /*
14000 + * __put_user_X
14001 +@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
14002 + ENTER
14003 + cmpl TI_addr_limit(%ebx),%ecx
14004 + jae bad_put_user
14005 ++ pushl $(__USER_DS)
14006 ++ popl %ds
14007 + 1: movb %al,(%ecx)
14008 ++ pushl %ss
14009 ++ popl %ds
14010 + xorl %eax,%eax
14011 + EXIT
14012 + ENDPROC(__put_user_1)
14013 +@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
14014 + subl $1,%ebx
14015 + cmpl %ebx,%ecx
14016 + jae bad_put_user
14017 ++ pushl $(__USER_DS)
14018 ++ popl %ds
14019 + 2: movw %ax,(%ecx)
14020 ++ pushl %ss
14021 ++ popl %ds
14022 + xorl %eax,%eax
14023 + EXIT
14024 + ENDPROC(__put_user_2)
14025 +@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
14026 + subl $3,%ebx
14027 + cmpl %ebx,%ecx
14028 + jae bad_put_user
14029 ++ pushl $(__USER_DS)
14030 ++ popl %ds
14031 + 3: movl %eax,(%ecx)
14032 ++ pushl %ss
14033 ++ popl %ds
14034 + xorl %eax,%eax
14035 + EXIT
14036 + ENDPROC(__put_user_4)
14037 +@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
14038 + subl $7,%ebx
14039 + cmpl %ebx,%ecx
14040 + jae bad_put_user
14041 ++ pushl $(__USER_DS)
14042 ++ popl %ds
14043 + 4: movl %eax,(%ecx)
14044 + 5: movl %edx,4(%ecx)
14045 ++ pushl %ss
14046 ++ popl %ds
14047 + xorl %eax,%eax
14048 + EXIT
14049 + ENDPROC(__put_user_8)
14050 +@@ -85,6 +101,10 @@ bad_put_user:
14051 + CFI_DEF_CFA esp, 2*4
14052 + CFI_OFFSET eip, -1*4
14053 + CFI_OFFSET ebx, -2*4
14054 ++ pushl %ss
14055 ++ CFI_ADJUST_CFA_OFFSET 4
14056 ++ popl %ds
14057 ++ CFI_ADJUST_CFA_OFFSET -4
14058 + movl $-14,%eax
14059 + EXIT
14060 + END(bad_put_user)
14061 +diff -urNp a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
14062 +--- a/arch/x86/lib/usercopy_32.c 2008-08-20 11:16:13.000000000 -0700
14063 ++++ b/arch/x86/lib/usercopy_32.c 2008-08-20 18:36:57.000000000 -0700
14064 +@@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
14065 + * Copy a null terminated string from userspace.
14066 + */
14067 +
14068 +-#define __do_strncpy_from_user(dst,src,count,res) \
14069 +-do { \
14070 +- int __d0, __d1, __d2; \
14071 +- might_sleep(); \
14072 +- __asm__ __volatile__( \
14073 +- " testl %1,%1\n" \
14074 +- " jz 2f\n" \
14075 +- "0: lodsb\n" \
14076 +- " stosb\n" \
14077 +- " testb %%al,%%al\n" \
14078 +- " jz 1f\n" \
14079 +- " decl %1\n" \
14080 +- " jnz 0b\n" \
14081 +- "1: subl %1,%0\n" \
14082 +- "2:\n" \
14083 +- ".section .fixup,\"ax\"\n" \
14084 +- "3: movl %5,%0\n" \
14085 +- " jmp 2b\n" \
14086 +- ".previous\n" \
14087 +- _ASM_EXTABLE(0b,3b) \
14088 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
14089 +- "=&D" (__d2) \
14090 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
14091 +- : "memory"); \
14092 +-} while (0)
14093 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
14094 ++{
14095 ++ int __d0, __d1, __d2;
14096 ++ long res = -EFAULT;
14097 ++
14098 ++ might_sleep();
14099 ++ __asm__ __volatile__(
14100 ++ " movw %w10,%%ds\n"
14101 ++ " testl %1,%1\n"
14102 ++ " jz 2f\n"
14103 ++ "0: lodsb\n"
14104 ++ " stosb\n"
14105 ++ " testb %%al,%%al\n"
14106 ++ " jz 1f\n"
14107 ++ " decl %1\n"
14108 ++ " jnz 0b\n"
14109 ++ "1: subl %1,%0\n"
14110 ++ "2:\n"
14111 ++ " pushl %%ss\n"
14112 ++ " popl %%ds\n"
14113 ++ ".section .fixup,\"ax\"\n"
14114 ++ "3: movl %5,%0\n"
14115 ++ " jmp 2b\n"
14116 ++ ".previous\n"
14117 ++ _ASM_EXTABLE(0b,3b)
14118 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
14119 ++ "=&D" (__d2)
14120 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
14121 ++ "r"(__USER_DS)
14122 ++ : "memory");
14123 ++ return res;
14124 ++}
14125 +
14126 + /**
14127 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
14128 +@@ -78,9 +85,7 @@ do { \
14129 + long
14130 + __strncpy_from_user(char *dst, const char __user *src, long count)
14131 + {
14132 +- long res;
14133 +- __do_strncpy_from_user(dst, src, count, res);
14134 +- return res;
14135 ++ return __do_strncpy_from_user(dst, src, count);
14136 + }
14137 + EXPORT_SYMBOL(__strncpy_from_user);
14138 +
14139 +@@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char
14140 + {
14141 + long res = -EFAULT;
14142 + if (access_ok(VERIFY_READ, src, 1))
14143 +- __do_strncpy_from_user(dst, src, count, res);
14144 ++ res = __do_strncpy_from_user(dst, src, count);
14145 + return res;
14146 + }
14147 + EXPORT_SYMBOL(strncpy_from_user);
14148 +@@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
14149 + * Zero Userspace
14150 + */
14151 +
14152 +-#define __do_clear_user(addr,size) \
14153 +-do { \
14154 +- int __d0; \
14155 +- might_sleep(); \
14156 +- __asm__ __volatile__( \
14157 +- "0: rep; stosl\n" \
14158 +- " movl %2,%0\n" \
14159 +- "1: rep; stosb\n" \
14160 +- "2:\n" \
14161 +- ".section .fixup,\"ax\"\n" \
14162 +- "3: lea 0(%2,%0,4),%0\n" \
14163 +- " jmp 2b\n" \
14164 +- ".previous\n" \
14165 +- _ASM_EXTABLE(0b,3b) \
14166 +- _ASM_EXTABLE(1b,2b) \
14167 +- : "=&c"(size), "=&D" (__d0) \
14168 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
14169 +-} while (0)
14170 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
14171 ++{
14172 ++ int __d0;
14173 ++
14174 ++ might_sleep();
14175 ++ __asm__ __volatile__(
14176 ++ " movw %w6,%%es\n"
14177 ++ "0: rep; stosl\n"
14178 ++ " movl %2,%0\n"
14179 ++ "1: rep; stosb\n"
14180 ++ "2:\n"
14181 ++ " pushl %%ss\n"
14182 ++ " popl %%es\n"
14183 ++ ".section .fixup,\"ax\"\n"
14184 ++ "3: lea 0(%2,%0,4),%0\n"
14185 ++ " jmp 2b\n"
14186 ++ ".previous\n"
14187 ++ _ASM_EXTABLE(0b,3b)
14188 ++ _ASM_EXTABLE(1b,2b)
14189 ++ : "=&c"(size), "=&D" (__d0)
14190 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
14191 ++ "r"(__USER_DS));
14192 ++ return size;
14193 ++}
14194 +
14195 + /**
14196 + * clear_user: - Zero a block of memory in user space.
14197 +@@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
14198 + {
14199 + might_sleep();
14200 + if (access_ok(VERIFY_WRITE, to, n))
14201 +- __do_clear_user(to, n);
14202 ++ n = __do_clear_user(to, n);
14203 + return n;
14204 + }
14205 + EXPORT_SYMBOL(clear_user);
14206 +@@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
14207 + unsigned long
14208 + __clear_user(void __user *to, unsigned long n)
14209 + {
14210 +- __do_clear_user(to, n);
14211 +- return n;
14212 ++ return __do_clear_user(to, n);
14213 + }
14214 + EXPORT_SYMBOL(__clear_user);
14215 +
14216 +@@ -193,14 +203,17 @@ long strnlen_user(const char __user *s,
14217 + might_sleep();
14218 +
14219 + __asm__ __volatile__(
14220 ++ " movw %w8,%%es\n"
14221 + " testl %0, %0\n"
14222 + " jz 3f\n"
14223 +- " andl %0,%%ecx\n"
14224 ++ " movl %0,%%ecx\n"
14225 + "0: repne; scasb\n"
14226 + " setne %%al\n"
14227 + " subl %%ecx,%0\n"
14228 + " addl %0,%%eax\n"
14229 + "1:\n"
14230 ++ " pushl %%ss\n"
14231 ++ " popl %%es\n"
14232 + ".section .fixup,\"ax\"\n"
14233 + "2: xorl %%eax,%%eax\n"
14234 + " jmp 1b\n"
14235 +@@ -212,7 +225,7 @@ long strnlen_user(const char __user *s,
14236 + " .long 0b,2b\n"
14237 + ".previous"
14238 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
14239 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
14240 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
14241 + :"cc");
14242 + return res & mask;
14243 + }
14244 +@@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
14245 +
14246 + #ifdef CONFIG_X86_INTEL_USERCOPY
14247 + static unsigned long
14248 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
14249 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
14250 + {
14251 + int d0, d1;
14252 + __asm__ __volatile__(
14253 ++ " movw %w6, %%es\n"
14254 + " .align 2,0x90\n"
14255 + "1: movl 32(%4), %%eax\n"
14256 + " cmpl $67, %0\n"
14257 +@@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
14258 + " .align 2,0x90\n"
14259 + "3: movl 0(%4), %%eax\n"
14260 + "4: movl 4(%4), %%edx\n"
14261 +- "5: movl %%eax, 0(%3)\n"
14262 +- "6: movl %%edx, 4(%3)\n"
14263 ++ "5: movl %%eax, %%es:0(%3)\n"
14264 ++ "6: movl %%edx, %%es:4(%3)\n"
14265 + "7: movl 8(%4), %%eax\n"
14266 + "8: movl 12(%4),%%edx\n"
14267 +- "9: movl %%eax, 8(%3)\n"
14268 +- "10: movl %%edx, 12(%3)\n"
14269 ++ "9: movl %%eax, %%es:8(%3)\n"
14270 ++ "10: movl %%edx, %%es:12(%3)\n"
14271 + "11: movl 16(%4), %%eax\n"
14272 + "12: movl 20(%4), %%edx\n"
14273 +- "13: movl %%eax, 16(%3)\n"
14274 +- "14: movl %%edx, 20(%3)\n"
14275 ++ "13: movl %%eax, %%es:16(%3)\n"
14276 ++ "14: movl %%edx, %%es:20(%3)\n"
14277 + "15: movl 24(%4), %%eax\n"
14278 + "16: movl 28(%4), %%edx\n"
14279 +- "17: movl %%eax, 24(%3)\n"
14280 +- "18: movl %%edx, 28(%3)\n"
14281 ++ "17: movl %%eax, %%es:24(%3)\n"
14282 ++ "18: movl %%edx, %%es:28(%3)\n"
14283 + "19: movl 32(%4), %%eax\n"
14284 + "20: movl 36(%4), %%edx\n"
14285 +- "21: movl %%eax, 32(%3)\n"
14286 +- "22: movl %%edx, 36(%3)\n"
14287 ++ "21: movl %%eax, %%es:32(%3)\n"
14288 ++ "22: movl %%edx, %%es:36(%3)\n"
14289 + "23: movl 40(%4), %%eax\n"
14290 + "24: movl 44(%4), %%edx\n"
14291 +- "25: movl %%eax, 40(%3)\n"
14292 +- "26: movl %%edx, 44(%3)\n"
14293 ++ "25: movl %%eax, %%es:40(%3)\n"
14294 ++ "26: movl %%edx, %%es:44(%3)\n"
14295 + "27: movl 48(%4), %%eax\n"
14296 + "28: movl 52(%4), %%edx\n"
14297 +- "29: movl %%eax, 48(%3)\n"
14298 +- "30: movl %%edx, 52(%3)\n"
14299 ++ "29: movl %%eax, %%es:48(%3)\n"
14300 ++ "30: movl %%edx, %%es:52(%3)\n"
14301 + "31: movl 56(%4), %%eax\n"
14302 + "32: movl 60(%4), %%edx\n"
14303 +- "33: movl %%eax, 56(%3)\n"
14304 +- "34: movl %%edx, 60(%3)\n"
14305 ++ "33: movl %%eax, %%es:56(%3)\n"
14306 ++ "34: movl %%edx, %%es:60(%3)\n"
14307 + " addl $-64, %0\n"
14308 + " addl $64, %4\n"
14309 + " addl $64, %3\n"
14310 +@@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
14311 + "36: movl %%eax, %0\n"
14312 + "37: rep; movsb\n"
14313 + "100:\n"
14314 ++ " pushl %%ss\n"
14315 ++ " popl %%es\n"
14316 + ".section .fixup,\"ax\"\n"
14317 + "101: lea 0(%%eax,%0,4),%0\n"
14318 + " jmp 100b\n"
14319 +@@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
14320 + " .long 99b,101b\n"
14321 + ".previous"
14322 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14323 +- : "1"(to), "2"(from), "0"(size)
14324 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14325 ++ : "eax", "edx", "memory");
14326 ++ return size;
14327 ++}
14328 ++
14329 ++static unsigned long
14330 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
14331 ++{
14332 ++ int d0, d1;
14333 ++ __asm__ __volatile__(
14334 ++ " movw %w6, %%ds\n"
14335 ++ " .align 2,0x90\n"
14336 ++ "1: movl 32(%4), %%eax\n"
14337 ++ " cmpl $67, %0\n"
14338 ++ " jbe 3f\n"
14339 ++ "2: movl 64(%4), %%eax\n"
14340 ++ " .align 2,0x90\n"
14341 ++ "3: movl 0(%4), %%eax\n"
14342 ++ "4: movl 4(%4), %%edx\n"
14343 ++ "5: movl %%eax, %%es:0(%3)\n"
14344 ++ "6: movl %%edx, %%es:4(%3)\n"
14345 ++ "7: movl 8(%4), %%eax\n"
14346 ++ "8: movl 12(%4),%%edx\n"
14347 ++ "9: movl %%eax, %%es:8(%3)\n"
14348 ++ "10: movl %%edx, %%es:12(%3)\n"
14349 ++ "11: movl 16(%4), %%eax\n"
14350 ++ "12: movl 20(%4), %%edx\n"
14351 ++ "13: movl %%eax, %%es:16(%3)\n"
14352 ++ "14: movl %%edx, %%es:20(%3)\n"
14353 ++ "15: movl 24(%4), %%eax\n"
14354 ++ "16: movl 28(%4), %%edx\n"
14355 ++ "17: movl %%eax, %%es:24(%3)\n"
14356 ++ "18: movl %%edx, %%es:28(%3)\n"
14357 ++ "19: movl 32(%4), %%eax\n"
14358 ++ "20: movl 36(%4), %%edx\n"
14359 ++ "21: movl %%eax, %%es:32(%3)\n"
14360 ++ "22: movl %%edx, %%es:36(%3)\n"
14361 ++ "23: movl 40(%4), %%eax\n"
14362 ++ "24: movl 44(%4), %%edx\n"
14363 ++ "25: movl %%eax, %%es:40(%3)\n"
14364 ++ "26: movl %%edx, %%es:44(%3)\n"
14365 ++ "27: movl 48(%4), %%eax\n"
14366 ++ "28: movl 52(%4), %%edx\n"
14367 ++ "29: movl %%eax, %%es:48(%3)\n"
14368 ++ "30: movl %%edx, %%es:52(%3)\n"
14369 ++ "31: movl 56(%4), %%eax\n"
14370 ++ "32: movl 60(%4), %%edx\n"
14371 ++ "33: movl %%eax, %%es:56(%3)\n"
14372 ++ "34: movl %%edx, %%es:60(%3)\n"
14373 ++ " addl $-64, %0\n"
14374 ++ " addl $64, %4\n"
14375 ++ " addl $64, %3\n"
14376 ++ " cmpl $63, %0\n"
14377 ++ " ja 1b\n"
14378 ++ "35: movl %0, %%eax\n"
14379 ++ " shrl $2, %0\n"
14380 ++ " andl $3, %%eax\n"
14381 ++ " cld\n"
14382 ++ "99: rep; movsl\n"
14383 ++ "36: movl %%eax, %0\n"
14384 ++ "37: rep; movsb\n"
14385 ++ "100:\n"
14386 ++ " pushl %%ss\n"
14387 ++ " popl %%ds\n"
14388 ++ ".section .fixup,\"ax\"\n"
14389 ++ "101: lea 0(%%eax,%0,4),%0\n"
14390 ++ " jmp 100b\n"
14391 ++ ".previous\n"
14392 ++ ".section __ex_table,\"a\"\n"
14393 ++ " .align 4\n"
14394 ++ " .long 1b,100b\n"
14395 ++ " .long 2b,100b\n"
14396 ++ " .long 3b,100b\n"
14397 ++ " .long 4b,100b\n"
14398 ++ " .long 5b,100b\n"
14399 ++ " .long 6b,100b\n"
14400 ++ " .long 7b,100b\n"
14401 ++ " .long 8b,100b\n"
14402 ++ " .long 9b,100b\n"
14403 ++ " .long 10b,100b\n"
14404 ++ " .long 11b,100b\n"
14405 ++ " .long 12b,100b\n"
14406 ++ " .long 13b,100b\n"
14407 ++ " .long 14b,100b\n"
14408 ++ " .long 15b,100b\n"
14409 ++ " .long 16b,100b\n"
14410 ++ " .long 17b,100b\n"
14411 ++ " .long 18b,100b\n"
14412 ++ " .long 19b,100b\n"
14413 ++ " .long 20b,100b\n"
14414 ++ " .long 21b,100b\n"
14415 ++ " .long 22b,100b\n"
14416 ++ " .long 23b,100b\n"
14417 ++ " .long 24b,100b\n"
14418 ++ " .long 25b,100b\n"
14419 ++ " .long 26b,100b\n"
14420 ++ " .long 27b,100b\n"
14421 ++ " .long 28b,100b\n"
14422 ++ " .long 29b,100b\n"
14423 ++ " .long 30b,100b\n"
14424 ++ " .long 31b,100b\n"
14425 ++ " .long 32b,100b\n"
14426 ++ " .long 33b,100b\n"
14427 ++ " .long 34b,100b\n"
14428 ++ " .long 35b,100b\n"
14429 ++ " .long 36b,100b\n"
14430 ++ " .long 37b,100b\n"
14431 ++ " .long 99b,101b\n"
14432 ++ ".previous"
14433 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
14434 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14435 + : "eax", "edx", "memory");
14436 + return size;
14437 + }
14438 +@@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
14439 + {
14440 + int d0, d1;
14441 + __asm__ __volatile__(
14442 ++ " movw %w6, %%ds\n"
14443 + " .align 2,0x90\n"
14444 + "0: movl 32(%4), %%eax\n"
14445 + " cmpl $67, %0\n"
14446 +@@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
14447 + " .align 2,0x90\n"
14448 + "2: movl 0(%4), %%eax\n"
14449 + "21: movl 4(%4), %%edx\n"
14450 +- " movl %%eax, 0(%3)\n"
14451 +- " movl %%edx, 4(%3)\n"
14452 ++ " movl %%eax, %%es:0(%3)\n"
14453 ++ " movl %%edx, %%es:4(%3)\n"
14454 + "3: movl 8(%4), %%eax\n"
14455 + "31: movl 12(%4),%%edx\n"
14456 +- " movl %%eax, 8(%3)\n"
14457 +- " movl %%edx, 12(%3)\n"
14458 ++ " movl %%eax, %%es:8(%3)\n"
14459 ++ " movl %%edx, %%es:12(%3)\n"
14460 + "4: movl 16(%4), %%eax\n"
14461 + "41: movl 20(%4), %%edx\n"
14462 +- " movl %%eax, 16(%3)\n"
14463 +- " movl %%edx, 20(%3)\n"
14464 ++ " movl %%eax, %%es:16(%3)\n"
14465 ++ " movl %%edx, %%es:20(%3)\n"
14466 + "10: movl 24(%4), %%eax\n"
14467 + "51: movl 28(%4), %%edx\n"
14468 +- " movl %%eax, 24(%3)\n"
14469 +- " movl %%edx, 28(%3)\n"
14470 ++ " movl %%eax, %%es:24(%3)\n"
14471 ++ " movl %%edx, %%es:28(%3)\n"
14472 + "11: movl 32(%4), %%eax\n"
14473 + "61: movl 36(%4), %%edx\n"
14474 +- " movl %%eax, 32(%3)\n"
14475 +- " movl %%edx, 36(%3)\n"
14476 ++ " movl %%eax, %%es:32(%3)\n"
14477 ++ " movl %%edx, %%es:36(%3)\n"
14478 + "12: movl 40(%4), %%eax\n"
14479 + "71: movl 44(%4), %%edx\n"
14480 +- " movl %%eax, 40(%3)\n"
14481 +- " movl %%edx, 44(%3)\n"
14482 ++ " movl %%eax, %%es:40(%3)\n"
14483 ++ " movl %%edx, %%es:44(%3)\n"
14484 + "13: movl 48(%4), %%eax\n"
14485 + "81: movl 52(%4), %%edx\n"
14486 +- " movl %%eax, 48(%3)\n"
14487 +- " movl %%edx, 52(%3)\n"
14488 ++ " movl %%eax, %%es:48(%3)\n"
14489 ++ " movl %%edx, %%es:52(%3)\n"
14490 + "14: movl 56(%4), %%eax\n"
14491 + "91: movl 60(%4), %%edx\n"
14492 +- " movl %%eax, 56(%3)\n"
14493 +- " movl %%edx, 60(%3)\n"
14494 ++ " movl %%eax, %%es:56(%3)\n"
14495 ++ " movl %%edx, %%es:60(%3)\n"
14496 + " addl $-64, %0\n"
14497 + " addl $64, %4\n"
14498 + " addl $64, %3\n"
14499 +@@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
14500 + " movl %%eax,%0\n"
14501 + "7: rep; movsb\n"
14502 + "8:\n"
14503 ++ " pushl %%ss\n"
14504 ++ " popl %%ds\n"
14505 + ".section .fixup,\"ax\"\n"
14506 + "9: lea 0(%%eax,%0,4),%0\n"
14507 + "16: pushl %0\n"
14508 +@@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
14509 + " .long 7b,16b\n"
14510 + ".previous"
14511 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14512 +- : "1"(to), "2"(from), "0"(size)
14513 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14514 + : "eax", "edx", "memory");
14515 + return size;
14516 + }
14517 +@@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
14518 + int d0, d1;
14519 +
14520 + __asm__ __volatile__(
14521 ++ " movw %w6, %%ds\n"
14522 + " .align 2,0x90\n"
14523 + "0: movl 32(%4), %%eax\n"
14524 + " cmpl $67, %0\n"
14525 +@@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
14526 + " .align 2,0x90\n"
14527 + "2: movl 0(%4), %%eax\n"
14528 + "21: movl 4(%4), %%edx\n"
14529 +- " movnti %%eax, 0(%3)\n"
14530 +- " movnti %%edx, 4(%3)\n"
14531 ++ " movnti %%eax, %%es:0(%3)\n"
14532 ++ " movnti %%edx, %%es:4(%3)\n"
14533 + "3: movl 8(%4), %%eax\n"
14534 + "31: movl 12(%4),%%edx\n"
14535 +- " movnti %%eax, 8(%3)\n"
14536 +- " movnti %%edx, 12(%3)\n"
14537 ++ " movnti %%eax, %%es:8(%3)\n"
14538 ++ " movnti %%edx, %%es:12(%3)\n"
14539 + "4: movl 16(%4), %%eax\n"
14540 + "41: movl 20(%4), %%edx\n"
14541 +- " movnti %%eax, 16(%3)\n"
14542 +- " movnti %%edx, 20(%3)\n"
14543 ++ " movnti %%eax, %%es:16(%3)\n"
14544 ++ " movnti %%edx, %%es:20(%3)\n"
14545 + "10: movl 24(%4), %%eax\n"
14546 + "51: movl 28(%4), %%edx\n"
14547 +- " movnti %%eax, 24(%3)\n"
14548 +- " movnti %%edx, 28(%3)\n"
14549 ++ " movnti %%eax, %%es:24(%3)\n"
14550 ++ " movnti %%edx, %%es:28(%3)\n"
14551 + "11: movl 32(%4), %%eax\n"
14552 + "61: movl 36(%4), %%edx\n"
14553 +- " movnti %%eax, 32(%3)\n"
14554 +- " movnti %%edx, 36(%3)\n"
14555 ++ " movnti %%eax, %%es:32(%3)\n"
14556 ++ " movnti %%edx, %%es:36(%3)\n"
14557 + "12: movl 40(%4), %%eax\n"
14558 + "71: movl 44(%4), %%edx\n"
14559 +- " movnti %%eax, 40(%3)\n"
14560 +- " movnti %%edx, 44(%3)\n"
14561 ++ " movnti %%eax, %%es:40(%3)\n"
14562 ++ " movnti %%edx, %%es:44(%3)\n"
14563 + "13: movl 48(%4), %%eax\n"
14564 + "81: movl 52(%4), %%edx\n"
14565 +- " movnti %%eax, 48(%3)\n"
14566 +- " movnti %%edx, 52(%3)\n"
14567 ++ " movnti %%eax, %%es:48(%3)\n"
14568 ++ " movnti %%edx, %%es:52(%3)\n"
14569 + "14: movl 56(%4), %%eax\n"
14570 + "91: movl 60(%4), %%edx\n"
14571 +- " movnti %%eax, 56(%3)\n"
14572 +- " movnti %%edx, 60(%3)\n"
14573 ++ " movnti %%eax, %%es:56(%3)\n"
14574 ++ " movnti %%edx, %%es:60(%3)\n"
14575 + " addl $-64, %0\n"
14576 + " addl $64, %4\n"
14577 + " addl $64, %3\n"
14578 +@@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
14579 + " movl %%eax,%0\n"
14580 + "7: rep; movsb\n"
14581 + "8:\n"
14582 ++ " pushl %%ss\n"
14583 ++ " popl %%ds\n"
14584 + ".section .fixup,\"ax\"\n"
14585 + "9: lea 0(%%eax,%0,4),%0\n"
14586 + "16: pushl %0\n"
14587 +@@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
14588 + " .long 7b,16b\n"
14589 + ".previous"
14590 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14591 +- : "1"(to), "2"(from), "0"(size)
14592 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14593 + : "eax", "edx", "memory");
14594 + return size;
14595 + }
14596 +@@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
14597 + int d0, d1;
14598 +
14599 + __asm__ __volatile__(
14600 ++ " movw %w6, %%ds\n"
14601 + " .align 2,0x90\n"
14602 + "0: movl 32(%4), %%eax\n"
14603 + " cmpl $67, %0\n"
14604 +@@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
14605 + " .align 2,0x90\n"
14606 + "2: movl 0(%4), %%eax\n"
14607 + "21: movl 4(%4), %%edx\n"
14608 +- " movnti %%eax, 0(%3)\n"
14609 +- " movnti %%edx, 4(%3)\n"
14610 ++ " movnti %%eax, %%es:0(%3)\n"
14611 ++ " movnti %%edx, %%es:4(%3)\n"
14612 + "3: movl 8(%4), %%eax\n"
14613 + "31: movl 12(%4),%%edx\n"
14614 +- " movnti %%eax, 8(%3)\n"
14615 +- " movnti %%edx, 12(%3)\n"
14616 ++ " movnti %%eax, %%es:8(%3)\n"
14617 ++ " movnti %%edx, %%es:12(%3)\n"
14618 + "4: movl 16(%4), %%eax\n"
14619 + "41: movl 20(%4), %%edx\n"
14620 +- " movnti %%eax, 16(%3)\n"
14621 +- " movnti %%edx, 20(%3)\n"
14622 ++ " movnti %%eax, %%es:16(%3)\n"
14623 ++ " movnti %%edx, %%es:20(%3)\n"
14624 + "10: movl 24(%4), %%eax\n"
14625 + "51: movl 28(%4), %%edx\n"
14626 +- " movnti %%eax, 24(%3)\n"
14627 +- " movnti %%edx, 28(%3)\n"
14628 ++ " movnti %%eax, %%es:24(%3)\n"
14629 ++ " movnti %%edx, %%es:28(%3)\n"
14630 + "11: movl 32(%4), %%eax\n"
14631 + "61: movl 36(%4), %%edx\n"
14632 +- " movnti %%eax, 32(%3)\n"
14633 +- " movnti %%edx, 36(%3)\n"
14634 ++ " movnti %%eax, %%es:32(%3)\n"
14635 ++ " movnti %%edx, %%es:36(%3)\n"
14636 + "12: movl 40(%4), %%eax\n"
14637 + "71: movl 44(%4), %%edx\n"
14638 +- " movnti %%eax, 40(%3)\n"
14639 +- " movnti %%edx, 44(%3)\n"
14640 ++ " movnti %%eax, %%es:40(%3)\n"
14641 ++ " movnti %%edx, %%es:44(%3)\n"
14642 + "13: movl 48(%4), %%eax\n"
14643 + "81: movl 52(%4), %%edx\n"
14644 +- " movnti %%eax, 48(%3)\n"
14645 +- " movnti %%edx, 52(%3)\n"
14646 ++ " movnti %%eax, %%es:48(%3)\n"
14647 ++ " movnti %%edx, %%es:52(%3)\n"
14648 + "14: movl 56(%4), %%eax\n"
14649 + "91: movl 60(%4), %%edx\n"
14650 +- " movnti %%eax, 56(%3)\n"
14651 +- " movnti %%edx, 60(%3)\n"
14652 ++ " movnti %%eax, %%es:56(%3)\n"
14653 ++ " movnti %%edx, %%es:60(%3)\n"
14654 + " addl $-64, %0\n"
14655 + " addl $64, %4\n"
14656 + " addl $64, %3\n"
14657 +@@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
14658 + " movl %%eax,%0\n"
14659 + "7: rep; movsb\n"
14660 + "8:\n"
14661 ++ " pushl %%ss\n"
14662 ++ " popl %%ds\n"
14663 + ".section .fixup,\"ax\"\n"
14664 + "9: lea 0(%%eax,%0,4),%0\n"
14665 + "16: jmp 8b\n"
14666 +@@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
14667 + " .long 7b,16b\n"
14668 + ".previous"
14669 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
14670 +- : "1"(to), "2"(from), "0"(size)
14671 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
14672 + : "eax", "edx", "memory");
14673 + return size;
14674 + }
14675 +@@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
14676 + */
14677 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
14678 + unsigned long size);
14679 +-unsigned long __copy_user_intel(void __user *to, const void *from,
14680 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
14681 ++ unsigned long size);
14682 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
14683 + unsigned long size);
14684 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
14685 + const void __user *from, unsigned long size);
14686 + #endif /* CONFIG_X86_INTEL_USERCOPY */
14687 +
14688 + /* Generic arbitrary sized copy. */
14689 +-#define __copy_user(to,from,size) \
14690 +-do { \
14691 +- int __d0, __d1, __d2; \
14692 +- __asm__ __volatile__( \
14693 +- " cmp $7,%0\n" \
14694 +- " jbe 1f\n" \
14695 +- " movl %1,%0\n" \
14696 +- " negl %0\n" \
14697 +- " andl $7,%0\n" \
14698 +- " subl %0,%3\n" \
14699 +- "4: rep; movsb\n" \
14700 +- " movl %3,%0\n" \
14701 +- " shrl $2,%0\n" \
14702 +- " andl $3,%3\n" \
14703 +- " .align 2,0x90\n" \
14704 +- "0: rep; movsl\n" \
14705 +- " movl %3,%0\n" \
14706 +- "1: rep; movsb\n" \
14707 +- "2:\n" \
14708 +- ".section .fixup,\"ax\"\n" \
14709 +- "5: addl %3,%0\n" \
14710 +- " jmp 2b\n" \
14711 +- "3: lea 0(%3,%0,4),%0\n" \
14712 +- " jmp 2b\n" \
14713 +- ".previous\n" \
14714 +- ".section __ex_table,\"a\"\n" \
14715 +- " .align 4\n" \
14716 +- " .long 4b,5b\n" \
14717 +- " .long 0b,3b\n" \
14718 +- " .long 1b,2b\n" \
14719 +- ".previous" \
14720 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
14721 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
14722 +- : "memory"); \
14723 +-} while (0)
14724 +-
14725 +-#define __copy_user_zeroing(to,from,size) \
14726 +-do { \
14727 +- int __d0, __d1, __d2; \
14728 +- __asm__ __volatile__( \
14729 +- " cmp $7,%0\n" \
14730 +- " jbe 1f\n" \
14731 +- " movl %1,%0\n" \
14732 +- " negl %0\n" \
14733 +- " andl $7,%0\n" \
14734 +- " subl %0,%3\n" \
14735 +- "4: rep; movsb\n" \
14736 +- " movl %3,%0\n" \
14737 +- " shrl $2,%0\n" \
14738 +- " andl $3,%3\n" \
14739 +- " .align 2,0x90\n" \
14740 +- "0: rep; movsl\n" \
14741 +- " movl %3,%0\n" \
14742 +- "1: rep; movsb\n" \
14743 +- "2:\n" \
14744 +- ".section .fixup,\"ax\"\n" \
14745 +- "5: addl %3,%0\n" \
14746 +- " jmp 6f\n" \
14747 +- "3: lea 0(%3,%0,4),%0\n" \
14748 +- "6: pushl %0\n" \
14749 +- " pushl %%eax\n" \
14750 +- " xorl %%eax,%%eax\n" \
14751 +- " rep; stosb\n" \
14752 +- " popl %%eax\n" \
14753 +- " popl %0\n" \
14754 +- " jmp 2b\n" \
14755 +- ".previous\n" \
14756 +- ".section __ex_table,\"a\"\n" \
14757 +- " .align 4\n" \
14758 +- " .long 4b,5b\n" \
14759 +- " .long 0b,3b\n" \
14760 +- " .long 1b,6b\n" \
14761 +- ".previous" \
14762 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
14763 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
14764 +- : "memory"); \
14765 +-} while (0)
14766 ++static unsigned long
14767 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
14768 ++{
14769 ++ int __d0, __d1, __d2;
14770 ++
14771 ++ __asm__ __volatile__(
14772 ++ " movw %w8,%%es\n"
14773 ++ " cmp $7,%0\n"
14774 ++ " jbe 1f\n"
14775 ++ " movl %1,%0\n"
14776 ++ " negl %0\n"
14777 ++ " andl $7,%0\n"
14778 ++ " subl %0,%3\n"
14779 ++ "4: rep; movsb\n"
14780 ++ " movl %3,%0\n"
14781 ++ " shrl $2,%0\n"
14782 ++ " andl $3,%3\n"
14783 ++ " .align 2,0x90\n"
14784 ++ "0: rep; movsl\n"
14785 ++ " movl %3,%0\n"
14786 ++ "1: rep; movsb\n"
14787 ++ "2:\n"
14788 ++ " pushl %%ss\n"
14789 ++ " popl %%es\n"
14790 ++ ".section .fixup,\"ax\"\n"
14791 ++ "5: addl %3,%0\n"
14792 ++ " jmp 2b\n"
14793 ++ "3: lea 0(%3,%0,4),%0\n"
14794 ++ " jmp 2b\n"
14795 ++ ".previous\n"
14796 ++ ".section __ex_table,\"a\"\n"
14797 ++ " .align 4\n"
14798 ++ " .long 4b,5b\n"
14799 ++ " .long 0b,3b\n"
14800 ++ " .long 1b,2b\n"
14801 ++ ".previous"
14802 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14803 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14804 ++ : "memory");
14805 ++ return size;
14806 ++}
14807 ++
14808 ++static unsigned long
14809 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
14810 ++{
14811 ++ int __d0, __d1, __d2;
14812 ++
14813 ++ __asm__ __volatile__(
14814 ++ " movw %w8,%%ds\n"
14815 ++ " cmp $7,%0\n"
14816 ++ " jbe 1f\n"
14817 ++ " movl %1,%0\n"
14818 ++ " negl %0\n"
14819 ++ " andl $7,%0\n"
14820 ++ " subl %0,%3\n"
14821 ++ "4: rep; movsb\n"
14822 ++ " movl %3,%0\n"
14823 ++ " shrl $2,%0\n"
14824 ++ " andl $3,%3\n"
14825 ++ " .align 2,0x90\n"
14826 ++ "0: rep; movsl\n"
14827 ++ " movl %3,%0\n"
14828 ++ "1: rep; movsb\n"
14829 ++ "2:\n"
14830 ++ " pushl %%ss\n"
14831 ++ " popl %%ds\n"
14832 ++ ".section .fixup,\"ax\"\n"
14833 ++ "5: addl %3,%0\n"
14834 ++ " jmp 2b\n"
14835 ++ "3: lea 0(%3,%0,4),%0\n"
14836 ++ " jmp 2b\n"
14837 ++ ".previous\n"
14838 ++ ".section __ex_table,\"a\"\n"
14839 ++ " .align 4\n"
14840 ++ " .long 4b,5b\n"
14841 ++ " .long 0b,3b\n"
14842 ++ " .long 1b,2b\n"
14843 ++ ".previous"
14844 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14845 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14846 ++ : "memory");
14847 ++ return size;
14848 ++}
14849 ++
14850 ++static unsigned long
14851 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
14852 ++{
14853 ++ int __d0, __d1, __d2;
14854 ++
14855 ++ __asm__ __volatile__(
14856 ++ " movw %w8,%%ds\n"
14857 ++ " cmp $7,%0\n"
14858 ++ " jbe 1f\n"
14859 ++ " movl %1,%0\n"
14860 ++ " negl %0\n"
14861 ++ " andl $7,%0\n"
14862 ++ " subl %0,%3\n"
14863 ++ "4: rep; movsb\n"
14864 ++ " movl %3,%0\n"
14865 ++ " shrl $2,%0\n"
14866 ++ " andl $3,%3\n"
14867 ++ " .align 2,0x90\n"
14868 ++ "0: rep; movsl\n"
14869 ++ " movl %3,%0\n"
14870 ++ "1: rep; movsb\n"
14871 ++ "2:\n"
14872 ++ " pushl %%ss\n"
14873 ++ " popl %%ds\n"
14874 ++ ".section .fixup,\"ax\"\n"
14875 ++ "5: addl %3,%0\n"
14876 ++ " jmp 6f\n"
14877 ++ "3: lea 0(%3,%0,4),%0\n"
14878 ++ "6: pushl %0\n"
14879 ++ " pushl %%eax\n"
14880 ++ " xorl %%eax,%%eax\n"
14881 ++ " rep; stosb\n"
14882 ++ " popl %%eax\n"
14883 ++ " popl %0\n"
14884 ++ " jmp 2b\n"
14885 ++ ".previous\n"
14886 ++ ".section __ex_table,\"a\"\n"
14887 ++ " .align 4\n"
14888 ++ " .long 4b,5b\n"
14889 ++ " .long 0b,3b\n"
14890 ++ " .long 1b,6b\n"
14891 ++ ".previous"
14892 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
14893 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
14894 ++ : "memory");
14895 ++ return size;
14896 ++}
14897 +
14898 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
14899 + unsigned long n)
14900 +@@ -768,9 +959,9 @@ survive:
14901 + }
14902 + #endif
14903 + if (movsl_is_ok(to, from, n))
14904 +- __copy_user(to, from, n);
14905 ++ n = __generic_copy_to_user(to, from, n);
14906 + else
14907 +- n = __copy_user_intel(to, from, n);
14908 ++ n = __generic_copy_to_user_intel(to, from, n);
14909 + return n;
14910 + }
14911 + EXPORT_SYMBOL(__copy_to_user_ll);
14912 +@@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
14913 + unsigned long n)
14914 + {
14915 + if (movsl_is_ok(to, from, n))
14916 +- __copy_user_zeroing(to, from, n);
14917 ++ n = __copy_user_zeroing(to, from, n);
14918 + else
14919 + n = __copy_user_zeroing_intel(to, from, n);
14920 + return n;
14921 +@@ -790,9 +981,9 @@ unsigned long __copy_from_user_ll_nozero
14922 + unsigned long n)
14923 + {
14924 + if (movsl_is_ok(to, from, n))
14925 +- __copy_user(to, from, n);
14926 ++ n = __generic_copy_from_user(to, from, n);
14927 + else
14928 +- n = __copy_user_intel((void __user *)to,
14929 ++ n = __generic_copy_from_user_intel((void __user *)to,
14930 + (const void *)from, n);
14931 + return n;
14932 + }
14933 +@@ -803,11 +994,11 @@ unsigned long __copy_from_user_ll_nocach
14934 + {
14935 + #ifdef CONFIG_X86_INTEL_USERCOPY
14936 + if ( n > 64 && cpu_has_xmm2)
14937 +- n = __copy_user_zeroing_intel_nocache(to, from, n);
14938 ++ n = __copy_user_zeroing_intel_nocache(to, from, n);
14939 + else
14940 +- __copy_user_zeroing(to, from, n);
14941 ++ n = __copy_user_zeroing(to, from, n);
14942 + #else
14943 +- __copy_user_zeroing(to, from, n);
14944 ++ n = __copy_user_zeroing(to, from, n);
14945 + #endif
14946 + return n;
14947 + }
14948 +@@ -818,11 +1009,11 @@ unsigned long __copy_from_user_ll_nocach
14949 + {
14950 + #ifdef CONFIG_X86_INTEL_USERCOPY
14951 + if ( n > 64 && cpu_has_xmm2)
14952 +- n = __copy_user_intel_nocache(to, from, n);
14953 ++ n = __copy_user_intel_nocache(to, from, n);
14954 + else
14955 +- __copy_user(to, from, n);
14956 ++ n = __generic_copy_from_user(to, from, n);
14957 + #else
14958 +- __copy_user(to, from, n);
14959 ++ n = __generic_copy_from_user(to, from, n);
14960 + #endif
14961 + return n;
14962 + }
14963 +@@ -871,8 +1062,35 @@ copy_from_user(void *to, const void __us
14964 + {
14965 + if (access_ok(VERIFY_READ, from, n))
14966 + n = __copy_from_user(to, from, n);
14967 +- else
14968 ++ else if ((long)n > 0)
14969 + memset(to, 0, n);
14970 + return n;
14971 + }
14972 + EXPORT_SYMBOL(copy_from_user);
14973 ++
14974 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
14975 ++void __set_fs(mm_segment_t x, int cpu)
14976 ++{
14977 ++ unsigned long limit = x.seg;
14978 ++ struct desc_struct d;
14979 ++
14980 ++ current_thread_info()->addr_limit = x;
14981 ++ if (likely(limit))
14982 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
14983 ++ pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
14984 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
14985 ++}
14986 ++
14987 ++void set_fs(mm_segment_t x)
14988 ++{
14989 ++ __set_fs(x, get_cpu());
14990 ++ put_cpu_no_resched();
14991 ++}
14992 ++#else
14993 ++void set_fs(mm_segment_t x)
14994 ++{
14995 ++ current_thread_info()->addr_limit = x;
14996 ++}
14997 ++#endif
14998 ++
14999 ++EXPORT_SYMBOL(set_fs);
15000 +diff -urNp a/arch/x86/mach-voyager/voyager_basic.c b/arch/x86/mach-voyager/voyager_basic.c
15001 +--- a/arch/x86/mach-voyager/voyager_basic.c 2008-08-20 11:16:13.000000000 -0700
15002 ++++ b/arch/x86/mach-voyager/voyager_basic.c 2008-08-20 18:36:57.000000000 -0700
15003 +@@ -125,7 +125,7 @@ int __init voyager_memory_detect(int reg
15004 + __u8 cmos[4];
15005 + ClickMap_t *map;
15006 + unsigned long map_addr;
15007 +- unsigned long old;
15008 ++ pte_t old;
15009 +
15010 + if (region >= CLICK_ENTRIES) {
15011 + printk("Voyager: Illegal ClickMap region %d\n", region);
15012 +@@ -140,7 +140,7 @@ int __init voyager_memory_detect(int reg
15013 +
15014 + /* steal page 0 for this */
15015 + old = pg0[0];
15016 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
15017 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
15018 + local_flush_tlb();
15019 + /* now clear everything out but page 0 */
15020 + map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
15021 +diff -urNp a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
15022 +--- a/arch/x86/mach-voyager/voyager_smp.c 2008-08-20 11:16:13.000000000 -0700
15023 ++++ b/arch/x86/mach-voyager/voyager_smp.c 2008-08-20 18:36:57.000000000 -0700
15024 +@@ -540,6 +540,10 @@ static void __init do_boot_cpu(__u8 cpu)
15025 + __u32 *hijack_vector;
15026 + __u32 start_phys_address = setup_trampoline();
15027 +
15028 ++#ifdef CONFIG_PAX_KERNEXEC
15029 ++ unsigned long cr0;
15030 ++#endif
15031 ++
15032 + /* There's a clever trick to this: The linux trampoline is
15033 + * compiled to begin at absolute location zero, so make the
15034 + * address zero but have the data segment selector compensate
15035 +@@ -559,7 +563,17 @@ static void __init do_boot_cpu(__u8 cpu)
15036 +
15037 + init_gdt(cpu);
15038 + per_cpu(current_task, cpu) = idle;
15039 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
15040 ++
15041 ++#ifdef CONFIG_PAX_KERNEXEC
15042 ++ pax_open_kernel(cr0);
15043 ++#endif
15044 ++
15045 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
15046 ++
15047 ++#ifdef CONFIG_PAX_KERNEXEC
15048 ++ pax_close_kernel(cr0);
15049 ++#endif
15050 ++
15051 + irq_ctx_init(cpu);
15052 +
15053 + /* Note: Don't modify initial ss override */
15054 +@@ -1242,7 +1256,7 @@ void smp_local_timer_interrupt(void)
15055 + per_cpu(prof_counter, cpu);
15056 + }
15057 +
15058 +- update_process_times(user_mode_vm(get_irq_regs()));
15059 ++ update_process_times(user_mode(get_irq_regs()));
15060 + }
15061 +
15062 + if (((1 << cpu) & voyager_extended_vic_processors) == 0)
15063 +diff -urNp a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
15064 +--- a/arch/x86/mm/extable.c 2008-08-20 11:16:13.000000000 -0700
15065 ++++ b/arch/x86/mm/extable.c 2008-08-20 18:36:57.000000000 -0700
15066 +@@ -1,14 +1,62 @@
15067 + #include <linux/module.h>
15068 + #include <linux/spinlock.h>
15069 ++#include <linux/sort.h>
15070 + #include <asm/uaccess.h>
15071 +
15072 ++/*
15073 ++ * The exception table needs to be sorted so that the binary
15074 ++ * search that we use to find entries in it works properly.
15075 ++ * This is used both for the kernel exception table and for
15076 ++ * the exception tables of modules that get loaded.
15077 ++ */
15078 ++static int cmp_ex(const void *a, const void *b)
15079 ++{
15080 ++ const struct exception_table_entry *x = a, *y = b;
15081 ++
15082 ++ /* avoid overflow */
15083 ++ if (x->insn > y->insn)
15084 ++ return 1;
15085 ++ if (x->insn < y->insn)
15086 ++ return -1;
15087 ++ return 0;
15088 ++}
15089 ++
15090 ++static void swap_ex(void *a, void *b, int size)
15091 ++{
15092 ++ struct exception_table_entry t, *x = a, *y = b;
15093 ++
15094 ++#ifdef CONFIG_PAX_KERNEXEC
15095 ++ unsigned long cr0;
15096 ++#endif
15097 ++
15098 ++ t = *x;
15099 ++
15100 ++#ifdef CONFIG_PAX_KERNEXEC
15101 ++ pax_open_kernel(cr0);
15102 ++#endif
15103 ++
15104 ++ *x = *y;
15105 ++ *y = t;
15106 ++
15107 ++#ifdef CONFIG_PAX_KERNEXEC
15108 ++ pax_close_kernel(cr0);
15109 ++#endif
15110 ++
15111 ++}
15112 ++
15113 ++void sort_extable(struct exception_table_entry *start,
15114 ++ struct exception_table_entry *finish)
15115 ++{
15116 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
15117 ++ cmp_ex, swap_ex);
15118 ++}
15119 +
15120 + int fixup_exception(struct pt_regs *regs)
15121 + {
15122 + const struct exception_table_entry *fixup;
15123 +
15124 + #ifdef CONFIG_PNPBIOS
15125 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
15126 ++ if (unlikely(!(regs->flags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->cs))) {
15127 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
15128 + extern u32 pnp_bios_is_utter_crap;
15129 + pnp_bios_is_utter_crap = 1;
15130 +diff -urNp a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
15131 +--- a/arch/x86/mm/fault.c 2008-08-20 11:16:13.000000000 -0700
15132 ++++ b/arch/x86/mm/fault.c 2008-08-20 18:36:57.000000000 -0700
15133 +@@ -25,6 +25,9 @@
15134 + #include <linux/kprobes.h>
15135 + #include <linux/uaccess.h>
15136 + #include <linux/kdebug.h>
15137 ++#include <linux/unistd.h>
15138 ++#include <linux/compiler.h>
15139 ++#include <linux/binfmts.h>
15140 +
15141 + #include <asm/system.h>
15142 + #include <asm/desc.h>
15143 +@@ -34,6 +37,7 @@
15144 + #include <asm/tlbflush.h>
15145 + #include <asm/proto.h>
15146 + #include <asm-generic/sections.h>
15147 ++#include <asm/tlbflush.h>
15148 +
15149 + /*
15150 + * Page fault error code bits
15151 +@@ -55,11 +59,7 @@ static inline int notify_page_fault(stru
15152 + int ret = 0;
15153 +
15154 + /* kprobe_running() needs smp_processor_id() */
15155 +-#ifdef CONFIG_X86_32
15156 +- if (!user_mode_vm(regs)) {
15157 +-#else
15158 + if (!user_mode(regs)) {
15159 +-#endif
15160 + preempt_disable();
15161 + if (kprobe_running() && kprobe_fault_handler(regs, 14))
15162 + ret = 1;
15163 +@@ -257,6 +257,30 @@ bad:
15164 + #endif
15165 + }
15166 +
15167 ++#ifdef CONFIG_PAX_EMUTRAMP
15168 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
15169 ++#endif
15170 ++
15171 ++#ifdef CONFIG_PAX_PAGEEXEC
15172 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
15173 ++{
15174 ++ pgd_t *pgd;
15175 ++ pud_t *pud;
15176 ++ pmd_t *pmd;
15177 ++
15178 ++ pgd = pgd_offset(mm, address);
15179 ++ if (!pgd_present(*pgd))
15180 ++ return NULL;
15181 ++ pud = pud_offset(pgd, address);
15182 ++ if (!pud_present(*pud))
15183 ++ return NULL;
15184 ++ pmd = pmd_offset(pud, address);
15185 ++ if (!pmd_present(*pmd))
15186 ++ return NULL;
15187 ++ return pmd;
15188 ++}
15189 ++#endif
15190 ++
15191 + #ifdef CONFIG_X86_32
15192 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
15193 + {
15194 +@@ -343,7 +367,7 @@ static int is_errata93(struct pt_regs *r
15195 + static int is_errata100(struct pt_regs *regs, unsigned long address)
15196 + {
15197 + #ifdef CONFIG_X86_64
15198 +- if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
15199 ++ if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
15200 + (address >> 32))
15201 + return 1;
15202 + #endif
15203 +@@ -380,17 +404,32 @@ static void show_fault_oops(struct pt_re
15204 + #endif
15205 +
15206 + #ifdef CONFIG_X86_PAE
15207 +- if (error_code & PF_INSTR) {
15208 ++ if (nx_enabled && (error_code & PF_INSTR)) {
15209 + unsigned int level;
15210 + pte_t *pte = lookup_address(address, &level);
15211 +
15212 + if (pte && pte_present(*pte) && !pte_exec(*pte))
15213 + printk(KERN_CRIT "kernel tried to execute "
15214 + "NX-protected page - exploit attempt? "
15215 +- "(uid: %d)\n", current->uid);
15216 ++ "(uid: %d, task: %s, pid: %d)\n",
15217 ++ current->uid, current->comm, task_pid_nr(current));
15218 + }
15219 + #endif
15220 +
15221 ++#ifdef CONFIG_PAX_KERNEXEC
15222 ++#ifdef CONFIG_MODULES
15223 ++ if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
15224 ++#else
15225 ++ if (init_mm.start_code <= address && address < init_mm.end_code)
15226 ++#endif
15227 ++ if (current->signal->curr_ip)
15228 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
15229 ++ NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
15230 ++ else
15231 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
15232 ++ current->comm, task_pid_nr(current), current->uid, current->euid);
15233 ++#endif
15234 ++
15235 + printk(KERN_ALERT "BUG: unable to handle kernel ");
15236 + if (address < PAGE_SIZE)
15237 + printk(KERN_CONT "NULL pointer dereference");
15238 +@@ -578,13 +617,22 @@ void __kprobes do_page_fault(struct pt_r
15239 + struct task_struct *tsk;
15240 + struct mm_struct *mm;
15241 + struct vm_area_struct *vma;
15242 +- unsigned long address;
15243 + int write, si_code;
15244 + int fault;
15245 + #ifdef CONFIG_X86_64
15246 + unsigned long flags;
15247 + #endif
15248 +
15249 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
15250 ++ pte_t *pte;
15251 ++ pmd_t *pmd;
15252 ++ spinlock_t *ptl;
15253 ++ unsigned char pte_mask;
15254 ++#endif
15255 ++
15256 ++ /* get the address */
15257 ++ const unsigned long address = read_cr2();
15258 ++
15259 + /*
15260 + * We can fault from pretty much anywhere, with unknown IRQ state.
15261 + */
15262 +@@ -594,9 +642,6 @@ void __kprobes do_page_fault(struct pt_r
15263 + mm = tsk->mm;
15264 + prefetchw(&mm->mmap_sem);
15265 +
15266 +- /* get the address */
15267 +- address = read_cr2();
15268 +-
15269 + si_code = SEGV_MAPERR;
15270 +
15271 + if (notify_page_fault(regs))
15272 +@@ -647,7 +692,7 @@ void __kprobes do_page_fault(struct pt_r
15273 + * atomic region then we must not take the fault.
15274 + */
15275 + if (in_atomic() || !mm)
15276 +- goto bad_area_nosemaphore;
15277 ++ goto bad_area_nopax;
15278 + #else /* CONFIG_X86_64 */
15279 + if (likely(regs->flags & X86_EFLAGS_IF))
15280 + local_irq_enable();
15281 +@@ -660,13 +705,13 @@ void __kprobes do_page_fault(struct pt_r
15282 + * atomic region then we must not take the fault.
15283 + */
15284 + if (unlikely(in_atomic() || !mm))
15285 +- goto bad_area_nosemaphore;
15286 ++ goto bad_area_nopax;
15287 +
15288 + /*
15289 + * User-mode registers count as a user access even for any
15290 + * potential system fault or CPU buglet.
15291 + */
15292 +- if (user_mode_vm(regs))
15293 ++ if (user_mode(regs))
15294 + error_code |= PF_USER;
15295 + again:
15296 + #endif
15297 +@@ -688,10 +733,104 @@ again:
15298 + if (!down_read_trylock(&mm->mmap_sem)) {
15299 + if ((error_code & PF_USER) == 0 &&
15300 + !search_exception_tables(regs->ip))
15301 +- goto bad_area_nosemaphore;
15302 ++ goto bad_area_nopax;
15303 + down_read(&mm->mmap_sem);
15304 + }
15305 +
15306 ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
15307 ++ if (nx_enabled || (error_code & 5) != 5 || (regs->flags & X86_EFLAGS_VM) ||
15308 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
15309 ++ goto not_pax_fault;
15310 ++
15311 ++ /* PaX: it's our fault, let's handle it if we can */
15312 ++
15313 ++ /* PaX: take a look at read faults before acquiring any locks */
15314 ++ if (unlikely(!(error_code & 2) && (regs->ip == address))) {
15315 ++ /* instruction fetch attempt from a protected page in user mode */
15316 ++ up_read(&mm->mmap_sem);
15317 ++
15318 ++#ifdef CONFIG_PAX_EMUTRAMP
15319 ++ switch (pax_handle_fetch_fault(regs)) {
15320 ++ case 2:
15321 ++ return;
15322 ++ }
15323 ++#endif
15324 ++
15325 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
15326 ++ do_group_exit(SIGKILL);
15327 ++ }
15328 ++
15329 ++ pmd = pax_get_pmd(mm, address);
15330 ++ if (unlikely(!pmd))
15331 ++ goto not_pax_fault;
15332 ++
15333 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
15334 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
15335 ++ pte_unmap_unlock(pte, ptl);
15336 ++ goto not_pax_fault;
15337 ++ }
15338 ++
15339 ++ if (unlikely((error_code & 2) && !pte_write(*pte))) {
15340 ++ /* write attempt to a protected page in user mode */
15341 ++ pte_unmap_unlock(pte, ptl);
15342 ++ goto not_pax_fault;
15343 ++ }
15344 ++
15345 ++#ifdef CONFIG_SMP
15346 ++ if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
15347 ++#else
15348 ++ if (likely(address > get_limit(regs->cs)))
15349 ++#endif
15350 ++ {
15351 ++ set_pte(pte, pte_mkread(*pte));
15352 ++ __flush_tlb_one(address);
15353 ++ pte_unmap_unlock(pte, ptl);
15354 ++ up_read(&mm->mmap_sem);
15355 ++ return;
15356 ++ }
15357 ++
15358 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
15359 ++
15360 ++ /*
15361 ++ * PaX: fill DTLB with user rights and retry
15362 ++ */
15363 ++ __asm__ __volatile__ (
15364 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
15365 ++ "movw %w4,%%es\n"
15366 ++#endif
15367 ++ "orb %2,(%1)\n"
15368 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
15369 ++/*
15370 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
15371 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
15372 ++ * page fault when examined during a TLB load attempt. this is true not only
15373 ++ * for PTEs holding a non-present entry but also present entries that will
15374 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
15375 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
15376 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
15377 ++
15378 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
15379 ++ * fast path of the page fault handler and can get rid of tracing since we
15380 ++ * can no longer flush unintended entries.
15381 ++ */
15382 ++ "invlpg (%0)\n"
15383 ++#endif
15384 ++ "testb $0,%%es:(%0)\n"
15385 ++ "xorb %3,(%1)\n"
15386 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
15387 ++ "pushl %%ss\n"
15388 ++ "popl %%es\n"
15389 ++#endif
15390 ++ :
15391 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
15392 ++ : "memory", "cc");
15393 ++ pte_unmap_unlock(pte, ptl);
15394 ++ up_read(&mm->mmap_sem);
15395 ++ return;
15396 ++
15397 ++not_pax_fault:
15398 ++#endif
15399 ++
15400 + vma = find_vma(mm, address);
15401 + if (!vma)
15402 + goto bad_area;
15403 +@@ -709,6 +848,12 @@ again:
15404 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
15405 + goto bad_area;
15406 + }
15407 ++
15408 ++#ifdef CONFIG_PAX_SEGMEXEC
15409 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
15410 ++ goto bad_area;
15411 ++#endif
15412 ++
15413 + if (expand_stack(vma, address))
15414 + goto bad_area;
15415 + /*
15416 +@@ -718,6 +863,8 @@ again:
15417 + good_area:
15418 + si_code = SEGV_ACCERR;
15419 + write = 0;
15420 ++ if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
15421 ++ goto bad_area;
15422 + switch (error_code & (PF_PROT|PF_WRITE)) {
15423 + default: /* 3: write, present */
15424 + /* fall through */
15425 +@@ -775,6 +922,49 @@ bad_area:
15426 + up_read(&mm->mmap_sem);
15427 +
15428 + bad_area_nosemaphore:
15429 ++
15430 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15431 ++ if (mm && (error_code & 4) && !(regs->flags & X86_EFLAGS_VM)) {
15432 ++ /*
15433 ++ * It's possible to have interrupts off here.
15434 ++ */
15435 ++ local_irq_enable();
15436 ++
15437 ++#ifdef CONFIG_PAX_PAGEEXEC
15438 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
15439 ++ ((nx_enabled && ((error_code & PF_INSTR) || !(error_code & (PF_PROT | PF_WRITE))) && (regs->ip == address)))) {
15440 ++
15441 ++#ifdef CONFIG_PAX_EMUTRAMP
15442 ++ switch (pax_handle_fetch_fault(regs)) {
15443 ++ case 2:
15444 ++ return;
15445 ++ }
15446 ++#endif
15447 ++
15448 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
15449 ++ do_group_exit(SIGKILL);
15450 ++ }
15451 ++#endif
15452 ++
15453 ++#ifdef CONFIG_PAX_SEGMEXEC
15454 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
15455 ++
15456 ++#ifdef CONFIG_PAX_EMUTRAMP
15457 ++ switch (pax_handle_fetch_fault(regs)) {
15458 ++ case 2:
15459 ++ return;
15460 ++ }
15461 ++#endif
15462 ++
15463 ++ pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
15464 ++ do_group_exit(SIGKILL);
15465 ++ }
15466 ++#endif
15467 ++
15468 ++ }
15469 ++#endif
15470 ++
15471 ++bad_area_nopax:
15472 + /* User mode accesses just cause a SIGSEGV */
15473 + if (error_code & PF_USER) {
15474 + /*
15475 +@@ -857,7 +1047,7 @@ no_context:
15476 + #ifdef CONFIG_X86_32
15477 + die("Oops", regs, error_code);
15478 + bust_spinlocks(0);
15479 +- do_exit(SIGKILL);
15480 ++ do_group_exit(SIGKILL);
15481 + #else
15482 + if (__die("Oops", regs, error_code))
15483 + regs = NULL;
15484 +@@ -871,17 +1061,17 @@ no_context:
15485 + * us unable to handle the page fault gracefully.
15486 + */
15487 + out_of_memory:
15488 +- up_read(&mm->mmap_sem);
15489 + if (is_global_init(tsk)) {
15490 + yield();
15491 + #ifdef CONFIG_X86_32
15492 +- down_read(&mm->mmap_sem);
15493 + goto survive;
15494 + #else
15495 ++ up_read(&mm->mmap_sem);
15496 + goto again;
15497 + #endif
15498 + }
15499 +
15500 ++ up_read(&mm->mmap_sem);
15501 + printk("VM: killing process %s\n", tsk->comm);
15502 + if (error_code & PF_USER)
15503 + do_group_exit(SIGKILL);
15504 +@@ -982,3 +1172,174 @@ void vmalloc_sync_all(void)
15505 + (__START_KERNEL & PGDIR_MASK)));
15506 + #endif
15507 + }
15508 ++
15509 ++#ifdef CONFIG_PAX_EMUTRAMP
15510 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
15511 ++{
15512 ++ int err;
15513 ++
15514 ++ do { /* PaX: gcc trampoline emulation #1 */
15515 ++ unsigned char mov1, mov2;
15516 ++ unsigned short jmp;
15517 ++ unsigned int addr1, addr2;
15518 ++
15519 ++#ifdef CONFIG_X86_64
15520 ++ if ((regs->ip + 11) >> 32)
15521 ++ break;
15522 ++#endif
15523 ++
15524 ++ err = get_user(mov1, (unsigned char __user *)regs->ip);
15525 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
15526 ++ err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
15527 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
15528 ++ err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
15529 ++
15530 ++ if (err)
15531 ++ break;
15532 ++
15533 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
15534 ++ regs->cx = addr1;
15535 ++ regs->ax = addr2;
15536 ++ regs->ip = addr2;
15537 ++ return 2;
15538 ++ }
15539 ++ } while (0);
15540 ++
15541 ++ do { /* PaX: gcc trampoline emulation #2 */
15542 ++ unsigned char mov, jmp;
15543 ++ unsigned int addr1, addr2;
15544 ++
15545 ++#ifdef CONFIG_X86_64
15546 ++ if ((regs->ip + 9) >> 32)
15547 ++ break;
15548 ++#endif
15549 ++
15550 ++ err = get_user(mov, (unsigned char __user *)regs->ip);
15551 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
15552 ++ err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
15553 ++ err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
15554 ++
15555 ++ if (err)
15556 ++ break;
15557 ++
15558 ++ if (mov == 0xB9 && jmp == 0xE9) {
15559 ++ regs->cx = addr1;
15560 ++ regs->ip = (unsigned int)(regs->ip + addr2 + 10);
15561 ++ return 2;
15562 ++ }
15563 ++ } while (0);
15564 ++
15565 ++ return 1; /* PaX in action */
15566 ++}
15567 ++
15568 ++#ifdef CONFIG_X86_64
15569 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
15570 ++{
15571 ++ int err;
15572 ++
15573 ++ do { /* PaX: gcc trampoline emulation #1 */
15574 ++ unsigned short mov1, mov2, jmp1;
15575 ++ unsigned char jmp2;
15576 ++ unsigned int addr1;
15577 ++ unsigned long addr2;
15578 ++
15579 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
15580 ++ err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
15581 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
15582 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
15583 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
15584 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
15585 ++
15586 ++ if (err)
15587 ++ break;
15588 ++
15589 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
15590 ++ regs->r11 = addr1;
15591 ++ regs->r10 = addr2;
15592 ++ regs->ip = addr1;
15593 ++ return 2;
15594 ++ }
15595 ++ } while (0);
15596 ++
15597 ++ do { /* PaX: gcc trampoline emulation #2 */
15598 ++ unsigned short mov1, mov2, jmp1;
15599 ++ unsigned char jmp2;
15600 ++ unsigned long addr1, addr2;
15601 ++
15602 ++ err = get_user(mov1, (unsigned short __user *)regs->ip);
15603 ++ err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
15604 ++ err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
15605 ++ err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
15606 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
15607 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
15608 ++
15609 ++ if (err)
15610 ++ break;
15611 ++
15612 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
15613 ++ regs->r11 = addr1;
15614 ++ regs->r10 = addr2;
15615 ++ regs->ip = addr1;
15616 ++ return 2;
15617 ++ }
15618 ++ } while (0);
15619 ++
15620 ++ return 1; /* PaX in action */
15621 ++}
15622 ++#endif
15623 ++
15624 ++/*
15625 ++ * PaX: decide what to do with offenders (regs->ip = fault address)
15626 ++ *
15627 ++ * returns 1 when task should be killed
15628 ++ * 2 when gcc trampoline was detected
15629 ++ */
15630 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
15631 ++{
15632 ++ if (regs->flags & X86_EFLAGS_VM)
15633 ++ return 1;
15634 ++
15635 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
15636 ++ return 1;
15637 ++
15638 ++#ifdef CONFIG_X86_32
15639 ++ return pax_handle_fetch_fault_32(regs);
15640 ++#else
15641 ++ if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
15642 ++ return pax_handle_fetch_fault_32(regs);
15643 ++ else
15644 ++ return pax_handle_fetch_fault_64(regs);
15645 ++#endif
15646 ++}
15647 ++#endif
15648 ++
15649 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15650 ++void pax_report_insns(void *pc, void *sp)
15651 ++{
15652 ++ long i;
15653 ++
15654 ++ printk(KERN_ERR "PAX: bytes at PC: ");
15655 ++ for (i = 0; i < 20; i++) {
15656 ++ unsigned char c;
15657 ++ if (get_user(c, (unsigned char __user *)pc+i))
15658 ++ printk(KERN_CONT "?? ");
15659 ++ else
15660 ++ printk(KERN_CONT "%02x ", c);
15661 ++ }
15662 ++ printk("\n");
15663 ++
15664 ++ printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
15665 ++ for (i = -1; i < 80 / sizeof(long); i++) {
15666 ++ unsigned long c;
15667 ++ if (get_user(c, (unsigned long __user *)sp+i))
15668 ++#ifdef CONFIG_X86_32
15669 ++ printk(KERN_CONT "???????? ");
15670 ++#else
15671 ++ printk(KERN_CONT "???????????????? ");
15672 ++#endif
15673 ++ else
15674 ++ printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
15675 ++ }
15676 ++ printk("\n");
15677 ++}
15678 ++#endif
15679 +diff -urNp a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
15680 +--- a/arch/x86/mm/highmem_32.c 2008-08-20 11:16:13.000000000 -0700
15681 ++++ b/arch/x86/mm/highmem_32.c 2008-08-20 18:36:57.000000000 -0700
15682 +@@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
15683 + enum fixed_addresses idx;
15684 + unsigned long vaddr;
15685 +
15686 ++#ifdef CONFIG_PAX_KERNEXEC
15687 ++ unsigned long cr0;
15688 ++#endif
15689 ++
15690 + /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
15691 + pagefault_disable();
15692 +
15693 +@@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
15694 + idx = type + KM_TYPE_NR*smp_processor_id();
15695 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15696 + BUG_ON(!pte_none(*(kmap_pte-idx)));
15697 ++
15698 ++#ifdef CONFIG_PAX_KERNEXEC
15699 ++ pax_open_kernel(cr0);
15700 ++#endif
15701 ++
15702 + set_pte(kmap_pte-idx, mk_pte(page, prot));
15703 ++
15704 ++#ifdef CONFIG_PAX_KERNEXEC
15705 ++ pax_close_kernel(cr0);
15706 ++#endif
15707 ++
15708 + arch_flush_lazy_mmu_mode();
15709 +
15710 + return (void *)vaddr;
15711 +@@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
15712 + unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
15713 + enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
15714 +
15715 ++#ifdef CONFIG_PAX_KERNEXEC
15716 ++ unsigned long cr0;
15717 ++#endif
15718 ++
15719 + /*
15720 + * Force other mappings to Oops if they'll try to access this pte
15721 + * without first remap it. Keeping stale mappings around is a bad idea
15722 + * also, in case the page changes cacheability attributes or becomes
15723 + * a protected page in a hypervisor.
15724 + */
15725 +- if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
15726 ++ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
15727 ++
15728 ++#ifdef CONFIG_PAX_KERNEXEC
15729 ++ pax_open_kernel(cr0);
15730 ++#endif
15731 ++
15732 + kpte_clear_flush(kmap_pte-idx, vaddr);
15733 +- else {
15734 ++
15735 ++#ifdef CONFIG_PAX_KERNEXEC
15736 ++ pax_close_kernel(cr0);
15737 ++#endif
15738 ++
15739 ++ } else {
15740 + #ifdef CONFIG_DEBUG_HIGHMEM
15741 + BUG_ON(vaddr < PAGE_OFFSET);
15742 + BUG_ON(vaddr >= (unsigned long)high_memory);
15743 +@@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
15744 + enum fixed_addresses idx;
15745 + unsigned long vaddr;
15746 +
15747 ++#ifdef CONFIG_PAX_KERNEXEC
15748 ++ unsigned long cr0;
15749 ++#endif
15750 ++
15751 + pagefault_disable();
15752 +
15753 + idx = type + KM_TYPE_NR*smp_processor_id();
15754 + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
15755 ++
15756 ++#ifdef CONFIG_PAX_KERNEXEC
15757 ++ pax_open_kernel(cr0);
15758 ++#endif
15759 ++
15760 + set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
15761 ++
15762 ++#ifdef CONFIG_PAX_KERNEXEC
15763 ++ pax_close_kernel(cr0);
15764 ++#endif
15765 ++
15766 + arch_flush_lazy_mmu_mode();
15767 +
15768 + return (void*) vaddr;
15769 +diff -urNp a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
15770 +--- a/arch/x86/mm/hugetlbpage.c 2008-08-20 11:16:13.000000000 -0700
15771 ++++ b/arch/x86/mm/hugetlbpage.c 2008-08-20 18:36:57.000000000 -0700
15772 +@@ -230,13 +230,18 @@ static unsigned long hugetlb_get_unmappe
15773 + {
15774 + struct mm_struct *mm = current->mm;
15775 + struct vm_area_struct *vma;
15776 +- unsigned long start_addr;
15777 ++ unsigned long start_addr, pax_task_size = TASK_SIZE;
15778 ++
15779 ++#ifdef CONFIG_PAX_SEGMEXEC
15780 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15781 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
15782 ++#endif
15783 +
15784 + if (len > mm->cached_hole_size) {
15785 +- start_addr = mm->free_area_cache;
15786 ++ start_addr = mm->free_area_cache;
15787 + } else {
15788 +- start_addr = TASK_UNMAPPED_BASE;
15789 +- mm->cached_hole_size = 0;
15790 ++ start_addr = mm->mmap_base;
15791 ++ mm->cached_hole_size = 0;
15792 + }
15793 +
15794 + full_search:
15795 +@@ -244,13 +249,13 @@ full_search:
15796 +
15797 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
15798 + /* At this point: (!vma || addr < vma->vm_end). */
15799 +- if (TASK_SIZE - len < addr) {
15800 ++ if (pax_task_size - len < addr) {
15801 + /*
15802 + * Start a new search - just in case we missed
15803 + * some holes.
15804 + */
15805 +- if (start_addr != TASK_UNMAPPED_BASE) {
15806 +- start_addr = TASK_UNMAPPED_BASE;
15807 ++ if (start_addr != mm->mmap_base) {
15808 ++ start_addr = mm->mmap_base;
15809 + mm->cached_hole_size = 0;
15810 + goto full_search;
15811 + }
15812 +@@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
15813 + {
15814 + struct mm_struct *mm = current->mm;
15815 + struct vm_area_struct *vma, *prev_vma;
15816 +- unsigned long base = mm->mmap_base, addr = addr0;
15817 ++ unsigned long base = mm->mmap_base, addr;
15818 + unsigned long largest_hole = mm->cached_hole_size;
15819 +- int first_time = 1;
15820 +
15821 + /* don't allow allocations above current base */
15822 + if (mm->free_area_cache > base)
15823 +@@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
15824 + largest_hole = 0;
15825 + mm->free_area_cache = base;
15826 + }
15827 +-try_again:
15828 ++
15829 + /* make sure it can fit in the remaining address space */
15830 + if (mm->free_area_cache < len)
15831 + goto fail;
15832 +@@ -326,22 +330,26 @@ try_again:
15833 +
15834 + fail:
15835 + /*
15836 +- * if hint left us with no space for the requested
15837 +- * mapping then try again:
15838 +- */
15839 +- if (first_time) {
15840 +- mm->free_area_cache = base;
15841 +- largest_hole = 0;
15842 +- first_time = 0;
15843 +- goto try_again;
15844 +- }
15845 +- /*
15846 + * A failed mmap() very likely causes application failure,
15847 + * so fall back to the bottom-up function here. This scenario
15848 + * can happen with large stack limits and large mmap()
15849 + * allocations.
15850 + */
15851 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
15852 ++
15853 ++#ifdef CONFIG_PAX_SEGMEXEC
15854 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15855 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
15856 ++ else
15857 ++#endif
15858 ++
15859 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
15860 ++
15861 ++#ifdef CONFIG_PAX_RANDMMAP
15862 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
15863 ++ mm->mmap_base += mm->delta_mmap;
15864 ++#endif
15865 ++
15866 ++ mm->free_area_cache = mm->mmap_base;
15867 + mm->cached_hole_size = ~0UL;
15868 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
15869 + len, pgoff, flags);
15870 +@@ -349,6 +357,7 @@ fail:
15871 + /*
15872 + * Restore the topdown base:
15873 + */
15874 ++ mm->mmap_base = base;
15875 + mm->free_area_cache = base;
15876 + mm->cached_hole_size = ~0UL;
15877 +
15878 +@@ -361,10 +370,17 @@ hugetlb_get_unmapped_area(struct file *f
15879 + {
15880 + struct mm_struct *mm = current->mm;
15881 + struct vm_area_struct *vma;
15882 ++ unsigned long pax_task_size = TASK_SIZE;
15883 +
15884 + if (len & ~HPAGE_MASK)
15885 + return -EINVAL;
15886 +- if (len > TASK_SIZE)
15887 ++
15888 ++#ifdef CONFIG_PAX_SEGMEXEC
15889 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
15890 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
15891 ++#endif
15892 ++
15893 ++ if (len > pax_task_size)
15894 + return -ENOMEM;
15895 +
15896 + if (flags & MAP_FIXED) {
15897 +@@ -376,7 +392,7 @@ hugetlb_get_unmapped_area(struct file *f
15898 + if (addr) {
15899 + addr = ALIGN(addr, HPAGE_SIZE);
15900 + vma = find_vma(mm, addr);
15901 +- if (TASK_SIZE - len >= addr &&
15902 ++ if (pax_task_size - len >= addr &&
15903 + (!vma || addr + len <= vma->vm_start))
15904 + return addr;
15905 + }
15906 +diff -urNp a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
15907 +--- a/arch/x86/mm/init_32.c 2008-08-20 11:16:13.000000000 -0700
15908 ++++ b/arch/x86/mm/init_32.c 2008-08-20 18:36:57.000000000 -0700
15909 +@@ -48,6 +48,7 @@
15910 + #include <asm/paravirt.h>
15911 + #include <asm/setup.h>
15912 + #include <asm/cacheflush.h>
15913 ++#include <asm/desc.h>
15914 +
15915 + unsigned int __VMALLOC_RESERVE = 128 << 20;
15916 +
15917 +@@ -57,32 +58,6 @@ unsigned long highstart_pfn, highend_pfn
15918 + static noinline int do_test_wp_bit(void);
15919 +
15920 + /*
15921 +- * Creates a middle page table and puts a pointer to it in the
15922 +- * given global directory entry. This only returns the gd entry
15923 +- * in non-PAE compilation mode, since the middle layer is folded.
15924 +- */
15925 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
15926 +-{
15927 +- pud_t *pud;
15928 +- pmd_t *pmd_table;
15929 +-
15930 +-#ifdef CONFIG_X86_PAE
15931 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
15932 +- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
15933 +-
15934 +- paravirt_alloc_pd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
15935 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
15936 +- pud = pud_offset(pgd, 0);
15937 +- BUG_ON(pmd_table != pmd_offset(pud, 0));
15938 +- }
15939 +-#endif
15940 +- pud = pud_offset(pgd, 0);
15941 +- pmd_table = pmd_offset(pud, 0);
15942 +-
15943 +- return pmd_table;
15944 +-}
15945 +-
15946 +-/*
15947 + * Create a page table and place a pointer to it in a middle page
15948 + * directory entry:
15949 + */
15950 +@@ -100,7 +75,11 @@ static pte_t * __init one_page_table_ini
15951 + }
15952 +
15953 + paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
15954 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15955 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
15956 ++#else
15957 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
15958 ++#endif
15959 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
15960 + }
15961 +
15962 +@@ -122,6 +101,7 @@ page_table_range_init(unsigned long star
15963 + int pgd_idx, pmd_idx;
15964 + unsigned long vaddr;
15965 + pgd_t *pgd;
15966 ++ pud_t *pud;
15967 + pmd_t *pmd;
15968 +
15969 + vaddr = start;
15970 +@@ -130,8 +110,13 @@ page_table_range_init(unsigned long star
15971 + pgd = pgd_base + pgd_idx;
15972 +
15973 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
15974 +- pmd = one_md_table_init(pgd);
15975 +- pmd = pmd + pmd_index(vaddr);
15976 ++ pud = pud_offset(pgd, vaddr);
15977 ++ pmd = pmd_offset(pud, vaddr);
15978 ++
15979 ++#ifdef CONFIG_X86_PAE
15980 ++ paravirt_alloc_pd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
15981 ++#endif
15982 ++
15983 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
15984 + pmd++, pmd_idx++) {
15985 + one_page_table_init(pmd);
15986 +@@ -142,11 +127,23 @@ page_table_range_init(unsigned long star
15987 + }
15988 + }
15989 +
15990 +-static inline int is_kernel_text(unsigned long addr)
15991 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
15992 + {
15993 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
15994 +- return 1;
15995 +- return 0;
15996 ++ unsigned long etext;
15997 ++
15998 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
15999 ++ etext = ktva_ktla((unsigned long)&MODULES_END);
16000 ++#else
16001 ++ etext = (unsigned long)&_etext;
16002 ++#endif
16003 ++
16004 ++ if ((start > ktla_ktva(etext) ||
16005 ++ end <= ktla_ktva((unsigned long)_stext)) &&
16006 ++ (start > ktla_ktva((unsigned long)_einittext) ||
16007 ++ end <= ktla_ktva((unsigned long)_sinittext)) &&
16008 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
16009 ++ return 0;
16010 ++ return 1;
16011 + }
16012 +
16013 + /*
16014 +@@ -156,9 +153,10 @@ static inline int is_kernel_text(unsigne
16015 + */
16016 + static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
16017 + {
16018 +- int pgd_idx, pmd_idx, pte_ofs;
16019 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
16020 + unsigned long pfn;
16021 + pgd_t *pgd;
16022 ++ pud_t *pud;
16023 + pmd_t *pmd;
16024 + pte_t *pte;
16025 +
16026 +@@ -166,29 +164,27 @@ static void __init kernel_physical_mappi
16027 + pgd = pgd_base + pgd_idx;
16028 + pfn = 0;
16029 +
16030 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
16031 +- pmd = one_md_table_init(pgd);
16032 +- if (pfn >= max_low_pfn)
16033 +- continue;
16034 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
16035 ++ pud = pud_offset(pgd, 0);
16036 ++ pmd = pmd_offset(pud, 0);
16037 ++
16038 ++#ifdef CONFIG_X86_PAE
16039 ++ paravirt_alloc_pd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
16040 ++#endif
16041 +
16042 + for (pmd_idx = 0;
16043 + pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn;
16044 + pmd++, pmd_idx++) {
16045 +- unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
16046 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
16047 +
16048 + /*
16049 + * Map with big pages if possible, otherwise
16050 + * create normal page tables:
16051 + */
16052 +- if (cpu_has_pse) {
16053 +- unsigned int addr2;
16054 ++ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
16055 + pgprot_t prot = PAGE_KERNEL_LARGE;
16056 +
16057 +- addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
16058 +- PAGE_OFFSET + PAGE_SIZE-1;
16059 +-
16060 +- if (is_kernel_text(addr) ||
16061 +- is_kernel_text(addr2))
16062 ++ if (is_kernel_text(address, address + PMD_SIZE))
16063 + prot = PAGE_KERNEL_LARGE_EXEC;
16064 +
16065 + set_pmd(pmd, pfn_pmd(pfn, prot));
16066 +@@ -200,10 +196,10 @@ static void __init kernel_physical_mappi
16067 +
16068 + for (pte_ofs = 0;
16069 + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
16070 +- pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
16071 ++ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
16072 + pgprot_t prot = PAGE_KERNEL;
16073 +
16074 +- if (is_kernel_text(addr))
16075 ++ if (is_kernel_text(address, address + PAGE_SIZE))
16076 + prot = PAGE_KERNEL_EXEC;
16077 +
16078 + set_pte(pte, pfn_pte(pfn, prot));
16079 +@@ -323,10 +319,10 @@ static void __init set_highmem_pages_ini
16080 + # define set_highmem_pages_init(bad_ppro) do { } while (0)
16081 + #endif /* CONFIG_HIGHMEM */
16082 +
16083 +-pteval_t __PAGE_KERNEL = _PAGE_KERNEL;
16084 ++pteval_t __PAGE_KERNEL __read_only = _PAGE_KERNEL;
16085 + EXPORT_SYMBOL(__PAGE_KERNEL);
16086 +
16087 +-pteval_t __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
16088 ++pteval_t __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
16089 +
16090 + void __init native_pagetable_setup_start(pgd_t *base)
16091 + {
16092 +@@ -348,7 +344,7 @@ void __init native_pagetable_setup_start
16093 +
16094 + pud = pud_offset(pgd, va);
16095 + pmd = pmd_offset(pud, va);
16096 +- if (!pmd_present(*pmd))
16097 ++ if (!pmd_present(*pmd) || pmd_huge(*pmd))
16098 + break;
16099 +
16100 + pte = pte_offset_kernel(pmd, va);
16101 +@@ -424,12 +420,12 @@ static void __init pagetable_init(void)
16102 + * ACPI suspend needs this for resume, because things like the intel-agp
16103 + * driver might have split up a kernel 4MB mapping.
16104 + */
16105 +-char swsusp_pg_dir[PAGE_SIZE]
16106 ++pgd_t swsusp_pg_dir[PTRS_PER_PGD]
16107 + __attribute__ ((aligned(PAGE_SIZE)));
16108 +
16109 + static inline void save_pg_dir(void)
16110 + {
16111 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
16112 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
16113 + }
16114 + #else /* !CONFIG_ACPI_SLEEP */
16115 + static inline void save_pg_dir(void)
16116 +@@ -461,13 +457,11 @@ void zap_low_mappings(void)
16117 +
16118 + int nx_enabled;
16119 +
16120 +-pteval_t __supported_pte_mask __read_mostly = ~_PAGE_NX;
16121 ++pteval_t __supported_pte_mask __read_only = ~_PAGE_NX;
16122 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
16123 +
16124 + #ifdef CONFIG_X86_PAE
16125 +
16126 +-static int disable_nx __initdata;
16127 +-
16128 + /*
16129 + * noexec = on|off
16130 + *
16131 +@@ -476,40 +470,33 @@ static int disable_nx __initdata;
16132 + * on Enable
16133 + * off Disable
16134 + */
16135 ++#if !defined(CONFIG_PAX_PAGEEXEC)
16136 + static int __init noexec_setup(char *str)
16137 + {
16138 + if (!str || !strcmp(str, "on")) {
16139 +- if (cpu_has_nx) {
16140 +- __supported_pte_mask |= _PAGE_NX;
16141 +- disable_nx = 0;
16142 +- }
16143 ++ if (cpu_has_nx)
16144 ++ nx_enabled = 1;
16145 + } else {
16146 +- if (!strcmp(str, "off")) {
16147 +- disable_nx = 1;
16148 +- __supported_pte_mask &= ~_PAGE_NX;
16149 +- } else {
16150 ++ if (!strcmp(str, "off"))
16151 ++ nx_enabled = 0;
16152 ++ else
16153 + return -EINVAL;
16154 +- }
16155 + }
16156 +
16157 + return 0;
16158 + }
16159 + early_param("noexec", noexec_setup);
16160 ++#endif
16161 +
16162 + static void __init set_nx(void)
16163 + {
16164 +- unsigned int v[4], l, h;
16165 +-
16166 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
16167 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
16168 ++ if (!nx_enabled && cpu_has_nx) {
16169 ++ unsigned l, h;
16170 +
16171 +- if ((v[3] & (1 << 20)) && !disable_nx) {
16172 +- rdmsr(MSR_EFER, l, h);
16173 +- l |= EFER_NX;
16174 +- wrmsr(MSR_EFER, l, h);
16175 +- nx_enabled = 1;
16176 +- __supported_pte_mask |= _PAGE_NX;
16177 +- }
16178 ++ __supported_pte_mask &= ~_PAGE_NX;
16179 ++ rdmsr(MSR_EFER, l, h);
16180 ++ l &= ~EFER_NX;
16181 ++ wrmsr(MSR_EFER, l, h);
16182 + }
16183 + }
16184 + #endif
16185 +@@ -601,7 +588,7 @@ void __init mem_init(void)
16186 + set_highmem_pages_init(bad_ppro);
16187 +
16188 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
16189 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
16190 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
16191 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
16192 +
16193 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
16194 +@@ -648,10 +635,10 @@ void __init mem_init(void)
16195 + ((unsigned long)&__init_end -
16196 + (unsigned long)&__init_begin) >> 10,
16197 +
16198 +- (unsigned long)&_etext, (unsigned long)&_edata,
16199 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
16200 ++ (unsigned long)&_data, (unsigned long)&_edata,
16201 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
16202 +
16203 +- (unsigned long)&_text, (unsigned long)&_etext,
16204 ++ ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
16205 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
16206 +
16207 + #ifdef CONFIG_HIGHMEM
16208 +@@ -794,6 +781,46 @@ void free_init_pages(char *what, unsigne
16209 +
16210 + void free_initmem(void)
16211 + {
16212 ++
16213 ++#ifdef CONFIG_PAX_KERNEXEC
16214 ++ /* PaX: limit KERNEL_CS to actual size */
16215 ++ unsigned long addr, limit;
16216 ++ struct desc_struct d;
16217 ++ int cpu;
16218 ++ pgd_t *pgd;
16219 ++ pud_t *pud;
16220 ++ pmd_t *pmd;
16221 ++
16222 ++#ifdef CONFIG_MODULES
16223 ++ limit = ktva_ktla((unsigned long)&MODULES_END);
16224 ++#else
16225 ++ limit = (unsigned long)&_etext;
16226 ++#endif
16227 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
16228 ++
16229 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
16230 ++ pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
16231 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
16232 ++ }
16233 ++
16234 ++ /* PaX: make KERNEL_CS read-only */
16235 ++ for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
16236 ++ pgd = pgd_offset_k(addr);
16237 ++ pud = pud_offset(pgd, addr);
16238 ++ pmd = pmd_offset(pud, addr);
16239 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
16240 ++ }
16241 ++#ifdef CONFIG_X86_PAE
16242 ++ for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
16243 ++ pgd = pgd_offset_k(addr);
16244 ++ pud = pud_offset(pgd, addr);
16245 ++ pmd = pmd_offset(pud, addr);
16246 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
16247 ++ }
16248 ++#endif
16249 ++ flush_tlb_all();
16250 ++#endif
16251 ++
16252 + free_init_pages("unused kernel memory",
16253 + (unsigned long)(&__init_begin),
16254 + (unsigned long)(&__init_end));
16255 +diff -urNp a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
16256 +--- a/arch/x86/mm/init_64.c 2008-08-20 11:16:13.000000000 -0700
16257 ++++ b/arch/x86/mm/init_64.c 2008-08-20 18:36:57.000000000 -0700
16258 +@@ -129,6 +129,10 @@ set_pte_phys(unsigned long vaddr, unsign
16259 + pmd_t *pmd;
16260 + pte_t *pte, new_pte;
16261 +
16262 ++#ifdef CONFIG_PAX_KERNEXEC
16263 ++ unsigned long cr0;
16264 ++#endif
16265 ++
16266 + pr_debug("set_pte_phys %lx to %lx\n", vaddr, phys);
16267 +
16268 + pgd = pgd_offset_k(vaddr);
16269 +@@ -140,7 +144,7 @@ set_pte_phys(unsigned long vaddr, unsign
16270 + pud = pud_offset(pgd, vaddr);
16271 + if (pud_none(*pud)) {
16272 + pmd = (pmd_t *) spp_getpage();
16273 +- set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
16274 ++ set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
16275 + if (pmd != pmd_offset(pud, 0)) {
16276 + printk(KERN_ERR "PAGETABLE BUG #01! %p <-> %p\n",
16277 + pmd, pmd_offset(pud, 0));
16278 +@@ -150,7 +154,7 @@ set_pte_phys(unsigned long vaddr, unsign
16279 + pmd = pmd_offset(pud, vaddr);
16280 + if (pmd_none(*pmd)) {
16281 + pte = (pte_t *) spp_getpage();
16282 +- set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
16283 ++ set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
16284 + if (pte != pte_offset_kernel(pmd, 0)) {
16285 + printk(KERN_ERR "PAGETABLE BUG #02!\n");
16286 + return;
16287 +@@ -162,8 +166,17 @@ set_pte_phys(unsigned long vaddr, unsign
16288 + if (!pte_none(*pte) &&
16289 + pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
16290 + pte_ERROR(*pte);
16291 ++
16292 ++#ifdef CONFIG_PAX_KERNEXEC
16293 ++ pax_open_kernel(cr0);
16294 ++#endif
16295 ++
16296 + set_pte(pte, new_pte);
16297 +
16298 ++#ifdef CONFIG_PAX_KERNEXEC
16299 ++ pax_close_kernel(cr0);
16300 ++#endif
16301 ++
16302 + /*
16303 + * It's enough to flush this one mapping.
16304 + * (PGE mappings get flushed as well)
16305 +@@ -585,6 +598,39 @@ void free_init_pages(char *what, unsigne
16306 +
16307 + void free_initmem(void)
16308 + {
16309 ++
16310 ++#ifdef CONFIG_PAX_KERNEXEC
16311 ++ unsigned long addr, end;
16312 ++ pgd_t *pgd;
16313 ++ pud_t *pud;
16314 ++ pmd_t *pmd;
16315 ++
16316 ++ /* PaX: make kernel code/rodata read-only, rest non-executable */
16317 ++ for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
16318 ++ pgd = pgd_offset_k(addr);
16319 ++ pud = pud_offset(pgd, addr);
16320 ++ pmd = pmd_offset(pud, addr);
16321 ++ if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
16322 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
16323 ++ else
16324 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
16325 ++ }
16326 ++
16327 ++ addr = (unsigned long)__va(__pa(__START_KERNEL_map));
16328 ++ end = addr + KERNEL_IMAGE_SIZE;
16329 ++ for (; addr < end; addr += PMD_SIZE) {
16330 ++ pgd = pgd_offset_k(addr);
16331 ++ pud = pud_offset(pgd, addr);
16332 ++ pmd = pmd_offset(pud, addr);
16333 ++ if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
16334 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
16335 ++ else
16336 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
16337 ++ }
16338 ++
16339 ++ flush_tlb_all();
16340 ++#endif
16341 ++
16342 + free_init_pages("unused kernel memory",
16343 + (unsigned long)(&__init_begin),
16344 + (unsigned long)(&__init_end));
16345 +@@ -753,7 +799,7 @@ int in_gate_area_no_task(unsigned long a
16346 +
16347 + const char *arch_vma_name(struct vm_area_struct *vma)
16348 + {
16349 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
16350 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
16351 + return "[vdso]";
16352 + if (vma == &gate_vma)
16353 + return "[vsyscall]";
16354 +diff -urNp a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
16355 +--- a/arch/x86/mm/ioremap.c 2008-08-20 11:16:13.000000000 -0700
16356 ++++ b/arch/x86/mm/ioremap.c 2008-08-20 18:36:57.000000000 -0700
16357 +@@ -149,6 +149,8 @@ static void __iomem *__ioremap(resource_
16358 + break;
16359 + }
16360 +
16361 ++ prot = canon_pgprot(prot);
16362 ++
16363 + /*
16364 + * Mappings have to be page-aligned
16365 + */
16366 +diff -urNp a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
16367 +--- a/arch/x86/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
16368 ++++ b/arch/x86/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
16369 +@@ -36,7 +36,7 @@
16370 + * Leave an at least ~128 MB hole.
16371 + */
16372 + #define MIN_GAP (128*1024*1024)
16373 +-#define MAX_GAP (TASK_SIZE/6*5)
16374 ++#define MAX_GAP (pax_task_size/6*5)
16375 +
16376 + /*
16377 + * True on X86_32 or when emulating IA32 on X86_64
16378 +@@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
16379 + return rnd << PAGE_SHIFT;
16380 + }
16381 +
16382 +-static unsigned long mmap_base(void)
16383 ++static unsigned long mmap_base(struct mm_struct *mm)
16384 + {
16385 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
16386 ++ unsigned long pax_task_size = TASK_SIZE;
16387 ++
16388 ++#ifdef CONFIG_PAX_SEGMEXEC
16389 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
16390 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
16391 ++#endif
16392 +
16393 + if (gap < MIN_GAP)
16394 + gap = MIN_GAP;
16395 + else if (gap > MAX_GAP)
16396 + gap = MAX_GAP;
16397 +
16398 +- return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
16399 ++ return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
16400 + }
16401 +
16402 + /*
16403 + * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
16404 + * does, but not when emulating X86_32
16405 + */
16406 +-static unsigned long mmap_legacy_base(void)
16407 ++static unsigned long mmap_legacy_base(struct mm_struct *mm)
16408 + {
16409 +- if (mmap_is_ia32())
16410 ++ if (mmap_is_ia32()) {
16411 ++
16412 ++#ifdef CONFIG_PAX_SEGMEXEC
16413 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
16414 ++ return SEGMEXEC_TASK_UNMAPPED_BASE;
16415 ++ else
16416 ++#endif
16417 ++
16418 + return TASK_UNMAPPED_BASE;
16419 +- else
16420 ++ } else
16421 + return TASK_UNMAPPED_BASE + mmap_rnd();
16422 + }
16423 +
16424 +@@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
16425 + void arch_pick_mmap_layout(struct mm_struct *mm)
16426 + {
16427 + if (mmap_is_legacy()) {
16428 +- mm->mmap_base = mmap_legacy_base();
16429 ++ mm->mmap_base = mmap_legacy_base(mm);
16430 ++
16431 ++#ifdef CONFIG_PAX_RANDMMAP
16432 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16433 ++ mm->mmap_base += mm->delta_mmap;
16434 ++#endif
16435 ++
16436 + mm->get_unmapped_area = arch_get_unmapped_area;
16437 + mm->unmap_area = arch_unmap_area;
16438 + } else {
16439 +- mm->mmap_base = mmap_base();
16440 ++ mm->mmap_base = mmap_base(mm);
16441 ++
16442 ++#ifdef CONFIG_PAX_RANDMMAP
16443 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16444 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
16445 ++#endif
16446 ++
16447 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
16448 + mm->unmap_area = arch_unmap_area_topdown;
16449 + }
16450 +diff -urNp a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
16451 +--- a/arch/x86/mm/numa_64.c 2008-08-20 11:16:13.000000000 -0700
16452 ++++ b/arch/x86/mm/numa_64.c 2008-08-20 18:36:57.000000000 -0700
16453 +@@ -21,7 +21,7 @@
16454 + #include <asm/k8.h>
16455 +
16456 + #ifndef Dprintk
16457 +-#define Dprintk(x...)
16458 ++#define Dprintk(x...) do {} while (0)
16459 + #endif
16460 +
16461 + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
16462 +diff -urNp a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
16463 +--- a/arch/x86/mm/pageattr.c 2008-08-20 11:16:13.000000000 -0700
16464 ++++ b/arch/x86/mm/pageattr.c 2008-08-20 18:36:57.000000000 -0700
16465 +@@ -17,6 +17,7 @@
16466 + #include <asm/uaccess.h>
16467 + #include <asm/pgalloc.h>
16468 + #include <asm/proto.h>
16469 ++#include <asm/desc.h>
16470 +
16471 + /*
16472 + * The current flushing context - we pass it instead of 5 arguments:
16473 +@@ -168,7 +169,7 @@ static inline pgprot_t static_protection
16474 + * Does not cover __inittext since that is gone later on. On
16475 + * 64bit we do not enforce !NX on the low mapping
16476 + */
16477 +- if (within(address, (unsigned long)_text, (unsigned long)_etext))
16478 ++ if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
16479 + pgprot_val(forbidden) |= _PAGE_NX;
16480 +
16481 + /*
16482 +@@ -229,8 +230,20 @@ pte_t *lookup_address(unsigned long addr
16483 + */
16484 + static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
16485 + {
16486 ++
16487 ++#ifdef CONFIG_PAX_KERNEXEC
16488 ++ unsigned long cr0;
16489 ++
16490 ++ pax_open_kernel(cr0);
16491 ++#endif
16492 ++
16493 + /* change init_mm */
16494 + set_pte_atomic(kpte, pte);
16495 ++
16496 ++#ifdef CONFIG_PAX_KERNEXEC
16497 ++ pax_close_kernel(cr0);
16498 ++#endif
16499 ++
16500 + #ifdef CONFIG_X86_32
16501 + if (!SHARED_KERNEL_PMD) {
16502 + struct page *page;
16503 +diff -urNp a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
16504 +--- a/arch/x86/mm/pgtable_32.c 2008-08-20 11:16:13.000000000 -0700
16505 ++++ b/arch/x86/mm/pgtable_32.c 2008-08-20 18:36:57.000000000 -0700
16506 +@@ -83,6 +83,10 @@ static void set_pte_pfn(unsigned long va
16507 + pmd_t *pmd;
16508 + pte_t *pte;
16509 +
16510 ++#ifdef CONFIG_PAX_KERNEXEC
16511 ++ unsigned long cr0;
16512 ++#endif
16513 ++
16514 + pgd = swapper_pg_dir + pgd_index(vaddr);
16515 + if (pgd_none(*pgd)) {
16516 + BUG();
16517 +@@ -99,11 +103,20 @@ static void set_pte_pfn(unsigned long va
16518 + return;
16519 + }
16520 + pte = pte_offset_kernel(pmd, vaddr);
16521 ++
16522 ++#ifdef CONFIG_PAX_KERNEXEC
16523 ++ pax_open_kernel(cr0);
16524 ++#endif
16525 ++
16526 + if (pgprot_val(flags))
16527 + set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
16528 + else
16529 + pte_clear(&init_mm, vaddr, pte);
16530 +
16531 ++#ifdef CONFIG_PAX_KERNEXEC
16532 ++ pax_close_kernel(cr0);
16533 ++#endif
16534 ++
16535 + /*
16536 + * It's enough to flush this one mapping.
16537 + * (PGE mappings get flushed as well)
16538 +diff -urNp a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
16539 +--- a/arch/x86/oprofile/backtrace.c 2008-08-20 11:16:13.000000000 -0700
16540 ++++ b/arch/x86/oprofile/backtrace.c 2008-08-20 18:36:57.000000000 -0700
16541 +@@ -37,7 +37,7 @@ static void backtrace_address(void *data
16542 + unsigned int *depth = data;
16543 +
16544 + if ((*depth)--)
16545 +- oprofile_add_trace(addr);
16546 ++ oprofile_add_trace(ktla_ktva(addr));
16547 + }
16548 +
16549 + static struct stacktrace_ops backtrace_ops = {
16550 +@@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
16551 + struct frame_head *head = (struct frame_head *)frame_pointer(regs);
16552 + unsigned long stack = kernel_trap_sp(regs);
16553 +
16554 +- if (!user_mode_vm(regs)) {
16555 ++ if (!user_mode(regs)) {
16556 + if (depth)
16557 + dump_trace(NULL, regs, (unsigned long *)stack, 0,
16558 + &backtrace_ops, &depth);
16559 +diff -urNp a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
16560 +--- a/arch/x86/oprofile/op_model_p4.c 2008-08-20 11:16:13.000000000 -0700
16561 ++++ b/arch/x86/oprofile/op_model_p4.c 2008-08-20 18:36:57.000000000 -0700
16562 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
16563 + #endif
16564 + }
16565 +
16566 +-static int inline addr_increment(void)
16567 ++static inline int addr_increment(void)
16568 + {
16569 + #ifdef CONFIG_SMP
16570 + return smp_num_siblings == 2 ? 2 : 1;
16571 +diff -urNp a/arch/x86/pci/common.c b/arch/x86/pci/common.c
16572 +--- a/arch/x86/pci/common.c 2008-08-20 11:16:13.000000000 -0700
16573 ++++ b/arch/x86/pci/common.c 2008-08-20 18:36:57.000000000 -0700
16574 +@@ -352,7 +352,7 @@ static struct dmi_system_id __devinitdat
16575 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
16576 + },
16577 + },
16578 +- {}
16579 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
16580 + };
16581 +
16582 + void __init dmi_check_pciprobe(void)
16583 +diff -urNp a/arch/x86/pci/early.c b/arch/x86/pci/early.c
16584 +--- a/arch/x86/pci/early.c 2008-08-20 11:16:13.000000000 -0700
16585 ++++ b/arch/x86/pci/early.c 2008-08-20 18:36:57.000000000 -0700
16586 +@@ -7,7 +7,7 @@
16587 + /* Direct PCI access. This is used for PCI accesses in early boot before
16588 + the PCI subsystem works. */
16589 +
16590 +-#define PDprintk(x...)
16591 ++#define PDprintk(x...) do {} while (0)
16592 +
16593 + u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
16594 + {
16595 +diff -urNp a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c
16596 +--- a/arch/x86/pci/fixup.c 2008-08-20 11:16:13.000000000 -0700
16597 ++++ b/arch/x86/pci/fixup.c 2008-08-20 18:36:57.000000000 -0700
16598 +@@ -364,7 +364,7 @@ static struct dmi_system_id __devinitdat
16599 + DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
16600 + },
16601 + },
16602 +- {}
16603 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
16604 + };
16605 +
16606 + /*
16607 +@@ -435,7 +435,7 @@ static struct dmi_system_id __devinitdat
16608 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
16609 + },
16610 + },
16611 +- { }
16612 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
16613 + };
16614 +
16615 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
16616 +diff -urNp a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
16617 +--- a/arch/x86/pci/irq.c 2008-08-20 11:16:13.000000000 -0700
16618 ++++ b/arch/x86/pci/irq.c 2008-08-20 18:36:57.000000000 -0700
16619 +@@ -540,7 +540,7 @@ static __init int intel_router_probe(str
16620 + static struct pci_device_id __initdata pirq_440gx[] = {
16621 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
16622 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
16623 +- { },
16624 ++ { PCI_DEVICE(0, 0) }
16625 + };
16626 +
16627 + /* 440GX has a proprietary PIRQ router -- don't use it */
16628 +@@ -1106,7 +1106,7 @@ static struct dmi_system_id __initdata p
16629 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
16630 + },
16631 + },
16632 +- { }
16633 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
16634 + };
16635 +
16636 + static int __init pcibios_irq_init(void)
16637 +diff -urNp a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
16638 +--- a/arch/x86/pci/pcbios.c 2008-08-20 11:16:13.000000000 -0700
16639 ++++ b/arch/x86/pci/pcbios.c 2008-08-20 18:36:57.000000000 -0700
16640 +@@ -57,50 +57,120 @@ union bios32 {
16641 + static struct {
16642 + unsigned long address;
16643 + unsigned short segment;
16644 +-} bios32_indirect = { 0, __KERNEL_CS };
16645 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
16646 +
16647 + /*
16648 + * Returns the entry point for the given service, NULL on error
16649 + */
16650 +
16651 +-static unsigned long bios32_service(unsigned long service)
16652 ++static unsigned long __devinit bios32_service(unsigned long service)
16653 + {
16654 + unsigned char return_code; /* %al */
16655 + unsigned long address; /* %ebx */
16656 + unsigned long length; /* %ecx */
16657 + unsigned long entry; /* %edx */
16658 + unsigned long flags;
16659 ++ struct desc_struct d, *gdt;
16660 ++
16661 ++#ifdef CONFIG_PAX_KERNEXEC
16662 ++ unsigned long cr0;
16663 ++#endif
16664 +
16665 + local_irq_save(flags);
16666 +- __asm__("lcall *(%%edi); cld"
16667 ++
16668 ++ gdt = get_cpu_gdt_table(smp_processor_id());
16669 ++
16670 ++#ifdef CONFIG_PAX_KERNEXEC
16671 ++ pax_open_kernel(cr0);
16672 ++#endif
16673 ++
16674 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
16675 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
16676 ++ pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
16677 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
16678 ++
16679 ++#ifdef CONFIG_PAX_KERNEXEC
16680 ++ pax_close_kernel(cr0);
16681 ++#endif
16682 ++
16683 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
16684 + : "=a" (return_code),
16685 + "=b" (address),
16686 + "=c" (length),
16687 + "=d" (entry)
16688 + : "0" (service),
16689 + "1" (0),
16690 +- "D" (&bios32_indirect));
16691 ++ "D" (&bios32_indirect),
16692 ++ "r"(__PCIBIOS_DS)
16693 ++ : "memory");
16694 ++
16695 ++#ifdef CONFIG_PAX_KERNEXEC
16696 ++ pax_open_kernel(cr0);
16697 ++#endif
16698 ++
16699 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
16700 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
16701 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
16702 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
16703 ++
16704 ++#ifdef CONFIG_PAX_KERNEXEC
16705 ++ pax_close_kernel(cr0);
16706 ++#endif
16707 ++
16708 + local_irq_restore(flags);
16709 +
16710 + switch (return_code) {
16711 +- case 0:
16712 +- return address + entry;
16713 +- case 0x80: /* Not present */
16714 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
16715 +- return 0;
16716 +- default: /* Shouldn't happen */
16717 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
16718 +- service, return_code);
16719 ++ case 0: {
16720 ++ int cpu;
16721 ++ unsigned char flags;
16722 ++
16723 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
16724 ++ if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
16725 ++ printk(KERN_WARNING "bios32_service: not valid\n");
16726 + return 0;
16727 ++ }
16728 ++ address = address + PAGE_OFFSET;
16729 ++ length += 16UL; /* some BIOSs underreport this... */
16730 ++ flags = 4;
16731 ++ if (length >= 64*1024*1024) {
16732 ++ length >>= PAGE_SHIFT;
16733 ++ flags |= 8;
16734 ++ }
16735 ++
16736 ++#ifdef CONFIG_PAX_KERNEXEC
16737 ++ pax_open_kernel(cr0);
16738 ++#endif
16739 ++
16740 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
16741 ++ gdt = get_cpu_gdt_table(cpu);
16742 ++ pack_descriptor(&d, address, length, 0x9b, flags);
16743 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
16744 ++ pack_descriptor(&d, address, length, 0x93, flags);
16745 ++ write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
16746 ++ }
16747 ++
16748 ++#ifdef CONFIG_PAX_KERNEXEC
16749 ++ pax_close_kernel(cr0);
16750 ++#endif
16751 ++
16752 ++ return entry;
16753 ++ }
16754 ++ case 0x80: /* Not present */
16755 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
16756 ++ return 0;
16757 ++ default: /* Shouldn't happen */
16758 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
16759 ++ service, return_code);
16760 ++ return 0;
16761 + }
16762 + }
16763 +
16764 + static struct {
16765 + unsigned long address;
16766 + unsigned short segment;
16767 +-} pci_indirect = { 0, __KERNEL_CS };
16768 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
16769 +
16770 +-static int pci_bios_present;
16771 ++static int pci_bios_present __read_only;
16772 +
16773 + static int __devinit check_pcibios(void)
16774 + {
16775 +@@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
16776 + unsigned long flags, pcibios_entry;
16777 +
16778 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
16779 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
16780 ++ pci_indirect.address = pcibios_entry;
16781 +
16782 + local_irq_save(flags);
16783 +- __asm__(
16784 +- "lcall *(%%edi); cld\n\t"
16785 ++ __asm__("movw %w6, %%ds\n\t"
16786 ++ "lcall *%%ss:(%%edi); cld\n\t"
16787 ++ "push %%ss\n\t"
16788 ++ "pop %%ds\n\t"
16789 + "jc 1f\n\t"
16790 + "xor %%ah, %%ah\n"
16791 + "1:"
16792 +@@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
16793 + "=b" (ebx),
16794 + "=c" (ecx)
16795 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
16796 +- "D" (&pci_indirect)
16797 ++ "D" (&pci_indirect),
16798 ++ "r" (__PCIBIOS_DS)
16799 + : "memory");
16800 + local_irq_restore(flags);
16801 +
16802 +@@ -158,7 +231,10 @@ static int __devinit pci_bios_find_devic
16803 + unsigned short bx;
16804 + unsigned short ret;
16805 +
16806 +- __asm__("lcall *(%%edi); cld\n\t"
16807 ++ __asm__("movw %w7, %%ds\n\t"
16808 ++ "lcall *%%ss:(%%edi); cld\n\t"
16809 ++ "push %%ss\n\t"
16810 ++ "pop %%ds\n\t"
16811 + "jc 1f\n\t"
16812 + "xor %%ah, %%ah\n"
16813 + "1:"
16814 +@@ -168,7 +244,8 @@ static int __devinit pci_bios_find_devic
16815 + "c" (device_id),
16816 + "d" (vendor),
16817 + "S" ((int) index),
16818 +- "D" (&pci_indirect));
16819 ++ "D" (&pci_indirect),
16820 ++ "r" (__PCIBIOS_DS));
16821 + *bus = (bx >> 8) & 0xff;
16822 + *device_fn = bx & 0xff;
16823 + return (int) (ret & 0xff00) >> 8;
16824 +@@ -188,7 +265,10 @@ static int pci_bios_read(unsigned int se
16825 +
16826 + switch (len) {
16827 + case 1:
16828 +- __asm__("lcall *(%%esi); cld\n\t"
16829 ++ __asm__("movw %w6, %%ds\n\t"
16830 ++ "lcall *%%ss:(%%esi); cld\n\t"
16831 ++ "push %%ss\n\t"
16832 ++ "pop %%ds\n\t"
16833 + "jc 1f\n\t"
16834 + "xor %%ah, %%ah\n"
16835 + "1:"
16836 +@@ -197,7 +277,8 @@ static int pci_bios_read(unsigned int se
16837 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
16838 + "b" (bx),
16839 + "D" ((long)reg),
16840 +- "S" (&pci_indirect));
16841 ++ "S" (&pci_indirect),
16842 ++ "r" (__PCIBIOS_DS));
16843 + /*
16844 + * Zero-extend the result beyond 8 bits, do not trust the
16845 + * BIOS having done it:
16846 +@@ -205,7 +286,10 @@ static int pci_bios_read(unsigned int se
16847 + *value &= 0xff;
16848 + break;
16849 + case 2:
16850 +- __asm__("lcall *(%%esi); cld\n\t"
16851 ++ __asm__("movw %w6, %%ds\n\t"
16852 ++ "lcall *%%ss:(%%esi); cld\n\t"
16853 ++ "push %%ss\n\t"
16854 ++ "pop %%ds\n\t"
16855 + "jc 1f\n\t"
16856 + "xor %%ah, %%ah\n"
16857 + "1:"
16858 +@@ -214,7 +298,8 @@ static int pci_bios_read(unsigned int se
16859 + : "1" (PCIBIOS_READ_CONFIG_WORD),
16860 + "b" (bx),
16861 + "D" ((long)reg),
16862 +- "S" (&pci_indirect));
16863 ++ "S" (&pci_indirect),
16864 ++ "r" (__PCIBIOS_DS));
16865 + /*
16866 + * Zero-extend the result beyond 16 bits, do not trust the
16867 + * BIOS having done it:
16868 +@@ -222,7 +307,10 @@ static int pci_bios_read(unsigned int se
16869 + *value &= 0xffff;
16870 + break;
16871 + case 4:
16872 +- __asm__("lcall *(%%esi); cld\n\t"
16873 ++ __asm__("movw %w6, %%ds\n\t"
16874 ++ "lcall *%%ss:(%%esi); cld\n\t"
16875 ++ "push %%ss\n\t"
16876 ++ "pop %%ds\n\t"
16877 + "jc 1f\n\t"
16878 + "xor %%ah, %%ah\n"
16879 + "1:"
16880 +@@ -231,7 +319,8 @@ static int pci_bios_read(unsigned int se
16881 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
16882 + "b" (bx),
16883 + "D" ((long)reg),
16884 +- "S" (&pci_indirect));
16885 ++ "S" (&pci_indirect),
16886 ++ "r" (__PCIBIOS_DS));
16887 + break;
16888 + }
16889 +
16890 +@@ -254,7 +343,10 @@ static int pci_bios_write(unsigned int s
16891 +
16892 + switch (len) {
16893 + case 1:
16894 +- __asm__("lcall *(%%esi); cld\n\t"
16895 ++ __asm__("movw %w6, %%ds\n\t"
16896 ++ "lcall *%%ss:(%%esi); cld\n\t"
16897 ++ "push %%ss\n\t"
16898 ++ "pop %%ds\n\t"
16899 + "jc 1f\n\t"
16900 + "xor %%ah, %%ah\n"
16901 + "1:"
16902 +@@ -263,10 +355,14 @@ static int pci_bios_write(unsigned int s
16903 + "c" (value),
16904 + "b" (bx),
16905 + "D" ((long)reg),
16906 +- "S" (&pci_indirect));
16907 ++ "S" (&pci_indirect),
16908 ++ "r" (__PCIBIOS_DS));
16909 + break;
16910 + case 2:
16911 +- __asm__("lcall *(%%esi); cld\n\t"
16912 ++ __asm__("movw %w6, %%ds\n\t"
16913 ++ "lcall *%%ss:(%%esi); cld\n\t"
16914 ++ "push %%ss\n\t"
16915 ++ "pop %%ds\n\t"
16916 + "jc 1f\n\t"
16917 + "xor %%ah, %%ah\n"
16918 + "1:"
16919 +@@ -275,10 +371,14 @@ static int pci_bios_write(unsigned int s
16920 + "c" (value),
16921 + "b" (bx),
16922 + "D" ((long)reg),
16923 +- "S" (&pci_indirect));
16924 ++ "S" (&pci_indirect),
16925 ++ "r" (__PCIBIOS_DS));
16926 + break;
16927 + case 4:
16928 +- __asm__("lcall *(%%esi); cld\n\t"
16929 ++ __asm__("movw %w6, %%ds\n\t"
16930 ++ "lcall *%%ss:(%%esi); cld\n\t"
16931 ++ "push %%ss\n\t"
16932 ++ "pop %%ds\n\t"
16933 + "jc 1f\n\t"
16934 + "xor %%ah, %%ah\n"
16935 + "1:"
16936 +@@ -287,7 +387,8 @@ static int pci_bios_write(unsigned int s
16937 + "c" (value),
16938 + "b" (bx),
16939 + "D" ((long)reg),
16940 +- "S" (&pci_indirect));
16941 ++ "S" (&pci_indirect),
16942 ++ "r" (__PCIBIOS_DS));
16943 + break;
16944 + }
16945 +
16946 +@@ -440,10 +541,13 @@ struct irq_routing_table * pcibios_get_i
16947 +
16948 + DBG("PCI: Fetching IRQ routing table... ");
16949 + __asm__("push %%es\n\t"
16950 ++ "movw %w8, %%ds\n\t"
16951 + "push %%ds\n\t"
16952 + "pop %%es\n\t"
16953 +- "lcall *(%%esi); cld\n\t"
16954 ++ "lcall *%%ss:(%%esi); cld\n\t"
16955 + "pop %%es\n\t"
16956 ++ "push %%ss\n\t"
16957 ++ "pop %%ds\n"
16958 + "jc 1f\n\t"
16959 + "xor %%ah, %%ah\n"
16960 + "1:"
16961 +@@ -454,7 +558,8 @@ struct irq_routing_table * pcibios_get_i
16962 + "1" (0),
16963 + "D" ((long) &opt),
16964 + "S" (&pci_indirect),
16965 +- "m" (opt)
16966 ++ "m" (opt),
16967 ++ "r" (__PCIBIOS_DS)
16968 + : "memory");
16969 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
16970 + if (ret & 0xff00)
16971 +@@ -478,7 +583,10 @@ int pcibios_set_irq_routing(struct pci_d
16972 + {
16973 + int ret;
16974 +
16975 +- __asm__("lcall *(%%esi); cld\n\t"
16976 ++ __asm__("movw %w5, %%ds\n\t"
16977 ++ "lcall *%%ss:(%%esi); cld\n\t"
16978 ++ "push %%ss\n\t"
16979 ++ "pop %%ds\n"
16980 + "jc 1f\n\t"
16981 + "xor %%ah, %%ah\n"
16982 + "1:"
16983 +@@ -486,7 +594,8 @@ int pcibios_set_irq_routing(struct pci_d
16984 + : "0" (PCIBIOS_SET_PCI_HW_INT),
16985 + "b" ((dev->bus->number << 8) | dev->devfn),
16986 + "c" ((irq << 8) | (pin + 10)),
16987 +- "S" (&pci_indirect));
16988 ++ "S" (&pci_indirect),
16989 ++ "r" (__PCIBIOS_DS));
16990 + return !(ret & 0xff00);
16991 + }
16992 + EXPORT_SYMBOL(pcibios_set_irq_routing);
16993 +diff -urNp a/arch/x86/power/cpu_32.c b/arch/x86/power/cpu_32.c
16994 +--- a/arch/x86/power/cpu_32.c 2008-08-20 11:16:13.000000000 -0700
16995 ++++ b/arch/x86/power/cpu_32.c 2008-08-20 18:36:57.000000000 -0700
16996 +@@ -64,7 +64,7 @@ static void do_fpu_end(void)
16997 + static void fix_processor_context(void)
16998 + {
16999 + int cpu = smp_processor_id();
17000 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
17001 ++ struct tss_struct *t = init_tss + cpu;
17002 +
17003 + 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. */
17004 +
17005 +diff -urNp a/arch/x86/power/cpu_64.c b/arch/x86/power/cpu_64.c
17006 +--- a/arch/x86/power/cpu_64.c 2008-08-20 11:16:13.000000000 -0700
17007 ++++ b/arch/x86/power/cpu_64.c 2008-08-20 18:36:57.000000000 -0700
17008 +@@ -136,7 +136,11 @@ void restore_processor_state(void)
17009 + static void fix_processor_context(void)
17010 + {
17011 + int cpu = smp_processor_id();
17012 +- struct tss_struct *t = &per_cpu(init_tss, cpu);
17013 ++ struct tss_struct *t = init_tss + cpu;
17014 ++
17015 ++#ifdef CONFIG_PAX_KERNEXEC
17016 ++ unsigned long cr0;
17017 ++#endif
17018 +
17019 + /*
17020 + * This just modifies memory; should not be necessary. But... This
17021 +@@ -145,8 +149,16 @@ static void fix_processor_context(void)
17022 + */
17023 + set_tss_desc(cpu, t);
17024 +
17025 ++#ifdef CONFIG_PAX_KERNEXEC
17026 ++ pax_open_kernel(cr0);
17027 ++#endif
17028 ++
17029 + get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
17030 +
17031 ++#ifdef CONFIG_PAX_KERNEXEC
17032 ++ pax_close_kernel(cr0);
17033 ++#endif
17034 ++
17035 + syscall_init(); /* This sets MSR_*STAR and related */
17036 + load_TR_desc(); /* This does ltr */
17037 + load_LDT(&current->active_mm->context); /* This does lldt */
17038 +diff -urNp a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
17039 +--- a/arch/x86/vdso/vdso32-setup.c 2008-08-20 11:16:13.000000000 -0700
17040 ++++ b/arch/x86/vdso/vdso32-setup.c 2008-08-20 18:36:57.000000000 -0700
17041 +@@ -235,7 +235,7 @@ static inline void map_compat_vdso(int m
17042 + void enable_sep_cpu(void)
17043 + {
17044 + int cpu = get_cpu();
17045 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
17046 ++ struct tss_struct *tss = init_tss + cpu;
17047 +
17048 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
17049 + put_cpu();
17050 +@@ -258,7 +258,7 @@ static int __init gate_vma_init(void)
17051 + gate_vma.vm_start = FIXADDR_USER_START;
17052 + gate_vma.vm_end = FIXADDR_USER_END;
17053 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
17054 +- gate_vma.vm_page_prot = __P101;
17055 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
17056 + /*
17057 + * Make sure the vDSO gets into every core dump.
17058 + * Dumping its contents makes post-mortem fully interpretable later
17059 +@@ -336,7 +336,7 @@ int arch_setup_additional_pages(struct l
17060 + if (compat)
17061 + addr = VDSO_HIGH_BASE;
17062 + else {
17063 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
17064 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
17065 + if (IS_ERR_VALUE(addr)) {
17066 + ret = addr;
17067 + goto up_fail;
17068 +@@ -363,7 +363,7 @@ int arch_setup_additional_pages(struct l
17069 + goto up_fail;
17070 + }
17071 +
17072 +- current->mm->context.vdso = (void *)addr;
17073 ++ current->mm->context.vdso = addr;
17074 + current_thread_info()->sysenter_return =
17075 + VDSO32_SYMBOL(addr, SYSENTER_RETURN);
17076 +
17077 +@@ -389,7 +389,7 @@ static ctl_table abi_table2[] = {
17078 + .mode = 0644,
17079 + .proc_handler = proc_dointvec
17080 + },
17081 +- {}
17082 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
17083 + };
17084 +
17085 + static ctl_table abi_root_table2[] = {
17086 +@@ -399,7 +399,7 @@ static ctl_table abi_root_table2[] = {
17087 + .mode = 0555,
17088 + .child = abi_table2
17089 + },
17090 +- {}
17091 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
17092 + };
17093 +
17094 + static __init int ia32_binfmt_init(void)
17095 +@@ -414,8 +414,14 @@ __initcall(ia32_binfmt_init);
17096 +
17097 + const char *arch_vma_name(struct vm_area_struct *vma)
17098 + {
17099 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
17100 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
17101 + return "[vdso]";
17102 ++
17103 ++#ifdef CONFIG_PAX_SEGMEXEC
17104 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
17105 ++ return "[vdso]";
17106 ++#endif
17107 ++
17108 + return NULL;
17109 + }
17110 +
17111 +@@ -424,7 +430,7 @@ struct vm_area_struct *get_gate_vma(stru
17112 + struct mm_struct *mm = tsk->mm;
17113 +
17114 + /* Check to see if this task was created in compat vdso mode */
17115 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
17116 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
17117 + return &gate_vma;
17118 + return NULL;
17119 + }
17120 +diff -urNp a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
17121 +--- a/arch/x86/vdso/vma.c 2008-08-20 11:16:13.000000000 -0700
17122 ++++ b/arch/x86/vdso/vma.c 2008-08-20 18:36:57.000000000 -0700
17123 +@@ -122,7 +122,7 @@ int arch_setup_additional_pages(struct l
17124 + if (ret)
17125 + goto up_fail;
17126 +
17127 +- current->mm->context.vdso = (void *)addr;
17128 ++ current->mm->context.vdso = addr;
17129 + up_fail:
17130 + up_write(&mm->mmap_sem);
17131 + return ret;
17132 +diff -urNp a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
17133 +--- a/arch/x86/xen/enlighten.c 2008-08-20 11:16:13.000000000 -0700
17134 ++++ b/arch/x86/xen/enlighten.c 2008-08-20 18:36:57.000000000 -0700
17135 +@@ -293,7 +293,7 @@ static void xen_set_ldt(const void *addr
17136 + static void xen_load_gdt(const struct desc_ptr *dtr)
17137 + {
17138 + unsigned long *frames;
17139 +- unsigned long va = dtr->address;
17140 ++ unsigned long va = (unsigned long)dtr->address;
17141 + unsigned int size = dtr->size + 1;
17142 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
17143 + int f;
17144 +@@ -308,7 +308,7 @@ static void xen_load_gdt(const struct de
17145 + mcs = xen_mc_entry(sizeof(*frames) * pages);
17146 + frames = mcs.args;
17147 +
17148 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
17149 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
17150 + frames[f] = virt_to_mfn(va);
17151 + make_lowmem_page_readonly((void *)va);
17152 + }
17153 +@@ -401,7 +401,7 @@ static void xen_write_idt_entry(gate_des
17154 +
17155 + preempt_disable();
17156 +
17157 +- start = __get_cpu_var(idt_desc).address;
17158 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
17159 + end = start + __get_cpu_var(idt_desc).size + 1;
17160 +
17161 + xen_mc_flush();
17162 +diff -urNp a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
17163 +--- a/arch/x86/xen/smp.c 2008-08-20 11:16:13.000000000 -0700
17164 ++++ b/arch/x86/xen/smp.c 2008-08-20 18:36:57.000000000 -0700
17165 +@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
17166 +
17167 + /* We've switched to the "real" per-cpu gdt, so make sure the
17168 + old memory can be recycled */
17169 +- make_lowmem_page_readwrite(&per_cpu__gdt_page);
17170 ++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
17171 +
17172 + for_each_possible_cpu(cpu) {
17173 + cpus_clear(per_cpu(cpu_sibling_map, cpu));
17174 +@@ -208,7 +208,7 @@ static __cpuinit int
17175 + cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
17176 + {
17177 + struct vcpu_guest_context *ctxt;
17178 +- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
17179 ++ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
17180 +
17181 + if (cpu_test_and_set(cpu, cpu_initialized_map))
17182 + return 0;
17183 +@@ -218,8 +218,8 @@ cpu_initialize_context(unsigned int cpu,
17184 + return -ENOMEM;
17185 +
17186 + ctxt->flags = VGCF_IN_KERNEL;
17187 +- ctxt->user_regs.ds = __USER_DS;
17188 +- ctxt->user_regs.es = __USER_DS;
17189 ++ ctxt->user_regs.ds = __KERNEL_DS;
17190 ++ ctxt->user_regs.es = __KERNEL_DS;
17191 + ctxt->user_regs.fs = __KERNEL_PERCPU;
17192 + ctxt->user_regs.gs = 0;
17193 + ctxt->user_regs.ss = __KERNEL_DS;
17194 +@@ -232,11 +232,11 @@ cpu_initialize_context(unsigned int cpu,
17195 +
17196 + ctxt->ldt_ents = 0;
17197 +
17198 +- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
17199 +- make_lowmem_page_readonly(gdt->gdt);
17200 ++ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
17201 ++ make_lowmem_page_readonly(gdt);
17202 +
17203 +- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
17204 +- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
17205 ++ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
17206 ++ ctxt->gdt_ents = GDT_ENTRIES;
17207 +
17208 + ctxt->user_regs.cs = __KERNEL_CS;
17209 + ctxt->user_regs.esp = idle->thread.sp0 - sizeof(struct pt_regs);
17210 +diff -urNp a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
17211 +--- a/crypto/async_tx/async_tx.c 2008-08-20 11:16:13.000000000 -0700
17212 ++++ b/crypto/async_tx/async_tx.c 2008-08-20 18:36:57.000000000 -0700
17213 +@@ -341,8 +341,8 @@ async_tx_init(void)
17214 + err:
17215 + printk(KERN_ERR "async_tx: initialization failure\n");
17216 +
17217 +- while (--cap >= 0)
17218 +- free_percpu(channel_table[cap]);
17219 ++ while (cap)
17220 ++ free_percpu(channel_table[--cap]);
17221 +
17222 + return 1;
17223 + }
17224 +diff -urNp a/crypto/lrw.c b/crypto/lrw.c
17225 +--- a/crypto/lrw.c 2008-08-20 11:16:13.000000000 -0700
17226 ++++ b/crypto/lrw.c 2008-08-20 18:36:57.000000000 -0700
17227 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
17228 + struct priv *ctx = crypto_tfm_ctx(parent);
17229 + struct crypto_cipher *child = ctx->child;
17230 + int err, i;
17231 +- be128 tmp = { 0 };
17232 ++ be128 tmp = { 0, 0 };
17233 + int bsize = crypto_cipher_blocksize(child);
17234 +
17235 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
17236 +diff -urNp a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
17237 +--- a/drivers/acpi/blacklist.c 2008-08-20 11:16:13.000000000 -0700
17238 ++++ b/drivers/acpi/blacklist.c 2008-08-20 18:36:57.000000000 -0700
17239 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
17240 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
17241 + "Incorrect _ADR", 1},
17242 +
17243 +- {""}
17244 ++ {"", "", 0, 0, 0, all_versions, 0}
17245 + };
17246 +
17247 + #if CONFIG_ACPI_BLACKLIST_YEAR
17248 +diff -urNp a/drivers/acpi/osl.c b/drivers/acpi/osl.c
17249 +--- a/drivers/acpi/osl.c 2008-08-20 11:16:13.000000000 -0700
17250 ++++ b/drivers/acpi/osl.c 2008-08-20 18:36:57.000000000 -0700
17251 +@@ -489,6 +489,8 @@ acpi_os_read_memory(acpi_physical_addres
17252 + void __iomem *virt_addr;
17253 +
17254 + virt_addr = ioremap(phys_addr, width);
17255 ++ if (!virt_addr)
17256 ++ return AE_NO_MEMORY;
17257 + if (!value)
17258 + value = &dummy;
17259 +
17260 +@@ -517,6 +519,8 @@ acpi_os_write_memory(acpi_physical_addre
17261 + void __iomem *virt_addr;
17262 +
17263 + virt_addr = ioremap(phys_addr, width);
17264 ++ if (!virt_addr)
17265 ++ return AE_NO_MEMORY;
17266 +
17267 + switch (width) {
17268 + case 8:
17269 +diff -urNp a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
17270 +--- a/drivers/acpi/processor_core.c 2008-08-20 11:16:13.000000000 -0700
17271 ++++ b/drivers/acpi/processor_core.c 2008-08-20 18:36:57.000000000 -0700
17272 +@@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_star
17273 + return 0;
17274 + }
17275 +
17276 +- BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
17277 ++ BUG_ON(pr->id >= nr_cpu_ids);
17278 +
17279 + /*
17280 + * Buggy BIOS check
17281 +diff -urNp a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
17282 +--- a/drivers/acpi/processor_idle.c 2008-08-20 11:16:13.000000000 -0700
17283 ++++ b/drivers/acpi/processor_idle.c 2008-08-20 18:36:57.000000000 -0700
17284 +@@ -181,7 +181,7 @@ static struct dmi_system_id __cpuinitdat
17285 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
17286 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
17287 + (void *)2},
17288 +- {},
17289 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
17290 + };
17291 +
17292 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
17293 +diff -urNp a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
17294 +--- a/drivers/acpi/sleep/main.c 2008-08-20 11:16:13.000000000 -0700
17295 ++++ b/drivers/acpi/sleep/main.c 2008-08-20 18:36:57.000000000 -0700
17296 +@@ -250,7 +250,7 @@ static struct dmi_system_id __initdata a
17297 + .ident = "Toshiba Satellite 4030cdt",
17298 + .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
17299 + },
17300 +- {},
17301 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
17302 + };
17303 + #endif /* CONFIG_SUSPEND */
17304 +
17305 +diff -urNp a/drivers/acpi/tables/tbfadt.c b/drivers/acpi/tables/tbfadt.c
17306 +--- a/drivers/acpi/tables/tbfadt.c 2008-08-20 11:16:13.000000000 -0700
17307 ++++ b/drivers/acpi/tables/tbfadt.c 2008-08-20 18:36:57.000000000 -0700
17308 +@@ -48,7 +48,7 @@
17309 + ACPI_MODULE_NAME("tbfadt")
17310 +
17311 + /* Local prototypes */
17312 +-static void inline
17313 ++static inline void
17314 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
17315 + u8 bit_width, u64 address);
17316 +
17317 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
17318 + *
17319 + ******************************************************************************/
17320 +
17321 +-static void inline
17322 ++static inline void
17323 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
17324 + u8 bit_width, u64 address)
17325 + {
17326 +diff -urNp a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
17327 +--- a/drivers/acpi/tables/tbxface.c 2008-08-20 11:16:13.000000000 -0700
17328 ++++ b/drivers/acpi/tables/tbxface.c 2008-08-20 18:36:57.000000000 -0700
17329 +@@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespac
17330 + acpi_tb_print_table_header(0, table);
17331 +
17332 + if (no_auto_ssdt == 0) {
17333 +- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
17334 ++ printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
17335 + }
17336 + }
17337 +
17338 +diff -urNp a/drivers/ata/ahci.c b/drivers/ata/ahci.c
17339 +--- a/drivers/ata/ahci.c 2008-08-20 11:16:13.000000000 -0700
17340 ++++ b/drivers/ata/ahci.c 2008-08-20 18:36:57.000000000 -0700
17341 +@@ -598,7 +598,7 @@ static const struct pci_device_id ahci_p
17342 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
17343 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
17344 +
17345 +- { } /* terminate list */
17346 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17347 + };
17348 +
17349 +
17350 +diff -urNp a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
17351 +--- a/drivers/ata/ata_piix.c 2008-08-20 11:16:13.000000000 -0700
17352 ++++ b/drivers/ata/ata_piix.c 2008-08-20 18:36:57.000000000 -0700
17353 +@@ -276,7 +276,7 @@ static const struct pci_device_id piix_p
17354 + /* SATA Controller IDE (ICH10) */
17355 + { 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
17356 +
17357 +- { } /* terminate list */
17358 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17359 + };
17360 +
17361 + static struct pci_driver piix_pci_driver = {
17362 +@@ -723,7 +723,7 @@ static const struct ich_laptop ich_lapto
17363 + { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
17364 + { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
17365 + /* end marker */
17366 +- { 0, }
17367 ++ { 0, 0, 0 }
17368 + };
17369 +
17370 + /**
17371 +@@ -1307,7 +1307,7 @@ static int piix_broken_suspend(void)
17372 + },
17373 + },
17374 +
17375 +- { } /* terminate list */
17376 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
17377 + };
17378 + static const char *oemstrs[] = {
17379 + "Tecra M3,",
17380 +diff -urNp a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
17381 +--- a/drivers/ata/libata-core.c 2008-08-20 11:16:13.000000000 -0700
17382 ++++ b/drivers/ata/libata-core.c 2008-08-20 18:36:57.000000000 -0700
17383 +@@ -725,7 +725,7 @@ static const struct ata_xfer_ent {
17384 + { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
17385 + { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
17386 + { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
17387 +- { -1, },
17388 ++ { -1, 0, 0 }
17389 + };
17390 +
17391 + /**
17392 +@@ -3043,7 +3043,7 @@ static const struct ata_timing ata_timin
17393 + { XFER_UDMA_5, 0, 0, 0, 0, 0, 0, 0, 20 },
17394 + { XFER_UDMA_6, 0, 0, 0, 0, 0, 0, 0, 15 },
17395 +
17396 +- { 0xFF }
17397 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
17398 + };
17399 +
17400 + #define ENOUGH(v, unit) (((v)-1)/(unit)+1)
17401 +@@ -4465,7 +4465,7 @@ static const struct ata_blacklist_entry
17402 + { "TSSTcorp CDDVDW SH-S202N", "SB01", ATA_HORKAGE_IVB, },
17403 +
17404 + /* End Marker */
17405 +- { }
17406 ++ { NULL, NULL, 0 }
17407 + };
17408 +
17409 + static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
17410 +diff -urNp a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
17411 +--- a/drivers/char/agp/frontend.c 2008-08-20 11:16:13.000000000 -0700
17412 ++++ b/drivers/char/agp/frontend.c 2008-08-20 18:36:57.000000000 -0700
17413 +@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
17414 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
17415 + return -EFAULT;
17416 +
17417 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
17418 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
17419 + return -EFAULT;
17420 +
17421 + client = agp_find_client_by_pid(reserve.pid);
17422 +diff -urNp a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
17423 +--- a/drivers/char/agp/intel-agp.c 2008-08-20 11:16:13.000000000 -0700
17424 ++++ b/drivers/char/agp/intel-agp.c 2008-08-20 18:36:57.000000000 -0700
17425 +@@ -2254,7 +2254,7 @@ static struct pci_device_id agp_intel_pc
17426 + ID(PCI_DEVICE_ID_INTEL_Q35_HB),
17427 + ID(PCI_DEVICE_ID_INTEL_Q33_HB),
17428 + ID(PCI_DEVICE_ID_INTEL_IGD_HB),
17429 +- { }
17430 ++ { 0, 0, 0, 0, 0, 0, 0 }
17431 + };
17432 +
17433 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
17434 +diff -urNp a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
17435 +--- a/drivers/char/drm/drm_pciids.h 2008-08-20 11:16:13.000000000 -0700
17436 ++++ b/drivers/char/drm/drm_pciids.h 2008-08-20 18:36:57.000000000 -0700
17437 +@@ -348,7 +348,7 @@
17438 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17439 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17440 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17441 +- {0, 0, 0}
17442 ++ {0, 0, 0, 0, 0, 0, 0 }
17443 +
17444 + #define i830_PCI_IDS \
17445 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17446 +diff -urNp a/drivers/char/hpet.c b/drivers/char/hpet.c
17447 +--- a/drivers/char/hpet.c 2008-08-20 11:16:13.000000000 -0700
17448 ++++ b/drivers/char/hpet.c 2008-08-20 18:36:57.000000000 -0700
17449 +@@ -953,7 +953,7 @@ static struct acpi_driver hpet_acpi_driv
17450 + },
17451 + };
17452 +
17453 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
17454 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
17455 +
17456 + static int __init hpet_init(void)
17457 + {
17458 +diff -urNp a/drivers/char/keyboard.c b/drivers/char/keyboard.c
17459 +--- a/drivers/char/keyboard.c 2008-08-20 11:16:13.000000000 -0700
17460 ++++ b/drivers/char/keyboard.c 2008-08-20 18:36:57.000000000 -0700
17461 +@@ -630,6 +630,16 @@ static void k_spec(struct vc_data *vc, u
17462 + kbd->kbdmode == VC_MEDIUMRAW) &&
17463 + value != KVAL(K_SAK))
17464 + return; /* SAK is allowed even in raw mode */
17465 ++
17466 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
17467 ++ {
17468 ++ void *func = fn_handler[value];
17469 ++ if (func == fn_show_state || func == fn_show_ptregs ||
17470 ++ func == fn_show_mem)
17471 ++ return;
17472 ++ }
17473 ++#endif
17474 ++
17475 + fn_handler[value](vc);
17476 + }
17477 +
17478 +@@ -1384,7 +1394,7 @@ static const struct input_device_id kbd_
17479 + .evbit = { BIT_MASK(EV_SND) },
17480 + },
17481 +
17482 +- { }, /* Terminating entry */
17483 ++ { 0 }, /* Terminating entry */
17484 + };
17485 +
17486 + MODULE_DEVICE_TABLE(input, kbd_ids);
17487 +diff -urNp a/drivers/char/mem.c b/drivers/char/mem.c
17488 +--- a/drivers/char/mem.c 2008-08-20 11:16:13.000000000 -0700
17489 ++++ b/drivers/char/mem.c 2008-08-20 18:36:57.000000000 -0700
17490 +@@ -26,6 +26,7 @@
17491 + #include <linux/bootmem.h>
17492 + #include <linux/splice.h>
17493 + #include <linux/pfn.h>
17494 ++#include <linux/grsecurity.h>
17495 +
17496 + #include <asm/uaccess.h>
17497 + #include <asm/io.h>
17498 +@@ -34,6 +35,10 @@
17499 + # include <linux/efi.h>
17500 + #endif
17501 +
17502 ++#ifdef CONFIG_GRKERNSEC
17503 ++extern struct file_operations grsec_fops;
17504 ++#endif
17505 ++
17506 + /*
17507 + * Architectures vary in how they handle caching for addresses
17508 + * outside of main memory.
17509 +@@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
17510 + if (!valid_phys_addr_range(p, count))
17511 + return -EFAULT;
17512 +
17513 ++#ifdef CONFIG_GRKERNSEC_KMEM
17514 ++ gr_handle_mem_write();
17515 ++ return -EPERM;
17516 ++#endif
17517 ++
17518 + written = 0;
17519 +
17520 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
17521 +@@ -281,6 +291,11 @@ static int mmap_mem(struct file * file,
17522 + if (!private_mapping_ok(vma))
17523 + return -ENOSYS;
17524 +
17525 ++#ifdef CONFIG_GRKERNSEC_KMEM
17526 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
17527 ++ return -EPERM;
17528 ++#endif
17529 ++
17530 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
17531 + size,
17532 + vma->vm_page_prot);
17533 +@@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file *
17534 + ssize_t written;
17535 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
17536 +
17537 ++#ifdef CONFIG_GRKERNSEC_KMEM
17538 ++ gr_handle_kmem_write();
17539 ++ return -EPERM;
17540 ++#endif
17541 ++
17542 + if (p < (unsigned long) high_memory) {
17543 +
17544 + wrote = count;
17545 +@@ -714,6 +734,16 @@ static loff_t memory_lseek(struct file *
17546 +
17547 + static int open_port(struct inode * inode, struct file * filp)
17548 + {
17549 ++#ifdef CONFIG_GRKERNSEC_KMEM
17550 ++ gr_handle_open_port();
17551 ++ return -EPERM;
17552 ++#endif
17553 ++
17554 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17555 ++}
17556 ++
17557 ++static int open_mem(struct inode * inode, struct file * filp)
17558 ++{
17559 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17560 + }
17561 +
17562 +@@ -721,7 +751,6 @@ static int open_port(struct inode * inod
17563 + #define full_lseek null_lseek
17564 + #define write_zero write_null
17565 + #define read_full read_zero
17566 +-#define open_mem open_port
17567 + #define open_kmem open_mem
17568 + #define open_oldmem open_mem
17569 +
17570 +@@ -854,6 +883,11 @@ static int memory_open(struct inode * in
17571 + filp->f_op = &oldmem_fops;
17572 + break;
17573 + #endif
17574 ++#ifdef CONFIG_GRKERNSEC
17575 ++ case 13:
17576 ++ filp->f_op = &grsec_fops;
17577 ++ break;
17578 ++#endif
17579 + default:
17580 + return -ENXIO;
17581 + }
17582 +@@ -886,6 +920,9 @@ static const struct {
17583 + #ifdef CONFIG_CRASH_DUMP
17584 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
17585 + #endif
17586 ++#ifdef CONFIG_GRKERNSEC
17587 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
17588 ++#endif
17589 + };
17590 +
17591 + static struct class *mem_class;
17592 +diff -urNp a/drivers/char/nvram.c b/drivers/char/nvram.c
17593 +--- a/drivers/char/nvram.c 2008-08-20 11:16:13.000000000 -0700
17594 ++++ b/drivers/char/nvram.c 2008-08-20 18:36:57.000000000 -0700
17595 +@@ -430,7 +430,10 @@ static const struct file_operations nvra
17596 + static struct miscdevice nvram_dev = {
17597 + NVRAM_MINOR,
17598 + "nvram",
17599 +- &nvram_fops
17600 ++ &nvram_fops,
17601 ++ {NULL, NULL},
17602 ++ NULL,
17603 ++ NULL
17604 + };
17605 +
17606 + static int __init
17607 +diff -urNp a/drivers/char/random.c b/drivers/char/random.c
17608 +--- a/drivers/char/random.c 2008-08-20 11:16:13.000000000 -0700
17609 ++++ b/drivers/char/random.c 2008-08-20 18:36:57.000000000 -0700
17610 +@@ -248,8 +248,13 @@
17611 + /*
17612 + * Configuration information
17613 + */
17614 ++#ifdef CONFIG_GRKERNSEC_RANDNET
17615 ++#define INPUT_POOL_WORDS 512
17616 ++#define OUTPUT_POOL_WORDS 128
17617 ++#else
17618 + #define INPUT_POOL_WORDS 128
17619 + #define OUTPUT_POOL_WORDS 32
17620 ++#endif
17621 + #define SEC_XFER_SIZE 512
17622 +
17623 + /*
17624 +@@ -286,10 +291,17 @@ static struct poolinfo {
17625 + int poolwords;
17626 + int tap1, tap2, tap3, tap4, tap5;
17627 + } poolinfo_table[] = {
17628 ++#ifdef CONFIG_GRKERNSEC_RANDNET
17629 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
17630 ++ { 512, 411, 308, 208, 104, 1 },
17631 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
17632 ++ { 128, 103, 76, 51, 25, 1 },
17633 ++#else
17634 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
17635 + { 128, 103, 76, 51, 25, 1 },
17636 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
17637 + { 32, 26, 20, 14, 7, 1 },
17638 ++#endif
17639 + #if 0
17640 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
17641 + { 2048, 1638, 1231, 819, 411, 1 },
17642 +@@ -1171,7 +1183,7 @@ EXPORT_SYMBOL(generate_random_uuid);
17643 + #include <linux/sysctl.h>
17644 +
17645 + static int min_read_thresh = 8, min_write_thresh;
17646 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
17647 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
17648 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
17649 + static char sysctl_bootid[16];
17650 +
17651 +diff -urNp a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
17652 +--- a/drivers/char/tpm/tpm.c 2008-08-20 11:16:13.000000000 -0700
17653 ++++ b/drivers/char/tpm/tpm.c 2008-08-20 18:36:57.000000000 -0700
17654 +@@ -970,7 +970,7 @@ ssize_t tpm_write(struct file *file, con
17655 +
17656 + mutex_lock(&chip->buffer_mutex);
17657 +
17658 +- if (in_size > TPM_BUFSIZE)
17659 ++ if (in_size > (unsigned int)TPM_BUFSIZE)
17660 + in_size = TPM_BUFSIZE;
17661 +
17662 + if (copy_from_user
17663 +diff -urNp a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
17664 +--- a/drivers/char/vt_ioctl.c 2008-08-20 11:16:13.000000000 -0700
17665 ++++ b/drivers/char/vt_ioctl.c 2008-08-20 18:36:57.000000000 -0700
17666 +@@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
17667 + case KDSKBENT:
17668 + if (!perm)
17669 + return -EPERM;
17670 ++
17671 ++#ifdef CONFIG_GRKERNSEC
17672 ++ if (!capable(CAP_SYS_TTY_CONFIG))
17673 ++ return -EPERM;
17674 ++#endif
17675 ++
17676 + if (!i && v == K_NOSUCHMAP) {
17677 + /* deallocate map */
17678 + key_map = key_maps[s];
17679 +@@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
17680 + goto reterr;
17681 + }
17682 +
17683 ++#ifdef CONFIG_GRKERNSEC
17684 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
17685 ++ ret = -EPERM;
17686 ++ goto reterr;
17687 ++ }
17688 ++#endif
17689 ++
17690 + q = func_table[i];
17691 + first_free = funcbufptr + (funcbufsize - funcbufleft);
17692 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
17693 +diff -urNp a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
17694 +--- a/drivers/edac/edac_core.h 2008-08-20 11:16:13.000000000 -0700
17695 ++++ b/drivers/edac/edac_core.h 2008-08-20 18:36:57.000000000 -0700
17696 +@@ -86,11 +86,11 @@ extern int edac_debug_level;
17697 +
17698 + #else /* !CONFIG_EDAC_DEBUG */
17699 +
17700 +-#define debugf0( ... )
17701 +-#define debugf1( ... )
17702 +-#define debugf2( ... )
17703 +-#define debugf3( ... )
17704 +-#define debugf4( ... )
17705 ++#define debugf0( ... ) do {} while (0)
17706 ++#define debugf1( ... ) do {} while (0)
17707 ++#define debugf2( ... ) do {} while (0)
17708 ++#define debugf3( ... ) do {} while (0)
17709 ++#define debugf4( ... ) do {} while (0)
17710 +
17711 + #endif /* !CONFIG_EDAC_DEBUG */
17712 +
17713 +diff -urNp a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
17714 +--- a/drivers/firmware/dmi_scan.c 2008-08-20 11:16:13.000000000 -0700
17715 ++++ b/drivers/firmware/dmi_scan.c 2008-08-20 18:36:57.000000000 -0700
17716 +@@ -379,11 +379,6 @@ void __init dmi_scan_machine(void)
17717 + }
17718 + }
17719 + else {
17720 +- /*
17721 +- * no iounmap() for that ioremap(); it would be a no-op, but
17722 +- * it's so early in setup that sucker gets confused into doing
17723 +- * what it shouldn't if we actually call it.
17724 +- */
17725 + p = dmi_ioremap(0xF0000, 0x10000);
17726 + if (p == NULL)
17727 + goto out;
17728 +diff -urNp a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c
17729 +--- a/drivers/hwmon/fscpos.c 2008-08-20 11:16:13.000000000 -0700
17730 ++++ b/drivers/hwmon/fscpos.c 2008-08-20 18:36:57.000000000 -0700
17731 +@@ -230,7 +230,6 @@ static ssize_t set_pwm(struct i2c_client
17732 + unsigned long v = simple_strtoul(buf, NULL, 10);
17733 +
17734 + /* Range: 0..255 */
17735 +- if (v < 0) v = 0;
17736 + if (v > 255) v = 255;
17737 +
17738 + mutex_lock(&data->update_lock);
17739 +diff -urNp a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
17740 +--- a/drivers/hwmon/k8temp.c 2008-08-20 11:16:13.000000000 -0700
17741 ++++ b/drivers/hwmon/k8temp.c 2008-08-20 18:36:57.000000000 -0700
17742 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
17743 +
17744 + static struct pci_device_id k8temp_ids[] = {
17745 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
17746 +- { 0 },
17747 ++ { 0, 0, 0, 0, 0, 0, 0 },
17748 + };
17749 +
17750 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
17751 +diff -urNp a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
17752 +--- a/drivers/hwmon/sis5595.c 2008-08-20 11:16:13.000000000 -0700
17753 ++++ b/drivers/hwmon/sis5595.c 2008-08-20 18:36:57.000000000 -0700
17754 +@@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
17755 +
17756 + static struct pci_device_id sis5595_pci_ids[] = {
17757 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
17758 +- { 0, }
17759 ++ { 0, 0, 0, 0, 0, 0, 0 }
17760 + };
17761 +
17762 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
17763 +diff -urNp a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
17764 +--- a/drivers/hwmon/via686a.c 2008-08-20 11:16:13.000000000 -0700
17765 ++++ b/drivers/hwmon/via686a.c 2008-08-20 18:36:57.000000000 -0700
17766 +@@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
17767 +
17768 + static struct pci_device_id via686a_pci_ids[] = {
17769 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
17770 +- { 0, }
17771 ++ { 0, 0, 0, 0, 0, 0, 0 }
17772 + };
17773 +
17774 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
17775 +diff -urNp a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
17776 +--- a/drivers/hwmon/vt8231.c 2008-08-20 11:16:13.000000000 -0700
17777 ++++ b/drivers/hwmon/vt8231.c 2008-08-20 18:36:57.000000000 -0700
17778 +@@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
17779 +
17780 + static struct pci_device_id vt8231_pci_ids[] = {
17781 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
17782 +- { 0, }
17783 ++ { 0, 0, 0, 0, 0, 0, 0 }
17784 + };
17785 +
17786 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
17787 +diff -urNp a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
17788 +--- a/drivers/hwmon/w83791d.c 2008-08-20 11:16:13.000000000 -0700
17789 ++++ b/drivers/hwmon/w83791d.c 2008-08-20 18:36:57.000000000 -0700
17790 +@@ -290,8 +290,8 @@ static int w83791d_attach_adapter(struct
17791 + static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
17792 + static int w83791d_detach_client(struct i2c_client *client);
17793 +
17794 +-static int w83791d_read(struct i2c_client *client, u8 register);
17795 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
17796 ++static int w83791d_read(struct i2c_client *client, u8 reg);
17797 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
17798 + static struct w83791d_data *w83791d_update_device(struct device *dev);
17799 +
17800 + #ifdef DEBUG
17801 +diff -urNp a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
17802 +--- a/drivers/i2c/busses/i2c-i801.c 2008-08-20 11:16:13.000000000 -0700
17803 ++++ b/drivers/i2c/busses/i2c-i801.c 2008-08-20 18:36:57.000000000 -0700
17804 +@@ -592,7 +592,7 @@ static struct pci_device_id i801_ids[] =
17805 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
17806 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
17807 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
17808 +- { 0, }
17809 ++ { 0, 0, 0, 0, 0, 0, 0 }
17810 + };
17811 +
17812 + MODULE_DEVICE_TABLE (pci, i801_ids);
17813 +diff -urNp a/drivers/i2c/busses/i2c-i810.c b/drivers/i2c/busses/i2c-i810.c
17814 +--- a/drivers/i2c/busses/i2c-i810.c 2008-08-20 11:16:13.000000000 -0700
17815 ++++ b/drivers/i2c/busses/i2c-i810.c 2008-08-20 18:36:57.000000000 -0700
17816 +@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
17817 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
17818 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
17819 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
17820 +- { 0, },
17821 ++ { 0, 0, 0, 0, 0, 0, 0 },
17822 + };
17823 +
17824 + MODULE_DEVICE_TABLE (pci, i810_ids);
17825 +diff -urNp a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
17826 +--- a/drivers/i2c/busses/i2c-piix4.c 2008-08-20 11:16:13.000000000 -0700
17827 ++++ b/drivers/i2c/busses/i2c-piix4.c 2008-08-20 18:36:57.000000000 -0700
17828 +@@ -133,7 +133,7 @@ static struct dmi_system_id __devinitdat
17829 + .ident = "IBM",
17830 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
17831 + },
17832 +- { },
17833 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
17834 + };
17835 +
17836 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
17837 +@@ -428,7 +428,7 @@ static struct pci_device_id piix4_ids[]
17838 + PCI_DEVICE_ID_SERVERWORKS_CSB6) },
17839 + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
17840 + PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
17841 +- { 0, }
17842 ++ { 0, 0, 0, 0, 0, 0, 0 }
17843 + };
17844 +
17845 + MODULE_DEVICE_TABLE (pci, piix4_ids);
17846 +diff -urNp a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
17847 +--- a/drivers/i2c/busses/i2c-sis630.c 2008-08-20 11:16:13.000000000 -0700
17848 ++++ b/drivers/i2c/busses/i2c-sis630.c 2008-08-20 18:36:57.000000000 -0700
17849 +@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
17850 + static struct pci_device_id sis630_ids[] __devinitdata = {
17851 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
17852 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
17853 +- { 0, }
17854 ++ { 0, 0, 0, 0, 0, 0, 0 }
17855 + };
17856 +
17857 + MODULE_DEVICE_TABLE (pci, sis630_ids);
17858 +diff -urNp a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
17859 +--- a/drivers/i2c/busses/i2c-sis96x.c 2008-08-20 11:16:13.000000000 -0700
17860 ++++ b/drivers/i2c/busses/i2c-sis96x.c 2008-08-20 18:36:57.000000000 -0700
17861 +@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
17862 +
17863 + static struct pci_device_id sis96x_ids[] = {
17864 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
17865 +- { 0, }
17866 ++ { 0, 0, 0, 0, 0, 0, 0 }
17867 + };
17868 +
17869 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
17870 +diff -urNp a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
17871 +--- a/drivers/ide/ide-cd.c 2008-08-20 11:16:13.000000000 -0700
17872 ++++ b/drivers/ide/ide-cd.c 2008-08-20 18:36:57.000000000 -0700
17873 +@@ -182,8 +182,6 @@ void cdrom_analyze_sense_data(ide_drive_
17874 + sector &= ~(bio_sectors -1);
17875 + valid = (sector - failed_command->sector) << 9;
17876 +
17877 +- if (valid < 0)
17878 +- valid = 0;
17879 + if (sector < get_capacity(info->disk) &&
17880 + drive->probed_capacity - sector < 4 * 75) {
17881 + set_capacity(info->disk, sector);
17882 +diff -urNp a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
17883 +--- a/drivers/ieee1394/dv1394.c 2008-08-20 11:16:13.000000000 -0700
17884 ++++ b/drivers/ieee1394/dv1394.c 2008-08-20 18:36:57.000000000 -0700
17885 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
17886 + based upon DIF section and sequence
17887 + */
17888 +
17889 +-static void inline
17890 ++static inline void
17891 + frame_put_packet (struct frame *f, struct packet *p)
17892 + {
17893 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
17894 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
17895 + /* default SYT offset is 3 cycles */
17896 + init->syt_offset = 3;
17897 +
17898 +- if ( (init->channel > 63) || (init->channel < 0) )
17899 ++ if (init->channel > 63)
17900 + init->channel = 63;
17901 +
17902 + chan_mask = (u64)1 << init->channel;
17903 +@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
17904 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
17905 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
17906 + },
17907 +- { }
17908 ++ { 0, 0, 0, 0, 0, 0 }
17909 + };
17910 +
17911 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
17912 +diff -urNp a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
17913 +--- a/drivers/ieee1394/eth1394.c 2008-08-20 11:16:13.000000000 -0700
17914 ++++ b/drivers/ieee1394/eth1394.c 2008-08-20 18:36:57.000000000 -0700
17915 +@@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
17916 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
17917 + .version = ETHER1394_GASP_VERSION,
17918 + },
17919 +- {}
17920 ++ { 0, 0, 0, 0, 0, 0 }
17921 + };
17922 +
17923 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
17924 +diff -urNp a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
17925 +--- a/drivers/ieee1394/hosts.c 2008-08-20 11:16:13.000000000 -0700
17926 ++++ b/drivers/ieee1394/hosts.c 2008-08-20 18:36:57.000000000 -0700
17927 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
17928 + }
17929 +
17930 + static struct hpsb_host_driver dummy_driver = {
17931 ++ .name = "dummy",
17932 + .transmit_packet = dummy_transmit_packet,
17933 + .devctl = dummy_devctl,
17934 + .isoctl = dummy_isoctl
17935 +diff -urNp a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
17936 +--- a/drivers/ieee1394/ohci1394.c 2008-08-20 11:16:13.000000000 -0700
17937 ++++ b/drivers/ieee1394/ohci1394.c 2008-08-20 18:36:57.000000000 -0700
17938 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
17939 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
17940 +
17941 + /* Module Parameters */
17942 +-static int phys_dma = 1;
17943 ++static int phys_dma;
17944 + module_param(phys_dma, int, 0444);
17945 +-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
17946 ++MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
17947 +
17948 + static void dma_trm_tasklet(unsigned long data);
17949 + static void dma_trm_reset(struct dma_trm_ctx *d);
17950 +@@ -3400,7 +3400,7 @@ static struct pci_device_id ohci1394_pci
17951 + .subvendor = PCI_ANY_ID,
17952 + .subdevice = PCI_ANY_ID,
17953 + },
17954 +- { 0, },
17955 ++ { 0, 0, 0, 0, 0, 0, 0 },
17956 + };
17957 +
17958 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
17959 +diff -urNp a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
17960 +--- a/drivers/ieee1394/raw1394.c 2008-08-20 11:16:13.000000000 -0700
17961 ++++ b/drivers/ieee1394/raw1394.c 2008-08-20 18:36:57.000000000 -0700
17962 +@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
17963 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
17964 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
17965 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
17966 +- {}
17967 ++ { 0, 0, 0, 0, 0, 0 }
17968 + };
17969 +
17970 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
17971 +diff -urNp a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
17972 +--- a/drivers/ieee1394/sbp2.c 2008-08-20 11:16:13.000000000 -0700
17973 ++++ b/drivers/ieee1394/sbp2.c 2008-08-20 18:36:57.000000000 -0700
17974 +@@ -283,7 +283,7 @@ static struct ieee1394_device_id sbp2_id
17975 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
17976 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
17977 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
17978 +- {}
17979 ++ { 0, 0, 0, 0, 0, 0 }
17980 + };
17981 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
17982 +
17983 +@@ -2108,7 +2108,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
17984 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
17985 + MODULE_LICENSE("GPL");
17986 +
17987 +-static int sbp2_module_init(void)
17988 ++static int __init sbp2_module_init(void)
17989 + {
17990 + int ret;
17991 +
17992 +diff -urNp a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
17993 +--- a/drivers/ieee1394/video1394.c 2008-08-20 11:16:13.000000000 -0700
17994 ++++ b/drivers/ieee1394/video1394.c 2008-08-20 18:36:57.000000000 -0700
17995 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
17996 + if (unlikely(d == NULL))
17997 + return -EFAULT;
17998 +
17999 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
18000 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
18001 + PRINT(KERN_ERR, ohci->host->id,
18002 + "Buffer %d out of range",v.buffer);
18003 + return -EINVAL;
18004 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
18005 + if (unlikely(d == NULL))
18006 + return -EFAULT;
18007 +
18008 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
18009 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
18010 + PRINT(KERN_ERR, ohci->host->id,
18011 + "Buffer %d out of range",v.buffer);
18012 + return -EINVAL;
18013 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
18014 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
18015 + if (d == NULL) return -EFAULT;
18016 +
18017 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
18018 ++ if (v.buffer>=d->num_desc - 1) {
18019 + PRINT(KERN_ERR, ohci->host->id,
18020 + "Buffer %d out of range",v.buffer);
18021 + return -EINVAL;
18022 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
18023 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
18024 + if (d == NULL) return -EFAULT;
18025 +
18026 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
18027 ++ if (v.buffer>=d->num_desc-1) {
18028 + PRINT(KERN_ERR, ohci->host->id,
18029 + "Buffer %d out of range",v.buffer);
18030 + return -EINVAL;
18031 +@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
18032 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
18033 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
18034 + },
18035 +- { }
18036 ++ { 0, 0, 0, 0, 0, 0 }
18037 + };
18038 +
18039 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
18040 +diff -urNp a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
18041 +--- a/drivers/input/keyboard/atkbd.c 2008-08-20 11:16:13.000000000 -0700
18042 ++++ b/drivers/input/keyboard/atkbd.c 2008-08-20 18:36:57.000000000 -0700
18043 +@@ -1113,7 +1113,7 @@ static struct serio_device_id atkbd_seri
18044 + .id = SERIO_ANY,
18045 + .extra = SERIO_ANY,
18046 + },
18047 +- { 0 }
18048 ++ { 0, 0, 0, 0 }
18049 + };
18050 +
18051 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
18052 +diff -urNp a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
18053 +--- a/drivers/input/mouse/lifebook.c 2008-08-20 11:16:13.000000000 -0700
18054 ++++ b/drivers/input/mouse/lifebook.c 2008-08-20 18:36:57.000000000 -0700
18055 +@@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
18056 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
18057 + },
18058 + },
18059 +- { }
18060 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
18061 + };
18062 +
18063 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
18064 +diff -urNp a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
18065 +--- a/drivers/input/mouse/psmouse-base.c 2008-08-20 11:16:13.000000000 -0700
18066 ++++ b/drivers/input/mouse/psmouse-base.c 2008-08-20 18:36:57.000000000 -0700
18067 +@@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
18068 + .id = SERIO_ANY,
18069 + .extra = SERIO_ANY,
18070 + },
18071 +- { 0 }
18072 ++ { 0, 0, 0, 0 }
18073 + };
18074 +
18075 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
18076 +diff -urNp a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
18077 +--- a/drivers/input/mouse/synaptics.c 2008-08-20 11:16:13.000000000 -0700
18078 ++++ b/drivers/input/mouse/synaptics.c 2008-08-20 18:36:57.000000000 -0700
18079 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
18080 + break;
18081 + case 2:
18082 + if (SYN_MODEL_PEN(priv->model_id))
18083 +- ; /* Nothing, treat a pen as a single finger */
18084 ++ break; /* Nothing, treat a pen as a single finger */
18085 + break;
18086 + case 4 ... 15:
18087 + if (SYN_CAP_PALMDETECT(priv->capabilities))
18088 +@@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
18089 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
18090 + },
18091 + },
18092 +- { }
18093 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18094 + };
18095 + #endif
18096 +
18097 +diff -urNp a/drivers/input/mousedev.c b/drivers/input/mousedev.c
18098 +--- a/drivers/input/mousedev.c 2008-08-20 11:16:13.000000000 -0700
18099 ++++ b/drivers/input/mousedev.c 2008-08-20 18:36:57.000000000 -0700
18100 +@@ -1056,7 +1056,7 @@ static struct input_handler mousedev_han
18101 +
18102 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
18103 + static struct miscdevice psaux_mouse = {
18104 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
18105 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
18106 + };
18107 + static int psaux_registered;
18108 + #endif
18109 +diff -urNp a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
18110 +--- a/drivers/input/serio/i8042-x86ia64io.h 2008-08-20 11:16:13.000000000 -0700
18111 ++++ b/drivers/input/serio/i8042-x86ia64io.h 2008-08-20 18:36:57.000000000 -0700
18112 +@@ -118,7 +118,7 @@ static struct dmi_system_id __initdata i
18113 + DMI_MATCH(DMI_PRODUCT_VERSION, "VS2005R2"),
18114 + },
18115 + },
18116 +- { }
18117 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18118 + };
18119 +
18120 + /*
18121 +@@ -305,7 +305,7 @@ static struct dmi_system_id __initdata i
18122 + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1360"),
18123 + },
18124 + },
18125 +- { }
18126 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18127 + };
18128 +
18129 + #ifdef CONFIG_PNP
18130 +diff -urNp a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
18131 +--- a/drivers/input/serio/serio_raw.c 2008-08-20 11:16:13.000000000 -0700
18132 ++++ b/drivers/input/serio/serio_raw.c 2008-08-20 18:36:57.000000000 -0700
18133 +@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
18134 + .id = SERIO_ANY,
18135 + .extra = SERIO_ANY,
18136 + },
18137 +- { 0 }
18138 ++ { 0, 0, 0, 0 }
18139 + };
18140 +
18141 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
18142 +diff -urNp a/drivers/md/bitmap.c b/drivers/md/bitmap.c
18143 +--- a/drivers/md/bitmap.c 2008-08-20 11:16:13.000000000 -0700
18144 ++++ b/drivers/md/bitmap.c 2008-08-20 18:36:57.000000000 -0700
18145 +@@ -57,7 +57,7 @@
18146 + # if DEBUG > 0
18147 + # define PRINTK(x...) printk(KERN_DEBUG x)
18148 + # else
18149 +-# define PRINTK(x...)
18150 ++# define PRINTK(x...) do {} while (0)
18151 + # endif
18152 + #endif
18153 +
18154 +diff -urNp a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
18155 +--- a/drivers/mtd/devices/doc2000.c 2008-08-20 11:16:13.000000000 -0700
18156 ++++ b/drivers/mtd/devices/doc2000.c 2008-08-20 18:36:57.000000000 -0700
18157 +@@ -779,7 +779,7 @@ static int doc_write(struct mtd_info *mt
18158 +
18159 + /* The ECC will not be calculated correctly if less than 512 is written */
18160 + /* DBB-
18161 +- if (len != 0x200 && eccbuf)
18162 ++ if (len != 0x200)
18163 + printk(KERN_WARNING
18164 + "ECC needs a full sector write (adr: %lx size %lx)\n",
18165 + (long) to, (long) len);
18166 +diff -urNp a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
18167 +--- a/drivers/mtd/devices/doc2001.c 2008-08-20 11:16:13.000000000 -0700
18168 ++++ b/drivers/mtd/devices/doc2001.c 2008-08-20 18:36:57.000000000 -0700
18169 +@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
18170 + /* Don't allow read past end of device */
18171 + if (from >= this->totlen)
18172 + return -EINVAL;
18173 ++ if (!len)
18174 ++ return -EINVAL;
18175 +
18176 + /* Don't allow a single read to cross a 512-byte block boundary */
18177 + if (from + len > ((from | 0x1ff) + 1))
18178 +diff -urNp a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
18179 +--- a/drivers/mtd/devices/slram.c 2008-08-20 11:16:13.000000000 -0700
18180 ++++ b/drivers/mtd/devices/slram.c 2008-08-20 18:36:57.000000000 -0700
18181 +@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
18182 + }
18183 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
18184 + devname, devstart, devlength);
18185 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
18186 ++ if (devlength % SLRAM_BLK_SZ != 0) {
18187 + E("slram: Illegal start / length parameter.\n");
18188 + return(-EINVAL);
18189 + }
18190 +diff -urNp a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
18191 +--- a/drivers/mtd/ubi/build.c 2008-08-20 11:16:13.000000000 -0700
18192 ++++ b/drivers/mtd/ubi/build.c 2008-08-20 18:36:57.000000000 -0700
18193 +@@ -1059,7 +1059,7 @@ static int __init bytes_str_to_int(const
18194 + unsigned long result;
18195 +
18196 + result = simple_strtoul(str, &endp, 0);
18197 +- if (str == endp || result < 0) {
18198 ++ if (str == endp) {
18199 + printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
18200 + str);
18201 + return -EINVAL;
18202 +diff -urNp a/drivers/net/eepro100.c b/drivers/net/eepro100.c
18203 +--- a/drivers/net/eepro100.c 2008-08-20 11:16:13.000000000 -0700
18204 ++++ b/drivers/net/eepro100.c 2008-08-20 18:36:57.000000000 -0700
18205 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
18206 + # define rx_align(skb) skb_reserve((skb), 2)
18207 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
18208 + #else
18209 +-# define rx_align(skb)
18210 ++# define rx_align(skb) do {} while (0)
18211 + # define RxFD_ALIGNMENT
18212 + #endif
18213 +
18214 +@@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
18215 + }
18216 +
18217 + static struct pci_device_id eepro100_pci_tbl[] = {
18218 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
18219 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
18220 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
18221 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
18222 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
18223 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
18224 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
18225 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
18226 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
18227 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
18228 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
18229 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
18230 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
18231 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
18232 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
18233 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
18234 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
18235 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
18236 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
18237 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
18238 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
18239 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
18240 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
18241 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
18242 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
18243 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
18244 +- { 0,}
18245 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18246 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18247 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18248 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18249 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18250 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18251 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18252 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18253 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18254 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18255 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18256 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18257 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18258 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18259 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18260 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18261 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18262 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18263 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18264 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18265 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18266 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18267 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18268 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18269 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18270 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18271 ++ { 0, 0, 0, 0, 0, 0, 0 }
18272 + };
18273 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
18274 +
18275 +diff -urNp a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
18276 +--- a/drivers/net/irda/vlsi_ir.c 2008-08-20 11:16:13.000000000 -0700
18277 ++++ b/drivers/net/irda/vlsi_ir.c 2008-08-20 18:36:57.000000000 -0700
18278 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
18279 + /* no race - tx-ring already empty */
18280 + vlsi_set_baud(idev, iobase);
18281 + netif_wake_queue(ndev);
18282 +- }
18283 +- else
18284 +- ;
18285 ++ } else {
18286 + /* keep the speed change pending like it would
18287 + * for any len>0 packet. tx completion interrupt
18288 + * will apply it when the tx ring becomes empty.
18289 + */
18290 ++ }
18291 + spin_unlock_irqrestore(&idev->lock, flags);
18292 + dev_kfree_skb_any(skb);
18293 + return 0;
18294 +diff -urNp a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
18295 +--- a/drivers/net/pcnet32.c 2008-08-20 11:16:13.000000000 -0700
18296 ++++ b/drivers/net/pcnet32.c 2008-08-20 18:36:57.000000000 -0700
18297 +@@ -82,7 +82,7 @@ static int cards_found;
18298 + /*
18299 + * VLB I/O addresses
18300 + */
18301 +-static unsigned int pcnet32_portlist[] __initdata =
18302 ++static unsigned int pcnet32_portlist[] __devinitdata =
18303 + { 0x300, 0x320, 0x340, 0x360, 0 };
18304 +
18305 + static int pcnet32_debug = 0;
18306 +diff -urNp a/drivers/net/tg3.h b/drivers/net/tg3.h
18307 +--- a/drivers/net/tg3.h 2008-08-20 11:16:13.000000000 -0700
18308 ++++ b/drivers/net/tg3.h 2008-08-20 18:36:57.000000000 -0700
18309 +@@ -102,6 +102,7 @@
18310 + #define CHIPREV_ID_5750_A0 0x4000
18311 + #define CHIPREV_ID_5750_A1 0x4001
18312 + #define CHIPREV_ID_5750_A3 0x4003
18313 ++#define CHIPREV_ID_5750_C1 0x4201
18314 + #define CHIPREV_ID_5750_C2 0x4202
18315 + #define CHIPREV_ID_5752_A0_HW 0x5000
18316 + #define CHIPREV_ID_5752_A0 0x6000
18317 +diff -urNp a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
18318 +--- a/drivers/pci/hotplug/cpqphp_nvram.c 2008-08-20 11:16:13.000000000 -0700
18319 ++++ b/drivers/pci/hotplug/cpqphp_nvram.c 2008-08-20 18:36:57.000000000 -0700
18320 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
18321 +
18322 + void compaq_nvram_init (void __iomem *rom_start)
18323 + {
18324 ++
18325 ++#ifndef CONFIG_PAX_KERNEXEC
18326 + if (rom_start) {
18327 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
18328 + }
18329 ++#endif
18330 ++
18331 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
18332 +
18333 + /* initialize our int15 lock */
18334 +diff -urNp a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
18335 +--- a/drivers/pci/pcie/aer/aerdrv.c 2008-08-20 11:16:13.000000000 -0700
18336 ++++ b/drivers/pci/pcie/aer/aerdrv.c 2008-08-20 18:36:57.000000000 -0700
18337 +@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
18338 + .port_type = PCIE_RC_PORT,
18339 + .service_type = PCIE_PORT_SERVICE_AER,
18340 + },
18341 +- { /* end: all zeroes */ }
18342 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18343 + };
18344 +
18345 + static struct pci_error_handlers aer_error_handlers = {
18346 +diff -urNp a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
18347 +--- a/drivers/pci/pcie/aer/aerdrv_core.c 2008-08-20 11:16:13.000000000 -0700
18348 ++++ b/drivers/pci/pcie/aer/aerdrv_core.c 2008-08-20 18:36:57.000000000 -0700
18349 +@@ -661,7 +661,7 @@ static void aer_isr_one_error(struct pci
18350 + struct aer_err_source *e_src)
18351 + {
18352 + struct device *s_device;
18353 +- struct aer_err_info e_info = {0, 0, 0,};
18354 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
18355 + int i;
18356 + u16 id;
18357 +
18358 +diff -urNp a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
18359 +--- a/drivers/pci/pcie/portdrv_pci.c 2008-08-20 11:16:13.000000000 -0700
18360 ++++ b/drivers/pci/pcie/portdrv_pci.c 2008-08-20 18:36:57.000000000 -0700
18361 +@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
18362 + static const struct pci_device_id port_pci_ids[] = { {
18363 + /* handle any PCI-Express port */
18364 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
18365 +- }, { /* end: all zeroes */ }
18366 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
18367 + };
18368 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
18369 +
18370 +diff -urNp a/drivers/pci/proc.c b/drivers/pci/proc.c
18371 +--- a/drivers/pci/proc.c 2008-08-20 11:16:13.000000000 -0700
18372 ++++ b/drivers/pci/proc.c 2008-08-20 18:36:57.000000000 -0700
18373 +@@ -472,7 +472,15 @@ static int __init pci_proc_init(void)
18374 + {
18375 + struct proc_dir_entry *entry;
18376 + struct pci_dev *dev = NULL;
18377 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
18378 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
18379 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
18380 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
18381 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
18382 ++#endif
18383 ++#else
18384 + proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
18385 ++#endif
18386 + entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
18387 + if (entry)
18388 + entry->proc_fops = &proc_bus_pci_dev_operations;
18389 +diff -urNp a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
18390 +--- a/drivers/pcmcia/ti113x.h 2008-08-20 11:16:13.000000000 -0700
18391 ++++ b/drivers/pcmcia/ti113x.h 2008-08-20 18:36:57.000000000 -0700
18392 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
18393 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
18394 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
18395 +
18396 +- {}
18397 ++ { 0, 0, 0, 0, 0, 0, 0 }
18398 + };
18399 +
18400 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
18401 +diff -urNp a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
18402 +--- a/drivers/pcmcia/yenta_socket.c 2008-08-20 11:16:13.000000000 -0700
18403 ++++ b/drivers/pcmcia/yenta_socket.c 2008-08-20 18:36:57.000000000 -0700
18404 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
18405 +
18406 + /* match any cardbus bridge */
18407 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
18408 +- { /* all zeroes */ }
18409 ++ { 0, 0, 0, 0, 0, 0, 0 }
18410 + };
18411 + MODULE_DEVICE_TABLE(pci, yenta_table);
18412 +
18413 +diff -urNp a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c
18414 +--- a/drivers/pnp/pnpbios/bioscalls.c 2008-08-20 11:16:13.000000000 -0700
18415 ++++ b/drivers/pnp/pnpbios/bioscalls.c 2008-08-20 18:36:57.000000000 -0700
18416 +@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
18417 + set_limit(gdt[(selname) >> 3], size); \
18418 + } while(0)
18419 +
18420 +-static struct desc_struct bad_bios_desc;
18421 ++static struct desc_struct bad_bios_desc __read_only;
18422 +
18423 + /*
18424 + * At some point we want to use this stack frame pointer to unwind
18425 +@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
18426 + struct desc_struct save_desc_40;
18427 + int cpu;
18428 +
18429 ++#ifdef CONFIG_PAX_KERNEXEC
18430 ++ unsigned long cr0;
18431 ++#endif
18432 ++
18433 + /*
18434 + * PnP BIOSes are generally not terribly re-entrant.
18435 + * Also, don't rely on them to save everything correctly.
18436 +@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
18437 +
18438 + cpu = get_cpu();
18439 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
18440 ++
18441 ++#ifdef CONFIG_PAX_KERNEXEC
18442 ++ pax_open_kernel(cr0);
18443 ++#endif
18444 ++
18445 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
18446 +
18447 ++#ifdef CONFIG_PAX_KERNEXEC
18448 ++ pax_close_kernel(cr0);
18449 ++#endif
18450 ++
18451 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
18452 + spin_lock_irqsave(&pnp_bios_lock, flags);
18453 +
18454 +@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
18455 + :"memory");
18456 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
18457 +
18458 ++#ifdef CONFIG_PAX_KERNEXEC
18459 ++ pax_open_kernel(cr0);
18460 ++#endif
18461 ++
18462 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
18463 ++
18464 ++#ifdef CONFIG_PAX_KERNEXEC
18465 ++ pax_close_kernel(cr0);
18466 ++#endif
18467 ++
18468 + put_cpu();
18469 +
18470 + /* If we get here and this is set then the PnP BIOS faulted on us. */
18471 +@@ -469,16 +491,24 @@ int pnp_bios_read_escd(char *data, u32 n
18472 + return status;
18473 + }
18474 +
18475 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
18476 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
18477 + {
18478 + int i;
18479 +
18480 ++#ifdef CONFIG_PAX_KERNEXEC
18481 ++ unsigned long cr0;
18482 ++#endif
18483 ++
18484 + spin_lock_init(&pnp_bios_lock);
18485 + pnp_bios_callpoint.offset = header->fields.pm16offset;
18486 + pnp_bios_callpoint.segment = PNP_CS16;
18487 +
18488 ++#ifdef CONFIG_PAX_KERNEXEC
18489 ++ pax_open_kernel(cr0);
18490 ++#endif
18491 ++
18492 + bad_bios_desc.a = 0;
18493 +- bad_bios_desc.b = 0x00409200;
18494 ++ bad_bios_desc.b = 0x00409300;
18495 +
18496 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
18497 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
18498 +@@ -492,4 +522,9 @@ void pnpbios_calls_init(union pnp_bios_i
18499 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
18500 + __va(header->fields.pm16dseg));
18501 + }
18502 ++
18503 ++#ifdef CONFIG_PAX_KERNEXEC
18504 ++ pax_close_kernel(cr0);
18505 ++#endif
18506 ++
18507 + }
18508 +diff -urNp a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
18509 +--- a/drivers/pnp/quirks.c 2008-08-20 11:16:13.000000000 -0700
18510 ++++ b/drivers/pnp/quirks.c 2008-08-20 18:36:57.000000000 -0700
18511 +@@ -201,7 +201,7 @@ static struct pnp_fixup pnp_fixups[] = {
18512 + {"CTL0045", quirk_sb16audio_resources},
18513 + {"PNP0c01", quirk_system_pci_resources},
18514 + {"PNP0c02", quirk_system_pci_resources},
18515 +- {""}
18516 ++ {"", NULL}
18517 + };
18518 +
18519 + void pnp_fixup_device(struct pnp_dev *dev)
18520 +diff -urNp a/drivers/pnp/resource.c b/drivers/pnp/resource.c
18521 +--- a/drivers/pnp/resource.c 2008-08-20 11:16:13.000000000 -0700
18522 ++++ b/drivers/pnp/resource.c 2008-08-20 18:36:57.000000000 -0700
18523 +@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
18524 + return 1;
18525 +
18526 + /* check if the resource is valid */
18527 +- if (*irq < 0 || *irq > 15)
18528 ++ if (*irq > 15)
18529 + return 0;
18530 +
18531 + /* check if the resource is reserved */
18532 +@@ -414,7 +414,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
18533 + return 1;
18534 +
18535 + /* check if the resource is valid */
18536 +- if (*dma < 0 || *dma == 4 || *dma > 7)
18537 ++ if (*dma == 4 || *dma > 7)
18538 + return 0;
18539 +
18540 + /* check if the resource is reserved */
18541 +diff -urNp a/drivers/scsi/scsi_logging.h b/drivers/scsi/scsi_logging.h
18542 +--- a/drivers/scsi/scsi_logging.h 2008-08-20 11:16:13.000000000 -0700
18543 ++++ b/drivers/scsi/scsi_logging.h 2008-08-20 18:36:57.000000000 -0700
18544 +@@ -51,7 +51,7 @@ do { \
18545 + } while (0); \
18546 + } while (0)
18547 + #else
18548 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
18549 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
18550 + #endif /* CONFIG_SCSI_LOGGING */
18551 +
18552 + /*
18553 +diff -urNp a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
18554 +--- a/drivers/serial/8250_pci.c 2008-08-20 11:16:13.000000000 -0700
18555 ++++ b/drivers/serial/8250_pci.c 2008-08-20 18:36:57.000000000 -0700
18556 +@@ -2837,7 +2837,7 @@ static struct pci_device_id serial_pci_t
18557 + PCI_ANY_ID, PCI_ANY_ID,
18558 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
18559 + 0xffff00, pbn_default },
18560 +- { 0, }
18561 ++ { 0, 0, 0, 0, 0, 0, 0 }
18562 + };
18563 +
18564 + static struct pci_driver serial_pci_driver = {
18565 +diff -urNp a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
18566 +--- a/drivers/usb/class/cdc-acm.c 2008-08-20 11:16:13.000000000 -0700
18567 ++++ b/drivers/usb/class/cdc-acm.c 2008-08-20 18:36:57.000000000 -0700
18568 +@@ -1261,7 +1261,7 @@ static struct usb_device_id acm_ids[] =
18569 + USB_CDC_ACM_PROTO_AT_CDMA) },
18570 +
18571 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
18572 +- { }
18573 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18574 + };
18575 +
18576 + MODULE_DEVICE_TABLE (usb, acm_ids);
18577 +diff -urNp a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
18578 +--- a/drivers/usb/class/usblp.c 2008-08-20 11:16:13.000000000 -0700
18579 ++++ b/drivers/usb/class/usblp.c 2008-08-20 18:36:57.000000000 -0700
18580 +@@ -227,7 +227,7 @@ static const struct quirk_printer_struct
18581 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
18582 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
18583 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
18584 +- { 0, 0 }
18585 ++ { 0, 0, 0 }
18586 + };
18587 +
18588 + static int usblp_wwait(struct usblp *usblp, int nonblock);
18589 +@@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
18590 + { USB_INTERFACE_INFO(7, 1, 2) },
18591 + { USB_INTERFACE_INFO(7, 1, 3) },
18592 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
18593 +- { } /* Terminating entry */
18594 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
18595 + };
18596 +
18597 + MODULE_DEVICE_TABLE (usb, usblp_ids);
18598 +diff -urNp a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
18599 +--- a/drivers/usb/core/hub.c 2008-08-20 11:16:13.000000000 -0700
18600 ++++ b/drivers/usb/core/hub.c 2008-08-20 18:36:57.000000000 -0700
18601 +@@ -2909,7 +2909,7 @@ static struct usb_device_id hub_id_table
18602 + .bDeviceClass = USB_CLASS_HUB},
18603 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
18604 + .bInterfaceClass = USB_CLASS_HUB},
18605 +- { } /* Terminating entry */
18606 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
18607 + };
18608 +
18609 + MODULE_DEVICE_TABLE (usb, hub_id_table);
18610 +diff -urNp a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
18611 +--- a/drivers/usb/host/ehci-pci.c 2008-08-20 11:16:13.000000000 -0700
18612 ++++ b/drivers/usb/host/ehci-pci.c 2008-08-20 18:36:57.000000000 -0700
18613 +@@ -389,7 +389,7 @@ static const struct pci_device_id pci_id
18614 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
18615 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
18616 + },
18617 +- { /* end: all zeroes */ }
18618 ++ { 0, 0, 0, 0, 0, 0, 0 }
18619 + };
18620 + MODULE_DEVICE_TABLE(pci, pci_ids);
18621 +
18622 +diff -urNp a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
18623 +--- a/drivers/usb/host/uhci-hcd.c 2008-08-20 11:16:13.000000000 -0700
18624 ++++ b/drivers/usb/host/uhci-hcd.c 2008-08-20 18:36:57.000000000 -0700
18625 +@@ -893,7 +893,7 @@ static const struct pci_device_id uhci_p
18626 + /* handle any USB UHCI controller */
18627 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
18628 + .driver_data = (unsigned long) &uhci_driver,
18629 +- }, { /* end: all zeroes */ }
18630 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
18631 + };
18632 +
18633 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
18634 +diff -urNp a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h
18635 +--- a/drivers/usb/storage/debug.h 2008-08-20 11:16:13.000000000 -0700
18636 ++++ b/drivers/usb/storage/debug.h 2008-08-20 18:36:57.000000000 -0700
18637 +@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
18638 + #define US_DEBUGPX(x...) printk( x )
18639 + #define US_DEBUG(x) x
18640 + #else
18641 +-#define US_DEBUGP(x...)
18642 +-#define US_DEBUGPX(x...)
18643 +-#define US_DEBUG(x)
18644 ++#define US_DEBUGP(x...) do {} while (0)
18645 ++#define US_DEBUGPX(x...) do {} while (0)
18646 ++#define US_DEBUG(x) do {} while (0)
18647 + #endif
18648 +
18649 + #endif
18650 +diff -urNp a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
18651 +--- a/drivers/usb/storage/usb.c 2008-08-20 11:16:13.000000000 -0700
18652 ++++ b/drivers/usb/storage/usb.c 2008-08-20 18:36:57.000000000 -0700
18653 +@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
18654 + #undef UNUSUAL_DEV
18655 + #undef USUAL_DEV
18656 + /* Terminating entry */
18657 +- { }
18658 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18659 + };
18660 +
18661 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
18662 +@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
18663 + # undef USUAL_DEV
18664 +
18665 + /* Terminating entry */
18666 +- { NULL }
18667 ++ { NULL, NULL, 0, 0, NULL }
18668 + };
18669 +
18670 +
18671 +diff -urNp a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
18672 +--- a/drivers/video/fbcmap.c 2008-08-20 11:16:13.000000000 -0700
18673 ++++ b/drivers/video/fbcmap.c 2008-08-20 18:36:57.000000000 -0700
18674 +@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
18675 + int rc, size = cmap->len * sizeof(u16);
18676 + struct fb_cmap umap;
18677 +
18678 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
18679 +- !info->fbops->fb_setcmap))
18680 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
18681 + return -EINVAL;
18682 +
18683 + memset(&umap, 0, sizeof(struct fb_cmap));
18684 +diff -urNp a/drivers/video/fbmem.c b/drivers/video/fbmem.c
18685 +--- a/drivers/video/fbmem.c 2008-08-20 11:16:13.000000000 -0700
18686 ++++ b/drivers/video/fbmem.c 2008-08-20 18:36:57.000000000 -0700
18687 +@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
18688 + image->dx += image->width + 8;
18689 + }
18690 + } else if (rotate == FB_ROTATE_UD) {
18691 +- for (x = 0; x < num && image->dx >= 0; x++) {
18692 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
18693 + info->fbops->fb_imageblit(info, image);
18694 + image->dx -= image->width + 8;
18695 + }
18696 +@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
18697 + image->dy += image->height + 8;
18698 + }
18699 + } else if (rotate == FB_ROTATE_CCW) {
18700 +- for (x = 0; x < num && image->dy >= 0; x++) {
18701 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
18702 + info->fbops->fb_imageblit(info, image);
18703 + image->dy -= image->height + 8;
18704 + }
18705 +@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
18706 + case FBIOPUT_CON2FBMAP:
18707 + if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
18708 + return - EFAULT;
18709 +- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
18710 ++ if (con2fb.console > MAX_NR_CONSOLES)
18711 + return -EINVAL;
18712 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
18713 ++ if (con2fb.framebuffer >= FB_MAX)
18714 + return -EINVAL;
18715 + #ifdef CONFIG_KMOD
18716 + if (!registered_fb[con2fb.framebuffer])
18717 +diff -urNp a/drivers/video/fbmon.c b/drivers/video/fbmon.c
18718 +--- a/drivers/video/fbmon.c 2008-08-20 11:16:13.000000000 -0700
18719 ++++ b/drivers/video/fbmon.c 2008-08-20 18:36:57.000000000 -0700
18720 +@@ -45,7 +45,7 @@
18721 + #ifdef DEBUG
18722 + #define DPRINTK(fmt, args...) printk(fmt,## args)
18723 + #else
18724 +-#define DPRINTK(fmt, args...)
18725 ++#define DPRINTK(fmt, args...) do {} while (0)
18726 + #endif
18727 +
18728 + #define FBMON_FIX_HEADER 1
18729 +diff -urNp a/drivers/video/i810/i810_accel.c b/drivers/video/i810/i810_accel.c
18730 +--- a/drivers/video/i810/i810_accel.c 2008-08-20 11:16:13.000000000 -0700
18731 ++++ b/drivers/video/i810/i810_accel.c 2008-08-20 18:36:57.000000000 -0700
18732 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
18733 + }
18734 + }
18735 + printk("ringbuffer lockup!!!\n");
18736 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
18737 + i810_report_error(mmio);
18738 + par->dev_flags |= LOCKUP;
18739 + info->pixmap.scan_align = 1;
18740 +diff -urNp a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
18741 +--- a/drivers/video/i810/i810_main.c 2008-08-20 11:16:13.000000000 -0700
18742 ++++ b/drivers/video/i810/i810_main.c 2008-08-20 18:36:57.000000000 -0700
18743 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
18744 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
18745 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
18746 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
18747 +- { 0 },
18748 ++ { 0, 0, 0, 0, 0, 0, 0 },
18749 + };
18750 +
18751 + static struct pci_driver i810fb_driver = {
18752 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
18753 + int size = ((cursor->image.width + 7) >> 3) *
18754 + cursor->image.height;
18755 + int i;
18756 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
18757 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
18758 +
18759 + if (data == NULL)
18760 + return -ENOMEM;
18761 +diff -urNp a/drivers/video/modedb.c b/drivers/video/modedb.c
18762 +--- a/drivers/video/modedb.c 2008-08-20 11:16:13.000000000 -0700
18763 ++++ b/drivers/video/modedb.c 2008-08-20 18:36:57.000000000 -0700
18764 +@@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
18765 + {
18766 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
18767 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
18768 +- 0, FB_VMODE_NONINTERLACED
18769 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18770 + }, {
18771 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
18772 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
18773 +- 0, FB_VMODE_NONINTERLACED
18774 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18775 + }, {
18776 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
18777 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
18778 +- 0, FB_VMODE_NONINTERLACED
18779 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18780 + }, {
18781 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
18782 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
18783 +- 0, FB_VMODE_INTERLACED
18784 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18785 + }, {
18786 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
18787 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
18788 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18789 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18790 + }, {
18791 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
18792 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
18793 +- 0, FB_VMODE_NONINTERLACED
18794 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18795 + }, {
18796 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
18797 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
18798 +- 0, FB_VMODE_NONINTERLACED
18799 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18800 + }, {
18801 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
18802 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
18803 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18804 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18805 + }, {
18806 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
18807 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
18808 +- 0, FB_VMODE_NONINTERLACED
18809 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18810 + }, {
18811 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
18812 + NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
18813 +- 0, FB_VMODE_INTERLACED
18814 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18815 + }, {
18816 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
18817 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
18818 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18819 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18820 + }, {
18821 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
18822 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
18823 +- 0, FB_VMODE_NONINTERLACED
18824 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18825 + }, {
18826 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
18827 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
18828 +- 0, FB_VMODE_NONINTERLACED
18829 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18830 + }, {
18831 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
18832 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
18833 +- 0, FB_VMODE_NONINTERLACED
18834 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18835 + }, {
18836 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
18837 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
18838 +- 0, FB_VMODE_NONINTERLACED
18839 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18840 + }, {
18841 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
18842 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
18843 +- 0, FB_VMODE_NONINTERLACED
18844 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18845 + }, {
18846 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
18847 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
18848 +- 0, FB_VMODE_INTERLACED
18849 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18850 + }, {
18851 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
18852 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
18853 +- 0, FB_VMODE_NONINTERLACED
18854 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18855 + }, {
18856 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
18857 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
18858 +- 0, FB_VMODE_NONINTERLACED
18859 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18860 + }, {
18861 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
18862 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
18863 +- 0, FB_VMODE_NONINTERLACED
18864 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18865 + }, {
18866 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
18867 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
18868 +- 0, FB_VMODE_NONINTERLACED
18869 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18870 + }, {
18871 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
18872 + NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
18873 +- 0, FB_VMODE_NONINTERLACED
18874 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18875 + }, {
18876 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
18877 + NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
18878 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18879 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18880 + }, {
18881 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
18882 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
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 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
18887 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
18888 +- 0, FB_VMODE_NONINTERLACED
18889 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18890 + }, {
18891 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
18892 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
18893 +- 0, FB_VMODE_NONINTERLACED
18894 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18895 + }, {
18896 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
18897 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
18898 +- 0, FB_VMODE_NONINTERLACED
18899 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18900 + }, {
18901 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
18902 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
18903 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18904 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18905 + }, {
18906 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
18907 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
18908 +- 0, FB_VMODE_NONINTERLACED
18909 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18910 + }, {
18911 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
18912 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
18913 +- 0, FB_VMODE_NONINTERLACED
18914 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18915 + }, {
18916 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
18917 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
18918 +- 0, FB_VMODE_NONINTERLACED
18919 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18920 + }, {
18921 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
18922 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
18923 +- 0, FB_VMODE_NONINTERLACED
18924 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18925 + }, {
18926 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
18927 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
18928 +- 0, FB_VMODE_NONINTERLACED
18929 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18930 + }, {
18931 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
18932 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
18933 +- 0, FB_VMODE_NONINTERLACED
18934 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18935 + }, {
18936 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
18937 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
18938 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18939 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18940 + }, {
18941 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
18942 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 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 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
18947 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
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 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
18952 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
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 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
18957 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
18958 +- 0, FB_VMODE_NONINTERLACED
18959 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18960 + }, {
18961 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
18962 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
18963 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18964 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18965 + }, {
18966 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
18967 + NULL, 70, 1800, 1440, 4000, 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 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
18972 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
18973 +- 0, FB_VMODE_NONINTERLACED
18974 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18975 + }, {
18976 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
18977 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
18978 +- 0, FB_VMODE_NONINTERLACED
18979 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18980 + }, {
18981 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
18982 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
18983 +- 0, FB_VMODE_DOUBLE
18984 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
18985 + }, {
18986 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
18987 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
18988 +- 0, FB_VMODE_DOUBLE
18989 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
18990 + }, {
18991 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
18992 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
18993 +- 0, FB_VMODE_DOUBLE
18994 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
18995 + }, {
18996 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
18997 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
18998 +- 0, FB_VMODE_DOUBLE
18999 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19000 + }, {
19001 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
19002 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
19003 +- 0, FB_VMODE_DOUBLE
19004 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19005 + }, {
19006 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
19007 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
19008 +- 0, FB_VMODE_DOUBLE
19009 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19010 + }, {
19011 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
19012 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
19013 +- 0, FB_VMODE_DOUBLE
19014 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19015 + }, {
19016 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
19017 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
19018 +- 0, FB_VMODE_DOUBLE
19019 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19020 + }, {
19021 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
19022 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
19023 +- 0, FB_VMODE_DOUBLE
19024 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19025 + }, {
19026 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
19027 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
19028 +- 0, FB_VMODE_DOUBLE
19029 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19030 + }, {
19031 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
19032 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
19033 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
19034 +- FB_VMODE_NONINTERLACED
19035 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19036 + }, {
19037 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
19038 + NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
19039 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19040 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19041 + }, {
19042 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
19043 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
19044 +- 0, FB_VMODE_NONINTERLACED
19045 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19046 + }, {
19047 + /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
19048 + NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
19049 +- 0, FB_VMODE_NONINTERLACED
19050 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19051 + },
19052 + };
19053 +
19054 +diff -urNp a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
19055 +--- a/drivers/video/uvesafb.c 2008-08-20 11:16:13.000000000 -0700
19056 ++++ b/drivers/video/uvesafb.c 2008-08-20 18:36:57.000000000 -0700
19057 +@@ -18,6 +18,7 @@
19058 + #include <linux/fb.h>
19059 + #include <linux/io.h>
19060 + #include <linux/mutex.h>
19061 ++#include <linux/moduleloader.h>
19062 + #include <video/edid.h>
19063 + #include <video/uvesafb.h>
19064 + #ifdef CONFIG_X86
19065 +@@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
19066 + NULL,
19067 + };
19068 +
19069 +- return call_usermodehelper(v86d_path, argv, envp, 1);
19070 ++ return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
19071 + }
19072 +
19073 + /*
19074 +@@ -560,18 +561,46 @@ static int __devinit uvesafb_vbe_getpmi(
19075 + {
19076 + int i, err;
19077 +
19078 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19079 ++ u8 *pmi_code;
19080 ++ unsigned long cr0;
19081 ++#endif
19082 ++
19083 + uvesafb_reset(task);
19084 + task->t.regs.eax = 0x4f0a;
19085 + task->t.regs.ebx = 0x0;
19086 + err = uvesafb_exec(task);
19087 +
19088 +- if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
19089 +- par->pmi_setpal = par->ypan = 0;
19090 +- } else {
19091 ++ par->pmi_setpal = par->ypan = 0;
19092 ++ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000)
19093 ++ return 0;
19094 ++
19095 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19096 ++ pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
19097 ++ if (pmi_code) {
19098 ++#elif !defined(CONFIG_PAX_KERNEXEC)
19099 ++ if (1) {
19100 ++#endif
19101 ++
19102 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
19103 + + task->t.regs.edi);
19104 +- par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
19105 +- par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
19106 ++
19107 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19108 ++ pax_open_kernel(cr0);
19109 ++ memcpy(pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
19110 ++ pax_close_kernel(cr0);
19111 ++#else
19112 ++ pmi_code = par->pmi_base;
19113 ++#endif
19114 ++
19115 ++ par->pmi_start = pmi_code + par->pmi_base[1];
19116 ++ par->pmi_pal = pmi_code + par->pmi_base[2];
19117 ++
19118 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19119 ++ par->pmi_start = ktva_ktla(par->pmi_start);
19120 ++ par->pmi_pal = ktva_ktla(par->pmi_pal);
19121 ++#endif
19122 ++
19123 + printk(KERN_INFO "uvesafb: protected mode interface info at "
19124 + "%04x:%04x\n",
19125 + (u16)task->t.regs.es, (u16)task->t.regs.edi);
19126 +diff -urNp a/drivers/video/vesafb.c b/drivers/video/vesafb.c
19127 +--- a/drivers/video/vesafb.c 2008-08-20 11:16:13.000000000 -0700
19128 ++++ b/drivers/video/vesafb.c 2008-08-20 18:36:57.000000000 -0700
19129 +@@ -9,6 +9,7 @@
19130 + */
19131 +
19132 + #include <linux/module.h>
19133 ++#include <linux/moduleloader.h>
19134 + #include <linux/kernel.h>
19135 + #include <linux/errno.h>
19136 + #include <linux/string.h>
19137 +@@ -53,8 +54,8 @@ static int vram_remap __initdata; /*
19138 + static int vram_total __initdata; /* Set total amount of memory */
19139 + static int pmi_setpal __read_mostly = 1; /* pmi for palette changes ??? */
19140 + static int ypan __read_mostly; /* 0..nothing, 1..ypan, 2..ywrap */
19141 +-static void (*pmi_start)(void) __read_mostly;
19142 +-static void (*pmi_pal) (void) __read_mostly;
19143 ++static void (*pmi_start)(void) __read_only;
19144 ++static void (*pmi_pal) (void) __read_only;
19145 + static int depth __read_mostly;
19146 + static int vga_compat __read_mostly;
19147 + /* --------------------------------------------------------------------- */
19148 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
19149 + unsigned int size_vmode;
19150 + unsigned int size_remap;
19151 + unsigned int size_total;
19152 ++ void *pmi_code = NULL;
19153 +
19154 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
19155 + return -ENODEV;
19156 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
19157 + size_remap = size_total;
19158 + vesafb_fix.smem_len = size_remap;
19159 +
19160 +-#ifndef __i386__
19161 +- screen_info.vesapm_seg = 0;
19162 +-#endif
19163 +-
19164 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
19165 + printk(KERN_WARNING
19166 + "vesafb: cannot reserve video memory at 0x%lx\n",
19167 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
19168 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
19169 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
19170 +
19171 ++#ifdef __i386__
19172 ++
19173 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19174 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
19175 ++ if (!pmi_code)
19176 ++#elif !defined(CONFIG_PAX_KERNEXEC)
19177 ++ if (0)
19178 ++#endif
19179 ++
19180 ++#endif
19181 ++ screen_info.vesapm_seg = 0;
19182 ++
19183 + if (screen_info.vesapm_seg) {
19184 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
19185 +- screen_info.vesapm_seg,screen_info.vesapm_off);
19186 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
19187 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
19188 + }
19189 +
19190 + if (screen_info.vesapm_seg < 0xc000)
19191 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
19192 +
19193 + if (ypan || pmi_setpal) {
19194 + unsigned short *pmi_base;
19195 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
19196 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
19197 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
19198 ++
19199 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19200 ++ unsigned long cr0;
19201 ++#endif
19202 ++
19203 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
19204 ++
19205 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19206 ++ pax_open_kernel(cr0);
19207 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
19208 ++#else
19209 ++ pmi_code = pmi_base;
19210 ++#endif
19211 ++
19212 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
19213 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
19214 ++
19215 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19216 ++ pmi_start = ktva_ktla(pmi_start);
19217 ++ pmi_pal = ktva_ktla(pmi_pal);
19218 ++ pax_close_kernel(cr0);
19219 ++#endif
19220 ++
19221 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
19222 + if (pmi_base[3]) {
19223 + printk(KERN_INFO "vesafb: pmi: ports = ");
19224 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
19225 + info->node, info->fix.id);
19226 + return 0;
19227 + err:
19228 ++
19229 ++#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
19230 ++ module_free_exec(NULL, pmi_code);
19231 ++#endif
19232 ++
19233 + if (info->screen_base)
19234 + iounmap(info->screen_base);
19235 + framebuffer_release(info);
19236 +diff -urNp a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
19237 +--- a/fs/9p/vfs_inode.c 2008-08-20 11:16:13.000000000 -0700
19238 ++++ b/fs/9p/vfs_inode.c 2008-08-20 18:36:57.000000000 -0700
19239 +@@ -1001,7 +1001,7 @@ static void *v9fs_vfs_follow_link(struct
19240 +
19241 + static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
19242 + {
19243 +- char *s = nd_get_link(nd);
19244 ++ const char *s = nd_get_link(nd);
19245 +
19246 + P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
19247 + if (!IS_ERR(s))
19248 +diff -urNp a/fs/Kconfig b/fs/Kconfig
19249 +--- a/fs/Kconfig 2008-08-20 11:16:13.000000000 -0700
19250 ++++ b/fs/Kconfig 2008-08-20 18:36:57.000000000 -0700
19251 +@@ -899,7 +899,7 @@ config PROC_FS
19252 +
19253 + config PROC_KCORE
19254 + bool "/proc/kcore support" if !ARM
19255 +- depends on PROC_FS && MMU
19256 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
19257 +
19258 + config PROC_VMCORE
19259 + bool "/proc/vmcore support (EXPERIMENTAL)"
19260 +diff -urNp a/fs/aio.c b/fs/aio.c
19261 +--- a/fs/aio.c 2008-08-20 11:16:13.000000000 -0700
19262 ++++ b/fs/aio.c 2008-08-20 18:36:57.000000000 -0700
19263 +@@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx
19264 + size += sizeof(struct io_event) * nr_events;
19265 + nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
19266 +
19267 +- if (nr_pages < 0)
19268 ++ if (nr_pages <= 0)
19269 + return -EINVAL;
19270 +
19271 + nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
19272 +diff -urNp a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
19273 +--- a/fs/autofs4/symlink.c 2008-08-20 11:16:13.000000000 -0700
19274 ++++ b/fs/autofs4/symlink.c 2008-08-20 18:36:57.000000000 -0700
19275 +@@ -15,7 +15,7 @@
19276 + static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
19277 + {
19278 + struct autofs_info *ino = autofs4_dentry_ino(dentry);
19279 +- nd_set_link(nd, (char *)ino->u.symlink);
19280 ++ nd_set_link(nd, ino->u.symlink);
19281 + return NULL;
19282 + }
19283 +
19284 +diff -urNp a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
19285 +--- a/fs/befs/linuxvfs.c 2008-08-20 11:16:13.000000000 -0700
19286 ++++ b/fs/befs/linuxvfs.c 2008-08-20 18:36:57.000000000 -0700
19287 +@@ -489,7 +489,7 @@ static void befs_put_link(struct dentry
19288 + {
19289 + befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
19290 + if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
19291 +- char *p = nd_get_link(nd);
19292 ++ const char *p = nd_get_link(nd);
19293 + if (!IS_ERR(p))
19294 + kfree(p);
19295 + }
19296 +diff -urNp a/fs/binfmt_aout.c b/fs/binfmt_aout.c
19297 +--- a/fs/binfmt_aout.c 2008-08-20 11:16:13.000000000 -0700
19298 ++++ b/fs/binfmt_aout.c 2008-08-20 18:36:57.000000000 -0700
19299 +@@ -24,6 +24,7 @@
19300 + #include <linux/binfmts.h>
19301 + #include <linux/personality.h>
19302 + #include <linux/init.h>
19303 ++#include <linux/grsecurity.h>
19304 +
19305 + #include <asm/system.h>
19306 + #include <asm/uaccess.h>
19307 +@@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
19308 + /* If the size of the dump file exceeds the rlimit, then see what would happen
19309 + if we wrote the stack, but not the data area. */
19310 + #ifdef __sparc__
19311 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
19312 + if ((dump.u_dsize + dump.u_ssize) > limit)
19313 + dump.u_dsize = 0;
19314 + #else
19315 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
19316 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
19317 + dump.u_dsize = 0;
19318 + #endif
19319 +
19320 + /* Make sure we have enough room to write the stack and data areas. */
19321 + #ifdef __sparc__
19322 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
19323 + if (dump.u_ssize > limit)
19324 + dump.u_ssize = 0;
19325 + #else
19326 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
19327 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
19328 + dump.u_ssize = 0;
19329 + #endif
19330 +@@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
19331 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
19332 + if (rlim >= RLIM_INFINITY)
19333 + rlim = ~0;
19334 ++
19335 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
19336 + if (ex.a_data + ex.a_bss > rlim)
19337 + return -ENOMEM;
19338 +
19339 +@@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
19340 +
19341 + compute_creds(bprm);
19342 + current->flags &= ~PF_FORKNOEXEC;
19343 ++
19344 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19345 ++ current->mm->pax_flags = 0UL;
19346 ++#endif
19347 ++
19348 ++#ifdef CONFIG_PAX_PAGEEXEC
19349 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
19350 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
19351 ++
19352 ++#ifdef CONFIG_PAX_EMUTRAMP
19353 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
19354 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
19355 ++#endif
19356 ++
19357 ++#ifdef CONFIG_PAX_MPROTECT
19358 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
19359 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
19360 ++#endif
19361 ++
19362 ++ }
19363 ++#endif
19364 ++
19365 + #ifdef __sparc__
19366 + if (N_MAGIC(ex) == NMAGIC) {
19367 + loff_t pos = fd_offset;
19368 +@@ -417,7 +446,7 @@ static int load_aout_binary(struct linux
19369 +
19370 + down_write(&current->mm->mmap_sem);
19371 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
19372 +- PROT_READ | PROT_WRITE | PROT_EXEC,
19373 ++ PROT_READ | PROT_WRITE,
19374 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
19375 + fd_offset + ex.a_text);
19376 + up_write(&current->mm->mmap_sem);
19377 +diff -urNp a/fs/binfmt_elf.c b/fs/binfmt_elf.c
19378 +--- a/fs/binfmt_elf.c 2008-08-20 11:16:13.000000000 -0700
19379 ++++ b/fs/binfmt_elf.c 2008-08-20 18:36:57.000000000 -0700
19380 +@@ -39,10 +39,16 @@
19381 + #include <linux/random.h>
19382 + #include <linux/elf.h>
19383 + #include <linux/utsname.h>
19384 ++#include <linux/grsecurity.h>
19385 ++
19386 + #include <asm/uaccess.h>
19387 + #include <asm/param.h>
19388 + #include <asm/page.h>
19389 +
19390 ++#ifdef CONFIG_PAX_SEGMEXEC
19391 ++#include <asm/desc.h>
19392 ++#endif
19393 ++
19394 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
19395 + static int load_elf_library(struct file *);
19396 + static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
19397 +@@ -85,6 +91,8 @@ static struct linux_binfmt elf_format =
19398 +
19399 + static int set_brk(unsigned long start, unsigned long end)
19400 + {
19401 ++ unsigned long e = end;
19402 ++
19403 + start = ELF_PAGEALIGN(start);
19404 + end = ELF_PAGEALIGN(end);
19405 + if (end > start) {
19406 +@@ -95,7 +103,7 @@ static int set_brk(unsigned long start,
19407 + if (BAD_ADDR(addr))
19408 + return addr;
19409 + }
19410 +- current->mm->start_brk = current->mm->brk = end;
19411 ++ current->mm->start_brk = current->mm->brk = e;
19412 + return 0;
19413 + }
19414 +
19415 +@@ -352,10 +360,10 @@ static unsigned long load_elf_interp(str
19416 + {
19417 + struct elf_phdr *elf_phdata;
19418 + struct elf_phdr *eppnt;
19419 +- unsigned long load_addr = 0;
19420 ++ unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
19421 + int load_addr_set = 0;
19422 + unsigned long last_bss = 0, elf_bss = 0;
19423 +- unsigned long error = ~0UL;
19424 ++ unsigned long error = -EINVAL;
19425 + unsigned long total_size;
19426 + int retval, i, size;
19427 +
19428 +@@ -401,6 +409,11 @@ static unsigned long load_elf_interp(str
19429 + goto out_close;
19430 + }
19431 +
19432 ++#ifdef CONFIG_PAX_SEGMEXEC
19433 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
19434 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
19435 ++#endif
19436 ++
19437 + eppnt = elf_phdata;
19438 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
19439 + if (eppnt->p_type == PT_LOAD) {
19440 +@@ -444,8 +457,8 @@ static unsigned long load_elf_interp(str
19441 + k = load_addr + eppnt->p_vaddr;
19442 + if (BAD_ADDR(k) ||
19443 + eppnt->p_filesz > eppnt->p_memsz ||
19444 +- eppnt->p_memsz > TASK_SIZE ||
19445 +- TASK_SIZE - eppnt->p_memsz < k) {
19446 ++ eppnt->p_memsz > pax_task_size ||
19447 ++ pax_task_size - eppnt->p_memsz < k) {
19448 + error = -ENOMEM;
19449 + goto out_close;
19450 + }
19451 +@@ -499,6 +512,177 @@ out:
19452 + return error;
19453 + }
19454 +
19455 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
19456 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
19457 ++{
19458 ++ unsigned long pax_flags = 0UL;
19459 ++
19460 ++#ifdef CONFIG_PAX_PAGEEXEC
19461 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
19462 ++ pax_flags |= MF_PAX_PAGEEXEC;
19463 ++#endif
19464 ++
19465 ++#ifdef CONFIG_PAX_SEGMEXEC
19466 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
19467 ++ pax_flags |= MF_PAX_SEGMEXEC;
19468 ++#endif
19469 ++
19470 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19471 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19472 ++ if (nx_enabled)
19473 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19474 ++ else
19475 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19476 ++ }
19477 ++#endif
19478 ++
19479 ++#ifdef CONFIG_PAX_EMUTRAMP
19480 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
19481 ++ pax_flags |= MF_PAX_EMUTRAMP;
19482 ++#endif
19483 ++
19484 ++#ifdef CONFIG_PAX_MPROTECT
19485 ++ if (elf_phdata->p_flags & PF_MPROTECT)
19486 ++ pax_flags |= MF_PAX_MPROTECT;
19487 ++#endif
19488 ++
19489 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
19490 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
19491 ++ pax_flags |= MF_PAX_RANDMMAP;
19492 ++#endif
19493 ++
19494 ++ return pax_flags;
19495 ++}
19496 ++#endif
19497 ++
19498 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19499 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
19500 ++{
19501 ++ unsigned long pax_flags = 0UL;
19502 ++
19503 ++#ifdef CONFIG_PAX_PAGEEXEC
19504 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
19505 ++ pax_flags |= MF_PAX_PAGEEXEC;
19506 ++#endif
19507 ++
19508 ++#ifdef CONFIG_PAX_SEGMEXEC
19509 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
19510 ++ pax_flags |= MF_PAX_SEGMEXEC;
19511 ++#endif
19512 ++
19513 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19514 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19515 ++ if (nx_enabled)
19516 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19517 ++ else
19518 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19519 ++ }
19520 ++#endif
19521 ++
19522 ++#ifdef CONFIG_PAX_EMUTRAMP
19523 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
19524 ++ pax_flags |= MF_PAX_EMUTRAMP;
19525 ++#endif
19526 ++
19527 ++#ifdef CONFIG_PAX_MPROTECT
19528 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
19529 ++ pax_flags |= MF_PAX_MPROTECT;
19530 ++#endif
19531 ++
19532 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
19533 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
19534 ++ pax_flags |= MF_PAX_RANDMMAP;
19535 ++#endif
19536 ++
19537 ++ return pax_flags;
19538 ++}
19539 ++#endif
19540 ++
19541 ++#ifdef CONFIG_PAX_EI_PAX
19542 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
19543 ++{
19544 ++ unsigned long pax_flags = 0UL;
19545 ++
19546 ++#ifdef CONFIG_PAX_PAGEEXEC
19547 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
19548 ++ pax_flags |= MF_PAX_PAGEEXEC;
19549 ++#endif
19550 ++
19551 ++#ifdef CONFIG_PAX_SEGMEXEC
19552 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
19553 ++ pax_flags |= MF_PAX_SEGMEXEC;
19554 ++#endif
19555 ++
19556 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19557 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19558 ++ if (nx_enabled)
19559 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19560 ++ else
19561 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19562 ++ }
19563 ++#endif
19564 ++
19565 ++#ifdef CONFIG_PAX_EMUTRAMP
19566 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
19567 ++ pax_flags |= MF_PAX_EMUTRAMP;
19568 ++#endif
19569 ++
19570 ++#ifdef CONFIG_PAX_MPROTECT
19571 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
19572 ++ pax_flags |= MF_PAX_MPROTECT;
19573 ++#endif
19574 ++
19575 ++#ifdef CONFIG_PAX_ASLR
19576 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
19577 ++ pax_flags |= MF_PAX_RANDMMAP;
19578 ++#endif
19579 ++
19580 ++ return pax_flags;
19581 ++}
19582 ++#endif
19583 ++
19584 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
19585 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
19586 ++{
19587 ++ unsigned long pax_flags = 0UL;
19588 ++
19589 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19590 ++ unsigned long i;
19591 ++#endif
19592 ++
19593 ++#ifdef CONFIG_PAX_EI_PAX
19594 ++ pax_flags = pax_parse_ei_pax(elf_ex);
19595 ++#endif
19596 ++
19597 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19598 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
19599 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
19600 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
19601 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
19602 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
19603 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
19604 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
19605 ++ return -EINVAL;
19606 ++
19607 ++#ifdef CONFIG_PAX_SOFTMODE
19608 ++ if (pax_softmode)
19609 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
19610 ++ else
19611 ++#endif
19612 ++
19613 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
19614 ++ break;
19615 ++ }
19616 ++#endif
19617 ++
19618 ++ if (0 > pax_check_flags(&pax_flags))
19619 ++ return -EINVAL;
19620 ++
19621 ++ current->mm->pax_flags = pax_flags;
19622 ++ return 0;
19623 ++}
19624 ++#endif
19625 ++
19626 + /*
19627 + * These are the functions used to load ELF style executables and shared
19628 + * libraries. There is no binary dependent code anywhere else.
19629 +@@ -515,6 +699,11 @@ static unsigned long randomize_stack_top
19630 + {
19631 + unsigned int random_variable = 0;
19632 +
19633 ++#ifdef CONFIG_PAX_RANDUSTACK
19634 ++ if (randomize_va_space)
19635 ++ return stack_top - current->mm->delta_stack;
19636 ++#endif
19637 ++
19638 + if ((current->flags & PF_RANDOMIZE) &&
19639 + !(current->personality & ADDR_NO_RANDOMIZE)) {
19640 + random_variable = get_random_int() & STACK_RND_MASK;
19641 +@@ -533,7 +722,7 @@ static int load_elf_binary(struct linux_
19642 + unsigned long load_addr = 0, load_bias = 0;
19643 + int load_addr_set = 0;
19644 + char * elf_interpreter = NULL;
19645 +- unsigned long error;
19646 ++ unsigned long error = 0;
19647 + struct elf_phdr *elf_ppnt, *elf_phdata;
19648 + unsigned long elf_bss, elf_brk;
19649 + int elf_exec_fileno;
19650 +@@ -545,12 +734,12 @@ static int load_elf_binary(struct linux_
19651 + unsigned long reloc_func_desc = 0;
19652 + struct files_struct *files;
19653 + int executable_stack = EXSTACK_DEFAULT;
19654 +- unsigned long def_flags = 0;
19655 + struct {
19656 + struct elfhdr elf_ex;
19657 + struct elfhdr interp_elf_ex;
19658 + struct exec interp_ex;
19659 + } *loc;
19660 ++ unsigned long pax_task_size = TASK_SIZE;
19661 +
19662 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
19663 + if (!loc) {
19664 +@@ -736,11 +925,79 @@ static int load_elf_binary(struct linux_
19665 +
19666 + /* OK, This is the point of no return */
19667 + current->flags &= ~PF_FORKNOEXEC;
19668 +- current->mm->def_flags = def_flags;
19669 ++
19670 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19671 ++ current->mm->pax_flags = 0UL;
19672 ++#endif
19673 ++
19674 ++#ifdef CONFIG_PAX_DLRESOLVE
19675 ++ current->mm->call_dl_resolve = 0UL;
19676 ++#endif
19677 ++
19678 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19679 ++ current->mm->call_syscall = 0UL;
19680 ++#endif
19681 ++
19682 ++#ifdef CONFIG_PAX_ASLR
19683 ++ current->mm->delta_mmap = 0UL;
19684 ++ current->mm->delta_stack = 0UL;
19685 ++#endif
19686 ++
19687 ++ current->mm->def_flags = 0;
19688 ++
19689 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
19690 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
19691 ++ send_sig(SIGKILL, current, 0);
19692 ++ goto out_free_dentry;
19693 ++ }
19694 ++#endif
19695 ++
19696 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19697 ++ pax_set_initial_flags(bprm);
19698 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
19699 ++ if (pax_set_initial_flags_func)
19700 ++ (pax_set_initial_flags_func)(bprm);
19701 ++#endif
19702 ++
19703 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19704 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
19705 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
19706 ++ current->mm->def_flags |= VM_PAGEEXEC;
19707 ++ }
19708 ++#endif
19709 ++
19710 ++#ifdef CONFIG_PAX_SEGMEXEC
19711 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
19712 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
19713 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
19714 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
19715 ++ }
19716 ++#endif
19717 ++
19718 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
19719 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19720 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
19721 ++ put_cpu_no_resched();
19722 ++ }
19723 ++#endif
19724 ++
19725 ++#ifdef CONFIG_PAX_ASLR
19726 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
19727 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
19728 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
19729 ++ }
19730 ++#endif
19731 +
19732 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
19733 + may depend on the personality. */
19734 + SET_PERSONALITY(loc->elf_ex, 0);
19735 ++
19736 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19737 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
19738 ++ executable_stack = EXSTACK_DISABLE_X;
19739 ++ else
19740 ++#endif
19741 ++
19742 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
19743 + current->personality |= READ_IMPLIES_EXEC;
19744 +
19745 +@@ -821,6 +1078,20 @@ static int load_elf_binary(struct linux_
19746 + #else
19747 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
19748 + #endif
19749 ++
19750 ++#ifdef CONFIG_PAX_RANDMMAP
19751 ++ /* PaX: randomize base address at the default exe base if requested */
19752 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
19753 ++#ifdef CONFIG_SPARC64
19754 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
19755 ++#else
19756 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
19757 ++#endif
19758 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
19759 ++ elf_flags |= MAP_FIXED;
19760 ++ }
19761 ++#endif
19762 ++
19763 + }
19764 +
19765 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
19766 +@@ -853,9 +1124,9 @@ static int load_elf_binary(struct linux_
19767 + * allowed task size. Note that p_filesz must always be
19768 + * <= p_memsz so it is only necessary to check p_memsz.
19769 + */
19770 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
19771 +- elf_ppnt->p_memsz > TASK_SIZE ||
19772 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
19773 ++ if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
19774 ++ elf_ppnt->p_memsz > pax_task_size ||
19775 ++ pax_task_size - elf_ppnt->p_memsz < k) {
19776 + /* set_brk can never work. Avoid overflows. */
19777 + send_sig(SIGKILL, current, 0);
19778 + retval = -EINVAL;
19779 +@@ -883,6 +1154,11 @@ static int load_elf_binary(struct linux_
19780 + start_data += load_bias;
19781 + end_data += load_bias;
19782 +
19783 ++#ifdef CONFIG_PAX_RANDMMAP
19784 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
19785 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
19786 ++#endif
19787 ++
19788 + /* Calling set_brk effectively mmaps the pages that we need
19789 + * for the bss and break sections. We must do this before
19790 + * mapping in the interpreter, to make sure it doesn't wind
19791 +@@ -894,9 +1170,11 @@ static int load_elf_binary(struct linux_
19792 + goto out_free_dentry;
19793 + }
19794 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
19795 +- send_sig(SIGSEGV, current, 0);
19796 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
19797 +- goto out_free_dentry;
19798 ++ /*
19799 ++ * This bss-zeroing can fail if the ELF
19800 ++ * file specifies odd protections. So
19801 ++ * we don't check the return value
19802 ++ */
19803 + }
19804 +
19805 + if (elf_interpreter) {
19806 +@@ -1142,8 +1420,10 @@ static int dump_seek(struct file *file,
19807 + unsigned long n = off;
19808 + if (n > PAGE_SIZE)
19809 + n = PAGE_SIZE;
19810 +- if (!dump_write(file, buf, n))
19811 ++ if (!dump_write(file, buf, n)) {
19812 ++ free_page((unsigned long)buf);
19813 + return 0;
19814 ++ }
19815 + off -= n;
19816 + }
19817 + free_page((unsigned long)buf);
19818 +@@ -1155,7 +1435,7 @@ static int dump_seek(struct file *file,
19819 + * Decide what to dump of a segment, part, all or none.
19820 + */
19821 + static unsigned long vma_dump_size(struct vm_area_struct *vma,
19822 +- unsigned long mm_flags)
19823 ++ unsigned long mm_flags, long signr)
19824 + {
19825 + /* The vma can be set up to tell us the answer directly. */
19826 + if (vma->vm_flags & VM_ALWAYSDUMP)
19827 +@@ -1181,7 +1461,7 @@ static unsigned long vma_dump_size(struc
19828 + if (vma->vm_file == NULL)
19829 + return 0;
19830 +
19831 +- if (FILTER(MAPPED_PRIVATE))
19832 ++ if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
19833 + goto whole;
19834 +
19835 + /*
19836 +@@ -1267,8 +1547,11 @@ static int writenote(struct memelfnote *
19837 + #undef DUMP_WRITE
19838 +
19839 + #define DUMP_WRITE(addr, nr) \
19840 ++ do { \
19841 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
19842 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
19843 +- goto end_coredump;
19844 ++ goto end_coredump; \
19845 ++ } while (0);
19846 + #define DUMP_SEEK(off) \
19847 + if (!dump_seek(file, (off))) \
19848 + goto end_coredump;
19849 +@@ -1985,7 +2268,7 @@ static int elf_core_dump(long signr, str
19850 + phdr.p_offset = offset;
19851 + phdr.p_vaddr = vma->vm_start;
19852 + phdr.p_paddr = 0;
19853 +- phdr.p_filesz = vma_dump_size(vma, mm_flags);
19854 ++ phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
19855 + phdr.p_memsz = vma->vm_end - vma->vm_start;
19856 + offset += phdr.p_filesz;
19857 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
19858 +@@ -2017,7 +2300,7 @@ static int elf_core_dump(long signr, str
19859 + unsigned long addr;
19860 + unsigned long end;
19861 +
19862 +- end = vma->vm_start + vma_dump_size(vma, mm_flags);
19863 ++ end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
19864 +
19865 + for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
19866 + struct page *page;
19867 +@@ -2037,6 +2320,7 @@ static int elf_core_dump(long signr, str
19868 + flush_cache_page(vma, addr,
19869 + page_to_pfn(page));
19870 + kaddr = kmap(page);
19871 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
19872 + if ((size += PAGE_SIZE) > limit ||
19873 + !dump_write(file, kaddr,
19874 + PAGE_SIZE)) {
19875 +diff -urNp a/fs/binfmt_flat.c b/fs/binfmt_flat.c
19876 +--- a/fs/binfmt_flat.c 2008-08-20 11:16:13.000000000 -0700
19877 ++++ b/fs/binfmt_flat.c 2008-08-20 18:36:57.000000000 -0700
19878 +@@ -560,7 +560,9 @@ static int load_flat_file(struct linux_b
19879 + realdatastart = (unsigned long) -ENOMEM;
19880 + printk("Unable to allocate RAM for process data, errno %d\n",
19881 + (int)-realdatastart);
19882 ++ down_write(&current->mm->mmap_sem);
19883 + do_munmap(current->mm, textpos, text_len);
19884 ++ up_write(&current->mm->mmap_sem);
19885 + ret = realdatastart;
19886 + goto err;
19887 + }
19888 +@@ -582,8 +584,10 @@ static int load_flat_file(struct linux_b
19889 + }
19890 + if (result >= (unsigned long)-4096) {
19891 + printk("Unable to read data+bss, errno %d\n", (int)-result);
19892 ++ down_write(&current->mm->mmap_sem);
19893 + do_munmap(current->mm, textpos, text_len);
19894 + do_munmap(current->mm, realdatastart, data_len + extra);
19895 ++ up_write(&current->mm->mmap_sem);
19896 + ret = result;
19897 + goto err;
19898 + }
19899 +@@ -656,8 +660,10 @@ static int load_flat_file(struct linux_b
19900 + }
19901 + if (result >= (unsigned long)-4096) {
19902 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
19903 ++ down_write(&current->mm->mmap_sem);
19904 + do_munmap(current->mm, textpos, text_len + data_len + extra +
19905 + MAX_SHARED_LIBS * sizeof(unsigned long));
19906 ++ up_write(&current->mm->mmap_sem);
19907 + ret = result;
19908 + goto err;
19909 + }
19910 +diff -urNp a/fs/binfmt_misc.c b/fs/binfmt_misc.c
19911 +--- a/fs/binfmt_misc.c 2008-08-20 11:16:13.000000000 -0700
19912 ++++ b/fs/binfmt_misc.c 2008-08-20 18:36:57.000000000 -0700
19913 +@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
19914 + struct files_struct *files = NULL;
19915 +
19916 + retval = -ENOEXEC;
19917 +- if (!enabled)
19918 ++ if (!enabled || bprm->misc)
19919 + goto _ret;
19920 +
19921 ++ bprm->misc++;
19922 ++
19923 + /* to keep locking time low, we copy the interpreter string */
19924 + read_lock(&entries_lock);
19925 + fmt = check_file(bprm);
19926 +@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
19927 + static struct tree_descr bm_files[] = {
19928 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
19929 + [3] = {"register", &bm_register_operations, S_IWUSR},
19930 +- /* last one */ {""}
19931 ++ /* last one */ {"", NULL, 0}
19932 + };
19933 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
19934 + if (!err)
19935 +diff -urNp a/fs/buffer.c b/fs/buffer.c
19936 +--- a/fs/buffer.c 2008-08-20 11:16:13.000000000 -0700
19937 ++++ b/fs/buffer.c 2008-08-20 18:36:57.000000000 -0700
19938 +@@ -41,6 +41,7 @@
19939 + #include <linux/bitops.h>
19940 + #include <linux/mpage.h>
19941 + #include <linux/bit_spinlock.h>
19942 ++#include <linux/grsecurity.h>
19943 +
19944 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
19945 +
19946 +@@ -2188,6 +2189,7 @@ int generic_cont_expand_simple(struct in
19947 +
19948 + err = -EFBIG;
19949 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
19950 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
19951 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
19952 + send_sig(SIGXFSZ, current, 0);
19953 + goto out;
19954 +diff -urNp a/fs/cifs/cifs_uniupr.h b/fs/cifs/cifs_uniupr.h
19955 +--- a/fs/cifs/cifs_uniupr.h 2008-08-20 11:16:13.000000000 -0700
19956 ++++ b/fs/cifs/cifs_uniupr.h 2008-08-20 18:36:57.000000000 -0700
19957 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
19958 + {0x0490, 0x04cc, UniCaseRangeU0490},
19959 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
19960 + {0xff40, 0xff5a, UniCaseRangeUff40},
19961 +- {0}
19962 ++ {0, 0, NULL}
19963 + };
19964 + #endif
19965 +
19966 +diff -urNp a/fs/cifs/link.c b/fs/cifs/link.c
19967 +--- a/fs/cifs/link.c 2008-08-20 11:16:13.000000000 -0700
19968 ++++ b/fs/cifs/link.c 2008-08-20 18:36:57.000000000 -0700
19969 +@@ -355,7 +355,7 @@ cifs_readlink(struct dentry *direntry, c
19970 +
19971 + void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
19972 + {
19973 +- char *p = nd_get_link(nd);
19974 ++ const char *p = nd_get_link(nd);
19975 + if (!IS_ERR(p))
19976 + kfree(p);
19977 + }
19978 +diff -urNp a/fs/compat.c b/fs/compat.c
19979 +--- a/fs/compat.c 2008-08-20 11:16:13.000000000 -0700
19980 ++++ b/fs/compat.c 2008-08-20 18:36:57.000000000 -0700
19981 +@@ -50,6 +50,7 @@
19982 + #include <linux/poll.h>
19983 + #include <linux/mm.h>
19984 + #include <linux/eventpoll.h>
19985 ++#include <linux/grsecurity.h>
19986 +
19987 + #include <asm/uaccess.h>
19988 + #include <asm/mmu_context.h>
19989 +@@ -1293,14 +1294,12 @@ static int compat_copy_strings(int argc,
19990 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
19991 + struct page *page;
19992 +
19993 +-#ifdef CONFIG_STACK_GROWSUP
19994 + ret = expand_stack_downwards(bprm->vma, pos);
19995 + if (ret < 0) {
19996 + /* We've exceed the stack rlimit. */
19997 + ret = -E2BIG;
19998 + goto out;
19999 + }
20000 +-#endif
20001 + ret = get_user_pages(current, bprm->mm, pos,
20002 + 1, 1, 1, &page, NULL);
20003 + if (ret <= 0) {
20004 +@@ -1346,6 +1345,11 @@ int compat_do_execve(char * filename,
20005 + compat_uptr_t __user *envp,
20006 + struct pt_regs * regs)
20007 + {
20008 ++#ifdef CONFIG_GRKERNSEC
20009 ++ struct file *old_exec_file;
20010 ++ struct acl_subject_label *old_acl;
20011 ++ struct rlimit old_rlim[RLIM_NLIMITS];
20012 ++#endif
20013 + struct linux_binprm *bprm;
20014 + struct file *file;
20015 + int retval;
20016 +@@ -1366,6 +1370,14 @@ int compat_do_execve(char * filename,
20017 + bprm->filename = filename;
20018 + bprm->interp = filename;
20019 +
20020 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
20021 ++ retval = -EAGAIN;
20022 ++ if (gr_handle_nproc())
20023 ++ goto out_file;
20024 ++ retval = -EACCES;
20025 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
20026 ++ goto out_file;
20027 ++
20028 + retval = bprm_mm_init(bprm);
20029 + if (retval)
20030 + goto out_file;
20031 +@@ -1399,8 +1411,36 @@ int compat_do_execve(char * filename,
20032 + if (retval < 0)
20033 + goto out;
20034 +
20035 ++ if (!gr_tpe_allow(file)) {
20036 ++ retval = -EACCES;
20037 ++ goto out;
20038 ++ }
20039 ++
20040 ++ if (gr_check_crash_exec(file)) {
20041 ++ retval = -EACCES;
20042 ++ goto out;
20043 ++ }
20044 ++
20045 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
20046 ++
20047 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
20048 ++
20049 ++#ifdef CONFIG_GRKERNSEC
20050 ++ old_acl = current->acl;
20051 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
20052 ++ old_exec_file = current->exec_file;
20053 ++ get_file(file);
20054 ++ current->exec_file = file;
20055 ++#endif
20056 ++
20057 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
20058 ++
20059 + retval = search_binary_handler(bprm, regs);
20060 + if (retval >= 0) {
20061 ++#ifdef CONFIG_GRKERNSEC
20062 ++ if (old_exec_file)
20063 ++ fput(old_exec_file);
20064 ++#endif
20065 + /* execve success */
20066 + security_bprm_free(bprm);
20067 + acct_update_integrals(current);
20068 +@@ -1408,6 +1448,13 @@ int compat_do_execve(char * filename,
20069 + return retval;
20070 + }
20071 +
20072 ++#ifdef CONFIG_GRKERNSEC
20073 ++ current->acl = old_acl;
20074 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
20075 ++ fput(current->exec_file);
20076 ++ current->exec_file = old_exec_file;
20077 ++#endif
20078 ++
20079 + out:
20080 + if (bprm->security)
20081 + security_bprm_free(bprm);
20082 +diff -urNp a/fs/compat_ioctl.c b/fs/compat_ioctl.c
20083 +--- a/fs/compat_ioctl.c 2008-08-20 11:16:13.000000000 -0700
20084 ++++ b/fs/compat_ioctl.c 2008-08-20 18:36:57.000000000 -0700
20085 +@@ -1889,15 +1889,15 @@ struct ioctl_trans {
20086 + };
20087 +
20088 + #define HANDLE_IOCTL(cmd,handler) \
20089 +- { (cmd), (ioctl_trans_handler_t)(handler) },
20090 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
20091 +
20092 + /* pointer to compatible structure or no argument */
20093 + #define COMPATIBLE_IOCTL(cmd) \
20094 +- { (cmd), do_ioctl32_pointer },
20095 ++ { (cmd), do_ioctl32_pointer, NULL },
20096 +
20097 + /* argument is an unsigned long integer, not a pointer */
20098 + #define ULONG_IOCTL(cmd) \
20099 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
20100 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
20101 +
20102 + /* ioctl should not be warned about even if it's not implemented.
20103 + Valid reasons to use this:
20104 +diff -urNp a/fs/debugfs/inode.c b/fs/debugfs/inode.c
20105 +--- a/fs/debugfs/inode.c 2008-08-20 11:16:13.000000000 -0700
20106 ++++ b/fs/debugfs/inode.c 2008-08-20 18:36:57.000000000 -0700
20107 +@@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
20108 +
20109 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
20110 + {
20111 +- static struct tree_descr debug_files[] = {{""}};
20112 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
20113 +
20114 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
20115 + }
20116 +diff -urNp a/fs/exec.c b/fs/exec.c
20117 +--- a/fs/exec.c 2008-08-20 11:16:13.000000000 -0700
20118 ++++ b/fs/exec.c 2008-08-20 18:36:57.000000000 -0700
20119 +@@ -51,6 +51,8 @@
20120 + #include <linux/tsacct_kern.h>
20121 + #include <linux/cn_proc.h>
20122 + #include <linux/audit.h>
20123 ++#include <linux/random.h>
20124 ++#include <linux/grsecurity.h>
20125 +
20126 + #include <asm/uaccess.h>
20127 + #include <asm/mmu_context.h>
20128 +@@ -60,6 +62,11 @@
20129 + #include <linux/kmod.h>
20130 + #endif
20131 +
20132 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
20133 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
20134 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
20135 ++#endif
20136 ++
20137 + int core_uses_pid;
20138 + char core_pattern[CORENAME_MAX_SIZE] = "core";
20139 + int suid_dumpable = 0;
20140 +@@ -158,18 +165,10 @@ static struct page *get_arg_page(struct
20141 + int write)
20142 + {
20143 + struct page *page;
20144 +- int ret;
20145 +
20146 +-#ifdef CONFIG_STACK_GROWSUP
20147 +- if (write) {
20148 +- ret = expand_stack_downwards(bprm->vma, pos);
20149 +- if (ret < 0)
20150 +- return NULL;
20151 +- }
20152 +-#endif
20153 +- ret = get_user_pages(current, bprm->mm, pos,
20154 +- 1, write, 1, &page, NULL);
20155 +- if (ret <= 0)
20156 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
20157 ++ return NULL;
20158 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
20159 + return NULL;
20160 +
20161 + if (write) {
20162 +@@ -242,6 +241,11 @@ static int __bprm_mm_init(struct linux_b
20163 + vma->vm_start = vma->vm_end - PAGE_SIZE;
20164 +
20165 + vma->vm_flags = VM_STACK_FLAGS;
20166 ++
20167 ++#ifdef CONFIG_PAX_SEGMEXEC
20168 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
20169 ++#endif
20170 ++
20171 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
20172 + err = insert_vm_struct(mm, vma);
20173 + if (err) {
20174 +@@ -254,6 +258,11 @@ static int __bprm_mm_init(struct linux_b
20175 +
20176 + bprm->p = vma->vm_end - sizeof(void *);
20177 +
20178 ++#ifdef CONFIG_PAX_RANDUSTACK
20179 ++ if (randomize_va_space)
20180 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
20181 ++#endif
20182 ++
20183 + return 0;
20184 +
20185 + err:
20186 +@@ -377,7 +386,7 @@ static int count(char __user * __user *
20187 + if (!p)
20188 + break;
20189 + argv++;
20190 +- if(++i > max)
20191 ++ if (++i > max)
20192 + return -E2BIG;
20193 + cond_resched();
20194 + }
20195 +@@ -517,6 +526,10 @@ static int shift_arg_pages(struct vm_are
20196 + if (vma != find_vma(mm, new_start))
20197 + return -EFAULT;
20198 +
20199 ++#ifdef CONFIG_PAX_SEGMEXEC
20200 ++ BUG_ON(pax_find_mirror_vma(vma));
20201 ++#endif
20202 ++
20203 + /*
20204 + * cover the whole range: [new_start, old_end)
20205 + */
20206 +@@ -605,6 +618,14 @@ int setup_arg_pages(struct linux_binprm
20207 + bprm->exec -= stack_shift;
20208 +
20209 + down_write(&mm->mmap_sem);
20210 ++
20211 ++ /* Move stack pages down in memory. */
20212 ++ if (stack_shift) {
20213 ++ ret = shift_arg_pages(vma, stack_shift);
20214 ++ if (ret)
20215 ++ goto out_unlock;
20216 ++ }
20217 ++
20218 + vm_flags = VM_STACK_FLAGS;
20219 +
20220 + /*
20221 +@@ -618,21 +639,24 @@ int setup_arg_pages(struct linux_binprm
20222 + vm_flags &= ~VM_EXEC;
20223 + vm_flags |= mm->def_flags;
20224 +
20225 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20226 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
20227 ++ vm_flags &= ~VM_EXEC;
20228 ++
20229 ++#ifdef CONFIG_PAX_MPROTECT
20230 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
20231 ++ vm_flags &= ~VM_MAYEXEC;
20232 ++#endif
20233 ++
20234 ++ }
20235 ++#endif
20236 ++
20237 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
20238 + vm_flags);
20239 + if (ret)
20240 + goto out_unlock;
20241 + BUG_ON(prev != vma);
20242 +
20243 +- /* Move stack pages down in memory. */
20244 +- if (stack_shift) {
20245 +- ret = shift_arg_pages(vma, stack_shift);
20246 +- if (ret) {
20247 +- up_write(&mm->mmap_sem);
20248 +- return ret;
20249 +- }
20250 +- }
20251 +-
20252 + #ifdef CONFIG_STACK_GROWSUP
20253 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
20254 + #else
20255 +@@ -644,7 +668,7 @@ int setup_arg_pages(struct linux_binprm
20256 +
20257 + out_unlock:
20258 + up_write(&mm->mmap_sem);
20259 +- return 0;
20260 ++ return ret;
20261 + }
20262 + EXPORT_SYMBOL(setup_arg_pages);
20263 +
20264 +@@ -663,7 +687,7 @@ struct file *open_exec(const char *name)
20265 + struct inode *inode = nd.path.dentry->d_inode;
20266 + file = ERR_PTR(-EACCES);
20267 + if (S_ISREG(inode->i_mode)) {
20268 +- int err = vfs_permission(&nd, MAY_EXEC);
20269 ++ err = vfs_permission(&nd, MAY_EXEC);
20270 + file = ERR_PTR(err);
20271 + if (!err) {
20272 + file = nameidata_to_filp(&nd,
20273 +@@ -1280,6 +1304,11 @@ int do_execve(char * filename,
20274 + char __user *__user *envp,
20275 + struct pt_regs * regs)
20276 + {
20277 ++#ifdef CONFIG_GRKERNSEC
20278 ++ struct file *old_exec_file;
20279 ++ struct acl_subject_label *old_acl;
20280 ++ struct rlimit old_rlim[RLIM_NLIMITS];
20281 ++#endif
20282 + struct linux_binprm *bprm;
20283 + struct file *file;
20284 + unsigned long env_p;
20285 +@@ -1295,6 +1324,20 @@ int do_execve(char * filename,
20286 + if (IS_ERR(file))
20287 + goto out_kfree;
20288 +
20289 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
20290 ++
20291 ++ if (gr_handle_nproc()) {
20292 ++ allow_write_access(file);
20293 ++ fput(file);
20294 ++ return -EAGAIN;
20295 ++ }
20296 ++
20297 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
20298 ++ allow_write_access(file);
20299 ++ fput(file);
20300 ++ return -EACCES;
20301 ++ }
20302 ++
20303 + sched_exec();
20304 +
20305 + bprm->file = file;
20306 +@@ -1336,8 +1379,38 @@ int do_execve(char * filename,
20307 + goto out;
20308 + bprm->argv_len = env_p - bprm->p;
20309 +
20310 ++ if (!gr_tpe_allow(file)) {
20311 ++ retval = -EACCES;
20312 ++ goto out;
20313 ++ }
20314 ++
20315 ++ if (gr_check_crash_exec(file)) {
20316 ++ retval = -EACCES;
20317 ++ goto out;
20318 ++ }
20319 ++
20320 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
20321 ++
20322 ++ gr_handle_exec_args(bprm, argv);
20323 ++
20324 ++#ifdef CONFIG_GRKERNSEC
20325 ++ old_acl = current->acl;
20326 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
20327 ++ old_exec_file = current->exec_file;
20328 ++ get_file(file);
20329 ++ current->exec_file = file;
20330 ++#endif
20331 ++
20332 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
20333 ++ if (retval < 0)
20334 ++ goto out_fail;
20335 ++
20336 + retval = search_binary_handler(bprm,regs);
20337 + if (retval >= 0) {
20338 ++#ifdef CONFIG_GRKERNSEC
20339 ++ if (old_exec_file)
20340 ++ fput(old_exec_file);
20341 ++#endif
20342 + /* execve success */
20343 + free_arg_pages(bprm);
20344 + security_bprm_free(bprm);
20345 +@@ -1346,6 +1419,14 @@ int do_execve(char * filename,
20346 + return retval;
20347 + }
20348 +
20349 ++out_fail:
20350 ++#ifdef CONFIG_GRKERNSEC
20351 ++ current->acl = old_acl;
20352 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
20353 ++ fput(current->exec_file);
20354 ++ current->exec_file = old_exec_file;
20355 ++#endif
20356 ++
20357 + out:
20358 + free_arg_pages(bprm);
20359 + if (bprm->security)
20360 +@@ -1510,6 +1591,116 @@ out:
20361 + return ispipe;
20362 + }
20363 +
20364 ++int pax_check_flags(unsigned long *flags)
20365 ++{
20366 ++ int retval = 0;
20367 ++
20368 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
20369 ++ if (*flags & MF_PAX_SEGMEXEC)
20370 ++ {
20371 ++ *flags &= ~MF_PAX_SEGMEXEC;
20372 ++ retval = -EINVAL;
20373 ++ }
20374 ++#endif
20375 ++
20376 ++ if ((*flags & MF_PAX_PAGEEXEC)
20377 ++
20378 ++#ifdef CONFIG_PAX_PAGEEXEC
20379 ++ && (*flags & MF_PAX_SEGMEXEC)
20380 ++#endif
20381 ++
20382 ++ )
20383 ++ {
20384 ++ *flags &= ~MF_PAX_PAGEEXEC;
20385 ++ retval = -EINVAL;
20386 ++ }
20387 ++
20388 ++ if ((*flags & MF_PAX_MPROTECT)
20389 ++
20390 ++#ifdef CONFIG_PAX_MPROTECT
20391 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
20392 ++#endif
20393 ++
20394 ++ )
20395 ++ {
20396 ++ *flags &= ~MF_PAX_MPROTECT;
20397 ++ retval = -EINVAL;
20398 ++ }
20399 ++
20400 ++ if ((*flags & MF_PAX_EMUTRAMP)
20401 ++
20402 ++#ifdef CONFIG_PAX_EMUTRAMP
20403 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
20404 ++#endif
20405 ++
20406 ++ )
20407 ++ {
20408 ++ *flags &= ~MF_PAX_EMUTRAMP;
20409 ++ retval = -EINVAL;
20410 ++ }
20411 ++
20412 ++ return retval;
20413 ++}
20414 ++
20415 ++EXPORT_SYMBOL(pax_check_flags);
20416 ++
20417 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20418 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
20419 ++{
20420 ++ struct task_struct *tsk = current;
20421 ++ struct mm_struct *mm = current->mm;
20422 ++ char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
20423 ++ char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
20424 ++ char *path_exec = NULL;
20425 ++ char *path_fault = NULL;
20426 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
20427 ++
20428 ++ if (buffer_exec && buffer_fault) {
20429 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
20430 ++
20431 ++ down_read(&mm->mmap_sem);
20432 ++ vma = mm->mmap;
20433 ++ while (vma && (!vma_exec || !vma_fault)) {
20434 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
20435 ++ vma_exec = vma;
20436 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
20437 ++ vma_fault = vma;
20438 ++ vma = vma->vm_next;
20439 ++ }
20440 ++ if (vma_exec) {
20441 ++ struct path path = {vma_exec->vm_file->f_path.mnt, vma_exec->vm_file->f_path.dentry};
20442 ++ path_exec = d_path(&path, buffer_exec, PAGE_SIZE);
20443 ++ if (IS_ERR(path_exec))
20444 ++ path_exec = "<path too long>";
20445 ++ }
20446 ++ if (vma_fault) {
20447 ++ start = vma_fault->vm_start;
20448 ++ end = vma_fault->vm_end;
20449 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
20450 ++ if (vma_fault->vm_file) {
20451 ++ struct path path = {vma_fault->vm_file->f_path.mnt, vma_fault->vm_file->f_path.dentry};
20452 ++ path_fault = d_path(&path, buffer_fault, PAGE_SIZE);
20453 ++ if (IS_ERR(path_fault))
20454 ++ path_fault = "<path too long>";
20455 ++ } else
20456 ++ path_fault = "<anonymous mapping>";
20457 ++ }
20458 ++ up_read(&mm->mmap_sem);
20459 ++ }
20460 ++ if (tsk->signal->curr_ip)
20461 ++ 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);
20462 ++ else
20463 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
20464 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
20465 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
20466 ++ tsk->uid, tsk->euid, pc, sp);
20467 ++ free_page((unsigned long)buffer_exec);
20468 ++ free_page((unsigned long)buffer_fault);
20469 ++ pax_report_insns(pc, sp);
20470 ++ do_coredump(SIGKILL, SIGKILL, regs);
20471 ++}
20472 ++#endif
20473 ++
20474 + static void zap_process(struct task_struct *start)
20475 + {
20476 + struct task_struct *t;
20477 +@@ -1707,6 +1898,10 @@ int do_coredump(long signr, int exit_cod
20478 + */
20479 + clear_thread_flag(TIF_SIGPENDING);
20480 +
20481 ++ if (signr == SIGKILL || signr == SIGILL)
20482 ++ gr_handle_brute_attach(current);
20483 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
20484 ++
20485 + /*
20486 + * lock_kernel() because format_corename() is controlled by sysctl, which
20487 + * uses lock_kernel()
20488 +@@ -1727,6 +1922,8 @@ int do_coredump(long signr, int exit_cod
20489 +
20490 + if (ispipe) {
20491 + helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
20492 ++ if (!helper_argv)
20493 ++ goto fail_unlock;
20494 + /* Terminate the string before the first option */
20495 + delimit = strchr(corename, ' ');
20496 + if (delimit)
20497 +diff -urNp a/fs/ext2/balloc.c b/fs/ext2/balloc.c
20498 +--- a/fs/ext2/balloc.c 2008-08-20 11:16:13.000000000 -0700
20499 ++++ b/fs/ext2/balloc.c 2008-08-20 18:36:57.000000000 -0700
20500 +@@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
20501 +
20502 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20503 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
20504 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20505 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20506 + sbi->s_resuid != current->fsuid &&
20507 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20508 + return 0;
20509 +diff -urNp a/fs/ext3/balloc.c b/fs/ext3/balloc.c
20510 +--- a/fs/ext3/balloc.c 2008-08-20 11:16:13.000000000 -0700
20511 ++++ b/fs/ext3/balloc.c 2008-08-20 18:36:57.000000000 -0700
20512 +@@ -1421,7 +1421,7 @@ static int ext3_has_free_blocks(struct e
20513 +
20514 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20515 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
20516 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20517 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20518 + sbi->s_resuid != current->fsuid &&
20519 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20520 + return 0;
20521 +diff -urNp a/fs/ext3/namei.c b/fs/ext3/namei.c
20522 +--- a/fs/ext3/namei.c 2008-08-20 11:16:13.000000000 -0700
20523 ++++ b/fs/ext3/namei.c 2008-08-20 18:36:57.000000000 -0700
20524 +@@ -1166,9 +1166,9 @@ static struct ext3_dir_entry_2 *do_split
20525 + u32 hash2;
20526 + struct dx_map_entry *map;
20527 + char *data1 = (*bh)->b_data, *data2;
20528 +- unsigned split, move, size, i;
20529 ++ unsigned split, move, size;
20530 + struct ext3_dir_entry_2 *de = NULL, *de2;
20531 +- int err = 0;
20532 ++ int i, err = 0;
20533 +
20534 + bh2 = ext3_append (handle, dir, &newblock, &err);
20535 + if (!(bh2)) {
20536 +diff -urNp a/fs/ext3/xattr.c b/fs/ext3/xattr.c
20537 +--- a/fs/ext3/xattr.c 2008-08-20 11:16:13.000000000 -0700
20538 ++++ b/fs/ext3/xattr.c 2008-08-20 18:36:57.000000000 -0700
20539 +@@ -89,8 +89,8 @@
20540 + printk("\n"); \
20541 + } while (0)
20542 + #else
20543 +-# define ea_idebug(f...)
20544 +-# define ea_bdebug(f...)
20545 ++# define ea_idebug(f...) do {} while (0)
20546 ++# define ea_bdebug(f...) do {} while (0)
20547 + #endif
20548 +
20549 + static void ext3_xattr_cache_insert(struct buffer_head *);
20550 +diff -urNp a/fs/ext4/balloc.c b/fs/ext4/balloc.c
20551 +--- a/fs/ext4/balloc.c 2008-08-20 11:16:13.000000000 -0700
20552 ++++ b/fs/ext4/balloc.c 2008-08-20 18:36:57.000000000 -0700
20553 +@@ -1557,7 +1557,7 @@ static int ext4_has_free_blocks(struct e
20554 +
20555 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20556 + root_blocks = ext4_r_blocks_count(sbi->s_es);
20557 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20558 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20559 + sbi->s_resuid != current->fsuid &&
20560 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20561 + return 0;
20562 +diff -urNp a/fs/ext4/namei.c b/fs/ext4/namei.c
20563 +--- a/fs/ext4/namei.c 2008-08-20 11:16:13.000000000 -0700
20564 ++++ b/fs/ext4/namei.c 2008-08-20 18:36:57.000000000 -0700
20565 +@@ -1168,9 +1168,9 @@ static struct ext4_dir_entry_2 *do_split
20566 + u32 hash2;
20567 + struct dx_map_entry *map;
20568 + char *data1 = (*bh)->b_data, *data2;
20569 +- unsigned split, move, size, i;
20570 ++ unsigned split, move, size;
20571 + struct ext4_dir_entry_2 *de = NULL, *de2;
20572 +- int err = 0;
20573 ++ int i, err = 0;
20574 +
20575 + bh2 = ext4_append (handle, dir, &newblock, &err);
20576 + if (!(bh2)) {
20577 +diff -urNp a/fs/fcntl.c b/fs/fcntl.c
20578 +--- a/fs/fcntl.c 2008-08-20 11:16:13.000000000 -0700
20579 ++++ b/fs/fcntl.c 2008-08-20 18:36:57.000000000 -0700
20580 +@@ -19,6 +19,7 @@
20581 + #include <linux/signal.h>
20582 + #include <linux/rcupdate.h>
20583 + #include <linux/pid_namespace.h>
20584 ++#include <linux/grsecurity.h>
20585 +
20586 + #include <asm/poll.h>
20587 + #include <asm/siginfo.h>
20588 +@@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
20589 + struct fdtable *fdt;
20590 +
20591 + error = -EINVAL;
20592 ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
20593 + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20594 + goto out;
20595 +
20596 +@@ -83,6 +85,7 @@ repeat:
20597 + fdt->max_fds, start);
20598 +
20599 + error = -EMFILE;
20600 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
20601 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20602 + goto out;
20603 +
20604 +@@ -144,6 +147,8 @@ asmlinkage long sys_dup2(unsigned int ol
20605 + struct files_struct * files = current->files;
20606 + struct fdtable *fdt;
20607 +
20608 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
20609 ++
20610 + spin_lock(&files->file_lock);
20611 + if (!(file = fcheck(oldfd)))
20612 + goto out_unlock;
20613 +@@ -463,7 +468,8 @@ static inline int sigio_perm(struct task
20614 + return (((fown->euid == 0) ||
20615 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
20616 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
20617 +- !security_file_send_sigiotask(p, fown, sig));
20618 ++ !security_file_send_sigiotask(p, fown, sig) &&
20619 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
20620 + }
20621 +
20622 + static void send_sigio_to_task(struct task_struct *p,
20623 +diff -urNp a/fs/fuse/control.c b/fs/fuse/control.c
20624 +--- a/fs/fuse/control.c 2008-08-20 11:16:13.000000000 -0700
20625 ++++ b/fs/fuse/control.c 2008-08-20 18:36:57.000000000 -0700
20626 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
20627 +
20628 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
20629 + {
20630 +- struct tree_descr empty_descr = {""};
20631 ++ struct tree_descr empty_descr = {"", NULL, 0};
20632 + struct fuse_conn *fc;
20633 + int err;
20634 +
20635 +diff -urNp a/fs/fuse/dir.c b/fs/fuse/dir.c
20636 +--- a/fs/fuse/dir.c 2008-08-20 11:16:13.000000000 -0700
20637 ++++ b/fs/fuse/dir.c 2008-08-20 18:36:57.000000000 -0700
20638 +@@ -1031,7 +1031,7 @@ static char *read_link(struct dentry *de
20639 + return link;
20640 + }
20641 +
20642 +-static void free_link(char *link)
20643 ++static void free_link(const char *link)
20644 + {
20645 + if (!IS_ERR(link))
20646 + free_page((unsigned long) link);
20647 +diff -urNp a/fs/hfs/inode.c b/fs/hfs/inode.c
20648 +--- a/fs/hfs/inode.c 2008-08-20 11:16:13.000000000 -0700
20649 ++++ b/fs/hfs/inode.c 2008-08-20 18:36:57.000000000 -0700
20650 +@@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
20651 +
20652 + if (S_ISDIR(main_inode->i_mode)) {
20653 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
20654 +- /* panic? */;
20655 ++ {/* panic? */}
20656 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
20657 + sizeof(struct hfs_cat_dir));
20658 + if (rec.type != HFS_CDR_DIR ||
20659 +@@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
20660 + sizeof(struct hfs_cat_file));
20661 + } else {
20662 + if (fd.entrylength < sizeof(struct hfs_cat_file))
20663 +- /* panic? */;
20664 ++ {/* panic? */}
20665 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
20666 + sizeof(struct hfs_cat_file));
20667 + if (rec.type != HFS_CDR_FIL ||
20668 +diff -urNp a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
20669 +--- a/fs/hfsplus/inode.c 2008-08-20 11:16:13.000000000 -0700
20670 ++++ b/fs/hfsplus/inode.c 2008-08-20 18:36:57.000000000 -0700
20671 +@@ -422,7 +422,7 @@ int hfsplus_cat_read_inode(struct inode
20672 + struct hfsplus_cat_folder *folder = &entry.folder;
20673 +
20674 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
20675 +- /* panic? */;
20676 ++ {/* panic? */}
20677 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
20678 + sizeof(struct hfsplus_cat_folder));
20679 + hfsplus_get_perms(inode, &folder->permissions, 1);
20680 +@@ -439,7 +439,7 @@ int hfsplus_cat_read_inode(struct inode
20681 + struct hfsplus_cat_file *file = &entry.file;
20682 +
20683 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
20684 +- /* panic? */;
20685 ++ {/* panic? */}
20686 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
20687 + sizeof(struct hfsplus_cat_file));
20688 +
20689 +@@ -495,7 +495,7 @@ int hfsplus_cat_write_inode(struct inode
20690 + struct hfsplus_cat_folder *folder = &entry.folder;
20691 +
20692 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
20693 +- /* panic? */;
20694 ++ {/* panic? */}
20695 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
20696 + sizeof(struct hfsplus_cat_folder));
20697 + /* simple node checks? */
20698 +@@ -517,7 +517,7 @@ int hfsplus_cat_write_inode(struct inode
20699 + struct hfsplus_cat_file *file = &entry.file;
20700 +
20701 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
20702 +- /* panic? */;
20703 ++ {/* panic? */}
20704 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
20705 + sizeof(struct hfsplus_cat_file));
20706 + hfsplus_inode_write_fork(inode, &file->data_fork);
20707 +diff -urNp a/fs/jffs2/debug.h b/fs/jffs2/debug.h
20708 +--- a/fs/jffs2/debug.h 2008-08-20 11:16:13.000000000 -0700
20709 ++++ b/fs/jffs2/debug.h 2008-08-20 18:36:57.000000000 -0700
20710 +@@ -51,13 +51,13 @@
20711 + #if CONFIG_JFFS2_FS_DEBUG > 0
20712 + #define D1(x) x
20713 + #else
20714 +-#define D1(x)
20715 ++#define D1(x) do {} while (0);
20716 + #endif
20717 +
20718 + #if CONFIG_JFFS2_FS_DEBUG > 1
20719 + #define D2(x) x
20720 + #else
20721 +-#define D2(x)
20722 ++#define D2(x) do {} while (0);
20723 + #endif
20724 +
20725 + /* The prefixes of JFFS2 messages */
20726 +@@ -113,68 +113,68 @@
20727 + #ifdef JFFS2_DBG_READINODE_MESSAGES
20728 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20729 + #else
20730 +-#define dbg_readinode(fmt, ...)
20731 ++#define dbg_readinode(fmt, ...) do {} while (0)
20732 + #endif
20733 +
20734 + /* Fragtree build debugging messages */
20735 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
20736 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20737 + #else
20738 +-#define dbg_fragtree(fmt, ...)
20739 ++#define dbg_fragtree(fmt, ...) do {} while (0)
20740 + #endif
20741 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
20742 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20743 + #else
20744 +-#define dbg_fragtree2(fmt, ...)
20745 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
20746 + #endif
20747 +
20748 + /* Directory entry list manilulation debugging messages */
20749 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
20750 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20751 + #else
20752 +-#define dbg_dentlist(fmt, ...)
20753 ++#define dbg_dentlist(fmt, ...) do {} while (0)
20754 + #endif
20755 +
20756 + /* Print the messages about manipulating node_refs */
20757 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
20758 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20759 + #else
20760 +-#define dbg_noderef(fmt, ...)
20761 ++#define dbg_noderef(fmt, ...) do {} while (0)
20762 + #endif
20763 +
20764 + /* Manipulations with the list of inodes (JFFS2 inocache) */
20765 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
20766 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20767 + #else
20768 +-#define dbg_inocache(fmt, ...)
20769 ++#define dbg_inocache(fmt, ...) do {} while (0)
20770 + #endif
20771 +
20772 + /* Summary debugging messages */
20773 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
20774 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20775 + #else
20776 +-#define dbg_summary(fmt, ...)
20777 ++#define dbg_summary(fmt, ...) do {} while (0)
20778 + #endif
20779 +
20780 + /* File system build messages */
20781 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
20782 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20783 + #else
20784 +-#define dbg_fsbuild(fmt, ...)
20785 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
20786 + #endif
20787 +
20788 + /* Watch the object allocations */
20789 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
20790 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20791 + #else
20792 +-#define dbg_memalloc(fmt, ...)
20793 ++#define dbg_memalloc(fmt, ...) do {} while (0)
20794 + #endif
20795 +
20796 + /* Watch the XATTR subsystem */
20797 + #ifdef JFFS2_DBG_XATTR_MESSAGES
20798 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20799 + #else
20800 +-#define dbg_xattr(fmt, ...)
20801 ++#define dbg_xattr(fmt, ...) do {} while (0)
20802 + #endif
20803 +
20804 + /* "Sanity" checks */
20805 +diff -urNp a/fs/jffs2/erase.c b/fs/jffs2/erase.c
20806 +--- a/fs/jffs2/erase.c 2008-08-20 11:16:13.000000000 -0700
20807 ++++ b/fs/jffs2/erase.c 2008-08-20 18:36:57.000000000 -0700
20808 +@@ -425,7 +425,8 @@ static void jffs2_mark_erased_block(stru
20809 + struct jffs2_unknown_node marker = {
20810 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
20811 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
20812 +- .totlen = cpu_to_je32(c->cleanmarker_size)
20813 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
20814 ++ .hdr_crc = cpu_to_je32(0)
20815 + };
20816 +
20817 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
20818 +diff -urNp a/fs/jffs2/summary.h b/fs/jffs2/summary.h
20819 +--- a/fs/jffs2/summary.h 2008-08-20 11:16:13.000000000 -0700
20820 ++++ b/fs/jffs2/summary.h 2008-08-20 18:36:57.000000000 -0700
20821 +@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
20822 +
20823 + #define jffs2_sum_active() (0)
20824 + #define jffs2_sum_init(a) (0)
20825 +-#define jffs2_sum_exit(a)
20826 +-#define jffs2_sum_disable_collecting(a)
20827 ++#define jffs2_sum_exit(a) do {} while (0)
20828 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
20829 + #define jffs2_sum_is_disabled(a) (0)
20830 +-#define jffs2_sum_reset_collected(a)
20831 ++#define jffs2_sum_reset_collected(a) do {} while (0)
20832 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
20833 +-#define jffs2_sum_move_collected(a,b)
20834 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
20835 + #define jffs2_sum_write_sumnode(a) (0)
20836 +-#define jffs2_sum_add_padding_mem(a,b)
20837 +-#define jffs2_sum_add_inode_mem(a,b,c)
20838 +-#define jffs2_sum_add_dirent_mem(a,b,c)
20839 +-#define jffs2_sum_add_xattr_mem(a,b,c)
20840 +-#define jffs2_sum_add_xref_mem(a,b,c)
20841 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
20842 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
20843 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
20844 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
20845 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
20846 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
20847 +
20848 + #endif /* CONFIG_JFFS2_SUMMARY */
20849 +diff -urNp a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
20850 +--- a/fs/jffs2/wbuf.c 2008-08-20 11:16:13.000000000 -0700
20851 ++++ b/fs/jffs2/wbuf.c 2008-08-20 18:36:57.000000000 -0700
20852 +@@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
20853 + {
20854 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
20855 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
20856 +- .totlen = constant_cpu_to_je32(8)
20857 ++ .totlen = constant_cpu_to_je32(8),
20858 ++ .hdr_crc = constant_cpu_to_je32(0)
20859 + };
20860 +
20861 + /*
20862 +diff -urNp a/fs/namei.c b/fs/namei.c
20863 +--- a/fs/namei.c 2008-08-20 11:16:13.000000000 -0700
20864 ++++ b/fs/namei.c 2008-08-20 18:36:57.000000000 -0700
20865 +@@ -30,6 +30,7 @@
20866 + #include <linux/capability.h>
20867 + #include <linux/file.h>
20868 + #include <linux/fcntl.h>
20869 ++#include <linux/grsecurity.h>
20870 + #include <asm/namei.h>
20871 + #include <asm/uaccess.h>
20872 +
20873 +@@ -670,7 +671,7 @@ static __always_inline int __do_follow_l
20874 + cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
20875 + error = PTR_ERR(cookie);
20876 + if (!IS_ERR(cookie)) {
20877 +- char *s = nd_get_link(nd);
20878 ++ const char *s = nd_get_link(nd);
20879 + error = 0;
20880 + if (s)
20881 + error = __vfs_follow_link(nd, s);
20882 +@@ -701,6 +702,13 @@ static inline int do_follow_link(struct
20883 + err = security_inode_follow_link(path->dentry, nd);
20884 + if (err)
20885 + goto loop;
20886 ++
20887 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
20888 ++ path->dentry->d_inode, path->dentry, nd->path.mnt)) {
20889 ++ err = -EACCES;
20890 ++ goto loop;
20891 ++ }
20892 ++
20893 + current->link_count++;
20894 + current->total_link_count++;
20895 + nd->depth++;
20896 +@@ -1049,11 +1057,18 @@ return_reval:
20897 + break;
20898 + }
20899 + return_base:
20900 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
20901 ++ path_put(&nd->path);
20902 ++ return -ENOENT;
20903 ++ }
20904 + return 0;
20905 + out_dput:
20906 + path_put_conditional(&next, nd);
20907 + break;
20908 + }
20909 ++ if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
20910 ++ err = -ENOENT;
20911 ++
20912 + path_put(&nd->path);
20913 + return_err:
20914 + return err;
20915 +@@ -1698,9 +1713,17 @@ static int open_namei_create(struct name
20916 + int error;
20917 + struct dentry *dir = nd->path.dentry;
20918 +
20919 ++ if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
20920 ++ error = -EACCES;
20921 ++ goto out_unlock_dput;
20922 ++ }
20923 ++
20924 + if (!IS_POSIXACL(dir->d_inode))
20925 + mode &= ~current->fs->umask;
20926 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
20927 ++ if (!error)
20928 ++ gr_handle_create(path->dentry, nd->path.mnt);
20929 ++out_unlock_dput:
20930 + mutex_unlock(&dir->d_inode->i_mutex);
20931 + dput(nd->path.dentry);
20932 + nd->path.dentry = path->dentry;
20933 +@@ -1751,6 +1774,17 @@ int open_namei(int dfd, const char *path
20934 + nd, flag);
20935 + if (error)
20936 + return error;
20937 ++
20938 ++ if (gr_handle_rawio(nd->path.dentry->d_inode)) {
20939 ++ error = -EPERM;
20940 ++ goto exit;
20941 ++ }
20942 ++
20943 ++ if (!gr_acl_handle_open(nd->path.dentry, nd->path.mnt, flag)) {
20944 ++ error = -EACCES;
20945 ++ goto exit;
20946 ++ }
20947 ++
20948 + goto ok;
20949 + }
20950 +
20951 +@@ -1800,6 +1834,23 @@ do_last:
20952 + /*
20953 + * It already exists.
20954 + */
20955 ++
20956 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
20957 ++ mutex_unlock(&dir->d_inode->i_mutex);
20958 ++ error = -EPERM;
20959 ++ goto exit_dput;
20960 ++ }
20961 ++ if (!gr_acl_handle_open(path.dentry, nd->path.mnt, flag)) {
20962 ++ mutex_unlock(&dir->d_inode->i_mutex);
20963 ++ error = -EACCES;
20964 ++ goto exit_dput;
20965 ++ }
20966 ++ if (gr_handle_fifo(path.dentry, nd->path.mnt, dir, flag, acc_mode)) {
20967 ++ mutex_unlock(&dir->d_inode->i_mutex);
20968 ++ error = -EACCES;
20969 ++ goto exit_dput;
20970 ++ }
20971 ++
20972 + mutex_unlock(&dir->d_inode->i_mutex);
20973 + audit_inode(pathname, path.dentry);
20974 +
20975 +@@ -1855,6 +1906,13 @@ do_link:
20976 + error = security_inode_follow_link(path.dentry, nd);
20977 + if (error)
20978 + goto exit_dput;
20979 ++
20980 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
20981 ++ path.dentry, nd->path.mnt)) {
20982 ++ error = -EACCES;
20983 ++ goto exit_dput;
20984 ++ }
20985 ++
20986 + error = __do_follow_link(&path, nd);
20987 + if (error) {
20988 + /* Does someone understand code flow here? Or it is only
20989 +@@ -1987,6 +2045,16 @@ asmlinkage long sys_mknodat(int dfd, con
20990 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
20991 + mode &= ~current->fs->umask;
20992 + if (!IS_ERR(dentry)) {
20993 ++ if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
20994 ++ error = -EPERM;
20995 ++ goto out_free;
20996 ++ }
20997 ++
20998 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
20999 ++ error = -EACCES;
21000 ++ goto out_free;
21001 ++ }
21002 ++
21003 + switch (mode & S_IFMT) {
21004 + case 0: case S_IFREG:
21005 + error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
21006 +@@ -2004,6 +2072,11 @@ asmlinkage long sys_mknodat(int dfd, con
21007 + default:
21008 + error = -EINVAL;
21009 + }
21010 ++
21011 ++ if (!error)
21012 ++ gr_handle_create(dentry, nd.path.mnt);
21013 ++
21014 ++out_free:
21015 + dput(dentry);
21016 + }
21017 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21018 +@@ -2061,9 +2134,18 @@ asmlinkage long sys_mkdirat(int dfd, con
21019 + if (IS_ERR(dentry))
21020 + goto out_unlock;
21021 +
21022 ++ if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
21023 ++ error = -EACCES;
21024 ++ goto out_unlock_dput;
21025 ++ }
21026 ++
21027 + if (!IS_POSIXACL(nd.path.dentry->d_inode))
21028 + mode &= ~current->fs->umask;
21029 + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
21030 ++
21031 ++ if (!error)
21032 ++ gr_handle_create(dentry, nd.path.mnt);
21033 ++out_unlock_dput:
21034 + dput(dentry);
21035 + out_unlock:
21036 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21037 +@@ -2145,6 +2227,8 @@ static long do_rmdir(int dfd, const char
21038 + char * name;
21039 + struct dentry *dentry;
21040 + struct nameidata nd;
21041 ++ ino_t saved_ino = 0;
21042 ++ dev_t saved_dev = 0;
21043 +
21044 + name = getname(pathname);
21045 + if(IS_ERR(name))
21046 +@@ -2170,7 +2254,23 @@ static long do_rmdir(int dfd, const char
21047 + error = PTR_ERR(dentry);
21048 + if (IS_ERR(dentry))
21049 + goto exit2;
21050 ++
21051 ++ if (dentry->d_inode != NULL) {
21052 ++ if (dentry->d_inode->i_nlink <= 1) {
21053 ++ saved_ino = dentry->d_inode->i_ino;
21054 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
21055 ++ }
21056 ++
21057 ++ if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
21058 ++ error = -EACCES;
21059 ++ goto dput_exit2;
21060 ++ }
21061 ++ }
21062 ++
21063 + error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
21064 ++ if (!error && (saved_dev || saved_ino))
21065 ++ gr_handle_delete(saved_ino, saved_dev);
21066 ++dput_exit2:
21067 + dput(dentry);
21068 + exit2:
21069 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21070 +@@ -2230,6 +2330,8 @@ static long do_unlinkat(int dfd, const c
21071 + struct dentry *dentry;
21072 + struct nameidata nd;
21073 + struct inode *inode = NULL;
21074 ++ ino_t saved_ino = 0;
21075 ++ dev_t saved_dev = 0;
21076 +
21077 + name = getname(pathname);
21078 + if(IS_ERR(name))
21079 +@@ -2245,13 +2347,26 @@ static long do_unlinkat(int dfd, const c
21080 + dentry = lookup_hash(&nd);
21081 + error = PTR_ERR(dentry);
21082 + if (!IS_ERR(dentry)) {
21083 ++ error = 0;
21084 + /* Why not before? Because we want correct error value */
21085 + if (nd.last.name[nd.last.len])
21086 + goto slashes;
21087 + inode = dentry->d_inode;
21088 +- if (inode)
21089 ++ if (inode) {
21090 ++ if (inode->i_nlink <= 1) {
21091 ++ saved_ino = inode->i_ino;
21092 ++ saved_dev = inode->i_sb->s_dev;
21093 ++ }
21094 ++
21095 ++ if (!gr_acl_handle_unlink(dentry, nd.path.mnt))
21096 ++ error = -EACCES;
21097 ++
21098 + atomic_inc(&inode->i_count);
21099 +- error = vfs_unlink(nd.path.dentry->d_inode, dentry);
21100 ++ }
21101 ++ if (!error)
21102 ++ error = vfs_unlink(nd.path.dentry->d_inode, dentry);
21103 ++ if (!error && (saved_ino || saved_dev))
21104 ++ gr_handle_delete(saved_ino, saved_dev);
21105 + exit2:
21106 + dput(dentry);
21107 + }
21108 +@@ -2332,7 +2447,17 @@ asmlinkage long sys_symlinkat(const char
21109 + if (IS_ERR(dentry))
21110 + goto out_unlock;
21111 +
21112 ++ if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
21113 ++ error = -EACCES;
21114 ++ goto out_dput_unlock;
21115 ++ }
21116 ++
21117 + error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO);
21118 ++
21119 ++ if (!error)
21120 ++ gr_handle_create(dentry, nd.path.mnt);
21121 ++
21122 ++out_dput_unlock:
21123 + dput(dentry);
21124 + out_unlock:
21125 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21126 +@@ -2427,7 +2552,26 @@ asmlinkage long sys_linkat(int olddfd, c
21127 + error = PTR_ERR(new_dentry);
21128 + if (IS_ERR(new_dentry))
21129 + goto out_unlock;
21130 ++
21131 ++ if (gr_handle_hardlink(old_nd.path.dentry, old_nd.path.mnt,
21132 ++ old_nd.path.dentry->d_inode,
21133 ++ old_nd.path.dentry->d_inode->i_mode, to)) {
21134 ++ error = -EACCES;
21135 ++ goto out_unlock_dput;
21136 ++ }
21137 ++
21138 ++ if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
21139 ++ old_nd.path.dentry, old_nd.path.mnt, to)) {
21140 ++ error = -EACCES;
21141 ++ goto out_unlock_dput;
21142 ++ }
21143 ++
21144 + error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
21145 ++
21146 ++ if (!error)
21147 ++ gr_handle_create(new_dentry, nd.path.mnt);
21148 ++
21149 ++out_unlock_dput:
21150 + dput(new_dentry);
21151 + out_unlock:
21152 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
21153 +@@ -2653,8 +2797,16 @@ static int do_rename(int olddfd, const c
21154 + if (new_dentry == trap)
21155 + goto exit5;
21156 +
21157 +- error = vfs_rename(old_dir->d_inode, old_dentry,
21158 ++ error = gr_acl_handle_rename(new_dentry, newnd.path.dentry, newnd.path.mnt,
21159 ++ old_dentry, old_dir->d_inode, oldnd.path.mnt,
21160 ++ newname);
21161 ++
21162 ++ if (!error)
21163 ++ error = vfs_rename(old_dir->d_inode, old_dentry,
21164 + new_dir->d_inode, new_dentry);
21165 ++ if (!error)
21166 ++ gr_handle_rename(old_dir->d_inode, newnd.path.dentry->d_inode, old_dentry,
21167 ++ new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
21168 + exit5:
21169 + dput(new_dentry);
21170 + exit4:
21171 +diff -urNp a/fs/namespace.c b/fs/namespace.c
21172 +--- a/fs/namespace.c 2008-08-20 11:16:13.000000000 -0700
21173 ++++ b/fs/namespace.c 2008-08-20 18:36:57.000000000 -0700
21174 +@@ -26,6 +26,7 @@
21175 + #include <linux/mount.h>
21176 + #include <linux/ramfs.h>
21177 + #include <linux/log2.h>
21178 ++#include <linux/grsecurity.h>
21179 + #include <asm/uaccess.h>
21180 + #include <asm/unistd.h>
21181 + #include "pnode.h"
21182 +@@ -644,6 +645,8 @@ static int do_umount(struct vfsmount *mn
21183 + DQUOT_OFF(sb);
21184 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
21185 + unlock_kernel();
21186 ++
21187 ++ gr_log_remount(mnt->mnt_devname, retval);
21188 + }
21189 + up_write(&sb->s_umount);
21190 + return retval;
21191 +@@ -667,6 +670,9 @@ static int do_umount(struct vfsmount *mn
21192 + security_sb_umount_busy(mnt);
21193 + up_write(&namespace_sem);
21194 + release_mounts(&umount_list);
21195 ++
21196 ++ gr_log_unmount(mnt->mnt_devname, retval);
21197 ++
21198 + return retval;
21199 + }
21200 +
21201 +@@ -1438,6 +1444,11 @@ long do_mount(char *dev_name, char *dir_
21202 + if (retval)
21203 + goto dput_out;
21204 +
21205 ++ if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
21206 ++ retval = -EPERM;
21207 ++ goto dput_out;
21208 ++ }
21209 ++
21210 + if (flags & MS_REMOUNT)
21211 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
21212 + data_page);
21213 +@@ -1452,6 +1463,9 @@ long do_mount(char *dev_name, char *dir_
21214 + dev_name, data_page);
21215 + dput_out:
21216 + path_put(&nd.path);
21217 ++
21218 ++ gr_log_mount(dev_name, dir_name, retval);
21219 ++
21220 + return retval;
21221 + }
21222 +
21223 +@@ -1681,6 +1695,9 @@ asmlinkage long sys_pivot_root(const cha
21224 + if (!capable(CAP_SYS_ADMIN))
21225 + return -EPERM;
21226 +
21227 ++ if (gr_handle_chroot_pivot())
21228 ++ return -EPERM;
21229 ++
21230 + lock_kernel();
21231 +
21232 + error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
21233 +diff -urNp a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
21234 +--- a/fs/nfs/nfs4proc.c 2008-08-20 11:16:13.000000000 -0700
21235 ++++ b/fs/nfs/nfs4proc.c 2008-08-20 18:36:57.000000000 -0700
21236 +@@ -654,7 +654,7 @@ static int _nfs4_do_open_reclaim(struct
21237 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
21238 + {
21239 + struct nfs_server *server = NFS_SERVER(state->inode);
21240 +- struct nfs4_exception exception = { };
21241 ++ struct nfs4_exception exception = {0, 0};
21242 + int err;
21243 + do {
21244 + err = _nfs4_do_open_reclaim(ctx, state);
21245 +@@ -696,7 +696,7 @@ static int _nfs4_open_delegation_recall(
21246 +
21247 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
21248 + {
21249 +- struct nfs4_exception exception = { };
21250 ++ struct nfs4_exception exception = {0, 0};
21251 + struct nfs_server *server = NFS_SERVER(state->inode);
21252 + int err;
21253 + do {
21254 +@@ -992,7 +992,7 @@ static int _nfs4_open_expired(struct nfs
21255 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
21256 + {
21257 + struct nfs_server *server = NFS_SERVER(state->inode);
21258 +- struct nfs4_exception exception = { };
21259 ++ struct nfs4_exception exception = {0, 0};
21260 + int err;
21261 +
21262 + do {
21263 +@@ -1094,7 +1094,7 @@ out_err:
21264 +
21265 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
21266 + {
21267 +- struct nfs4_exception exception = { };
21268 ++ struct nfs4_exception exception = {0, 0};
21269 + struct nfs4_state *res;
21270 + int status;
21271 +
21272 +@@ -1183,7 +1183,7 @@ static int nfs4_do_setattr(struct inode
21273 + struct iattr *sattr, struct nfs4_state *state)
21274 + {
21275 + struct nfs_server *server = NFS_SERVER(inode);
21276 +- struct nfs4_exception exception = { };
21277 ++ struct nfs4_exception exception = {0, 0};
21278 + int err;
21279 + do {
21280 + err = nfs4_handle_exception(server,
21281 +@@ -1496,7 +1496,7 @@ static int _nfs4_server_capabilities(str
21282 +
21283 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
21284 + {
21285 +- struct nfs4_exception exception = { };
21286 ++ struct nfs4_exception exception = {0, 0};
21287 + int err;
21288 + do {
21289 + err = nfs4_handle_exception(server,
21290 +@@ -1529,7 +1529,7 @@ static int _nfs4_lookup_root(struct nfs_
21291 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
21292 + struct nfs_fsinfo *info)
21293 + {
21294 +- struct nfs4_exception exception = { };
21295 ++ struct nfs4_exception exception = {0, 0};
21296 + int err;
21297 + do {
21298 + err = nfs4_handle_exception(server,
21299 +@@ -1618,7 +1618,7 @@ static int _nfs4_proc_getattr(struct nfs
21300 +
21301 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
21302 + {
21303 +- struct nfs4_exception exception = { };
21304 ++ struct nfs4_exception exception = {0, 0};
21305 + int err;
21306 + do {
21307 + err = nfs4_handle_exception(server,
21308 +@@ -1708,7 +1708,7 @@ static int nfs4_proc_lookupfh(struct nfs
21309 + struct qstr *name, struct nfs_fh *fhandle,
21310 + struct nfs_fattr *fattr)
21311 + {
21312 +- struct nfs4_exception exception = { };
21313 ++ struct nfs4_exception exception = {0, 0};
21314 + int err;
21315 + do {
21316 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
21317 +@@ -1737,7 +1737,7 @@ static int _nfs4_proc_lookup(struct inod
21318 +
21319 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
21320 + {
21321 +- struct nfs4_exception exception = { };
21322 ++ struct nfs4_exception exception = {0, 0};
21323 + int err;
21324 + do {
21325 + err = nfs4_handle_exception(NFS_SERVER(dir),
21326 +@@ -1801,7 +1801,7 @@ static int _nfs4_proc_access(struct inod
21327 +
21328 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
21329 + {
21330 +- struct nfs4_exception exception = { };
21331 ++ struct nfs4_exception exception = {0, 0};
21332 + int err;
21333 + do {
21334 + err = nfs4_handle_exception(NFS_SERVER(inode),
21335 +@@ -1856,7 +1856,7 @@ static int _nfs4_proc_readlink(struct in
21336 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
21337 + unsigned int pgbase, unsigned int pglen)
21338 + {
21339 +- struct nfs4_exception exception = { };
21340 ++ struct nfs4_exception exception = {0, 0};
21341 + int err;
21342 + do {
21343 + err = nfs4_handle_exception(NFS_SERVER(inode),
21344 +@@ -1952,7 +1952,7 @@ static int _nfs4_proc_remove(struct inod
21345 +
21346 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
21347 + {
21348 +- struct nfs4_exception exception = { };
21349 ++ struct nfs4_exception exception = {0, 0};
21350 + int err;
21351 + do {
21352 + err = nfs4_handle_exception(NFS_SERVER(dir),
21353 +@@ -2024,7 +2024,7 @@ static int _nfs4_proc_rename(struct inod
21354 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
21355 + struct inode *new_dir, struct qstr *new_name)
21356 + {
21357 +- struct nfs4_exception exception = { };
21358 ++ struct nfs4_exception exception = {0, 0};
21359 + int err;
21360 + do {
21361 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
21362 +@@ -2071,7 +2071,7 @@ static int _nfs4_proc_link(struct inode
21363 +
21364 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
21365 + {
21366 +- struct nfs4_exception exception = { };
21367 ++ struct nfs4_exception exception = {0, 0};
21368 + int err;
21369 + do {
21370 + err = nfs4_handle_exception(NFS_SERVER(inode),
21371 +@@ -2128,7 +2128,7 @@ static int _nfs4_proc_symlink(struct ino
21372 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
21373 + struct page *page, unsigned int len, struct iattr *sattr)
21374 + {
21375 +- struct nfs4_exception exception = { };
21376 ++ struct nfs4_exception exception = {0, 0};
21377 + int err;
21378 + do {
21379 + err = nfs4_handle_exception(NFS_SERVER(dir),
21380 +@@ -2181,7 +2181,7 @@ static int _nfs4_proc_mkdir(struct inode
21381 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
21382 + struct iattr *sattr)
21383 + {
21384 +- struct nfs4_exception exception = { };
21385 ++ struct nfs4_exception exception = {0, 0};
21386 + int err;
21387 + do {
21388 + err = nfs4_handle_exception(NFS_SERVER(dir),
21389 +@@ -2230,7 +2230,7 @@ static int _nfs4_proc_readdir(struct den
21390 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
21391 + u64 cookie, struct page *page, unsigned int count, int plus)
21392 + {
21393 +- struct nfs4_exception exception = { };
21394 ++ struct nfs4_exception exception = {0, 0};
21395 + int err;
21396 + do {
21397 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
21398 +@@ -2300,7 +2300,7 @@ static int _nfs4_proc_mknod(struct inode
21399 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
21400 + struct iattr *sattr, dev_t rdev)
21401 + {
21402 +- struct nfs4_exception exception = { };
21403 ++ struct nfs4_exception exception = {0, 0};
21404 + int err;
21405 + do {
21406 + err = nfs4_handle_exception(NFS_SERVER(dir),
21407 +@@ -2329,7 +2329,7 @@ static int _nfs4_proc_statfs(struct nfs_
21408 +
21409 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
21410 + {
21411 +- struct nfs4_exception exception = { };
21412 ++ struct nfs4_exception exception = {0, 0};
21413 + int err;
21414 + do {
21415 + err = nfs4_handle_exception(server,
21416 +@@ -2357,7 +2357,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
21417 +
21418 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
21419 + {
21420 +- struct nfs4_exception exception = { };
21421 ++ struct nfs4_exception exception = {0, 0};
21422 + int err;
21423 +
21424 + do {
21425 +@@ -2400,7 +2400,7 @@ static int _nfs4_proc_pathconf(struct nf
21426 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
21427 + struct nfs_pathconf *pathconf)
21428 + {
21429 +- struct nfs4_exception exception = { };
21430 ++ struct nfs4_exception exception = {0, 0};
21431 + int err;
21432 +
21433 + do {
21434 +@@ -2687,7 +2687,7 @@ out_free:
21435 +
21436 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
21437 + {
21438 +- struct nfs4_exception exception = { };
21439 ++ struct nfs4_exception exception = {0, 0};
21440 + ssize_t ret;
21441 + do {
21442 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
21443 +@@ -2744,7 +2744,7 @@ static int __nfs4_proc_set_acl(struct in
21444 +
21445 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
21446 + {
21447 +- struct nfs4_exception exception = { };
21448 ++ struct nfs4_exception exception = {0, 0};
21449 + int err;
21450 + do {
21451 + err = nfs4_handle_exception(NFS_SERVER(inode),
21452 +@@ -3036,7 +3036,7 @@ out:
21453 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
21454 + {
21455 + struct nfs_server *server = NFS_SERVER(inode);
21456 +- struct nfs4_exception exception = { };
21457 ++ struct nfs4_exception exception = {0, 0};
21458 + int err;
21459 + do {
21460 + err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
21461 +@@ -3111,7 +3111,7 @@ out:
21462 +
21463 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
21464 + {
21465 +- struct nfs4_exception exception = { };
21466 ++ struct nfs4_exception exception = {0, 0};
21467 + int err;
21468 +
21469 + do {
21470 +@@ -3457,7 +3457,7 @@ static int _nfs4_do_setlk(struct nfs4_st
21471 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
21472 + {
21473 + struct nfs_server *server = NFS_SERVER(state->inode);
21474 +- struct nfs4_exception exception = { };
21475 ++ struct nfs4_exception exception = {0, 0};
21476 + int err;
21477 +
21478 + do {
21479 +@@ -3475,7 +3475,7 @@ static int nfs4_lock_reclaim(struct nfs4
21480 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
21481 + {
21482 + struct nfs_server *server = NFS_SERVER(state->inode);
21483 +- struct nfs4_exception exception = { };
21484 ++ struct nfs4_exception exception = {0, 0};
21485 + int err;
21486 +
21487 + err = nfs4_set_lock_state(state, request);
21488 +@@ -3536,7 +3536,7 @@ out:
21489 +
21490 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
21491 + {
21492 +- struct nfs4_exception exception = { };
21493 ++ struct nfs4_exception exception = {0, 0};
21494 + int err;
21495 +
21496 + do {
21497 +@@ -3586,7 +3586,7 @@ nfs4_proc_lock(struct file *filp, int cm
21498 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
21499 + {
21500 + struct nfs_server *server = NFS_SERVER(state->inode);
21501 +- struct nfs4_exception exception = { };
21502 ++ struct nfs4_exception exception = {0, 0};
21503 + int err;
21504 +
21505 + err = nfs4_set_lock_state(state, fl);
21506 +diff -urNp a/fs/nfsd/export.c b/fs/nfsd/export.c
21507 +--- a/fs/nfsd/export.c 2008-08-20 11:16:13.000000000 -0700
21508 ++++ b/fs/nfsd/export.c 2008-08-20 18:36:57.000000000 -0700
21509 +@@ -472,7 +472,7 @@ static int secinfo_parse(char **mesg, ch
21510 + * probably discover the problem when someone fails to
21511 + * authenticate.
21512 + */
21513 +- if (f->pseudoflavor < 0)
21514 ++ if ((s32)f->pseudoflavor < 0)
21515 + return -EINVAL;
21516 + err = get_int(mesg, &f->flags);
21517 + if (err)
21518 +diff -urNp a/fs/nls/nls_base.c b/fs/nls/nls_base.c
21519 +--- a/fs/nls/nls_base.c 2008-08-20 11:16:13.000000000 -0700
21520 ++++ b/fs/nls/nls_base.c 2008-08-20 18:36:57.000000000 -0700
21521 +@@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
21522 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
21523 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
21524 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
21525 +- {0, /* end of table */}
21526 ++ {0, 0, 0, 0, 0, /* end of table */}
21527 + };
21528 +
21529 + int
21530 +diff -urNp a/fs/ntfs/file.c b/fs/ntfs/file.c
21531 +--- a/fs/ntfs/file.c 2008-08-20 11:16:13.000000000 -0700
21532 ++++ b/fs/ntfs/file.c 2008-08-20 18:36:57.000000000 -0700
21533 +@@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
21534 + #endif /* NTFS_RW */
21535 + };
21536 +
21537 +-const struct file_operations ntfs_empty_file_ops = {};
21538 ++const struct file_operations ntfs_empty_file_ops;
21539 +
21540 +-const struct inode_operations ntfs_empty_inode_ops = {};
21541 ++const struct inode_operations ntfs_empty_inode_ops;
21542 +diff -urNp a/fs/open.c b/fs/open.c
21543 +--- a/fs/open.c 2008-08-20 11:16:13.000000000 -0700
21544 ++++ b/fs/open.c 2008-08-20 18:36:57.000000000 -0700
21545 +@@ -27,6 +27,7 @@
21546 + #include <linux/rcupdate.h>
21547 + #include <linux/audit.h>
21548 + #include <linux/falloc.h>
21549 ++#include <linux/grsecurity.h>
21550 +
21551 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
21552 + {
21553 +@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
21554 + if (length < 0)
21555 + return -EINVAL;
21556 +
21557 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
21558 ++ return -EACCES;
21559 ++
21560 + newattrs.ia_size = length;
21561 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
21562 + if (filp) {
21563 +@@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c
21564 + if(IS_RDONLY(nd.path.dentry->d_inode))
21565 + res = -EROFS;
21566 +
21567 ++ if (!res && !gr_acl_handle_access(nd.path.dentry, nd.path.mnt, mode))
21568 ++ res = -EACCES;
21569 ++
21570 + out_path_release:
21571 + path_put(&nd.path);
21572 + out:
21573 +@@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u
21574 + if (error)
21575 + goto dput_and_out;
21576 +
21577 ++ gr_log_chdir(nd.path.dentry, nd.path.mnt);
21578 ++
21579 + set_fs_pwd(current->fs, &nd.path);
21580 +
21581 + dput_and_out:
21582 +@@ -516,6 +525,13 @@ asmlinkage long sys_fchdir(unsigned int
21583 + goto out_putf;
21584 +
21585 + error = file_permission(file, MAY_EXEC);
21586 ++
21587 ++ if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
21588 ++ error = -EPERM;
21589 ++
21590 ++ if (!error)
21591 ++ gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
21592 ++
21593 + if (!error)
21594 + set_fs_pwd(current->fs, &file->f_path);
21595 + out_putf:
21596 +@@ -541,8 +557,16 @@ asmlinkage long sys_chroot(const char __
21597 + if (!capable(CAP_SYS_CHROOT))
21598 + goto dput_and_out;
21599 +
21600 ++ if (gr_handle_chroot_chroot(nd.path.dentry, nd.path.mnt))
21601 ++ goto dput_and_out;
21602 ++
21603 + set_fs_root(current->fs, &nd.path);
21604 + set_fs_altroot();
21605 ++
21606 ++ gr_handle_chroot_caps(current);
21607 ++
21608 ++ gr_handle_chroot_chdir(&nd.path);
21609 ++
21610 + error = 0;
21611 + dput_and_out:
21612 + path_put(&nd.path);
21613 +@@ -573,9 +597,22 @@ asmlinkage long sys_fchmod(unsigned int
21614 + err = -EPERM;
21615 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21616 + goto out_putf;
21617 ++
21618 ++ if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
21619 ++ err = -EACCES;
21620 ++ goto out_putf;
21621 ++ }
21622 ++
21623 + mutex_lock(&inode->i_mutex);
21624 + if (mode == (mode_t) -1)
21625 + mode = inode->i_mode;
21626 ++
21627 ++ if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
21628 ++ err = -EPERM;
21629 ++ mutex_unlock(&inode->i_mutex);
21630 ++ goto out_putf;
21631 ++ }
21632 ++
21633 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
21634 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
21635 + err = notify_change(dentry, &newattrs);
21636 +@@ -608,9 +645,21 @@ asmlinkage long sys_fchmodat(int dfd, co
21637 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21638 + goto dput_and_out;
21639 +
21640 ++ if (!gr_acl_handle_chmod(nd.path.dentry, nd.path.mnt, mode)) {
21641 ++ error = -EACCES;
21642 ++ goto dput_and_out;
21643 ++ };
21644 ++
21645 + mutex_lock(&inode->i_mutex);
21646 + if (mode == (mode_t) -1)
21647 + mode = inode->i_mode;
21648 ++
21649 ++ if (gr_handle_chroot_chmod(nd.path.dentry, nd.path.mnt, mode)) {
21650 ++ error = -EACCES;
21651 ++ mutex_unlock(&inode->i_mutex);
21652 ++ goto dput_and_out;
21653 ++ }
21654 ++
21655 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
21656 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
21657 + error = notify_change(nd.path.dentry, &newattrs);
21658 +@@ -627,7 +676,7 @@ asmlinkage long sys_chmod(const char __u
21659 + return sys_fchmodat(AT_FDCWD, filename, mode);
21660 + }
21661 +
21662 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
21663 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
21664 + {
21665 + struct inode * inode;
21666 + int error;
21667 +@@ -644,6 +693,12 @@ static int chown_common(struct dentry *
21668 + error = -EPERM;
21669 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21670 + goto out;
21671 ++
21672 ++ if (!gr_acl_handle_chown(dentry, mnt)) {
21673 ++ error = -EACCES;
21674 ++ goto out;
21675 ++ }
21676 ++
21677 + newattrs.ia_valid = ATTR_CTIME;
21678 + if (user != (uid_t) -1) {
21679 + newattrs.ia_valid |= ATTR_UID;
21680 +@@ -671,7 +726,7 @@ asmlinkage long sys_chown(const char __u
21681 + error = user_path_walk(filename, &nd);
21682 + if (error)
21683 + goto out;
21684 +- error = chown_common(nd.path.dentry, user, group);
21685 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
21686 + path_put(&nd.path);
21687 + out:
21688 + return error;
21689 +@@ -691,7 +746,7 @@ asmlinkage long sys_fchownat(int dfd, co
21690 + error = __user_walk_fd(dfd, filename, follow, &nd);
21691 + if (error)
21692 + goto out;
21693 +- error = chown_common(nd.path.dentry, user, group);
21694 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
21695 + path_put(&nd.path);
21696 + out:
21697 + return error;
21698 +@@ -705,7 +760,7 @@ asmlinkage long sys_lchown(const char __
21699 + error = user_path_walk_link(filename, &nd);
21700 + if (error)
21701 + goto out;
21702 +- error = chown_common(nd.path.dentry, user, group);
21703 ++ error = chown_common(nd.path.dentry, user, group, nd.path.mnt);
21704 + path_put(&nd.path);
21705 + out:
21706 + return error;
21707 +@@ -724,7 +779,7 @@ asmlinkage long sys_fchown(unsigned int
21708 +
21709 + dentry = file->f_path.dentry;
21710 + audit_inode(NULL, dentry);
21711 +- error = chown_common(dentry, user, group);
21712 ++ error = chown_common(dentry, user, group, file->f_path.mnt);
21713 + fput(file);
21714 + out:
21715 + return error;
21716 +@@ -948,6 +1003,7 @@ repeat:
21717 + * N.B. For clone tasks sharing a files structure, this test
21718 + * will limit the total number of files that can be opened.
21719 + */
21720 ++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
21721 + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
21722 + goto out;
21723 +
21724 +diff -urNp a/fs/partitions/efi.c b/fs/partitions/efi.c
21725 +--- a/fs/partitions/efi.c 2008-08-20 11:16:13.000000000 -0700
21726 ++++ b/fs/partitions/efi.c 2008-08-20 18:36:57.000000000 -0700
21727 +@@ -99,7 +99,7 @@
21728 + #ifdef EFI_DEBUG
21729 + #define Dprintk(x...) printk(KERN_DEBUG x)
21730 + #else
21731 +-#define Dprintk(x...)
21732 ++#define Dprintk(x...) do {} while (0)
21733 + #endif
21734 +
21735 + /* This allows a kernel command line option 'gpt' to override
21736 +diff -urNp a/fs/pipe.c b/fs/pipe.c
21737 +--- a/fs/pipe.c 2008-08-20 11:16:13.000000000 -0700
21738 ++++ b/fs/pipe.c 2008-08-20 18:36:57.000000000 -0700
21739 +@@ -885,7 +885,7 @@ void free_pipe_info(struct inode *inode)
21740 + inode->i_pipe = NULL;
21741 + }
21742 +
21743 +-static struct vfsmount *pipe_mnt __read_mostly;
21744 ++struct vfsmount *pipe_mnt __read_mostly;
21745 + static int pipefs_delete_dentry(struct dentry *dentry)
21746 + {
21747 + /*
21748 +diff -urNp a/fs/proc/array.c b/fs/proc/array.c
21749 +--- a/fs/proc/array.c 2008-08-20 11:16:13.000000000 -0700
21750 ++++ b/fs/proc/array.c 2008-08-20 18:36:57.000000000 -0700
21751 +@@ -308,6 +308,21 @@ static inline void task_context_switch_c
21752 + p->nivcsw);
21753 + }
21754 +
21755 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21756 ++static inline void task_pax(struct seq_file *m, struct task_struct *p)
21757 ++{
21758 ++ if (p->mm)
21759 ++ seq_printf(m, "PaX:\t%c%c%c%c%c\n",
21760 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
21761 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
21762 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
21763 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
21764 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
21765 ++ else
21766 ++ seq_printf(m, "PaX:\t-----\n");
21767 ++}
21768 ++#endif
21769 ++
21770 + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
21771 + struct pid *pid, struct task_struct *task)
21772 + {
21773 +@@ -327,6 +342,11 @@ int proc_pid_status(struct seq_file *m,
21774 + task_show_regs(m, task);
21775 + #endif
21776 + task_context_switch_counts(m, task);
21777 ++
21778 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21779 ++ task_pax(m, task);
21780 ++#endif
21781 ++
21782 + return 0;
21783 + }
21784 +
21785 +@@ -389,6 +409,12 @@ static cputime_t task_gtime(struct task_
21786 + return p->gtime;
21787 + }
21788 +
21789 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21790 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
21791 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
21792 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
21793 ++#endif
21794 ++
21795 + static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
21796 + struct pid *pid, struct task_struct *task, int whole)
21797 + {
21798 +@@ -481,6 +507,19 @@ static int do_task_stat(struct seq_file
21799 + gtime = task_gtime(task);
21800 + }
21801 +
21802 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21803 ++ if (PAX_RAND_FLAGS(mm)) {
21804 ++ eip = 0;
21805 ++ esp = 0;
21806 ++ wchan = 0;
21807 ++ }
21808 ++#endif
21809 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
21810 ++ wchan = 0;
21811 ++ eip =0;
21812 ++ esp =0;
21813 ++#endif
21814 ++
21815 + /* scale priority and nice values from timeslices to -20..20 */
21816 + /* to make it look like a "normal" Unix priority/nice value */
21817 + priority = task_prio(task);
21818 +@@ -521,9 +560,15 @@ static int do_task_stat(struct seq_file
21819 + vsize,
21820 + mm ? get_mm_rss(mm) : 0,
21821 + rsslim,
21822 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21823 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
21824 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
21825 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
21826 ++#else
21827 + mm ? mm->start_code : 0,
21828 + mm ? mm->end_code : 0,
21829 + mm ? mm->start_stack : 0,
21830 ++#endif
21831 + esp,
21832 + eip,
21833 + /* The signal information here is obsolete.
21834 +@@ -576,3 +621,10 @@ int proc_pid_statm(struct seq_file *m, s
21835 +
21836 + return 0;
21837 + }
21838 ++
21839 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
21840 ++int proc_pid_ipaddr(struct task_struct *task, char *buffer)
21841 ++{
21842 ++ return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
21843 ++}
21844 ++#endif
21845 +diff -urNp a/fs/proc/base.c b/fs/proc/base.c
21846 +--- a/fs/proc/base.c 2008-08-20 11:16:13.000000000 -0700
21847 ++++ b/fs/proc/base.c 2008-08-20 18:36:57.000000000 -0700
21848 +@@ -76,6 +76,8 @@
21849 + #include <linux/oom.h>
21850 + #include <linux/elf.h>
21851 + #include <linux/pid_namespace.h>
21852 ++#include <linux/grsecurity.h>
21853 ++
21854 + #include "internal.h"
21855 +
21856 + /* NOTE:
21857 +@@ -145,7 +147,7 @@ static unsigned int pid_entry_count_dirs
21858 + return count;
21859 + }
21860 +
21861 +-int maps_protect;
21862 ++int maps_protect = 1;
21863 + EXPORT_SYMBOL(maps_protect);
21864 +
21865 + static struct fs_struct *get_fs_struct(struct task_struct *task)
21866 +@@ -219,7 +221,7 @@ static int proc_root_link(struct inode *
21867 + (task->parent == current && \
21868 + (task->ptrace & PT_PTRACED) && \
21869 + (task_is_stopped_or_traced(task)) && \
21870 +- security_ptrace(current,task) == 0))
21871 ++ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
21872 +
21873 + struct mm_struct *mm_for_maps(struct task_struct *task)
21874 + {
21875 +@@ -284,9 +286,9 @@ static int proc_pid_auxv(struct task_str
21876 + struct mm_struct *mm = get_task_mm(task);
21877 + if (mm) {
21878 + unsigned int nwords = 0;
21879 +- do
21880 ++ do {
21881 + nwords += 2;
21882 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
21883 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
21884 + res = nwords * sizeof(mm->saved_auxv[0]);
21885 + if (res > PAGE_SIZE)
21886 + res = PAGE_SIZE;
21887 +@@ -734,7 +736,7 @@ static ssize_t mem_read(struct file * fi
21888 + if (!task)
21889 + goto out_no_task;
21890 +
21891 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
21892 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
21893 + goto out;
21894 +
21895 + ret = -ENOMEM;
21896 +@@ -804,7 +806,7 @@ static ssize_t mem_write(struct file * f
21897 + if (!task)
21898 + goto out_no_task;
21899 +
21900 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
21901 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
21902 + goto out;
21903 +
21904 + copied = -ENOMEM;
21905 +@@ -1307,7 +1309,11 @@ static struct inode *proc_pid_make_inode
21906 + inode->i_gid = 0;
21907 + if (task_dumpable(task)) {
21908 + inode->i_uid = task->euid;
21909 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21910 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
21911 ++#else
21912 + inode->i_gid = task->egid;
21913 ++#endif
21914 + }
21915 + security_task_to_inode(task, inode);
21916 +
21917 +@@ -1323,17 +1329,45 @@ static int pid_getattr(struct vfsmount *
21918 + {
21919 + struct inode *inode = dentry->d_inode;
21920 + struct task_struct *task;
21921 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21922 ++ struct task_struct *tmp = current;
21923 ++#endif
21924 ++
21925 + generic_fillattr(inode, stat);
21926 +
21927 + rcu_read_lock();
21928 + stat->uid = 0;
21929 + stat->gid = 0;
21930 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
21931 +- if (task) {
21932 ++
21933 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
21934 ++ rcu_read_unlock();
21935 ++ return -ENOENT;
21936 ++ }
21937 ++
21938 ++
21939 ++ if (task
21940 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21941 ++ && (!tmp->uid || (tmp->uid == task->uid)
21942 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21943 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
21944 ++#endif
21945 ++ )
21946 ++#endif
21947 ++ ) {
21948 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
21949 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
21950 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
21951 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21952 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
21953 ++#endif
21954 + task_dumpable(task)) {
21955 + stat->uid = task->euid;
21956 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21957 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
21958 ++#else
21959 + stat->gid = task->egid;
21960 ++#endif
21961 + }
21962 + }
21963 + rcu_read_unlock();
21964 +@@ -1361,11 +1395,21 @@ static int pid_revalidate(struct dentry
21965 + {
21966 + struct inode *inode = dentry->d_inode;
21967 + struct task_struct *task = get_proc_task(inode);
21968 ++
21969 + if (task) {
21970 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
21971 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
21972 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
21973 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
21974 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
21975 ++#endif
21976 + task_dumpable(task)) {
21977 + inode->i_uid = task->euid;
21978 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
21979 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
21980 ++#else
21981 + inode->i_gid = task->egid;
21982 ++#endif
21983 + } else {
21984 + inode->i_uid = 0;
21985 + inode->i_gid = 0;
21986 +@@ -1736,12 +1780,22 @@ static int proc_fd_permission(struct ino
21987 + struct nameidata *nd)
21988 + {
21989 + int rv;
21990 ++ struct task_struct *task;
21991 +
21992 + rv = generic_permission(inode, mask, NULL);
21993 +- if (rv == 0)
21994 +- return 0;
21995 ++
21996 + if (task_pid(current) == proc_pid(inode))
21997 + rv = 0;
21998 ++
21999 ++ task = get_proc_task(inode);
22000 ++ if (task == NULL)
22001 ++ return rv;
22002 ++
22003 ++ if (gr_acl_handle_procpidmem(task))
22004 ++ rv = -EACCES;
22005 ++
22006 ++ put_task_struct(task);
22007 ++
22008 + return rv;
22009 + }
22010 +
22011 +@@ -1852,6 +1906,9 @@ static struct dentry *proc_pident_lookup
22012 + if (!task)
22013 + goto out_no_task;
22014 +
22015 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22016 ++ goto out;
22017 ++
22018 + /*
22019 + * Yes, it does not scale. And it should not. Don't add
22020 + * new entries into /proc/<tgid>/ without very good reasons.
22021 +@@ -1896,6 +1953,9 @@ static int proc_pident_readdir(struct fi
22022 + if (!task)
22023 + goto out_no_task;
22024 +
22025 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22026 ++ goto out;
22027 ++
22028 + ret = 0;
22029 + i = filp->f_pos;
22030 + switch (i) {
22031 +@@ -2258,6 +2318,9 @@ static struct dentry *proc_base_lookup(s
22032 + if (p > last)
22033 + goto out;
22034 +
22035 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22036 ++ goto out;
22037 ++
22038 + error = proc_base_instantiate(dir, dentry, task, p);
22039 +
22040 + out:
22041 +@@ -2369,6 +2432,9 @@ static const struct pid_entry tgid_base_
22042 + #ifdef CONFIG_TASK_IO_ACCOUNTING
22043 + INF("io", S_IRUGO, pid_io_accounting),
22044 + #endif
22045 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
22046 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
22047 ++#endif
22048 + };
22049 +
22050 + static int proc_tgid_base_readdir(struct file * filp,
22051 +@@ -2498,7 +2564,14 @@ static struct dentry *proc_pid_instantia
22052 + if (!inode)
22053 + goto out;
22054 +
22055 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22056 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
22057 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22058 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22059 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
22060 ++#else
22061 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
22062 ++#endif
22063 + inode->i_op = &proc_tgid_base_inode_operations;
22064 + inode->i_fop = &proc_tgid_base_operations;
22065 + inode->i_flags|=S_IMMUTABLE;
22066 +@@ -2540,7 +2613,11 @@ struct dentry *proc_pid_lookup(struct in
22067 + if (!task)
22068 + goto out;
22069 +
22070 ++ if (gr_check_hidden_task(task))
22071 ++ goto out_put_task;
22072 ++
22073 + result = proc_pid_instantiate(dir, dentry, task, NULL);
22074 ++out_put_task:
22075 + put_task_struct(task);
22076 + out:
22077 + return result;
22078 +@@ -2605,6 +2682,9 @@ int proc_pid_readdir(struct file * filp,
22079 + {
22080 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
22081 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
22082 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22083 ++ struct task_struct *tmp = current;
22084 ++#endif
22085 + struct tgid_iter iter;
22086 + struct pid_namespace *ns;
22087 +
22088 +@@ -2623,6 +2703,17 @@ int proc_pid_readdir(struct file * filp,
22089 + for (iter = next_tgid(ns, iter);
22090 + iter.task;
22091 + iter.tgid += 1, iter = next_tgid(ns, iter)) {
22092 ++ if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
22093 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22094 ++ || (tmp->uid && (iter.task->uid != tmp->uid)
22095 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22096 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
22097 ++#endif
22098 ++ )
22099 ++#endif
22100 ++ )
22101 ++ continue;
22102 ++
22103 + filp->f_pos = iter.tgid + TGID_OFFSET;
22104 + if (proc_pid_fill_cache(filp, dirent, filldir, iter) < 0) {
22105 + put_task_struct(iter.task);
22106 +diff -urNp a/fs/proc/inode.c b/fs/proc/inode.c
22107 +--- a/fs/proc/inode.c 2008-08-20 11:16:13.000000000 -0700
22108 ++++ b/fs/proc/inode.c 2008-08-20 18:36:57.000000000 -0700
22109 +@@ -406,7 +406,11 @@ struct inode *proc_get_inode(struct supe
22110 + if (de->mode) {
22111 + inode->i_mode = de->mode;
22112 + inode->i_uid = de->uid;
22113 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22114 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22115 ++#else
22116 + inode->i_gid = de->gid;
22117 ++#endif
22118 + }
22119 + if (de->size)
22120 + inode->i_size = de->size;
22121 +diff -urNp a/fs/proc/internal.h b/fs/proc/internal.h
22122 +--- a/fs/proc/internal.h 2008-08-20 11:16:13.000000000 -0700
22123 ++++ b/fs/proc/internal.h 2008-08-20 18:36:57.000000000 -0700
22124 +@@ -57,6 +57,9 @@ extern int proc_pid_status(struct seq_fi
22125 + struct pid *pid, struct task_struct *task);
22126 + extern int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
22127 + struct pid *pid, struct task_struct *task);
22128 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
22129 ++extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
22130 ++#endif
22131 + extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
22132 +
22133 + extern const struct file_operations proc_maps_operations;
22134 +diff -urNp a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
22135 +--- a/fs/proc/proc_misc.c 2008-08-20 11:16:13.000000000 -0700
22136 ++++ b/fs/proc/proc_misc.c 2008-08-20 18:36:57.000000000 -0700
22137 +@@ -822,6 +822,8 @@ void create_seq_entry(char *name, mode_t
22138 +
22139 + void __init proc_misc_init(void)
22140 + {
22141 ++ int gr_mode = 0;
22142 ++
22143 + static struct {
22144 + char *name;
22145 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
22146 +@@ -837,13 +839,24 @@ void __init proc_misc_init(void)
22147 + {"stram", stram_read_proc},
22148 + #endif
22149 + {"filesystems", filesystems_read_proc},
22150 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
22151 + {"cmdline", cmdline_read_proc},
22152 ++#endif
22153 + {"execdomains", execdomains_read_proc},
22154 + {NULL,}
22155 + };
22156 + for (p = simple_ones; p->name; p++)
22157 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
22158 +
22159 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22160 ++ gr_mode = S_IRUSR;
22161 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22162 ++ gr_mode = S_IRUSR | S_IRGRP;
22163 ++#endif
22164 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22165 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
22166 ++#endif
22167 ++
22168 + proc_symlink("mounts", NULL, "self/mounts");
22169 +
22170 + /* And now for trickier ones */
22171 +@@ -856,7 +869,11 @@ void __init proc_misc_init(void)
22172 + }
22173 + #endif
22174 + create_seq_entry("locks", 0, &proc_locks_operations);
22175 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22176 ++ create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
22177 ++#else
22178 + create_seq_entry("devices", 0, &proc_devinfo_operations);
22179 ++#endif
22180 + create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
22181 + #ifdef CONFIG_BLOCK
22182 + create_seq_entry("partitions", 0, &proc_partitions_operations);
22183 +@@ -864,7 +881,11 @@ void __init proc_misc_init(void)
22184 + create_seq_entry("stat", 0, &proc_stat_operations);
22185 + create_seq_entry("interrupts", 0, &proc_interrupts_operations);
22186 + #ifdef CONFIG_SLABINFO
22187 ++#ifdef CONFIG_GRKRENSEC_PROC_ADD
22188 ++ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
22189 ++#else
22190 + create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
22191 ++#endif
22192 + #ifdef CONFIG_DEBUG_SLAB_LEAK
22193 + create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
22194 + #endif
22195 +@@ -882,7 +903,7 @@ void __init proc_misc_init(void)
22196 + #ifdef CONFIG_SCHEDSTATS
22197 + create_seq_entry("schedstat", 0, &proc_schedstat_operations);
22198 + #endif
22199 +-#ifdef CONFIG_PROC_KCORE
22200 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
22201 + proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
22202 + if (proc_root_kcore) {
22203 + proc_root_kcore->proc_fops = &proc_kcore_operations;
22204 +diff -urNp a/fs/proc/proc_net.c b/fs/proc/proc_net.c
22205 +--- a/fs/proc/proc_net.c 2008-08-20 11:16:13.000000000 -0700
22206 ++++ b/fs/proc/proc_net.c 2008-08-20 18:36:57.000000000 -0700
22207 +@@ -69,6 +69,14 @@ static struct net *get_proc_task_net(str
22208 + struct nsproxy *ns;
22209 + struct net *net = NULL;
22210 +
22211 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22212 ++ if (current->fsuid)
22213 ++ return net;
22214 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22215 ++ if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
22216 ++ return net;
22217 ++#endif
22218 ++
22219 + rcu_read_lock();
22220 + task = pid_task(proc_pid(dir), PIDTYPE_PID);
22221 + if (task != NULL) {
22222 +diff -urNp a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
22223 +--- a/fs/proc/proc_sysctl.c 2008-08-20 11:16:13.000000000 -0700
22224 ++++ b/fs/proc/proc_sysctl.c 2008-08-20 18:36:57.000000000 -0700
22225 +@@ -7,6 +7,8 @@
22226 + #include <linux/security.h>
22227 + #include "internal.h"
22228 +
22229 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
22230 ++
22231 + static struct dentry_operations proc_sys_dentry_operations;
22232 + static const struct file_operations proc_sys_file_operations;
22233 + static const struct inode_operations proc_sys_inode_operations;
22234 +@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
22235 + if (!table)
22236 + goto out;
22237 +
22238 ++ if (gr_handle_sysctl(table, 001))
22239 ++ goto out;
22240 ++
22241 + err = ERR_PTR(-ENOMEM);
22242 + inode = proc_sys_make_inode(dir, table);
22243 + if (!inode)
22244 +@@ -360,6 +365,9 @@ static int proc_sys_readdir(struct file
22245 + if (pos < filp->f_pos)
22246 + continue;
22247 +
22248 ++ if (gr_handle_sysctl(table, 0))
22249 ++ continue;
22250 ++
22251 + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
22252 + goto out;
22253 + filp->f_pos = pos + 1;
22254 +@@ -422,6 +430,30 @@ out:
22255 + return error;
22256 + }
22257 +
22258 ++/* Eric Biederman is to blame */
22259 ++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
22260 ++{
22261 ++ int error = 0;
22262 ++ struct ctl_table_header *head;
22263 ++ struct ctl_table *table;
22264 ++
22265 ++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
22266 ++ /* Has the sysctl entry disappeared on us? */
22267 ++ if (!table)
22268 ++ goto out;
22269 ++
22270 ++ if (gr_handle_sysctl(table, 001)) {
22271 ++ error = -ENOENT;
22272 ++ goto out;
22273 ++ }
22274 ++
22275 ++out:
22276 ++ sysctl_head_finish(head);
22277 ++
22278 ++ generic_fillattr(dentry->d_inode, stat);
22279 ++
22280 ++ return error;
22281 ++}
22282 + static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
22283 + {
22284 + struct inode *inode = dentry->d_inode;
22285 +@@ -450,6 +482,7 @@ static const struct inode_operations pro
22286 + .lookup = proc_sys_lookup,
22287 + .permission = proc_sys_permission,
22288 + .setattr = proc_sys_setattr,
22289 ++ .getattr = proc_sys_getattr,
22290 + };
22291 +
22292 + static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
22293 +diff -urNp a/fs/proc/root.c b/fs/proc/root.c
22294 +--- a/fs/proc/root.c 2008-08-20 11:16:13.000000000 -0700
22295 ++++ b/fs/proc/root.c 2008-08-20 18:36:57.000000000 -0700
22296 +@@ -137,7 +137,15 @@ void __init proc_root_init(void)
22297 + #ifdef CONFIG_PROC_DEVICETREE
22298 + proc_device_tree_init();
22299 + #endif
22300 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22301 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22302 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
22303 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22304 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
22305 ++#endif
22306 ++#else
22307 + proc_bus = proc_mkdir("bus", NULL);
22308 ++#endif
22309 + proc_sys_init();
22310 + }
22311 +
22312 +diff -urNp a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
22313 +--- a/fs/proc/task_mmu.c 2008-08-20 11:16:13.000000000 -0700
22314 ++++ b/fs/proc/task_mmu.c 2008-08-20 18:36:57.000000000 -0700
22315 +@@ -48,15 +48,26 @@ void task_mem(struct seq_file *m, struct
22316 + "VmStk:\t%8lu kB\n"
22317 + "VmExe:\t%8lu kB\n"
22318 + "VmLib:\t%8lu kB\n"
22319 +- "VmPTE:\t%8lu kB\n",
22320 +- hiwater_vm << (PAGE_SHIFT-10),
22321 ++ "VmPTE:\t%8lu kB\n"
22322 ++
22323 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22324 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
22325 ++#endif
22326 ++
22327 ++ ,hiwater_vm << (PAGE_SHIFT-10),
22328 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
22329 + mm->locked_vm << (PAGE_SHIFT-10),
22330 + hiwater_rss << (PAGE_SHIFT-10),
22331 + total_rss << (PAGE_SHIFT-10),
22332 + data << (PAGE_SHIFT-10),
22333 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
22334 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
22335 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
22336 ++
22337 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22338 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
22339 ++#endif
22340 ++
22341 ++ );
22342 + }
22343 +
22344 + unsigned long task_vsize(struct mm_struct *mm)
22345 +@@ -234,6 +245,12 @@ static int do_maps_open(struct inode *in
22346 + return ret;
22347 + }
22348 +
22349 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22350 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
22351 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
22352 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
22353 ++#endif
22354 ++
22355 + static int show_map(struct seq_file *m, void *v)
22356 + {
22357 + struct proc_maps_private *priv = m->private;
22358 +@@ -256,13 +273,22 @@ static int show_map(struct seq_file *m,
22359 + }
22360 +
22361 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
22362 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22363 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
22364 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
22365 ++#else
22366 + vma->vm_start,
22367 + vma->vm_end,
22368 ++#endif
22369 + flags & VM_READ ? 'r' : '-',
22370 + flags & VM_WRITE ? 'w' : '-',
22371 + flags & VM_EXEC ? 'x' : '-',
22372 + flags & VM_MAYSHARE ? 's' : 'p',
22373 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22374 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
22375 ++#else
22376 + vma->vm_pgoff << PAGE_SHIFT,
22377 ++#endif
22378 + MAJOR(dev), MINOR(dev), ino, &len);
22379 +
22380 + /*
22381 +@@ -276,11 +302,11 @@ static int show_map(struct seq_file *m,
22382 + const char *name = arch_vma_name(vma);
22383 + if (!name) {
22384 + if (mm) {
22385 +- if (vma->vm_start <= mm->start_brk &&
22386 +- vma->vm_end >= mm->brk) {
22387 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
22388 + name = "[heap]";
22389 +- } else if (vma->vm_start <= mm->start_stack &&
22390 +- vma->vm_end >= mm->start_stack) {
22391 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
22392 ++ (vma->vm_start <= mm->start_stack &&
22393 ++ vma->vm_end >= mm->start_stack)) {
22394 + name = "[stack]";
22395 + }
22396 + } else {
22397 +@@ -404,10 +430,17 @@ static int show_smap(struct seq_file *m,
22398 + int ret;
22399 +
22400 + memset(&mss, 0, sizeof mss);
22401 +- mss.vma = vma;
22402 +- if (vma->vm_mm && !is_vm_hugetlb_page(vma))
22403 +- walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end,
22404 +- &smaps_walk, &mss);
22405 ++
22406 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22407 ++ if (!PAX_RAND_FLAGS(vma->vm_mm)) {
22408 ++#endif
22409 ++ mss.vma = vma;
22410 ++ if (vma->vm_mm && !is_vm_hugetlb_page(vma))
22411 ++ walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end,
22412 ++ &smaps_walk, &mss);
22413 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22414 ++ }
22415 ++#endif
22416 +
22417 + ret = show_map(m, v);
22418 + if (ret)
22419 +@@ -422,7 +455,11 @@ static int show_smap(struct seq_file *m,
22420 + "Private_Clean: %8lu kB\n"
22421 + "Private_Dirty: %8lu kB\n"
22422 + "Referenced: %8lu kB\n",
22423 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22424 ++ PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
22425 ++#else
22426 + (vma->vm_end - vma->vm_start) >> 10,
22427 ++#endif
22428 + mss.resident >> 10,
22429 + (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
22430 + mss.shared_clean >> 10,
22431 +diff -urNp a/fs/readdir.c b/fs/readdir.c
22432 +--- a/fs/readdir.c 2008-08-20 11:16:13.000000000 -0700
22433 ++++ b/fs/readdir.c 2008-08-20 18:36:57.000000000 -0700
22434 +@@ -16,6 +16,8 @@
22435 + #include <linux/security.h>
22436 + #include <linux/syscalls.h>
22437 + #include <linux/unistd.h>
22438 ++#include <linux/namei.h>
22439 ++#include <linux/grsecurity.h>
22440 +
22441 + #include <asm/uaccess.h>
22442 +
22443 +@@ -67,6 +69,7 @@ struct old_linux_dirent {
22444 +
22445 + struct readdir_callback {
22446 + struct old_linux_dirent __user * dirent;
22447 ++ struct file * file;
22448 + int result;
22449 + };
22450 +
22451 +@@ -82,6 +85,10 @@ static int fillonedir(void * __buf, cons
22452 + d_ino = ino;
22453 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
22454 + return -EOVERFLOW;
22455 ++
22456 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22457 ++ return 0;
22458 ++
22459 + buf->result++;
22460 + dirent = buf->dirent;
22461 + if (!access_ok(VERIFY_WRITE, dirent,
22462 +@@ -113,6 +120,7 @@ asmlinkage long old_readdir(unsigned int
22463 +
22464 + buf.result = 0;
22465 + buf.dirent = dirent;
22466 ++ buf.file = file;
22467 +
22468 + error = vfs_readdir(file, fillonedir, &buf);
22469 + if (error >= 0)
22470 +@@ -139,6 +147,7 @@ struct linux_dirent {
22471 + struct getdents_callback {
22472 + struct linux_dirent __user * current_dir;
22473 + struct linux_dirent __user * previous;
22474 ++ struct file * file;
22475 + int count;
22476 + int error;
22477 + };
22478 +@@ -157,6 +166,10 @@ static int filldir(void * __buf, const c
22479 + d_ino = ino;
22480 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
22481 + return -EOVERFLOW;
22482 ++
22483 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22484 ++ return 0;
22485 ++
22486 + dirent = buf->previous;
22487 + if (dirent) {
22488 + if (__put_user(offset, &dirent->d_off))
22489 +@@ -203,6 +216,7 @@ asmlinkage long sys_getdents(unsigned in
22490 + buf.previous = NULL;
22491 + buf.count = count;
22492 + buf.error = 0;
22493 ++ buf.file = file;
22494 +
22495 + error = vfs_readdir(file, filldir, &buf);
22496 + if (error < 0)
22497 +@@ -225,6 +239,7 @@ out:
22498 + struct getdents_callback64 {
22499 + struct linux_dirent64 __user * current_dir;
22500 + struct linux_dirent64 __user * previous;
22501 ++ struct file *file;
22502 + int count;
22503 + int error;
22504 + };
22505 +@@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
22506 + buf->error = -EINVAL; /* only used if we fail.. */
22507 + if (reclen > buf->count)
22508 + return -EINVAL;
22509 ++
22510 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22511 ++ return 0;
22512 ++
22513 + dirent = buf->previous;
22514 + if (dirent) {
22515 + if (__put_user(offset, &dirent->d_off))
22516 +@@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
22517 +
22518 + buf.current_dir = dirent;
22519 + buf.previous = NULL;
22520 ++ buf.file = file;
22521 + buf.count = count;
22522 + buf.error = 0;
22523 +
22524 +diff -urNp a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
22525 +--- a/fs/smbfs/symlink.c 2008-08-20 11:16:13.000000000 -0700
22526 ++++ b/fs/smbfs/symlink.c 2008-08-20 18:36:57.000000000 -0700
22527 +@@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
22528 +
22529 + static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
22530 + {
22531 +- char *s = nd_get_link(nd);
22532 ++ const char *s = nd_get_link(nd);
22533 + if (!IS_ERR(s))
22534 + __putname(s);
22535 + }
22536 +diff -urNp a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
22537 +--- a/fs/sysfs/symlink.c 2008-08-20 11:16:13.000000000 -0700
22538 ++++ b/fs/sysfs/symlink.c 2008-08-20 18:36:57.000000000 -0700
22539 +@@ -168,7 +168,7 @@ static void *sysfs_follow_link(struct de
22540 +
22541 + static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
22542 + {
22543 +- char *page = nd_get_link(nd);
22544 ++ const char *page = nd_get_link(nd);
22545 + if (!IS_ERR(page))
22546 + free_page((unsigned long)page);
22547 + }
22548 +diff -urNp a/fs/udf/balloc.c b/fs/udf/balloc.c
22549 +--- a/fs/udf/balloc.c 2008-08-20 11:16:13.000000000 -0700
22550 ++++ b/fs/udf/balloc.c 2008-08-20 18:36:57.000000000 -0700
22551 +@@ -170,9 +170,7 @@ static void udf_bitmap_free_blocks(struc
22552 + unsigned long overflow;
22553 +
22554 + mutex_lock(&sbi->s_alloc_mutex);
22555 +- if (bloc.logicalBlockNum < 0 ||
22556 +- (bloc.logicalBlockNum + count) >
22557 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22558 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22559 + udf_debug("%d < %d || %d + %d > %d\n",
22560 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
22561 + sbi->s_partmaps[bloc.partitionReferenceNum].
22562 +@@ -240,7 +238,7 @@ static int udf_bitmap_prealloc_blocks(st
22563 +
22564 + mutex_lock(&sbi->s_alloc_mutex);
22565 + part_len = sbi->s_partmaps[partition].s_partition_len;
22566 +- if (first_block < 0 || first_block >= part_len)
22567 ++ if (first_block >= part_len)
22568 + goto out;
22569 +
22570 + if (first_block + block_count > part_len)
22571 +@@ -301,7 +299,7 @@ static int udf_bitmap_new_block(struct s
22572 + mutex_lock(&sbi->s_alloc_mutex);
22573 +
22574 + repeat:
22575 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
22576 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
22577 + goal = 0;
22578 +
22579 + nr_groups = bitmap->s_nr_groups;
22580 +@@ -439,9 +437,7 @@ static void udf_table_free_blocks(struct
22581 + struct udf_inode_info *iinfo;
22582 +
22583 + mutex_lock(&sbi->s_alloc_mutex);
22584 +- if (bloc.logicalBlockNum < 0 ||
22585 +- (bloc.logicalBlockNum + count) >
22586 +- sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22587 ++ if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
22588 + udf_debug("%d < %d || %d + %d > %d\n",
22589 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
22590 + sbi->s_partmaps[bloc.partitionReferenceNum].
22591 +@@ -676,8 +672,7 @@ static int udf_table_prealloc_blocks(str
22592 + int8_t etype = -1;
22593 + struct udf_inode_info *iinfo;
22594 +
22595 +- if (first_block < 0 ||
22596 +- first_block >= sbi->s_partmaps[partition].s_partition_len)
22597 ++ if (first_block >= sbi->s_partmaps[partition].s_partition_len)
22598 + return 0;
22599 +
22600 + iinfo = UDF_I(table);
22601 +@@ -755,7 +750,7 @@ static int udf_table_new_block(struct su
22602 + return newblock;
22603 +
22604 + mutex_lock(&sbi->s_alloc_mutex);
22605 +- if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
22606 ++ if (goal >= sbi->s_partmaps[partition].s_partition_len)
22607 + goal = 0;
22608 +
22609 + /* We search for the closest matching block to goal. If we find
22610 +diff -urNp a/fs/udf/inode.c b/fs/udf/inode.c
22611 +--- a/fs/udf/inode.c 2008-08-20 11:16:13.000000000 -0700
22612 ++++ b/fs/udf/inode.c 2008-08-20 18:36:57.000000000 -0700
22613 +@@ -323,9 +323,6 @@ static int udf_get_block(struct inode *i
22614 +
22615 + lock_kernel();
22616 +
22617 +- if (block < 0)
22618 +- goto abort_negative;
22619 +-
22620 + iinfo = UDF_I(inode);
22621 + if (block == iinfo->i_next_alloc_block + 1) {
22622 + iinfo->i_next_alloc_block++;
22623 +@@ -347,10 +344,6 @@ static int udf_get_block(struct inode *i
22624 + abort:
22625 + unlock_kernel();
22626 + return err;
22627 +-
22628 +-abort_negative:
22629 +- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
22630 +- goto abort;
22631 + }
22632 +
22633 + static struct buffer_head *udf_getblk(struct inode *inode, long block,
22634 +diff -urNp a/fs/ufs/inode.c b/fs/ufs/inode.c
22635 +--- a/fs/ufs/inode.c 2008-08-20 11:16:13.000000000 -0700
22636 ++++ b/fs/ufs/inode.c 2008-08-20 18:36:57.000000000 -0700
22637 +@@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
22638 +
22639 +
22640 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
22641 +- if (i_block < 0) {
22642 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
22643 +- } else if (i_block < direct_blocks) {
22644 ++ if (i_block < direct_blocks) {
22645 + offsets[n++] = i_block;
22646 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
22647 + offsets[n++] = UFS_IND_BLOCK;
22648 +@@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
22649 + lock_kernel();
22650 +
22651 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
22652 +- if (fragment < 0)
22653 +- goto abort_negative;
22654 + if (fragment >
22655 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
22656 + << uspi->s_fpbshift))
22657 +@@ -504,10 +500,6 @@ abort:
22658 + unlock_kernel();
22659 + return err;
22660 +
22661 +-abort_negative:
22662 +- ufs_warning(sb, "ufs_get_block", "block < 0");
22663 +- goto abort;
22664 +-
22665 + abort_too_big:
22666 + ufs_warning(sb, "ufs_get_block", "block > big");
22667 + goto abort;
22668 +diff -urNp a/fs/utimes.c b/fs/utimes.c
22669 +--- a/fs/utimes.c 2008-08-20 11:16:13.000000000 -0700
22670 ++++ b/fs/utimes.c 2008-08-20 18:36:57.000000000 -0700
22671 +@@ -7,6 +7,7 @@
22672 + #include <linux/stat.h>
22673 + #include <linux/utime.h>
22674 + #include <linux/syscalls.h>
22675 ++#include <linux/grsecurity.h>
22676 + #include <asm/uaccess.h>
22677 + #include <asm/unistd.h>
22678 +
22679 +@@ -61,6 +62,7 @@ long do_utimes(int dfd, char __user *fil
22680 + int error;
22681 + struct nameidata nd;
22682 + struct dentry *dentry;
22683 ++ struct vfsmount *mnt;
22684 + struct inode *inode;
22685 + struct iattr newattrs;
22686 + struct file *f = NULL;
22687 +@@ -84,12 +86,14 @@ long do_utimes(int dfd, char __user *fil
22688 + if (!f)
22689 + goto out;
22690 + dentry = f->f_path.dentry;
22691 ++ mnt = f->f_path.mnt;
22692 + } else {
22693 + error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
22694 + if (error)
22695 + goto out;
22696 +
22697 + dentry = nd.path.dentry;
22698 ++ mnt = nd.path.mnt;
22699 + }
22700 +
22701 + inode = dentry->d_inode;
22702 +@@ -144,6 +148,12 @@ long do_utimes(int dfd, char __user *fil
22703 + }
22704 + }
22705 + }
22706 ++
22707 ++ if (!gr_acl_handle_utime(dentry, mnt)) {
22708 ++ error = -EACCES;
22709 ++ goto dput_and_out;
22710 ++ }
22711 ++
22712 + mutex_lock(&inode->i_mutex);
22713 + error = notify_change(dentry, &newattrs);
22714 + mutex_unlock(&inode->i_mutex);
22715 +diff -urNp a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
22716 +--- a/fs/xfs/linux-2.6/xfs_iops.c 2008-08-20 11:16:13.000000000 -0700
22717 ++++ b/fs/xfs/linux-2.6/xfs_iops.c 2008-08-20 18:36:57.000000000 -0700
22718 +@@ -547,7 +547,7 @@ xfs_vn_put_link(
22719 + struct nameidata *nd,
22720 + void *p)
22721 + {
22722 +- char *s = nd_get_link(nd);
22723 ++ const char *s = nd_get_link(nd);
22724 +
22725 + if (!IS_ERR(s))
22726 + kfree(s);
22727 +diff -urNp a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
22728 +--- a/fs/xfs/xfs_bmap.c 2008-08-20 11:16:13.000000000 -0700
22729 ++++ b/fs/xfs/xfs_bmap.c 2008-08-20 18:36:57.000000000 -0700
22730 +@@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
22731 + int nmap,
22732 + int ret_nmap);
22733 + #else
22734 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
22735 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
22736 + #endif /* DEBUG */
22737 +
22738 + #if defined(XFS_RW_TRACE)
22739 +diff -urNp a/grsecurity/Kconfig b/grsecurity/Kconfig
22740 +--- a/grsecurity/Kconfig 1969-12-31 16:00:00.000000000 -0800
22741 ++++ b/grsecurity/Kconfig 2008-08-20 18:36:57.000000000 -0700
22742 +@@ -0,0 +1,861 @@
22743 ++#
22744 ++# grecurity configuration
22745 ++#
22746 ++
22747 ++menu "Grsecurity"
22748 ++
22749 ++config GRKERNSEC
22750 ++ bool "Grsecurity"
22751 ++ select CRYPTO
22752 ++ select CRYPTO_SHA256
22753 ++ select SECURITY
22754 ++ select SECURITY_CAPABILITIES
22755 ++ help
22756 ++ If you say Y here, you will be able to configure many features
22757 ++ that will enhance the security of your system. It is highly
22758 ++ recommended that you say Y here and read through the help
22759 ++ for each option so that you fully understand the features and
22760 ++ can evaluate their usefulness for your machine.
22761 ++
22762 ++choice
22763 ++ prompt "Security Level"
22764 ++ depends on GRKERNSEC
22765 ++ default GRKERNSEC_CUSTOM
22766 ++
22767 ++config GRKERNSEC_LOW
22768 ++ bool "Low"
22769 ++ select GRKERNSEC_LINK
22770 ++ select GRKERNSEC_FIFO
22771 ++ select GRKERNSEC_EXECVE
22772 ++ select GRKERNSEC_RANDNET
22773 ++ select GRKERNSEC_DMESG
22774 ++ select GRKERNSEC_CHROOT_CHDIR
22775 ++ select GRKERNSEC_MODSTOP if (MODULES)
22776 ++
22777 ++ help
22778 ++ If you choose this option, several of the grsecurity options will
22779 ++ be enabled that will give you greater protection against a number
22780 ++ of attacks, while assuring that none of your software will have any
22781 ++ conflicts with the additional security measures. If you run a lot
22782 ++ of unusual software, or you are having problems with the higher
22783 ++ security levels, you should say Y here. With this option, the
22784 ++ following features are enabled:
22785 ++
22786 ++ - Linking restrictions
22787 ++ - FIFO restrictions
22788 ++ - Enforcing RLIMIT_NPROC on execve
22789 ++ - Restricted dmesg
22790 ++ - Enforced chdir("/") on chroot
22791 ++ - Runtime module disabling
22792 ++
22793 ++config GRKERNSEC_MEDIUM
22794 ++ bool "Medium"
22795 ++ select PAX
22796 ++ select PAX_EI_PAX
22797 ++ select PAX_PT_PAX_FLAGS
22798 ++ select PAX_HAVE_ACL_FLAGS
22799 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22800 ++ select GRKERNSEC_CHROOT_SYSCTL
22801 ++ select GRKERNSEC_LINK
22802 ++ select GRKERNSEC_FIFO
22803 ++ select GRKERNSEC_EXECVE
22804 ++ select GRKERNSEC_DMESG
22805 ++ select GRKERNSEC_RANDNET
22806 ++ select GRKERNSEC_FORKFAIL
22807 ++ select GRKERNSEC_TIME
22808 ++ select GRKERNSEC_SIGNAL
22809 ++ select GRKERNSEC_CHROOT
22810 ++ select GRKERNSEC_CHROOT_UNIX
22811 ++ select GRKERNSEC_CHROOT_MOUNT
22812 ++ select GRKERNSEC_CHROOT_PIVOT
22813 ++ select GRKERNSEC_CHROOT_DOUBLE
22814 ++ select GRKERNSEC_CHROOT_CHDIR
22815 ++ select GRKERNSEC_CHROOT_MKNOD
22816 ++ select GRKERNSEC_PROC
22817 ++ select GRKERNSEC_PROC_USERGROUP
22818 ++ select GRKERNSEC_MODSTOP if (MODULES)
22819 ++ select PAX_RANDUSTACK
22820 ++ select PAX_ASLR
22821 ++ select PAX_RANDMMAP
22822 ++
22823 ++ help
22824 ++ If you say Y here, several features in addition to those included
22825 ++ in the low additional security level will be enabled. These
22826 ++ features provide even more security to your system, though in rare
22827 ++ cases they may be incompatible with very old or poorly written
22828 ++ software. If you enable this option, make sure that your auth
22829 ++ service (identd) is running as gid 1001. With this option,
22830 ++ the following features (in addition to those provided in the
22831 ++ low additional security level) will be enabled:
22832 ++
22833 ++ - Failed fork logging
22834 ++ - Time change logging
22835 ++ - Signal logging
22836 ++ - Deny mounts in chroot
22837 ++ - Deny double chrooting
22838 ++ - Deny sysctl writes in chroot
22839 ++ - Deny mknod in chroot
22840 ++ - Deny access to abstract AF_UNIX sockets out of chroot
22841 ++ - Deny pivot_root in chroot
22842 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
22843 ++ - /proc restrictions with special GID set to 10 (usually wheel)
22844 ++ - Address Space Layout Randomization (ASLR)
22845 ++
22846 ++config GRKERNSEC_HIGH
22847 ++ bool "High"
22848 ++ select GRKERNSEC_LINK
22849 ++ select GRKERNSEC_FIFO
22850 ++ select GRKERNSEC_EXECVE
22851 ++ select GRKERNSEC_DMESG
22852 ++ select GRKERNSEC_FORKFAIL
22853 ++ select GRKERNSEC_TIME
22854 ++ select GRKERNSEC_SIGNAL
22855 ++ select GRKERNSEC_CHROOT_SHMAT
22856 ++ select GRKERNSEC_CHROOT_UNIX
22857 ++ select GRKERNSEC_CHROOT_MOUNT
22858 ++ select GRKERNSEC_CHROOT_FCHDIR
22859 ++ select GRKERNSEC_CHROOT_PIVOT
22860 ++ select GRKERNSEC_CHROOT_DOUBLE
22861 ++ select GRKERNSEC_CHROOT_CHDIR
22862 ++ select GRKERNSEC_CHROOT_MKNOD
22863 ++ select GRKERNSEC_CHROOT_CAPS
22864 ++ select GRKERNSEC_CHROOT_SYSCTL
22865 ++ select GRKERNSEC_CHROOT_FINDTASK
22866 ++ select GRKERNSEC_PROC
22867 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22868 ++ select GRKERNSEC_HIDESYM
22869 ++ select GRKERNSEC_BRUTE
22870 ++ select GRKERNSEC_PROC_USERGROUP
22871 ++ select GRKERNSEC_KMEM
22872 ++ select GRKERNSEC_RESLOG
22873 ++ select GRKERNSEC_RANDNET
22874 ++ select GRKERNSEC_PROC_ADD
22875 ++ select GRKERNSEC_CHROOT_CHMOD
22876 ++ select GRKERNSEC_CHROOT_NICE
22877 ++ select GRKERNSEC_AUDIT_MOUNT
22878 ++ select GRKERNSEC_MODSTOP if (MODULES)
22879 ++ select PAX
22880 ++ select PAX_RANDUSTACK
22881 ++ select PAX_ASLR
22882 ++ select PAX_RANDMMAP
22883 ++ select PAX_NOEXEC
22884 ++ select PAX_MPROTECT
22885 ++ select PAX_EI_PAX
22886 ++ select PAX_PT_PAX_FLAGS
22887 ++ select PAX_HAVE_ACL_FLAGS
22888 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
22889 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
22890 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
22891 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
22892 ++ select PAX_PAGEEXEC if (!X86)
22893 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
22894 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
22895 ++ select PAX_SYSCALL if (PPC32)
22896 ++ select PAX_EMUTRAMP if (PARISC)
22897 ++ select PAX_EMUSIGRT if (PARISC)
22898 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
22899 ++ help
22900 ++ If you say Y here, many of the features of grsecurity will be
22901 ++ enabled, which will protect you against many kinds of attacks
22902 ++ against your system. The heightened security comes at a cost
22903 ++ of an increased chance of incompatibilities with rare software
22904 ++ on your machine. Since this security level enables PaX, you should
22905 ++ view <http://pax.grsecurity.net> and read about the PaX
22906 ++ project. While you are there, download chpax and run it on
22907 ++ binaries that cause problems with PaX. Also remember that
22908 ++ since the /proc restrictions are enabled, you must run your
22909 ++ identd as gid 1001. This security level enables the following
22910 ++ features in addition to those listed in the low and medium
22911 ++ security levels:
22912 ++
22913 ++ - Additional /proc restrictions
22914 ++ - Chmod restrictions in chroot
22915 ++ - No signals, ptrace, or viewing of processes outside of chroot
22916 ++ - Capability restrictions in chroot
22917 ++ - Deny fchdir out of chroot
22918 ++ - Priority restrictions in chroot
22919 ++ - Segmentation-based implementation of PaX
22920 ++ - Mprotect restrictions
22921 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
22922 ++ - Kernel stack randomization
22923 ++ - Mount/unmount/remount logging
22924 ++ - Kernel symbol hiding
22925 ++ - Prevention of memory exhaustion-based exploits
22926 ++config GRKERNSEC_CUSTOM
22927 ++ bool "Custom"
22928 ++ help
22929 ++ If you say Y here, you will be able to configure every grsecurity
22930 ++ option, which allows you to enable many more features that aren't
22931 ++ covered in the basic security levels. These additional features
22932 ++ include TPE, socket restrictions, and the sysctl system for
22933 ++ grsecurity. It is advised that you read through the help for
22934 ++ each option to determine its usefulness in your situation.
22935 ++
22936 ++endchoice
22937 ++
22938 ++menu "Address Space Protection"
22939 ++depends on GRKERNSEC
22940 ++
22941 ++config GRKERNSEC_KMEM
22942 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
22943 ++ help
22944 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
22945 ++ be written to via mmap or otherwise to modify the running kernel.
22946 ++ /dev/port will also not be allowed to be opened. If you have module
22947 ++ support disabled, enabling this will close up four ways that are
22948 ++ currently used to insert malicious code into the running kernel.
22949 ++ Even with all these features enabled, we still highly recommend that
22950 ++ you use the RBAC system, as it is still possible for an attacker to
22951 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
22952 ++ If you are not using XFree86, you may be able to stop this additional
22953 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
22954 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
22955 ++ but only to video memory, which is the only writing we allow in this
22956 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
22957 ++ not be allowed to mprotect it with PROT_WRITE later.
22958 ++ It is highly recommended that you say Y here if you meet all the
22959 ++ conditions above.
22960 ++
22961 ++config GRKERNSEC_IO
22962 ++ bool "Disable privileged I/O"
22963 ++ depends on X86
22964 ++ select RTC
22965 ++ help
22966 ++ If you say Y here, all ioperm and iopl calls will return an error.
22967 ++ Ioperm and iopl can be used to modify the running kernel.
22968 ++ Unfortunately, some programs need this access to operate properly,
22969 ++ the most notable of which are XFree86 and hwclock. hwclock can be
22970 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
22971 ++ enabled if this option is enabled, to ensure that hwclock operates
22972 ++ correctly. XFree86 still will not operate correctly with this option
22973 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
22974 ++ and you still want to protect your kernel against modification,
22975 ++ use the RBAC system.
22976 ++
22977 ++config GRKERNSEC_PROC_MEMMAP
22978 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
22979 ++ depends on PAX_NOEXEC || PAX_ASLR
22980 ++ help
22981 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
22982 ++ give no information about the addresses of its mappings if
22983 ++ PaX features that rely on random addresses are enabled on the task.
22984 ++ If you use PaX it is greatly recommended that you say Y here as it
22985 ++ closes up a hole that makes the full ASLR useless for suid
22986 ++ binaries.
22987 ++
22988 ++config GRKERNSEC_BRUTE
22989 ++ bool "Deter exploit bruteforcing"
22990 ++ help
22991 ++ If you say Y here, attempts to bruteforce exploits against forking
22992 ++ daemons such as apache or sshd will be deterred. When a child of a
22993 ++ forking daemon is killed by PaX or crashes due to an illegal
22994 ++ instruction, the parent process will be delayed 30 seconds upon every
22995 ++ subsequent fork until the administrator is able to assess the
22996 ++ situation and restart the daemon. It is recommended that you also
22997 ++ enable signal logging in the auditing section so that logs are
22998 ++ generated when a process performs an illegal instruction.
22999 ++
23000 ++config GRKERNSEC_MODSTOP
23001 ++ bool "Runtime module disabling"
23002 ++ depends on MODULES
23003 ++ help
23004 ++ If you say Y here, you will be able to disable the ability to (un)load
23005 ++ modules at runtime. This feature is useful if you need the ability
23006 ++ to load kernel modules at boot time, but do not want to allow an
23007 ++ attacker to load a rootkit kernel module into the system, or to remove
23008 ++ a loaded kernel module important to system functioning. You should
23009 ++ enable the /dev/mem protection feature as well, since rootkits can be
23010 ++ inserted into the kernel via other methods than kernel modules. Since
23011 ++ an untrusted module could still be loaded by modifying init scripts and
23012 ++ rebooting the system, it is also recommended that you enable the RBAC
23013 ++ system. If you enable this option, a sysctl option with name
23014 ++ "disable_modules" will be created. Setting this option to "1" disables
23015 ++ module loading. After this option is set, no further writes to it are
23016 ++ allowed until the system is rebooted.
23017 ++
23018 ++config GRKERNSEC_HIDESYM
23019 ++ bool "Hide kernel symbols"
23020 ++ help
23021 ++ If you say Y here, getting information on loaded modules, and
23022 ++ displaying all kernel symbols through a syscall will be restricted
23023 ++ to users with CAP_SYS_MODULE. This option is only effective
23024 ++ provided the following conditions are met:
23025 ++ 1) The kernel using grsecurity is not precompiled by some distribution
23026 ++ 2) You are using the RBAC system and hiding other files such as your
23027 ++ kernel image and System.map
23028 ++ 3) You have the additional /proc restrictions enabled, which removes
23029 ++ /proc/kcore
23030 ++ If the above conditions are met, this option will aid to provide a
23031 ++ useful protection against local and remote kernel exploitation of
23032 ++ overflows and arbitrary read/write vulnerabilities.
23033 ++
23034 ++endmenu
23035 ++menu "Role Based Access Control Options"
23036 ++depends on GRKERNSEC
23037 ++
23038 ++config GRKERNSEC_ACL_HIDEKERN
23039 ++ bool "Hide kernel processes"
23040 ++ help
23041 ++ If you say Y here, all kernel threads will be hidden to all
23042 ++ processes but those whose subject has the "view hidden processes"
23043 ++ flag.
23044 ++
23045 ++config GRKERNSEC_ACL_MAXTRIES
23046 ++ int "Maximum tries before password lockout"
23047 ++ default 3
23048 ++ help
23049 ++ This option enforces the maximum number of times a user can attempt
23050 ++ to authorize themselves with the grsecurity RBAC system before being
23051 ++ denied the ability to attempt authorization again for a specified time.
23052 ++ The lower the number, the harder it will be to brute-force a password.
23053 ++
23054 ++config GRKERNSEC_ACL_TIMEOUT
23055 ++ int "Time to wait after max password tries, in seconds"
23056 ++ default 30
23057 ++ help
23058 ++ This option specifies the time the user must wait after attempting to
23059 ++ authorize to the RBAC system with the maximum number of invalid
23060 ++ passwords. The higher the number, the harder it will be to brute-force
23061 ++ a password.
23062 ++
23063 ++endmenu
23064 ++menu "Filesystem Protections"
23065 ++depends on GRKERNSEC
23066 ++
23067 ++config GRKERNSEC_PROC
23068 ++ bool "Proc restrictions"
23069 ++ help
23070 ++ If you say Y here, the permissions of the /proc filesystem
23071 ++ will be altered to enhance system security and privacy. You MUST
23072 ++ choose either a user only restriction or a user and group restriction.
23073 ++ Depending upon the option you choose, you can either restrict users to
23074 ++ see only the processes they themselves run, or choose a group that can
23075 ++ view all processes and files normally restricted to root if you choose
23076 ++ the "restrict to user only" option. NOTE: If you're running identd as
23077 ++ a non-root user, you will have to run it as the group you specify here.
23078 ++
23079 ++config GRKERNSEC_PROC_USER
23080 ++ bool "Restrict /proc to user only"
23081 ++ depends on GRKERNSEC_PROC
23082 ++ help
23083 ++ If you say Y here, non-root users will only be able to view their own
23084 ++ processes, and restricts them from viewing network-related information,
23085 ++ and viewing kernel symbol and module information.
23086 ++
23087 ++config GRKERNSEC_PROC_USERGROUP
23088 ++ bool "Allow special group"
23089 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
23090 ++ help
23091 ++ If you say Y here, you will be able to select a group that will be
23092 ++ able to view all processes, network-related information, and
23093 ++ kernel and symbol information. This option is useful if you want
23094 ++ to run identd as a non-root user.
23095 ++
23096 ++config GRKERNSEC_PROC_GID
23097 ++ int "GID for special group"
23098 ++ depends on GRKERNSEC_PROC_USERGROUP
23099 ++ default 1001
23100 ++
23101 ++config GRKERNSEC_PROC_ADD
23102 ++ bool "Additional restrictions"
23103 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
23104 ++ help
23105 ++ If you say Y here, additional restrictions will be placed on
23106 ++ /proc that keep normal users from viewing device information and
23107 ++ slabinfo information that could be useful for exploits.
23108 ++
23109 ++config GRKERNSEC_LINK
23110 ++ bool "Linking restrictions"
23111 ++ help
23112 ++ If you say Y here, /tmp race exploits will be prevented, since users
23113 ++ will no longer be able to follow symlinks owned by other users in
23114 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
23115 ++ symlink is the owner of the directory. users will also not be
23116 ++ able to hardlink to files they do not own. If the sysctl option is
23117 ++ enabled, a sysctl option with name "linking_restrictions" is created.
23118 ++
23119 ++config GRKERNSEC_FIFO
23120 ++ bool "FIFO restrictions"
23121 ++ help
23122 ++ If you say Y here, users will not be able to write to FIFOs they don't
23123 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
23124 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
23125 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
23126 ++ created.
23127 ++
23128 ++config GRKERNSEC_CHROOT
23129 ++ bool "Chroot jail restrictions"
23130 ++ help
23131 ++ If you say Y here, you will be able to choose several options that will
23132 ++ make breaking out of a chrooted jail much more difficult. If you
23133 ++ encounter no software incompatibilities with the following options, it
23134 ++ is recommended that you enable each one.
23135 ++
23136 ++config GRKERNSEC_CHROOT_MOUNT
23137 ++ bool "Deny mounts"
23138 ++ depends on GRKERNSEC_CHROOT
23139 ++ help
23140 ++ If you say Y here, processes inside a chroot will not be able to
23141 ++ mount or remount filesystems. If the sysctl option is enabled, a
23142 ++ sysctl option with name "chroot_deny_mount" is created.
23143 ++
23144 ++config GRKERNSEC_CHROOT_DOUBLE
23145 ++ bool "Deny double-chroots"
23146 ++ depends on GRKERNSEC_CHROOT
23147 ++ help
23148 ++ If you say Y here, processes inside a chroot will not be able to chroot
23149 ++ again outside the chroot. This is a widely used method of breaking
23150 ++ out of a chroot jail and should not be allowed. If the sysctl
23151 ++ option is enabled, a sysctl option with name
23152 ++ "chroot_deny_chroot" is created.
23153 ++
23154 ++config GRKERNSEC_CHROOT_PIVOT
23155 ++ bool "Deny pivot_root in chroot"
23156 ++ depends on GRKERNSEC_CHROOT
23157 ++ help
23158 ++ If you say Y here, processes inside a chroot will not be able to use
23159 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
23160 ++ works similar to chroot in that it changes the root filesystem. This
23161 ++ function could be misused in a chrooted process to attempt to break out
23162 ++ of the chroot, and therefore should not be allowed. If the sysctl
23163 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
23164 ++ created.
23165 ++
23166 ++config GRKERNSEC_CHROOT_CHDIR
23167 ++ bool "Enforce chdir(\"/\") on all chroots"
23168 ++ depends on GRKERNSEC_CHROOT
23169 ++ help
23170 ++ If you say Y here, the current working directory of all newly-chrooted
23171 ++ applications will be set to the the root directory of the chroot.
23172 ++ The man page on chroot(2) states:
23173 ++ Note that this call does not change the current working
23174 ++ directory, so that `.' can be outside the tree rooted at
23175 ++ `/'. In particular, the super-user can escape from a
23176 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
23177 ++
23178 ++ It is recommended that you say Y here, since it's not known to break
23179 ++ any software. If the sysctl option is enabled, a sysctl option with
23180 ++ name "chroot_enforce_chdir" is created.
23181 ++
23182 ++config GRKERNSEC_CHROOT_CHMOD
23183 ++ bool "Deny (f)chmod +s"
23184 ++ depends on GRKERNSEC_CHROOT
23185 ++ help
23186 ++ If you say Y here, processes inside a chroot will not be able to chmod
23187 ++ or fchmod files to make them have suid or sgid bits. This protects
23188 ++ against another published method of breaking a chroot. If the sysctl
23189 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
23190 ++ created.
23191 ++
23192 ++config GRKERNSEC_CHROOT_FCHDIR
23193 ++ bool "Deny fchdir out of chroot"
23194 ++ depends on GRKERNSEC_CHROOT
23195 ++ help
23196 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
23197 ++ to a file descriptor of the chrooting process that points to a directory
23198 ++ outside the filesystem will be stopped. If the sysctl option
23199 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
23200 ++
23201 ++config GRKERNSEC_CHROOT_MKNOD
23202 ++ bool "Deny mknod"
23203 ++ depends on GRKERNSEC_CHROOT
23204 ++ help
23205 ++ If you say Y here, processes inside a chroot will not be allowed to
23206 ++ mknod. The problem with using mknod inside a chroot is that it
23207 ++ would allow an attacker to create a device entry that is the same
23208 ++ as one on the physical root of your system, which could range from
23209 ++ anything from the console device to a device for your harddrive (which
23210 ++ they could then use to wipe the drive or steal data). It is recommended
23211 ++ that you say Y here, unless you run into software incompatibilities.
23212 ++ If the sysctl option is enabled, a sysctl option with name
23213 ++ "chroot_deny_mknod" is created.
23214 ++
23215 ++config GRKERNSEC_CHROOT_SHMAT
23216 ++ bool "Deny shmat() out of chroot"
23217 ++ depends on GRKERNSEC_CHROOT
23218 ++ help
23219 ++ If you say Y here, processes inside a chroot will not be able to attach
23220 ++ to shared memory segments that were created outside of the chroot jail.
23221 ++ It is recommended that you say Y here. If the sysctl option is enabled,
23222 ++ a sysctl option with name "chroot_deny_shmat" is created.
23223 ++
23224 ++config GRKERNSEC_CHROOT_UNIX
23225 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
23226 ++ depends on GRKERNSEC_CHROOT
23227 ++ help
23228 ++ If you say Y here, processes inside a chroot will not be able to
23229 ++ connect to abstract (meaning not belonging to a filesystem) Unix
23230 ++ domain sockets that were bound outside of a chroot. It is recommended
23231 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
23232 ++ with name "chroot_deny_unix" is created.
23233 ++
23234 ++config GRKERNSEC_CHROOT_FINDTASK
23235 ++ bool "Protect outside processes"
23236 ++ depends on GRKERNSEC_CHROOT
23237 ++ help
23238 ++ If you say Y here, processes inside a chroot will not be able to
23239 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
23240 ++ or view any process outside of the chroot. If the sysctl
23241 ++ option is enabled, a sysctl option with name "chroot_findtask" is
23242 ++ created.
23243 ++
23244 ++config GRKERNSEC_CHROOT_NICE
23245 ++ bool "Restrict priority changes"
23246 ++ depends on GRKERNSEC_CHROOT
23247 ++ help
23248 ++ If you say Y here, processes inside a chroot will not be able to raise
23249 ++ the priority of processes in the chroot, or alter the priority of
23250 ++ processes outside the chroot. This provides more security than simply
23251 ++ removing CAP_SYS_NICE from the process' capability set. If the
23252 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
23253 ++ is created.
23254 ++
23255 ++config GRKERNSEC_CHROOT_SYSCTL
23256 ++ bool "Deny sysctl writes"
23257 ++ depends on GRKERNSEC_CHROOT
23258 ++ help
23259 ++ If you say Y here, an attacker in a chroot will not be able to
23260 ++ write to sysctl entries, either by sysctl(2) or through a /proc
23261 ++ interface. It is strongly recommended that you say Y here. If the
23262 ++ sysctl option is enabled, a sysctl option with name
23263 ++ "chroot_deny_sysctl" is created.
23264 ++
23265 ++config GRKERNSEC_CHROOT_CAPS
23266 ++ bool "Capability restrictions"
23267 ++ depends on GRKERNSEC_CHROOT
23268 ++ help
23269 ++ If you say Y here, the capabilities on all root processes within a
23270 ++ chroot jail will be lowered to stop module insertion, raw i/o,
23271 ++ system and net admin tasks, rebooting the system, modifying immutable
23272 ++ files, modifying IPC owned by another, and changing the system time.
23273 ++ This is left an option because it can break some apps. Disable this
23274 ++ if your chrooted apps are having problems performing those kinds of
23275 ++ tasks. If the sysctl option is enabled, a sysctl option with
23276 ++ name "chroot_caps" is created.
23277 ++
23278 ++endmenu
23279 ++menu "Kernel Auditing"
23280 ++depends on GRKERNSEC
23281 ++
23282 ++config GRKERNSEC_AUDIT_GROUP
23283 ++ bool "Single group for auditing"
23284 ++ help
23285 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
23286 ++ will only operate on a group you specify. This option is recommended
23287 ++ if you only want to watch certain users instead of having a large
23288 ++ amount of logs from the entire system. If the sysctl option is enabled,
23289 ++ a sysctl option with name "audit_group" is created.
23290 ++
23291 ++config GRKERNSEC_AUDIT_GID
23292 ++ int "GID for auditing"
23293 ++ depends on GRKERNSEC_AUDIT_GROUP
23294 ++ default 1007
23295 ++
23296 ++config GRKERNSEC_EXECLOG
23297 ++ bool "Exec logging"
23298 ++ help
23299 ++ If you say Y here, all execve() calls will be logged (since the
23300 ++ other exec*() calls are frontends to execve(), all execution
23301 ++ will be logged). Useful for shell-servers that like to keep track
23302 ++ of their users. If the sysctl option is enabled, a sysctl option with
23303 ++ name "exec_logging" is created.
23304 ++ WARNING: This option when enabled will produce a LOT of logs, especially
23305 ++ on an active system.
23306 ++
23307 ++config GRKERNSEC_RESLOG
23308 ++ bool "Resource logging"
23309 ++ help
23310 ++ If you say Y here, all attempts to overstep resource limits will
23311 ++ be logged with the resource name, the requested size, and the current
23312 ++ limit. It is highly recommended that you say Y here. If the sysctl
23313 ++ option is enabled, a sysctl option with name "resource_logging" is
23314 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
23315 ++
23316 ++config GRKERNSEC_CHROOT_EXECLOG
23317 ++ bool "Log execs within chroot"
23318 ++ help
23319 ++ If you say Y here, all executions inside a chroot jail will be logged
23320 ++ to syslog. This can cause a large amount of logs if certain
23321 ++ applications (eg. djb's daemontools) are installed on the system, and
23322 ++ is therefore left as an option. If the sysctl option is enabled, a
23323 ++ sysctl option with name "chroot_execlog" is created.
23324 ++
23325 ++config GRKERNSEC_AUDIT_CHDIR
23326 ++ bool "Chdir logging"
23327 ++ help
23328 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
23329 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
23330 ++
23331 ++config GRKERNSEC_AUDIT_MOUNT
23332 ++ bool "(Un)Mount logging"
23333 ++ help
23334 ++ If you say Y here, all mounts and unmounts will be logged. If the
23335 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
23336 ++ created.
23337 ++
23338 ++config GRKERNSEC_AUDIT_IPC
23339 ++ bool "IPC logging"
23340 ++ help
23341 ++ If you say Y here, creation and removal of message queues, semaphores,
23342 ++ and shared memory will be logged. If the sysctl option is enabled, a
23343 ++ sysctl option with name "audit_ipc" is created.
23344 ++
23345 ++config GRKERNSEC_SIGNAL
23346 ++ bool "Signal logging"
23347 ++ help
23348 ++ If you say Y here, certain important signals will be logged, such as
23349 ++ SIGSEGV, which will as a result inform you of when a error in a program
23350 ++ occurred, which in some cases could mean a possible exploit attempt.
23351 ++ If the sysctl option is enabled, a sysctl option with name
23352 ++ "signal_logging" is created.
23353 ++
23354 ++config GRKERNSEC_FORKFAIL
23355 ++ bool "Fork failure logging"
23356 ++ help
23357 ++ If you say Y here, all failed fork() attempts will be logged.
23358 ++ This could suggest a fork bomb, or someone attempting to overstep
23359 ++ their process limit. If the sysctl option is enabled, a sysctl option
23360 ++ with name "forkfail_logging" is created.
23361 ++
23362 ++config GRKERNSEC_TIME
23363 ++ bool "Time change logging"
23364 ++ help
23365 ++ If you say Y here, any changes of the system clock will be logged.
23366 ++ If the sysctl option is enabled, a sysctl option with name
23367 ++ "timechange_logging" is created.
23368 ++
23369 ++config GRKERNSEC_PROC_IPADDR
23370 ++ bool "/proc/<pid>/ipaddr support"
23371 ++ help
23372 ++ If you say Y here, a new entry will be added to each /proc/<pid>
23373 ++ directory that contains the IP address of the person using the task.
23374 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
23375 ++ This information can be useful for IDS/IPSes to perform remote response
23376 ++ to a local attack. The entry is readable by only the owner of the
23377 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
23378 ++ the RBAC system), and thus does not create privacy concerns.
23379 ++
23380 ++config GRKERNSEC_AUDIT_TEXTREL
23381 ++ bool 'ELF text relocations logging (READ HELP)'
23382 ++ depends on PAX_MPROTECT
23383 ++ help
23384 ++ If you say Y here, text relocations will be logged with the filename
23385 ++ of the offending library or binary. The purpose of the feature is
23386 ++ to help Linux distribution developers get rid of libraries and
23387 ++ binaries that need text relocations which hinder the future progress
23388 ++ of PaX. Only Linux distribution developers should say Y here, and
23389 ++ never on a production machine, as this option creates an information
23390 ++ leak that could aid an attacker in defeating the randomization of
23391 ++ a single memory region. If the sysctl option is enabled, a sysctl
23392 ++ option with name "audit_textrel" is created.
23393 ++
23394 ++endmenu
23395 ++
23396 ++menu "Executable Protections"
23397 ++depends on GRKERNSEC
23398 ++
23399 ++config GRKERNSEC_EXECVE
23400 ++ bool "Enforce RLIMIT_NPROC on execs"
23401 ++ help
23402 ++ If you say Y here, users with a resource limit on processes will
23403 ++ have the value checked during execve() calls. The current system
23404 ++ only checks the system limit during fork() calls. If the sysctl option
23405 ++ is enabled, a sysctl option with name "execve_limiting" is created.
23406 ++
23407 ++config GRKERNSEC_DMESG
23408 ++ bool "Dmesg(8) restriction"
23409 ++ help
23410 ++ If you say Y here, non-root users will not be able to use dmesg(8)
23411 ++ to view up to the last 4kb of messages in the kernel's log buffer.
23412 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
23413 ++ created.
23414 ++
23415 ++config GRKERNSEC_TPE
23416 ++ bool "Trusted Path Execution (TPE)"
23417 ++ help
23418 ++ If you say Y here, you will be able to choose a gid to add to the
23419 ++ supplementary groups of users you want to mark as "untrusted."
23420 ++ These users will not be able to execute any files that are not in
23421 ++ root-owned directories writable only by root. If the sysctl option
23422 ++ is enabled, a sysctl option with name "tpe" is created.
23423 ++
23424 ++config GRKERNSEC_TPE_ALL
23425 ++ bool "Partially restrict non-root users"
23426 ++ depends on GRKERNSEC_TPE
23427 ++ help
23428 ++ If you say Y here, All non-root users other than the ones in the
23429 ++ group specified in the main TPE option will only be allowed to
23430 ++ execute files in directories they own that are not group or
23431 ++ world-writable, or in directories owned by root and writable only by
23432 ++ root. If the sysctl option is enabled, a sysctl option with name
23433 ++ "tpe_restrict_all" is created.
23434 ++
23435 ++config GRKERNSEC_TPE_INVERT
23436 ++ bool "Invert GID option"
23437 ++ depends on GRKERNSEC_TPE
23438 ++ help
23439 ++ If you say Y here, the group you specify in the TPE configuration will
23440 ++ decide what group TPE restrictions will be *disabled* for. This
23441 ++ option is useful if you want TPE restrictions to be applied to most
23442 ++ users on the system.
23443 ++
23444 ++config GRKERNSEC_TPE_GID
23445 ++ int "GID for untrusted users"
23446 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
23447 ++ default 1005
23448 ++ help
23449 ++ If you have selected the "Invert GID option" above, setting this
23450 ++ GID determines what group TPE restrictions will be *disabled* for.
23451 ++ If you have not selected the "Invert GID option" above, setting this
23452 ++ GID determines what group TPE restrictions will be *enabled* for.
23453 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23454 ++ is created.
23455 ++
23456 ++config GRKERNSEC_TPE_GID
23457 ++ int "GID for trusted users"
23458 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
23459 ++ default 1005
23460 ++ help
23461 ++ If you have selected the "Invert GID option" above, setting this
23462 ++ GID determines what group TPE restrictions will be *disabled* for.
23463 ++ If you have not selected the "Invert GID option" above, setting this
23464 ++ GID determines what group TPE restrictions will be *enabled* for.
23465 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23466 ++ is created.
23467 ++
23468 ++endmenu
23469 ++menu "Network Protections"
23470 ++depends on GRKERNSEC
23471 ++
23472 ++config GRKERNSEC_RANDNET
23473 ++ bool "Larger entropy pools"
23474 ++ help
23475 ++ If you say Y here, the entropy pools used for many features of Linux
23476 ++ and grsecurity will be doubled in size. Since several grsecurity
23477 ++ features use additional randomness, it is recommended that you say Y
23478 ++ here. Saying Y here has a similar effect as modifying
23479 ++ /proc/sys/kernel/random/poolsize.
23480 ++
23481 ++config GRKERNSEC_SOCKET
23482 ++ bool "Socket restrictions"
23483 ++ help
23484 ++ If you say Y here, you will be able to choose from several options.
23485 ++ If you assign a GID on your system and add it to the supplementary
23486 ++ groups of users you want to restrict socket access to, this patch
23487 ++ will perform up to three things, based on the option(s) you choose.
23488 ++
23489 ++config GRKERNSEC_SOCKET_ALL
23490 ++ bool "Deny any sockets to group"
23491 ++ depends on GRKERNSEC_SOCKET
23492 ++ help
23493 ++ If you say Y here, you will be able to choose a GID of whose users will
23494 ++ be unable to connect to other hosts from your machine or run server
23495 ++ applications from your machine. If the sysctl option is enabled, a
23496 ++ sysctl option with name "socket_all" is created.
23497 ++
23498 ++config GRKERNSEC_SOCKET_ALL_GID
23499 ++ int "GID to deny all sockets for"
23500 ++ depends on GRKERNSEC_SOCKET_ALL
23501 ++ default 1004
23502 ++ help
23503 ++ Here you can choose the GID to disable socket access for. Remember to
23504 ++ add the users you want socket access disabled for to the GID
23505 ++ specified here. If the sysctl option is enabled, a sysctl option
23506 ++ with name "socket_all_gid" is created.
23507 ++
23508 ++config GRKERNSEC_SOCKET_CLIENT
23509 ++ bool "Deny client sockets to group"
23510 ++ depends on GRKERNSEC_SOCKET
23511 ++ help
23512 ++ If you say Y here, you will be able to choose a GID of whose users will
23513 ++ be unable to connect to other hosts from your machine, but will be
23514 ++ able to run servers. If this option is enabled, all users in the group
23515 ++ you specify will have to use passive mode when initiating ftp transfers
23516 ++ from the shell on your machine. If the sysctl option is enabled, a
23517 ++ sysctl option with name "socket_client" is created.
23518 ++
23519 ++config GRKERNSEC_SOCKET_CLIENT_GID
23520 ++ int "GID to deny client sockets for"
23521 ++ depends on GRKERNSEC_SOCKET_CLIENT
23522 ++ default 1003
23523 ++ help
23524 ++ Here you can choose the GID to disable client socket access for.
23525 ++ Remember to add the users you want client socket access disabled for to
23526 ++ the GID specified here. If the sysctl option is enabled, a sysctl
23527 ++ option with name "socket_client_gid" is created.
23528 ++
23529 ++config GRKERNSEC_SOCKET_SERVER
23530 ++ bool "Deny server sockets to group"
23531 ++ depends on GRKERNSEC_SOCKET
23532 ++ help
23533 ++ If you say Y here, you will be able to choose a GID of whose users will
23534 ++ be unable to run server applications from your machine. If the sysctl
23535 ++ option is enabled, a sysctl option with name "socket_server" is created.
23536 ++
23537 ++config GRKERNSEC_SOCKET_SERVER_GID
23538 ++ int "GID to deny server sockets for"
23539 ++ depends on GRKERNSEC_SOCKET_SERVER
23540 ++ default 1002
23541 ++ help
23542 ++ Here you can choose the GID to disable server socket access for.
23543 ++ Remember to add the users you want server socket access disabled for to
23544 ++ the GID specified here. If the sysctl option is enabled, a sysctl
23545 ++ option with name "socket_server_gid" is created.
23546 ++
23547 ++endmenu
23548 ++menu "Sysctl support"
23549 ++depends on GRKERNSEC && SYSCTL
23550 ++
23551 ++config GRKERNSEC_SYSCTL
23552 ++ bool "Sysctl support"
23553 ++ help
23554 ++ If you say Y here, you will be able to change the options that
23555 ++ grsecurity runs with at bootup, without having to recompile your
23556 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
23557 ++ to enable (1) or disable (0) various features. All the sysctl entries
23558 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
23559 ++ All features enabled in the kernel configuration are disabled at boot
23560 ++ if you do not say Y to the "Turn on features by default" option.
23561 ++ All options should be set at startup, and the grsec_lock entry should
23562 ++ be set to a non-zero value after all the options are set.
23563 ++ *THIS IS EXTREMELY IMPORTANT*
23564 ++
23565 ++config GRKERNSEC_SYSCTL_ON
23566 ++ bool "Turn on features by default"
23567 ++ depends on GRKERNSEC_SYSCTL
23568 ++ help
23569 ++ If you say Y here, instead of having all features enabled in the
23570 ++ kernel configuration disabled at boot time, the features will be
23571 ++ enabled at boot time. It is recommended you say Y here unless
23572 ++ there is some reason you would want all sysctl-tunable features to
23573 ++ be disabled by default. As mentioned elsewhere, it is important
23574 ++ to enable the grsec_lock entry once you have finished modifying
23575 ++ the sysctl entries.
23576 ++
23577 ++endmenu
23578 ++menu "Logging Options"
23579 ++depends on GRKERNSEC
23580 ++
23581 ++config GRKERNSEC_FLOODTIME
23582 ++ int "Seconds in between log messages (minimum)"
23583 ++ default 10
23584 ++ help
23585 ++ This option allows you to enforce the number of seconds between
23586 ++ grsecurity log messages. The default should be suitable for most
23587 ++ people, however, if you choose to change it, choose a value small enough
23588 ++ to allow informative logs to be produced, but large enough to
23589 ++ prevent flooding.
23590 ++
23591 ++config GRKERNSEC_FLOODBURST
23592 ++ int "Number of messages in a burst (maximum)"
23593 ++ default 4
23594 ++ help
23595 ++ This option allows you to choose the maximum number of messages allowed
23596 ++ within the flood time interval you chose in a separate option. The
23597 ++ default should be suitable for most people, however if you find that
23598 ++ many of your logs are being interpreted as flooding, you may want to
23599 ++ raise this value.
23600 ++
23601 ++endmenu
23602 ++
23603 ++endmenu
23604 +diff -urNp a/grsecurity/Makefile b/grsecurity/Makefile
23605 +--- a/grsecurity/Makefile 1969-12-31 16:00:00.000000000 -0800
23606 ++++ b/grsecurity/Makefile 2008-08-20 18:36:57.000000000 -0700
23607 +@@ -0,0 +1,20 @@
23608 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
23609 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
23610 ++# into an RBAC system
23611 ++#
23612 ++# All code in this directory and various hooks inserted throughout the kernel
23613 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
23614 ++
23615 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
23616 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
23617 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
23618 ++
23619 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
23620 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
23621 ++ gracl_learn.o grsec_log.o
23622 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
23623 ++
23624 ++ifndef CONFIG_GRKERNSEC
23625 ++obj-y += grsec_disabled.o
23626 ++endif
23627 ++
23628 +diff -urNp a/grsecurity/gracl.c b/grsecurity/gracl.c
23629 +--- a/grsecurity/gracl.c 1969-12-31 16:00:00.000000000 -0800
23630 ++++ b/grsecurity/gracl.c 2008-08-20 18:36:57.000000000 -0700
23631 +@@ -0,0 +1,3721 @@
23632 ++#include <linux/kernel.h>
23633 ++#include <linux/module.h>
23634 ++#include <linux/sched.h>
23635 ++#include <linux/mm.h>
23636 ++#include <linux/file.h>
23637 ++#include <linux/fs.h>
23638 ++#include <linux/namei.h>
23639 ++#include <linux/mount.h>
23640 ++#include <linux/tty.h>
23641 ++#include <linux/proc_fs.h>
23642 ++#include <linux/smp_lock.h>
23643 ++#include <linux/slab.h>
23644 ++#include <linux/vmalloc.h>
23645 ++#include <linux/types.h>
23646 ++#include <linux/sysctl.h>
23647 ++#include <linux/netdevice.h>
23648 ++#include <linux/ptrace.h>
23649 ++#include <linux/gracl.h>
23650 ++#include <linux/gralloc.h>
23651 ++#include <linux/grsecurity.h>
23652 ++#include <linux/grinternal.h>
23653 ++#include <linux/pid_namespace.h>
23654 ++#include <linux/percpu.h>
23655 ++
23656 ++#include <asm/uaccess.h>
23657 ++#include <asm/errno.h>
23658 ++#include <asm/mman.h>
23659 ++
23660 ++static struct acl_role_db acl_role_set;
23661 ++static struct name_db name_set;
23662 ++static struct inodev_db inodev_set;
23663 ++
23664 ++/* for keeping track of userspace pointers used for subjects, so we
23665 ++ can share references in the kernel as well
23666 ++*/
23667 ++
23668 ++static struct dentry *real_root;
23669 ++static struct vfsmount *real_root_mnt;
23670 ++
23671 ++static struct acl_subj_map_db subj_map_set;
23672 ++
23673 ++static struct acl_role_label *default_role;
23674 ++
23675 ++static u16 acl_sp_role_value;
23676 ++
23677 ++extern char *gr_shared_page[4];
23678 ++static DECLARE_MUTEX(gr_dev_sem);
23679 ++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
23680 ++
23681 ++struct gr_arg *gr_usermode;
23682 ++
23683 ++static unsigned int gr_status = GR_STATUS_INIT;
23684 ++
23685 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
23686 ++extern void gr_clear_learn_entries(void);
23687 ++
23688 ++#ifdef CONFIG_GRKERNSEC_RESLOG
23689 ++extern void gr_log_resource(const struct task_struct *task,
23690 ++ const int res, const unsigned long wanted, const int gt);
23691 ++#endif
23692 ++
23693 ++unsigned char *gr_system_salt;
23694 ++unsigned char *gr_system_sum;
23695 ++
23696 ++static struct sprole_pw **acl_special_roles = NULL;
23697 ++static __u16 num_sprole_pws = 0;
23698 ++
23699 ++static struct acl_role_label *kernel_role = NULL;
23700 ++
23701 ++static unsigned int gr_auth_attempts = 0;
23702 ++static unsigned long gr_auth_expires = 0UL;
23703 ++
23704 ++extern struct vfsmount *sock_mnt;
23705 ++extern struct vfsmount *pipe_mnt;
23706 ++extern struct vfsmount *shm_mnt;
23707 ++static struct acl_object_label *fakefs_obj;
23708 ++
23709 ++extern int gr_init_uidset(void);
23710 ++extern void gr_free_uidset(void);
23711 ++extern void gr_remove_uid(uid_t uid);
23712 ++extern int gr_find_uid(uid_t uid);
23713 ++
23714 ++__inline__ int
23715 ++gr_acl_is_enabled(void)
23716 ++{
23717 ++ return (gr_status & GR_READY);
23718 ++}
23719 ++
23720 ++char gr_roletype_to_char(void)
23721 ++{
23722 ++ switch (current->role->roletype &
23723 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
23724 ++ GR_ROLE_SPECIAL)) {
23725 ++ case GR_ROLE_DEFAULT:
23726 ++ return 'D';
23727 ++ case GR_ROLE_USER:
23728 ++ return 'U';
23729 ++ case GR_ROLE_GROUP:
23730 ++ return 'G';
23731 ++ case GR_ROLE_SPECIAL:
23732 ++ return 'S';
23733 ++ }
23734 ++
23735 ++ return 'X';
23736 ++}
23737 ++
23738 ++__inline__ int
23739 ++gr_acl_tpe_check(void)
23740 ++{
23741 ++ if (unlikely(!(gr_status & GR_READY)))
23742 ++ return 0;
23743 ++ if (current->role->roletype & GR_ROLE_TPE)
23744 ++ return 1;
23745 ++ else
23746 ++ return 0;
23747 ++}
23748 ++
23749 ++int
23750 ++gr_handle_rawio(const struct inode *inode)
23751 ++{
23752 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23753 ++ if (inode && S_ISBLK(inode->i_mode) &&
23754 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
23755 ++ !capable(CAP_SYS_RAWIO))
23756 ++ return 1;
23757 ++#endif
23758 ++ return 0;
23759 ++}
23760 ++
23761 ++static int
23762 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
23763 ++{
23764 ++ int i;
23765 ++ unsigned long *l1;
23766 ++ unsigned long *l2;
23767 ++ unsigned char *c1;
23768 ++ unsigned char *c2;
23769 ++ int num_longs;
23770 ++
23771 ++ if (likely(lena != lenb))
23772 ++ return 0;
23773 ++
23774 ++ l1 = (unsigned long *)a;
23775 ++ l2 = (unsigned long *)b;
23776 ++
23777 ++ num_longs = lena / sizeof(unsigned long);
23778 ++
23779 ++ for (i = num_longs; i--; l1++, l2++) {
23780 ++ if (unlikely(*l1 != *l2))
23781 ++ return 0;
23782 ++ }
23783 ++
23784 ++ c1 = (unsigned char *) l1;
23785 ++ c2 = (unsigned char *) l2;
23786 ++
23787 ++ i = lena - (num_longs * sizeof(unsigned long));
23788 ++
23789 ++ for (; i--; c1++, c2++) {
23790 ++ if (unlikely(*c1 != *c2))
23791 ++ return 0;
23792 ++ }
23793 ++
23794 ++ return 1;
23795 ++}
23796 ++
23797 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
23798 ++ struct dentry *root, struct vfsmount *rootmnt,
23799 ++ char *buffer, int buflen)
23800 ++{
23801 ++ char * end = buffer+buflen;
23802 ++ char * retval;
23803 ++ int namelen;
23804 ++
23805 ++ *--end = '\0';
23806 ++ buflen--;
23807 ++
23808 ++ if (buflen < 1)
23809 ++ goto Elong;
23810 ++ /* Get '/' right */
23811 ++ retval = end-1;
23812 ++ *retval = '/';
23813 ++
23814 ++ for (;;) {
23815 ++ struct dentry * parent;
23816 ++
23817 ++ if (dentry == root && vfsmnt == rootmnt)
23818 ++ break;
23819 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
23820 ++ /* Global root? */
23821 ++ spin_lock(&vfsmount_lock);
23822 ++ if (vfsmnt->mnt_parent == vfsmnt) {
23823 ++ spin_unlock(&vfsmount_lock);
23824 ++ goto global_root;
23825 ++ }
23826 ++ dentry = vfsmnt->mnt_mountpoint;
23827 ++ vfsmnt = vfsmnt->mnt_parent;
23828 ++ spin_unlock(&vfsmount_lock);
23829 ++ continue;
23830 ++ }
23831 ++ parent = dentry->d_parent;
23832 ++ prefetch(parent);
23833 ++ namelen = dentry->d_name.len;
23834 ++ buflen -= namelen + 1;
23835 ++ if (buflen < 0)
23836 ++ goto Elong;
23837 ++ end -= namelen;
23838 ++ memcpy(end, dentry->d_name.name, namelen);
23839 ++ *--end = '/';
23840 ++ retval = end;
23841 ++ dentry = parent;
23842 ++ }
23843 ++
23844 ++ return retval;
23845 ++
23846 ++global_root:
23847 ++ namelen = dentry->d_name.len;
23848 ++ buflen -= namelen;
23849 ++ if (buflen < 0)
23850 ++ goto Elong;
23851 ++ retval -= namelen-1; /* hit the slash */
23852 ++ memcpy(retval, dentry->d_name.name, namelen);
23853 ++ return retval;
23854 ++Elong:
23855 ++ return ERR_PTR(-ENAMETOOLONG);
23856 ++}
23857 ++
23858 ++static char *
23859 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
23860 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
23861 ++{
23862 ++ char *retval;
23863 ++
23864 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
23865 ++ if (unlikely(IS_ERR(retval)))
23866 ++ retval = strcpy(buf, "<path too long>");
23867 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
23868 ++ retval[1] = '\0';
23869 ++
23870 ++ return retval;
23871 ++}
23872 ++
23873 ++static char *
23874 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
23875 ++ char *buf, int buflen)
23876 ++{
23877 ++ char *res;
23878 ++
23879 ++ /* we can use real_root, real_root_mnt, because this is only called
23880 ++ by the RBAC system */
23881 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
23882 ++
23883 ++ return res;
23884 ++}
23885 ++
23886 ++static char *
23887 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
23888 ++ char *buf, int buflen)
23889 ++{
23890 ++ char *res;
23891 ++ struct dentry *root;
23892 ++ struct vfsmount *rootmnt;
23893 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
23894 ++
23895 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
23896 ++ read_lock(&reaper->fs->lock);
23897 ++ root = dget(reaper->fs->root.dentry);
23898 ++ rootmnt = mntget(reaper->fs->root.mnt);
23899 ++ read_unlock(&reaper->fs->lock);
23900 ++
23901 ++ spin_lock(&dcache_lock);
23902 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
23903 ++ spin_unlock(&dcache_lock);
23904 ++
23905 ++ dput(root);
23906 ++ mntput(rootmnt);
23907 ++ return res;
23908 ++}
23909 ++
23910 ++static char *
23911 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
23912 ++{
23913 ++ char *ret;
23914 ++ spin_lock(&dcache_lock);
23915 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
23916 ++ PAGE_SIZE);
23917 ++ spin_unlock(&dcache_lock);
23918 ++ return ret;
23919 ++}
23920 ++
23921 ++char *
23922 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
23923 ++{
23924 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
23925 ++ PAGE_SIZE);
23926 ++}
23927 ++
23928 ++char *
23929 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
23930 ++{
23931 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
23932 ++ PAGE_SIZE);
23933 ++}
23934 ++
23935 ++char *
23936 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
23937 ++{
23938 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
23939 ++ PAGE_SIZE);
23940 ++}
23941 ++
23942 ++char *
23943 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
23944 ++{
23945 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
23946 ++ PAGE_SIZE);
23947 ++}
23948 ++
23949 ++char *
23950 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
23951 ++{
23952 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
23953 ++ PAGE_SIZE);
23954 ++}
23955 ++
23956 ++__inline__ __u32
23957 ++to_gr_audit(const __u32 reqmode)
23958 ++{
23959 ++ /* masks off auditable permission flags, then shifts them to create
23960 ++ auditing flags, and adds the special case of append auditing if
23961 ++ we're requesting write */
23962 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
23963 ++}
23964 ++
23965 ++struct acl_subject_label *
23966 ++lookup_subject_map(const struct acl_subject_label *userp)
23967 ++{
23968 ++ unsigned int index = shash(userp, subj_map_set.s_size);
23969 ++ struct subject_map *match;
23970 ++
23971 ++ match = subj_map_set.s_hash[index];
23972 ++
23973 ++ while (match && match->user != userp)
23974 ++ match = match->next;
23975 ++
23976 ++ if (match != NULL)
23977 ++ return match->kernel;
23978 ++ else
23979 ++ return NULL;
23980 ++}
23981 ++
23982 ++static void
23983 ++insert_subj_map_entry(struct subject_map *subjmap)
23984 ++{
23985 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
23986 ++ struct subject_map **curr;
23987 ++
23988 ++ subjmap->prev = NULL;
23989 ++
23990 ++ curr = &subj_map_set.s_hash[index];
23991 ++ if (*curr != NULL)
23992 ++ (*curr)->prev = subjmap;
23993 ++
23994 ++ subjmap->next = *curr;
23995 ++ *curr = subjmap;
23996 ++
23997 ++ return;
23998 ++}
23999 ++
24000 ++static struct acl_role_label *
24001 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
24002 ++ const gid_t gid)
24003 ++{
24004 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
24005 ++ struct acl_role_label *match;
24006 ++ struct role_allowed_ip *ipp;
24007 ++ unsigned int x;
24008 ++
24009 ++ match = acl_role_set.r_hash[index];
24010 ++
24011 ++ while (match) {
24012 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
24013 ++ for (x = 0; x < match->domain_child_num; x++) {
24014 ++ if (match->domain_children[x] == uid)
24015 ++ goto found;
24016 ++ }
24017 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
24018 ++ break;
24019 ++ match = match->next;
24020 ++ }
24021 ++found:
24022 ++ if (match == NULL) {
24023 ++ try_group:
24024 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
24025 ++ match = acl_role_set.r_hash[index];
24026 ++
24027 ++ while (match) {
24028 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
24029 ++ for (x = 0; x < match->domain_child_num; x++) {
24030 ++ if (match->domain_children[x] == gid)
24031 ++ goto found2;
24032 ++ }
24033 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
24034 ++ break;
24035 ++ match = match->next;
24036 ++ }
24037 ++found2:
24038 ++ if (match == NULL)
24039 ++ match = default_role;
24040 ++ if (match->allowed_ips == NULL)
24041 ++ return match;
24042 ++ else {
24043 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
24044 ++ if (likely
24045 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
24046 ++ (ntohl(ipp->addr) & ipp->netmask)))
24047 ++ return match;
24048 ++ }
24049 ++ match = default_role;
24050 ++ }
24051 ++ } else if (match->allowed_ips == NULL) {
24052 ++ return match;
24053 ++ } else {
24054 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
24055 ++ if (likely
24056 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
24057 ++ (ntohl(ipp->addr) & ipp->netmask)))
24058 ++ return match;
24059 ++ }
24060 ++ goto try_group;
24061 ++ }
24062 ++
24063 ++ return match;
24064 ++}
24065 ++
24066 ++struct acl_subject_label *
24067 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
24068 ++ const struct acl_role_label *role)
24069 ++{
24070 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
24071 ++ struct acl_subject_label *match;
24072 ++
24073 ++ match = role->subj_hash[index];
24074 ++
24075 ++ while (match && (match->inode != ino || match->device != dev ||
24076 ++ (match->mode & GR_DELETED))) {
24077 ++ match = match->next;
24078 ++ }
24079 ++
24080 ++ if (match && !(match->mode & GR_DELETED))
24081 ++ return match;
24082 ++ else
24083 ++ return NULL;
24084 ++}
24085 ++
24086 ++static struct acl_object_label *
24087 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
24088 ++ const struct acl_subject_label *subj)
24089 ++{
24090 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
24091 ++ struct acl_object_label *match;
24092 ++
24093 ++ match = subj->obj_hash[index];
24094 ++
24095 ++ while (match && (match->inode != ino || match->device != dev ||
24096 ++ (match->mode & GR_DELETED))) {
24097 ++ match = match->next;
24098 ++ }
24099 ++
24100 ++ if (match && !(match->mode & GR_DELETED))
24101 ++ return match;
24102 ++ else
24103 ++ return NULL;
24104 ++}
24105 ++
24106 ++static struct acl_object_label *
24107 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
24108 ++ const struct acl_subject_label *subj)
24109 ++{
24110 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
24111 ++ struct acl_object_label *match;
24112 ++
24113 ++ match = subj->obj_hash[index];
24114 ++
24115 ++ while (match && (match->inode != ino || match->device != dev ||
24116 ++ !(match->mode & GR_DELETED))) {
24117 ++ match = match->next;
24118 ++ }
24119 ++
24120 ++ if (match && (match->mode & GR_DELETED))
24121 ++ return match;
24122 ++
24123 ++ match = subj->obj_hash[index];
24124 ++
24125 ++ while (match && (match->inode != ino || match->device != dev ||
24126 ++ (match->mode & GR_DELETED))) {
24127 ++ match = match->next;
24128 ++ }
24129 ++
24130 ++ if (match && !(match->mode & GR_DELETED))
24131 ++ return match;
24132 ++ else
24133 ++ return NULL;
24134 ++}
24135 ++
24136 ++static struct name_entry *
24137 ++lookup_name_entry(const char *name)
24138 ++{
24139 ++ unsigned int len = strlen(name);
24140 ++ unsigned int key = full_name_hash(name, len);
24141 ++ unsigned int index = key % name_set.n_size;
24142 ++ struct name_entry *match;
24143 ++
24144 ++ match = name_set.n_hash[index];
24145 ++
24146 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
24147 ++ match = match->next;
24148 ++
24149 ++ return match;
24150 ++}
24151 ++
24152 ++static struct name_entry *
24153 ++lookup_name_entry_create(const char *name)
24154 ++{
24155 ++ unsigned int len = strlen(name);
24156 ++ unsigned int key = full_name_hash(name, len);
24157 ++ unsigned int index = key % name_set.n_size;
24158 ++ struct name_entry *match;
24159 ++
24160 ++ match = name_set.n_hash[index];
24161 ++
24162 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
24163 ++ !match->deleted))
24164 ++ match = match->next;
24165 ++
24166 ++ if (match && match->deleted)
24167 ++ return match;
24168 ++
24169 ++ match = name_set.n_hash[index];
24170 ++
24171 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
24172 ++ match->deleted))
24173 ++ match = match->next;
24174 ++
24175 ++ if (match && !match->deleted)
24176 ++ return match;
24177 ++ else
24178 ++ return NULL;
24179 ++}
24180 ++
24181 ++static struct inodev_entry *
24182 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
24183 ++{
24184 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
24185 ++ struct inodev_entry *match;
24186 ++
24187 ++ match = inodev_set.i_hash[index];
24188 ++
24189 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
24190 ++ match = match->next;
24191 ++
24192 ++ return match;
24193 ++}
24194 ++
24195 ++static void
24196 ++insert_inodev_entry(struct inodev_entry *entry)
24197 ++{
24198 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
24199 ++ inodev_set.i_size);
24200 ++ struct inodev_entry **curr;
24201 ++
24202 ++ entry->prev = NULL;
24203 ++
24204 ++ curr = &inodev_set.i_hash[index];
24205 ++ if (*curr != NULL)
24206 ++ (*curr)->prev = entry;
24207 ++
24208 ++ entry->next = *curr;
24209 ++ *curr = entry;
24210 ++
24211 ++ return;
24212 ++}
24213 ++
24214 ++static void
24215 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
24216 ++{
24217 ++ unsigned int index =
24218 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
24219 ++ struct acl_role_label **curr;
24220 ++
24221 ++ role->prev = NULL;
24222 ++
24223 ++ curr = &acl_role_set.r_hash[index];
24224 ++ if (*curr != NULL)
24225 ++ (*curr)->prev = role;
24226 ++
24227 ++ role->next = *curr;
24228 ++ *curr = role;
24229 ++
24230 ++ return;
24231 ++}
24232 ++
24233 ++static void
24234 ++insert_acl_role_label(struct acl_role_label *role)
24235 ++{
24236 ++ int i;
24237 ++
24238 ++ if (role->roletype & GR_ROLE_DOMAIN) {
24239 ++ for (i = 0; i < role->domain_child_num; i++)
24240 ++ __insert_acl_role_label(role, role->domain_children[i]);
24241 ++ } else
24242 ++ __insert_acl_role_label(role, role->uidgid);
24243 ++}
24244 ++
24245 ++static int
24246 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
24247 ++{
24248 ++ struct name_entry **curr, *nentry;
24249 ++ struct inodev_entry *ientry;
24250 ++ unsigned int len = strlen(name);
24251 ++ unsigned int key = full_name_hash(name, len);
24252 ++ unsigned int index = key % name_set.n_size;
24253 ++
24254 ++ curr = &name_set.n_hash[index];
24255 ++
24256 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
24257 ++ curr = &((*curr)->next);
24258 ++
24259 ++ if (*curr != NULL)
24260 ++ return 1;
24261 ++
24262 ++ nentry = acl_alloc(sizeof (struct name_entry));
24263 ++ if (nentry == NULL)
24264 ++ return 0;
24265 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
24266 ++ if (ientry == NULL)
24267 ++ return 0;
24268 ++ ientry->nentry = nentry;
24269 ++
24270 ++ nentry->key = key;
24271 ++ nentry->name = name;
24272 ++ nentry->inode = inode;
24273 ++ nentry->device = device;
24274 ++ nentry->len = len;
24275 ++ nentry->deleted = deleted;
24276 ++
24277 ++ nentry->prev = NULL;
24278 ++ curr = &name_set.n_hash[index];
24279 ++ if (*curr != NULL)
24280 ++ (*curr)->prev = nentry;
24281 ++ nentry->next = *curr;
24282 ++ *curr = nentry;
24283 ++
24284 ++ /* insert us into the table searchable by inode/dev */
24285 ++ insert_inodev_entry(ientry);
24286 ++
24287 ++ return 1;
24288 ++}
24289 ++
24290 ++static void
24291 ++insert_acl_obj_label(struct acl_object_label *obj,
24292 ++ struct acl_subject_label *subj)
24293 ++{
24294 ++ unsigned int index =
24295 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
24296 ++ struct acl_object_label **curr;
24297 ++
24298 ++
24299 ++ obj->prev = NULL;
24300 ++
24301 ++ curr = &subj->obj_hash[index];
24302 ++ if (*curr != NULL)
24303 ++ (*curr)->prev = obj;
24304 ++
24305 ++ obj->next = *curr;
24306 ++ *curr = obj;
24307 ++
24308 ++ return;
24309 ++}
24310 ++
24311 ++static void
24312 ++insert_acl_subj_label(struct acl_subject_label *obj,
24313 ++ struct acl_role_label *role)
24314 ++{
24315 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
24316 ++ struct acl_subject_label **curr;
24317 ++
24318 ++ obj->prev = NULL;
24319 ++
24320 ++ curr = &role->subj_hash[index];
24321 ++ if (*curr != NULL)
24322 ++ (*curr)->prev = obj;
24323 ++
24324 ++ obj->next = *curr;
24325 ++ *curr = obj;
24326 ++
24327 ++ return;
24328 ++}
24329 ++
24330 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
24331 ++
24332 ++static void *
24333 ++create_table(__u32 * len, int elementsize)
24334 ++{
24335 ++ unsigned int table_sizes[] = {
24336 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
24337 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
24338 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
24339 ++ 268435399, 536870909, 1073741789, 2147483647
24340 ++ };
24341 ++ void *newtable = NULL;
24342 ++ unsigned int pwr = 0;
24343 ++
24344 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
24345 ++ table_sizes[pwr] <= *len)
24346 ++ pwr++;
24347 ++
24348 ++ if (table_sizes[pwr] <= *len)
24349 ++ return newtable;
24350 ++
24351 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
24352 ++ newtable =
24353 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
24354 ++ else
24355 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
24356 ++
24357 ++ *len = table_sizes[pwr];
24358 ++
24359 ++ return newtable;
24360 ++}
24361 ++
24362 ++static int
24363 ++init_variables(const struct gr_arg *arg)
24364 ++{
24365 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
24366 ++ unsigned int stacksize;
24367 ++
24368 ++ subj_map_set.s_size = arg->role_db.num_subjects;
24369 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
24370 ++ name_set.n_size = arg->role_db.num_objects;
24371 ++ inodev_set.i_size = arg->role_db.num_objects;
24372 ++
24373 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
24374 ++ !name_set.n_size || !inodev_set.i_size)
24375 ++ return 1;
24376 ++
24377 ++ if (!gr_init_uidset())
24378 ++ return 1;
24379 ++
24380 ++ /* set up the stack that holds allocation info */
24381 ++
24382 ++ stacksize = arg->role_db.num_pointers + 5;
24383 ++
24384 ++ if (!acl_alloc_stack_init(stacksize))
24385 ++ return 1;
24386 ++
24387 ++ /* grab reference for the real root dentry and vfsmount */
24388 ++ read_lock(&reaper->fs->lock);
24389 ++ real_root_mnt = mntget(reaper->fs->root.mnt);
24390 ++ real_root = dget(reaper->fs->root.dentry);
24391 ++ read_unlock(&reaper->fs->lock);
24392 ++
24393 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
24394 ++ if (fakefs_obj == NULL)
24395 ++ return 1;
24396 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
24397 ++
24398 ++ subj_map_set.s_hash =
24399 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
24400 ++ acl_role_set.r_hash =
24401 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
24402 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
24403 ++ inodev_set.i_hash =
24404 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
24405 ++
24406 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
24407 ++ !name_set.n_hash || !inodev_set.i_hash)
24408 ++ return 1;
24409 ++
24410 ++ memset(subj_map_set.s_hash, 0,
24411 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
24412 ++ memset(acl_role_set.r_hash, 0,
24413 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
24414 ++ memset(name_set.n_hash, 0,
24415 ++ sizeof (struct name_entry *) * name_set.n_size);
24416 ++ memset(inodev_set.i_hash, 0,
24417 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
24418 ++
24419 ++ return 0;
24420 ++}
24421 ++
24422 ++/* free information not needed after startup
24423 ++ currently contains user->kernel pointer mappings for subjects
24424 ++*/
24425 ++
24426 ++static void
24427 ++free_init_variables(void)
24428 ++{
24429 ++ __u32 i;
24430 ++
24431 ++ if (subj_map_set.s_hash) {
24432 ++ for (i = 0; i < subj_map_set.s_size; i++) {
24433 ++ if (subj_map_set.s_hash[i]) {
24434 ++ kfree(subj_map_set.s_hash[i]);
24435 ++ subj_map_set.s_hash[i] = NULL;
24436 ++ }
24437 ++ }
24438 ++
24439 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
24440 ++ PAGE_SIZE)
24441 ++ kfree(subj_map_set.s_hash);
24442 ++ else
24443 ++ vfree(subj_map_set.s_hash);
24444 ++ }
24445 ++
24446 ++ return;
24447 ++}
24448 ++
24449 ++static void
24450 ++free_variables(void)
24451 ++{
24452 ++ struct acl_subject_label *s;
24453 ++ struct acl_role_label *r;
24454 ++ struct task_struct *task, *task2;
24455 ++ unsigned int i, x;
24456 ++
24457 ++ gr_clear_learn_entries();
24458 ++
24459 ++ read_lock(&tasklist_lock);
24460 ++ do_each_thread(task2, task) {
24461 ++ task->acl_sp_role = 0;
24462 ++ task->acl_role_id = 0;
24463 ++ task->acl = NULL;
24464 ++ task->role = NULL;
24465 ++ } while_each_thread(task2, task);
24466 ++ read_unlock(&tasklist_lock);
24467 ++
24468 ++ /* release the reference to the real root dentry and vfsmount */
24469 ++ if (real_root)
24470 ++ dput(real_root);
24471 ++ real_root = NULL;
24472 ++ if (real_root_mnt)
24473 ++ mntput(real_root_mnt);
24474 ++ real_root_mnt = NULL;
24475 ++
24476 ++ /* free all object hash tables */
24477 ++
24478 ++ FOR_EACH_ROLE_START(r, i)
24479 ++ if (r->subj_hash == NULL)
24480 ++ break;
24481 ++ FOR_EACH_SUBJECT_START(r, s, x)
24482 ++ if (s->obj_hash == NULL)
24483 ++ break;
24484 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
24485 ++ kfree(s->obj_hash);
24486 ++ else
24487 ++ vfree(s->obj_hash);
24488 ++ FOR_EACH_SUBJECT_END(s, x)
24489 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
24490 ++ if (s->obj_hash == NULL)
24491 ++ break;
24492 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
24493 ++ kfree(s->obj_hash);
24494 ++ else
24495 ++ vfree(s->obj_hash);
24496 ++ FOR_EACH_NESTED_SUBJECT_END(s)
24497 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
24498 ++ kfree(r->subj_hash);
24499 ++ else
24500 ++ vfree(r->subj_hash);
24501 ++ r->subj_hash = NULL;
24502 ++ FOR_EACH_ROLE_END(r,i)
24503 ++
24504 ++ acl_free_all();
24505 ++
24506 ++ if (acl_role_set.r_hash) {
24507 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
24508 ++ PAGE_SIZE)
24509 ++ kfree(acl_role_set.r_hash);
24510 ++ else
24511 ++ vfree(acl_role_set.r_hash);
24512 ++ }
24513 ++ if (name_set.n_hash) {
24514 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
24515 ++ PAGE_SIZE)
24516 ++ kfree(name_set.n_hash);
24517 ++ else
24518 ++ vfree(name_set.n_hash);
24519 ++ }
24520 ++
24521 ++ if (inodev_set.i_hash) {
24522 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
24523 ++ PAGE_SIZE)
24524 ++ kfree(inodev_set.i_hash);
24525 ++ else
24526 ++ vfree(inodev_set.i_hash);
24527 ++ }
24528 ++
24529 ++ gr_free_uidset();
24530 ++
24531 ++ memset(&name_set, 0, sizeof (struct name_db));
24532 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
24533 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
24534 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
24535 ++
24536 ++ default_role = NULL;
24537 ++
24538 ++ return;
24539 ++}
24540 ++
24541 ++static __u32
24542 ++count_user_objs(struct acl_object_label *userp)
24543 ++{
24544 ++ struct acl_object_label o_tmp;
24545 ++ __u32 num = 0;
24546 ++
24547 ++ while (userp) {
24548 ++ if (copy_from_user(&o_tmp, userp,
24549 ++ sizeof (struct acl_object_label)))
24550 ++ break;
24551 ++
24552 ++ userp = o_tmp.prev;
24553 ++ num++;
24554 ++ }
24555 ++
24556 ++ return num;
24557 ++}
24558 ++
24559 ++static struct acl_subject_label *
24560 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
24561 ++
24562 ++static int
24563 ++copy_user_glob(struct acl_object_label *obj)
24564 ++{
24565 ++ struct acl_object_label *g_tmp, **guser;
24566 ++ unsigned int len;
24567 ++ char *tmp;
24568 ++
24569 ++ if (obj->globbed == NULL)
24570 ++ return 0;
24571 ++
24572 ++ guser = &obj->globbed;
24573 ++ while (*guser) {
24574 ++ g_tmp = (struct acl_object_label *)
24575 ++ acl_alloc(sizeof (struct acl_object_label));
24576 ++ if (g_tmp == NULL)
24577 ++ return -ENOMEM;
24578 ++
24579 ++ if (copy_from_user(g_tmp, *guser,
24580 ++ sizeof (struct acl_object_label)))
24581 ++ return -EFAULT;
24582 ++
24583 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
24584 ++
24585 ++ if (!len || len >= PATH_MAX)
24586 ++ return -EINVAL;
24587 ++
24588 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24589 ++ return -ENOMEM;
24590 ++
24591 ++ if (copy_from_user(tmp, g_tmp->filename, len))
24592 ++ return -EFAULT;
24593 ++
24594 ++ g_tmp->filename = tmp;
24595 ++
24596 ++ *guser = g_tmp;
24597 ++ guser = &(g_tmp->next);
24598 ++ }
24599 ++
24600 ++ return 0;
24601 ++}
24602 ++
24603 ++static int
24604 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
24605 ++ struct acl_role_label *role)
24606 ++{
24607 ++ struct acl_object_label *o_tmp;
24608 ++ unsigned int len;
24609 ++ int ret;
24610 ++ char *tmp;
24611 ++
24612 ++ while (userp) {
24613 ++ if ((o_tmp = (struct acl_object_label *)
24614 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
24615 ++ return -ENOMEM;
24616 ++
24617 ++ if (copy_from_user(o_tmp, userp,
24618 ++ sizeof (struct acl_object_label)))
24619 ++ return -EFAULT;
24620 ++
24621 ++ userp = o_tmp->prev;
24622 ++
24623 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
24624 ++
24625 ++ if (!len || len >= PATH_MAX)
24626 ++ return -EINVAL;
24627 ++
24628 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24629 ++ return -ENOMEM;
24630 ++
24631 ++ if (copy_from_user(tmp, o_tmp->filename, len))
24632 ++ return -EFAULT;
24633 ++
24634 ++ o_tmp->filename = tmp;
24635 ++
24636 ++ insert_acl_obj_label(o_tmp, subj);
24637 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
24638 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
24639 ++ return -ENOMEM;
24640 ++
24641 ++ ret = copy_user_glob(o_tmp);
24642 ++ if (ret)
24643 ++ return ret;
24644 ++
24645 ++ if (o_tmp->nested) {
24646 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
24647 ++ if (IS_ERR(o_tmp->nested))
24648 ++ return PTR_ERR(o_tmp->nested);
24649 ++
24650 ++ /* insert into nested subject list */
24651 ++ o_tmp->nested->next = role->hash->first;
24652 ++ role->hash->first = o_tmp->nested;
24653 ++ }
24654 ++ }
24655 ++
24656 ++ return 0;
24657 ++}
24658 ++
24659 ++static __u32
24660 ++count_user_subjs(struct acl_subject_label *userp)
24661 ++{
24662 ++ struct acl_subject_label s_tmp;
24663 ++ __u32 num = 0;
24664 ++
24665 ++ while (userp) {
24666 ++ if (copy_from_user(&s_tmp, userp,
24667 ++ sizeof (struct acl_subject_label)))
24668 ++ break;
24669 ++
24670 ++ userp = s_tmp.prev;
24671 ++ /* do not count nested subjects against this count, since
24672 ++ they are not included in the hash table, but are
24673 ++ attached to objects. We have already counted
24674 ++ the subjects in userspace for the allocation
24675 ++ stack
24676 ++ */
24677 ++ if (!(s_tmp.mode & GR_NESTED))
24678 ++ num++;
24679 ++ }
24680 ++
24681 ++ return num;
24682 ++}
24683 ++
24684 ++static int
24685 ++copy_user_allowedips(struct acl_role_label *rolep)
24686 ++{
24687 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
24688 ++
24689 ++ ruserip = rolep->allowed_ips;
24690 ++
24691 ++ while (ruserip) {
24692 ++ rlast = rtmp;
24693 ++
24694 ++ if ((rtmp = (struct role_allowed_ip *)
24695 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
24696 ++ return -ENOMEM;
24697 ++
24698 ++ if (copy_from_user(rtmp, ruserip,
24699 ++ sizeof (struct role_allowed_ip)))
24700 ++ return -EFAULT;
24701 ++
24702 ++ ruserip = rtmp->prev;
24703 ++
24704 ++ if (!rlast) {
24705 ++ rtmp->prev = NULL;
24706 ++ rolep->allowed_ips = rtmp;
24707 ++ } else {
24708 ++ rlast->next = rtmp;
24709 ++ rtmp->prev = rlast;
24710 ++ }
24711 ++
24712 ++ if (!ruserip)
24713 ++ rtmp->next = NULL;
24714 ++ }
24715 ++
24716 ++ return 0;
24717 ++}
24718 ++
24719 ++static int
24720 ++copy_user_transitions(struct acl_role_label *rolep)
24721 ++{
24722 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
24723 ++
24724 ++ unsigned int len;
24725 ++ char *tmp;
24726 ++
24727 ++ rusertp = rolep->transitions;
24728 ++
24729 ++ while (rusertp) {
24730 ++ rlast = rtmp;
24731 ++
24732 ++ if ((rtmp = (struct role_transition *)
24733 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
24734 ++ return -ENOMEM;
24735 ++
24736 ++ if (copy_from_user(rtmp, rusertp,
24737 ++ sizeof (struct role_transition)))
24738 ++ return -EFAULT;
24739 ++
24740 ++ rusertp = rtmp->prev;
24741 ++
24742 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
24743 ++
24744 ++ if (!len || len >= GR_SPROLE_LEN)
24745 ++ return -EINVAL;
24746 ++
24747 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24748 ++ return -ENOMEM;
24749 ++
24750 ++ if (copy_from_user(tmp, rtmp->rolename, len))
24751 ++ return -EFAULT;
24752 ++
24753 ++ rtmp->rolename = tmp;
24754 ++
24755 ++ if (!rlast) {
24756 ++ rtmp->prev = NULL;
24757 ++ rolep->transitions = rtmp;
24758 ++ } else {
24759 ++ rlast->next = rtmp;
24760 ++ rtmp->prev = rlast;
24761 ++ }
24762 ++
24763 ++ if (!rusertp)
24764 ++ rtmp->next = NULL;
24765 ++ }
24766 ++
24767 ++ return 0;
24768 ++}
24769 ++
24770 ++static struct acl_subject_label *
24771 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
24772 ++{
24773 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
24774 ++ unsigned int len;
24775 ++ char *tmp;
24776 ++ __u32 num_objs;
24777 ++ struct acl_ip_label **i_tmp, *i_utmp2;
24778 ++ struct gr_hash_struct ghash;
24779 ++ struct subject_map *subjmap;
24780 ++ unsigned int i_num;
24781 ++ int err;
24782 ++
24783 ++ s_tmp = lookup_subject_map(userp);
24784 ++
24785 ++ /* we've already copied this subject into the kernel, just return
24786 ++ the reference to it, and don't copy it over again
24787 ++ */
24788 ++ if (s_tmp)
24789 ++ return(s_tmp);
24790 ++
24791 ++ if ((s_tmp = (struct acl_subject_label *)
24792 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
24793 ++ return ERR_PTR(-ENOMEM);
24794 ++
24795 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
24796 ++ if (subjmap == NULL)
24797 ++ return ERR_PTR(-ENOMEM);
24798 ++
24799 ++ subjmap->user = userp;
24800 ++ subjmap->kernel = s_tmp;
24801 ++ insert_subj_map_entry(subjmap);
24802 ++
24803 ++ if (copy_from_user(s_tmp, userp,
24804 ++ sizeof (struct acl_subject_label)))
24805 ++ return ERR_PTR(-EFAULT);
24806 ++
24807 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
24808 ++
24809 ++ if (!len || len >= PATH_MAX)
24810 ++ return ERR_PTR(-EINVAL);
24811 ++
24812 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24813 ++ return ERR_PTR(-ENOMEM);
24814 ++
24815 ++ if (copy_from_user(tmp, s_tmp->filename, len))
24816 ++ return ERR_PTR(-EFAULT);
24817 ++
24818 ++ s_tmp->filename = tmp;
24819 ++
24820 ++ if (!strcmp(s_tmp->filename, "/"))
24821 ++ role->root_label = s_tmp;
24822 ++
24823 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
24824 ++ return ERR_PTR(-EFAULT);
24825 ++
24826 ++ /* copy user and group transition tables */
24827 ++
24828 ++ if (s_tmp->user_trans_num) {
24829 ++ uid_t *uidlist;
24830 ++
24831 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
24832 ++ if (uidlist == NULL)
24833 ++ return ERR_PTR(-ENOMEM);
24834 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
24835 ++ return ERR_PTR(-EFAULT);
24836 ++
24837 ++ s_tmp->user_transitions = uidlist;
24838 ++ }
24839 ++
24840 ++ if (s_tmp->group_trans_num) {
24841 ++ gid_t *gidlist;
24842 ++
24843 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
24844 ++ if (gidlist == NULL)
24845 ++ return ERR_PTR(-ENOMEM);
24846 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
24847 ++ return ERR_PTR(-EFAULT);
24848 ++
24849 ++ s_tmp->group_transitions = gidlist;
24850 ++ }
24851 ++
24852 ++ /* set up object hash table */
24853 ++ num_objs = count_user_objs(ghash.first);
24854 ++
24855 ++ s_tmp->obj_hash_size = num_objs;
24856 ++ s_tmp->obj_hash =
24857 ++ (struct acl_object_label **)
24858 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
24859 ++
24860 ++ if (!s_tmp->obj_hash)
24861 ++ return ERR_PTR(-ENOMEM);
24862 ++
24863 ++ memset(s_tmp->obj_hash, 0,
24864 ++ s_tmp->obj_hash_size *
24865 ++ sizeof (struct acl_object_label *));
24866 ++
24867 ++ /* add in objects */
24868 ++ err = copy_user_objs(ghash.first, s_tmp, role);
24869 ++
24870 ++ if (err)
24871 ++ return ERR_PTR(err);
24872 ++
24873 ++ /* set pointer for parent subject */
24874 ++ if (s_tmp->parent_subject) {
24875 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
24876 ++
24877 ++ if (IS_ERR(s_tmp2))
24878 ++ return s_tmp2;
24879 ++
24880 ++ s_tmp->parent_subject = s_tmp2;
24881 ++ }
24882 ++
24883 ++ /* add in ip acls */
24884 ++
24885 ++ if (!s_tmp->ip_num) {
24886 ++ s_tmp->ips = NULL;
24887 ++ goto insert;
24888 ++ }
24889 ++
24890 ++ i_tmp =
24891 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
24892 ++ sizeof (struct
24893 ++ acl_ip_label *));
24894 ++
24895 ++ if (!i_tmp)
24896 ++ return ERR_PTR(-ENOMEM);
24897 ++
24898 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
24899 ++ *(i_tmp + i_num) =
24900 ++ (struct acl_ip_label *)
24901 ++ acl_alloc(sizeof (struct acl_ip_label));
24902 ++ if (!*(i_tmp + i_num))
24903 ++ return ERR_PTR(-ENOMEM);
24904 ++
24905 ++ if (copy_from_user
24906 ++ (&i_utmp2, s_tmp->ips + i_num,
24907 ++ sizeof (struct acl_ip_label *)))
24908 ++ return ERR_PTR(-EFAULT);
24909 ++
24910 ++ if (copy_from_user
24911 ++ (*(i_tmp + i_num), i_utmp2,
24912 ++ sizeof (struct acl_ip_label)))
24913 ++ return ERR_PTR(-EFAULT);
24914 ++
24915 ++ if ((*(i_tmp + i_num))->iface == NULL)
24916 ++ continue;
24917 ++
24918 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
24919 ++ if (!len || len >= IFNAMSIZ)
24920 ++ return ERR_PTR(-EINVAL);
24921 ++ tmp = acl_alloc(len);
24922 ++ if (tmp == NULL)
24923 ++ return ERR_PTR(-ENOMEM);
24924 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
24925 ++ return ERR_PTR(-EFAULT);
24926 ++ (*(i_tmp + i_num))->iface = tmp;
24927 ++ }
24928 ++
24929 ++ s_tmp->ips = i_tmp;
24930 ++
24931 ++insert:
24932 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
24933 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
24934 ++ return ERR_PTR(-ENOMEM);
24935 ++
24936 ++ return s_tmp;
24937 ++}
24938 ++
24939 ++static int
24940 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
24941 ++{
24942 ++ struct acl_subject_label s_pre;
24943 ++ struct acl_subject_label * ret;
24944 ++ int err;
24945 ++
24946 ++ while (userp) {
24947 ++ if (copy_from_user(&s_pre, userp,
24948 ++ sizeof (struct acl_subject_label)))
24949 ++ return -EFAULT;
24950 ++
24951 ++ /* do not add nested subjects here, add
24952 ++ while parsing objects
24953 ++ */
24954 ++
24955 ++ if (s_pre.mode & GR_NESTED) {
24956 ++ userp = s_pre.prev;
24957 ++ continue;
24958 ++ }
24959 ++
24960 ++ ret = do_copy_user_subj(userp, role);
24961 ++
24962 ++ err = PTR_ERR(ret);
24963 ++ if (IS_ERR(ret))
24964 ++ return err;
24965 ++
24966 ++ insert_acl_subj_label(ret, role);
24967 ++
24968 ++ userp = s_pre.prev;
24969 ++ }
24970 ++
24971 ++ return 0;
24972 ++}
24973 ++
24974 ++static int
24975 ++copy_user_acl(struct gr_arg *arg)
24976 ++{
24977 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
24978 ++ struct sprole_pw *sptmp;
24979 ++ struct gr_hash_struct *ghash;
24980 ++ uid_t *domainlist;
24981 ++ unsigned int r_num;
24982 ++ unsigned int len;
24983 ++ char *tmp;
24984 ++ int err = 0;
24985 ++ __u16 i;
24986 ++ __u32 num_subjs;
24987 ++
24988 ++ /* we need a default and kernel role */
24989 ++ if (arg->role_db.num_roles < 2)
24990 ++ return -EINVAL;
24991 ++
24992 ++ /* copy special role authentication info from userspace */
24993 ++
24994 ++ num_sprole_pws = arg->num_sprole_pws;
24995 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
24996 ++
24997 ++ if (!acl_special_roles) {
24998 ++ err = -ENOMEM;
24999 ++ goto cleanup;
25000 ++ }
25001 ++
25002 ++ for (i = 0; i < num_sprole_pws; i++) {
25003 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
25004 ++ if (!sptmp) {
25005 ++ err = -ENOMEM;
25006 ++ goto cleanup;
25007 ++ }
25008 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
25009 ++ sizeof (struct sprole_pw))) {
25010 ++ err = -EFAULT;
25011 ++ goto cleanup;
25012 ++ }
25013 ++
25014 ++ len =
25015 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
25016 ++
25017 ++ if (!len || len >= GR_SPROLE_LEN) {
25018 ++ err = -EINVAL;
25019 ++ goto cleanup;
25020 ++ }
25021 ++
25022 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
25023 ++ err = -ENOMEM;
25024 ++ goto cleanup;
25025 ++ }
25026 ++
25027 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
25028 ++ err = -EFAULT;
25029 ++ goto cleanup;
25030 ++ }
25031 ++
25032 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25033 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
25034 ++#endif
25035 ++ sptmp->rolename = tmp;
25036 ++ acl_special_roles[i] = sptmp;
25037 ++ }
25038 ++
25039 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
25040 ++
25041 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
25042 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
25043 ++
25044 ++ if (!r_tmp) {
25045 ++ err = -ENOMEM;
25046 ++ goto cleanup;
25047 ++ }
25048 ++
25049 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
25050 ++ sizeof (struct acl_role_label *))) {
25051 ++ err = -EFAULT;
25052 ++ goto cleanup;
25053 ++ }
25054 ++
25055 ++ if (copy_from_user(r_tmp, r_utmp2,
25056 ++ sizeof (struct acl_role_label))) {
25057 ++ err = -EFAULT;
25058 ++ goto cleanup;
25059 ++ }
25060 ++
25061 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
25062 ++
25063 ++ if (!len || len >= PATH_MAX) {
25064 ++ err = -EINVAL;
25065 ++ goto cleanup;
25066 ++ }
25067 ++
25068 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
25069 ++ err = -ENOMEM;
25070 ++ goto cleanup;
25071 ++ }
25072 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
25073 ++ err = -EFAULT;
25074 ++ goto cleanup;
25075 ++ }
25076 ++ r_tmp->rolename = tmp;
25077 ++
25078 ++ if (!strcmp(r_tmp->rolename, "default")
25079 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
25080 ++ default_role = r_tmp;
25081 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
25082 ++ kernel_role = r_tmp;
25083 ++ }
25084 ++
25085 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
25086 ++ err = -ENOMEM;
25087 ++ goto cleanup;
25088 ++ }
25089 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
25090 ++ err = -EFAULT;
25091 ++ goto cleanup;
25092 ++ }
25093 ++
25094 ++ r_tmp->hash = ghash;
25095 ++
25096 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
25097 ++
25098 ++ r_tmp->subj_hash_size = num_subjs;
25099 ++ r_tmp->subj_hash =
25100 ++ (struct acl_subject_label **)
25101 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
25102 ++
25103 ++ if (!r_tmp->subj_hash) {
25104 ++ err = -ENOMEM;
25105 ++ goto cleanup;
25106 ++ }
25107 ++
25108 ++ err = copy_user_allowedips(r_tmp);
25109 ++ if (err)
25110 ++ goto cleanup;
25111 ++
25112 ++ /* copy domain info */
25113 ++ if (r_tmp->domain_children != NULL) {
25114 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
25115 ++ if (domainlist == NULL) {
25116 ++ err = -ENOMEM;
25117 ++ goto cleanup;
25118 ++ }
25119 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
25120 ++ err = -EFAULT;
25121 ++ goto cleanup;
25122 ++ }
25123 ++ r_tmp->domain_children = domainlist;
25124 ++ }
25125 ++
25126 ++ err = copy_user_transitions(r_tmp);
25127 ++ if (err)
25128 ++ goto cleanup;
25129 ++
25130 ++ memset(r_tmp->subj_hash, 0,
25131 ++ r_tmp->subj_hash_size *
25132 ++ sizeof (struct acl_subject_label *));
25133 ++
25134 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
25135 ++
25136 ++ if (err)
25137 ++ goto cleanup;
25138 ++
25139 ++ /* set nested subject list to null */
25140 ++ r_tmp->hash->first = NULL;
25141 ++
25142 ++ insert_acl_role_label(r_tmp);
25143 ++ }
25144 ++
25145 ++ goto return_err;
25146 ++ cleanup:
25147 ++ free_variables();
25148 ++ return_err:
25149 ++ return err;
25150 ++
25151 ++}
25152 ++
25153 ++static int
25154 ++gracl_init(struct gr_arg *args)
25155 ++{
25156 ++ int error = 0;
25157 ++
25158 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
25159 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
25160 ++
25161 ++ if (init_variables(args)) {
25162 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
25163 ++ error = -ENOMEM;
25164 ++ free_variables();
25165 ++ goto out;
25166 ++ }
25167 ++
25168 ++ error = copy_user_acl(args);
25169 ++ free_init_variables();
25170 ++ if (error) {
25171 ++ free_variables();
25172 ++ goto out;
25173 ++ }
25174 ++
25175 ++ if ((error = gr_set_acls(0))) {
25176 ++ free_variables();
25177 ++ goto out;
25178 ++ }
25179 ++
25180 ++ gr_status |= GR_READY;
25181 ++ out:
25182 ++ return error;
25183 ++}
25184 ++
25185 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
25186 ++
25187 ++static int
25188 ++glob_match(const char *p, const char *n)
25189 ++{
25190 ++ char c;
25191 ++
25192 ++ while ((c = *p++) != '\0') {
25193 ++ switch (c) {
25194 ++ case '?':
25195 ++ if (*n == '\0')
25196 ++ return 1;
25197 ++ else if (*n == '/')
25198 ++ return 1;
25199 ++ break;
25200 ++ case '\\':
25201 ++ if (*n != c)
25202 ++ return 1;
25203 ++ break;
25204 ++ case '*':
25205 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
25206 ++ if (*n == '/')
25207 ++ return 1;
25208 ++ else if (c == '?') {
25209 ++ if (*n == '\0')
25210 ++ return 1;
25211 ++ else
25212 ++ ++n;
25213 ++ }
25214 ++ }
25215 ++ if (c == '\0') {
25216 ++ return 0;
25217 ++ } else {
25218 ++ const char *endp;
25219 ++
25220 ++ if ((endp = strchr(n, '/')) == NULL)
25221 ++ endp = n + strlen(n);
25222 ++
25223 ++ if (c == '[') {
25224 ++ for (--p; n < endp; ++n)
25225 ++ if (!glob_match(p, n))
25226 ++ return 0;
25227 ++ } else if (c == '/') {
25228 ++ while (*n != '\0' && *n != '/')
25229 ++ ++n;
25230 ++ if (*n == '/' && !glob_match(p, n + 1))
25231 ++ return 0;
25232 ++ } else {
25233 ++ for (--p; n < endp; ++n)
25234 ++ if (*n == c && !glob_match(p, n))
25235 ++ return 0;
25236 ++ }
25237 ++
25238 ++ return 1;
25239 ++ }
25240 ++ case '[':
25241 ++ {
25242 ++ int not;
25243 ++ char cold;
25244 ++
25245 ++ if (*n == '\0' || *n == '/')
25246 ++ return 1;
25247 ++
25248 ++ not = (*p == '!' || *p == '^');
25249 ++ if (not)
25250 ++ ++p;
25251 ++
25252 ++ c = *p++;
25253 ++ for (;;) {
25254 ++ unsigned char fn = (unsigned char)*n;
25255 ++
25256 ++ if (c == '\0')
25257 ++ return 1;
25258 ++ else {
25259 ++ if (c == fn)
25260 ++ goto matched;
25261 ++ cold = c;
25262 ++ c = *p++;
25263 ++
25264 ++ if (c == '-' && *p != ']') {
25265 ++ unsigned char cend = *p++;
25266 ++
25267 ++ if (cend == '\0')
25268 ++ return 1;
25269 ++
25270 ++ if (cold <= fn && fn <= cend)
25271 ++ goto matched;
25272 ++
25273 ++ c = *p++;
25274 ++ }
25275 ++ }
25276 ++
25277 ++ if (c == ']')
25278 ++ break;
25279 ++ }
25280 ++ if (!not)
25281 ++ return 1;
25282 ++ break;
25283 ++ matched:
25284 ++ while (c != ']') {
25285 ++ if (c == '\0')
25286 ++ return 1;
25287 ++
25288 ++ c = *p++;
25289 ++ }
25290 ++ if (not)
25291 ++ return 1;
25292 ++ }
25293 ++ break;
25294 ++ default:
25295 ++ if (c != *n)
25296 ++ return 1;
25297 ++ }
25298 ++
25299 ++ ++n;
25300 ++ }
25301 ++
25302 ++ if (*n == '\0')
25303 ++ return 0;
25304 ++
25305 ++ if (*n == '/')
25306 ++ return 0;
25307 ++
25308 ++ return 1;
25309 ++}
25310 ++
25311 ++static struct acl_object_label *
25312 ++chk_glob_label(struct acl_object_label *globbed,
25313 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
25314 ++{
25315 ++ struct acl_object_label *tmp;
25316 ++
25317 ++ if (*path == NULL)
25318 ++ *path = gr_to_filename_nolock(dentry, mnt);
25319 ++
25320 ++ tmp = globbed;
25321 ++
25322 ++ while (tmp) {
25323 ++ if (!glob_match(tmp->filename, *path))
25324 ++ return tmp;
25325 ++ tmp = tmp->next;
25326 ++ }
25327 ++
25328 ++ return NULL;
25329 ++}
25330 ++
25331 ++static struct acl_object_label *
25332 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
25333 ++ const ino_t curr_ino, const dev_t curr_dev,
25334 ++ const struct acl_subject_label *subj, char **path)
25335 ++{
25336 ++ struct acl_subject_label *tmpsubj;
25337 ++ struct acl_object_label *retval;
25338 ++ struct acl_object_label *retval2;
25339 ++
25340 ++ tmpsubj = (struct acl_subject_label *) subj;
25341 ++ read_lock(&gr_inode_lock);
25342 ++ do {
25343 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
25344 ++ if (retval) {
25345 ++ if (retval->globbed) {
25346 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
25347 ++ (struct vfsmount *)orig_mnt, path);
25348 ++ if (retval2)
25349 ++ retval = retval2;
25350 ++ }
25351 ++ break;
25352 ++ }
25353 ++ } while ((tmpsubj = tmpsubj->parent_subject));
25354 ++ read_unlock(&gr_inode_lock);
25355 ++
25356 ++ return retval;
25357 ++}
25358 ++
25359 ++static __inline__ struct acl_object_label *
25360 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
25361 ++ const struct dentry *curr_dentry,
25362 ++ const struct acl_subject_label *subj, char **path)
25363 ++{
25364 ++ return __full_lookup(orig_dentry, orig_mnt,
25365 ++ curr_dentry->d_inode->i_ino,
25366 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
25367 ++}
25368 ++
25369 ++static struct acl_object_label *
25370 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25371 ++ const struct acl_subject_label *subj, char *path)
25372 ++{
25373 ++ struct dentry *dentry = (struct dentry *) l_dentry;
25374 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
25375 ++ struct acl_object_label *retval;
25376 ++
25377 ++ spin_lock(&dcache_lock);
25378 ++
25379 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
25380 ++ /* ignore Eric Biederman */
25381 ++ IS_PRIVATE(l_dentry->d_inode))) {
25382 ++ retval = fakefs_obj;
25383 ++ goto out;
25384 ++ }
25385 ++
25386 ++ for (;;) {
25387 ++ if (dentry == real_root && mnt == real_root_mnt)
25388 ++ break;
25389 ++
25390 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
25391 ++ if (mnt->mnt_parent == mnt)
25392 ++ break;
25393 ++
25394 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25395 ++ if (retval != NULL)
25396 ++ goto out;
25397 ++
25398 ++ dentry = mnt->mnt_mountpoint;
25399 ++ mnt = mnt->mnt_parent;
25400 ++ continue;
25401 ++ }
25402 ++
25403 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25404 ++ if (retval != NULL)
25405 ++ goto out;
25406 ++
25407 ++ dentry = dentry->d_parent;
25408 ++ }
25409 ++
25410 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25411 ++
25412 ++ if (retval == NULL)
25413 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
25414 ++out:
25415 ++ spin_unlock(&dcache_lock);
25416 ++ return retval;
25417 ++}
25418 ++
25419 ++static __inline__ struct acl_object_label *
25420 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25421 ++ const struct acl_subject_label *subj)
25422 ++{
25423 ++ char *path = NULL;
25424 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
25425 ++}
25426 ++
25427 ++static __inline__ struct acl_object_label *
25428 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25429 ++ const struct acl_subject_label *subj, char *path)
25430 ++{
25431 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
25432 ++}
25433 ++
25434 ++static struct acl_subject_label *
25435 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25436 ++ const struct acl_role_label *role)
25437 ++{
25438 ++ struct dentry *dentry = (struct dentry *) l_dentry;
25439 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
25440 ++ struct acl_subject_label *retval;
25441 ++
25442 ++ spin_lock(&dcache_lock);
25443 ++
25444 ++ for (;;) {
25445 ++ if (dentry == real_root && mnt == real_root_mnt)
25446 ++ break;
25447 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
25448 ++ if (mnt->mnt_parent == mnt)
25449 ++ break;
25450 ++
25451 ++ read_lock(&gr_inode_lock);
25452 ++ retval =
25453 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
25454 ++ dentry->d_inode->i_sb->s_dev, role);
25455 ++ read_unlock(&gr_inode_lock);
25456 ++ if (retval != NULL)
25457 ++ goto out;
25458 ++
25459 ++ dentry = mnt->mnt_mountpoint;
25460 ++ mnt = mnt->mnt_parent;
25461 ++ continue;
25462 ++ }
25463 ++
25464 ++ read_lock(&gr_inode_lock);
25465 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
25466 ++ dentry->d_inode->i_sb->s_dev, role);
25467 ++ read_unlock(&gr_inode_lock);
25468 ++ if (retval != NULL)
25469 ++ goto out;
25470 ++
25471 ++ dentry = dentry->d_parent;
25472 ++ }
25473 ++
25474 ++ read_lock(&gr_inode_lock);
25475 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
25476 ++ dentry->d_inode->i_sb->s_dev, role);
25477 ++ read_unlock(&gr_inode_lock);
25478 ++
25479 ++ if (unlikely(retval == NULL)) {
25480 ++ read_lock(&gr_inode_lock);
25481 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
25482 ++ real_root->d_inode->i_sb->s_dev, role);
25483 ++ read_unlock(&gr_inode_lock);
25484 ++ }
25485 ++out:
25486 ++ spin_unlock(&dcache_lock);
25487 ++
25488 ++ return retval;
25489 ++}
25490 ++
25491 ++static void
25492 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
25493 ++{
25494 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
25495 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
25496 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
25497 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
25498 ++
25499 ++ return;
25500 ++}
25501 ++
25502 ++static void
25503 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
25504 ++{
25505 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
25506 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
25507 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
25508 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
25509 ++
25510 ++ return;
25511 ++}
25512 ++
25513 ++static void
25514 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
25515 ++ const unsigned int effective, const unsigned int fs)
25516 ++{
25517 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
25518 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
25519 ++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
25520 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
25521 ++
25522 ++ return;
25523 ++}
25524 ++
25525 ++__u32
25526 ++gr_check_link(const struct dentry * new_dentry,
25527 ++ const struct dentry * parent_dentry,
25528 ++ const struct vfsmount * parent_mnt,
25529 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
25530 ++{
25531 ++ struct acl_object_label *obj;
25532 ++ __u32 oldmode, newmode;
25533 ++ __u32 needmode;
25534 ++
25535 ++ if (unlikely(!(gr_status & GR_READY)))
25536 ++ return (GR_CREATE | GR_LINK);
25537 ++
25538 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
25539 ++ oldmode = obj->mode;
25540 ++
25541 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25542 ++ oldmode |= (GR_CREATE | GR_LINK);
25543 ++
25544 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
25545 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
25546 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
25547 ++
25548 ++ newmode =
25549 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
25550 ++ oldmode | needmode);
25551 ++
25552 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
25553 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
25554 ++ GR_INHERIT | GR_AUDIT_INHERIT);
25555 ++
25556 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
25557 ++ goto bad;
25558 ++
25559 ++ if ((oldmode & needmode) != needmode)
25560 ++ goto bad;
25561 ++
25562 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
25563 ++ if ((newmode & needmode) != needmode)
25564 ++ goto bad;
25565 ++
25566 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
25567 ++ return newmode;
25568 ++bad:
25569 ++ needmode = oldmode;
25570 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
25571 ++ needmode |= GR_SETID;
25572 ++
25573 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
25574 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
25575 ++ return (GR_CREATE | GR_LINK);
25576 ++ } else if (newmode & GR_SUPPRESS)
25577 ++ return GR_SUPPRESS;
25578 ++ else
25579 ++ return 0;
25580 ++}
25581 ++
25582 ++__u32
25583 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
25584 ++ const struct vfsmount * mnt)
25585 ++{
25586 ++ __u32 retval = mode;
25587 ++ struct acl_subject_label *curracl;
25588 ++ struct acl_object_label *currobj;
25589 ++
25590 ++ if (unlikely(!(gr_status & GR_READY)))
25591 ++ return (mode & ~GR_AUDITS);
25592 ++
25593 ++ curracl = current->acl;
25594 ++
25595 ++ currobj = chk_obj_label(dentry, mnt, curracl);
25596 ++ retval = currobj->mode & mode;
25597 ++
25598 ++ if (unlikely
25599 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
25600 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
25601 ++ __u32 new_mode = mode;
25602 ++
25603 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25604 ++
25605 ++ retval = new_mode;
25606 ++
25607 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
25608 ++ new_mode |= GR_INHERIT;
25609 ++
25610 ++ if (!(mode & GR_NOLEARN))
25611 ++ gr_log_learn(current, dentry, mnt, new_mode);
25612 ++ }
25613 ++
25614 ++ return retval;
25615 ++}
25616 ++
25617 ++__u32
25618 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
25619 ++ const struct vfsmount * mnt, const __u32 mode)
25620 ++{
25621 ++ struct name_entry *match;
25622 ++ struct acl_object_label *matchpo;
25623 ++ struct acl_subject_label *curracl;
25624 ++ char *path;
25625 ++ __u32 retval;
25626 ++
25627 ++ if (unlikely(!(gr_status & GR_READY)))
25628 ++ return (mode & ~GR_AUDITS);
25629 ++
25630 ++ preempt_disable();
25631 ++ path = gr_to_filename_rbac(new_dentry, mnt);
25632 ++ match = lookup_name_entry_create(path);
25633 ++
25634 ++ if (!match)
25635 ++ goto check_parent;
25636 ++
25637 ++ curracl = current->acl;
25638 ++
25639 ++ read_lock(&gr_inode_lock);
25640 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
25641 ++ read_unlock(&gr_inode_lock);
25642 ++
25643 ++ if (matchpo) {
25644 ++ if ((matchpo->mode & mode) !=
25645 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
25646 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
25647 ++ __u32 new_mode = mode;
25648 ++
25649 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25650 ++
25651 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
25652 ++
25653 ++ preempt_enable();
25654 ++ return new_mode;
25655 ++ }
25656 ++ preempt_enable();
25657 ++ return (matchpo->mode & mode);
25658 ++ }
25659 ++
25660 ++ check_parent:
25661 ++ curracl = current->acl;
25662 ++
25663 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
25664 ++ retval = matchpo->mode & mode;
25665 ++
25666 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
25667 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
25668 ++ __u32 new_mode = mode;
25669 ++
25670 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25671 ++
25672 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
25673 ++ preempt_enable();
25674 ++ return new_mode;
25675 ++ }
25676 ++
25677 ++ preempt_enable();
25678 ++ return retval;
25679 ++}
25680 ++
25681 ++int
25682 ++gr_check_hidden_task(const struct task_struct *task)
25683 ++{
25684 ++ if (unlikely(!(gr_status & GR_READY)))
25685 ++ return 0;
25686 ++
25687 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
25688 ++ return 1;
25689 ++
25690 ++ return 0;
25691 ++}
25692 ++
25693 ++int
25694 ++gr_check_protected_task(const struct task_struct *task)
25695 ++{
25696 ++ if (unlikely(!(gr_status & GR_READY) || !task))
25697 ++ return 0;
25698 ++
25699 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
25700 ++ task->acl != current->acl)
25701 ++ return 1;
25702 ++
25703 ++ return 0;
25704 ++}
25705 ++
25706 ++void
25707 ++gr_copy_label(struct task_struct *tsk)
25708 ++{
25709 ++ tsk->signal->used_accept = 0;
25710 ++ tsk->acl_sp_role = 0;
25711 ++ tsk->acl_role_id = current->acl_role_id;
25712 ++ tsk->acl = current->acl;
25713 ++ tsk->role = current->role;
25714 ++ tsk->signal->curr_ip = current->signal->curr_ip;
25715 ++ if (current->exec_file)
25716 ++ get_file(current->exec_file);
25717 ++ tsk->exec_file = current->exec_file;
25718 ++ tsk->is_writable = current->is_writable;
25719 ++ if (unlikely(current->signal->used_accept))
25720 ++ current->signal->curr_ip = 0;
25721 ++
25722 ++ return;
25723 ++}
25724 ++
25725 ++static void
25726 ++gr_set_proc_res(struct task_struct *task)
25727 ++{
25728 ++ struct acl_subject_label *proc;
25729 ++ unsigned short i;
25730 ++
25731 ++ proc = task->acl;
25732 ++
25733 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
25734 ++ return;
25735 ++
25736 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
25737 ++ if (!(proc->resmask & (1 << i)))
25738 ++ continue;
25739 ++
25740 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
25741 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
25742 ++ }
25743 ++
25744 ++ return;
25745 ++}
25746 ++
25747 ++int
25748 ++gr_check_user_change(int real, int effective, int fs)
25749 ++{
25750 ++ unsigned int i;
25751 ++ __u16 num;
25752 ++ uid_t *uidlist;
25753 ++ int curuid;
25754 ++ int realok = 0;
25755 ++ int effectiveok = 0;
25756 ++ int fsok = 0;
25757 ++
25758 ++ if (unlikely(!(gr_status & GR_READY)))
25759 ++ return 0;
25760 ++
25761 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25762 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
25763 ++
25764 ++ num = current->acl->user_trans_num;
25765 ++ uidlist = current->acl->user_transitions;
25766 ++
25767 ++ if (uidlist == NULL)
25768 ++ return 0;
25769 ++
25770 ++ if (real == -1)
25771 ++ realok = 1;
25772 ++ if (effective == -1)
25773 ++ effectiveok = 1;
25774 ++ if (fs == -1)
25775 ++ fsok = 1;
25776 ++
25777 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
25778 ++ for (i = 0; i < num; i++) {
25779 ++ curuid = (int)uidlist[i];
25780 ++ if (real == curuid)
25781 ++ realok = 1;
25782 ++ if (effective == curuid)
25783 ++ effectiveok = 1;
25784 ++ if (fs == curuid)
25785 ++ fsok = 1;
25786 ++ }
25787 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
25788 ++ for (i = 0; i < num; i++) {
25789 ++ curuid = (int)uidlist[i];
25790 ++ if (real == curuid)
25791 ++ break;
25792 ++ if (effective == curuid)
25793 ++ break;
25794 ++ if (fs == curuid)
25795 ++ break;
25796 ++ }
25797 ++ /* not in deny list */
25798 ++ if (i == num) {
25799 ++ realok = 1;
25800 ++ effectiveok = 1;
25801 ++ fsok = 1;
25802 ++ }
25803 ++ }
25804 ++
25805 ++ if (realok && effectiveok && fsok)
25806 ++ return 0;
25807 ++ else {
25808 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
25809 ++ return 1;
25810 ++ }
25811 ++}
25812 ++
25813 ++int
25814 ++gr_check_group_change(int real, int effective, int fs)
25815 ++{
25816 ++ unsigned int i;
25817 ++ __u16 num;
25818 ++ gid_t *gidlist;
25819 ++ int curgid;
25820 ++ int realok = 0;
25821 ++ int effectiveok = 0;
25822 ++ int fsok = 0;
25823 ++
25824 ++ if (unlikely(!(gr_status & GR_READY)))
25825 ++ return 0;
25826 ++
25827 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25828 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
25829 ++
25830 ++ num = current->acl->group_trans_num;
25831 ++ gidlist = current->acl->group_transitions;
25832 ++
25833 ++ if (gidlist == NULL)
25834 ++ return 0;
25835 ++
25836 ++ if (real == -1)
25837 ++ realok = 1;
25838 ++ if (effective == -1)
25839 ++ effectiveok = 1;
25840 ++ if (fs == -1)
25841 ++ fsok = 1;
25842 ++
25843 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
25844 ++ for (i = 0; i < num; i++) {
25845 ++ curgid = (int)gidlist[i];
25846 ++ if (real == curgid)
25847 ++ realok = 1;
25848 ++ if (effective == curgid)
25849 ++ effectiveok = 1;
25850 ++ if (fs == curgid)
25851 ++ fsok = 1;
25852 ++ }
25853 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
25854 ++ for (i = 0; i < num; i++) {
25855 ++ curgid = (int)gidlist[i];
25856 ++ if (real == curgid)
25857 ++ break;
25858 ++ if (effective == curgid)
25859 ++ break;
25860 ++ if (fs == curgid)
25861 ++ break;
25862 ++ }
25863 ++ /* not in deny list */
25864 ++ if (i == num) {
25865 ++ realok = 1;
25866 ++ effectiveok = 1;
25867 ++ fsok = 1;
25868 ++ }
25869 ++ }
25870 ++
25871 ++ if (realok && effectiveok && fsok)
25872 ++ return 0;
25873 ++ else {
25874 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
25875 ++ return 1;
25876 ++ }
25877 ++}
25878 ++
25879 ++void
25880 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
25881 ++{
25882 ++ struct acl_role_label *role = task->role;
25883 ++ struct acl_subject_label *subj = NULL;
25884 ++ struct acl_object_label *obj;
25885 ++ struct file *filp;
25886 ++
25887 ++ if (unlikely(!(gr_status & GR_READY)))
25888 ++ return;
25889 ++
25890 ++ filp = task->exec_file;
25891 ++
25892 ++ /* kernel process, we'll give them the kernel role */
25893 ++ if (unlikely(!filp)) {
25894 ++ task->role = kernel_role;
25895 ++ task->acl = kernel_role->root_label;
25896 ++ return;
25897 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
25898 ++ role = lookup_acl_role_label(task, uid, gid);
25899 ++
25900 ++ /* perform subject lookup in possibly new role
25901 ++ we can use this result below in the case where role == task->role
25902 ++ */
25903 ++ subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
25904 ++
25905 ++ /* if we changed uid/gid, but result in the same role
25906 ++ and are using inheritance, don't lose the inherited subject
25907 ++ if current subject is other than what normal lookup
25908 ++ would result in, we arrived via inheritance, don't
25909 ++ lose subject
25910 ++ */
25911 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
25912 ++ (subj == task->acl)))
25913 ++ task->acl = subj;
25914 ++
25915 ++ task->role = role;
25916 ++
25917 ++ task->is_writable = 0;
25918 ++
25919 ++ /* ignore additional mmap checks for processes that are writable
25920 ++ by the default ACL */
25921 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
25922 ++ if (unlikely(obj->mode & GR_WRITE))
25923 ++ task->is_writable = 1;
25924 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
25925 ++ if (unlikely(obj->mode & GR_WRITE))
25926 ++ task->is_writable = 1;
25927 ++
25928 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25929 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
25930 ++#endif
25931 ++
25932 ++ gr_set_proc_res(task);
25933 ++
25934 ++ return;
25935 ++}
25936 ++
25937 ++int
25938 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
25939 ++{
25940 ++ struct task_struct *task = current;
25941 ++ struct acl_subject_label *newacl;
25942 ++ struct acl_object_label *obj;
25943 ++ __u32 retmode;
25944 ++
25945 ++ if (unlikely(!(gr_status & GR_READY)))
25946 ++ return 0;
25947 ++
25948 ++ newacl = chk_subj_label(dentry, mnt, task->role);
25949 ++
25950 ++ task_lock(task);
25951 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
25952 ++ GR_POVERRIDE) && (task->acl != newacl) &&
25953 ++ !(task->role->roletype & GR_ROLE_GOD) &&
25954 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
25955 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
25956 ++ (atomic_read(&task->fs->count) > 1 ||
25957 ++ atomic_read(&task->files->count) > 1 ||
25958 ++ atomic_read(&task->sighand->count) > 1)) {
25959 ++ task_unlock(task);
25960 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
25961 ++ return -EACCES;
25962 ++ }
25963 ++ task_unlock(task);
25964 ++
25965 ++ obj = chk_obj_label(dentry, mnt, task->acl);
25966 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
25967 ++
25968 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
25969 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
25970 ++ if (obj->nested)
25971 ++ task->acl = obj->nested;
25972 ++ else
25973 ++ task->acl = newacl;
25974 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
25975 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
25976 ++
25977 ++ task->is_writable = 0;
25978 ++
25979 ++ /* ignore additional mmap checks for processes that are writable
25980 ++ by the default ACL */
25981 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
25982 ++ if (unlikely(obj->mode & GR_WRITE))
25983 ++ task->is_writable = 1;
25984 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
25985 ++ if (unlikely(obj->mode & GR_WRITE))
25986 ++ task->is_writable = 1;
25987 ++
25988 ++ gr_set_proc_res(task);
25989 ++
25990 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25991 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
25992 ++#endif
25993 ++ return 0;
25994 ++}
25995 ++
25996 ++/* always called with valid inodev ptr */
25997 ++static void
25998 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
25999 ++{
26000 ++ struct acl_object_label *matchpo;
26001 ++ struct acl_subject_label *matchps;
26002 ++ struct acl_subject_label *subj;
26003 ++ struct acl_role_label *role;
26004 ++ unsigned int i, x;
26005 ++
26006 ++ FOR_EACH_ROLE_START(role, i)
26007 ++ FOR_EACH_SUBJECT_START(role, subj, x)
26008 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
26009 ++ matchpo->mode |= GR_DELETED;
26010 ++ FOR_EACH_SUBJECT_END(subj,x)
26011 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
26012 ++ if (subj->inode == ino && subj->device == dev)
26013 ++ subj->mode |= GR_DELETED;
26014 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
26015 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
26016 ++ matchps->mode |= GR_DELETED;
26017 ++ FOR_EACH_ROLE_END(role,i)
26018 ++
26019 ++ inodev->nentry->deleted = 1;
26020 ++
26021 ++ return;
26022 ++}
26023 ++
26024 ++void
26025 ++gr_handle_delete(const ino_t ino, const dev_t dev)
26026 ++{
26027 ++ struct inodev_entry *inodev;
26028 ++
26029 ++ if (unlikely(!(gr_status & GR_READY)))
26030 ++ return;
26031 ++
26032 ++ write_lock(&gr_inode_lock);
26033 ++ inodev = lookup_inodev_entry(ino, dev);
26034 ++ if (inodev != NULL)
26035 ++ do_handle_delete(inodev, ino, dev);
26036 ++ write_unlock(&gr_inode_lock);
26037 ++
26038 ++ return;
26039 ++}
26040 ++
26041 ++static void
26042 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
26043 ++ const ino_t newinode, const dev_t newdevice,
26044 ++ struct acl_subject_label *subj)
26045 ++{
26046 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
26047 ++ struct acl_object_label *match;
26048 ++
26049 ++ match = subj->obj_hash[index];
26050 ++
26051 ++ while (match && (match->inode != oldinode ||
26052 ++ match->device != olddevice ||
26053 ++ !(match->mode & GR_DELETED)))
26054 ++ match = match->next;
26055 ++
26056 ++ if (match && (match->inode == oldinode)
26057 ++ && (match->device == olddevice)
26058 ++ && (match->mode & GR_DELETED)) {
26059 ++ if (match->prev == NULL) {
26060 ++ subj->obj_hash[index] = match->next;
26061 ++ if (match->next != NULL)
26062 ++ match->next->prev = NULL;
26063 ++ } else {
26064 ++ match->prev->next = match->next;
26065 ++ if (match->next != NULL)
26066 ++ match->next->prev = match->prev;
26067 ++ }
26068 ++ match->prev = NULL;
26069 ++ match->next = NULL;
26070 ++ match->inode = newinode;
26071 ++ match->device = newdevice;
26072 ++ match->mode &= ~GR_DELETED;
26073 ++
26074 ++ insert_acl_obj_label(match, subj);
26075 ++ }
26076 ++
26077 ++ return;
26078 ++}
26079 ++
26080 ++static void
26081 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
26082 ++ const ino_t newinode, const dev_t newdevice,
26083 ++ struct acl_role_label *role)
26084 ++{
26085 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
26086 ++ struct acl_subject_label *match;
26087 ++
26088 ++ match = role->subj_hash[index];
26089 ++
26090 ++ while (match && (match->inode != oldinode ||
26091 ++ match->device != olddevice ||
26092 ++ !(match->mode & GR_DELETED)))
26093 ++ match = match->next;
26094 ++
26095 ++ if (match && (match->inode == oldinode)
26096 ++ && (match->device == olddevice)
26097 ++ && (match->mode & GR_DELETED)) {
26098 ++ if (match->prev == NULL) {
26099 ++ role->subj_hash[index] = match->next;
26100 ++ if (match->next != NULL)
26101 ++ match->next->prev = NULL;
26102 ++ } else {
26103 ++ match->prev->next = match->next;
26104 ++ if (match->next != NULL)
26105 ++ match->next->prev = match->prev;
26106 ++ }
26107 ++ match->prev = NULL;
26108 ++ match->next = NULL;
26109 ++ match->inode = newinode;
26110 ++ match->device = newdevice;
26111 ++ match->mode &= ~GR_DELETED;
26112 ++
26113 ++ insert_acl_subj_label(match, role);
26114 ++ }
26115 ++
26116 ++ return;
26117 ++}
26118 ++
26119 ++static void
26120 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
26121 ++ const ino_t newinode, const dev_t newdevice)
26122 ++{
26123 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
26124 ++ struct inodev_entry *match;
26125 ++
26126 ++ match = inodev_set.i_hash[index];
26127 ++
26128 ++ while (match && (match->nentry->inode != oldinode ||
26129 ++ match->nentry->device != olddevice || !match->nentry->deleted))
26130 ++ match = match->next;
26131 ++
26132 ++ if (match && (match->nentry->inode == oldinode)
26133 ++ && (match->nentry->device == olddevice) &&
26134 ++ match->nentry->deleted) {
26135 ++ if (match->prev == NULL) {
26136 ++ inodev_set.i_hash[index] = match->next;
26137 ++ if (match->next != NULL)
26138 ++ match->next->prev = NULL;
26139 ++ } else {
26140 ++ match->prev->next = match->next;
26141 ++ if (match->next != NULL)
26142 ++ match->next->prev = match->prev;
26143 ++ }
26144 ++ match->prev = NULL;
26145 ++ match->next = NULL;
26146 ++ match->nentry->inode = newinode;
26147 ++ match->nentry->device = newdevice;
26148 ++ match->nentry->deleted = 0;
26149 ++
26150 ++ insert_inodev_entry(match);
26151 ++ }
26152 ++
26153 ++ return;
26154 ++}
26155 ++
26156 ++static void
26157 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
26158 ++ const struct vfsmount *mnt)
26159 ++{
26160 ++ struct acl_subject_label *subj;
26161 ++ struct acl_role_label *role;
26162 ++ unsigned int i, x;
26163 ++
26164 ++ FOR_EACH_ROLE_START(role, i)
26165 ++ update_acl_subj_label(matchn->inode, matchn->device,
26166 ++ dentry->d_inode->i_ino,
26167 ++ dentry->d_inode->i_sb->s_dev, role);
26168 ++
26169 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
26170 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
26171 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
26172 ++ subj->inode = dentry->d_inode->i_ino;
26173 ++ subj->device = dentry->d_inode->i_sb->s_dev;
26174 ++ }
26175 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
26176 ++ FOR_EACH_SUBJECT_START(role, subj, x)
26177 ++ update_acl_obj_label(matchn->inode, matchn->device,
26178 ++ dentry->d_inode->i_ino,
26179 ++ dentry->d_inode->i_sb->s_dev, subj);
26180 ++ FOR_EACH_SUBJECT_END(subj,x)
26181 ++ FOR_EACH_ROLE_END(role,i)
26182 ++
26183 ++ update_inodev_entry(matchn->inode, matchn->device,
26184 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
26185 ++
26186 ++ return;
26187 ++}
26188 ++
26189 ++void
26190 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
26191 ++{
26192 ++ struct name_entry *matchn;
26193 ++
26194 ++ if (unlikely(!(gr_status & GR_READY)))
26195 ++ return;
26196 ++
26197 ++ preempt_disable();
26198 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
26199 ++
26200 ++ if (unlikely((unsigned long)matchn)) {
26201 ++ write_lock(&gr_inode_lock);
26202 ++ do_handle_create(matchn, dentry, mnt);
26203 ++ write_unlock(&gr_inode_lock);
26204 ++ }
26205 ++ preempt_enable();
26206 ++
26207 ++ return;
26208 ++}
26209 ++
26210 ++void
26211 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26212 ++ struct dentry *old_dentry,
26213 ++ struct dentry *new_dentry,
26214 ++ struct vfsmount *mnt, const __u8 replace)
26215 ++{
26216 ++ struct name_entry *matchn;
26217 ++ struct inodev_entry *inodev;
26218 ++
26219 ++ /* vfs_rename swaps the name and parent link for old_dentry and
26220 ++ new_dentry
26221 ++ at this point, old_dentry has the new name, parent link, and inode
26222 ++ for the renamed file
26223 ++ if a file is being replaced by a rename, new_dentry has the inode
26224 ++ and name for the replaced file
26225 ++ */
26226 ++
26227 ++ if (unlikely(!(gr_status & GR_READY)))
26228 ++ return;
26229 ++
26230 ++ preempt_disable();
26231 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
26232 ++
26233 ++ /* we wouldn't have to check d_inode if it weren't for
26234 ++ NFS silly-renaming
26235 ++ */
26236 ++
26237 ++ write_lock(&gr_inode_lock);
26238 ++ if (unlikely(replace && new_dentry->d_inode)) {
26239 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
26240 ++ new_dentry->d_inode->i_sb->s_dev);
26241 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
26242 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
26243 ++ new_dentry->d_inode->i_sb->s_dev);
26244 ++ }
26245 ++
26246 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
26247 ++ old_dentry->d_inode->i_sb->s_dev);
26248 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
26249 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
26250 ++ old_dentry->d_inode->i_sb->s_dev);
26251 ++
26252 ++ if (unlikely((unsigned long)matchn))
26253 ++ do_handle_create(matchn, old_dentry, mnt);
26254 ++
26255 ++ write_unlock(&gr_inode_lock);
26256 ++ preempt_enable();
26257 ++
26258 ++ return;
26259 ++}
26260 ++
26261 ++static int
26262 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
26263 ++ unsigned char **sum)
26264 ++{
26265 ++ struct acl_role_label *r;
26266 ++ struct role_allowed_ip *ipp;
26267 ++ struct role_transition *trans;
26268 ++ unsigned int i;
26269 ++ int found = 0;
26270 ++
26271 ++ /* check transition table */
26272 ++
26273 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
26274 ++ if (!strcmp(rolename, trans->rolename)) {
26275 ++ found = 1;
26276 ++ break;
26277 ++ }
26278 ++ }
26279 ++
26280 ++ if (!found)
26281 ++ return 0;
26282 ++
26283 ++ /* handle special roles that do not require authentication
26284 ++ and check ip */
26285 ++
26286 ++ FOR_EACH_ROLE_START(r, i)
26287 ++ if (!strcmp(rolename, r->rolename) &&
26288 ++ (r->roletype & GR_ROLE_SPECIAL)) {
26289 ++ found = 0;
26290 ++ if (r->allowed_ips != NULL) {
26291 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
26292 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
26293 ++ (ntohl(ipp->addr) & ipp->netmask))
26294 ++ found = 1;
26295 ++ }
26296 ++ } else
26297 ++ found = 2;
26298 ++ if (!found)
26299 ++ return 0;
26300 ++
26301 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
26302 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
26303 ++ *salt = NULL;
26304 ++ *sum = NULL;
26305 ++ return 1;
26306 ++ }
26307 ++ }
26308 ++ FOR_EACH_ROLE_END(r,i)
26309 ++
26310 ++ for (i = 0; i < num_sprole_pws; i++) {
26311 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
26312 ++ *salt = acl_special_roles[i]->salt;
26313 ++ *sum = acl_special_roles[i]->sum;
26314 ++ return 1;
26315 ++ }
26316 ++ }
26317 ++
26318 ++ return 0;
26319 ++}
26320 ++
26321 ++static void
26322 ++assign_special_role(char *rolename)
26323 ++{
26324 ++ struct acl_object_label *obj;
26325 ++ struct acl_role_label *r;
26326 ++ struct acl_role_label *assigned = NULL;
26327 ++ struct task_struct *tsk;
26328 ++ struct file *filp;
26329 ++ unsigned int i;
26330 ++
26331 ++ FOR_EACH_ROLE_START(r, i)
26332 ++ if (!strcmp(rolename, r->rolename) &&
26333 ++ (r->roletype & GR_ROLE_SPECIAL))
26334 ++ assigned = r;
26335 ++ FOR_EACH_ROLE_END(r,i)
26336 ++
26337 ++ if (!assigned)
26338 ++ return;
26339 ++
26340 ++ read_lock(&tasklist_lock);
26341 ++ read_lock(&grsec_exec_file_lock);
26342 ++
26343 ++ tsk = current->parent;
26344 ++ if (tsk == NULL)
26345 ++ goto out_unlock;
26346 ++
26347 ++ filp = tsk->exec_file;
26348 ++ if (filp == NULL)
26349 ++ goto out_unlock;
26350 ++
26351 ++ tsk->is_writable = 0;
26352 ++
26353 ++ tsk->acl_sp_role = 1;
26354 ++ tsk->acl_role_id = ++acl_sp_role_value;
26355 ++ tsk->role = assigned;
26356 ++ tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
26357 ++
26358 ++ /* ignore additional mmap checks for processes that are writable
26359 ++ by the default ACL */
26360 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
26361 ++ if (unlikely(obj->mode & GR_WRITE))
26362 ++ tsk->is_writable = 1;
26363 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
26364 ++ if (unlikely(obj->mode & GR_WRITE))
26365 ++ tsk->is_writable = 1;
26366 ++
26367 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26368 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
26369 ++#endif
26370 ++
26371 ++out_unlock:
26372 ++ read_unlock(&grsec_exec_file_lock);
26373 ++ read_unlock(&tasklist_lock);
26374 ++ return;
26375 ++}
26376 ++
26377 ++int gr_check_secure_terminal(struct task_struct *task)
26378 ++{
26379 ++ struct task_struct *p, *p2, *p3;
26380 ++ struct files_struct *files;
26381 ++ struct fdtable *fdt;
26382 ++ struct file *our_file = NULL, *file;
26383 ++ int i;
26384 ++
26385 ++ if (task->signal->tty == NULL)
26386 ++ return 1;
26387 ++
26388 ++ files = get_files_struct(task);
26389 ++ if (files != NULL) {
26390 ++ rcu_read_lock();
26391 ++ fdt = files_fdtable(files);
26392 ++ for (i=0; i < fdt->max_fds; i++) {
26393 ++ file = fcheck_files(files, i);
26394 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
26395 ++ get_file(file);
26396 ++ our_file = file;
26397 ++ }
26398 ++ }
26399 ++ rcu_read_unlock();
26400 ++ put_files_struct(files);
26401 ++ }
26402 ++
26403 ++ if (our_file == NULL)
26404 ++ return 1;
26405 ++
26406 ++ read_lock(&tasklist_lock);
26407 ++ do_each_thread(p2, p) {
26408 ++ files = get_files_struct(p);
26409 ++ if (files == NULL ||
26410 ++ (p->signal && p->signal->tty == task->signal->tty)) {
26411 ++ if (files != NULL)
26412 ++ put_files_struct(files);
26413 ++ continue;
26414 ++ }
26415 ++ rcu_read_lock();
26416 ++ fdt = files_fdtable(files);
26417 ++ for (i=0; i < fdt->max_fds; i++) {
26418 ++ file = fcheck_files(files, i);
26419 ++ if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
26420 ++ file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
26421 ++ p3 = task;
26422 ++ while (p3->pid > 0) {
26423 ++ if (p3 == p)
26424 ++ break;
26425 ++ p3 = p3->parent;
26426 ++ }
26427 ++ if (p3 == p)
26428 ++ break;
26429 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
26430 ++ gr_handle_alertkill(p);
26431 ++ rcu_read_unlock();
26432 ++ put_files_struct(files);
26433 ++ read_unlock(&tasklist_lock);
26434 ++ fput(our_file);
26435 ++ return 0;
26436 ++ }
26437 ++ }
26438 ++ rcu_read_unlock();
26439 ++ put_files_struct(files);
26440 ++ } while_each_thread(p2, p);
26441 ++ read_unlock(&tasklist_lock);
26442 ++
26443 ++ fput(our_file);
26444 ++ return 1;
26445 ++}
26446 ++
26447 ++ssize_t
26448 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
26449 ++{
26450 ++ struct gr_arg_wrapper uwrap;
26451 ++ unsigned char *sprole_salt;
26452 ++ unsigned char *sprole_sum;
26453 ++ int error = sizeof (struct gr_arg_wrapper);
26454 ++ int error2 = 0;
26455 ++
26456 ++ down(&gr_dev_sem);
26457 ++
26458 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
26459 ++ error = -EPERM;
26460 ++ goto out;
26461 ++ }
26462 ++
26463 ++ if (count != sizeof (struct gr_arg_wrapper)) {
26464 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
26465 ++ error = -EINVAL;
26466 ++ goto out;
26467 ++ }
26468 ++
26469 ++
26470 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
26471 ++ gr_auth_expires = 0;
26472 ++ gr_auth_attempts = 0;
26473 ++ }
26474 ++
26475 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
26476 ++ error = -EFAULT;
26477 ++ goto out;
26478 ++ }
26479 ++
26480 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
26481 ++ error = -EINVAL;
26482 ++ goto out;
26483 ++ }
26484 ++
26485 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
26486 ++ error = -EFAULT;
26487 ++ goto out;
26488 ++ }
26489 ++
26490 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
26491 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
26492 ++ time_after(gr_auth_expires, get_seconds())) {
26493 ++ error = -EBUSY;
26494 ++ goto out;
26495 ++ }
26496 ++
26497 ++ /* if non-root trying to do anything other than use a special role,
26498 ++ do not attempt authentication, do not count towards authentication
26499 ++ locking
26500 ++ */
26501 ++
26502 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
26503 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
26504 ++ current->uid) {
26505 ++ error = -EPERM;
26506 ++ goto out;
26507 ++ }
26508 ++
26509 ++ /* ensure pw and special role name are null terminated */
26510 ++
26511 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
26512 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
26513 ++
26514 ++ /* Okay.
26515 ++ * We have our enough of the argument structure..(we have yet
26516 ++ * to copy_from_user the tables themselves) . Copy the tables
26517 ++ * only if we need them, i.e. for loading operations. */
26518 ++
26519 ++ switch (gr_usermode->mode) {
26520 ++ case STATUS:
26521 ++ if (gr_status & GR_READY) {
26522 ++ error = 1;
26523 ++ if (!gr_check_secure_terminal(current))
26524 ++ error = 3;
26525 ++ } else
26526 ++ error = 2;
26527 ++ goto out;
26528 ++ case SHUTDOWN:
26529 ++ if ((gr_status & GR_READY)
26530 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26531 ++ gr_status &= ~GR_READY;
26532 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
26533 ++ free_variables();
26534 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
26535 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
26536 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
26537 ++ } else if (gr_status & GR_READY) {
26538 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
26539 ++ error = -EPERM;
26540 ++ } else {
26541 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
26542 ++ error = -EAGAIN;
26543 ++ }
26544 ++ break;
26545 ++ case ENABLE:
26546 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
26547 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
26548 ++ else {
26549 ++ if (gr_status & GR_READY)
26550 ++ error = -EAGAIN;
26551 ++ else
26552 ++ error = error2;
26553 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
26554 ++ }
26555 ++ break;
26556 ++ case RELOAD:
26557 ++ if (!(gr_status & GR_READY)) {
26558 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
26559 ++ error = -EAGAIN;
26560 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26561 ++ lock_kernel();
26562 ++ gr_status &= ~GR_READY;
26563 ++ free_variables();
26564 ++ if (!(error2 = gracl_init(gr_usermode))) {
26565 ++ unlock_kernel();
26566 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
26567 ++ } else {
26568 ++ unlock_kernel();
26569 ++ error = error2;
26570 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
26571 ++ }
26572 ++ } else {
26573 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
26574 ++ error = -EPERM;
26575 ++ }
26576 ++ break;
26577 ++ case SEGVMOD:
26578 ++ if (unlikely(!(gr_status & GR_READY))) {
26579 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
26580 ++ error = -EAGAIN;
26581 ++ break;
26582 ++ }
26583 ++
26584 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26585 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
26586 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
26587 ++ struct acl_subject_label *segvacl;
26588 ++ segvacl =
26589 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
26590 ++ gr_usermode->segv_device,
26591 ++ current->role);
26592 ++ if (segvacl) {
26593 ++ segvacl->crashes = 0;
26594 ++ segvacl->expires = 0;
26595 ++ }
26596 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
26597 ++ gr_remove_uid(gr_usermode->segv_uid);
26598 ++ }
26599 ++ } else {
26600 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
26601 ++ error = -EPERM;
26602 ++ }
26603 ++ break;
26604 ++ case SPROLE:
26605 ++ case SPROLEPAM:
26606 ++ if (unlikely(!(gr_status & GR_READY))) {
26607 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
26608 ++ error = -EAGAIN;
26609 ++ break;
26610 ++ }
26611 ++
26612 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
26613 ++ current->role->expires = 0;
26614 ++ current->role->auth_attempts = 0;
26615 ++ }
26616 ++
26617 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
26618 ++ time_after(current->role->expires, get_seconds())) {
26619 ++ error = -EBUSY;
26620 ++ goto out;
26621 ++ }
26622 ++
26623 ++ if (lookup_special_role_auth
26624 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
26625 ++ && ((!sprole_salt && !sprole_sum)
26626 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
26627 ++ char *p = "";
26628 ++ assign_special_role(gr_usermode->sp_role);
26629 ++ read_lock(&tasklist_lock);
26630 ++ if (current->parent)
26631 ++ p = current->parent->role->rolename;
26632 ++ read_unlock(&tasklist_lock);
26633 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
26634 ++ p, acl_sp_role_value);
26635 ++ } else {
26636 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
26637 ++ error = -EPERM;
26638 ++ if(!(current->role->auth_attempts++))
26639 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
26640 ++
26641 ++ goto out;
26642 ++ }
26643 ++ break;
26644 ++ case UNSPROLE:
26645 ++ if (unlikely(!(gr_status & GR_READY))) {
26646 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
26647 ++ error = -EAGAIN;
26648 ++ break;
26649 ++ }
26650 ++
26651 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
26652 ++ char *p = "";
26653 ++ int i = 0;
26654 ++
26655 ++ read_lock(&tasklist_lock);
26656 ++ if (current->parent) {
26657 ++ p = current->parent->role->rolename;
26658 ++ i = current->parent->acl_role_id;
26659 ++ }
26660 ++ read_unlock(&tasklist_lock);
26661 ++
26662 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
26663 ++ gr_set_acls(1);
26664 ++ } else {
26665 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
26666 ++ error = -EPERM;
26667 ++ goto out;
26668 ++ }
26669 ++ break;
26670 ++ default:
26671 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
26672 ++ error = -EINVAL;
26673 ++ break;
26674 ++ }
26675 ++
26676 ++ if (error != -EPERM)
26677 ++ goto out;
26678 ++
26679 ++ if(!(gr_auth_attempts++))
26680 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
26681 ++
26682 ++ out:
26683 ++ up(&gr_dev_sem);
26684 ++ return error;
26685 ++}
26686 ++
26687 ++int
26688 ++gr_set_acls(const int type)
26689 ++{
26690 ++ struct acl_object_label *obj;
26691 ++ struct task_struct *task, *task2;
26692 ++ struct file *filp;
26693 ++ struct acl_role_label *role = current->role;
26694 ++ __u16 acl_role_id = current->acl_role_id;
26695 ++
26696 ++ read_lock(&tasklist_lock);
26697 ++ read_lock(&grsec_exec_file_lock);
26698 ++ do_each_thread(task2, task) {
26699 ++ /* check to see if we're called from the exit handler,
26700 ++ if so, only replace ACLs that have inherited the admin
26701 ++ ACL */
26702 ++
26703 ++ if (type && (task->role != role ||
26704 ++ task->acl_role_id != acl_role_id))
26705 ++ continue;
26706 ++
26707 ++ task->acl_role_id = 0;
26708 ++ task->acl_sp_role = 0;
26709 ++
26710 ++ if ((filp = task->exec_file)) {
26711 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
26712 ++
26713 ++ task->acl =
26714 ++ chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
26715 ++ task->role);
26716 ++ if (task->acl) {
26717 ++ struct acl_subject_label *curr;
26718 ++ curr = task->acl;
26719 ++
26720 ++ task->is_writable = 0;
26721 ++ /* ignore additional mmap checks for processes that are writable
26722 ++ by the default ACL */
26723 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
26724 ++ if (unlikely(obj->mode & GR_WRITE))
26725 ++ task->is_writable = 1;
26726 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
26727 ++ if (unlikely(obj->mode & GR_WRITE))
26728 ++ task->is_writable = 1;
26729 ++
26730 ++ gr_set_proc_res(task);
26731 ++
26732 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26733 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
26734 ++#endif
26735 ++ } else {
26736 ++ read_unlock(&grsec_exec_file_lock);
26737 ++ read_unlock(&tasklist_lock);
26738 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
26739 ++ return 1;
26740 ++ }
26741 ++ } else {
26742 ++ // it's a kernel process
26743 ++ task->role = kernel_role;
26744 ++ task->acl = kernel_role->root_label;
26745 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
26746 ++ task->acl->mode &= ~GR_PROCFIND;
26747 ++#endif
26748 ++ }
26749 ++ } while_each_thread(task2, task);
26750 ++ read_unlock(&grsec_exec_file_lock);
26751 ++ read_unlock(&tasklist_lock);
26752 ++ return 0;
26753 ++}
26754 ++
26755 ++void
26756 ++gr_learn_resource(const struct task_struct *task,
26757 ++ const int res, const unsigned long wanted, const int gt)
26758 ++{
26759 ++ struct acl_subject_label *acl;
26760 ++
26761 ++ if (unlikely((gr_status & GR_READY) &&
26762 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
26763 ++ goto skip_reslog;
26764 ++
26765 ++#ifdef CONFIG_GRKERNSEC_RESLOG
26766 ++ gr_log_resource(task, res, wanted, gt);
26767 ++#endif
26768 ++ skip_reslog:
26769 ++
26770 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
26771 ++ return;
26772 ++
26773 ++ acl = task->acl;
26774 ++
26775 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
26776 ++ !(acl->resmask & (1 << (unsigned short) res))))
26777 ++ return;
26778 ++
26779 ++ if (wanted >= acl->res[res].rlim_cur) {
26780 ++ unsigned long res_add;
26781 ++
26782 ++ res_add = wanted;
26783 ++ switch (res) {
26784 ++ case RLIMIT_CPU:
26785 ++ res_add += GR_RLIM_CPU_BUMP;
26786 ++ break;
26787 ++ case RLIMIT_FSIZE:
26788 ++ res_add += GR_RLIM_FSIZE_BUMP;
26789 ++ break;
26790 ++ case RLIMIT_DATA:
26791 ++ res_add += GR_RLIM_DATA_BUMP;
26792 ++ break;
26793 ++ case RLIMIT_STACK:
26794 ++ res_add += GR_RLIM_STACK_BUMP;
26795 ++ break;
26796 ++ case RLIMIT_CORE:
26797 ++ res_add += GR_RLIM_CORE_BUMP;
26798 ++ break;
26799 ++ case RLIMIT_RSS:
26800 ++ res_add += GR_RLIM_RSS_BUMP;
26801 ++ break;
26802 ++ case RLIMIT_NPROC:
26803 ++ res_add += GR_RLIM_NPROC_BUMP;
26804 ++ break;
26805 ++ case RLIMIT_NOFILE:
26806 ++ res_add += GR_RLIM_NOFILE_BUMP;
26807 ++ break;
26808 ++ case RLIMIT_MEMLOCK:
26809 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
26810 ++ break;
26811 ++ case RLIMIT_AS:
26812 ++ res_add += GR_RLIM_AS_BUMP;
26813 ++ break;
26814 ++ case RLIMIT_LOCKS:
26815 ++ res_add += GR_RLIM_LOCKS_BUMP;
26816 ++ break;
26817 ++ }
26818 ++
26819 ++ acl->res[res].rlim_cur = res_add;
26820 ++
26821 ++ if (wanted > acl->res[res].rlim_max)
26822 ++ acl->res[res].rlim_max = res_add;
26823 ++
26824 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
26825 ++ task->role->roletype, acl->filename,
26826 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
26827 ++ "", (unsigned long) res);
26828 ++ }
26829 ++
26830 ++ return;
26831 ++}
26832 ++
26833 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26834 ++void
26835 ++pax_set_initial_flags(struct linux_binprm *bprm)
26836 ++{
26837 ++ struct task_struct *task = current;
26838 ++ struct acl_subject_label *proc;
26839 ++ unsigned long flags;
26840 ++
26841 ++ if (unlikely(!(gr_status & GR_READY)))
26842 ++ return;
26843 ++
26844 ++ flags = pax_get_flags(task);
26845 ++
26846 ++ proc = task->acl;
26847 ++
26848 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
26849 ++ flags &= ~MF_PAX_PAGEEXEC;
26850 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
26851 ++ flags &= ~MF_PAX_SEGMEXEC;
26852 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
26853 ++ flags &= ~MF_PAX_RANDMMAP;
26854 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
26855 ++ flags &= ~MF_PAX_EMUTRAMP;
26856 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
26857 ++ flags &= ~MF_PAX_MPROTECT;
26858 ++
26859 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
26860 ++ flags |= MF_PAX_PAGEEXEC;
26861 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
26862 ++ flags |= MF_PAX_SEGMEXEC;
26863 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
26864 ++ flags |= MF_PAX_RANDMMAP;
26865 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
26866 ++ flags |= MF_PAX_EMUTRAMP;
26867 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
26868 ++ flags |= MF_PAX_MPROTECT;
26869 ++
26870 ++ pax_set_flags(task, flags);
26871 ++
26872 ++ return;
26873 ++}
26874 ++#endif
26875 ++
26876 ++#ifdef CONFIG_SYSCTL
26877 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
26878 ++ system to save 35kb of memory */
26879 ++
26880 ++/* we modify the passed in filename, but adjust it back before returning */
26881 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
26882 ++{
26883 ++ struct name_entry *nmatch;
26884 ++ char *p, *lastp = NULL;
26885 ++ struct acl_object_label *obj = NULL, *tmp;
26886 ++ struct acl_subject_label *tmpsubj;
26887 ++ char c = '\0';
26888 ++
26889 ++ read_lock(&gr_inode_lock);
26890 ++
26891 ++ p = name + len - 1;
26892 ++ do {
26893 ++ nmatch = lookup_name_entry(name);
26894 ++ if (lastp != NULL)
26895 ++ *lastp = c;
26896 ++
26897 ++ if (nmatch == NULL)
26898 ++ goto next_component;
26899 ++ tmpsubj = current->acl;
26900 ++ do {
26901 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
26902 ++ if (obj != NULL) {
26903 ++ tmp = obj->globbed;
26904 ++ while (tmp) {
26905 ++ if (!glob_match(tmp->filename, name)) {
26906 ++ obj = tmp;
26907 ++ goto found_obj;
26908 ++ }
26909 ++ tmp = tmp->next;
26910 ++ }
26911 ++ goto found_obj;
26912 ++ }
26913 ++ } while ((tmpsubj = tmpsubj->parent_subject));
26914 ++next_component:
26915 ++ /* end case */
26916 ++ if (p == name)
26917 ++ break;
26918 ++
26919 ++ while (*p != '/')
26920 ++ p--;
26921 ++ if (p == name)
26922 ++ lastp = p + 1;
26923 ++ else {
26924 ++ lastp = p;
26925 ++ p--;
26926 ++ }
26927 ++ c = *lastp;
26928 ++ *lastp = '\0';
26929 ++ } while (1);
26930 ++found_obj:
26931 ++ read_unlock(&gr_inode_lock);
26932 ++ /* obj returned will always be non-null */
26933 ++ return obj;
26934 ++}
26935 ++
26936 ++/* returns 0 when allowing, non-zero on error
26937 ++ op of 0 is used for readdir, so we don't log the names of hidden files
26938 ++*/
26939 ++__u32
26940 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
26941 ++{
26942 ++ ctl_table *tmp;
26943 ++ const char *proc_sys = "/proc/sys";
26944 ++ char *path;
26945 ++ struct acl_object_label *obj;
26946 ++ unsigned short len = 0, pos = 0, depth = 0, i;
26947 ++ __u32 err = 0;
26948 ++ __u32 mode = 0;
26949 ++
26950 ++ if (unlikely(!(gr_status & GR_READY)))
26951 ++ return 0;
26952 ++
26953 ++ /* for now, ignore operations on non-sysctl entries if it's not a
26954 ++ readdir*/
26955 ++ if (table->child != NULL && op != 0)
26956 ++ return 0;
26957 ++
26958 ++ mode |= GR_FIND;
26959 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
26960 ++ if (op & 004)
26961 ++ mode |= GR_READ;
26962 ++ if (op & 002)
26963 ++ mode |= GR_WRITE;
26964 ++
26965 ++ preempt_disable();
26966 ++
26967 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
26968 ++
26969 ++ /* it's only a read/write if it's an actual entry, not a dir
26970 ++ (which are opened for readdir)
26971 ++ */
26972 ++
26973 ++ /* convert the requested sysctl entry into a pathname */
26974 ++
26975 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
26976 ++ len += strlen(tmp->procname);
26977 ++ len++;
26978 ++ depth++;
26979 ++ }
26980 ++
26981 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
26982 ++ /* deny */
26983 ++ goto out;
26984 ++ }
26985 ++
26986 ++ memset(path, 0, PAGE_SIZE);
26987 ++
26988 ++ memcpy(path, proc_sys, strlen(proc_sys));
26989 ++
26990 ++ pos += strlen(proc_sys);
26991 ++
26992 ++ for (; depth > 0; depth--) {
26993 ++ path[pos] = '/';
26994 ++ pos++;
26995 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
26996 ++ if (depth == i) {
26997 ++ memcpy(path + pos, tmp->procname,
26998 ++ strlen(tmp->procname));
26999 ++ pos += strlen(tmp->procname);
27000 ++ }
27001 ++ i++;
27002 ++ }
27003 ++ }
27004 ++
27005 ++ obj = gr_lookup_by_name(path, pos);
27006 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
27007 ++
27008 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
27009 ++ ((err & mode) != mode))) {
27010 ++ __u32 new_mode = mode;
27011 ++
27012 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
27013 ++
27014 ++ err = 0;
27015 ++ gr_log_learn_sysctl(current, path, new_mode);
27016 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
27017 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
27018 ++ err = -ENOENT;
27019 ++ } else if (!(err & GR_FIND)) {
27020 ++ err = -ENOENT;
27021 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
27022 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
27023 ++ path, (mode & GR_READ) ? " reading" : "",
27024 ++ (mode & GR_WRITE) ? " writing" : "");
27025 ++ err = -EACCES;
27026 ++ } else if ((err & mode) != mode) {
27027 ++ err = -EACCES;
27028 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
27029 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
27030 ++ path, (mode & GR_READ) ? " reading" : "",
27031 ++ (mode & GR_WRITE) ? " writing" : "");
27032 ++ err = 0;
27033 ++ } else
27034 ++ err = 0;
27035 ++
27036 ++ out:
27037 ++ preempt_enable();
27038 ++
27039 ++ return err;
27040 ++}
27041 ++#endif
27042 ++
27043 ++int
27044 ++gr_handle_proc_ptrace(struct task_struct *task)
27045 ++{
27046 ++ struct file *filp;
27047 ++ struct task_struct *tmp = task;
27048 ++ struct task_struct *curtemp = current;
27049 ++ __u32 retmode;
27050 ++
27051 ++ if (unlikely(!(gr_status & GR_READY)))
27052 ++ return 0;
27053 ++
27054 ++ read_lock(&tasklist_lock);
27055 ++ read_lock(&grsec_exec_file_lock);
27056 ++ filp = task->exec_file;
27057 ++
27058 ++ while (tmp->pid > 0) {
27059 ++ if (tmp == curtemp)
27060 ++ break;
27061 ++ tmp = tmp->parent;
27062 ++ }
27063 ++
27064 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
27065 ++ read_unlock(&grsec_exec_file_lock);
27066 ++ read_unlock(&tasklist_lock);
27067 ++ return 1;
27068 ++ }
27069 ++
27070 ++ retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
27071 ++ read_unlock(&grsec_exec_file_lock);
27072 ++ read_unlock(&tasklist_lock);
27073 ++
27074 ++ if (retmode & GR_NOPTRACE)
27075 ++ return 1;
27076 ++
27077 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
27078 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
27079 ++ && current->pid != task->pid)))
27080 ++ return 1;
27081 ++
27082 ++ return 0;
27083 ++}
27084 ++
27085 ++int
27086 ++gr_handle_ptrace(struct task_struct *task, const long request)
27087 ++{
27088 ++ struct task_struct *tmp = task;
27089 ++ struct task_struct *curtemp = current;
27090 ++ __u32 retmode;
27091 ++
27092 ++ if (unlikely(!(gr_status & GR_READY)))
27093 ++ return 0;
27094 ++
27095 ++ read_lock(&tasklist_lock);
27096 ++ while (tmp->pid > 0) {
27097 ++ if (tmp == curtemp)
27098 ++ break;
27099 ++ tmp = tmp->parent;
27100 ++ }
27101 ++
27102 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
27103 ++ read_unlock(&tasklist_lock);
27104 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27105 ++ return 1;
27106 ++ }
27107 ++ read_unlock(&tasklist_lock);
27108 ++
27109 ++ read_lock(&grsec_exec_file_lock);
27110 ++ if (unlikely(!task->exec_file)) {
27111 ++ read_unlock(&grsec_exec_file_lock);
27112 ++ return 0;
27113 ++ }
27114 ++
27115 ++ retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
27116 ++ read_unlock(&grsec_exec_file_lock);
27117 ++
27118 ++ if (retmode & GR_NOPTRACE) {
27119 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27120 ++ return 1;
27121 ++ }
27122 ++
27123 ++ if (retmode & GR_PTRACERD) {
27124 ++ switch (request) {
27125 ++ case PTRACE_POKETEXT:
27126 ++ case PTRACE_POKEDATA:
27127 ++ case PTRACE_POKEUSR:
27128 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
27129 ++ case PTRACE_SETREGS:
27130 ++ case PTRACE_SETFPREGS:
27131 ++#endif
27132 ++#ifdef CONFIG_X86
27133 ++ case PTRACE_SETFPXREGS:
27134 ++#endif
27135 ++#ifdef CONFIG_ALTIVEC
27136 ++ case PTRACE_SETVRREGS:
27137 ++#endif
27138 ++ return 1;
27139 ++ default:
27140 ++ return 0;
27141 ++ }
27142 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
27143 ++ !(current->role->roletype & GR_ROLE_GOD) &&
27144 ++ (current->acl != task->acl)) {
27145 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27146 ++ return 1;
27147 ++ }
27148 ++
27149 ++ return 0;
27150 ++}
27151 ++
27152 ++static int is_writable_mmap(const struct file *filp)
27153 ++{
27154 ++ struct task_struct *task = current;
27155 ++ struct acl_object_label *obj, *obj2;
27156 ++
27157 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
27158 ++ !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
27159 ++ obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
27160 ++ obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
27161 ++ task->role->root_label);
27162 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
27163 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
27164 ++ return 1;
27165 ++ }
27166 ++ }
27167 ++ return 0;
27168 ++}
27169 ++
27170 ++int
27171 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
27172 ++{
27173 ++ __u32 mode;
27174 ++
27175 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
27176 ++ return 1;
27177 ++
27178 ++ if (is_writable_mmap(file))
27179 ++ return 0;
27180 ++
27181 ++ mode =
27182 ++ gr_search_file(file->f_path.dentry,
27183 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
27184 ++ file->f_path.mnt);
27185 ++
27186 ++ if (!gr_tpe_allow(file))
27187 ++ return 0;
27188 ++
27189 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
27190 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27191 ++ return 0;
27192 ++ } else if (unlikely(!(mode & GR_EXEC))) {
27193 ++ return 0;
27194 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
27195 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27196 ++ return 1;
27197 ++ }
27198 ++
27199 ++ return 1;
27200 ++}
27201 ++
27202 ++int
27203 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
27204 ++{
27205 ++ __u32 mode;
27206 ++
27207 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
27208 ++ return 1;
27209 ++
27210 ++ if (is_writable_mmap(file))
27211 ++ return 0;
27212 ++
27213 ++ mode =
27214 ++ gr_search_file(file->f_path.dentry,
27215 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
27216 ++ file->f_path.mnt);
27217 ++
27218 ++ if (!gr_tpe_allow(file))
27219 ++ return 0;
27220 ++
27221 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
27222 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27223 ++ return 0;
27224 ++ } else if (unlikely(!(mode & GR_EXEC))) {
27225 ++ return 0;
27226 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
27227 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
27228 ++ return 1;
27229 ++ }
27230 ++
27231 ++ return 1;
27232 ++}
27233 ++
27234 ++void
27235 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
27236 ++{
27237 ++ unsigned long runtime;
27238 ++ unsigned long cputime;
27239 ++ unsigned int wday, cday;
27240 ++ __u8 whr, chr;
27241 ++ __u8 wmin, cmin;
27242 ++ __u8 wsec, csec;
27243 ++ struct timespec timeval;
27244 ++
27245 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
27246 ++ !(task->acl->mode & GR_PROCACCT)))
27247 ++ return;
27248 ++
27249 ++ do_posix_clock_monotonic_gettime(&timeval);
27250 ++ runtime = timeval.tv_sec - task->start_time.tv_sec;
27251 ++ wday = runtime / (3600 * 24);
27252 ++ runtime -= wday * (3600 * 24);
27253 ++ whr = runtime / 3600;
27254 ++ runtime -= whr * 3600;
27255 ++ wmin = runtime / 60;
27256 ++ runtime -= wmin * 60;
27257 ++ wsec = runtime;
27258 ++
27259 ++ cputime = (task->utime + task->stime) / HZ;
27260 ++ cday = cputime / (3600 * 24);
27261 ++ cputime -= cday * (3600 * 24);
27262 ++ chr = cputime / 3600;
27263 ++ cputime -= chr * 3600;
27264 ++ cmin = cputime / 60;
27265 ++ cputime -= cmin * 60;
27266 ++ csec = cputime;
27267 ++
27268 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
27269 ++
27270 ++ return;
27271 ++}
27272 ++
27273 ++void gr_set_kernel_label(struct task_struct *task)
27274 ++{
27275 ++ if (gr_status & GR_READY) {
27276 ++ task->role = kernel_role;
27277 ++ task->acl = kernel_role->root_label;
27278 ++ }
27279 ++ return;
27280 ++}
27281 ++
27282 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
27283 ++{
27284 ++ struct task_struct *task = current;
27285 ++ struct dentry *dentry = file->f_path.dentry;
27286 ++ struct vfsmount *mnt = file->f_path.mnt;
27287 ++ struct acl_object_label *obj, *tmp;
27288 ++ struct acl_subject_label *subj;
27289 ++ unsigned int bufsize;
27290 ++ int is_not_root;
27291 ++ char *path;
27292 ++
27293 ++ if (unlikely(!(gr_status & GR_READY)))
27294 ++ return 1;
27295 ++
27296 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
27297 ++ return 1;
27298 ++
27299 ++ /* ignore Eric Biederman */
27300 ++ if (IS_PRIVATE(dentry->d_inode))
27301 ++ return 1;
27302 ++
27303 ++ subj = task->acl;
27304 ++ do {
27305 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
27306 ++ if (obj != NULL)
27307 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27308 ++ } while ((subj = subj->parent_subject));
27309 ++
27310 ++ obj = chk_obj_label(dentry, mnt, task->acl);
27311 ++ if (obj->globbed == NULL)
27312 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27313 ++
27314 ++ is_not_root = ((obj->filename[0] == '/') &&
27315 ++ (obj->filename[1] == '\0')) ? 0 : 1;
27316 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
27317 ++
27318 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
27319 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
27320 ++ return 1;
27321 ++
27322 ++ preempt_disable();
27323 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
27324 ++ bufsize);
27325 ++
27326 ++ bufsize = strlen(path);
27327 ++
27328 ++ /* if base is "/", don't append an additional slash */
27329 ++ if (is_not_root)
27330 ++ *(path + bufsize) = '/';
27331 ++ memcpy(path + bufsize + is_not_root, name, namelen);
27332 ++ *(path + bufsize + namelen + is_not_root) = '\0';
27333 ++
27334 ++ tmp = obj->globbed;
27335 ++ while (tmp) {
27336 ++ if (!glob_match(tmp->filename, path)) {
27337 ++ preempt_enable();
27338 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
27339 ++ }
27340 ++ tmp = tmp->next;
27341 ++ }
27342 ++ preempt_enable();
27343 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27344 ++}
27345 ++
27346 ++EXPORT_SYMBOL(gr_learn_resource);
27347 ++EXPORT_SYMBOL(gr_set_kernel_label);
27348 ++#ifdef CONFIG_SECURITY
27349 ++EXPORT_SYMBOL(gr_check_user_change);
27350 ++EXPORT_SYMBOL(gr_check_group_change);
27351 ++#endif
27352 ++
27353 +diff -urNp a/grsecurity/gracl_alloc.c b/grsecurity/gracl_alloc.c
27354 +--- a/grsecurity/gracl_alloc.c 1969-12-31 16:00:00.000000000 -0800
27355 ++++ b/grsecurity/gracl_alloc.c 2008-08-20 18:36:57.000000000 -0700
27356 +@@ -0,0 +1,91 @@
27357 ++#include <linux/kernel.h>
27358 ++#include <linux/mm.h>
27359 ++#include <linux/slab.h>
27360 ++#include <linux/vmalloc.h>
27361 ++#include <linux/gracl.h>
27362 ++#include <linux/grsecurity.h>
27363 ++
27364 ++static unsigned long alloc_stack_next = 1;
27365 ++static unsigned long alloc_stack_size = 1;
27366 ++static void **alloc_stack;
27367 ++
27368 ++static __inline__ int
27369 ++alloc_pop(void)
27370 ++{
27371 ++ if (alloc_stack_next == 1)
27372 ++ return 0;
27373 ++
27374 ++ kfree(alloc_stack[alloc_stack_next - 2]);
27375 ++
27376 ++ alloc_stack_next--;
27377 ++
27378 ++ return 1;
27379 ++}
27380 ++
27381 ++static __inline__ void
27382 ++alloc_push(void *buf)
27383 ++{
27384 ++ if (alloc_stack_next >= alloc_stack_size)
27385 ++ BUG();
27386 ++
27387 ++ alloc_stack[alloc_stack_next - 1] = buf;
27388 ++
27389 ++ alloc_stack_next++;
27390 ++
27391 ++ return;
27392 ++}
27393 ++
27394 ++void *
27395 ++acl_alloc(unsigned long len)
27396 ++{
27397 ++ void *ret;
27398 ++
27399 ++ if (len > PAGE_SIZE)
27400 ++ BUG();
27401 ++
27402 ++ ret = kmalloc(len, GFP_KERNEL);
27403 ++
27404 ++ if (ret)
27405 ++ alloc_push(ret);
27406 ++
27407 ++ return ret;
27408 ++}
27409 ++
27410 ++void
27411 ++acl_free_all(void)
27412 ++{
27413 ++ if (gr_acl_is_enabled() || !alloc_stack)
27414 ++ return;
27415 ++
27416 ++ while (alloc_pop()) ;
27417 ++
27418 ++ if (alloc_stack) {
27419 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
27420 ++ kfree(alloc_stack);
27421 ++ else
27422 ++ vfree(alloc_stack);
27423 ++ }
27424 ++
27425 ++ alloc_stack = NULL;
27426 ++ alloc_stack_size = 1;
27427 ++ alloc_stack_next = 1;
27428 ++
27429 ++ return;
27430 ++}
27431 ++
27432 ++int
27433 ++acl_alloc_stack_init(unsigned long size)
27434 ++{
27435 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
27436 ++ alloc_stack =
27437 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
27438 ++ else
27439 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
27440 ++
27441 ++ alloc_stack_size = size;
27442 ++
27443 ++ if (!alloc_stack)
27444 ++ return 0;
27445 ++ else
27446 ++ return 1;
27447 ++}
27448 +diff -urNp a/grsecurity/gracl_cap.c b/grsecurity/gracl_cap.c
27449 +--- a/grsecurity/gracl_cap.c 1969-12-31 16:00:00.000000000 -0800
27450 ++++ b/grsecurity/gracl_cap.c 2008-08-20 18:36:57.000000000 -0700
27451 +@@ -0,0 +1,129 @@
27452 ++#include <linux/kernel.h>
27453 ++#include <linux/module.h>
27454 ++#include <linux/sched.h>
27455 ++#include <linux/gracl.h>
27456 ++#include <linux/grsecurity.h>
27457 ++#include <linux/grinternal.h>
27458 ++
27459 ++static const char *captab_log[] = {
27460 ++ "CAP_CHOWN",
27461 ++ "CAP_DAC_OVERRIDE",
27462 ++ "CAP_DAC_READ_SEARCH",
27463 ++ "CAP_FOWNER",
27464 ++ "CAP_FSETID",
27465 ++ "CAP_KILL",
27466 ++ "CAP_SETGID",
27467 ++ "CAP_SETUID",
27468 ++ "CAP_SETPCAP",
27469 ++ "CAP_LINUX_IMMUTABLE",
27470 ++ "CAP_NET_BIND_SERVICE",
27471 ++ "CAP_NET_BROADCAST",
27472 ++ "CAP_NET_ADMIN",
27473 ++ "CAP_NET_RAW",
27474 ++ "CAP_IPC_LOCK",
27475 ++ "CAP_IPC_OWNER",
27476 ++ "CAP_SYS_MODULE",
27477 ++ "CAP_SYS_RAWIO",
27478 ++ "CAP_SYS_CHROOT",
27479 ++ "CAP_SYS_PTRACE",
27480 ++ "CAP_SYS_PACCT",
27481 ++ "CAP_SYS_ADMIN",
27482 ++ "CAP_SYS_BOOT",
27483 ++ "CAP_SYS_NICE",
27484 ++ "CAP_SYS_RESOURCE",
27485 ++ "CAP_SYS_TIME",
27486 ++ "CAP_SYS_TTY_CONFIG",
27487 ++ "CAP_MKNOD",
27488 ++ "CAP_LEASE",
27489 ++ "CAP_AUDIT_WRITE",
27490 ++ "CAP_AUDIT_CONTROL",
27491 ++ "CAP_SETFCAP",
27492 ++ "CAP_MAC_OVERRIDE",
27493 ++ "CAP_MAC_ADMIN"
27494 ++};
27495 ++
27496 ++EXPORT_SYMBOL(gr_task_is_capable);
27497 ++EXPORT_SYMBOL(gr_is_capable_nolog);
27498 ++
27499 ++int
27500 ++gr_task_is_capable(struct task_struct *task, const int cap)
27501 ++{
27502 ++ struct acl_subject_label *curracl;
27503 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
27504 ++
27505 ++ if (!gr_acl_is_enabled())
27506 ++ return 1;
27507 ++
27508 ++ curracl = task->acl;
27509 ++
27510 ++ cap_drop = curracl->cap_lower;
27511 ++ cap_mask = curracl->cap_mask;
27512 ++
27513 ++ while ((curracl = curracl->parent_subject)) {
27514 ++ /* if the cap isn't specified in the current computed mask but is specified in the
27515 ++ current level subject, and is lowered in the current level subject, then add
27516 ++ it to the set of dropped capabilities
27517 ++ otherwise, add the current level subject's mask to the current computed mask
27518 ++ */
27519 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
27520 ++ cap_raise(cap_mask, cap);
27521 ++ if (cap_raised(curracl->cap_lower, cap))
27522 ++ cap_raise(cap_drop, cap);
27523 ++ }
27524 ++ }
27525 ++
27526 ++ if (!cap_raised(cap_drop, cap))
27527 ++ return 1;
27528 ++
27529 ++ curracl = task->acl;
27530 ++
27531 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
27532 ++ && cap_raised(task->cap_effective, cap)) {
27533 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
27534 ++ task->role->roletype, task->uid,
27535 ++ task->gid, task->exec_file ?
27536 ++ gr_to_filename(task->exec_file->f_path.dentry,
27537 ++ task->exec_file->f_path.mnt) : curracl->filename,
27538 ++ curracl->filename, 0UL,
27539 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
27540 ++ return 1;
27541 ++ }
27542 ++
27543 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
27544 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
27545 ++ return 0;
27546 ++}
27547 ++
27548 ++int
27549 ++gr_is_capable_nolog(const int cap)
27550 ++{
27551 ++ struct acl_subject_label *curracl;
27552 ++ kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
27553 ++
27554 ++ if (!gr_acl_is_enabled())
27555 ++ return 1;
27556 ++
27557 ++ curracl = current->acl;
27558 ++
27559 ++ cap_drop = curracl->cap_lower;
27560 ++ cap_mask = curracl->cap_mask;
27561 ++
27562 ++ while ((curracl = curracl->parent_subject)) {
27563 ++ /* if the cap isn't specified in the current computed mask but is specified in the
27564 ++ current level subject, and is lowered in the current level subject, then add
27565 ++ it to the set of dropped capabilities
27566 ++ otherwise, add the current level subject's mask to the current computed mask
27567 ++ */
27568 ++ if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
27569 ++ cap_raise(cap_mask, cap);
27570 ++ if (cap_raised(curracl->cap_lower, cap))
27571 ++ cap_raise(cap_drop, cap);
27572 ++ }
27573 ++ }
27574 ++
27575 ++ if (!cap_raised(cap_drop, cap))
27576 ++ return 1;
27577 ++
27578 ++ return 0;
27579 ++}
27580 ++
27581 +diff -urNp a/grsecurity/gracl_fs.c b/grsecurity/gracl_fs.c
27582 +--- a/grsecurity/gracl_fs.c 1969-12-31 16:00:00.000000000 -0800
27583 ++++ b/grsecurity/gracl_fs.c 2008-08-20 18:36:57.000000000 -0700
27584 +@@ -0,0 +1,423 @@
27585 ++#include <linux/kernel.h>
27586 ++#include <linux/sched.h>
27587 ++#include <linux/types.h>
27588 ++#include <linux/fs.h>
27589 ++#include <linux/file.h>
27590 ++#include <linux/stat.h>
27591 ++#include <linux/grsecurity.h>
27592 ++#include <linux/grinternal.h>
27593 ++#include <linux/gracl.h>
27594 ++
27595 ++__u32
27596 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
27597 ++ const struct vfsmount * mnt)
27598 ++{
27599 ++ __u32 mode;
27600 ++
27601 ++ if (unlikely(!dentry->d_inode))
27602 ++ return GR_FIND;
27603 ++
27604 ++ mode =
27605 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
27606 ++
27607 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
27608 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
27609 ++ return mode;
27610 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
27611 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
27612 ++ return 0;
27613 ++ } else if (unlikely(!(mode & GR_FIND)))
27614 ++ return 0;
27615 ++
27616 ++ return GR_FIND;
27617 ++}
27618 ++
27619 ++__u32
27620 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
27621 ++ const int fmode)
27622 ++{
27623 ++ __u32 reqmode = GR_FIND;
27624 ++ __u32 mode;
27625 ++
27626 ++ if (unlikely(!dentry->d_inode))
27627 ++ return reqmode;
27628 ++
27629 ++ if (unlikely(fmode & O_APPEND))
27630 ++ reqmode |= GR_APPEND;
27631 ++ else if (unlikely(fmode & FMODE_WRITE))
27632 ++ reqmode |= GR_WRITE;
27633 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
27634 ++ reqmode |= GR_READ;
27635 ++
27636 ++ mode =
27637 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
27638 ++ mnt);
27639 ++
27640 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27641 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
27642 ++ reqmode & GR_READ ? " reading" : "",
27643 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27644 ++ GR_APPEND ? " appending" : "");
27645 ++ return reqmode;
27646 ++ } else
27647 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27648 ++ {
27649 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
27650 ++ reqmode & GR_READ ? " reading" : "",
27651 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27652 ++ GR_APPEND ? " appending" : "");
27653 ++ return 0;
27654 ++ } else if (unlikely((mode & reqmode) != reqmode))
27655 ++ return 0;
27656 ++
27657 ++ return reqmode;
27658 ++}
27659 ++
27660 ++__u32
27661 ++gr_acl_handle_creat(const struct dentry * dentry,
27662 ++ const struct dentry * p_dentry,
27663 ++ const struct vfsmount * p_mnt, const int fmode,
27664 ++ const int imode)
27665 ++{
27666 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
27667 ++ __u32 mode;
27668 ++
27669 ++ if (unlikely(fmode & O_APPEND))
27670 ++ reqmode |= GR_APPEND;
27671 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
27672 ++ reqmode |= GR_READ;
27673 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
27674 ++ reqmode |= GR_SETID;
27675 ++
27676 ++ mode =
27677 ++ gr_check_create(dentry, p_dentry, p_mnt,
27678 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
27679 ++
27680 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27681 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
27682 ++ reqmode & GR_READ ? " reading" : "",
27683 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27684 ++ GR_APPEND ? " appending" : "");
27685 ++ return reqmode;
27686 ++ } else
27687 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27688 ++ {
27689 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
27690 ++ reqmode & GR_READ ? " reading" : "",
27691 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27692 ++ GR_APPEND ? " appending" : "");
27693 ++ return 0;
27694 ++ } else if (unlikely((mode & reqmode) != reqmode))
27695 ++ return 0;
27696 ++
27697 ++ return reqmode;
27698 ++}
27699 ++
27700 ++__u32
27701 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
27702 ++ const int fmode)
27703 ++{
27704 ++ __u32 mode, reqmode = GR_FIND;
27705 ++
27706 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
27707 ++ reqmode |= GR_EXEC;
27708 ++ if (fmode & S_IWOTH)
27709 ++ reqmode |= GR_WRITE;
27710 ++ if (fmode & S_IROTH)
27711 ++ reqmode |= GR_READ;
27712 ++
27713 ++ mode =
27714 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
27715 ++ mnt);
27716 ++
27717 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27718 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
27719 ++ reqmode & GR_READ ? " reading" : "",
27720 ++ reqmode & GR_WRITE ? " writing" : "",
27721 ++ reqmode & GR_EXEC ? " executing" : "");
27722 ++ return reqmode;
27723 ++ } else
27724 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27725 ++ {
27726 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
27727 ++ reqmode & GR_READ ? " reading" : "",
27728 ++ reqmode & GR_WRITE ? " writing" : "",
27729 ++ reqmode & GR_EXEC ? " executing" : "");
27730 ++ return 0;
27731 ++ } else if (unlikely((mode & reqmode) != reqmode))
27732 ++ return 0;
27733 ++
27734 ++ return reqmode;
27735 ++}
27736 ++
27737 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
27738 ++{
27739 ++ __u32 mode;
27740 ++
27741 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
27742 ++
27743 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
27744 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
27745 ++ return mode;
27746 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
27747 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
27748 ++ return 0;
27749 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
27750 ++ return 0;
27751 ++
27752 ++ return (reqmode);
27753 ++}
27754 ++
27755 ++__u32
27756 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
27757 ++{
27758 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
27759 ++}
27760 ++
27761 ++__u32
27762 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
27763 ++{
27764 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
27765 ++}
27766 ++
27767 ++__u32
27768 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
27769 ++{
27770 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
27771 ++}
27772 ++
27773 ++__u32
27774 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
27775 ++{
27776 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
27777 ++}
27778 ++
27779 ++__u32
27780 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
27781 ++ mode_t mode)
27782 ++{
27783 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
27784 ++ return 1;
27785 ++
27786 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
27787 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
27788 ++ GR_FCHMOD_ACL_MSG);
27789 ++ } else {
27790 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
27791 ++ }
27792 ++}
27793 ++
27794 ++__u32
27795 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
27796 ++ mode_t mode)
27797 ++{
27798 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
27799 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
27800 ++ GR_CHMOD_ACL_MSG);
27801 ++ } else {
27802 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
27803 ++ }
27804 ++}
27805 ++
27806 ++__u32
27807 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
27808 ++{
27809 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
27810 ++}
27811 ++
27812 ++__u32
27813 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
27814 ++{
27815 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
27816 ++}
27817 ++
27818 ++__u32
27819 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
27820 ++{
27821 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
27822 ++ GR_UNIXCONNECT_ACL_MSG);
27823 ++}
27824 ++
27825 ++/* hardlinks require at minimum create permission,
27826 ++ any additional privilege required is based on the
27827 ++ privilege of the file being linked to
27828 ++*/
27829 ++__u32
27830 ++gr_acl_handle_link(const struct dentry * new_dentry,
27831 ++ const struct dentry * parent_dentry,
27832 ++ const struct vfsmount * parent_mnt,
27833 ++ const struct dentry * old_dentry,
27834 ++ const struct vfsmount * old_mnt, const char *to)
27835 ++{
27836 ++ __u32 mode;
27837 ++ __u32 needmode = GR_CREATE | GR_LINK;
27838 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
27839 ++
27840 ++ mode =
27841 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
27842 ++ old_mnt);
27843 ++
27844 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
27845 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
27846 ++ return mode;
27847 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
27848 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
27849 ++ return 0;
27850 ++ } else if (unlikely((mode & needmode) != needmode))
27851 ++ return 0;
27852 ++
27853 ++ return 1;
27854 ++}
27855 ++
27856 ++__u32
27857 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
27858 ++ const struct dentry * parent_dentry,
27859 ++ const struct vfsmount * parent_mnt, const char *from)
27860 ++{
27861 ++ __u32 needmode = GR_WRITE | GR_CREATE;
27862 ++ __u32 mode;
27863 ++
27864 ++ mode =
27865 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
27866 ++ GR_CREATE | GR_AUDIT_CREATE |
27867 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
27868 ++
27869 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
27870 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
27871 ++ return mode;
27872 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
27873 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
27874 ++ return 0;
27875 ++ } else if (unlikely((mode & needmode) != needmode))
27876 ++ return 0;
27877 ++
27878 ++ return (GR_WRITE | GR_CREATE);
27879 ++}
27880 ++
27881 ++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)
27882 ++{
27883 ++ __u32 mode;
27884 ++
27885 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
27886 ++
27887 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
27888 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
27889 ++ return mode;
27890 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
27891 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
27892 ++ return 0;
27893 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
27894 ++ return 0;
27895 ++
27896 ++ return (reqmode);
27897 ++}
27898 ++
27899 ++__u32
27900 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
27901 ++ const struct dentry * parent_dentry,
27902 ++ const struct vfsmount * parent_mnt,
27903 ++ const int mode)
27904 ++{
27905 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
27906 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
27907 ++ reqmode |= GR_SETID;
27908 ++
27909 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
27910 ++ reqmode, GR_MKNOD_ACL_MSG);
27911 ++}
27912 ++
27913 ++__u32
27914 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
27915 ++ const struct dentry *parent_dentry,
27916 ++ const struct vfsmount *parent_mnt)
27917 ++{
27918 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
27919 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
27920 ++}
27921 ++
27922 ++#define RENAME_CHECK_SUCCESS(old, new) \
27923 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
27924 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
27925 ++
27926 ++int
27927 ++gr_acl_handle_rename(struct dentry *new_dentry,
27928 ++ struct dentry *parent_dentry,
27929 ++ const struct vfsmount *parent_mnt,
27930 ++ struct dentry *old_dentry,
27931 ++ struct inode *old_parent_inode,
27932 ++ struct vfsmount *old_mnt, const char *newname)
27933 ++{
27934 ++ __u32 comp1, comp2;
27935 ++ int error = 0;
27936 ++
27937 ++ if (unlikely(!gr_acl_is_enabled()))
27938 ++ return 0;
27939 ++
27940 ++ if (!new_dentry->d_inode) {
27941 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
27942 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
27943 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
27944 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
27945 ++ GR_DELETE | GR_AUDIT_DELETE |
27946 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
27947 ++ GR_SUPPRESS, old_mnt);
27948 ++ } else {
27949 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
27950 ++ GR_CREATE | GR_DELETE |
27951 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
27952 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
27953 ++ GR_SUPPRESS, parent_mnt);
27954 ++ comp2 =
27955 ++ gr_search_file(old_dentry,
27956 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
27957 ++ GR_DELETE | GR_AUDIT_DELETE |
27958 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
27959 ++ }
27960 ++
27961 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
27962 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
27963 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
27964 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
27965 ++ && !(comp2 & GR_SUPPRESS)) {
27966 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
27967 ++ error = -EACCES;
27968 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
27969 ++ error = -EACCES;
27970 ++
27971 ++ return error;
27972 ++}
27973 ++
27974 ++void
27975 ++gr_acl_handle_exit(void)
27976 ++{
27977 ++ u16 id;
27978 ++ char *rolename;
27979 ++ struct file *exec_file;
27980 ++
27981 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
27982 ++ id = current->acl_role_id;
27983 ++ rolename = current->role->rolename;
27984 ++ gr_set_acls(1);
27985 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
27986 ++ }
27987 ++
27988 ++ write_lock(&grsec_exec_file_lock);
27989 ++ exec_file = current->exec_file;
27990 ++ current->exec_file = NULL;
27991 ++ write_unlock(&grsec_exec_file_lock);
27992 ++
27993 ++ if (exec_file)
27994 ++ fput(exec_file);
27995 ++}
27996 ++
27997 ++int
27998 ++gr_acl_handle_procpidmem(const struct task_struct *task)
27999 ++{
28000 ++ if (unlikely(!gr_acl_is_enabled()))
28001 ++ return 0;
28002 ++
28003 ++ if (task != current && task->acl->mode & GR_PROTPROCFD)
28004 ++ return -EACCES;
28005 ++
28006 ++ return 0;
28007 ++}
28008 +diff -urNp a/grsecurity/gracl_ip.c b/grsecurity/gracl_ip.c
28009 +--- a/grsecurity/gracl_ip.c 1969-12-31 16:00:00.000000000 -0800
28010 ++++ b/grsecurity/gracl_ip.c 2008-08-20 18:36:57.000000000 -0700
28011 +@@ -0,0 +1,313 @@
28012 ++#include <linux/kernel.h>
28013 ++#include <asm/uaccess.h>
28014 ++#include <asm/errno.h>
28015 ++#include <net/sock.h>
28016 ++#include <linux/file.h>
28017 ++#include <linux/fs.h>
28018 ++#include <linux/net.h>
28019 ++#include <linux/in.h>
28020 ++#include <linux/skbuff.h>
28021 ++#include <linux/ip.h>
28022 ++#include <linux/udp.h>
28023 ++#include <linux/smp_lock.h>
28024 ++#include <linux/types.h>
28025 ++#include <linux/sched.h>
28026 ++#include <linux/netdevice.h>
28027 ++#include <linux/inetdevice.h>
28028 ++#include <linux/gracl.h>
28029 ++#include <linux/grsecurity.h>
28030 ++#include <linux/grinternal.h>
28031 ++
28032 ++#define GR_BIND 0x01
28033 ++#define GR_CONNECT 0x02
28034 ++#define GR_INVERT 0x04
28035 ++
28036 ++static const char * gr_protocols[256] = {
28037 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
28038 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
28039 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
28040 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
28041 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
28042 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
28043 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
28044 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
28045 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
28046 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
28047 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
28048 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
28049 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
28050 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
28051 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
28052 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
28053 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
28054 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
28055 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
28056 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
28057 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
28058 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
28059 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
28060 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
28061 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
28062 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
28063 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
28064 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
28065 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
28066 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
28067 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
28068 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
28069 ++ };
28070 ++
28071 ++static const char * gr_socktypes[11] = {
28072 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
28073 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
28074 ++ };
28075 ++
28076 ++const char *
28077 ++gr_proto_to_name(unsigned char proto)
28078 ++{
28079 ++ return gr_protocols[proto];
28080 ++}
28081 ++
28082 ++const char *
28083 ++gr_socktype_to_name(unsigned char type)
28084 ++{
28085 ++ return gr_socktypes[type];
28086 ++}
28087 ++
28088 ++int
28089 ++gr_search_socket(const int domain, const int type, const int protocol)
28090 ++{
28091 ++ struct acl_subject_label *curr;
28092 ++
28093 ++ if (unlikely(!gr_acl_is_enabled()))
28094 ++ goto exit;
28095 ++
28096 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
28097 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
28098 ++ goto exit; // let the kernel handle it
28099 ++
28100 ++ curr = current->acl;
28101 ++
28102 ++ if (!curr->ips)
28103 ++ goto exit;
28104 ++
28105 ++ if ((curr->ip_type & (1 << type)) &&
28106 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
28107 ++ goto exit;
28108 ++
28109 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
28110 ++ /* we don't place acls on raw sockets , and sometimes
28111 ++ dgram/ip sockets are opened for ioctl and not
28112 ++ bind/connect, so we'll fake a bind learn log */
28113 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
28114 ++ __u32 fakeip = 0;
28115 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28116 ++ current->role->roletype, current->uid,
28117 ++ current->gid, current->exec_file ?
28118 ++ gr_to_filename(current->exec_file->f_path.dentry,
28119 ++ current->exec_file->f_path.mnt) :
28120 ++ curr->filename, curr->filename,
28121 ++ NIPQUAD(fakeip), 0, type,
28122 ++ protocol, GR_CONNECT,
28123 ++NIPQUAD(current->signal->curr_ip));
28124 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
28125 ++ __u32 fakeip = 0;
28126 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28127 ++ current->role->roletype, current->uid,
28128 ++ current->gid, current->exec_file ?
28129 ++ gr_to_filename(current->exec_file->f_path.dentry,
28130 ++ current->exec_file->f_path.mnt) :
28131 ++ curr->filename, curr->filename,
28132 ++ NIPQUAD(fakeip), 0, type,
28133 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
28134 ++ }
28135 ++ /* we'll log when they use connect or bind */
28136 ++ goto exit;
28137 ++ }
28138 ++
28139 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
28140 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
28141 ++
28142 ++ return 0;
28143 ++ exit:
28144 ++ return 1;
28145 ++}
28146 ++
28147 ++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)
28148 ++{
28149 ++ if ((ip->mode & mode) &&
28150 ++ (ip_port >= ip->low) &&
28151 ++ (ip_port <= ip->high) &&
28152 ++ ((ntohl(ip_addr) & our_netmask) ==
28153 ++ (ntohl(our_addr) & our_netmask))
28154 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
28155 ++ && (ip->type & (1 << type))) {
28156 ++ if (ip->mode & GR_INVERT)
28157 ++ return 2; // specifically denied
28158 ++ else
28159 ++ return 1; // allowed
28160 ++ }
28161 ++
28162 ++ return 0; // not specifically allowed, may continue parsing
28163 ++}
28164 ++
28165 ++static int
28166 ++gr_search_connectbind(const int mode, const struct sock *sk,
28167 ++ const struct sockaddr_in *addr, const int type)
28168 ++{
28169 ++ char iface[IFNAMSIZ] = {0};
28170 ++ struct acl_subject_label *curr;
28171 ++ struct acl_ip_label *ip;
28172 ++ struct net_device *dev;
28173 ++ struct in_device *idev;
28174 ++ unsigned long i;
28175 ++ int ret;
28176 ++ __u32 ip_addr = 0;
28177 ++ __u32 our_addr;
28178 ++ __u32 our_netmask;
28179 ++ char *p;
28180 ++ __u16 ip_port = 0;
28181 ++
28182 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
28183 ++ return 1;
28184 ++
28185 ++ curr = current->acl;
28186 ++
28187 ++ if (!curr->ips)
28188 ++ return 1;
28189 ++
28190 ++ ip_addr = addr->sin_addr.s_addr;
28191 ++ ip_port = ntohs(addr->sin_port);
28192 ++
28193 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
28194 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28195 ++ current->role->roletype, current->uid,
28196 ++ current->gid, current->exec_file ?
28197 ++ gr_to_filename(current->exec_file->f_path.dentry,
28198 ++ current->exec_file->f_path.mnt) :
28199 ++ curr->filename, curr->filename,
28200 ++ NIPQUAD(ip_addr), ip_port, type,
28201 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
28202 ++ return 1;
28203 ++ }
28204 ++
28205 ++ for (i = 0; i < curr->ip_num; i++) {
28206 ++ ip = *(curr->ips + i);
28207 ++ if (ip->iface != NULL) {
28208 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
28209 ++ p = strchr(iface, ':');
28210 ++ if (p != NULL)
28211 ++ *p = '\0';
28212 ++ dev = dev_get_by_name(sk->sk_net, iface);
28213 ++ if (dev == NULL)
28214 ++ continue;
28215 ++ idev = in_dev_get(dev);
28216 ++ if (idev == NULL) {
28217 ++ dev_put(dev);
28218 ++ continue;
28219 ++ }
28220 ++ rcu_read_lock();
28221 ++ for_ifa(idev) {
28222 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
28223 ++ our_addr = ifa->ifa_address;
28224 ++ our_netmask = 0xffffffff;
28225 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
28226 ++ if (ret == 1) {
28227 ++ rcu_read_unlock();
28228 ++ in_dev_put(idev);
28229 ++ dev_put(dev);
28230 ++ return 1;
28231 ++ } else if (ret == 2) {
28232 ++ rcu_read_unlock();
28233 ++ in_dev_put(idev);
28234 ++ dev_put(dev);
28235 ++ goto denied;
28236 ++ }
28237 ++ }
28238 ++ } endfor_ifa(idev);
28239 ++ rcu_read_unlock();
28240 ++ in_dev_put(idev);
28241 ++ dev_put(dev);
28242 ++ } else {
28243 ++ our_addr = ip->addr;
28244 ++ our_netmask = ip->netmask;
28245 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
28246 ++ if (ret == 1)
28247 ++ return 1;
28248 ++ else if (ret == 2)
28249 ++ goto denied;
28250 ++ }
28251 ++ }
28252 ++
28253 ++denied:
28254 ++ if (mode == GR_BIND)
28255 ++ 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));
28256 ++ else if (mode == GR_CONNECT)
28257 ++ 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));
28258 ++
28259 ++ return 0;
28260 ++}
28261 ++
28262 ++int
28263 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
28264 ++{
28265 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
28266 ++}
28267 ++
28268 ++int
28269 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
28270 ++{
28271 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
28272 ++}
28273 ++
28274 ++int gr_search_listen(const struct socket *sock)
28275 ++{
28276 ++ struct sock *sk = sock->sk;
28277 ++ struct sockaddr_in addr;
28278 ++
28279 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
28280 ++ addr.sin_port = inet_sk(sk)->sport;
28281 ++
28282 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
28283 ++}
28284 ++
28285 ++int gr_search_accept(const struct socket *sock)
28286 ++{
28287 ++ struct sock *sk = sock->sk;
28288 ++ struct sockaddr_in addr;
28289 ++
28290 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
28291 ++ addr.sin_port = inet_sk(sk)->sport;
28292 ++
28293 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
28294 ++}
28295 ++
28296 ++int
28297 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
28298 ++{
28299 ++ if (addr)
28300 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
28301 ++ else {
28302 ++ struct sockaddr_in sin;
28303 ++ const struct inet_sock *inet = inet_sk(sk);
28304 ++
28305 ++ sin.sin_addr.s_addr = inet->daddr;
28306 ++ sin.sin_port = inet->dport;
28307 ++
28308 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
28309 ++ }
28310 ++}
28311 ++
28312 ++int
28313 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
28314 ++{
28315 ++ struct sockaddr_in sin;
28316 ++
28317 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
28318 ++ return 1; // skip this packet
28319 ++
28320 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
28321 ++ sin.sin_port = udp_hdr(skb)->source;
28322 ++
28323 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
28324 ++}
28325 +diff -urNp a/grsecurity/gracl_learn.c b/grsecurity/gracl_learn.c
28326 +--- a/grsecurity/gracl_learn.c 1969-12-31 16:00:00.000000000 -0800
28327 ++++ b/grsecurity/gracl_learn.c 2008-08-20 18:36:57.000000000 -0700
28328 +@@ -0,0 +1,211 @@
28329 ++#include <linux/kernel.h>
28330 ++#include <linux/mm.h>
28331 ++#include <linux/sched.h>
28332 ++#include <linux/poll.h>
28333 ++#include <linux/smp_lock.h>
28334 ++#include <linux/string.h>
28335 ++#include <linux/file.h>
28336 ++#include <linux/types.h>
28337 ++#include <linux/vmalloc.h>
28338 ++#include <linux/grinternal.h>
28339 ++
28340 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
28341 ++ size_t count, loff_t *ppos);
28342 ++extern int gr_acl_is_enabled(void);
28343 ++
28344 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
28345 ++static int gr_learn_attached;
28346 ++
28347 ++/* use a 512k buffer */
28348 ++#define LEARN_BUFFER_SIZE (512 * 1024)
28349 ++
28350 ++static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
28351 ++static DECLARE_MUTEX(gr_learn_user_sem);
28352 ++
28353 ++/* we need to maintain two buffers, so that the kernel context of grlearn
28354 ++ uses a semaphore around the userspace copying, and the other kernel contexts
28355 ++ use a spinlock when copying into the buffer, since they cannot sleep
28356 ++*/
28357 ++static char *learn_buffer;
28358 ++static char *learn_buffer_user;
28359 ++static int learn_buffer_len;
28360 ++static int learn_buffer_user_len;
28361 ++
28362 ++static ssize_t
28363 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
28364 ++{
28365 ++ DECLARE_WAITQUEUE(wait, current);
28366 ++ ssize_t retval = 0;
28367 ++
28368 ++ add_wait_queue(&learn_wait, &wait);
28369 ++ set_current_state(TASK_INTERRUPTIBLE);
28370 ++ do {
28371 ++ down(&gr_learn_user_sem);
28372 ++ spin_lock(&gr_learn_lock);
28373 ++ if (learn_buffer_len)
28374 ++ break;
28375 ++ spin_unlock(&gr_learn_lock);
28376 ++ up(&gr_learn_user_sem);
28377 ++ if (file->f_flags & O_NONBLOCK) {
28378 ++ retval = -EAGAIN;
28379 ++ goto out;
28380 ++ }
28381 ++ if (signal_pending(current)) {
28382 ++ retval = -ERESTARTSYS;
28383 ++ goto out;
28384 ++ }
28385 ++
28386 ++ schedule();
28387 ++ } while (1);
28388 ++
28389 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
28390 ++ learn_buffer_user_len = learn_buffer_len;
28391 ++ retval = learn_buffer_len;
28392 ++ learn_buffer_len = 0;
28393 ++
28394 ++ spin_unlock(&gr_learn_lock);
28395 ++
28396 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
28397 ++ retval = -EFAULT;
28398 ++
28399 ++ up(&gr_learn_user_sem);
28400 ++out:
28401 ++ set_current_state(TASK_RUNNING);
28402 ++ remove_wait_queue(&learn_wait, &wait);
28403 ++ return retval;
28404 ++}
28405 ++
28406 ++static unsigned int
28407 ++poll_learn(struct file * file, poll_table * wait)
28408 ++{
28409 ++ poll_wait(file, &learn_wait, wait);
28410 ++
28411 ++ if (learn_buffer_len)
28412 ++ return (POLLIN | POLLRDNORM);
28413 ++
28414 ++ return 0;
28415 ++}
28416 ++
28417 ++void
28418 ++gr_clear_learn_entries(void)
28419 ++{
28420 ++ char *tmp;
28421 ++
28422 ++ down(&gr_learn_user_sem);
28423 ++ if (learn_buffer != NULL) {
28424 ++ spin_lock(&gr_learn_lock);
28425 ++ tmp = learn_buffer;
28426 ++ learn_buffer = NULL;
28427 ++ spin_unlock(&gr_learn_lock);
28428 ++ vfree(learn_buffer);
28429 ++ }
28430 ++ if (learn_buffer_user != NULL) {
28431 ++ vfree(learn_buffer_user);
28432 ++ learn_buffer_user = NULL;
28433 ++ }
28434 ++ learn_buffer_len = 0;
28435 ++ up(&gr_learn_user_sem);
28436 ++
28437 ++ return;
28438 ++}
28439 ++
28440 ++void
28441 ++gr_add_learn_entry(const char *fmt, ...)
28442 ++{
28443 ++ va_list args;
28444 ++ unsigned int len;
28445 ++
28446 ++ if (!gr_learn_attached)
28447 ++ return;
28448 ++
28449 ++ spin_lock(&gr_learn_lock);
28450 ++
28451 ++ /* leave a gap at the end so we know when it's "full" but don't have to
28452 ++ compute the exact length of the string we're trying to append
28453 ++ */
28454 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
28455 ++ spin_unlock(&gr_learn_lock);
28456 ++ wake_up_interruptible(&learn_wait);
28457 ++ return;
28458 ++ }
28459 ++ if (learn_buffer == NULL) {
28460 ++ spin_unlock(&gr_learn_lock);
28461 ++ return;
28462 ++ }
28463 ++
28464 ++ va_start(args, fmt);
28465 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
28466 ++ va_end(args);
28467 ++
28468 ++ learn_buffer_len += len + 1;
28469 ++
28470 ++ spin_unlock(&gr_learn_lock);
28471 ++ wake_up_interruptible(&learn_wait);
28472 ++
28473 ++ return;
28474 ++}
28475 ++
28476 ++static int
28477 ++open_learn(struct inode *inode, struct file *file)
28478 ++{
28479 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
28480 ++ return -EBUSY;
28481 ++ if (file->f_mode & FMODE_READ) {
28482 ++ int retval = 0;
28483 ++ down(&gr_learn_user_sem);
28484 ++ if (learn_buffer == NULL)
28485 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
28486 ++ if (learn_buffer_user == NULL)
28487 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
28488 ++ if (learn_buffer == NULL) {
28489 ++ retval = -ENOMEM;
28490 ++ goto out_error;
28491 ++ }
28492 ++ if (learn_buffer_user == NULL) {
28493 ++ retval = -ENOMEM;
28494 ++ goto out_error;
28495 ++ }
28496 ++ learn_buffer_len = 0;
28497 ++ learn_buffer_user_len = 0;
28498 ++ gr_learn_attached = 1;
28499 ++out_error:
28500 ++ up(&gr_learn_user_sem);
28501 ++ return retval;
28502 ++ }
28503 ++ return 0;
28504 ++}
28505 ++
28506 ++static int
28507 ++close_learn(struct inode *inode, struct file *file)
28508 ++{
28509 ++ char *tmp;
28510 ++
28511 ++ if (file->f_mode & FMODE_READ) {
28512 ++ down(&gr_learn_user_sem);
28513 ++ if (learn_buffer != NULL) {
28514 ++ spin_lock(&gr_learn_lock);
28515 ++ tmp = learn_buffer;
28516 ++ learn_buffer = NULL;
28517 ++ spin_unlock(&gr_learn_lock);
28518 ++ vfree(tmp);
28519 ++ }
28520 ++ if (learn_buffer_user != NULL) {
28521 ++ vfree(learn_buffer_user);
28522 ++ learn_buffer_user = NULL;
28523 ++ }
28524 ++ learn_buffer_len = 0;
28525 ++ learn_buffer_user_len = 0;
28526 ++ gr_learn_attached = 0;
28527 ++ up(&gr_learn_user_sem);
28528 ++ }
28529 ++
28530 ++ return 0;
28531 ++}
28532 ++
28533 ++struct file_operations grsec_fops = {
28534 ++ .read = read_learn,
28535 ++ .write = write_grsec_handler,
28536 ++ .open = open_learn,
28537 ++ .release = close_learn,
28538 ++ .poll = poll_learn,
28539 ++};
28540 +diff -urNp a/grsecurity/gracl_res.c b/grsecurity/gracl_res.c
28541 +--- a/grsecurity/gracl_res.c 1969-12-31 16:00:00.000000000 -0800
28542 ++++ b/grsecurity/gracl_res.c 2008-08-20 18:36:57.000000000 -0700
28543 +@@ -0,0 +1,45 @@
28544 ++#include <linux/kernel.h>
28545 ++#include <linux/sched.h>
28546 ++#include <linux/gracl.h>
28547 ++#include <linux/grinternal.h>
28548 ++
28549 ++static const char *restab_log[] = {
28550 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
28551 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
28552 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
28553 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
28554 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
28555 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
28556 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
28557 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
28558 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
28559 ++ [RLIMIT_AS] = "RLIMIT_AS",
28560 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
28561 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
28562 ++};
28563 ++
28564 ++void
28565 ++gr_log_resource(const struct task_struct *task,
28566 ++ const int res, const unsigned long wanted, const int gt)
28567 ++{
28568 ++ if (res == RLIMIT_NPROC &&
28569 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
28570 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
28571 ++ return;
28572 ++ else if (res == RLIMIT_MEMLOCK &&
28573 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
28574 ++ return;
28575 ++
28576 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
28577 ++ return;
28578 ++
28579 ++ preempt_disable();
28580 ++
28581 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
28582 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
28583 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
28584 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
28585 ++ preempt_enable_no_resched();
28586 ++
28587 ++ return;
28588 ++}
28589 +diff -urNp a/grsecurity/gracl_segv.c b/grsecurity/gracl_segv.c
28590 +--- a/grsecurity/gracl_segv.c 1969-12-31 16:00:00.000000000 -0800
28591 ++++ b/grsecurity/gracl_segv.c 2008-08-20 18:36:57.000000000 -0700
28592 +@@ -0,0 +1,301 @@
28593 ++#include <linux/kernel.h>
28594 ++#include <linux/mm.h>
28595 ++#include <asm/uaccess.h>
28596 ++#include <asm/errno.h>
28597 ++#include <asm/mman.h>
28598 ++#include <net/sock.h>
28599 ++#include <linux/file.h>
28600 ++#include <linux/fs.h>
28601 ++#include <linux/net.h>
28602 ++#include <linux/in.h>
28603 ++#include <linux/smp_lock.h>
28604 ++#include <linux/slab.h>
28605 ++#include <linux/types.h>
28606 ++#include <linux/sched.h>
28607 ++#include <linux/timer.h>
28608 ++#include <linux/gracl.h>
28609 ++#include <linux/grsecurity.h>
28610 ++#include <linux/grinternal.h>
28611 ++
28612 ++static struct crash_uid *uid_set;
28613 ++static unsigned short uid_used;
28614 ++static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
28615 ++extern rwlock_t gr_inode_lock;
28616 ++extern struct acl_subject_label *
28617 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
28618 ++ struct acl_role_label *role);
28619 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
28620 ++
28621 ++int
28622 ++gr_init_uidset(void)
28623 ++{
28624 ++ uid_set =
28625 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
28626 ++ uid_used = 0;
28627 ++
28628 ++ return uid_set ? 1 : 0;
28629 ++}
28630 ++
28631 ++void
28632 ++gr_free_uidset(void)
28633 ++{
28634 ++ if (uid_set)
28635 ++ kfree(uid_set);
28636 ++
28637 ++ return;
28638 ++}
28639 ++
28640 ++int
28641 ++gr_find_uid(const uid_t uid)
28642 ++{
28643 ++ struct crash_uid *tmp = uid_set;
28644 ++ uid_t buid;
28645 ++ int low = 0, high = uid_used - 1, mid;
28646 ++
28647 ++ while (high >= low) {
28648 ++ mid = (low + high) >> 1;
28649 ++ buid = tmp[mid].uid;
28650 ++ if (buid == uid)
28651 ++ return mid;
28652 ++ if (buid > uid)
28653 ++ high = mid - 1;
28654 ++ if (buid < uid)
28655 ++ low = mid + 1;
28656 ++ }
28657 ++
28658 ++ return -1;
28659 ++}
28660 ++
28661 ++static __inline__ void
28662 ++gr_insertsort(void)
28663 ++{
28664 ++ unsigned short i, j;
28665 ++ struct crash_uid index;
28666 ++
28667 ++ for (i = 1; i < uid_used; i++) {
28668 ++ index = uid_set[i];
28669 ++ j = i;
28670 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
28671 ++ uid_set[j] = uid_set[j - 1];
28672 ++ j--;
28673 ++ }
28674 ++ uid_set[j] = index;
28675 ++ }
28676 ++
28677 ++ return;
28678 ++}
28679 ++
28680 ++static __inline__ void
28681 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
28682 ++{
28683 ++ int loc;
28684 ++
28685 ++ if (uid_used == GR_UIDTABLE_MAX)
28686 ++ return;
28687 ++
28688 ++ loc = gr_find_uid(uid);
28689 ++
28690 ++ if (loc >= 0) {
28691 ++ uid_set[loc].expires = expires;
28692 ++ return;
28693 ++ }
28694 ++
28695 ++ uid_set[uid_used].uid = uid;
28696 ++ uid_set[uid_used].expires = expires;
28697 ++ uid_used++;
28698 ++
28699 ++ gr_insertsort();
28700 ++
28701 ++ return;
28702 ++}
28703 ++
28704 ++void
28705 ++gr_remove_uid(const unsigned short loc)
28706 ++{
28707 ++ unsigned short i;
28708 ++
28709 ++ for (i = loc + 1; i < uid_used; i++)
28710 ++ uid_set[i - 1] = uid_set[i];
28711 ++
28712 ++ uid_used--;
28713 ++
28714 ++ return;
28715 ++}
28716 ++
28717 ++int
28718 ++gr_check_crash_uid(const uid_t uid)
28719 ++{
28720 ++ int loc;
28721 ++ int ret = 0;
28722 ++
28723 ++ if (unlikely(!gr_acl_is_enabled()))
28724 ++ return 0;
28725 ++
28726 ++ spin_lock(&gr_uid_lock);
28727 ++ loc = gr_find_uid(uid);
28728 ++
28729 ++ if (loc < 0)
28730 ++ goto out_unlock;
28731 ++
28732 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
28733 ++ gr_remove_uid(loc);
28734 ++ else
28735 ++ ret = 1;
28736 ++
28737 ++out_unlock:
28738 ++ spin_unlock(&gr_uid_lock);
28739 ++ return ret;
28740 ++}
28741 ++
28742 ++static __inline__ int
28743 ++proc_is_setxid(const struct task_struct *task)
28744 ++{
28745 ++ if (task->uid != task->euid || task->uid != task->suid ||
28746 ++ task->uid != task->fsuid)
28747 ++ return 1;
28748 ++ if (task->gid != task->egid || task->gid != task->sgid ||
28749 ++ task->gid != task->fsgid)
28750 ++ return 1;
28751 ++
28752 ++ return 0;
28753 ++}
28754 ++static __inline__ int
28755 ++gr_fake_force_sig(int sig, struct task_struct *t)
28756 ++{
28757 ++ unsigned long int flags;
28758 ++ int ret, blocked, ignored;
28759 ++ struct k_sigaction *action;
28760 ++
28761 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
28762 ++ action = &t->sighand->action[sig-1];
28763 ++ ignored = action->sa.sa_handler == SIG_IGN;
28764 ++ blocked = sigismember(&t->blocked, sig);
28765 ++ if (blocked || ignored) {
28766 ++ action->sa.sa_handler = SIG_DFL;
28767 ++ if (blocked) {
28768 ++ sigdelset(&t->blocked, sig);
28769 ++ recalc_sigpending_and_wake(t);
28770 ++ }
28771 ++ }
28772 ++ ret = specific_send_sig_info(sig, (void*)1L, t);
28773 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
28774 ++
28775 ++ return ret;
28776 ++}
28777 ++
28778 ++void
28779 ++gr_handle_crash(struct task_struct *task, const int sig)
28780 ++{
28781 ++ struct acl_subject_label *curr;
28782 ++ struct acl_subject_label *curr2;
28783 ++ struct task_struct *tsk, *tsk2;
28784 ++
28785 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
28786 ++ return;
28787 ++
28788 ++ if (unlikely(!gr_acl_is_enabled()))
28789 ++ return;
28790 ++
28791 ++ curr = task->acl;
28792 ++
28793 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
28794 ++ return;
28795 ++
28796 ++ if (time_before_eq(curr->expires, get_seconds())) {
28797 ++ curr->expires = 0;
28798 ++ curr->crashes = 0;
28799 ++ }
28800 ++
28801 ++ curr->crashes++;
28802 ++
28803 ++ if (!curr->expires)
28804 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
28805 ++
28806 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
28807 ++ time_after(curr->expires, get_seconds())) {
28808 ++ if (task->uid && proc_is_setxid(task)) {
28809 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
28810 ++ spin_lock(&gr_uid_lock);
28811 ++ gr_insert_uid(task->uid, curr->expires);
28812 ++ spin_unlock(&gr_uid_lock);
28813 ++ curr->expires = 0;
28814 ++ curr->crashes = 0;
28815 ++ read_lock(&tasklist_lock);
28816 ++ do_each_thread(tsk2, tsk) {
28817 ++ if (tsk != task && tsk->uid == task->uid)
28818 ++ gr_fake_force_sig(SIGKILL, tsk);
28819 ++ } while_each_thread(tsk2, tsk);
28820 ++ read_unlock(&tasklist_lock);
28821 ++ } else {
28822 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
28823 ++ read_lock(&tasklist_lock);
28824 ++ do_each_thread(tsk2, tsk) {
28825 ++ if (likely(tsk != task)) {
28826 ++ curr2 = tsk->acl;
28827 ++
28828 ++ if (curr2->device == curr->device &&
28829 ++ curr2->inode == curr->inode)
28830 ++ gr_fake_force_sig(SIGKILL, tsk);
28831 ++ }
28832 ++ } while_each_thread(tsk2, tsk);
28833 ++ read_unlock(&tasklist_lock);
28834 ++ }
28835 ++ }
28836 ++
28837 ++ return;
28838 ++}
28839 ++
28840 ++int
28841 ++gr_check_crash_exec(const struct file *filp)
28842 ++{
28843 ++ struct acl_subject_label *curr;
28844 ++
28845 ++ if (unlikely(!gr_acl_is_enabled()))
28846 ++ return 0;
28847 ++
28848 ++ read_lock(&gr_inode_lock);
28849 ++ curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
28850 ++ filp->f_path.dentry->d_inode->i_sb->s_dev,
28851 ++ current->role);
28852 ++ read_unlock(&gr_inode_lock);
28853 ++
28854 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
28855 ++ (!curr->crashes && !curr->expires))
28856 ++ return 0;
28857 ++
28858 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
28859 ++ time_after(curr->expires, get_seconds()))
28860 ++ return 1;
28861 ++ else if (time_before_eq(curr->expires, get_seconds())) {
28862 ++ curr->crashes = 0;
28863 ++ curr->expires = 0;
28864 ++ }
28865 ++
28866 ++ return 0;
28867 ++}
28868 ++
28869 ++void
28870 ++gr_handle_alertkill(struct task_struct *task)
28871 ++{
28872 ++ struct acl_subject_label *curracl;
28873 ++ __u32 curr_ip;
28874 ++ struct task_struct *p, *p2;
28875 ++
28876 ++ if (unlikely(!gr_acl_is_enabled()))
28877 ++ return;
28878 ++
28879 ++ curracl = task->acl;
28880 ++ curr_ip = task->signal->curr_ip;
28881 ++
28882 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
28883 ++ read_lock(&tasklist_lock);
28884 ++ do_each_thread(p2, p) {
28885 ++ if (p->signal->curr_ip == curr_ip)
28886 ++ gr_fake_force_sig(SIGKILL, p);
28887 ++ } while_each_thread(p2, p);
28888 ++ read_unlock(&tasklist_lock);
28889 ++ } else if (curracl->mode & GR_KILLPROC)
28890 ++ gr_fake_force_sig(SIGKILL, task);
28891 ++
28892 ++ return;
28893 ++}
28894 +diff -urNp a/grsecurity/gracl_shm.c b/grsecurity/gracl_shm.c
28895 +--- a/grsecurity/gracl_shm.c 1969-12-31 16:00:00.000000000 -0800
28896 ++++ b/grsecurity/gracl_shm.c 2008-08-20 18:36:57.000000000 -0700
28897 +@@ -0,0 +1,33 @@
28898 ++#include <linux/kernel.h>
28899 ++#include <linux/mm.h>
28900 ++#include <linux/sched.h>
28901 ++#include <linux/file.h>
28902 ++#include <linux/ipc.h>
28903 ++#include <linux/gracl.h>
28904 ++#include <linux/grsecurity.h>
28905 ++#include <linux/grinternal.h>
28906 ++
28907 ++int
28908 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
28909 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
28910 ++{
28911 ++ struct task_struct *task;
28912 ++
28913 ++ if (!gr_acl_is_enabled())
28914 ++ return 1;
28915 ++
28916 ++ task = find_task_by_pid(shm_cprid);
28917 ++
28918 ++ if (unlikely(!task))
28919 ++ task = find_task_by_pid(shm_lapid);
28920 ++
28921 ++ if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
28922 ++ (task->pid == shm_lapid)) &&
28923 ++ (task->acl->mode & GR_PROTSHM) &&
28924 ++ (task->acl != current->acl))) {
28925 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
28926 ++ return 0;
28927 ++ }
28928 ++
28929 ++ return 1;
28930 ++}
28931 +diff -urNp a/grsecurity/grsec_chdir.c b/grsecurity/grsec_chdir.c
28932 +--- a/grsecurity/grsec_chdir.c 1969-12-31 16:00:00.000000000 -0800
28933 ++++ b/grsecurity/grsec_chdir.c 2008-08-20 18:36:57.000000000 -0700
28934 +@@ -0,0 +1,19 @@
28935 ++#include <linux/kernel.h>
28936 ++#include <linux/sched.h>
28937 ++#include <linux/fs.h>
28938 ++#include <linux/file.h>
28939 ++#include <linux/grsecurity.h>
28940 ++#include <linux/grinternal.h>
28941 ++
28942 ++void
28943 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
28944 ++{
28945 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
28946 ++ if ((grsec_enable_chdir && grsec_enable_group &&
28947 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
28948 ++ !grsec_enable_group)) {
28949 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
28950 ++ }
28951 ++#endif
28952 ++ return;
28953 ++}
28954 +diff -urNp a/grsecurity/grsec_chroot.c b/grsecurity/grsec_chroot.c
28955 +--- a/grsecurity/grsec_chroot.c 1969-12-31 16:00:00.000000000 -0800
28956 ++++ b/grsecurity/grsec_chroot.c 2008-08-20 18:36:57.000000000 -0700
28957 +@@ -0,0 +1,336 @@
28958 ++#include <linux/kernel.h>
28959 ++#include <linux/module.h>
28960 ++#include <linux/sched.h>
28961 ++#include <linux/file.h>
28962 ++#include <linux/fs.h>
28963 ++#include <linux/mount.h>
28964 ++#include <linux/types.h>
28965 ++#include <linux/pid_namespace.h>
28966 ++#include <linux/grsecurity.h>
28967 ++#include <linux/grinternal.h>
28968 ++
28969 ++int
28970 ++gr_handle_chroot_unix(const pid_t pid)
28971 ++{
28972 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
28973 ++ struct pid *spid = NULL;
28974 ++
28975 ++ if (unlikely(!grsec_enable_chroot_unix))
28976 ++ return 1;
28977 ++
28978 ++ if (likely(!proc_is_chrooted(current)))
28979 ++ return 1;
28980 ++
28981 ++ read_lock(&tasklist_lock);
28982 ++
28983 ++ spid = find_pid(pid);
28984 ++ if (spid) {
28985 ++ struct task_struct *p;
28986 ++ p = pid_task(spid, PIDTYPE_PID);
28987 ++ task_lock(p);
28988 ++ if (unlikely(!have_same_root(current, p))) {
28989 ++ task_unlock(p);
28990 ++ read_unlock(&tasklist_lock);
28991 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
28992 ++ return 0;
28993 ++ }
28994 ++ task_unlock(p);
28995 ++ }
28996 ++ read_unlock(&tasklist_lock);
28997 ++#endif
28998 ++ return 1;
28999 ++}
29000 ++
29001 ++int
29002 ++gr_handle_chroot_nice(void)
29003 ++{
29004 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
29005 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
29006 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
29007 ++ return -EPERM;
29008 ++ }
29009 ++#endif
29010 ++ return 0;
29011 ++}
29012 ++
29013 ++int
29014 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
29015 ++{
29016 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
29017 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
29018 ++ && proc_is_chrooted(current)) {
29019 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
29020 ++ return -EACCES;
29021 ++ }
29022 ++#endif
29023 ++ return 0;
29024 ++}
29025 ++
29026 ++int
29027 ++gr_handle_chroot_rawio(const struct inode *inode)
29028 ++{
29029 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
29030 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
29031 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
29032 ++ return 1;
29033 ++#endif
29034 ++ return 0;
29035 ++}
29036 ++
29037 ++int
29038 ++gr_pid_is_chrooted(struct task_struct *p)
29039 ++{
29040 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
29041 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
29042 ++ return 0;
29043 ++
29044 ++ task_lock(p);
29045 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
29046 ++ !have_same_root(current, p)) {
29047 ++ task_unlock(p);
29048 ++ return 1;
29049 ++ }
29050 ++ task_unlock(p);
29051 ++#endif
29052 ++ return 0;
29053 ++}
29054 ++
29055 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
29056 ++
29057 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
29058 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
29059 ++{
29060 ++ struct dentry *dentry = (struct dentry *)u_dentry;
29061 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
29062 ++ struct dentry *realroot;
29063 ++ struct vfsmount *realrootmnt;
29064 ++ struct dentry *currentroot;
29065 ++ struct vfsmount *currentmnt;
29066 ++ struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
29067 ++ int ret = 1;
29068 ++
29069 ++ read_lock(&reaper->fs->lock);
29070 ++ realrootmnt = mntget(reaper->fs->root.mnt);
29071 ++ realroot = dget(reaper->fs->root.dentry);
29072 ++ read_unlock(&reaper->fs->lock);
29073 ++
29074 ++ read_lock(&current->fs->lock);
29075 ++ currentmnt = mntget(current->fs->root.mnt);
29076 ++ currentroot = dget(current->fs->root.dentry);
29077 ++ read_unlock(&current->fs->lock);
29078 ++
29079 ++ spin_lock(&dcache_lock);
29080 ++ for (;;) {
29081 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
29082 ++ || (dentry == currentroot && mnt == currentmnt)))
29083 ++ break;
29084 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
29085 ++ if (mnt->mnt_parent == mnt)
29086 ++ break;
29087 ++ dentry = mnt->mnt_mountpoint;
29088 ++ mnt = mnt->mnt_parent;
29089 ++ continue;
29090 ++ }
29091 ++ dentry = dentry->d_parent;
29092 ++ }
29093 ++ spin_unlock(&dcache_lock);
29094 ++
29095 ++ dput(currentroot);
29096 ++ mntput(currentmnt);
29097 ++
29098 ++ /* access is outside of chroot */
29099 ++ if (dentry == realroot && mnt == realrootmnt)
29100 ++ ret = 0;
29101 ++
29102 ++ dput(realroot);
29103 ++ mntput(realrootmnt);
29104 ++ return ret;
29105 ++}
29106 ++#endif
29107 ++
29108 ++int
29109 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
29110 ++{
29111 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
29112 ++ if (!grsec_enable_chroot_fchdir)
29113 ++ return 1;
29114 ++
29115 ++ if (!proc_is_chrooted(current))
29116 ++ return 1;
29117 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
29118 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
29119 ++ return 0;
29120 ++ }
29121 ++#endif
29122 ++ return 1;
29123 ++}
29124 ++
29125 ++int
29126 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29127 ++ const time_t shm_createtime)
29128 ++{
29129 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
29130 ++ struct pid *pid = NULL;
29131 ++ time_t starttime;
29132 ++
29133 ++ if (unlikely(!grsec_enable_chroot_shmat))
29134 ++ return 1;
29135 ++
29136 ++ if (likely(!proc_is_chrooted(current)))
29137 ++ return 1;
29138 ++
29139 ++ read_lock(&tasklist_lock);
29140 ++
29141 ++ pid = find_pid(shm_cprid);
29142 ++ if (pid) {
29143 ++ struct task_struct *p;
29144 ++ p = pid_task(pid, PIDTYPE_PID);
29145 ++ task_lock(p);
29146 ++ starttime = p->start_time.tv_sec;
29147 ++ if (unlikely(!have_same_root(current, p) &&
29148 ++ time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
29149 ++ task_unlock(p);
29150 ++ read_unlock(&tasklist_lock);
29151 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
29152 ++ return 0;
29153 ++ }
29154 ++ task_unlock(p);
29155 ++ } else {
29156 ++ pid = find_pid(shm_lapid);
29157 ++ if (pid) {
29158 ++ struct task_struct *p;
29159 ++ p = pid_task(pid, PIDTYPE_PID);
29160 ++ task_lock(p);
29161 ++ if (unlikely(!have_same_root(current, p))) {
29162 ++ task_unlock(p);
29163 ++ read_unlock(&tasklist_lock);
29164 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
29165 ++ return 0;
29166 ++ }
29167 ++ task_unlock(p);
29168 ++ }
29169 ++ }
29170 ++
29171 ++ read_unlock(&tasklist_lock);
29172 ++#endif
29173 ++ return 1;
29174 ++}
29175 ++
29176 ++void
29177 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
29178 ++{
29179 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
29180 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
29181 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
29182 ++#endif
29183 ++ return;
29184 ++}
29185 ++
29186 ++int
29187 ++gr_handle_chroot_mknod(const struct dentry *dentry,
29188 ++ const struct vfsmount *mnt, const int mode)
29189 ++{
29190 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
29191 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
29192 ++ proc_is_chrooted(current)) {
29193 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
29194 ++ return -EPERM;
29195 ++ }
29196 ++#endif
29197 ++ return 0;
29198 ++}
29199 ++
29200 ++int
29201 ++gr_handle_chroot_mount(const struct dentry *dentry,
29202 ++ const struct vfsmount *mnt, const char *dev_name)
29203 ++{
29204 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
29205 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
29206 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
29207 ++ return -EPERM;
29208 ++ }
29209 ++#endif
29210 ++ return 0;
29211 ++}
29212 ++
29213 ++int
29214 ++gr_handle_chroot_pivot(void)
29215 ++{
29216 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
29217 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
29218 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
29219 ++ return -EPERM;
29220 ++ }
29221 ++#endif
29222 ++ return 0;
29223 ++}
29224 ++
29225 ++int
29226 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
29227 ++{
29228 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
29229 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
29230 ++ !gr_is_outside_chroot(dentry, mnt)) {
29231 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
29232 ++ return -EPERM;
29233 ++ }
29234 ++#endif
29235 ++ return 0;
29236 ++}
29237 ++
29238 ++void
29239 ++gr_handle_chroot_caps(struct task_struct *task)
29240 ++{
29241 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
29242 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
29243 ++ kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
29244 ++ task->cap_permitted =
29245 ++ cap_drop(task->cap_permitted, chroot_caps);
29246 ++ task->cap_inheritable =
29247 ++ cap_drop(task->cap_inheritable, chroot_caps);
29248 ++ task->cap_effective =
29249 ++ cap_drop(task->cap_effective, chroot_caps);
29250 ++ }
29251 ++#endif
29252 ++ return;
29253 ++}
29254 ++
29255 ++int
29256 ++gr_handle_chroot_sysctl(const int op)
29257 ++{
29258 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
29259 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
29260 ++ && (op & 002))
29261 ++ return -EACCES;
29262 ++#endif
29263 ++ return 0;
29264 ++}
29265 ++
29266 ++void
29267 ++gr_handle_chroot_chdir(struct path *path)
29268 ++{
29269 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
29270 ++ if (grsec_enable_chroot_chdir)
29271 ++ set_fs_pwd(current->fs, path);
29272 ++#endif
29273 ++ return;
29274 ++}
29275 ++
29276 ++int
29277 ++gr_handle_chroot_chmod(const struct dentry *dentry,
29278 ++ const struct vfsmount *mnt, const int mode)
29279 ++{
29280 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
29281 ++ if (grsec_enable_chroot_chmod &&
29282 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
29283 ++ proc_is_chrooted(current)) {
29284 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
29285 ++ return -EPERM;
29286 ++ }
29287 ++#endif
29288 ++ return 0;
29289 ++}
29290 ++
29291 ++#ifdef CONFIG_SECURITY
29292 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
29293 ++#endif
29294 +diff -urNp a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
29295 +--- a/grsecurity/grsec_disabled.c 1969-12-31 16:00:00.000000000 -0800
29296 ++++ b/grsecurity/grsec_disabled.c 2008-08-20 18:36:57.000000000 -0700
29297 +@@ -0,0 +1,418 @@
29298 ++#include <linux/kernel.h>
29299 ++#include <linux/module.h>
29300 ++#include <linux/sched.h>
29301 ++#include <linux/file.h>
29302 ++#include <linux/fs.h>
29303 ++#include <linux/kdev_t.h>
29304 ++#include <linux/net.h>
29305 ++#include <linux/in.h>
29306 ++#include <linux/ip.h>
29307 ++#include <linux/skbuff.h>
29308 ++#include <linux/sysctl.h>
29309 ++
29310 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29311 ++void
29312 ++pax_set_initial_flags(struct linux_binprm *bprm)
29313 ++{
29314 ++ return;
29315 ++}
29316 ++#endif
29317 ++
29318 ++#ifdef CONFIG_SYSCTL
29319 ++__u32
29320 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
29321 ++{
29322 ++ return 0;
29323 ++}
29324 ++#endif
29325 ++
29326 ++int
29327 ++gr_acl_is_enabled(void)
29328 ++{
29329 ++ return 0;
29330 ++}
29331 ++
29332 ++int
29333 ++gr_handle_rawio(const struct inode *inode)
29334 ++{
29335 ++ return 0;
29336 ++}
29337 ++
29338 ++void
29339 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
29340 ++{
29341 ++ return;
29342 ++}
29343 ++
29344 ++int
29345 ++gr_handle_ptrace(struct task_struct *task, const long request)
29346 ++{
29347 ++ return 0;
29348 ++}
29349 ++
29350 ++int
29351 ++gr_handle_proc_ptrace(struct task_struct *task)
29352 ++{
29353 ++ return 0;
29354 ++}
29355 ++
29356 ++void
29357 ++gr_learn_resource(const struct task_struct *task,
29358 ++ const int res, const unsigned long wanted, const int gt)
29359 ++{
29360 ++ return;
29361 ++}
29362 ++
29363 ++int
29364 ++gr_set_acls(const int type)
29365 ++{
29366 ++ return 0;
29367 ++}
29368 ++
29369 ++int
29370 ++gr_check_hidden_task(const struct task_struct *tsk)
29371 ++{
29372 ++ return 0;
29373 ++}
29374 ++
29375 ++int
29376 ++gr_check_protected_task(const struct task_struct *task)
29377 ++{
29378 ++ return 0;
29379 ++}
29380 ++
29381 ++void
29382 ++gr_copy_label(struct task_struct *tsk)
29383 ++{
29384 ++ return;
29385 ++}
29386 ++
29387 ++void
29388 ++gr_set_pax_flags(struct task_struct *task)
29389 ++{
29390 ++ return;
29391 ++}
29392 ++
29393 ++int
29394 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
29395 ++{
29396 ++ return 0;
29397 ++}
29398 ++
29399 ++void
29400 ++gr_handle_delete(const ino_t ino, const dev_t dev)
29401 ++{
29402 ++ return;
29403 ++}
29404 ++
29405 ++void
29406 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
29407 ++{
29408 ++ return;
29409 ++}
29410 ++
29411 ++void
29412 ++gr_handle_crash(struct task_struct *task, const int sig)
29413 ++{
29414 ++ return;
29415 ++}
29416 ++
29417 ++int
29418 ++gr_check_crash_exec(const struct file *filp)
29419 ++{
29420 ++ return 0;
29421 ++}
29422 ++
29423 ++int
29424 ++gr_check_crash_uid(const uid_t uid)
29425 ++{
29426 ++ return 0;
29427 ++}
29428 ++
29429 ++void
29430 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
29431 ++ struct dentry *old_dentry,
29432 ++ struct dentry *new_dentry,
29433 ++ struct vfsmount *mnt, const __u8 replace)
29434 ++{
29435 ++ return;
29436 ++}
29437 ++
29438 ++int
29439 ++gr_search_socket(const int family, const int type, const int protocol)
29440 ++{
29441 ++ return 1;
29442 ++}
29443 ++
29444 ++int
29445 ++gr_search_connectbind(const int mode, const struct socket *sock,
29446 ++ const struct sockaddr_in *addr)
29447 ++{
29448 ++ return 1;
29449 ++}
29450 ++
29451 ++int
29452 ++gr_task_is_capable(struct task_struct *task, const int cap)
29453 ++{
29454 ++ return 1;
29455 ++}
29456 ++
29457 ++int
29458 ++gr_is_capable_nolog(const int cap)
29459 ++{
29460 ++ return 1;
29461 ++}
29462 ++
29463 ++void
29464 ++gr_handle_alertkill(struct task_struct *task)
29465 ++{
29466 ++ return;
29467 ++}
29468 ++
29469 ++__u32
29470 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
29471 ++{
29472 ++ return 1;
29473 ++}
29474 ++
29475 ++__u32
29476 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
29477 ++ const struct vfsmount * mnt)
29478 ++{
29479 ++ return 1;
29480 ++}
29481 ++
29482 ++__u32
29483 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
29484 ++ const int fmode)
29485 ++{
29486 ++ return 1;
29487 ++}
29488 ++
29489 ++__u32
29490 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
29491 ++{
29492 ++ return 1;
29493 ++}
29494 ++
29495 ++__u32
29496 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
29497 ++{
29498 ++ return 1;
29499 ++}
29500 ++
29501 ++int
29502 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
29503 ++ unsigned int *vm_flags)
29504 ++{
29505 ++ return 1;
29506 ++}
29507 ++
29508 ++__u32
29509 ++gr_acl_handle_truncate(const struct dentry * dentry,
29510 ++ const struct vfsmount * mnt)
29511 ++{
29512 ++ return 1;
29513 ++}
29514 ++
29515 ++__u32
29516 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
29517 ++{
29518 ++ return 1;
29519 ++}
29520 ++
29521 ++__u32
29522 ++gr_acl_handle_access(const struct dentry * dentry,
29523 ++ const struct vfsmount * mnt, const int fmode)
29524 ++{
29525 ++ return 1;
29526 ++}
29527 ++
29528 ++__u32
29529 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
29530 ++ mode_t mode)
29531 ++{
29532 ++ return 1;
29533 ++}
29534 ++
29535 ++__u32
29536 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
29537 ++ mode_t mode)
29538 ++{
29539 ++ return 1;
29540 ++}
29541 ++
29542 ++__u32
29543 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
29544 ++{
29545 ++ return 1;
29546 ++}
29547 ++
29548 ++void
29549 ++grsecurity_init(void)
29550 ++{
29551 ++ return;
29552 ++}
29553 ++
29554 ++__u32
29555 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
29556 ++ const struct dentry * parent_dentry,
29557 ++ const struct vfsmount * parent_mnt,
29558 ++ const int mode)
29559 ++{
29560 ++ return 1;
29561 ++}
29562 ++
29563 ++__u32
29564 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
29565 ++ const struct dentry * parent_dentry,
29566 ++ const struct vfsmount * parent_mnt)
29567 ++{
29568 ++ return 1;
29569 ++}
29570 ++
29571 ++__u32
29572 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
29573 ++ const struct dentry * parent_dentry,
29574 ++ const struct vfsmount * parent_mnt, const char *from)
29575 ++{
29576 ++ return 1;
29577 ++}
29578 ++
29579 ++__u32
29580 ++gr_acl_handle_link(const struct dentry * new_dentry,
29581 ++ const struct dentry * parent_dentry,
29582 ++ const struct vfsmount * parent_mnt,
29583 ++ const struct dentry * old_dentry,
29584 ++ const struct vfsmount * old_mnt, const char *to)
29585 ++{
29586 ++ return 1;
29587 ++}
29588 ++
29589 ++int
29590 ++gr_acl_handle_rename(const struct dentry *new_dentry,
29591 ++ const struct dentry *parent_dentry,
29592 ++ const struct vfsmount *parent_mnt,
29593 ++ const struct dentry *old_dentry,
29594 ++ const struct inode *old_parent_inode,
29595 ++ const struct vfsmount *old_mnt, const char *newname)
29596 ++{
29597 ++ return 0;
29598 ++}
29599 ++
29600 ++int
29601 ++gr_acl_handle_filldir(const struct file *file, const char *name,
29602 ++ const int namelen, const ino_t ino)
29603 ++{
29604 ++ return 1;
29605 ++}
29606 ++
29607 ++int
29608 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29609 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
29610 ++{
29611 ++ return 1;
29612 ++}
29613 ++
29614 ++int
29615 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
29616 ++{
29617 ++ return 1;
29618 ++}
29619 ++
29620 ++int
29621 ++gr_search_accept(const struct socket *sock)
29622 ++{
29623 ++ return 1;
29624 ++}
29625 ++
29626 ++int
29627 ++gr_search_listen(const struct socket *sock)
29628 ++{
29629 ++ return 1;
29630 ++}
29631 ++
29632 ++int
29633 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
29634 ++{
29635 ++ return 1;
29636 ++}
29637 ++
29638 ++__u32
29639 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
29640 ++{
29641 ++ return 1;
29642 ++}
29643 ++
29644 ++__u32
29645 ++gr_acl_handle_creat(const struct dentry * dentry,
29646 ++ const struct dentry * p_dentry,
29647 ++ const struct vfsmount * p_mnt, const int fmode,
29648 ++ const int imode)
29649 ++{
29650 ++ return 1;
29651 ++}
29652 ++
29653 ++void
29654 ++gr_acl_handle_exit(void)
29655 ++{
29656 ++ return;
29657 ++}
29658 ++
29659 ++int
29660 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
29661 ++{
29662 ++ return 1;
29663 ++}
29664 ++
29665 ++void
29666 ++gr_set_role_label(const uid_t uid, const gid_t gid)
29667 ++{
29668 ++ return;
29669 ++}
29670 ++
29671 ++int
29672 ++gr_acl_handle_procpidmem(const struct task_struct *task)
29673 ++{
29674 ++ return 0;
29675 ++}
29676 ++
29677 ++int
29678 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
29679 ++{
29680 ++ return 1;
29681 ++}
29682 ++
29683 ++int
29684 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
29685 ++{
29686 ++ return 1;
29687 ++}
29688 ++
29689 ++void
29690 ++gr_set_kernel_label(struct task_struct *task)
29691 ++{
29692 ++ return;
29693 ++}
29694 ++
29695 ++int
29696 ++gr_check_user_change(int real, int effective, int fs)
29697 ++{
29698 ++ return 0;
29699 ++}
29700 ++
29701 ++int
29702 ++gr_check_group_change(int real, int effective, int fs)
29703 ++{
29704 ++ return 0;
29705 ++}
29706 ++
29707 ++
29708 ++EXPORT_SYMBOL(gr_task_is_capable);
29709 ++EXPORT_SYMBOL(gr_is_capable_nolog);
29710 ++EXPORT_SYMBOL(gr_learn_resource);
29711 ++EXPORT_SYMBOL(gr_set_kernel_label);
29712 ++#ifdef CONFIG_SECURITY
29713 ++EXPORT_SYMBOL(gr_check_user_change);
29714 ++EXPORT_SYMBOL(gr_check_group_change);
29715 ++#endif
29716 +diff -urNp a/grsecurity/grsec_exec.c b/grsecurity/grsec_exec.c
29717 +--- a/grsecurity/grsec_exec.c 1969-12-31 16:00:00.000000000 -0800
29718 ++++ b/grsecurity/grsec_exec.c 2008-08-20 18:36:57.000000000 -0700
29719 +@@ -0,0 +1,88 @@
29720 ++#include <linux/kernel.h>
29721 ++#include <linux/sched.h>
29722 ++#include <linux/file.h>
29723 ++#include <linux/binfmts.h>
29724 ++#include <linux/smp_lock.h>
29725 ++#include <linux/fs.h>
29726 ++#include <linux/types.h>
29727 ++#include <linux/grdefs.h>
29728 ++#include <linux/grinternal.h>
29729 ++#include <linux/capability.h>
29730 ++
29731 ++#include <asm/uaccess.h>
29732 ++
29733 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
29734 ++static char gr_exec_arg_buf[132];
29735 ++static DECLARE_MUTEX(gr_exec_arg_sem);
29736 ++#endif
29737 ++
29738 ++int
29739 ++gr_handle_nproc(void)
29740 ++{
29741 ++#ifdef CONFIG_GRKERNSEC_EXECVE
29742 ++ if (grsec_enable_execve && current->user &&
29743 ++ (atomic_read(&current->user->processes) >
29744 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
29745 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
29746 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
29747 ++ return -EAGAIN;
29748 ++ }
29749 ++#endif
29750 ++ return 0;
29751 ++}
29752 ++
29753 ++void
29754 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
29755 ++{
29756 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
29757 ++ char *grarg = gr_exec_arg_buf;
29758 ++ unsigned int i, x, execlen = 0;
29759 ++ char c;
29760 ++
29761 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
29762 ++ in_group_p(grsec_audit_gid))
29763 ++ || (grsec_enable_execlog && !grsec_enable_group)))
29764 ++ return;
29765 ++
29766 ++ down(&gr_exec_arg_sem);
29767 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
29768 ++
29769 ++ if (unlikely(argv == NULL))
29770 ++ goto log;
29771 ++
29772 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
29773 ++ const char __user *p;
29774 ++ unsigned int len;
29775 ++
29776 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
29777 ++ goto log;
29778 ++ if (!p)
29779 ++ goto log;
29780 ++ len = strnlen_user(p, 128 - execlen);
29781 ++ if (len > 128 - execlen)
29782 ++ len = 128 - execlen;
29783 ++ else if (len > 0)
29784 ++ len--;
29785 ++ if (copy_from_user(grarg + execlen, p, len))
29786 ++ goto log;
29787 ++
29788 ++ /* rewrite unprintable characters */
29789 ++ for (x = 0; x < len; x++) {
29790 ++ c = *(grarg + execlen + x);
29791 ++ if (c < 32 || c > 126)
29792 ++ *(grarg + execlen + x) = ' ';
29793 ++ }
29794 ++
29795 ++ execlen += len;
29796 ++ *(grarg + execlen) = ' ';
29797 ++ *(grarg + execlen + 1) = '\0';
29798 ++ execlen++;
29799 ++ }
29800 ++
29801 ++ log:
29802 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
29803 ++ bprm->file->f_path.mnt, grarg);
29804 ++ up(&gr_exec_arg_sem);
29805 ++#endif
29806 ++ return;
29807 ++}
29808 +diff -urNp a/grsecurity/grsec_fifo.c b/grsecurity/grsec_fifo.c
29809 +--- a/grsecurity/grsec_fifo.c 1969-12-31 16:00:00.000000000 -0800
29810 ++++ b/grsecurity/grsec_fifo.c 2008-08-20 18:36:57.000000000 -0700
29811 +@@ -0,0 +1,22 @@
29812 ++#include <linux/kernel.h>
29813 ++#include <linux/sched.h>
29814 ++#include <linux/fs.h>
29815 ++#include <linux/file.h>
29816 ++#include <linux/grinternal.h>
29817 ++
29818 ++int
29819 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
29820 ++ const struct dentry *dir, const int flag, const int acc_mode)
29821 ++{
29822 ++#ifdef CONFIG_GRKERNSEC_FIFO
29823 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
29824 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
29825 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
29826 ++ (current->fsuid != dentry->d_inode->i_uid)) {
29827 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
29828 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
29829 ++ return -EACCES;
29830 ++ }
29831 ++#endif
29832 ++ return 0;
29833 ++}
29834 +diff -urNp a/grsecurity/grsec_fork.c b/grsecurity/grsec_fork.c
29835 +--- a/grsecurity/grsec_fork.c 1969-12-31 16:00:00.000000000 -0800
29836 ++++ b/grsecurity/grsec_fork.c 2008-08-20 18:36:57.000000000 -0700
29837 +@@ -0,0 +1,15 @@
29838 ++#include <linux/kernel.h>
29839 ++#include <linux/sched.h>
29840 ++#include <linux/grsecurity.h>
29841 ++#include <linux/grinternal.h>
29842 ++#include <linux/errno.h>
29843 ++
29844 ++void
29845 ++gr_log_forkfail(const int retval)
29846 ++{
29847 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
29848 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
29849 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
29850 ++#endif
29851 ++ return;
29852 ++}
29853 +diff -urNp a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c
29854 +--- a/grsecurity/grsec_init.c 1969-12-31 16:00:00.000000000 -0800
29855 ++++ b/grsecurity/grsec_init.c 2008-08-20 18:36:57.000000000 -0700
29856 +@@ -0,0 +1,226 @@
29857 ++#include <linux/kernel.h>
29858 ++#include <linux/sched.h>
29859 ++#include <linux/mm.h>
29860 ++#include <linux/smp_lock.h>
29861 ++#include <linux/gracl.h>
29862 ++#include <linux/slab.h>
29863 ++#include <linux/vmalloc.h>
29864 ++#include <linux/percpu.h>
29865 ++
29866 ++int grsec_enable_link;
29867 ++int grsec_enable_dmesg;
29868 ++int grsec_enable_fifo;
29869 ++int grsec_enable_execve;
29870 ++int grsec_enable_execlog;
29871 ++int grsec_enable_signal;
29872 ++int grsec_enable_forkfail;
29873 ++int grsec_enable_time;
29874 ++int grsec_enable_audit_textrel;
29875 ++int grsec_enable_group;
29876 ++int grsec_audit_gid;
29877 ++int grsec_enable_chdir;
29878 ++int grsec_enable_audit_ipc;
29879 ++int grsec_enable_mount;
29880 ++int grsec_enable_chroot_findtask;
29881 ++int grsec_enable_chroot_mount;
29882 ++int grsec_enable_chroot_shmat;
29883 ++int grsec_enable_chroot_fchdir;
29884 ++int grsec_enable_chroot_double;
29885 ++int grsec_enable_chroot_pivot;
29886 ++int grsec_enable_chroot_chdir;
29887 ++int grsec_enable_chroot_chmod;
29888 ++int grsec_enable_chroot_mknod;
29889 ++int grsec_enable_chroot_nice;
29890 ++int grsec_enable_chroot_execlog;
29891 ++int grsec_enable_chroot_caps;
29892 ++int grsec_enable_chroot_sysctl;
29893 ++int grsec_enable_chroot_unix;
29894 ++int grsec_enable_tpe;
29895 ++int grsec_tpe_gid;
29896 ++int grsec_enable_tpe_all;
29897 ++int grsec_enable_socket_all;
29898 ++int grsec_socket_all_gid;
29899 ++int grsec_enable_socket_client;
29900 ++int grsec_socket_client_gid;
29901 ++int grsec_enable_socket_server;
29902 ++int grsec_socket_server_gid;
29903 ++int grsec_resource_logging;
29904 ++int grsec_lock;
29905 ++
29906 ++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
29907 ++unsigned long grsec_alert_wtime = 0;
29908 ++unsigned long grsec_alert_fyet = 0;
29909 ++
29910 ++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
29911 ++
29912 ++rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
29913 ++
29914 ++char *gr_shared_page[4];
29915 ++
29916 ++char *gr_alert_log_fmt;
29917 ++char *gr_audit_log_fmt;
29918 ++char *gr_alert_log_buf;
29919 ++char *gr_audit_log_buf;
29920 ++
29921 ++extern struct gr_arg *gr_usermode;
29922 ++extern unsigned char *gr_system_salt;
29923 ++extern unsigned char *gr_system_sum;
29924 ++
29925 ++void
29926 ++grsecurity_init(void)
29927 ++{
29928 ++ int j;
29929 ++ /* create the per-cpu shared pages */
29930 ++
29931 ++ for (j = 0; j < 4; j++) {
29932 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
29933 ++ if (gr_shared_page[j] == NULL) {
29934 ++ panic("Unable to allocate grsecurity shared page");
29935 ++ return;
29936 ++ }
29937 ++ }
29938 ++
29939 ++ /* allocate log buffers */
29940 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
29941 ++ if (!gr_alert_log_fmt) {
29942 ++ panic("Unable to allocate grsecurity alert log format buffer");
29943 ++ return;
29944 ++ }
29945 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
29946 ++ if (!gr_audit_log_fmt) {
29947 ++ panic("Unable to allocate grsecurity audit log format buffer");
29948 ++ return;
29949 ++ }
29950 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
29951 ++ if (!gr_alert_log_buf) {
29952 ++ panic("Unable to allocate grsecurity alert log buffer");
29953 ++ return;
29954 ++ }
29955 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
29956 ++ if (!gr_audit_log_buf) {
29957 ++ panic("Unable to allocate grsecurity audit log buffer");
29958 ++ return;
29959 ++ }
29960 ++
29961 ++ /* allocate memory for authentication structure */
29962 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
29963 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
29964 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
29965 ++
29966 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
29967 ++ panic("Unable to allocate grsecurity authentication structure");
29968 ++ return;
29969 ++ }
29970 ++
29971 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
29972 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
29973 ++ grsec_lock = 1;
29974 ++#endif
29975 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
29976 ++ grsec_enable_audit_textrel = 1;
29977 ++#endif
29978 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
29979 ++ grsec_enable_group = 1;
29980 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
29981 ++#endif
29982 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
29983 ++ grsec_enable_chdir = 1;
29984 ++#endif
29985 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
29986 ++ grsec_enable_audit_ipc = 1;
29987 ++#endif
29988 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
29989 ++ grsec_enable_mount = 1;
29990 ++#endif
29991 ++#ifdef CONFIG_GRKERNSEC_LINK
29992 ++ grsec_enable_link = 1;
29993 ++#endif
29994 ++#ifdef CONFIG_GRKERNSEC_DMESG
29995 ++ grsec_enable_dmesg = 1;
29996 ++#endif
29997 ++#ifdef CONFIG_GRKERNSEC_FIFO
29998 ++ grsec_enable_fifo = 1;
29999 ++#endif
30000 ++#ifdef CONFIG_GRKERNSEC_EXECVE
30001 ++ grsec_enable_execve = 1;
30002 ++#endif
30003 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
30004 ++ grsec_enable_execlog = 1;
30005 ++#endif
30006 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
30007 ++ grsec_enable_signal = 1;
30008 ++#endif
30009 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
30010 ++ grsec_enable_forkfail = 1;
30011 ++#endif
30012 ++#ifdef CONFIG_GRKERNSEC_TIME
30013 ++ grsec_enable_time = 1;
30014 ++#endif
30015 ++#ifdef CONFIG_GRKERNSEC_RESLOG
30016 ++ grsec_resource_logging = 1;
30017 ++#endif
30018 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
30019 ++ grsec_enable_chroot_findtask = 1;
30020 ++#endif
30021 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
30022 ++ grsec_enable_chroot_unix = 1;
30023 ++#endif
30024 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
30025 ++ grsec_enable_chroot_mount = 1;
30026 ++#endif
30027 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
30028 ++ grsec_enable_chroot_fchdir = 1;
30029 ++#endif
30030 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
30031 ++ grsec_enable_chroot_shmat = 1;
30032 ++#endif
30033 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
30034 ++ grsec_enable_chroot_double = 1;
30035 ++#endif
30036 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
30037 ++ grsec_enable_chroot_pivot = 1;
30038 ++#endif
30039 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
30040 ++ grsec_enable_chroot_chdir = 1;
30041 ++#endif
30042 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
30043 ++ grsec_enable_chroot_chmod = 1;
30044 ++#endif
30045 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
30046 ++ grsec_enable_chroot_mknod = 1;
30047 ++#endif
30048 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
30049 ++ grsec_enable_chroot_nice = 1;
30050 ++#endif
30051 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
30052 ++ grsec_enable_chroot_execlog = 1;
30053 ++#endif
30054 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
30055 ++ grsec_enable_chroot_caps = 1;
30056 ++#endif
30057 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
30058 ++ grsec_enable_chroot_sysctl = 1;
30059 ++#endif
30060 ++#ifdef CONFIG_GRKERNSEC_TPE
30061 ++ grsec_enable_tpe = 1;
30062 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
30063 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
30064 ++ grsec_enable_tpe_all = 1;
30065 ++#endif
30066 ++#endif
30067 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
30068 ++ grsec_enable_socket_all = 1;
30069 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
30070 ++#endif
30071 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
30072 ++ grsec_enable_socket_client = 1;
30073 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
30074 ++#endif
30075 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30076 ++ grsec_enable_socket_server = 1;
30077 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
30078 ++#endif
30079 ++#endif
30080 ++
30081 ++ return;
30082 ++}
30083 +diff -urNp a/grsecurity/grsec_ipc.c b/grsecurity/grsec_ipc.c
30084 +--- a/grsecurity/grsec_ipc.c 1969-12-31 16:00:00.000000000 -0800
30085 ++++ b/grsecurity/grsec_ipc.c 2008-08-20 18:36:57.000000000 -0700
30086 +@@ -0,0 +1,81 @@
30087 ++#include <linux/kernel.h>
30088 ++#include <linux/sched.h>
30089 ++#include <linux/types.h>
30090 ++#include <linux/ipc.h>
30091 ++#include <linux/grsecurity.h>
30092 ++#include <linux/grinternal.h>
30093 ++
30094 ++void
30095 ++gr_log_msgget(const int ret, const int msgflg)
30096 ++{
30097 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30098 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30099 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30100 ++ !grsec_enable_group)) && (ret >= 0)
30101 ++ && (msgflg & IPC_CREAT))
30102 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
30103 ++#endif
30104 ++ return;
30105 ++}
30106 ++
30107 ++void
30108 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
30109 ++{
30110 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30111 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30112 ++ grsec_enable_audit_ipc) ||
30113 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30114 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
30115 ++#endif
30116 ++ return;
30117 ++}
30118 ++
30119 ++void
30120 ++gr_log_semget(const int err, const int semflg)
30121 ++{
30122 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30123 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30124 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30125 ++ !grsec_enable_group)) && (err >= 0)
30126 ++ && (semflg & IPC_CREAT))
30127 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
30128 ++#endif
30129 ++ return;
30130 ++}
30131 ++
30132 ++void
30133 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
30134 ++{
30135 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30136 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30137 ++ grsec_enable_audit_ipc) ||
30138 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30139 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
30140 ++#endif
30141 ++ return;
30142 ++}
30143 ++
30144 ++void
30145 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
30146 ++{
30147 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30148 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30149 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30150 ++ !grsec_enable_group)) && (err >= 0)
30151 ++ && (shmflg & IPC_CREAT))
30152 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
30153 ++#endif
30154 ++ return;
30155 ++}
30156 ++
30157 ++void
30158 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
30159 ++{
30160 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30161 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30162 ++ grsec_enable_audit_ipc) ||
30163 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30164 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
30165 ++#endif
30166 ++ return;
30167 ++}
30168 +diff -urNp a/grsecurity/grsec_link.c b/grsecurity/grsec_link.c
30169 +--- a/grsecurity/grsec_link.c 1969-12-31 16:00:00.000000000 -0800
30170 ++++ b/grsecurity/grsec_link.c 2008-08-20 18:36:57.000000000 -0700
30171 +@@ -0,0 +1,39 @@
30172 ++#include <linux/kernel.h>
30173 ++#include <linux/sched.h>
30174 ++#include <linux/fs.h>
30175 ++#include <linux/file.h>
30176 ++#include <linux/grinternal.h>
30177 ++
30178 ++int
30179 ++gr_handle_follow_link(const struct inode *parent,
30180 ++ const struct inode *inode,
30181 ++ const struct dentry *dentry, const struct vfsmount *mnt)
30182 ++{
30183 ++#ifdef CONFIG_GRKERNSEC_LINK
30184 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
30185 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
30186 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
30187 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
30188 ++ return -EACCES;
30189 ++ }
30190 ++#endif
30191 ++ return 0;
30192 ++}
30193 ++
30194 ++int
30195 ++gr_handle_hardlink(const struct dentry *dentry,
30196 ++ const struct vfsmount *mnt,
30197 ++ struct inode *inode, const int mode, const char *to)
30198 ++{
30199 ++#ifdef CONFIG_GRKERNSEC_LINK
30200 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
30201 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
30202 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
30203 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
30204 ++ !capable(CAP_FOWNER) && current->uid) {
30205 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
30206 ++ return -EPERM;
30207 ++ }
30208 ++#endif
30209 ++ return 0;
30210 ++}
30211 +diff -urNp a/grsecurity/grsec_log.c b/grsecurity/grsec_log.c
30212 +--- a/grsecurity/grsec_log.c 1969-12-31 16:00:00.000000000 -0800
30213 ++++ b/grsecurity/grsec_log.c 2008-08-20 18:36:57.000000000 -0700
30214 +@@ -0,0 +1,269 @@
30215 ++#include <linux/kernel.h>
30216 ++#include <linux/sched.h>
30217 ++#include <linux/file.h>
30218 ++#include <linux/tty.h>
30219 ++#include <linux/fs.h>
30220 ++#include <linux/grinternal.h>
30221 ++
30222 ++#define BEGIN_LOCKS(x) \
30223 ++ read_lock(&tasklist_lock); \
30224 ++ read_lock(&grsec_exec_file_lock); \
30225 ++ if (x != GR_DO_AUDIT) \
30226 ++ spin_lock(&grsec_alert_lock); \
30227 ++ else \
30228 ++ spin_lock(&grsec_audit_lock)
30229 ++
30230 ++#define END_LOCKS(x) \
30231 ++ if (x != GR_DO_AUDIT) \
30232 ++ spin_unlock(&grsec_alert_lock); \
30233 ++ else \
30234 ++ spin_unlock(&grsec_audit_lock); \
30235 ++ read_unlock(&grsec_exec_file_lock); \
30236 ++ read_unlock(&tasklist_lock); \
30237 ++ if (x == GR_DONT_AUDIT) \
30238 ++ gr_handle_alertkill(current)
30239 ++
30240 ++enum {
30241 ++ FLOODING,
30242 ++ NO_FLOODING
30243 ++};
30244 ++
30245 ++extern char *gr_alert_log_fmt;
30246 ++extern char *gr_audit_log_fmt;
30247 ++extern char *gr_alert_log_buf;
30248 ++extern char *gr_audit_log_buf;
30249 ++
30250 ++static int gr_log_start(int audit)
30251 ++{
30252 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
30253 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
30254 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30255 ++
30256 ++ if (audit == GR_DO_AUDIT)
30257 ++ goto set_fmt;
30258 ++
30259 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
30260 ++ grsec_alert_wtime = jiffies;
30261 ++ grsec_alert_fyet = 0;
30262 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
30263 ++ grsec_alert_fyet++;
30264 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
30265 ++ grsec_alert_wtime = jiffies;
30266 ++ grsec_alert_fyet++;
30267 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
30268 ++ return FLOODING;
30269 ++ } else return FLOODING;
30270 ++
30271 ++set_fmt:
30272 ++ memset(buf, 0, PAGE_SIZE);
30273 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
30274 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
30275 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
30276 ++ } else if (current->signal->curr_ip) {
30277 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
30278 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
30279 ++ } else if (gr_acl_is_enabled()) {
30280 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
30281 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
30282 ++ } else {
30283 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
30284 ++ strcpy(buf, fmt);
30285 ++ }
30286 ++
30287 ++ return NO_FLOODING;
30288 ++}
30289 ++
30290 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
30291 ++{
30292 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30293 ++ unsigned int len = strlen(buf);
30294 ++
30295 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
30296 ++
30297 ++ return;
30298 ++}
30299 ++
30300 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
30301 ++{
30302 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30303 ++ unsigned int len = strlen(buf);
30304 ++ va_list ap;
30305 ++
30306 ++ va_start(ap, msg);
30307 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
30308 ++ va_end(ap);
30309 ++
30310 ++ return;
30311 ++}
30312 ++
30313 ++static void gr_log_end(int audit)
30314 ++{
30315 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30316 ++ unsigned int len = strlen(buf);
30317 ++
30318 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
30319 ++ printk("%s\n", buf);
30320 ++
30321 ++ return;
30322 ++}
30323 ++
30324 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
30325 ++{
30326 ++ int logtype;
30327 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
30328 ++ char *str1, *str2, *str3;
30329 ++ int num1, num2;
30330 ++ unsigned long ulong1, ulong2;
30331 ++ struct dentry *dentry;
30332 ++ struct vfsmount *mnt;
30333 ++ struct file *file;
30334 ++ struct task_struct *task;
30335 ++ va_list ap;
30336 ++
30337 ++ BEGIN_LOCKS(audit);
30338 ++ logtype = gr_log_start(audit);
30339 ++ if (logtype == FLOODING) {
30340 ++ END_LOCKS(audit);
30341 ++ return;
30342 ++ }
30343 ++ va_start(ap, argtypes);
30344 ++ switch (argtypes) {
30345 ++ case GR_TTYSNIFF:
30346 ++ task = va_arg(ap, struct task_struct *);
30347 ++ 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);
30348 ++ break;
30349 ++ case GR_SYSCTL_HIDDEN:
30350 ++ str1 = va_arg(ap, char *);
30351 ++ gr_log_middle_varargs(audit, msg, result, str1);
30352 ++ break;
30353 ++ case GR_RBAC:
30354 ++ dentry = va_arg(ap, struct dentry *);
30355 ++ mnt = va_arg(ap, struct vfsmount *);
30356 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
30357 ++ break;
30358 ++ case GR_RBAC_STR:
30359 ++ dentry = va_arg(ap, struct dentry *);
30360 ++ mnt = va_arg(ap, struct vfsmount *);
30361 ++ str1 = va_arg(ap, char *);
30362 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
30363 ++ break;
30364 ++ case GR_STR_RBAC:
30365 ++ str1 = va_arg(ap, char *);
30366 ++ dentry = va_arg(ap, struct dentry *);
30367 ++ mnt = va_arg(ap, struct vfsmount *);
30368 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
30369 ++ break;
30370 ++ case GR_RBAC_MODE2:
30371 ++ dentry = va_arg(ap, struct dentry *);
30372 ++ mnt = va_arg(ap, struct vfsmount *);
30373 ++ str1 = va_arg(ap, char *);
30374 ++ str2 = va_arg(ap, char *);
30375 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
30376 ++ break;
30377 ++ case GR_RBAC_MODE3:
30378 ++ dentry = va_arg(ap, struct dentry *);
30379 ++ mnt = va_arg(ap, struct vfsmount *);
30380 ++ str1 = va_arg(ap, char *);
30381 ++ str2 = va_arg(ap, char *);
30382 ++ str3 = va_arg(ap, char *);
30383 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
30384 ++ break;
30385 ++ case GR_FILENAME:
30386 ++ dentry = va_arg(ap, struct dentry *);
30387 ++ mnt = va_arg(ap, struct vfsmount *);
30388 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
30389 ++ break;
30390 ++ case GR_STR_FILENAME:
30391 ++ str1 = va_arg(ap, char *);
30392 ++ dentry = va_arg(ap, struct dentry *);
30393 ++ mnt = va_arg(ap, struct vfsmount *);
30394 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
30395 ++ break;
30396 ++ case GR_FILENAME_STR:
30397 ++ dentry = va_arg(ap, struct dentry *);
30398 ++ mnt = va_arg(ap, struct vfsmount *);
30399 ++ str1 = va_arg(ap, char *);
30400 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
30401 ++ break;
30402 ++ case GR_FILENAME_TWO_INT:
30403 ++ dentry = va_arg(ap, struct dentry *);
30404 ++ mnt = va_arg(ap, struct vfsmount *);
30405 ++ num1 = va_arg(ap, int);
30406 ++ num2 = va_arg(ap, int);
30407 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
30408 ++ break;
30409 ++ case GR_FILENAME_TWO_INT_STR:
30410 ++ dentry = va_arg(ap, struct dentry *);
30411 ++ mnt = va_arg(ap, struct vfsmount *);
30412 ++ num1 = va_arg(ap, int);
30413 ++ num2 = va_arg(ap, int);
30414 ++ str1 = va_arg(ap, char *);
30415 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
30416 ++ break;
30417 ++ case GR_TEXTREL:
30418 ++ file = va_arg(ap, struct file *);
30419 ++ ulong1 = va_arg(ap, unsigned long);
30420 ++ ulong2 = va_arg(ap, unsigned long);
30421 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
30422 ++ break;
30423 ++ case GR_PTRACE:
30424 ++ task = va_arg(ap, struct task_struct *);
30425 ++ 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);
30426 ++ break;
30427 ++ case GR_RESOURCE:
30428 ++ task = va_arg(ap, struct task_struct *);
30429 ++ ulong1 = va_arg(ap, unsigned long);
30430 ++ str1 = va_arg(ap, char *);
30431 ++ ulong2 = va_arg(ap, unsigned long);
30432 ++ 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);
30433 ++ break;
30434 ++ case GR_CAP:
30435 ++ task = va_arg(ap, struct task_struct *);
30436 ++ str1 = va_arg(ap, char *);
30437 ++ 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);
30438 ++ break;
30439 ++ case GR_SIG:
30440 ++ task = va_arg(ap, struct task_struct *);
30441 ++ num1 = va_arg(ap, int);
30442 ++ 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);
30443 ++ break;
30444 ++ case GR_CRASH1:
30445 ++ task = va_arg(ap, struct task_struct *);
30446 ++ ulong1 = va_arg(ap, unsigned long);
30447 ++ 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);
30448 ++ break;
30449 ++ case GR_CRASH2:
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, ulong1);
30453 ++ break;
30454 ++ case GR_PSACCT:
30455 ++ {
30456 ++ unsigned int wday, cday;
30457 ++ __u8 whr, chr;
30458 ++ __u8 wmin, cmin;
30459 ++ __u8 wsec, csec;
30460 ++ char cur_tty[64] = { 0 };
30461 ++ char parent_tty[64] = { 0 };
30462 ++
30463 ++ task = va_arg(ap, struct task_struct *);
30464 ++ wday = va_arg(ap, unsigned int);
30465 ++ cday = va_arg(ap, unsigned int);
30466 ++ whr = va_arg(ap, int);
30467 ++ chr = va_arg(ap, int);
30468 ++ wmin = va_arg(ap, int);
30469 ++ cmin = va_arg(ap, int);
30470 ++ wsec = va_arg(ap, int);
30471 ++ csec = va_arg(ap, int);
30472 ++ ulong1 = va_arg(ap, unsigned long);
30473 ++
30474 ++ 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);
30475 ++ }
30476 ++ break;
30477 ++ default:
30478 ++ gr_log_middle(audit, msg, ap);
30479 ++ }
30480 ++ va_end(ap);
30481 ++ gr_log_end(audit);
30482 ++ END_LOCKS(audit);
30483 ++}
30484 +diff -urNp a/grsecurity/grsec_mem.c b/grsecurity/grsec_mem.c
30485 +--- a/grsecurity/grsec_mem.c 1969-12-31 16:00:00.000000000 -0800
30486 ++++ b/grsecurity/grsec_mem.c 2008-08-20 18:36:57.000000000 -0700
30487 +@@ -0,0 +1,71 @@
30488 ++#include <linux/kernel.h>
30489 ++#include <linux/sched.h>
30490 ++#include <linux/mm.h>
30491 ++#include <linux/mman.h>
30492 ++#include <linux/grinternal.h>
30493 ++
30494 ++void
30495 ++gr_handle_ioperm(void)
30496 ++{
30497 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
30498 ++ return;
30499 ++}
30500 ++
30501 ++void
30502 ++gr_handle_iopl(void)
30503 ++{
30504 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
30505 ++ return;
30506 ++}
30507 ++
30508 ++void
30509 ++gr_handle_mem_write(void)
30510 ++{
30511 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
30512 ++ return;
30513 ++}
30514 ++
30515 ++void
30516 ++gr_handle_kmem_write(void)
30517 ++{
30518 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
30519 ++ return;
30520 ++}
30521 ++
30522 ++void
30523 ++gr_handle_open_port(void)
30524 ++{
30525 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
30526 ++ return;
30527 ++}
30528 ++
30529 ++int
30530 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
30531 ++{
30532 ++ unsigned long start, end;
30533 ++
30534 ++ start = offset;
30535 ++ end = start + vma->vm_end - vma->vm_start;
30536 ++
30537 ++ if (start > end) {
30538 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
30539 ++ return -EPERM;
30540 ++ }
30541 ++
30542 ++ /* allowed ranges : ISA I/O BIOS */
30543 ++ if ((start >= __pa(high_memory))
30544 ++#ifdef CONFIG_X86
30545 ++ || (start >= 0x000a0000 && end <= 0x00100000)
30546 ++ || (start >= 0x00000000 && end <= 0x00001000)
30547 ++#endif
30548 ++ )
30549 ++ return 0;
30550 ++
30551 ++ if (vma->vm_flags & VM_WRITE) {
30552 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
30553 ++ return -EPERM;
30554 ++ } else
30555 ++ vma->vm_flags &= ~VM_MAYWRITE;
30556 ++
30557 ++ return 0;
30558 ++}
30559 +diff -urNp a/grsecurity/grsec_mount.c b/grsecurity/grsec_mount.c
30560 +--- a/grsecurity/grsec_mount.c 1969-12-31 16:00:00.000000000 -0800
30561 ++++ b/grsecurity/grsec_mount.c 2008-08-20 18:36:57.000000000 -0700
30562 +@@ -0,0 +1,34 @@
30563 ++#include <linux/kernel.h>
30564 ++#include <linux/sched.h>
30565 ++#include <linux/grsecurity.h>
30566 ++#include <linux/grinternal.h>
30567 ++
30568 ++void
30569 ++gr_log_remount(const char *devname, const int retval)
30570 ++{
30571 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30572 ++ if (grsec_enable_mount && (retval >= 0))
30573 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
30574 ++#endif
30575 ++ return;
30576 ++}
30577 ++
30578 ++void
30579 ++gr_log_unmount(const char *devname, const int retval)
30580 ++{
30581 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30582 ++ if (grsec_enable_mount && (retval >= 0))
30583 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
30584 ++#endif
30585 ++ return;
30586 ++}
30587 ++
30588 ++void
30589 ++gr_log_mount(const char *from, const char *to, const int retval)
30590 ++{
30591 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30592 ++ if (grsec_enable_mount && (retval >= 0))
30593 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
30594 ++#endif
30595 ++ return;
30596 ++}
30597 +diff -urNp a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c
30598 +--- a/grsecurity/grsec_sig.c 1969-12-31 16:00:00.000000000 -0800
30599 ++++ b/grsecurity/grsec_sig.c 2008-08-20 18:36:57.000000000 -0700
30600 +@@ -0,0 +1,58 @@
30601 ++#include <linux/kernel.h>
30602 ++#include <linux/sched.h>
30603 ++#include <linux/delay.h>
30604 ++#include <linux/grsecurity.h>
30605 ++#include <linux/grinternal.h>
30606 ++
30607 ++void
30608 ++gr_log_signal(const int sig, const struct task_struct *t)
30609 ++{
30610 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
30611 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
30612 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
30613 ++ if (t->pid == current->pid) {
30614 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
30615 ++ } else {
30616 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
30617 ++ }
30618 ++ }
30619 ++#endif
30620 ++ return;
30621 ++}
30622 ++
30623 ++int
30624 ++gr_handle_signal(const struct task_struct *p, const int sig)
30625 ++{
30626 ++#ifdef CONFIG_GRKERNSEC
30627 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
30628 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
30629 ++ return -EPERM;
30630 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
30631 ++ return -EPERM;
30632 ++ }
30633 ++#endif
30634 ++ return 0;
30635 ++}
30636 ++
30637 ++void gr_handle_brute_attach(struct task_struct *p)
30638 ++{
30639 ++#ifdef CONFIG_GRKERNSEC_BRUTE
30640 ++ read_lock(&tasklist_lock);
30641 ++ read_lock(&grsec_exec_file_lock);
30642 ++ if (p->parent && p->parent->exec_file == p->exec_file)
30643 ++ p->parent->brute = 1;
30644 ++ read_unlock(&grsec_exec_file_lock);
30645 ++ read_unlock(&tasklist_lock);
30646 ++#endif
30647 ++ return;
30648 ++}
30649 ++
30650 ++void gr_handle_brute_check(void)
30651 ++{
30652 ++#ifdef CONFIG_GRKERNSEC_BRUTE
30653 ++ if (current->brute)
30654 ++ msleep(30 * 1000);
30655 ++#endif
30656 ++ return;
30657 ++}
30658 ++
30659 +diff -urNp a/grsecurity/grsec_sock.c b/grsecurity/grsec_sock.c
30660 +--- a/grsecurity/grsec_sock.c 1969-12-31 16:00:00.000000000 -0800
30661 ++++ b/grsecurity/grsec_sock.c 2008-08-20 18:36:57.000000000 -0700
30662 +@@ -0,0 +1,274 @@
30663 ++#include <linux/kernel.h>
30664 ++#include <linux/module.h>
30665 ++#include <linux/sched.h>
30666 ++#include <linux/file.h>
30667 ++#include <linux/net.h>
30668 ++#include <linux/in.h>
30669 ++#include <linux/ip.h>
30670 ++#include <net/sock.h>
30671 ++#include <net/inet_sock.h>
30672 ++#include <linux/grsecurity.h>
30673 ++#include <linux/grinternal.h>
30674 ++#include <linux/gracl.h>
30675 ++
30676 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
30677 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
30678 ++EXPORT_SYMBOL(udp_v4_lookup);
30679 ++#endif
30680 ++
30681 ++kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
30682 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
30683 ++
30684 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
30685 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
30686 ++
30687 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
30688 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
30689 ++
30690 ++#ifdef CONFIG_UNIX_MODULE
30691 ++EXPORT_SYMBOL(gr_acl_handle_unix);
30692 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
30693 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
30694 ++EXPORT_SYMBOL(gr_handle_create);
30695 ++#endif
30696 ++
30697 ++#ifdef CONFIG_GRKERNSEC
30698 ++#define gr_conn_table_size 32749
30699 ++struct conn_table_entry {
30700 ++ struct conn_table_entry *next;
30701 ++ struct signal_struct *sig;
30702 ++};
30703 ++
30704 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
30705 ++spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
30706 ++
30707 ++extern const char * gr_socktype_to_name(unsigned char type);
30708 ++extern const char * gr_proto_to_name(unsigned char proto);
30709 ++
30710 ++static __inline__ int
30711 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
30712 ++{
30713 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
30714 ++}
30715 ++
30716 ++static __inline__ int
30717 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
30718 ++ __u16 sport, __u16 dport)
30719 ++{
30720 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
30721 ++ sig->gr_sport == sport && sig->gr_dport == dport))
30722 ++ return 1;
30723 ++ else
30724 ++ return 0;
30725 ++}
30726 ++
30727 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
30728 ++{
30729 ++ struct conn_table_entry **match;
30730 ++ unsigned int index;
30731 ++
30732 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
30733 ++ sig->gr_sport, sig->gr_dport,
30734 ++ gr_conn_table_size);
30735 ++
30736 ++ newent->sig = sig;
30737 ++
30738 ++ match = &gr_conn_table[index];
30739 ++ newent->next = *match;
30740 ++ *match = newent;
30741 ++
30742 ++ return;
30743 ++}
30744 ++
30745 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
30746 ++{
30747 ++ struct conn_table_entry *match, *last = NULL;
30748 ++ unsigned int index;
30749 ++
30750 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
30751 ++ sig->gr_sport, sig->gr_dport,
30752 ++ gr_conn_table_size);
30753 ++
30754 ++ match = gr_conn_table[index];
30755 ++ while (match && !conn_match(match->sig,
30756 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
30757 ++ sig->gr_dport)) {
30758 ++ last = match;
30759 ++ match = match->next;
30760 ++ }
30761 ++
30762 ++ if (match) {
30763 ++ if (last)
30764 ++ last->next = match->next;
30765 ++ else
30766 ++ gr_conn_table[index] = NULL;
30767 ++ kfree(match);
30768 ++ }
30769 ++
30770 ++ return;
30771 ++}
30772 ++
30773 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
30774 ++ __u16 sport, __u16 dport)
30775 ++{
30776 ++ struct conn_table_entry *match;
30777 ++ unsigned int index;
30778 ++
30779 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
30780 ++
30781 ++ match = gr_conn_table[index];
30782 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
30783 ++ match = match->next;
30784 ++
30785 ++ if (match)
30786 ++ return match->sig;
30787 ++ else
30788 ++ return NULL;
30789 ++}
30790 ++
30791 ++#endif
30792 ++
30793 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
30794 ++{
30795 ++#ifdef CONFIG_GRKERNSEC
30796 ++ struct signal_struct *sig = task->signal;
30797 ++ struct conn_table_entry *newent;
30798 ++
30799 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
30800 ++ if (newent == NULL)
30801 ++ return;
30802 ++ /* no bh lock needed since we are called with bh disabled */
30803 ++ spin_lock(&gr_conn_table_lock);
30804 ++ gr_del_task_from_ip_table_nolock(sig);
30805 ++ sig->gr_saddr = inet->rcv_saddr;
30806 ++ sig->gr_daddr = inet->daddr;
30807 ++ sig->gr_sport = inet->sport;
30808 ++ sig->gr_dport = inet->dport;
30809 ++ gr_add_to_task_ip_table_nolock(sig, newent);
30810 ++ spin_unlock(&gr_conn_table_lock);
30811 ++#endif
30812 ++ return;
30813 ++}
30814 ++
30815 ++void gr_del_task_from_ip_table(struct task_struct *task)
30816 ++{
30817 ++#ifdef CONFIG_GRKERNSEC
30818 ++ spin_lock(&gr_conn_table_lock);
30819 ++ gr_del_task_from_ip_table_nolock(task->signal);
30820 ++ spin_unlock(&gr_conn_table_lock);
30821 ++#endif
30822 ++ return;
30823 ++}
30824 ++
30825 ++void
30826 ++gr_attach_curr_ip(const struct sock *sk)
30827 ++{
30828 ++#ifdef CONFIG_GRKERNSEC
30829 ++ struct signal_struct *p, *set;
30830 ++ const struct inet_sock *inet = inet_sk(sk);
30831 ++
30832 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
30833 ++ return;
30834 ++
30835 ++ set = current->signal;
30836 ++
30837 ++ spin_lock_bh(&gr_conn_table_lock);
30838 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
30839 ++ inet->dport, inet->sport);
30840 ++ if (unlikely(p != NULL)) {
30841 ++ set->curr_ip = p->curr_ip;
30842 ++ set->used_accept = 1;
30843 ++ gr_del_task_from_ip_table_nolock(p);
30844 ++ spin_unlock_bh(&gr_conn_table_lock);
30845 ++ return;
30846 ++ }
30847 ++ spin_unlock_bh(&gr_conn_table_lock);
30848 ++
30849 ++ set->curr_ip = inet->daddr;
30850 ++ set->used_accept = 1;
30851 ++#endif
30852 ++ return;
30853 ++}
30854 ++
30855 ++int
30856 ++gr_handle_sock_all(const int family, const int type, const int protocol)
30857 ++{
30858 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
30859 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
30860 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
30861 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
30862 ++ return -EACCES;
30863 ++ }
30864 ++#endif
30865 ++ return 0;
30866 ++}
30867 ++
30868 ++int
30869 ++gr_handle_sock_server(const struct sockaddr *sck)
30870 ++{
30871 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30872 ++ if (grsec_enable_socket_server &&
30873 ++ in_group_p(grsec_socket_server_gid) &&
30874 ++ sck && (sck->sa_family != AF_UNIX) &&
30875 ++ (sck->sa_family != AF_LOCAL)) {
30876 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
30877 ++ return -EACCES;
30878 ++ }
30879 ++#endif
30880 ++ return 0;
30881 ++}
30882 ++
30883 ++int
30884 ++gr_handle_sock_server_other(const struct sock *sck)
30885 ++{
30886 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30887 ++ if (grsec_enable_socket_server &&
30888 ++ in_group_p(grsec_socket_server_gid) &&
30889 ++ sck && (sck->sk_family != AF_UNIX) &&
30890 ++ (sck->sk_family != AF_LOCAL)) {
30891 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
30892 ++ return -EACCES;
30893 ++ }
30894 ++#endif
30895 ++ return 0;
30896 ++}
30897 ++
30898 ++int
30899 ++gr_handle_sock_client(const struct sockaddr *sck)
30900 ++{
30901 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
30902 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
30903 ++ sck && (sck->sa_family != AF_UNIX) &&
30904 ++ (sck->sa_family != AF_LOCAL)) {
30905 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
30906 ++ return -EACCES;
30907 ++ }
30908 ++#endif
30909 ++ return 0;
30910 ++}
30911 ++
30912 ++kernel_cap_t
30913 ++gr_cap_rtnetlink(struct sock *sock)
30914 ++{
30915 ++#ifdef CONFIG_GRKERNSEC
30916 ++ if (!gr_acl_is_enabled())
30917 ++ return current->cap_effective;
30918 ++ else if (sock->sk_protocol == NETLINK_ISCSI &&
30919 ++ cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
30920 ++ gr_task_is_capable(current, CAP_SYS_ADMIN))
30921 ++ return current->cap_effective;
30922 ++ else if (sock->sk_protocol == NETLINK_AUDIT &&
30923 ++ cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
30924 ++ gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
30925 ++ cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
30926 ++ gr_task_is_capable(current, CAP_AUDIT_CONTROL))
30927 ++ return current->cap_effective;
30928 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
30929 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
30930 ++ return current->cap_effective;
30931 ++ else
30932 ++ return __cap_empty_set;
30933 ++#else
30934 ++ return current->cap_effective;
30935 ++#endif
30936 ++}
30937 +diff -urNp a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c
30938 +--- a/grsecurity/grsec_sysctl.c 1969-12-31 16:00:00.000000000 -0800
30939 ++++ b/grsecurity/grsec_sysctl.c 2008-08-20 18:36:57.000000000 -0700
30940 +@@ -0,0 +1,435 @@
30941 ++#include <linux/kernel.h>
30942 ++#include <linux/sched.h>
30943 ++#include <linux/sysctl.h>
30944 ++#include <linux/grsecurity.h>
30945 ++#include <linux/grinternal.h>
30946 ++
30947 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
30948 ++int grsec_modstop;
30949 ++#endif
30950 ++
30951 ++int
30952 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
30953 ++{
30954 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
30955 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
30956 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
30957 ++ return -EACCES;
30958 ++ }
30959 ++#endif
30960 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
30961 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
30962 ++ grsec_modstop && (op & 002)) {
30963 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
30964 ++ return -EACCES;
30965 ++ }
30966 ++#endif
30967 ++ return 0;
30968 ++}
30969 ++
30970 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
30971 ++ctl_table grsecurity_table[] = {
30972 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
30973 ++#ifdef CONFIG_GRKERNSEC_LINK
30974 ++ {
30975 ++ .ctl_name = CTL_UNNUMBERED,
30976 ++ .procname = "linking_restrictions",
30977 ++ .data = &grsec_enable_link,
30978 ++ .maxlen = sizeof(int),
30979 ++ .mode = 0600,
30980 ++ .proc_handler = &proc_dointvec,
30981 ++ },
30982 ++#endif
30983 ++#ifdef CONFIG_GRKERNSEC_FIFO
30984 ++ {
30985 ++ .ctl_name = CTL_UNNUMBERED,
30986 ++ .procname = "fifo_restrictions",
30987 ++ .data = &grsec_enable_fifo,
30988 ++ .maxlen = sizeof(int),
30989 ++ .mode = 0600,
30990 ++ .proc_handler = &proc_dointvec,
30991 ++ },
30992 ++#endif
30993 ++#ifdef CONFIG_GRKERNSEC_EXECVE
30994 ++ {
30995 ++ .ctl_name = CTL_UNNUMBERED,
30996 ++ .procname = "execve_limiting",
30997 ++ .data = &grsec_enable_execve,
30998 ++ .maxlen = sizeof(int),
30999 ++ .mode = 0600,
31000 ++ .proc_handler = &proc_dointvec,
31001 ++ },
31002 ++#endif
31003 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
31004 ++ {
31005 ++ .ctl_name = CTL_UNNUMBERED,
31006 ++ .procname = "exec_logging",
31007 ++ .data = &grsec_enable_execlog,
31008 ++ .maxlen = sizeof(int),
31009 ++ .mode = 0600,
31010 ++ .proc_handler = &proc_dointvec,
31011 ++ },
31012 ++#endif
31013 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
31014 ++ {
31015 ++ .ctl_name = CTL_UNNUMBERED,
31016 ++ .procname = "signal_logging",
31017 ++ .data = &grsec_enable_signal,
31018 ++ .maxlen = sizeof(int),
31019 ++ .mode = 0600,
31020 ++ .proc_handler = &proc_dointvec,
31021 ++ },
31022 ++#endif
31023 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
31024 ++ {
31025 ++ .ctl_name = CTL_UNNUMBERED,
31026 ++ .procname = "forkfail_logging",
31027 ++ .data = &grsec_enable_forkfail,
31028 ++ .maxlen = sizeof(int),
31029 ++ .mode = 0600,
31030 ++ .proc_handler = &proc_dointvec,
31031 ++ },
31032 ++#endif
31033 ++#ifdef CONFIG_GRKERNSEC_TIME
31034 ++ {
31035 ++ .ctl_name = CTL_UNNUMBERED,
31036 ++ .procname = "timechange_logging",
31037 ++ .data = &grsec_enable_time,
31038 ++ .maxlen = sizeof(int),
31039 ++ .mode = 0600,
31040 ++ .proc_handler = &proc_dointvec,
31041 ++ },
31042 ++#endif
31043 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
31044 ++ {
31045 ++ .ctl_name = CTL_UNNUMBERED,
31046 ++ .procname = "chroot_deny_shmat",
31047 ++ .data = &grsec_enable_chroot_shmat,
31048 ++ .maxlen = sizeof(int),
31049 ++ .mode = 0600,
31050 ++ .proc_handler = &proc_dointvec,
31051 ++ },
31052 ++#endif
31053 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
31054 ++ {
31055 ++ .ctl_name = CTL_UNNUMBERED,
31056 ++ .procname = "chroot_deny_unix",
31057 ++ .data = &grsec_enable_chroot_unix,
31058 ++ .maxlen = sizeof(int),
31059 ++ .mode = 0600,
31060 ++ .proc_handler = &proc_dointvec,
31061 ++ },
31062 ++#endif
31063 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
31064 ++ {
31065 ++ .ctl_name = CTL_UNNUMBERED,
31066 ++ .procname = "chroot_deny_mount",
31067 ++ .data = &grsec_enable_chroot_mount,
31068 ++ .maxlen = sizeof(int),
31069 ++ .mode = 0600,
31070 ++ .proc_handler = &proc_dointvec,
31071 ++ },
31072 ++#endif
31073 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
31074 ++ {
31075 ++ .ctl_name = CTL_UNNUMBERED,
31076 ++ .procname = "chroot_deny_fchdir",
31077 ++ .data = &grsec_enable_chroot_fchdir,
31078 ++ .maxlen = sizeof(int),
31079 ++ .mode = 0600,
31080 ++ .proc_handler = &proc_dointvec,
31081 ++ },
31082 ++#endif
31083 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
31084 ++ {
31085 ++ .ctl_name = CTL_UNNUMBERED,
31086 ++ .procname = "chroot_deny_chroot",
31087 ++ .data = &grsec_enable_chroot_double,
31088 ++ .maxlen = sizeof(int),
31089 ++ .mode = 0600,
31090 ++ .proc_handler = &proc_dointvec,
31091 ++ },
31092 ++#endif
31093 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
31094 ++ {
31095 ++ .ctl_name = CTL_UNNUMBERED,
31096 ++ .procname = "chroot_deny_pivot",
31097 ++ .data = &grsec_enable_chroot_pivot,
31098 ++ .maxlen = sizeof(int),
31099 ++ .mode = 0600,
31100 ++ .proc_handler = &proc_dointvec,
31101 ++ },
31102 ++#endif
31103 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
31104 ++ {
31105 ++ .ctl_name = CTL_UNNUMBERED,
31106 ++ .procname = "chroot_enforce_chdir",
31107 ++ .data = &grsec_enable_chroot_chdir,
31108 ++ .maxlen = sizeof(int),
31109 ++ .mode = 0600,
31110 ++ .proc_handler = &proc_dointvec,
31111 ++ },
31112 ++#endif
31113 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
31114 ++ {
31115 ++ .ctl_name = CTL_UNNUMBERED,
31116 ++ .procname = "chroot_deny_chmod",
31117 ++ .data = &grsec_enable_chroot_chmod,
31118 ++ .maxlen = sizeof(int),
31119 ++ .mode = 0600,
31120 ++ .proc_handler = &proc_dointvec,
31121 ++ },
31122 ++#endif
31123 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
31124 ++ {
31125 ++ .ctl_name = CTL_UNNUMBERED,
31126 ++ .procname = "chroot_deny_mknod",
31127 ++ .data = &grsec_enable_chroot_mknod,
31128 ++ .maxlen = sizeof(int),
31129 ++ .mode = 0600,
31130 ++ .proc_handler = &proc_dointvec,
31131 ++ },
31132 ++#endif
31133 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
31134 ++ {
31135 ++ .ctl_name = CTL_UNNUMBERED,
31136 ++ .procname = "chroot_restrict_nice",
31137 ++ .data = &grsec_enable_chroot_nice,
31138 ++ .maxlen = sizeof(int),
31139 ++ .mode = 0600,
31140 ++ .proc_handler = &proc_dointvec,
31141 ++ },
31142 ++#endif
31143 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
31144 ++ {
31145 ++ .ctl_name = CTL_UNNUMBERED,
31146 ++ .procname = "chroot_execlog",
31147 ++ .data = &grsec_enable_chroot_execlog,
31148 ++ .maxlen = sizeof(int),
31149 ++ .mode = 0600,
31150 ++ .proc_handler = &proc_dointvec,
31151 ++ },
31152 ++#endif
31153 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
31154 ++ {
31155 ++ .ctl_name = CTL_UNNUMBERED,
31156 ++ .procname = "chroot_caps",
31157 ++ .data = &grsec_enable_chroot_caps,
31158 ++ .maxlen = sizeof(int),
31159 ++ .mode = 0600,
31160 ++ .proc_handler = &proc_dointvec,
31161 ++ },
31162 ++#endif
31163 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
31164 ++ {
31165 ++ .ctl_name = CTL_UNNUMBERED,
31166 ++ .procname = "chroot_deny_sysctl",
31167 ++ .data = &grsec_enable_chroot_sysctl,
31168 ++ .maxlen = sizeof(int),
31169 ++ .mode = 0600,
31170 ++ .proc_handler = &proc_dointvec,
31171 ++ },
31172 ++#endif
31173 ++#ifdef CONFIG_GRKERNSEC_TPE
31174 ++ {
31175 ++ .ctl_name = CTL_UNNUMBERED,
31176 ++ .procname = "tpe",
31177 ++ .data = &grsec_enable_tpe,
31178 ++ .maxlen = sizeof(int),
31179 ++ .mode = 0600,
31180 ++ .proc_handler = &proc_dointvec,
31181 ++ },
31182 ++ {
31183 ++ .ctl_name = CTL_UNNUMBERED,
31184 ++ .procname = "tpe_gid",
31185 ++ .data = &grsec_tpe_gid,
31186 ++ .maxlen = sizeof(int),
31187 ++ .mode = 0600,
31188 ++ .proc_handler = &proc_dointvec,
31189 ++ },
31190 ++#endif
31191 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
31192 ++ {
31193 ++ .ctl_name = CTL_UNNUMBERED,
31194 ++ .procname = "tpe_restrict_all",
31195 ++ .data = &grsec_enable_tpe_all,
31196 ++ .maxlen = sizeof(int),
31197 ++ .mode = 0600,
31198 ++ .proc_handler = &proc_dointvec,
31199 ++ },
31200 ++#endif
31201 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
31202 ++ {
31203 ++ .ctl_name = CTL_UNNUMBERED,
31204 ++ .procname = "socket_all",
31205 ++ .data = &grsec_enable_socket_all,
31206 ++ .maxlen = sizeof(int),
31207 ++ .mode = 0600,
31208 ++ .proc_handler = &proc_dointvec,
31209 ++ },
31210 ++ {
31211 ++ .ctl_name = CTL_UNNUMBERED,
31212 ++ .procname = "socket_all_gid",
31213 ++ .data = &grsec_socket_all_gid,
31214 ++ .maxlen = sizeof(int),
31215 ++ .mode = 0600,
31216 ++ .proc_handler = &proc_dointvec,
31217 ++ },
31218 ++#endif
31219 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
31220 ++ {
31221 ++ .ctl_name = CTL_UNNUMBERED,
31222 ++ .procname = "socket_client",
31223 ++ .data = &grsec_enable_socket_client,
31224 ++ .maxlen = sizeof(int),
31225 ++ .mode = 0600,
31226 ++ .proc_handler = &proc_dointvec,
31227 ++ },
31228 ++ {
31229 ++ .ctl_name = CTL_UNNUMBERED,
31230 ++ .procname = "socket_client_gid",
31231 ++ .data = &grsec_socket_client_gid,
31232 ++ .maxlen = sizeof(int),
31233 ++ .mode = 0600,
31234 ++ .proc_handler = &proc_dointvec,
31235 ++ },
31236 ++#endif
31237 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
31238 ++ {
31239 ++ .ctl_name = CTL_UNNUMBERED,
31240 ++ .procname = "socket_server",
31241 ++ .data = &grsec_enable_socket_server,
31242 ++ .maxlen = sizeof(int),
31243 ++ .mode = 0600,
31244 ++ .proc_handler = &proc_dointvec,
31245 ++ },
31246 ++ {
31247 ++ .ctl_name = CTL_UNNUMBERED,
31248 ++ .procname = "socket_server_gid",
31249 ++ .data = &grsec_socket_server_gid,
31250 ++ .maxlen = sizeof(int),
31251 ++ .mode = 0600,
31252 ++ .proc_handler = &proc_dointvec,
31253 ++ },
31254 ++#endif
31255 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
31256 ++ {
31257 ++ .ctl_name = CTL_UNNUMBERED,
31258 ++ .procname = "audit_group",
31259 ++ .data = &grsec_enable_group,
31260 ++ .maxlen = sizeof(int),
31261 ++ .mode = 0600,
31262 ++ .proc_handler = &proc_dointvec,
31263 ++ },
31264 ++ {
31265 ++ .ctl_name = CTL_UNNUMBERED,
31266 ++ .procname = "audit_gid",
31267 ++ .data = &grsec_audit_gid,
31268 ++ .maxlen = sizeof(int),
31269 ++ .mode = 0600,
31270 ++ .proc_handler = &proc_dointvec,
31271 ++ },
31272 ++#endif
31273 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
31274 ++ {
31275 ++ .ctl_name = CTL_UNNUMBERED,
31276 ++ .procname = "audit_chdir",
31277 ++ .data = &grsec_enable_chdir,
31278 ++ .maxlen = sizeof(int),
31279 ++ .mode = 0600,
31280 ++ .proc_handler = &proc_dointvec,
31281 ++ },
31282 ++#endif
31283 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
31284 ++ {
31285 ++ .ctl_name = CTL_UNNUMBERED,
31286 ++ .procname = "audit_mount",
31287 ++ .data = &grsec_enable_mount,
31288 ++ .maxlen = sizeof(int),
31289 ++ .mode = 0600,
31290 ++ .proc_handler = &proc_dointvec,
31291 ++ },
31292 ++#endif
31293 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
31294 ++ {
31295 ++ .ctl_name = CTL_UNNUMBERED,
31296 ++ .procname = "audit_ipc",
31297 ++ .data = &grsec_enable_audit_ipc,
31298 ++ .maxlen = sizeof(int),
31299 ++ .mode = 0600,
31300 ++ .proc_handler = &proc_dointvec,
31301 ++ },
31302 ++#endif
31303 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31304 ++ {
31305 ++ .ctl_name = CTL_UNNUMBERED,
31306 ++ .procname = "audit_textrel",
31307 ++ .data = &grsec_enable_audit_textrel,
31308 ++ .maxlen = sizeof(int),
31309 ++ .mode = 0600,
31310 ++ .proc_handler = &proc_dointvec,
31311 ++ },
31312 ++#endif
31313 ++#ifdef CONFIG_GRKERNSEC_DMESG
31314 ++ {
31315 ++ .ctl_name = CTL_UNNUMBERED,
31316 ++ .procname = "dmesg",
31317 ++ .data = &grsec_enable_dmesg,
31318 ++ .maxlen = sizeof(int),
31319 ++ .mode = 0600,
31320 ++ .proc_handler = &proc_dointvec,
31321 ++ },
31322 ++#endif
31323 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
31324 ++ {
31325 ++ .ctl_name = CTL_UNNUMBERED,
31326 ++ .procname = "chroot_findtask",
31327 ++ .data = &grsec_enable_chroot_findtask,
31328 ++ .maxlen = sizeof(int),
31329 ++ .mode = 0600,
31330 ++ .proc_handler = &proc_dointvec,
31331 ++ },
31332 ++#endif
31333 ++#ifdef CONFIG_GRKERNSEC_RESLOG
31334 ++ {
31335 ++ .ctl_name = CTL_UNNUMBERED,
31336 ++ .procname = "resource_logging",
31337 ++ .data = &grsec_resource_logging,
31338 ++ .maxlen = sizeof(int),
31339 ++ .mode = 0600,
31340 ++ .proc_handler = &proc_dointvec,
31341 ++ },
31342 ++#endif
31343 ++ {
31344 ++ .ctl_name = CTL_UNNUMBERED,
31345 ++ .procname = "grsec_lock",
31346 ++ .data = &grsec_lock,
31347 ++ .maxlen = sizeof(int),
31348 ++ .mode = 0600,
31349 ++ .proc_handler = &proc_dointvec,
31350 ++ },
31351 ++#endif
31352 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31353 ++ {
31354 ++ .ctl_name = CTL_UNNUMBERED,
31355 ++ .procname = "disable_modules",
31356 ++ .data = &grsec_modstop,
31357 ++ .maxlen = sizeof(int),
31358 ++ .mode = 0600,
31359 ++ .proc_handler = &proc_dointvec,
31360 ++ },
31361 ++#endif
31362 ++ { .ctl_name = 0 }
31363 ++};
31364 ++#endif
31365 ++
31366 ++int gr_check_modstop(void)
31367 ++{
31368 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31369 ++ if (grsec_modstop == 1) {
31370 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
31371 ++ return 1;
31372 ++ }
31373 ++#endif
31374 ++ return 0;
31375 ++}
31376 +diff -urNp a/grsecurity/grsec_textrel.c b/grsecurity/grsec_textrel.c
31377 +--- a/grsecurity/grsec_textrel.c 1969-12-31 16:00:00.000000000 -0800
31378 ++++ b/grsecurity/grsec_textrel.c 2008-08-20 18:36:57.000000000 -0700
31379 +@@ -0,0 +1,16 @@
31380 ++#include <linux/kernel.h>
31381 ++#include <linux/sched.h>
31382 ++#include <linux/mm.h>
31383 ++#include <linux/file.h>
31384 ++#include <linux/grinternal.h>
31385 ++#include <linux/grsecurity.h>
31386 ++
31387 ++void
31388 ++gr_log_textrel(struct vm_area_struct * vma)
31389 ++{
31390 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31391 ++ if (grsec_enable_audit_textrel)
31392 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
31393 ++#endif
31394 ++ return;
31395 ++}
31396 +diff -urNp a/grsecurity/grsec_time.c b/grsecurity/grsec_time.c
31397 +--- a/grsecurity/grsec_time.c 1969-12-31 16:00:00.000000000 -0800
31398 ++++ b/grsecurity/grsec_time.c 2008-08-20 18:36:57.000000000 -0700
31399 +@@ -0,0 +1,13 @@
31400 ++#include <linux/kernel.h>
31401 ++#include <linux/sched.h>
31402 ++#include <linux/grinternal.h>
31403 ++
31404 ++void
31405 ++gr_log_timechange(void)
31406 ++{
31407 ++#ifdef CONFIG_GRKERNSEC_TIME
31408 ++ if (grsec_enable_time)
31409 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
31410 ++#endif
31411 ++ return;
31412 ++}
31413 +diff -urNp a/grsecurity/grsec_tpe.c b/grsecurity/grsec_tpe.c
31414 +--- a/grsecurity/grsec_tpe.c 1969-12-31 16:00:00.000000000 -0800
31415 ++++ b/grsecurity/grsec_tpe.c 2008-08-20 18:36:57.000000000 -0700
31416 +@@ -0,0 +1,37 @@
31417 ++#include <linux/kernel.h>
31418 ++#include <linux/sched.h>
31419 ++#include <linux/file.h>
31420 ++#include <linux/fs.h>
31421 ++#include <linux/grinternal.h>
31422 ++
31423 ++extern int gr_acl_tpe_check(void);
31424 ++
31425 ++int
31426 ++gr_tpe_allow(const struct file *file)
31427 ++{
31428 ++#ifdef CONFIG_GRKERNSEC
31429 ++ struct inode *inode = file->f_path.dentry->d_parent->d_inode;
31430 ++
31431 ++ if (current->uid && ((grsec_enable_tpe &&
31432 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
31433 ++ !in_group_p(grsec_tpe_gid)
31434 ++#else
31435 ++ in_group_p(grsec_tpe_gid)
31436 ++#endif
31437 ++ ) || gr_acl_tpe_check()) &&
31438 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
31439 ++ (inode->i_mode & S_IWOTH))))) {
31440 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
31441 ++ return 0;
31442 ++ }
31443 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
31444 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
31445 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
31446 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
31447 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
31448 ++ return 0;
31449 ++ }
31450 ++#endif
31451 ++#endif
31452 ++ return 1;
31453 ++}
31454 +diff -urNp a/grsecurity/grsum.c b/grsecurity/grsum.c
31455 +--- a/grsecurity/grsum.c 1969-12-31 16:00:00.000000000 -0800
31456 ++++ b/grsecurity/grsum.c 2008-08-20 18:36:57.000000000 -0700
31457 +@@ -0,0 +1,59 @@
31458 ++#include <linux/err.h>
31459 ++#include <linux/kernel.h>
31460 ++#include <linux/sched.h>
31461 ++#include <linux/mm.h>
31462 ++#include <linux/scatterlist.h>
31463 ++#include <linux/crypto.h>
31464 ++#include <linux/gracl.h>
31465 ++
31466 ++
31467 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
31468 ++#error "crypto and sha256 must be built into the kernel"
31469 ++#endif
31470 ++
31471 ++int
31472 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
31473 ++{
31474 ++ char *p;
31475 ++ struct crypto_hash *tfm;
31476 ++ struct hash_desc desc;
31477 ++ struct scatterlist sg;
31478 ++ unsigned char temp_sum[GR_SHA_LEN];
31479 ++ volatile int retval = 0;
31480 ++ volatile int dummy = 0;
31481 ++ unsigned int i;
31482 ++
31483 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
31484 ++ if (IS_ERR(tfm)) {
31485 ++ /* should never happen, since sha256 should be built in */
31486 ++ return 1;
31487 ++ }
31488 ++
31489 ++ desc.tfm = tfm;
31490 ++ desc.flags = 0;
31491 ++
31492 ++ crypto_hash_init(&desc);
31493 ++
31494 ++ p = salt;
31495 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
31496 ++ crypto_hash_update(&desc, &sg, sg.length);
31497 ++
31498 ++ p = entry->pw;
31499 ++ sg_set_buf(&sg, p, strlen(p));
31500 ++
31501 ++ crypto_hash_update(&desc, &sg, sg.length);
31502 ++
31503 ++ crypto_hash_final(&desc, temp_sum);
31504 ++
31505 ++ memset(entry->pw, 0, GR_PW_LEN);
31506 ++
31507 ++ for (i = 0; i < GR_SHA_LEN; i++)
31508 ++ if (sum[i] != temp_sum[i])
31509 ++ retval = 1;
31510 ++ else
31511 ++ dummy = 1; // waste a cycle
31512 ++
31513 ++ crypto_free_hash(tfm);
31514 ++
31515 ++ return retval;
31516 ++}
31517 +diff -urNp a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
31518 +--- a/include/asm-alpha/elf.h 2008-08-20 11:16:13.000000000 -0700
31519 ++++ b/include/asm-alpha/elf.h 2008-08-20 18:36:57.000000000 -0700
31520 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
31521 +
31522 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
31523 +
31524 ++#ifdef CONFIG_PAX_ASLR
31525 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
31526 ++
31527 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
31528 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
31529 ++#endif
31530 ++
31531 + /* $0 is set by ld.so to a pointer to a function which might be
31532 + registered using atexit. This provides a mean for the dynamic
31533 + linker to call DT_FINI functions for shared libraries that have
31534 +diff -urNp a/include/asm-alpha/kmap_types.h b/include/asm-alpha/kmap_types.h
31535 +--- a/include/asm-alpha/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31536 ++++ b/include/asm-alpha/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31537 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
31538 + D(10) KM_IRQ1,
31539 + D(11) KM_SOFTIRQ0,
31540 + D(12) KM_SOFTIRQ1,
31541 +-D(13) KM_TYPE_NR
31542 ++D(13) KM_CLEARPAGE,
31543 ++D(14) KM_TYPE_NR
31544 + };
31545 +
31546 + #undef D
31547 +diff -urNp a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
31548 +--- a/include/asm-alpha/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31549 ++++ b/include/asm-alpha/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31550 +@@ -101,6 +101,17 @@ struct vm_area_struct;
31551 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
31552 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
31553 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
31554 ++
31555 ++#ifdef CONFIG_PAX_PAGEEXEC
31556 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
31557 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
31558 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
31559 ++#else
31560 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31561 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31562 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31563 ++#endif
31564 ++
31565 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
31566 +
31567 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
31568 +diff -urNp a/include/asm-arm/elf.h b/include/asm-arm/elf.h
31569 +--- a/include/asm-arm/elf.h 2008-08-20 11:16:13.000000000 -0700
31570 ++++ b/include/asm-arm/elf.h 2008-08-20 18:36:57.000000000 -0700
31571 +@@ -87,7 +87,14 @@ extern char elf_platform[];
31572 + the loader. We need to make sure that it is out of the way of the program
31573 + that it will "exec", and that there is sufficient room for the brk. */
31574 +
31575 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
31576 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31577 ++
31578 ++#ifdef CONFIG_PAX_ASLR
31579 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
31580 ++
31581 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
31582 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
31583 ++#endif
31584 +
31585 + /* When the program starts, a1 contains a pointer to a function to be
31586 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
31587 +diff -urNp a/include/asm-arm/kmap_types.h b/include/asm-arm/kmap_types.h
31588 +--- a/include/asm-arm/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31589 ++++ b/include/asm-arm/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31590 +@@ -18,6 +18,7 @@ enum km_type {
31591 + KM_IRQ1,
31592 + KM_SOFTIRQ0,
31593 + KM_SOFTIRQ1,
31594 ++ KM_CLEARPAGE,
31595 + KM_TYPE_NR
31596 + };
31597 +
31598 +diff -urNp a/include/asm-avr32/elf.h b/include/asm-avr32/elf.h
31599 +--- a/include/asm-avr32/elf.h 2008-08-20 11:16:13.000000000 -0700
31600 ++++ b/include/asm-avr32/elf.h 2008-08-20 18:36:57.000000000 -0700
31601 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
31602 + the loader. We need to make sure that it is out of the way of the program
31603 + that it will "exec", and that there is sufficient room for the brk. */
31604 +
31605 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
31606 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31607 +
31608 ++#ifdef CONFIG_PAX_ASLR
31609 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
31610 ++
31611 ++#define PAX_DELTA_MMAP_LEN 15
31612 ++#define PAX_DELTA_STACK_LEN 15
31613 ++#endif
31614 +
31615 + /* This yields a mask that user programs can use to figure out what
31616 + instruction set this CPU supports. This could be done in user space,
31617 +diff -urNp a/include/asm-avr32/kmap_types.h b/include/asm-avr32/kmap_types.h
31618 +--- a/include/asm-avr32/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31619 ++++ b/include/asm-avr32/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31620 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
31621 + D(11) KM_IRQ1,
31622 + D(12) KM_SOFTIRQ0,
31623 + D(13) KM_SOFTIRQ1,
31624 +-D(14) KM_TYPE_NR
31625 ++D(14) KM_CLEARPAGE,
31626 ++D(15) KM_TYPE_NR
31627 + };
31628 +
31629 + #undef D
31630 +diff -urNp a/include/asm-blackfin/kmap_types.h b/include/asm-blackfin/kmap_types.h
31631 +--- a/include/asm-blackfin/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31632 ++++ b/include/asm-blackfin/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31633 +@@ -15,6 +15,7 @@ enum km_type {
31634 + KM_IRQ1,
31635 + KM_SOFTIRQ0,
31636 + KM_SOFTIRQ1,
31637 ++ KM_CLEARPAGE,
31638 + KM_TYPE_NR
31639 + };
31640 +
31641 +diff -urNp a/include/asm-cris/kmap_types.h b/include/asm-cris/kmap_types.h
31642 +--- a/include/asm-cris/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31643 ++++ b/include/asm-cris/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31644 +@@ -19,6 +19,7 @@ enum km_type {
31645 + KM_IRQ1,
31646 + KM_SOFTIRQ0,
31647 + KM_SOFTIRQ1,
31648 ++ KM_CLEARPAGE,
31649 + KM_TYPE_NR
31650 + };
31651 +
31652 +diff -urNp a/include/asm-frv/kmap_types.h b/include/asm-frv/kmap_types.h
31653 +--- a/include/asm-frv/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31654 ++++ b/include/asm-frv/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31655 +@@ -23,6 +23,7 @@ enum km_type {
31656 + KM_IRQ1,
31657 + KM_SOFTIRQ0,
31658 + KM_SOFTIRQ1,
31659 ++ KM_CLEARPAGE,
31660 + KM_TYPE_NR
31661 + };
31662 +
31663 +diff -urNp a/include/asm-generic/futex.h b/include/asm-generic/futex.h
31664 +--- a/include/asm-generic/futex.h 2008-08-20 11:16:13.000000000 -0700
31665 ++++ b/include/asm-generic/futex.h 2008-08-20 18:36:57.000000000 -0700
31666 +@@ -8,7 +8,7 @@
31667 + #include <asm/uaccess.h>
31668 +
31669 + static inline int
31670 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
31671 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
31672 + {
31673 + int op = (encoded_op >> 28) & 7;
31674 + int cmp = (encoded_op >> 24) & 15;
31675 +@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
31676 + }
31677 +
31678 + static inline int
31679 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
31680 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
31681 + {
31682 + return -ENOSYS;
31683 + }
31684 +diff -urNp a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
31685 +--- a/include/asm-generic/vmlinux.lds.h 2008-08-20 11:16:13.000000000 -0700
31686 ++++ b/include/asm-generic/vmlinux.lds.h 2008-08-20 18:36:57.000000000 -0700
31687 +@@ -59,6 +59,7 @@
31688 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
31689 + VMLINUX_SYMBOL(__start_rodata) = .; \
31690 + *(.rodata) *(.rodata.*) \
31691 ++ *(.data.read_only) \
31692 + *(__vermagic) /* Kernel version magic */ \
31693 + *(__markers_strings) /* Markers: strings */ \
31694 + } \
31695 +diff -urNp a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h
31696 +--- a/include/asm-h8300/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31697 ++++ b/include/asm-h8300/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31698 +@@ -15,6 +15,7 @@ enum km_type {
31699 + KM_IRQ1,
31700 + KM_SOFTIRQ0,
31701 + KM_SOFTIRQ1,
31702 ++ KM_CLEARPAGE,
31703 + KM_TYPE_NR
31704 + };
31705 +
31706 +diff -urNp a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
31707 +--- a/include/asm-ia64/elf.h 2008-08-20 11:16:13.000000000 -0700
31708 ++++ b/include/asm-ia64/elf.h 2008-08-20 18:36:57.000000000 -0700
31709 +@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
31710 + typedef struct ia64_fpreg elf_fpreg_t;
31711 + typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
31712 +
31713 ++#ifdef CONFIG_PAX_ASLR
31714 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
31715 +
31716 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
31717 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
31718 ++#endif
31719 +
31720 + struct pt_regs; /* forward declaration... */
31721 + extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
31722 +diff -urNp a/include/asm-ia64/kmap_types.h b/include/asm-ia64/kmap_types.h
31723 +--- a/include/asm-ia64/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31724 ++++ b/include/asm-ia64/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31725 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
31726 + D(10) KM_IRQ1,
31727 + D(11) KM_SOFTIRQ0,
31728 + D(12) KM_SOFTIRQ1,
31729 +-D(13) KM_TYPE_NR
31730 ++D(13) KM_CLEARPAGE,
31731 ++D(14) KM_TYPE_NR
31732 + };
31733 +
31734 + #undef D
31735 +diff -urNp a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
31736 +--- a/include/asm-ia64/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31737 ++++ b/include/asm-ia64/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31738 +@@ -143,6 +143,17 @@
31739 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31740 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31741 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
31742 ++
31743 ++#ifdef CONFIG_PAX_PAGEEXEC
31744 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
31745 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31746 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
31747 ++#else
31748 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31749 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31750 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31751 ++#endif
31752 ++
31753 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
31754 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
31755 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
31756 +diff -urNp a/include/asm-m32r/kmap_types.h b/include/asm-m32r/kmap_types.h
31757 +--- a/include/asm-m32r/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31758 ++++ b/include/asm-m32r/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31759 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
31760 + D(10) KM_IRQ1,
31761 + D(11) KM_SOFTIRQ0,
31762 + D(12) KM_SOFTIRQ1,
31763 +-D(13) KM_TYPE_NR
31764 ++D(13) KM_CLEARPAGE,
31765 ++D(14) KM_TYPE_NR
31766 + };
31767 +
31768 + #undef D
31769 +diff -urNp a/include/asm-m68k/kmap_types.h b/include/asm-m68k/kmap_types.h
31770 +--- a/include/asm-m68k/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31771 ++++ b/include/asm-m68k/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31772 +@@ -15,6 +15,7 @@ enum km_type {
31773 + KM_IRQ1,
31774 + KM_SOFTIRQ0,
31775 + KM_SOFTIRQ1,
31776 ++ KM_CLEARPAGE,
31777 + KM_TYPE_NR
31778 + };
31779 +
31780 +diff -urNp a/include/asm-m68knommu/kmap_types.h b/include/asm-m68knommu/kmap_types.h
31781 +--- a/include/asm-m68knommu/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31782 ++++ b/include/asm-m68knommu/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31783 +@@ -15,6 +15,7 @@ enum km_type {
31784 + KM_IRQ1,
31785 + KM_SOFTIRQ0,
31786 + KM_SOFTIRQ1,
31787 ++ KM_CLEARPAGE,
31788 + KM_TYPE_NR
31789 + };
31790 +
31791 +diff -urNp a/include/asm-mips/elf.h b/include/asm-mips/elf.h
31792 +--- a/include/asm-mips/elf.h 2008-08-20 11:16:13.000000000 -0700
31793 ++++ b/include/asm-mips/elf.h 2008-08-20 18:36:57.000000000 -0700
31794 +@@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
31795 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31796 + #endif
31797 +
31798 ++#ifdef CONFIG_PAX_ASLR
31799 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
31800 ++
31801 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
31802 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
31803 ++#endif
31804 ++
31805 + #endif /* _ASM_ELF_H */
31806 +diff -urNp a/include/asm-mips/kmap_types.h b/include/asm-mips/kmap_types.h
31807 +--- a/include/asm-mips/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31808 ++++ b/include/asm-mips/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31809 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
31810 + D(10) KM_IRQ1,
31811 + D(11) KM_SOFTIRQ0,
31812 + D(12) KM_SOFTIRQ1,
31813 +-D(13) KM_TYPE_NR
31814 ++D(13) KM_CLEARPAGE,
31815 ++D(14) KM_TYPE_NR
31816 + };
31817 +
31818 + #undef D
31819 +diff -urNp a/include/asm-mips/page.h b/include/asm-mips/page.h
31820 +--- a/include/asm-mips/page.h 2008-08-20 11:16:13.000000000 -0700
31821 ++++ b/include/asm-mips/page.h 2008-08-20 18:36:57.000000000 -0700
31822 +@@ -79,7 +79,7 @@ extern void copy_user_highpage(struct pa
31823 + #ifdef CONFIG_CPU_MIPS32
31824 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
31825 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
31826 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
31827 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
31828 + #else
31829 + typedef struct { unsigned long long pte; } pte_t;
31830 + #define pte_val(x) ((x).pte)
31831 +diff -urNp a/include/asm-mips/system.h b/include/asm-mips/system.h
31832 +--- a/include/asm-mips/system.h 2008-08-20 11:16:13.000000000 -0700
31833 ++++ b/include/asm-mips/system.h 2008-08-20 18:36:57.000000000 -0700
31834 +@@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
31835 + */
31836 + #define __ARCH_WANT_UNLOCKED_CTXSW
31837 +
31838 +-extern unsigned long arch_align_stack(unsigned long sp);
31839 ++#define arch_align_stack(x) (x)
31840 +
31841 + #endif /* _ASM_SYSTEM_H */
31842 +diff -urNp a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h
31843 +--- a/include/asm-parisc/elf.h 2008-08-20 11:16:13.000000000 -0700
31844 ++++ b/include/asm-parisc/elf.h 2008-08-20 18:36:57.000000000 -0700
31845 +@@ -333,6 +333,13 @@ struct pt_regs; /* forward declaration..
31846 +
31847 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
31848 +
31849 ++#ifdef CONFIG_PAX_ASLR
31850 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
31851 ++
31852 ++#define PAX_DELTA_MMAP_LEN 16
31853 ++#define PAX_DELTA_STACK_LEN 16
31854 ++#endif
31855 ++
31856 + /* This yields a mask that user programs can use to figure out what
31857 + instruction set this CPU supports. This could be done in user space,
31858 + but it's not easy, and we've already done it here. */
31859 +diff -urNp a/include/asm-parisc/kmap_types.h b/include/asm-parisc/kmap_types.h
31860 +--- a/include/asm-parisc/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31861 ++++ b/include/asm-parisc/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31862 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
31863 + D(10) KM_IRQ1,
31864 + D(11) KM_SOFTIRQ0,
31865 + D(12) KM_SOFTIRQ1,
31866 +-D(13) KM_TYPE_NR
31867 ++D(13) KM_CLEARPAGE,
31868 ++D(14) KM_TYPE_NR
31869 + };
31870 +
31871 + #undef D
31872 +diff -urNp a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
31873 +--- a/include/asm-parisc/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31874 ++++ b/include/asm-parisc/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31875 +@@ -202,6 +202,17 @@
31876 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
31877 + #define PAGE_COPY PAGE_EXECREAD
31878 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
31879 ++
31880 ++#ifdef CONFIG_PAX_PAGEEXEC
31881 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
31882 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
31883 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
31884 ++#else
31885 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31886 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31887 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31888 ++#endif
31889 ++
31890 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
31891 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
31892 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
31893 +diff -urNp a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
31894 +--- a/include/asm-powerpc/elf.h 2008-08-20 11:16:13.000000000 -0700
31895 ++++ b/include/asm-powerpc/elf.h 2008-08-20 18:36:57.000000000 -0700
31896 +@@ -160,6 +160,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
31897 + typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
31898 + #endif
31899 +
31900 ++#ifdef CONFIG_PAX_ASLR
31901 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
31902 ++
31903 ++#ifdef __powerpc64__
31904 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
31905 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
31906 ++#else
31907 ++#define PAX_DELTA_MMAP_LEN 15
31908 ++#define PAX_DELTA_STACK_LEN 15
31909 ++#endif
31910 ++#endif
31911 ++
31912 + #ifdef __KERNEL__
31913 + /*
31914 + * This is used to ensure we don't load something for the wrong architecture.
31915 +diff -urNp a/include/asm-powerpc/kmap_types.h b/include/asm-powerpc/kmap_types.h
31916 +--- a/include/asm-powerpc/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
31917 ++++ b/include/asm-powerpc/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
31918 +@@ -26,6 +26,7 @@ enum km_type {
31919 + KM_SOFTIRQ1,
31920 + KM_PPC_SYNC_PAGE,
31921 + KM_PPC_SYNC_ICACHE,
31922 ++ KM_CLEARPAGE,
31923 + KM_TYPE_NR
31924 + };
31925 +
31926 +diff -urNp a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h
31927 +--- a/include/asm-powerpc/page.h 2008-08-20 11:16:13.000000000 -0700
31928 ++++ b/include/asm-powerpc/page.h 2008-08-20 18:36:57.000000000 -0700
31929 +@@ -70,8 +70,9 @@
31930 + * and needs to be executable. This means the whole heap ends
31931 + * up being executable.
31932 + */
31933 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
31934 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31935 ++#define VM_DATA_DEFAULT_FLAGS32 \
31936 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
31937 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31938 +
31939 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
31940 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31941 +diff -urNp a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h
31942 +--- a/include/asm-powerpc/page_64.h 2008-08-20 11:16:13.000000000 -0700
31943 ++++ b/include/asm-powerpc/page_64.h 2008-08-20 18:36:57.000000000 -0700
31944 +@@ -170,15 +170,18 @@ do { \
31945 + * stack by default, so in the absense of a PT_GNU_STACK program header
31946 + * we turn execute permission off.
31947 + */
31948 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
31949 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31950 ++#define VM_STACK_DEFAULT_FLAGS32 \
31951 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
31952 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31953 +
31954 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
31955 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
31956 +
31957 ++#ifndef CONFIG_PAX_PAGEEXEC
31958 + #define VM_STACK_DEFAULT_FLAGS \
31959 + (test_thread_flag(TIF_32BIT) ? \
31960 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
31961 ++#endif
31962 +
31963 + #include <asm-generic/page.h>
31964 +
31965 +diff -urNp a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
31966 +--- a/include/asm-ppc/mmu_context.h 2008-08-20 11:16:13.000000000 -0700
31967 ++++ b/include/asm-ppc/mmu_context.h 2008-08-20 18:36:57.000000000 -0700
31968 +@@ -141,7 +141,8 @@ static inline void get_mmu_context(struc
31969 + static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
31970 + {
31971 + mm->context.id = NO_CONTEXT;
31972 +- mm->context.vdso_base = 0;
31973 ++ if (t == current)
31974 ++ mm->context.vdso_base = ~0UL;
31975 + return 0;
31976 + }
31977 +
31978 +diff -urNp a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h
31979 +--- a/include/asm-ppc/pgtable.h 2008-08-20 11:16:13.000000000 -0700
31980 ++++ b/include/asm-ppc/pgtable.h 2008-08-20 18:36:57.000000000 -0700
31981 +@@ -390,11 +390,21 @@ extern unsigned long ioremap_bot, iorema
31982 +
31983 + #define PAGE_NONE __pgprot(_PAGE_BASE)
31984 + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
31985 +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
31986 ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
31987 + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
31988 +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
31989 ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
31990 + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
31991 +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
31992 ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
31993 ++
31994 ++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
31995 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
31996 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
31997 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
31998 ++#else
31999 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
32000 ++# define PAGE_COPY_NOEXEC PAGE_COPY
32001 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
32002 ++#endif
32003 +
32004 + #define PAGE_KERNEL __pgprot(_PAGE_RAM)
32005 + #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
32006 +@@ -406,21 +416,21 @@ extern unsigned long ioremap_bot, iorema
32007 + * This is the closest we can get..
32008 + */
32009 + #define __P000 PAGE_NONE
32010 +-#define __P001 PAGE_READONLY_X
32011 +-#define __P010 PAGE_COPY
32012 +-#define __P011 PAGE_COPY_X
32013 +-#define __P100 PAGE_READONLY
32014 ++#define __P001 PAGE_READONLY_NOEXEC
32015 ++#define __P010 PAGE_COPY_NOEXEC
32016 ++#define __P011 PAGE_COPY_NOEXEC
32017 ++#define __P100 PAGE_READONLY_X
32018 + #define __P101 PAGE_READONLY_X
32019 +-#define __P110 PAGE_COPY
32020 ++#define __P110 PAGE_COPY_X
32021 + #define __P111 PAGE_COPY_X
32022 +
32023 + #define __S000 PAGE_NONE
32024 +-#define __S001 PAGE_READONLY_X
32025 +-#define __S010 PAGE_SHARED
32026 +-#define __S011 PAGE_SHARED_X
32027 +-#define __S100 PAGE_READONLY
32028 ++#define __S001 PAGE_READONLY_NOEXEC
32029 ++#define __S010 PAGE_SHARED_NOEXEC
32030 ++#define __S011 PAGE_SHARED_NOEXEC
32031 ++#define __S100 PAGE_READONLY_X
32032 + #define __S101 PAGE_READONLY_X
32033 +-#define __S110 PAGE_SHARED
32034 ++#define __S110 PAGE_SHARED_X
32035 + #define __S111 PAGE_SHARED_X
32036 +
32037 + #ifndef __ASSEMBLY__
32038 +diff -urNp a/include/asm-s390/kmap_types.h b/include/asm-s390/kmap_types.h
32039 +--- a/include/asm-s390/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32040 ++++ b/include/asm-s390/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32041 +@@ -16,6 +16,7 @@ enum km_type {
32042 + KM_IRQ1,
32043 + KM_SOFTIRQ0,
32044 + KM_SOFTIRQ1,
32045 ++ KM_CLEARPAGE,
32046 + KM_TYPE_NR
32047 + };
32048 +
32049 +diff -urNp a/include/asm-sh/kmap_types.h b/include/asm-sh/kmap_types.h
32050 +--- a/include/asm-sh/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32051 ++++ b/include/asm-sh/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32052 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
32053 + D(10) KM_IRQ1,
32054 + D(11) KM_SOFTIRQ0,
32055 + D(12) KM_SOFTIRQ1,
32056 +-D(13) KM_TYPE_NR
32057 ++D(13) KM_CLEARPAGE,
32058 ++D(14) KM_TYPE_NR
32059 + };
32060 +
32061 + #undef D
32062 +diff -urNp a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
32063 +--- a/include/asm-sparc/elf.h 2008-08-20 11:16:13.000000000 -0700
32064 ++++ b/include/asm-sparc/elf.h 2008-08-20 18:36:57.000000000 -0700
32065 +@@ -120,6 +120,13 @@ typedef struct {
32066 +
32067 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
32068 +
32069 ++#ifdef CONFIG_PAX_ASLR
32070 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
32071 ++
32072 ++#define PAX_DELTA_MMAP_LEN 16
32073 ++#define PAX_DELTA_STACK_LEN 16
32074 ++#endif
32075 ++
32076 + /* This yields a mask that user programs can use to figure out what
32077 + instruction set this cpu supports. This can NOT be done in userspace
32078 + on Sparc. */
32079 +diff -urNp a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h
32080 +--- a/include/asm-sparc/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32081 ++++ b/include/asm-sparc/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32082 +@@ -15,6 +15,7 @@ enum km_type {
32083 + KM_IRQ1,
32084 + KM_SOFTIRQ0,
32085 + KM_SOFTIRQ1,
32086 ++ KM_CLEARPAGE,
32087 + KM_TYPE_NR
32088 + };
32089 +
32090 +diff -urNp a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
32091 +--- a/include/asm-sparc/pgtable.h 2008-08-20 11:16:13.000000000 -0700
32092 ++++ b/include/asm-sparc/pgtable.h 2008-08-20 18:36:57.000000000 -0700
32093 +@@ -48,6 +48,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
32094 + BTFIXUPDEF_INT(page_none)
32095 + BTFIXUPDEF_INT(page_copy)
32096 + BTFIXUPDEF_INT(page_readonly)
32097 ++
32098 ++#ifdef CONFIG_PAX_PAGEEXEC
32099 ++BTFIXUPDEF_INT(page_shared_noexec)
32100 ++BTFIXUPDEF_INT(page_copy_noexec)
32101 ++BTFIXUPDEF_INT(page_readonly_noexec)
32102 ++#endif
32103 ++
32104 + BTFIXUPDEF_INT(page_kernel)
32105 +
32106 + #define PMD_SHIFT SUN4C_PMD_SHIFT
32107 +@@ -69,6 +76,16 @@ extern pgprot_t PAGE_SHARED;
32108 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
32109 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
32110 +
32111 ++#ifdef CONFIG_PAX_PAGEEXEC
32112 ++extern pgprot_t PAGE_SHARED_NOEXEC;
32113 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
32114 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
32115 ++#else
32116 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
32117 ++# define PAGE_COPY_NOEXEC PAGE_COPY
32118 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
32119 ++#endif
32120 ++
32121 + extern unsigned long page_kernel;
32122 +
32123 + #ifdef MODULE
32124 +diff -urNp a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
32125 +--- a/include/asm-sparc/pgtsrmmu.h 2008-08-20 11:16:13.000000000 -0700
32126 ++++ b/include/asm-sparc/pgtsrmmu.h 2008-08-20 18:36:57.000000000 -0700
32127 +@@ -115,6 +115,16 @@
32128 + SRMMU_EXEC | SRMMU_REF)
32129 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32130 + SRMMU_EXEC | SRMMU_REF)
32131 ++
32132 ++#ifdef CONFIG_PAX_PAGEEXEC
32133 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32134 ++ SRMMU_WRITE | SRMMU_REF)
32135 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32136 ++ SRMMU_REF)
32137 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
32138 ++ SRMMU_REF)
32139 ++#endif
32140 ++
32141 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
32142 + SRMMU_DIRTY | SRMMU_REF)
32143 +
32144 +diff -urNp a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
32145 +--- a/include/asm-sparc64/elf.h 2008-08-20 11:16:13.000000000 -0700
32146 ++++ b/include/asm-sparc64/elf.h 2008-08-20 18:36:57.000000000 -0700
32147 +@@ -164,6 +164,12 @@ typedef struct {
32148 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
32149 + #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
32150 +
32151 ++#ifdef CONFIG_PAX_ASLR
32152 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
32153 ++
32154 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
32155 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
32156 ++#endif
32157 +
32158 + /* This yields a mask that user programs can use to figure out what
32159 + instruction set this cpu supports. */
32160 +diff -urNp a/include/asm-sparc64/kmap_types.h b/include/asm-sparc64/kmap_types.h
32161 +--- a/include/asm-sparc64/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32162 ++++ b/include/asm-sparc64/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32163 +@@ -19,6 +19,7 @@ enum km_type {
32164 + KM_IRQ1,
32165 + KM_SOFTIRQ0,
32166 + KM_SOFTIRQ1,
32167 ++ KM_CLEARPAGE,
32168 + KM_TYPE_NR
32169 + };
32170 +
32171 +diff -urNp a/include/asm-um/kmap_types.h b/include/asm-um/kmap_types.h
32172 +--- a/include/asm-um/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32173 ++++ b/include/asm-um/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32174 +@@ -23,6 +23,7 @@ enum km_type {
32175 + KM_IRQ1,
32176 + KM_SOFTIRQ0,
32177 + KM_SOFTIRQ1,
32178 ++ KM_CLEARPAGE,
32179 + KM_TYPE_NR
32180 + };
32181 +
32182 +diff -urNp a/include/asm-v850/kmap_types.h b/include/asm-v850/kmap_types.h
32183 +--- a/include/asm-v850/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32184 ++++ b/include/asm-v850/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32185 +@@ -13,6 +13,7 @@ enum km_type {
32186 + KM_PTE1,
32187 + KM_IRQ0,
32188 + KM_IRQ1,
32189 ++ KM_CLEARPAGE,
32190 + KM_TYPE_NR
32191 + };
32192 +
32193 +diff -urNp a/include/asm-x86/alternative.h b/include/asm-x86/alternative.h
32194 +--- a/include/asm-x86/alternative.h 2008-08-20 11:16:13.000000000 -0700
32195 ++++ b/include/asm-x86/alternative.h 2008-08-20 18:36:57.000000000 -0700
32196 +@@ -94,7 +94,7 @@ static inline void alternatives_smp_swit
32197 + " .byte 662b-661b\n" /* sourcelen */ \
32198 + " .byte 664f-663f\n" /* replacementlen */ \
32199 + ".previous\n" \
32200 +- ".section .altinstr_replacement,\"ax\"\n" \
32201 ++ ".section .altinstr_replacement,\"a\"\n" \
32202 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
32203 + ".previous" :: "i" (feature) : "memory")
32204 +
32205 +@@ -118,7 +118,7 @@ static inline void alternatives_smp_swit
32206 + " .byte 662b-661b\n" /* sourcelen */ \
32207 + " .byte 664f-663f\n" /* replacementlen */ \
32208 + ".previous\n" \
32209 +- ".section .altinstr_replacement,\"ax\"\n" \
32210 ++ ".section .altinstr_replacement,\"a\"\n" \
32211 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
32212 + ".previous" :: "i" (feature), ##input)
32213 +
32214 +@@ -133,7 +133,7 @@ static inline void alternatives_smp_swit
32215 + " .byte 662b-661b\n" /* sourcelen */ \
32216 + " .byte 664f-663f\n" /* replacementlen */ \
32217 + ".previous\n" \
32218 +- ".section .altinstr_replacement,\"ax\"\n" \
32219 ++ ".section .altinstr_replacement,\"a\"\n" \
32220 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
32221 + ".previous" : output : [feat] "i" (feature), ##input)
32222 +
32223 +diff -urNp a/include/asm-x86/apic.h b/include/asm-x86/apic.h
32224 +--- a/include/asm-x86/apic.h 2008-08-20 11:16:13.000000000 -0700
32225 ++++ b/include/asm-x86/apic.h 2008-08-20 18:36:57.000000000 -0700
32226 +@@ -10,7 +10,7 @@
32227 +
32228 + #define ARCH_APICTIMER_STOPS_ON_C3 1
32229 +
32230 +-#define Dprintk(x...)
32231 ++#define Dprintk(x...) do {} while (0)
32232 +
32233 + /*
32234 + * Debugging macros
32235 +diff -urNp a/include/asm-x86/boot.h b/include/asm-x86/boot.h
32236 +--- a/include/asm-x86/boot.h 2008-08-20 11:16:13.000000000 -0700
32237 ++++ b/include/asm-x86/boot.h 2008-08-20 18:36:57.000000000 -0700
32238 +@@ -13,8 +13,13 @@
32239 + #define ASK_VGA 0xfffd /* ask for it at bootup */
32240 +
32241 + /* Physical address where kernel should be loaded. */
32242 +-#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
32243 ++#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
32244 + + (CONFIG_PHYSICAL_ALIGN - 1)) \
32245 + & ~(CONFIG_PHYSICAL_ALIGN - 1))
32246 +
32247 ++#ifndef __ASSEMBLY__
32248 ++extern unsigned char __LOAD_PHYSICAL_ADDR[];
32249 ++#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
32250 ++#endif
32251 ++
32252 + #endif /* _ASM_BOOT_H */
32253 +diff -urNp a/include/asm-x86/cache.h b/include/asm-x86/cache.h
32254 +--- a/include/asm-x86/cache.h 2008-08-20 11:16:13.000000000 -0700
32255 ++++ b/include/asm-x86/cache.h 2008-08-20 18:36:57.000000000 -0700
32256 +@@ -6,6 +6,7 @@
32257 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
32258 +
32259 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
32260 ++#define __read_only __attribute__((__section__(".data.read_only")))
32261 +
32262 + #ifdef CONFIG_X86_VSMP
32263 + /* vSMP Internode cacheline shift */
32264 +diff -urNp a/include/asm-x86/checksum_32.h b/include/asm-x86/checksum_32.h
32265 +--- a/include/asm-x86/checksum_32.h 2008-08-20 11:16:13.000000000 -0700
32266 ++++ b/include/asm-x86/checksum_32.h 2008-08-20 18:36:57.000000000 -0700
32267 +@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
32268 + asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
32269 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
32270 +
32271 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
32272 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
32273 ++
32274 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
32275 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
32276 ++
32277 + /*
32278 + * Note: when you get a NULL pointer exception here this means someone
32279 + * passed in an incorrect kernel address to one of these functions.
32280 +@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
32281 + int len, __wsum sum, int *err_ptr)
32282 + {
32283 + might_sleep();
32284 +- return csum_partial_copy_generic((__force void *)src, dst,
32285 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
32286 + len, sum, err_ptr, NULL);
32287 + }
32288 +
32289 +@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
32290 + {
32291 + might_sleep();
32292 + if (access_ok(VERIFY_WRITE, dst, len))
32293 +- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
32294 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
32295 +
32296 + if (len)
32297 + *err_ptr = -EFAULT;
32298 +diff -urNp a/include/asm-x86/desc.h b/include/asm-x86/desc.h
32299 +--- a/include/asm-x86/desc.h 2008-08-20 11:16:13.000000000 -0700
32300 ++++ b/include/asm-x86/desc.h 2008-08-20 18:36:57.000000000 -0700
32301 +@@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
32302 + desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
32303 + desc->type = (info->read_exec_only ^ 1) << 1;
32304 + desc->type |= info->contents << 2;
32305 ++ desc->type |= info->seg_not_present ^ 1;
32306 + desc->s = 1;
32307 + desc->dpl = 0x3;
32308 + desc->p = info->seg_not_present ^ 1;
32309 +@@ -27,14 +28,15 @@ static inline void fill_ldt(struct desc_
32310 + }
32311 +
32312 + extern struct desc_ptr idt_descr;
32313 +-extern gate_desc idt_table[];
32314 ++extern gate_desc idt_table[256];
32315 +
32316 +-#ifdef CONFIG_X86_64
32317 +-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
32318 +-extern struct desc_ptr cpu_gdt_descr[];
32319 +-/* the cpu gdt accessor */
32320 +-#define get_cpu_gdt_table(x) ((struct desc_struct *)cpu_gdt_descr[x].address)
32321 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
32322 ++static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
32323 ++{
32324 ++ return cpu_gdt_table[cpu];
32325 ++}
32326 +
32327 ++#ifdef CONFIG_X86_64
32328 + static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
32329 + unsigned dpl, unsigned ist, unsigned seg)
32330 + {
32331 +@@ -51,16 +53,6 @@ static inline void pack_gate(gate_desc *
32332 + }
32333 +
32334 + #else
32335 +-struct gdt_page {
32336 +- struct desc_struct gdt[GDT_ENTRIES];
32337 +-} __attribute__((aligned(PAGE_SIZE)));
32338 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
32339 +-
32340 +-static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
32341 +-{
32342 +- return per_cpu(gdt_page, cpu).gdt;
32343 +-}
32344 +-
32345 + static inline void pack_gate(gate_desc *gate, unsigned char type,
32346 + unsigned long base, unsigned dpl, unsigned flags, unsigned short seg)
32347 +
32348 +@@ -69,7 +61,6 @@ static inline void pack_gate(gate_desc *
32349 + gate->b = (base & 0xffff0000) |
32350 + (((0x80 | type | (dpl << 5)) & 0xff) << 8);
32351 + }
32352 +-
32353 + #endif
32354 +
32355 + static inline int desc_empty(const void *ptr)
32356 +@@ -105,19 +96,48 @@ static inline int desc_empty(const void
32357 + static inline void native_write_idt_entry(gate_desc *idt, int entry,
32358 + const gate_desc *gate)
32359 + {
32360 ++
32361 ++#ifdef CONFIG_PAX_KERNEXEC
32362 ++ unsigned long cr0;
32363 ++
32364 ++ pax_open_kernel(cr0);
32365 ++#endif
32366 ++
32367 + memcpy(&idt[entry], gate, sizeof(*gate));
32368 ++
32369 ++#ifdef CONFIG_PAX_KERNEXEC
32370 ++ pax_close_kernel(cr0);
32371 ++#endif
32372 ++
32373 + }
32374 +
32375 + static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
32376 + const void *desc)
32377 + {
32378 ++
32379 ++#ifdef CONFIG_PAX_KERNEXEC
32380 ++ unsigned long cr0;
32381 ++
32382 ++ pax_open_kernel(cr0);
32383 ++#endif
32384 ++
32385 + memcpy(&ldt[entry], desc, 8);
32386 ++
32387 ++#ifdef CONFIG_PAX_KERNEXEC
32388 ++ pax_close_kernel(cr0);
32389 ++#endif
32390 ++
32391 + }
32392 +
32393 + static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
32394 + const void *desc, int type)
32395 + {
32396 + unsigned int size;
32397 ++
32398 ++#ifdef CONFIG_PAX_KERNEXEC
32399 ++ unsigned long cr0;
32400 ++#endif
32401 ++
32402 + switch (type) {
32403 + case DESC_TSS:
32404 + size = sizeof(tss_desc);
32405 +@@ -129,7 +149,17 @@ static inline void native_write_gdt_entr
32406 + size = sizeof(struct desc_struct);
32407 + break;
32408 + }
32409 ++
32410 ++#ifdef CONFIG_PAX_KERNEXEC
32411 ++ pax_open_kernel(cr0);
32412 ++#endif
32413 ++
32414 + memcpy(&gdt[entry], desc, size);
32415 ++
32416 ++#ifdef CONFIG_PAX_KERNEXEC
32417 ++ pax_close_kernel(cr0);
32418 ++#endif
32419 ++
32420 + }
32421 +
32422 + static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
32423 +@@ -201,7 +231,19 @@ static inline void native_set_ldt(const
32424 +
32425 + static inline void native_load_tr_desc(void)
32426 + {
32427 ++
32428 ++#ifdef CONFIG_PAX_KERNEXEC
32429 ++ unsigned long cr0;
32430 ++
32431 ++ pax_open_kernel(cr0);
32432 ++#endif
32433 ++
32434 + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
32435 ++
32436 ++#ifdef CONFIG_PAX_KERNEXEC
32437 ++ pax_close_kernel(cr0);
32438 ++#endif
32439 ++
32440 + }
32441 +
32442 + static inline void native_load_gdt(const struct desc_ptr *dtr)
32443 +@@ -236,8 +278,19 @@ static inline void native_load_tls(struc
32444 + unsigned int i;
32445 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
32446 +
32447 ++#ifdef CONFIG_PAX_KERNEXEC
32448 ++ unsigned long cr0;
32449 ++
32450 ++ pax_open_kernel(cr0);
32451 ++#endif
32452 ++
32453 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
32454 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
32455 ++
32456 ++#ifdef CONFIG_PAX_KERNEXEC
32457 ++ pax_close_kernel(cr0);
32458 ++#endif
32459 ++
32460 + }
32461 +
32462 + #define _LDT_empty(info) (\
32463 +@@ -353,6 +406,18 @@ static inline void set_system_gate_ist(i
32464 + _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
32465 + }
32466 +
32467 ++#ifdef CONFIG_X86_32
32468 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
32469 ++{
32470 ++ struct desc_struct d;
32471 ++
32472 ++ if (likely(limit))
32473 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
32474 ++ pack_descriptor(&d, base, limit, 0xFB, 0xC);
32475 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
32476 ++}
32477 ++#endif
32478 ++
32479 + #else
32480 + /*
32481 + * GET_DESC_BASE reads the descriptor base of the specified segment.
32482 +diff -urNp a/include/asm-x86/elf.h b/include/asm-x86/elf.h
32483 +--- a/include/asm-x86/elf.h 2008-08-20 11:16:13.000000000 -0700
32484 ++++ b/include/asm-x86/elf.h 2008-08-20 18:36:57.000000000 -0700
32485 +@@ -243,7 +243,25 @@ extern int force_personality32;
32486 + the loader. We need to make sure that it is out of the way of the program
32487 + that it will "exec", and that there is sufficient room for the brk. */
32488 +
32489 ++#ifdef CONFIG_PAX_SEGMEXEC
32490 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
32491 ++#else
32492 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
32493 ++#endif
32494 ++
32495 ++#ifdef CONFIG_PAX_ASLR
32496 ++#ifdef CONFIG_X86_32
32497 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
32498 ++
32499 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
32500 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
32501 ++#else
32502 ++#define PAX_ELF_ET_DYN_BASE 0x400000UL
32503 ++
32504 ++#define PAX_DELTA_MMAP_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
32505 ++#define PAX_DELTA_STACK_LEN ((test_thread_flag(TIF_IA32)) ? 16 : 32)
32506 ++#endif
32507 ++#endif
32508 +
32509 + /* This yields a mask that user programs can use to figure out what
32510 + instruction set this CPU supports. This could be done in user space,
32511 +@@ -292,7 +310,7 @@ do if (vdso_enabled) { \
32512 +
32513 + #define ARCH_DLINFO \
32514 + do if (vdso_enabled) { \
32515 +- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
32516 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR,current->mm->context.vdso);\
32517 + } while (0)
32518 +
32519 + #define AT_SYSINFO 32
32520 +@@ -303,7 +321,7 @@ do if (vdso_enabled) { \
32521 +
32522 + #endif /* !CONFIG_X86_32 */
32523 +
32524 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
32525 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
32526 +
32527 + #define VDSO_ENTRY \
32528 + ((unsigned long) VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
32529 +@@ -317,7 +335,4 @@ extern int arch_setup_additional_pages(s
32530 + extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
32531 + #define compat_arch_setup_additional_pages syscall32_setup_pages
32532 +
32533 +-extern unsigned long arch_randomize_brk(struct mm_struct *mm);
32534 +-#define arch_randomize_brk arch_randomize_brk
32535 +-
32536 + #endif
32537 +diff -urNp a/include/asm-x86/futex.h b/include/asm-x86/futex.h
32538 +--- a/include/asm-x86/futex.h 2008-08-20 11:16:13.000000000 -0700
32539 ++++ b/include/asm-x86/futex.h 2008-08-20 18:36:57.000000000 -0700
32540 +@@ -11,6 +11,41 @@
32541 + #include <asm/system.h>
32542 + #include <asm/uaccess.h>
32543 +
32544 ++#ifdef CONFIG_X86_32
32545 ++#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
32546 ++ __asm__ __volatile( \
32547 ++ "movw %w6, %%ds\n" \
32548 ++"1: " insn "\n" \
32549 ++"2: pushl %%ss\n \
32550 ++ popl %%ds\n \
32551 ++ .section .fixup,\"ax\"\n \
32552 ++3: mov %3, %1\n \
32553 ++ jmp 2b\n \
32554 ++ .previous\n" \
32555 ++ _ASM_EXTABLE(1b,3b) \
32556 ++ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
32557 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
32558 ++
32559 ++#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
32560 ++ __asm__ __volatile( \
32561 ++" movw %w7, %%es\n \
32562 ++1: movl %%es:%2, %0\n \
32563 ++ movl %0, %3\n" \
32564 ++ insn "\n" \
32565 ++"2: lock; cmpxchgl %3, %%es:%2\n \
32566 ++ jnz 1b\n \
32567 ++3: pushl %%ss\n \
32568 ++ popl %%es\n \
32569 ++ .section .fixup,\"ax\"\n \
32570 ++4: mov %5, %1\n \
32571 ++ jmp 3b\n \
32572 ++ .previous\n" \
32573 ++ _ASM_EXTABLE(1b,4b) \
32574 ++ _ASM_EXTABLE(2b,4b) \
32575 ++ : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
32576 ++ "=&r" (tem) \
32577 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
32578 ++#else
32579 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
32580 + __asm__ __volatile( \
32581 + "1: " insn "\n" \
32582 +@@ -38,6 +73,7 @@
32583 + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
32584 + "=&r" (tem) \
32585 + : "r" (oparg), "i" (-EFAULT), "1" (0))
32586 ++#endif
32587 +
32588 + static inline int
32589 + futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
32590 +@@ -64,11 +100,20 @@ futex_atomic_op_inuser(int encoded_op, i
32591 +
32592 + switch (op) {
32593 + case FUTEX_OP_SET:
32594 ++#ifdef CONFIG_X86_32
32595 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
32596 ++#else
32597 + __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
32598 ++#endif
32599 + break;
32600 + case FUTEX_OP_ADD:
32601 ++#ifdef CONFIG_X86_32
32602 ++ __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
32603 ++ uaddr, oparg);
32604 ++#else
32605 + __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
32606 + uaddr, oparg);
32607 ++#endif
32608 + break;
32609 + case FUTEX_OP_OR:
32610 + __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
32611 +@@ -113,14 +158,26 @@ futex_atomic_cmpxchg_inatomic(int __user
32612 + return -EFAULT;
32613 +
32614 + __asm__ __volatile__(
32615 ++#ifdef CONFIG_X86_32
32616 ++ " movw %w5, %%ds \n"
32617 ++ "1: lock; cmpxchgl %3, %%ds:%1 \n"
32618 ++ "2: pushl %%ss \n"
32619 ++ " popl %%ds \n"
32620 ++ " .section .fixup, \"ax\" \n"
32621 ++#else
32622 + "1: lock; cmpxchgl %3, %1 \n"
32623 + "2: .section .fixup, \"ax\" \n"
32624 ++#endif
32625 + "3: mov %2, %0 \n"
32626 + " jmp 2b \n"
32627 + " .previous \n"
32628 + _ASM_EXTABLE(1b,3b)
32629 + : "=a" (oldval), "+m" (*uaddr)
32630 ++#ifdef CONFIG_X86_32
32631 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
32632 ++#else
32633 + : "i" (-EFAULT), "r" (newval), "0" (oldval)
32634 ++#endif
32635 + : "memory"
32636 + );
32637 +
32638 +diff -urNp a/include/asm-x86/i387.h b/include/asm-x86/i387.h
32639 +--- a/include/asm-x86/i387.h 2008-08-20 11:16:13.000000000 -0700
32640 ++++ b/include/asm-x86/i387.h 2008-08-20 18:36:57.000000000 -0700
32641 +@@ -202,13 +202,8 @@ static inline void restore_fpu(struct ta
32642 + }
32643 +
32644 + /* We need a safe address that is cheap to find and that is already
32645 +- in L1 during context switch. The best choices are unfortunately
32646 +- different for UP and SMP */
32647 +-#ifdef CONFIG_SMP
32648 +-#define safe_address (__per_cpu_offset[0])
32649 +-#else
32650 +-#define safe_address (kstat_cpu(0).cpustat.user)
32651 +-#endif
32652 ++ in L1 during context switch. */
32653 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
32654 +
32655 + /*
32656 + * These must be called with preempt disabled
32657 +diff -urNp a/include/asm-x86/io_64.h b/include/asm-x86/io_64.h
32658 +--- a/include/asm-x86/io_64.h 2008-08-20 11:16:13.000000000 -0700
32659 ++++ b/include/asm-x86/io_64.h 2008-08-20 18:36:57.000000000 -0700
32660 +@@ -143,6 +143,17 @@ static inline void * phys_to_virt(unsign
32661 + }
32662 + #endif
32663 +
32664 ++#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
32665 ++static inline int valid_phys_addr_range (unsigned long addr, size_t count)
32666 ++{
32667 ++ return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
32668 ++}
32669 ++
32670 ++static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
32671 ++{
32672 ++ return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
32673 ++}
32674 ++
32675 + /*
32676 + * Change "struct page" to physical address.
32677 + */
32678 +diff -urNp a/include/asm-x86/irqflags.h b/include/asm-x86/irqflags.h
32679 +--- a/include/asm-x86/irqflags.h 2008-08-20 11:16:13.000000000 -0700
32680 ++++ b/include/asm-x86/irqflags.h 2008-08-20 18:36:57.000000000 -0700
32681 +@@ -146,6 +146,8 @@ static inline unsigned long __raw_local_
32682 + #define INTERRUPT_RETURN iret
32683 + #define ENABLE_INTERRUPTS_SYSCALL_RET sti; sysexit
32684 + #define GET_CR0_INTO_EAX movl %cr0, %eax
32685 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
32686 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
32687 + #endif
32688 +
32689 +
32690 +diff -urNp a/include/asm-x86/kmap_types.h b/include/asm-x86/kmap_types.h
32691 +--- a/include/asm-x86/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
32692 ++++ b/include/asm-x86/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
32693 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
32694 + D(10) KM_IRQ1,
32695 + D(11) KM_SOFTIRQ0,
32696 + D(12) KM_SOFTIRQ1,
32697 +-D(13) KM_TYPE_NR
32698 ++D(13) KM_CLEARPAGE,
32699 ++D(14) KM_TYPE_NR
32700 + };
32701 +
32702 + #undef D
32703 +diff -urNp a/include/asm-x86/linkage.h b/include/asm-x86/linkage.h
32704 +--- a/include/asm-x86/linkage.h 2008-08-20 11:16:13.000000000 -0700
32705 ++++ b/include/asm-x86/linkage.h 2008-08-20 18:36:57.000000000 -0700
32706 +@@ -4,6 +4,11 @@
32707 + #ifdef CONFIG_X86_64
32708 + #define __ALIGN .p2align 4,,15
32709 + #define __ALIGN_STR ".p2align 4,,15"
32710 ++#else
32711 ++#ifdef CONFIG_X86_ALIGNMENT_16
32712 ++#define __ALIGN .align 16,0x90
32713 ++#define __ALIGN_STR ".align 16,0x90"
32714 ++#endif
32715 + #endif
32716 +
32717 + #ifdef CONFIG_X86_32
32718 +@@ -49,10 +54,5 @@
32719 +
32720 + #endif
32721 +
32722 +-#ifdef CONFIG_X86_ALIGNMENT_16
32723 +-#define __ALIGN .align 16,0x90
32724 +-#define __ALIGN_STR ".align 16,0x90"
32725 +-#endif
32726 +-
32727 + #endif
32728 +
32729 +diff -urNp a/include/asm-x86/mach-default/apm.h b/include/asm-x86/mach-default/apm.h
32730 +--- a/include/asm-x86/mach-default/apm.h 2008-08-20 11:16:13.000000000 -0700
32731 ++++ b/include/asm-x86/mach-default/apm.h 2008-08-20 18:36:57.000000000 -0700
32732 +@@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
32733 + __asm__ __volatile__(APM_DO_ZERO_SEGS
32734 + "pushl %%edi\n\t"
32735 + "pushl %%ebp\n\t"
32736 +- "lcall *%%cs:apm_bios_entry\n\t"
32737 ++ "lcall *%%ss:apm_bios_entry\n\t"
32738 + "setc %%al\n\t"
32739 + "popl %%ebp\n\t"
32740 + "popl %%edi\n\t"
32741 +@@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
32742 + __asm__ __volatile__(APM_DO_ZERO_SEGS
32743 + "pushl %%edi\n\t"
32744 + "pushl %%ebp\n\t"
32745 +- "lcall *%%cs:apm_bios_entry\n\t"
32746 ++ "lcall *%%ss:apm_bios_entry\n\t"
32747 + "setc %%bl\n\t"
32748 + "popl %%ebp\n\t"
32749 + "popl %%edi\n\t"
32750 +diff -urNp a/include/asm-x86/mman.h b/include/asm-x86/mman.h
32751 +--- a/include/asm-x86/mman.h 2008-08-20 11:16:13.000000000 -0700
32752 ++++ b/include/asm-x86/mman.h 2008-08-20 18:36:57.000000000 -0700
32753 +@@ -16,4 +16,14 @@
32754 + #define MCL_CURRENT 1 /* lock all current mappings */
32755 + #define MCL_FUTURE 2 /* lock all future mappings */
32756 +
32757 ++#ifdef __KERNEL__
32758 ++#ifndef __ASSEMBLY__
32759 ++#ifdef CONFIG_X86_32
32760 ++#define arch_mmap_check i386_mmap_check
32761 ++int i386_mmap_check(unsigned long addr, unsigned long len,
32762 ++ unsigned long flags);
32763 ++#endif
32764 ++#endif
32765 ++#endif
32766 ++
32767 + #endif /* _ASM_X86_MMAN_H */
32768 +diff -urNp a/include/asm-x86/mmu.h b/include/asm-x86/mmu.h
32769 +--- a/include/asm-x86/mmu.h 2008-08-20 11:16:13.000000000 -0700
32770 ++++ b/include/asm-x86/mmu.h 2008-08-20 18:36:57.000000000 -0700
32771 +@@ -11,13 +11,26 @@
32772 + * cpu_vm_mask is used to optimize ldt flushing.
32773 + */
32774 + typedef struct {
32775 +- void *ldt;
32776 ++ struct desc_struct *ldt;
32777 + #ifdef CONFIG_X86_64
32778 + rwlock_t ldtlock;
32779 + #endif
32780 + int size;
32781 + struct mutex lock;
32782 +- void *vdso;
32783 ++ unsigned long vdso;
32784 ++
32785 ++#ifdef CONFIG_X86_32
32786 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32787 ++ unsigned long user_cs_base;
32788 ++ unsigned long user_cs_limit;
32789 ++
32790 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
32791 ++ cpumask_t cpu_user_cs_mask;
32792 ++#endif
32793 ++
32794 ++#endif
32795 ++#endif
32796 ++
32797 + } mm_context_t;
32798 +
32799 + #ifdef CONFIG_SMP
32800 +diff -urNp a/include/asm-x86/mmu_context_32.h b/include/asm-x86/mmu_context_32.h
32801 +--- a/include/asm-x86/mmu_context_32.h 2008-08-20 11:16:13.000000000 -0700
32802 ++++ b/include/asm-x86/mmu_context_32.h 2008-08-20 18:36:57.000000000 -0700
32803 +@@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
32804 + */
32805 + if (unlikely(prev->context.ldt != next->context.ldt))
32806 + load_LDT_nolock(&next->context);
32807 ++
32808 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
32809 ++ if (!nx_enabled) {
32810 ++ smp_mb__before_clear_bit();
32811 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
32812 ++ smp_mb__after_clear_bit();
32813 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
32814 ++ }
32815 ++#endif
32816 ++
32817 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32818 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
32819 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
32820 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
32821 ++#endif
32822 ++
32823 + }
32824 + #ifdef CONFIG_SMP
32825 + else {
32826 +@@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
32827 + */
32828 + load_cr3(next->pgd);
32829 + load_LDT_nolock(&next->context);
32830 ++
32831 ++#ifdef CONFIG_PAX_PAGEEXEC
32832 ++ if (!nx_enabled)
32833 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
32834 ++#endif
32835 ++
32836 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32837 ++#ifdef CONFIG_PAX_PAGEEXEC
32838 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
32839 ++#endif
32840 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
32841 ++#endif
32842 ++
32843 + }
32844 + }
32845 + #endif
32846 +diff -urNp a/include/asm-x86/module.h b/include/asm-x86/module.h
32847 +--- a/include/asm-x86/module.h 2008-08-20 11:16:13.000000000 -0700
32848 ++++ b/include/asm-x86/module.h 2008-08-20 18:36:57.000000000 -0700
32849 +@@ -76,7 +76,12 @@ struct mod_arch_specific {};
32850 + # else
32851 + # define MODULE_STACKSIZE ""
32852 + # endif
32853 +-# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
32854 ++# ifdef CONFIG_GRKERNSEC
32855 ++# define MODULE_GRSEC "GRSECURITY "
32856 ++# else
32857 ++# define MODULE_GRSEC ""
32858 ++# endif
32859 ++# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
32860 + #endif
32861 +
32862 + #endif /* _ASM_MODULE_H */
32863 +diff -urNp a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
32864 +--- a/include/asm-x86/page_32.h 2008-08-20 11:16:13.000000000 -0700
32865 ++++ b/include/asm-x86/page_32.h 2008-08-20 18:36:57.000000000 -0700
32866 +@@ -13,6 +13,23 @@
32867 + */
32868 + #define __PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
32869 +
32870 ++#ifdef CONFIG_PAX_KERNEXEC
32871 ++#ifndef __ASSEMBLY__
32872 ++extern unsigned char MODULES_VADDR[];
32873 ++extern unsigned char MODULES_END[];
32874 ++extern unsigned char KERNEL_TEXT_OFFSET[];
32875 ++#define ktla_ktva(addr) (addr + (unsigned long)KERNEL_TEXT_OFFSET)
32876 ++#define ktva_ktla(addr) (addr - (unsigned long)KERNEL_TEXT_OFFSET)
32877 ++#endif
32878 ++#else
32879 ++#define ktla_ktva(addr) (addr)
32880 ++#define ktva_ktla(addr) (addr)
32881 ++#endif
32882 ++
32883 ++#ifdef CONFIG_PAX_PAGEEXEC
32884 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
32885 ++#endif
32886 ++
32887 + #ifdef CONFIG_X86_PAE
32888 + /* 44=32+12, the limit we can fit into an unsigned long pfn */
32889 + #define __PHYSICAL_MASK_SHIFT 44
32890 +diff -urNp a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
32891 +--- a/include/asm-x86/page_64.h 2008-08-20 11:16:13.000000000 -0700
32892 ++++ b/include/asm-x86/page_64.h 2008-08-20 18:36:57.000000000 -0700
32893 +@@ -43,6 +43,9 @@
32894 + #define __START_KERNEL (__START_KERNEL_map + __PHYSICAL_START)
32895 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
32896 +
32897 ++#define ktla_ktva(addr) (addr)
32898 ++#define ktva_ktla(addr) (addr)
32899 ++
32900 + /* See Documentation/x86_64/mm.txt for a description of the memory map. */
32901 + #define __PHYSICAL_MASK_SHIFT 46
32902 + #define __VIRTUAL_MASK_SHIFT 48
32903 +@@ -87,5 +90,6 @@ typedef struct { pteval_t pte; } pte_t;
32904 + #define pfn_valid(pfn) ((pfn) < end_pfn)
32905 + #endif
32906 +
32907 ++#define nx_enabled (1)
32908 +
32909 + #endif /* _X86_64_PAGE_H */
32910 +diff -urNp a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
32911 +--- a/include/asm-x86/paravirt.h 2008-08-20 11:16:13.000000000 -0700
32912 ++++ b/include/asm-x86/paravirt.h 2008-08-20 18:36:57.000000000 -0700
32913 +@@ -1356,24 +1356,24 @@ static inline unsigned long __raw_local_
32914 +
32915 + #define INTERRUPT_RETURN \
32916 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \
32917 +- jmp *%cs:pv_cpu_ops+PV_CPU_iret)
32918 ++ jmp *%ss:pv_cpu_ops+PV_CPU_iret)
32919 +
32920 + #define DISABLE_INTERRUPTS(clobbers) \
32921 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
32922 + PV_SAVE_REGS; \
32923 +- call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
32924 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_disable; \
32925 + PV_RESTORE_REGS;) \
32926 +
32927 + #define ENABLE_INTERRUPTS(clobbers) \
32928 + PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
32929 + PV_SAVE_REGS; \
32930 +- call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
32931 ++ call *%ss:pv_irq_ops+PV_IRQ_irq_enable; \
32932 + PV_RESTORE_REGS;)
32933 +
32934 + #define ENABLE_INTERRUPTS_SYSCALL_RET \
32935 + PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
32936 + CLBR_NONE, \
32937 +- jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
32938 ++ jmp *%ss:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
32939 +
32940 +
32941 + #ifdef CONFIG_X86_32
32942 +diff -urNp a/include/asm-x86/pda.h b/include/asm-x86/pda.h
32943 +--- a/include/asm-x86/pda.h 2008-08-20 11:16:13.000000000 -0700
32944 ++++ b/include/asm-x86/pda.h 2008-08-20 18:36:57.000000000 -0700
32945 +@@ -16,11 +16,9 @@ struct x8664_pda {
32946 + unsigned long oldrsp; /* 24 user rsp for system call */
32947 + int irqcount; /* 32 Irq nesting counter. Starts -1 */
32948 + unsigned int cpunumber; /* 36 Logical CPU number */
32949 +-#ifdef CONFIG_CC_STACKPROTECTOR
32950 + unsigned long stack_canary; /* 40 stack canary value */
32951 + /* gcc-ABI: this canary MUST be at
32952 + offset 40!!! */
32953 +-#endif
32954 + char *irqstackptr;
32955 + unsigned int nodenumber; /* number of current node */
32956 + unsigned int __softirq_pending;
32957 +diff -urNp a/include/asm-x86/percpu.h b/include/asm-x86/percpu.h
32958 +--- a/include/asm-x86/percpu.h 2008-08-20 11:16:13.000000000 -0700
32959 ++++ b/include/asm-x86/percpu.h 2008-08-20 18:36:57.000000000 -0700
32960 +@@ -67,6 +67,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
32961 +
32962 + #define __my_cpu_offset x86_read_percpu(this_cpu_off)
32963 +
32964 ++#include <asm-generic/sections.h>
32965 ++#include <linux/threads.h>
32966 ++#define __per_cpu_offset __per_cpu_offset
32967 ++extern unsigned long __per_cpu_offset[NR_CPUS];
32968 ++#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
32969 ++
32970 + /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
32971 + #define __percpu_seg "%%fs:"
32972 +
32973 +diff -urNp a/include/asm-x86/pgalloc_32.h b/include/asm-x86/pgalloc_32.h
32974 +--- a/include/asm-x86/pgalloc_32.h 2008-08-20 11:16:13.000000000 -0700
32975 ++++ b/include/asm-x86/pgalloc_32.h 2008-08-20 18:36:57.000000000 -0700
32976 +@@ -21,7 +21,11 @@ static inline void pmd_populate_kernel(s
32977 + pmd_t *pmd, pte_t *pte)
32978 + {
32979 + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT);
32980 ++#ifdef CONFIG_COMPAT_VDSO
32981 + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
32982 ++#else
32983 ++ set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
32984 ++#endif
32985 + }
32986 +
32987 + static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
32988 +diff -urNp a/include/asm-x86/pgalloc_64.h b/include/asm-x86/pgalloc_64.h
32989 +--- a/include/asm-x86/pgalloc_64.h 2008-08-20 11:16:13.000000000 -0700
32990 ++++ b/include/asm-x86/pgalloc_64.h 2008-08-20 18:36:57.000000000 -0700
32991 +@@ -6,7 +6,7 @@
32992 + #include <linux/mm.h>
32993 +
32994 + #define pmd_populate_kernel(mm, pmd, pte) \
32995 +- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
32996 ++ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
32997 + #define pud_populate(mm, pud, pmd) \
32998 + set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
32999 + #define pgd_populate(mm, pgd, pud) \
33000 +diff -urNp a/include/asm-x86/pgtable-2level.h b/include/asm-x86/pgtable-2level.h
33001 +--- a/include/asm-x86/pgtable-2level.h 2008-08-20 11:16:13.000000000 -0700
33002 ++++ b/include/asm-x86/pgtable-2level.h 2008-08-20 18:36:57.000000000 -0700
33003 +@@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t
33004 +
33005 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
33006 + {
33007 ++
33008 ++#ifdef CONFIG_PAX_KERNEXEC
33009 ++ unsigned long cr0;
33010 ++
33011 ++ pax_open_kernel(cr0);
33012 ++#endif
33013 ++
33014 + *pmdp = pmd;
33015 ++
33016 ++#ifdef CONFIG_PAX_KERNEXEC
33017 ++ pax_close_kernel(cr0);
33018 ++#endif
33019 ++
33020 + }
33021 +
33022 + static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
33023 +diff -urNp a/include/asm-x86/pgtable-3level.h b/include/asm-x86/pgtable-3level.h
33024 +--- a/include/asm-x86/pgtable-3level.h 2008-08-20 11:16:13.000000000 -0700
33025 ++++ b/include/asm-x86/pgtable-3level.h 2008-08-20 18:36:57.000000000 -0700
33026 +@@ -64,11 +64,35 @@ static inline void native_set_pte_atomic
33027 + }
33028 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
33029 + {
33030 ++
33031 ++#ifdef CONFIG_PAX_KERNEXEC
33032 ++ unsigned long cr0;
33033 ++
33034 ++ pax_open_kernel(cr0);
33035 ++#endif
33036 ++
33037 + set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
33038 ++
33039 ++#ifdef CONFIG_PAX_KERNEXEC
33040 ++ pax_close_kernel(cr0);
33041 ++#endif
33042 ++
33043 + }
33044 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
33045 + {
33046 ++
33047 ++#ifdef CONFIG_PAX_KERNEXEC
33048 ++ unsigned long cr0;
33049 ++
33050 ++ pax_open_kernel(cr0);
33051 ++#endif
33052 ++
33053 + set_64bit((unsigned long long *)(pudp),native_pud_val(pud));
33054 ++
33055 ++#ifdef CONFIG_PAX_KERNEXEC
33056 ++ pax_close_kernel(cr0);
33057 ++#endif
33058 ++
33059 + }
33060 +
33061 + /*
33062 +diff -urNp a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
33063 +--- a/include/asm-x86/pgtable.h 2008-08-20 11:16:13.000000000 -0700
33064 ++++ b/include/asm-x86/pgtable.h 2008-08-20 18:36:57.000000000 -0700
33065 +@@ -67,6 +67,9 @@
33066 + #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
33067 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
33068 +
33069 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
33070 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
33071 ++
33072 + #ifdef CONFIG_X86_32
33073 + #define _PAGE_KERNEL_EXEC \
33074 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
33075 +@@ -87,7 +90,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KE
33076 + #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
33077 + #define __PAGE_KERNEL_UC_MINUS (__PAGE_KERNEL | _PAGE_PCD)
33078 + #define __PAGE_KERNEL_VSYSCALL (__PAGE_KERNEL_RX | _PAGE_USER)
33079 +-#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
33080 ++#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
33081 + #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE)
33082 + #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE)
33083 +
33084 +@@ -140,10 +143,13 @@ extern unsigned long empty_zero_page[PAG
33085 + extern spinlock_t pgd_lock;
33086 + extern struct list_head pgd_list;
33087 +
33088 ++extern pteval_t __supported_pte_mask;
33089 ++
33090 + /*
33091 + * The following only work if pte_present() is true.
33092 + * Undefined behaviour if not..
33093 + */
33094 ++static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
33095 + static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
33096 + static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
33097 + static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
33098 +@@ -157,10 +163,31 @@ static inline int pmd_large(pmd_t pte) {
33099 + (_PAGE_PSE|_PAGE_PRESENT);
33100 + }
33101 +
33102 ++static inline pte_t pte_exprotect(pte_t pte)
33103 ++{
33104 ++#ifdef CONFIG_X86_PAE
33105 ++ if (__supported_pte_mask & _PAGE_NX)
33106 ++ return __pte(pte_val(pte) | _PAGE_NX);
33107 ++ else
33108 ++#endif
33109 ++ return __pte(pte_val(pte) & ~_PAGE_USER);
33110 ++}
33111 ++
33112 + static inline pte_t pte_mkclean(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_DIRTY); }
33113 + static inline pte_t pte_mkold(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_ACCESSED); }
33114 + static inline pte_t pte_wrprotect(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_RW); }
33115 +-static inline pte_t pte_mkexec(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX); }
33116 ++static inline pte_t pte_mkread(pte_t pte) { return __pte(pte_val(pte) | _PAGE_USER); }
33117 ++
33118 ++static inline pte_t pte_mkexec(pte_t pte)
33119 ++{
33120 ++#ifdef CONFIG_X86_PAE
33121 ++ if (__supported_pte_mask & _PAGE_NX)
33122 ++ return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
33123 ++ else
33124 ++#endif
33125 ++ return __pte(pte_val(pte) | _PAGE_USER);
33126 ++}
33127 ++
33128 + static inline pte_t pte_mkdirty(pte_t pte) { return __pte(pte_val(pte) | _PAGE_DIRTY); }
33129 + static inline pte_t pte_mkyoung(pte_t pte) { return __pte(pte_val(pte) | _PAGE_ACCESSED); }
33130 + static inline pte_t pte_mkwrite(pte_t pte) { return __pte(pte_val(pte) | _PAGE_RW); }
33131 +@@ -169,8 +196,6 @@ static inline pte_t pte_clrhuge(pte_t pt
33132 + static inline pte_t pte_mkglobal(pte_t pte) { return __pte(pte_val(pte) | _PAGE_GLOBAL); }
33133 + static inline pte_t pte_clrglobal(pte_t pte) { return __pte(pte_val(pte) & ~(pteval_t)_PAGE_GLOBAL); }
33134 +
33135 +-extern pteval_t __supported_pte_mask;
33136 +-
33137 + static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
33138 + {
33139 + return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
33140 +diff -urNp a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
33141 +--- a/include/asm-x86/pgtable_32.h 2008-08-20 11:16:13.000000000 -0700
33142 ++++ b/include/asm-x86/pgtable_32.h 2008-08-20 18:36:57.000000000 -0700
33143 +@@ -25,8 +25,6 @@
33144 + struct mm_struct;
33145 + struct vm_area_struct;
33146 +
33147 +-extern pgd_t swapper_pg_dir[1024];
33148 +-
33149 + static inline void pgtable_cache_init(void) { }
33150 + static inline void check_pgt_cache(void) { }
33151 + void paging_init(void);
33152 +@@ -45,6 +43,11 @@ void paging_init(void);
33153 + # include <asm/pgtable-2level-defs.h>
33154 + #endif
33155 +
33156 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
33157 ++#ifdef CONFIG_X86_PAE
33158 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
33159 ++#endif
33160 ++
33161 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
33162 + #define PGDIR_MASK (~(PGDIR_SIZE-1))
33163 +
33164 +@@ -83,7 +86,7 @@ void paging_init(void);
33165 + #undef TEST_ACCESS_OK
33166 +
33167 + /* The boot page tables (all created as a single array) */
33168 +-extern unsigned long pg0[];
33169 ++extern pte_t pg0[];
33170 +
33171 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
33172 +
33173 +@@ -113,7 +116,19 @@ extern unsigned long pg0[];
33174 + */
33175 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
33176 + {
33177 +- memcpy(dst, src, count * sizeof(pgd_t));
33178 ++
33179 ++#ifdef CONFIG_PAX_KERNEXEC
33180 ++ unsigned long cr0;
33181 ++
33182 ++ pax_open_kernel(cr0);
33183 ++#endif
33184 ++
33185 ++ memcpy(dst, src, count * sizeof(pgd_t));
33186 ++
33187 ++#ifdef CONFIG_PAX_KERNEXEC
33188 ++ pax_close_kernel(cr0);
33189 ++#endif
33190 ++
33191 + }
33192 +
33193 + /*
33194 +@@ -223,6 +238,9 @@ static inline void paravirt_pagetable_se
33195 +
33196 + #endif /* !__ASSEMBLY__ */
33197 +
33198 ++#define HAVE_ARCH_UNMAPPED_AREA
33199 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
33200 ++
33201 + /*
33202 + * kern_addr_valid() is (1) for FLATMEM and (0) for
33203 + * SPARSEMEM and DISCONTIGMEM
33204 +diff -urNp a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
33205 +--- a/include/asm-x86/pgtable_64.h 2008-08-20 11:16:13.000000000 -0700
33206 ++++ b/include/asm-x86/pgtable_64.h 2008-08-20 18:36:57.000000000 -0700
33207 +@@ -96,7 +96,19 @@ static inline pte_t native_ptep_get_and_
33208 +
33209 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
33210 + {
33211 ++
33212 ++#ifdef CONFIG_PAX_KERNEXEC
33213 ++ unsigned long cr0;
33214 ++
33215 ++ pax_open_kernel(cr0);
33216 ++#endif
33217 ++
33218 + *pmdp = pmd;
33219 ++
33220 ++#ifdef CONFIG_PAX_KERNEXEC
33221 ++ pax_close_kernel(cr0);
33222 ++#endif
33223 ++
33224 + }
33225 +
33226 + static inline void native_pmd_clear(pmd_t *pmd)
33227 +@@ -148,17 +160,17 @@ static inline void native_pgd_clear(pgd_
33228 +
33229 + static inline unsigned long pgd_bad(pgd_t pgd)
33230 + {
33231 +- return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
33232 ++ return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
33233 + }
33234 +
33235 + static inline unsigned long pud_bad(pud_t pud)
33236 + {
33237 +- return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
33238 ++ return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
33239 + }
33240 +
33241 + static inline unsigned long pmd_bad(pmd_t pmd)
33242 + {
33243 +- return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER);
33244 ++ return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_NX);
33245 + }
33246 +
33247 + #define pte_none(x) (!pte_val(x))
33248 +diff -urNp a/include/asm-x86/processor.h b/include/asm-x86/processor.h
33249 +--- a/include/asm-x86/processor.h 2008-08-20 11:16:13.000000000 -0700
33250 ++++ b/include/asm-x86/processor.h 2008-08-20 18:36:57.000000000 -0700
33251 +@@ -236,7 +236,7 @@ struct tss_struct {
33252 + unsigned long stack[64];
33253 + } __attribute__((packed));
33254 +
33255 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
33256 ++extern struct tss_struct init_tss[NR_CPUS];
33257 +
33258 + /* Save the original ist values for checking stack pointers during debugging */
33259 + struct orig_ist {
33260 +@@ -714,11 +714,20 @@ static inline void prefetchw(const void
33261 + * User space process size: 3GB (default).
33262 + */
33263 + #define TASK_SIZE (PAGE_OFFSET)
33264 ++
33265 ++#ifdef CONFIG_PAX_SEGMEXEC
33266 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
33267 ++#endif
33268 ++
33269 ++#ifdef CONFIG_PAX_SEGMEXEC
33270 ++#define STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
33271 ++#else
33272 + #define STACK_TOP TASK_SIZE
33273 +-#define STACK_TOP_MAX STACK_TOP
33274 ++#endif
33275 ++#define STACK_TOP_MAX TASK_SIZE
33276 +
33277 + #define INIT_THREAD { \
33278 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
33279 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
33280 + .vm86_info = NULL, \
33281 + .sysenter_cs = __KERNEL_CS, \
33282 + .io_bitmap_ptr = NULL, \
33283 +@@ -733,7 +742,7 @@ static inline void prefetchw(const void
33284 + */
33285 + #define INIT_TSS { \
33286 + .x86_tss = { \
33287 +- .sp0 = sizeof(init_stack) + (long)&init_stack, \
33288 ++ .sp0 = sizeof(init_stack) + (long)&init_stack - 8, \
33289 + .ss0 = __KERNEL_DS, \
33290 + .ss1 = __KERNEL_CS, \
33291 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
33292 +@@ -757,11 +766,7 @@ static inline void prefetchw(const void
33293 + extern unsigned long thread_saved_pc(struct task_struct *tsk);
33294 +
33295 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
33296 +-#define KSTK_TOP(info) \
33297 +-({ \
33298 +- unsigned long *__ptr = (unsigned long *)(info); \
33299 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
33300 +-})
33301 ++#define KSTK_TOP(info) ((info)->task.thread.sp0)
33302 +
33303 + /*
33304 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
33305 +@@ -776,7 +781,7 @@ extern unsigned long thread_saved_pc(str
33306 + #define task_pt_regs(task) \
33307 + ({ \
33308 + struct pt_regs *__regs__; \
33309 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
33310 ++ __regs__ = (struct pt_regs *)((task)->thread.sp0); \
33311 + __regs__ - 1; \
33312 + })
33313 +
33314 +@@ -792,7 +797,7 @@ extern unsigned long thread_saved_pc(str
33315 + * space during mmap's.
33316 + */
33317 + #define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? \
33318 +- 0xc0000000 : 0xFFFFe000)
33319 ++ 0xc0000000 : 0xFFFFf000)
33320 +
33321 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? \
33322 + IA32_PAGE_OFFSET : TASK_SIZE64)
33323 +@@ -837,6 +842,10 @@ extern unsigned long thread_saved_pc(str
33324 + */
33325 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
33326 +
33327 ++#ifdef CONFIG_PAX_SEGMEXEC
33328 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
33329 ++#endif
33330 ++
33331 + #define KSTK_EIP(task) (task_pt_regs(task)->ip)
33332 +
33333 + #endif
33334 +diff -urNp a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
33335 +--- a/include/asm-x86/ptrace.h 2008-08-20 11:16:13.000000000 -0700
33336 ++++ b/include/asm-x86/ptrace.h 2008-08-20 18:36:57.000000000 -0700
33337 +@@ -56,7 +56,6 @@ struct pt_regs {
33338 + };
33339 +
33340 + #include <asm/vm86.h>
33341 +-#include <asm/segment.h>
33342 +
33343 + #endif /* __KERNEL__ */
33344 +
33345 +@@ -129,6 +128,7 @@ struct pt_regs {
33346 +
33347 + /* the DS BTS struct is used for ptrace as well */
33348 + #include <asm/ds.h>
33349 ++#include <asm/segment.h>
33350 +
33351 + struct task_struct;
33352 +
33353 +@@ -148,28 +148,29 @@ void signal_fault(struct pt_regs *regs,
33354 + #define regs_return_value(regs) ((regs)->ax)
33355 +
33356 + /*
33357 +- * user_mode_vm(regs) determines whether a register set came from user mode.
33358 ++ * user_mode(regs) determines whether a register set came from user mode.
33359 + * This is true if V8086 mode was enabled OR if the register set was from
33360 + * protected mode with RPL-3 CS value. This tricky test checks that with
33361 + * one comparison. Many places in the kernel can bypass this full check
33362 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
33363 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
33364 ++ * be used.
33365 + */
33366 +-static inline int user_mode(struct pt_regs *regs)
33367 ++static inline int user_mode_novm(struct pt_regs *regs)
33368 + {
33369 + #ifdef CONFIG_X86_32
33370 + return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
33371 + #else
33372 +- return !!(regs->cs & 3);
33373 ++ return !!(regs->cs & SEGMENT_RPL_MASK);
33374 + #endif
33375 + }
33376 +
33377 +-static inline int user_mode_vm(struct pt_regs *regs)
33378 ++static inline int user_mode(struct pt_regs *regs)
33379 + {
33380 + #ifdef CONFIG_X86_32
33381 + return ((regs->cs & SEGMENT_RPL_MASK) |
33382 + (regs->flags & VM_MASK)) >= USER_RPL;
33383 + #else
33384 +- return user_mode(regs);
33385 ++ return user_mode_novm(regs);
33386 + #endif
33387 + }
33388 +
33389 +diff -urNp a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h
33390 +--- a/include/asm-x86/reboot.h 2008-08-20 11:16:13.000000000 -0700
33391 ++++ b/include/asm-x86/reboot.h 2008-08-20 18:36:57.000000000 -0700
33392 +@@ -15,6 +15,6 @@ struct machine_ops
33393 +
33394 + extern struct machine_ops machine_ops;
33395 +
33396 +-void machine_real_restart(unsigned char *code, int length);
33397 ++void machine_real_restart(const unsigned char *code, unsigned int length);
33398 +
33399 + #endif /* _ASM_REBOOT_H */
33400 +diff -urNp a/include/asm-x86/segment.h b/include/asm-x86/segment.h
33401 +--- a/include/asm-x86/segment.h 2008-08-20 11:16:13.000000000 -0700
33402 ++++ b/include/asm-x86/segment.h 2008-08-20 18:36:57.000000000 -0700
33403 +@@ -83,13 +83,19 @@
33404 + #define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
33405 + #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
33406 +
33407 +-#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
33408 ++#define GDT_ENTRY_PERCPU (GDT_ENTRY_KERNEL_BASE + 15)
33409 + #ifdef CONFIG_SMP
33410 + #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
33411 + #else
33412 + #define __KERNEL_PERCPU 0
33413 + #endif
33414 +
33415 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
33416 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
33417 ++
33418 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
33419 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
33420 ++
33421 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
33422 +
33423 + /*
33424 +@@ -130,10 +136,10 @@
33425 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
33426 +
33427 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
33428 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
33429 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
33430 +
33431 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
33432 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
33433 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
33434 +
33435 +
33436 + #else
33437 +diff -urNp a/include/asm-x86/system.h b/include/asm-x86/system.h
33438 +--- a/include/asm-x86/system.h 2008-08-20 11:16:13.000000000 -0700
33439 ++++ b/include/asm-x86/system.h 2008-08-20 18:36:57.000000000 -0700
33440 +@@ -70,6 +70,8 @@ struct task_struct *__switch_to(struct t
33441 + ".globl thread_return\n" \
33442 + "thread_return:\n\t" \
33443 + "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
33444 ++ "movq %P[task_canary](%%rsi),%%r8\n\t" \
33445 ++ "movq %%r8,%%gs:%P[pda_canary]\n\t" \
33446 + "movq %P[thread_info](%%rsi),%%r8\n\t" \
33447 + LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
33448 + "movq %%rax,%%rdi\n\t" \
33449 +@@ -81,7 +83,9 @@ struct task_struct *__switch_to(struct t
33450 + [ti_flags] "i" (offsetof(struct thread_info, flags)), \
33451 + [tif_fork] "i" (TIF_FORK), \
33452 + [thread_info] "i" (offsetof(struct task_struct, stack)), \
33453 +- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
33454 ++ [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
33455 ++ [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
33456 ++ [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
33457 + : "memory", "cc" __EXTRA_CLOBBER)
33458 + #endif
33459 +
33460 +@@ -145,7 +149,7 @@ static inline unsigned long get_limit(un
33461 + unsigned long __limit;
33462 + __asm__("lsll %1,%0"
33463 + :"=r" (__limit):"r" (segment));
33464 +- return __limit+1;
33465 ++ return __limit;
33466 + }
33467 +
33468 + static inline void native_clts(void)
33469 +@@ -269,6 +273,21 @@ static inline void native_wbinvd(void)
33470 +
33471 + #define stts() write_cr0(8 | read_cr0())
33472 +
33473 ++#define pax_open_kernel(cr0) \
33474 ++do { \
33475 ++ typecheck(unsigned long, cr0); \
33476 ++ preempt_disable(); \
33477 ++ cr0 = read_cr0(); \
33478 ++ write_cr0(cr0 & ~X86_CR0_WP); \
33479 ++} while (0)
33480 ++
33481 ++#define pax_close_kernel(cr0) \
33482 ++do { \
33483 ++ typecheck(unsigned long, cr0); \
33484 ++ write_cr0(cr0); \
33485 ++ preempt_enable_no_resched(); \
33486 ++} while (0)
33487 ++
33488 + #endif /* __KERNEL__ */
33489 +
33490 + static inline void clflush(volatile void *__p)
33491 +@@ -284,7 +303,7 @@ void enable_hlt(void);
33492 + extern int es7000_plat;
33493 + void cpu_idle_wait(void);
33494 +
33495 +-extern unsigned long arch_align_stack(unsigned long sp);
33496 ++#define arch_align_stack(x) (x)
33497 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
33498 +
33499 + void default_idle(void);
33500 +diff -urNp a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h
33501 +--- a/include/asm-x86/uaccess_32.h 2008-08-20 11:16:13.000000000 -0700
33502 ++++ b/include/asm-x86/uaccess_32.h 2008-08-20 18:36:57.000000000 -0700
33503 +@@ -10,6 +10,7 @@
33504 + #include <linux/string.h>
33505 + #include <asm/asm.h>
33506 + #include <asm/page.h>
33507 ++#include <asm/segment.h>
33508 +
33509 + #define VERIFY_READ 0
33510 + #define VERIFY_WRITE 1
33511 +@@ -30,7 +31,8 @@
33512 +
33513 + #define get_ds() (KERNEL_DS)
33514 + #define get_fs() (current_thread_info()->addr_limit)
33515 +-#define set_fs(x) (current_thread_info()->addr_limit = (x))
33516 ++void __set_fs(mm_segment_t x, int cpu);
33517 ++void set_fs(mm_segment_t x);
33518 +
33519 + #define segment_eq(a,b) ((a).seg == (b).seg)
33520 +
33521 +@@ -102,6 +104,7 @@ struct exception_table_entry
33522 + };
33523 +
33524 + extern int fixup_exception(struct pt_regs *regs);
33525 ++#define ARCH_HAS_SORT_EXTABLE
33526 +
33527 + /*
33528 + * These are the main single-value transfer routines. They automatically
33529 +@@ -281,9 +284,12 @@ extern void __put_user_8(void);
33530 +
33531 + #define __put_user_u64(x, addr, err) \
33532 + __asm__ __volatile__( \
33533 +- "1: movl %%eax,0(%2)\n" \
33534 +- "2: movl %%edx,4(%2)\n" \
33535 ++ " movw %w5,%%ds\n" \
33536 ++ "1: movl %%eax,%%ds:0(%2)\n" \
33537 ++ "2: movl %%edx,%%ds:4(%2)\n" \
33538 + "3:\n" \
33539 ++ " pushl %%ss\n" \
33540 ++ " popl %%ds\n" \
33541 + ".section .fixup,\"ax\"\n" \
33542 + "4: movl %3,%0\n" \
33543 + " jmp 3b\n" \
33544 +@@ -291,7 +297,8 @@ extern void __put_user_8(void);
33545 + _ASM_EXTABLE(1b,4b) \
33546 + _ASM_EXTABLE(2b,4b) \
33547 + : "=r"(err) \
33548 +- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
33549 ++ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
33550 ++ "r"(__USER_DS))
33551 +
33552 + #ifdef CONFIG_X86_WP_WORKS_OK
33553 +
33554 +@@ -330,15 +337,19 @@ struct __large_struct { unsigned long bu
33555 + */
33556 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
33557 + __asm__ __volatile__( \
33558 +- "1: mov"itype" %"rtype"1,%2\n" \
33559 ++ " movw %w5,%%ds\n" \
33560 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
33561 + "2:\n" \
33562 ++ " pushl %%ss\n" \
33563 ++ " popl %%ds\n" \
33564 + ".section .fixup,\"ax\"\n" \
33565 + "3: movl %3,%0\n" \
33566 + " jmp 2b\n" \
33567 + ".previous\n" \
33568 + _ASM_EXTABLE(1b,3b) \
33569 + : "=r"(err) \
33570 +- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
33571 ++ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
33572 ++ "r"(__USER_DS))
33573 +
33574 +
33575 + #define __get_user_nocheck(x,ptr,size) \
33576 +@@ -366,8 +377,11 @@ do { \
33577 +
33578 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
33579 + __asm__ __volatile__( \
33580 +- "1: mov"itype" %2,%"rtype"1\n" \
33581 ++ " movw %w5,%%ds\n" \
33582 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
33583 + "2:\n" \
33584 ++ " pushl %%ss\n" \
33585 ++ " popl %%ds\n" \
33586 + ".section .fixup,\"ax\"\n" \
33587 + "3: movl %3,%0\n" \
33588 + " xor"itype" %"rtype"1,%"rtype"1\n" \
33589 +@@ -375,7 +389,7 @@ do { \
33590 + ".previous\n" \
33591 + _ASM_EXTABLE(1b,3b) \
33592 + : "=r"(err), ltype (x) \
33593 +- : "m"(__m(addr)), "i"(errret), "0"(err))
33594 ++ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
33595 +
33596 +
33597 + unsigned long __must_check __copy_to_user_ll(void __user *to,
33598 +diff -urNp a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h
33599 +--- a/include/asm-x86/uaccess_64.h 2008-08-20 11:16:13.000000000 -0700
33600 ++++ b/include/asm-x86/uaccess_64.h 2008-08-20 18:36:57.000000000 -0700
33601 +@@ -68,6 +68,7 @@ struct exception_table_entry
33602 + extern int fixup_exception(struct pt_regs *regs);
33603 +
33604 + #define ARCH_HAS_SEARCH_EXTABLE
33605 ++#define ARCH_HAS_SORT_EXTABLE
33606 +
33607 + /*
33608 + * These are the main single-value transfer routines. They automatically
33609 +diff -urNp a/include/asm-xtensa/kmap_types.h b/include/asm-xtensa/kmap_types.h
33610 +--- a/include/asm-xtensa/kmap_types.h 2008-08-20 11:16:13.000000000 -0700
33611 ++++ b/include/asm-xtensa/kmap_types.h 2008-08-20 18:36:57.000000000 -0700
33612 +@@ -25,6 +25,7 @@ enum km_type {
33613 + KM_IRQ1,
33614 + KM_SOFTIRQ0,
33615 + KM_SOFTIRQ1,
33616 ++ KM_CLEARPAGE,
33617 + KM_TYPE_NR
33618 + };
33619 +
33620 +diff -urNp a/include/linux/a.out.h b/include/linux/a.out.h
33621 +--- a/include/linux/a.out.h 2008-08-20 11:16:13.000000000 -0700
33622 ++++ b/include/linux/a.out.h 2008-08-20 18:36:57.000000000 -0700
33623 +@@ -41,6 +41,14 @@ enum machine_type {
33624 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
33625 + };
33626 +
33627 ++/* Constants for the N_FLAGS field */
33628 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
33629 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
33630 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
33631 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
33632 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
33633 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
33634 ++
33635 + #if !defined (N_MAGIC)
33636 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
33637 + #endif
33638 +diff -urNp a/include/linux/binfmts.h b/include/linux/binfmts.h
33639 +--- a/include/linux/binfmts.h 2008-08-20 11:16:13.000000000 -0700
33640 ++++ b/include/linux/binfmts.h 2008-08-20 18:36:57.000000000 -0700
33641 +@@ -49,6 +49,7 @@ struct linux_binprm{
33642 + unsigned interp_data;
33643 + unsigned long loader, exec;
33644 + unsigned long argv_len;
33645 ++ int misc;
33646 + };
33647 +
33648 + #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
33649 +@@ -100,5 +101,8 @@ extern void compute_creds(struct linux_b
33650 + extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
33651 + extern int set_binfmt(struct linux_binfmt *new);
33652 +
33653 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
33654 ++void pax_report_insns(void *pc, void *sp);
33655 ++
33656 + #endif /* __KERNEL__ */
33657 + #endif /* _LINUX_BINFMTS_H */
33658 +diff -urNp a/include/linux/cache.h b/include/linux/cache.h
33659 +--- a/include/linux/cache.h 2008-08-20 11:16:13.000000000 -0700
33660 ++++ b/include/linux/cache.h 2008-08-20 18:36:57.000000000 -0700
33661 +@@ -16,6 +16,10 @@
33662 + #define __read_mostly
33663 + #endif
33664 +
33665 ++#ifndef __read_only
33666 ++#define __read_only __read_mostly
33667 ++#endif
33668 ++
33669 + #ifndef ____cacheline_aligned
33670 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
33671 + #endif
33672 +diff -urNp a/include/linux/capability.h b/include/linux/capability.h
33673 +--- a/include/linux/capability.h 2008-08-20 11:16:13.000000000 -0700
33674 ++++ b/include/linux/capability.h 2008-08-20 18:36:57.000000000 -0700
33675 +@@ -501,6 +501,7 @@ extern const kernel_cap_t __cap_full_set
33676 + extern const kernel_cap_t __cap_init_eff_set;
33677 +
33678 + int capable(int cap);
33679 ++int capable_nolog(int cap);
33680 + int __capable(struct task_struct *t, int cap);
33681 +
33682 + extern long cap_prctl_drop(unsigned long cap);
33683 +diff -urNp a/include/linux/elf.h b/include/linux/elf.h
33684 +--- a/include/linux/elf.h 2008-08-20 11:16:13.000000000 -0700
33685 ++++ b/include/linux/elf.h 2008-08-20 18:36:57.000000000 -0700
33686 +@@ -50,6 +50,16 @@ typedef __s64 Elf64_Sxword;
33687 +
33688 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
33689 +
33690 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
33691 ++
33692 ++/* Constants for the e_flags field */
33693 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
33694 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
33695 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
33696 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
33697 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
33698 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
33699 ++
33700 + /* These constants define the different elf file types */
33701 + #define ET_NONE 0
33702 + #define ET_REL 1
33703 +@@ -84,6 +94,8 @@ typedef __s64 Elf64_Sxword;
33704 + #define DT_DEBUG 21
33705 + #define DT_TEXTREL 22
33706 + #define DT_JMPREL 23
33707 ++#define DT_FLAGS 30
33708 ++ #define DF_TEXTREL 0x00000004
33709 + #define DT_ENCODING 32
33710 + #define OLD_DT_LOOS 0x60000000
33711 + #define DT_LOOS 0x6000000d
33712 +@@ -230,6 +242,19 @@ typedef struct elf64_hdr {
33713 + #define PF_W 0x2
33714 + #define PF_X 0x1
33715 +
33716 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
33717 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
33718 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
33719 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
33720 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
33721 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
33722 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
33723 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
33724 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
33725 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
33726 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
33727 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
33728 ++
33729 + typedef struct elf32_phdr{
33730 + Elf32_Word p_type;
33731 + Elf32_Off p_offset;
33732 +@@ -322,6 +347,8 @@ typedef struct elf64_shdr {
33733 + #define EI_OSABI 7
33734 + #define EI_PAD 8
33735 +
33736 ++#define EI_PAX 14
33737 ++
33738 + #define ELFMAG0 0x7f /* EI_MAG */
33739 + #define ELFMAG1 'E'
33740 + #define ELFMAG2 'L'
33741 +@@ -382,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
33742 + #define elf_phdr elf32_phdr
33743 + #define elf_note elf32_note
33744 + #define elf_addr_t Elf32_Off
33745 ++#define elf_dyn Elf32_Dyn
33746 +
33747 + #else
33748 +
33749 +@@ -390,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
33750 + #define elf_phdr elf64_phdr
33751 + #define elf_note elf64_note
33752 + #define elf_addr_t Elf64_Off
33753 ++#define elf_dyn Elf64_Dyn
33754 +
33755 + #endif
33756 +
33757 +diff -urNp a/include/linux/ext4_fs_extents.h b/include/linux/ext4_fs_extents.h
33758 +--- a/include/linux/ext4_fs_extents.h 2008-08-20 11:16:13.000000000 -0700
33759 ++++ b/include/linux/ext4_fs_extents.h 2008-08-20 18:36:57.000000000 -0700
33760 +@@ -50,7 +50,7 @@
33761 + #ifdef EXT_DEBUG
33762 + #define ext_debug(a...) printk(a)
33763 + #else
33764 +-#define ext_debug(a...)
33765 ++#define ext_debug(a...) do {} while (0)
33766 + #endif
33767 +
33768 + /*
33769 +diff -urNp a/include/linux/gracl.h b/include/linux/gracl.h
33770 +--- a/include/linux/gracl.h 1969-12-31 16:00:00.000000000 -0800
33771 ++++ b/include/linux/gracl.h 2008-08-20 18:36:57.000000000 -0700
33772 +@@ -0,0 +1,318 @@
33773 ++#ifndef GR_ACL_H
33774 ++#define GR_ACL_H
33775 ++
33776 ++#include <linux/grdefs.h>
33777 ++#include <linux/resource.h>
33778 ++#include <linux/capability.h>
33779 ++#include <linux/dcache.h>
33780 ++#include <asm/resource.h>
33781 ++
33782 ++/* Major status information */
33783 ++
33784 ++#define GR_VERSION "grsecurity 2.1.12"
33785 ++#define GRSECURITY_VERSION 0x2112
33786 ++
33787 ++enum {
33788 ++
33789 ++ SHUTDOWN = 0,
33790 ++ ENABLE = 1,
33791 ++ SPROLE = 2,
33792 ++ RELOAD = 3,
33793 ++ SEGVMOD = 4,
33794 ++ STATUS = 5,
33795 ++ UNSPROLE = 6,
33796 ++ PASSSET = 7,
33797 ++ SPROLEPAM = 8
33798 ++};
33799 ++
33800 ++/* Password setup definitions
33801 ++ * kernel/grhash.c */
33802 ++enum {
33803 ++ GR_PW_LEN = 128,
33804 ++ GR_SALT_LEN = 16,
33805 ++ GR_SHA_LEN = 32,
33806 ++};
33807 ++
33808 ++enum {
33809 ++ GR_SPROLE_LEN = 64,
33810 ++};
33811 ++
33812 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
33813 ++
33814 ++/* Begin Data Structures */
33815 ++
33816 ++struct sprole_pw {
33817 ++ unsigned char *rolename;
33818 ++ unsigned char salt[GR_SALT_LEN];
33819 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
33820 ++};
33821 ++
33822 ++struct name_entry {
33823 ++ __u32 key;
33824 ++ ino_t inode;
33825 ++ dev_t device;
33826 ++ char *name;
33827 ++ __u16 len;
33828 ++ __u8 deleted;
33829 ++ struct name_entry *prev;
33830 ++ struct name_entry *next;
33831 ++};
33832 ++
33833 ++struct inodev_entry {
33834 ++ struct name_entry *nentry;
33835 ++ struct inodev_entry *prev;
33836 ++ struct inodev_entry *next;
33837 ++};
33838 ++
33839 ++struct acl_role_db {
33840 ++ struct acl_role_label **r_hash;
33841 ++ __u32 r_size;
33842 ++};
33843 ++
33844 ++struct inodev_db {
33845 ++ struct inodev_entry **i_hash;
33846 ++ __u32 i_size;
33847 ++};
33848 ++
33849 ++struct name_db {
33850 ++ struct name_entry **n_hash;
33851 ++ __u32 n_size;
33852 ++};
33853 ++
33854 ++struct crash_uid {
33855 ++ uid_t uid;
33856 ++ unsigned long expires;
33857 ++};
33858 ++
33859 ++struct gr_hash_struct {
33860 ++ void **table;
33861 ++ void **nametable;
33862 ++ void *first;
33863 ++ __u32 table_size;
33864 ++ __u32 used_size;
33865 ++ int type;
33866 ++};
33867 ++
33868 ++/* Userspace Grsecurity ACL data structures */
33869 ++
33870 ++struct acl_subject_label {
33871 ++ char *filename;
33872 ++ ino_t inode;
33873 ++ dev_t device;
33874 ++ __u32 mode;
33875 ++ kernel_cap_t cap_mask;
33876 ++ kernel_cap_t cap_lower;
33877 ++
33878 ++ struct rlimit res[GR_NLIMITS];
33879 ++ __u16 resmask;
33880 ++
33881 ++ __u8 user_trans_type;
33882 ++ __u8 group_trans_type;
33883 ++ uid_t *user_transitions;
33884 ++ gid_t *group_transitions;
33885 ++ __u16 user_trans_num;
33886 ++ __u16 group_trans_num;
33887 ++
33888 ++ __u32 ip_proto[8];
33889 ++ __u32 ip_type;
33890 ++ struct acl_ip_label **ips;
33891 ++ __u32 ip_num;
33892 ++
33893 ++ __u32 crashes;
33894 ++ unsigned long expires;
33895 ++
33896 ++ struct acl_subject_label *parent_subject;
33897 ++ struct gr_hash_struct *hash;
33898 ++ struct acl_subject_label *prev;
33899 ++ struct acl_subject_label *next;
33900 ++
33901 ++ struct acl_object_label **obj_hash;
33902 ++ __u32 obj_hash_size;
33903 ++ __u16 pax_flags;
33904 ++};
33905 ++
33906 ++struct role_allowed_ip {
33907 ++ __u32 addr;
33908 ++ __u32 netmask;
33909 ++
33910 ++ struct role_allowed_ip *prev;
33911 ++ struct role_allowed_ip *next;
33912 ++};
33913 ++
33914 ++struct role_transition {
33915 ++ char *rolename;
33916 ++
33917 ++ struct role_transition *prev;
33918 ++ struct role_transition *next;
33919 ++};
33920 ++
33921 ++struct acl_role_label {
33922 ++ char *rolename;
33923 ++ uid_t uidgid;
33924 ++ __u16 roletype;
33925 ++
33926 ++ __u16 auth_attempts;
33927 ++ unsigned long expires;
33928 ++
33929 ++ struct acl_subject_label *root_label;
33930 ++ struct gr_hash_struct *hash;
33931 ++
33932 ++ struct acl_role_label *prev;
33933 ++ struct acl_role_label *next;
33934 ++
33935 ++ struct role_transition *transitions;
33936 ++ struct role_allowed_ip *allowed_ips;
33937 ++ uid_t *domain_children;
33938 ++ __u16 domain_child_num;
33939 ++
33940 ++ struct acl_subject_label **subj_hash;
33941 ++ __u32 subj_hash_size;
33942 ++};
33943 ++
33944 ++struct user_acl_role_db {
33945 ++ struct acl_role_label **r_table;
33946 ++ __u32 num_pointers; /* Number of allocations to track */
33947 ++ __u32 num_roles; /* Number of roles */
33948 ++ __u32 num_domain_children; /* Number of domain children */
33949 ++ __u32 num_subjects; /* Number of subjects */
33950 ++ __u32 num_objects; /* Number of objects */
33951 ++};
33952 ++
33953 ++struct acl_object_label {
33954 ++ char *filename;
33955 ++ ino_t inode;
33956 ++ dev_t device;
33957 ++ __u32 mode;
33958 ++
33959 ++ struct acl_subject_label *nested;
33960 ++ struct acl_object_label *globbed;
33961 ++
33962 ++ /* next two structures not used */
33963 ++
33964 ++ struct acl_object_label *prev;
33965 ++ struct acl_object_label *next;
33966 ++};
33967 ++
33968 ++struct acl_ip_label {
33969 ++ char *iface;
33970 ++ __u32 addr;
33971 ++ __u32 netmask;
33972 ++ __u16 low, high;
33973 ++ __u8 mode;
33974 ++ __u32 type;
33975 ++ __u32 proto[8];
33976 ++
33977 ++ /* next two structures not used */
33978 ++
33979 ++ struct acl_ip_label *prev;
33980 ++ struct acl_ip_label *next;
33981 ++};
33982 ++
33983 ++struct gr_arg {
33984 ++ struct user_acl_role_db role_db;
33985 ++ unsigned char pw[GR_PW_LEN];
33986 ++ unsigned char salt[GR_SALT_LEN];
33987 ++ unsigned char sum[GR_SHA_LEN];
33988 ++ unsigned char sp_role[GR_SPROLE_LEN];
33989 ++ struct sprole_pw *sprole_pws;
33990 ++ dev_t segv_device;
33991 ++ ino_t segv_inode;
33992 ++ uid_t segv_uid;
33993 ++ __u16 num_sprole_pws;
33994 ++ __u16 mode;
33995 ++};
33996 ++
33997 ++struct gr_arg_wrapper {
33998 ++ struct gr_arg *arg;
33999 ++ __u32 version;
34000 ++ __u32 size;
34001 ++};
34002 ++
34003 ++struct subject_map {
34004 ++ struct acl_subject_label *user;
34005 ++ struct acl_subject_label *kernel;
34006 ++ struct subject_map *prev;
34007 ++ struct subject_map *next;
34008 ++};
34009 ++
34010 ++struct acl_subj_map_db {
34011 ++ struct subject_map **s_hash;
34012 ++ __u32 s_size;
34013 ++};
34014 ++
34015 ++/* End Data Structures Section */
34016 ++
34017 ++/* Hash functions generated by empirical testing by Brad Spengler
34018 ++ Makes good use of the low bits of the inode. Generally 0-1 times
34019 ++ in loop for successful match. 0-3 for unsuccessful match.
34020 ++ Shift/add algorithm with modulus of table size and an XOR*/
34021 ++
34022 ++static __inline__ unsigned int
34023 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
34024 ++{
34025 ++ return (((uid << type) + (uid ^ type)) % sz);
34026 ++}
34027 ++
34028 ++ static __inline__ unsigned int
34029 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
34030 ++{
34031 ++ return ((const unsigned long)userp % sz);
34032 ++}
34033 ++
34034 ++static __inline__ unsigned int
34035 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
34036 ++{
34037 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
34038 ++}
34039 ++
34040 ++static __inline__ unsigned int
34041 ++nhash(const char *name, const __u16 len, const unsigned int sz)
34042 ++{
34043 ++ return full_name_hash(name, len) % sz;
34044 ++}
34045 ++
34046 ++#define FOR_EACH_ROLE_START(role,iter) \
34047 ++ role = NULL; \
34048 ++ iter = 0; \
34049 ++ while (iter < acl_role_set.r_size) { \
34050 ++ if (role == NULL) \
34051 ++ role = acl_role_set.r_hash[iter]; \
34052 ++ if (role == NULL) { \
34053 ++ iter++; \
34054 ++ continue; \
34055 ++ }
34056 ++
34057 ++#define FOR_EACH_ROLE_END(role,iter) \
34058 ++ role = role->next; \
34059 ++ if (role == NULL) \
34060 ++ iter++; \
34061 ++ }
34062 ++
34063 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
34064 ++ subj = NULL; \
34065 ++ iter = 0; \
34066 ++ while (iter < role->subj_hash_size) { \
34067 ++ if (subj == NULL) \
34068 ++ subj = role->subj_hash[iter]; \
34069 ++ if (subj == NULL) { \
34070 ++ iter++; \
34071 ++ continue; \
34072 ++ }
34073 ++
34074 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
34075 ++ subj = subj->next; \
34076 ++ if (subj == NULL) \
34077 ++ iter++; \
34078 ++ }
34079 ++
34080 ++
34081 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
34082 ++ subj = role->hash->first; \
34083 ++ while (subj != NULL) {
34084 ++
34085 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
34086 ++ subj = subj->next; \
34087 ++ }
34088 ++
34089 ++#endif
34090 ++
34091 +diff -urNp a/include/linux/gralloc.h b/include/linux/gralloc.h
34092 +--- a/include/linux/gralloc.h 1969-12-31 16:00:00.000000000 -0800
34093 ++++ b/include/linux/gralloc.h 2008-08-20 18:36:57.000000000 -0700
34094 +@@ -0,0 +1,8 @@
34095 ++#ifndef __GRALLOC_H
34096 ++#define __GRALLOC_H
34097 ++
34098 ++void acl_free_all(void);
34099 ++int acl_alloc_stack_init(unsigned long size);
34100 ++void *acl_alloc(unsigned long len);
34101 ++
34102 ++#endif
34103 +diff -urNp a/include/linux/grdefs.h b/include/linux/grdefs.h
34104 +--- a/include/linux/grdefs.h 1969-12-31 16:00:00.000000000 -0800
34105 ++++ b/include/linux/grdefs.h 2008-08-20 18:36:57.000000000 -0700
34106 +@@ -0,0 +1,131 @@
34107 ++#ifndef GRDEFS_H
34108 ++#define GRDEFS_H
34109 ++
34110 ++/* Begin grsecurity status declarations */
34111 ++
34112 ++enum {
34113 ++ GR_READY = 0x01,
34114 ++ GR_STATUS_INIT = 0x00 // disabled state
34115 ++};
34116 ++
34117 ++/* Begin ACL declarations */
34118 ++
34119 ++/* Role flags */
34120 ++
34121 ++enum {
34122 ++ GR_ROLE_USER = 0x0001,
34123 ++ GR_ROLE_GROUP = 0x0002,
34124 ++ GR_ROLE_DEFAULT = 0x0004,
34125 ++ GR_ROLE_SPECIAL = 0x0008,
34126 ++ GR_ROLE_AUTH = 0x0010,
34127 ++ GR_ROLE_NOPW = 0x0020,
34128 ++ GR_ROLE_GOD = 0x0040,
34129 ++ GR_ROLE_LEARN = 0x0080,
34130 ++ GR_ROLE_TPE = 0x0100,
34131 ++ GR_ROLE_DOMAIN = 0x0200,
34132 ++ GR_ROLE_PAM = 0x0400
34133 ++};
34134 ++
34135 ++/* ACL Subject and Object mode flags */
34136 ++enum {
34137 ++ GR_DELETED = 0x80000000
34138 ++};
34139 ++
34140 ++/* ACL Object-only mode flags */
34141 ++enum {
34142 ++ GR_READ = 0x00000001,
34143 ++ GR_APPEND = 0x00000002,
34144 ++ GR_WRITE = 0x00000004,
34145 ++ GR_EXEC = 0x00000008,
34146 ++ GR_FIND = 0x00000010,
34147 ++ GR_INHERIT = 0x00000020,
34148 ++ GR_SETID = 0x00000040,
34149 ++ GR_CREATE = 0x00000080,
34150 ++ GR_DELETE = 0x00000100,
34151 ++ GR_LINK = 0x00000200,
34152 ++ GR_AUDIT_READ = 0x00000400,
34153 ++ GR_AUDIT_APPEND = 0x00000800,
34154 ++ GR_AUDIT_WRITE = 0x00001000,
34155 ++ GR_AUDIT_EXEC = 0x00002000,
34156 ++ GR_AUDIT_FIND = 0x00004000,
34157 ++ GR_AUDIT_INHERIT= 0x00008000,
34158 ++ GR_AUDIT_SETID = 0x00010000,
34159 ++ GR_AUDIT_CREATE = 0x00020000,
34160 ++ GR_AUDIT_DELETE = 0x00040000,
34161 ++ GR_AUDIT_LINK = 0x00080000,
34162 ++ GR_PTRACERD = 0x00100000,
34163 ++ GR_NOPTRACE = 0x00200000,
34164 ++ GR_SUPPRESS = 0x00400000,
34165 ++ GR_NOLEARN = 0x00800000
34166 ++};
34167 ++
34168 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
34169 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
34170 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
34171 ++
34172 ++/* ACL subject-only mode flags */
34173 ++enum {
34174 ++ GR_KILL = 0x00000001,
34175 ++ GR_VIEW = 0x00000002,
34176 ++ GR_PROTECTED = 0x00000004,
34177 ++ GR_LEARN = 0x00000008,
34178 ++ GR_OVERRIDE = 0x00000010,
34179 ++ /* just a placeholder, this mode is only used in userspace */
34180 ++ GR_DUMMY = 0x00000020,
34181 ++ GR_PROTSHM = 0x00000040,
34182 ++ GR_KILLPROC = 0x00000080,
34183 ++ GR_KILLIPPROC = 0x00000100,
34184 ++ /* just a placeholder, this mode is only used in userspace */
34185 ++ GR_NOTROJAN = 0x00000200,
34186 ++ GR_PROTPROCFD = 0x00000400,
34187 ++ GR_PROCACCT = 0x00000800,
34188 ++ GR_RELAXPTRACE = 0x00001000,
34189 ++ GR_NESTED = 0x00002000,
34190 ++ GR_INHERITLEARN = 0x00004000,
34191 ++ GR_PROCFIND = 0x00008000,
34192 ++ GR_POVERRIDE = 0x00010000,
34193 ++ GR_KERNELAUTH = 0x00020000,
34194 ++};
34195 ++
34196 ++enum {
34197 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
34198 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
34199 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
34200 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
34201 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
34202 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
34203 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
34204 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
34205 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
34206 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
34207 ++};
34208 ++
34209 ++enum {
34210 ++ GR_ID_USER = 0x01,
34211 ++ GR_ID_GROUP = 0x02,
34212 ++};
34213 ++
34214 ++enum {
34215 ++ GR_ID_ALLOW = 0x01,
34216 ++ GR_ID_DENY = 0x02,
34217 ++};
34218 ++
34219 ++#define GR_CRASH_RES 11
34220 ++#define GR_UIDTABLE_MAX 500
34221 ++
34222 ++/* begin resource learning section */
34223 ++enum {
34224 ++ GR_RLIM_CPU_BUMP = 60,
34225 ++ GR_RLIM_FSIZE_BUMP = 50000,
34226 ++ GR_RLIM_DATA_BUMP = 10000,
34227 ++ GR_RLIM_STACK_BUMP = 1000,
34228 ++ GR_RLIM_CORE_BUMP = 10000,
34229 ++ GR_RLIM_RSS_BUMP = 500000,
34230 ++ GR_RLIM_NPROC_BUMP = 1,
34231 ++ GR_RLIM_NOFILE_BUMP = 5,
34232 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
34233 ++ GR_RLIM_AS_BUMP = 500000,
34234 ++ GR_RLIM_LOCKS_BUMP = 2
34235 ++};
34236 ++
34237 ++#endif
34238 +diff -urNp a/include/linux/grinternal.h b/include/linux/grinternal.h
34239 +--- a/include/linux/grinternal.h 1969-12-31 16:00:00.000000000 -0800
34240 ++++ b/include/linux/grinternal.h 2008-08-20 18:36:57.000000000 -0700
34241 +@@ -0,0 +1,210 @@
34242 ++#ifndef __GRINTERNAL_H
34243 ++#define __GRINTERNAL_H
34244 ++
34245 ++#ifdef CONFIG_GRKERNSEC
34246 ++
34247 ++#include <linux/fs.h>
34248 ++#include <linux/gracl.h>
34249 ++#include <linux/grdefs.h>
34250 ++#include <linux/grmsg.h>
34251 ++
34252 ++void gr_add_learn_entry(const char *fmt, ...);
34253 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
34254 ++ const struct vfsmount *mnt);
34255 ++__u32 gr_check_create(const struct dentry *new_dentry,
34256 ++ const struct dentry *parent,
34257 ++ const struct vfsmount *mnt, const __u32 mode);
34258 ++int gr_check_protected_task(const struct task_struct *task);
34259 ++__u32 to_gr_audit(const __u32 reqmode);
34260 ++int gr_set_acls(const int type);
34261 ++
34262 ++int gr_acl_is_enabled(void);
34263 ++char gr_roletype_to_char(void);
34264 ++
34265 ++void gr_handle_alertkill(struct task_struct *task);
34266 ++char *gr_to_filename(const struct dentry *dentry,
34267 ++ const struct vfsmount *mnt);
34268 ++char *gr_to_filename1(const struct dentry *dentry,
34269 ++ const struct vfsmount *mnt);
34270 ++char *gr_to_filename2(const struct dentry *dentry,
34271 ++ const struct vfsmount *mnt);
34272 ++char *gr_to_filename3(const struct dentry *dentry,
34273 ++ const struct vfsmount *mnt);
34274 ++
34275 ++extern int grsec_enable_link;
34276 ++extern int grsec_enable_fifo;
34277 ++extern int grsec_enable_execve;
34278 ++extern int grsec_enable_shm;
34279 ++extern int grsec_enable_execlog;
34280 ++extern int grsec_enable_signal;
34281 ++extern int grsec_enable_forkfail;
34282 ++extern int grsec_enable_time;
34283 ++extern int grsec_enable_chroot_shmat;
34284 ++extern int grsec_enable_chroot_findtask;
34285 ++extern int grsec_enable_chroot_mount;
34286 ++extern int grsec_enable_chroot_double;
34287 ++extern int grsec_enable_chroot_pivot;
34288 ++extern int grsec_enable_chroot_chdir;
34289 ++extern int grsec_enable_chroot_chmod;
34290 ++extern int grsec_enable_chroot_mknod;
34291 ++extern int grsec_enable_chroot_fchdir;
34292 ++extern int grsec_enable_chroot_nice;
34293 ++extern int grsec_enable_chroot_execlog;
34294 ++extern int grsec_enable_chroot_caps;
34295 ++extern int grsec_enable_chroot_sysctl;
34296 ++extern int grsec_enable_chroot_unix;
34297 ++extern int grsec_enable_tpe;
34298 ++extern int grsec_tpe_gid;
34299 ++extern int grsec_enable_tpe_all;
34300 ++extern int grsec_enable_sidcaps;
34301 ++extern int grsec_enable_socket_all;
34302 ++extern int grsec_socket_all_gid;
34303 ++extern int grsec_enable_socket_client;
34304 ++extern int grsec_socket_client_gid;
34305 ++extern int grsec_enable_socket_server;
34306 ++extern int grsec_socket_server_gid;
34307 ++extern int grsec_audit_gid;
34308 ++extern int grsec_enable_group;
34309 ++extern int grsec_enable_audit_ipc;
34310 ++extern int grsec_enable_audit_textrel;
34311 ++extern int grsec_enable_mount;
34312 ++extern int grsec_enable_chdir;
34313 ++extern int grsec_resource_logging;
34314 ++extern int grsec_lock;
34315 ++
34316 ++extern spinlock_t grsec_alert_lock;
34317 ++extern unsigned long grsec_alert_wtime;
34318 ++extern unsigned long grsec_alert_fyet;
34319 ++
34320 ++extern spinlock_t grsec_audit_lock;
34321 ++
34322 ++extern rwlock_t grsec_exec_file_lock;
34323 ++
34324 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
34325 ++ gr_to_filename2(tsk->exec_file->f_path.dentry, \
34326 ++ tsk->exec_file->f_vfsmnt) : "/")
34327 ++
34328 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
34329 ++ gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
34330 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
34331 ++
34332 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
34333 ++ gr_to_filename(tsk->exec_file->f_path.dentry, \
34334 ++ tsk->exec_file->f_vfsmnt) : "/")
34335 ++
34336 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
34337 ++ gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
34338 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
34339 ++
34340 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
34341 ++ ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
34342 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
34343 ++ (tsk_a->fs->root.dentry->d_inode->i_ino != \
34344 ++ tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
34345 ++
34346 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
34347 ++ (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
34348 ++ tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
34349 ++ (tsk_a->fs->root.dentry->d_inode->i_ino == \
34350 ++ tsk_b->fs->root.dentry->d_inode->i_ino))
34351 ++
34352 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
34353 ++ task->pid, task->uid, \
34354 ++ task->euid, task->gid, task->egid, \
34355 ++ gr_parent_task_fullpath(task), \
34356 ++ task->parent->comm, task->parent->pid, \
34357 ++ task->parent->uid, task->parent->euid, \
34358 ++ task->parent->gid, task->parent->egid
34359 ++
34360 ++#define GR_CHROOT_CAPS {{ \
34361 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
34362 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
34363 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
34364 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
34365 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
34366 ++ CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
34367 ++
34368 ++#define security_learn(normal_msg,args...) \
34369 ++({ \
34370 ++ read_lock(&grsec_exec_file_lock); \
34371 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
34372 ++ read_unlock(&grsec_exec_file_lock); \
34373 ++})
34374 ++
34375 ++enum {
34376 ++ GR_DO_AUDIT,
34377 ++ GR_DONT_AUDIT,
34378 ++ GR_DONT_AUDIT_GOOD
34379 ++};
34380 ++
34381 ++enum {
34382 ++ GR_TTYSNIFF,
34383 ++ GR_RBAC,
34384 ++ GR_RBAC_STR,
34385 ++ GR_STR_RBAC,
34386 ++ GR_RBAC_MODE2,
34387 ++ GR_RBAC_MODE3,
34388 ++ GR_FILENAME,
34389 ++ GR_SYSCTL_HIDDEN,
34390 ++ GR_NOARGS,
34391 ++ GR_ONE_INT,
34392 ++ GR_ONE_INT_TWO_STR,
34393 ++ GR_ONE_STR,
34394 ++ GR_STR_INT,
34395 ++ GR_TWO_INT,
34396 ++ GR_THREE_INT,
34397 ++ GR_FIVE_INT_TWO_STR,
34398 ++ GR_TWO_STR,
34399 ++ GR_THREE_STR,
34400 ++ GR_FOUR_STR,
34401 ++ GR_STR_FILENAME,
34402 ++ GR_FILENAME_STR,
34403 ++ GR_FILENAME_TWO_INT,
34404 ++ GR_FILENAME_TWO_INT_STR,
34405 ++ GR_TEXTREL,
34406 ++ GR_PTRACE,
34407 ++ GR_RESOURCE,
34408 ++ GR_CAP,
34409 ++ GR_SIG,
34410 ++ GR_CRASH1,
34411 ++ GR_CRASH2,
34412 ++ GR_PSACCT
34413 ++};
34414 ++
34415 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
34416 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
34417 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
34418 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
34419 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
34420 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
34421 ++#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)
34422 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
34423 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
34424 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
34425 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
34426 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
34427 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
34428 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
34429 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
34430 ++#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)
34431 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
34432 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
34433 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
34434 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
34435 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
34436 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
34437 ++#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)
34438 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
34439 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
34440 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
34441 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
34442 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
34443 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
34444 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
34445 ++#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)
34446 ++
34447 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
34448 ++
34449 ++#endif
34450 ++
34451 ++#endif
34452 +diff -urNp a/include/linux/grmsg.h b/include/linux/grmsg.h
34453 +--- a/include/linux/grmsg.h 1969-12-31 16:00:00.000000000 -0800
34454 ++++ b/include/linux/grmsg.h 2008-08-20 18:36:57.000000000 -0700
34455 +@@ -0,0 +1,108 @@
34456 ++#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"
34457 ++#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"
34458 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
34459 ++#define GR_STOPMOD_MSG "denied modification of module state by "
34460 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
34461 ++#define GR_IOPL_MSG "denied use of iopl() by "
34462 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
34463 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
34464 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
34465 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
34466 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
34467 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
34468 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
34469 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
34470 ++#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"
34471 ++#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"
34472 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
34473 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
34474 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
34475 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
34476 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
34477 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
34478 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
34479 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
34480 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
34481 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
34482 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
34483 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
34484 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
34485 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
34486 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
34487 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
34488 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
34489 ++#define GR_NPROC_MSG "denied overstep of process limit by "
34490 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
34491 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
34492 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
34493 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
34494 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
34495 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
34496 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
34497 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
34498 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
34499 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
34500 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
34501 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
34502 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
34503 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
34504 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
34505 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
34506 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
34507 ++#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"
34508 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
34509 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
34510 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
34511 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
34512 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
34513 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
34514 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
34515 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
34516 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
34517 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
34518 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
34519 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
34520 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
34521 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
34522 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
34523 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
34524 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
34525 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
34526 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
34527 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
34528 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
34529 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
34530 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
34531 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
34532 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
34533 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
34534 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
34535 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
34536 ++#define GR_TIME_MSG "time set by "
34537 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
34538 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
34539 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
34540 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
34541 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
34542 ++#define GR_BIND_MSG "denied bind() by "
34543 ++#define GR_CONNECT_MSG "denied connect() by "
34544 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
34545 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
34546 ++#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"
34547 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
34548 ++#define GR_CAP_ACL_MSG "use of %s denied for "
34549 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
34550 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
34551 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
34552 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
34553 ++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
34554 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
34555 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
34556 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
34557 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
34558 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
34559 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
34560 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
34561 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
34562 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
34563 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
34564 +diff -urNp a/include/linux/grsecurity.h b/include/linux/grsecurity.h
34565 +--- a/include/linux/grsecurity.h 1969-12-31 16:00:00.000000000 -0800
34566 ++++ b/include/linux/grsecurity.h 2008-08-20 18:36:57.000000000 -0700
34567 +@@ -0,0 +1,200 @@
34568 ++#ifndef GR_SECURITY_H
34569 ++#define GR_SECURITY_H
34570 ++#include <linux/fs.h>
34571 ++#include <linux/binfmts.h>
34572 ++#include <linux/gracl.h>
34573 ++
34574 ++/* notify of brain-dead configs */
34575 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
34576 ++#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
34577 ++#endif
34578 ++#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
34579 ++#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
34580 ++#endif
34581 ++#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
34582 ++#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
34583 ++#endif
34584 ++#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
34585 ++#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
34586 ++#endif
34587 ++#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
34588 ++#error "CONFIG_PAX enabled, but no PaX options are enabled."
34589 ++#endif
34590 ++
34591 ++void gr_handle_brute_attach(struct task_struct *p);
34592 ++void gr_handle_brute_check(void);
34593 ++
34594 ++char gr_roletype_to_char(void);
34595 ++
34596 ++int gr_check_user_change(int real, int effective, int fs);
34597 ++int gr_check_group_change(int real, int effective, int fs);
34598 ++
34599 ++void gr_del_task_from_ip_table(struct task_struct *p);
34600 ++
34601 ++int gr_pid_is_chrooted(struct task_struct *p);
34602 ++int gr_handle_chroot_nice(void);
34603 ++int gr_handle_chroot_sysctl(const int op);
34604 ++int gr_handle_chroot_setpriority(struct task_struct *p,
34605 ++ const int niceval);
34606 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
34607 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
34608 ++ const struct vfsmount *mnt);
34609 ++void gr_handle_chroot_caps(struct task_struct *task);
34610 ++void gr_handle_chroot_chdir(struct path *path);
34611 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
34612 ++ const struct vfsmount *mnt, const int mode);
34613 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
34614 ++ const struct vfsmount *mnt, const int mode);
34615 ++int gr_handle_chroot_mount(const struct dentry *dentry,
34616 ++ const struct vfsmount *mnt,
34617 ++ const char *dev_name);
34618 ++int gr_handle_chroot_pivot(void);
34619 ++int gr_handle_chroot_unix(const pid_t pid);
34620 ++
34621 ++int gr_handle_rawio(const struct inode *inode);
34622 ++int gr_handle_nproc(void);
34623 ++
34624 ++void gr_handle_ioperm(void);
34625 ++void gr_handle_iopl(void);
34626 ++
34627 ++int gr_tpe_allow(const struct file *file);
34628 ++
34629 ++int gr_random_pid(void);
34630 ++
34631 ++void gr_log_forkfail(const int retval);
34632 ++void gr_log_timechange(void);
34633 ++void gr_log_signal(const int sig, const struct task_struct *t);
34634 ++void gr_log_chdir(const struct dentry *dentry,
34635 ++ const struct vfsmount *mnt);
34636 ++void gr_log_chroot_exec(const struct dentry *dentry,
34637 ++ const struct vfsmount *mnt);
34638 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
34639 ++void gr_log_remount(const char *devname, const int retval);
34640 ++void gr_log_unmount(const char *devname, const int retval);
34641 ++void gr_log_mount(const char *from, const char *to, const int retval);
34642 ++void gr_log_msgget(const int ret, const int msgflg);
34643 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
34644 ++void gr_log_semget(const int err, const int semflg);
34645 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
34646 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
34647 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
34648 ++void gr_log_textrel(struct vm_area_struct *vma);
34649 ++
34650 ++int gr_handle_follow_link(const struct inode *parent,
34651 ++ const struct inode *inode,
34652 ++ const struct dentry *dentry,
34653 ++ const struct vfsmount *mnt);
34654 ++int gr_handle_fifo(const struct dentry *dentry,
34655 ++ const struct vfsmount *mnt,
34656 ++ const struct dentry *dir, const int flag,
34657 ++ const int acc_mode);
34658 ++int gr_handle_hardlink(const struct dentry *dentry,
34659 ++ const struct vfsmount *mnt,
34660 ++ struct inode *inode,
34661 ++ const int mode, const char *to);
34662 ++
34663 ++int gr_task_is_capable(struct task_struct *task, const int cap);
34664 ++int gr_is_capable_nolog(const int cap);
34665 ++void gr_learn_resource(const struct task_struct *task, const int limit,
34666 ++ const unsigned long wanted, const int gt);
34667 ++void gr_copy_label(struct task_struct *tsk);
34668 ++void gr_handle_crash(struct task_struct *task, const int sig);
34669 ++int gr_handle_signal(const struct task_struct *p, const int sig);
34670 ++int gr_check_crash_uid(const uid_t uid);
34671 ++int gr_check_protected_task(const struct task_struct *task);
34672 ++int gr_acl_handle_mmap(const struct file *file,
34673 ++ const unsigned long prot);
34674 ++int gr_acl_handle_mprotect(const struct file *file,
34675 ++ const unsigned long prot);
34676 ++int gr_check_hidden_task(const struct task_struct *tsk);
34677 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
34678 ++ const struct vfsmount *mnt);
34679 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
34680 ++ const struct vfsmount *mnt);
34681 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
34682 ++ const struct vfsmount *mnt, const int fmode);
34683 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
34684 ++ const struct vfsmount *mnt, mode_t mode);
34685 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
34686 ++ const struct vfsmount *mnt, mode_t mode);
34687 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
34688 ++ const struct vfsmount *mnt);
34689 ++int gr_handle_ptrace(struct task_struct *task, const long request);
34690 ++int gr_handle_proc_ptrace(struct task_struct *task);
34691 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
34692 ++ const struct vfsmount *mnt);
34693 ++int gr_check_crash_exec(const struct file *filp);
34694 ++int gr_acl_is_enabled(void);
34695 ++void gr_set_kernel_label(struct task_struct *task);
34696 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
34697 ++ const gid_t gid);
34698 ++int gr_set_proc_label(const struct dentry *dentry,
34699 ++ const struct vfsmount *mnt);
34700 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
34701 ++ const struct vfsmount *mnt);
34702 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
34703 ++ const struct vfsmount *mnt, const int fmode);
34704 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
34705 ++ const struct dentry *p_dentry,
34706 ++ const struct vfsmount *p_mnt, const int fmode,
34707 ++ const int imode);
34708 ++void gr_handle_create(const struct dentry *dentry,
34709 ++ const struct vfsmount *mnt);
34710 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
34711 ++ const struct dentry *parent_dentry,
34712 ++ const struct vfsmount *parent_mnt,
34713 ++ const int mode);
34714 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
34715 ++ const struct dentry *parent_dentry,
34716 ++ const struct vfsmount *parent_mnt);
34717 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
34718 ++ const struct vfsmount *mnt);
34719 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
34720 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
34721 ++ const struct vfsmount *mnt);
34722 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
34723 ++ const struct dentry *parent_dentry,
34724 ++ const struct vfsmount *parent_mnt,
34725 ++ const char *from);
34726 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
34727 ++ const struct dentry *parent_dentry,
34728 ++ const struct vfsmount *parent_mnt,
34729 ++ const struct dentry *old_dentry,
34730 ++ const struct vfsmount *old_mnt, const char *to);
34731 ++int gr_acl_handle_rename(struct dentry *new_dentry,
34732 ++ struct dentry *parent_dentry,
34733 ++ const struct vfsmount *parent_mnt,
34734 ++ struct dentry *old_dentry,
34735 ++ struct inode *old_parent_inode,
34736 ++ struct vfsmount *old_mnt, const char *newname);
34737 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
34738 ++ struct dentry *old_dentry,
34739 ++ struct dentry *new_dentry,
34740 ++ struct vfsmount *mnt, const __u8 replace);
34741 ++__u32 gr_check_link(const struct dentry *new_dentry,
34742 ++ const struct dentry *parent_dentry,
34743 ++ const struct vfsmount *parent_mnt,
34744 ++ const struct dentry *old_dentry,
34745 ++ const struct vfsmount *old_mnt);
34746 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
34747 ++ const unsigned int namelen, const ino_t ino);
34748 ++
34749 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
34750 ++ const struct vfsmount *mnt);
34751 ++void gr_acl_handle_exit(void);
34752 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
34753 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
34754 ++
34755 ++#ifdef CONFIG_GRKERNSEC
34756 ++void gr_handle_mem_write(void);
34757 ++void gr_handle_kmem_write(void);
34758 ++void gr_handle_open_port(void);
34759 ++int gr_handle_mem_mmap(const unsigned long offset,
34760 ++ struct vm_area_struct *vma);
34761 ++
34762 ++extern int grsec_enable_dmesg;
34763 ++extern int grsec_enable_randsrc;
34764 ++extern int grsec_enable_shm;
34765 ++#endif
34766 ++
34767 ++#endif
34768 +diff -urNp a/include/linux/highmem.h b/include/linux/highmem.h
34769 +--- a/include/linux/highmem.h 2008-08-20 11:16:13.000000000 -0700
34770 ++++ b/include/linux/highmem.h 2008-08-20 18:36:57.000000000 -0700
34771 +@@ -122,6 +122,13 @@ static inline void clear_highpage(struct
34772 + kunmap_atomic(kaddr, KM_USER0);
34773 + }
34774 +
34775 ++static inline void sanitize_highpage(struct page *page)
34776 ++{
34777 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
34778 ++ clear_page(kaddr);
34779 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
34780 ++}
34781 ++
34782 + static inline void zero_user_segments(struct page *page,
34783 + unsigned start1, unsigned end1,
34784 + unsigned start2, unsigned end2)
34785 +diff -urNp a/include/linux/irqflags.h b/include/linux/irqflags.h
34786 +--- a/include/linux/irqflags.h 2008-08-20 11:16:13.000000000 -0700
34787 ++++ b/include/linux/irqflags.h 2008-08-20 18:36:57.000000000 -0700
34788 +@@ -84,10 +84,10 @@
34789 +
34790 + #define irqs_disabled() \
34791 + ({ \
34792 +- unsigned long flags; \
34793 ++ unsigned long __flags; \
34794 + \
34795 +- raw_local_save_flags(flags); \
34796 +- raw_irqs_disabled_flags(flags); \
34797 ++ raw_local_save_flags(__flags); \
34798 ++ raw_irqs_disabled_flags(__flags); \
34799 + })
34800 +
34801 + #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
34802 +diff -urNp a/include/linux/jbd.h b/include/linux/jbd.h
34803 +--- a/include/linux/jbd.h 2008-08-20 11:16:13.000000000 -0700
34804 ++++ b/include/linux/jbd.h 2008-08-20 18:36:57.000000000 -0700
34805 +@@ -68,7 +68,7 @@ extern u8 journal_enable_debug;
34806 + } \
34807 + } while (0)
34808 + #else
34809 +-#define jbd_debug(f, a...) /**/
34810 ++#define jbd_debug(f, a...) do {} while (0)
34811 + #endif
34812 +
34813 + static inline void *jbd_alloc(size_t size, gfp_t flags)
34814 +diff -urNp a/include/linux/jbd2.h b/include/linux/jbd2.h
34815 +--- a/include/linux/jbd2.h 2008-08-20 11:16:13.000000000 -0700
34816 ++++ b/include/linux/jbd2.h 2008-08-20 18:36:57.000000000 -0700
34817 +@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
34818 + } \
34819 + } while (0)
34820 + #else
34821 +-#define jbd_debug(f, a...) /**/
34822 ++#define jbd_debug(f, a...) do {} while (0)
34823 + #endif
34824 +
34825 + static inline void *jbd2_alloc(size_t size, gfp_t flags)
34826 +diff -urNp a/include/linux/libata.h b/include/linux/libata.h
34827 +--- a/include/linux/libata.h 2008-08-20 11:16:13.000000000 -0700
34828 ++++ b/include/linux/libata.h 2008-08-20 18:36:57.000000000 -0700
34829 +@@ -63,11 +63,11 @@
34830 + #ifdef ATA_VERBOSE_DEBUG
34831 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
34832 + #else
34833 +-#define VPRINTK(fmt, args...)
34834 ++#define VPRINTK(fmt, args...) do {} while (0)
34835 + #endif /* ATA_VERBOSE_DEBUG */
34836 + #else
34837 +-#define DPRINTK(fmt, args...)
34838 +-#define VPRINTK(fmt, args...)
34839 ++#define DPRINTK(fmt, args...) do {} while (0)
34840 ++#define VPRINTK(fmt, args...) do {} while (0)
34841 + #endif /* ATA_DEBUG */
34842 +
34843 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
34844 +diff -urNp a/include/linux/mm.h b/include/linux/mm.h
34845 +--- a/include/linux/mm.h 2008-08-20 11:16:13.000000000 -0700
34846 ++++ b/include/linux/mm.h 2008-08-20 18:36:57.000000000 -0700
34847 +@@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
34848 + #include <asm/page.h>
34849 + #include <asm/pgtable.h>
34850 + #include <asm/processor.h>
34851 ++#include <asm/mman.h>
34852 +
34853 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
34854 +
34855 +@@ -108,6 +109,14 @@ extern unsigned int kobjsize(const void
34856 +
34857 + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
34858 +
34859 ++#ifdef CONFIG_PAX_PAGEEXEC
34860 ++#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
34861 ++#endif
34862 ++
34863 ++#ifdef CONFIG_PAX_MPROTECT
34864 ++#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
34865 ++#endif
34866 ++
34867 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
34868 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
34869 + #endif
34870 +@@ -836,6 +845,8 @@ struct shrinker {
34871 + extern void register_shrinker(struct shrinker *);
34872 + extern void unregister_shrinker(struct shrinker *);
34873 +
34874 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
34875 ++
34876 + int vma_wants_writenotify(struct vm_area_struct *vma);
34877 +
34878 + extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
34879 +@@ -1074,6 +1085,7 @@ out:
34880 + }
34881 +
34882 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
34883 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
34884 +
34885 + extern unsigned long do_brk(unsigned long, unsigned long);
34886 +
34887 +@@ -1126,6 +1138,10 @@ extern struct vm_area_struct * find_vma(
34888 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
34889 + struct vm_area_struct **pprev);
34890 +
34891 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
34892 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
34893 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
34894 ++
34895 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
34896 + NULL if none. Assume start_addr < end_addr. */
34897 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
34898 +@@ -1142,7 +1158,6 @@ static inline unsigned long vma_pages(st
34899 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
34900 + }
34901 +
34902 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
34903 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
34904 + int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
34905 + unsigned long pfn, unsigned long size, pgprot_t);
34906 +@@ -1230,5 +1245,11 @@ int vmemmap_populate_basepages(struct pa
34907 + unsigned long pages, int node);
34908 + int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
34909 +
34910 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
34911 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
34912 ++#else
34913 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
34914 ++#endif
34915 ++
34916 + #endif /* __KERNEL__ */
34917 + #endif /* _LINUX_MM_H */
34918 +diff -urNp a/include/linux/mm_types.h b/include/linux/mm_types.h
34919 +--- a/include/linux/mm_types.h 2008-08-20 11:16:13.000000000 -0700
34920 ++++ b/include/linux/mm_types.h 2008-08-20 18:36:57.000000000 -0700
34921 +@@ -154,6 +154,8 @@ struct vm_area_struct {
34922 + #ifdef CONFIG_NUMA
34923 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
34924 + #endif
34925 ++
34926 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
34927 + };
34928 +
34929 + struct mm_struct {
34930 +@@ -225,6 +227,24 @@ struct mm_struct {
34931 + #ifdef CONFIG_CGROUP_MEM_RES_CTLR
34932 + struct mem_cgroup *mem_cgroup;
34933 + #endif
34934 ++
34935 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
34936 ++ unsigned long pax_flags;
34937 ++#endif
34938 ++
34939 ++#ifdef CONFIG_PAX_DLRESOLVE
34940 ++ unsigned long call_dl_resolve;
34941 ++#endif
34942 ++
34943 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
34944 ++ unsigned long call_syscall;
34945 ++#endif
34946 ++
34947 ++#ifdef CONFIG_PAX_ASLR
34948 ++ unsigned long delta_mmap; /* randomized offset */
34949 ++ unsigned long delta_stack; /* randomized offset */
34950 ++#endif
34951 ++
34952 + };
34953 +
34954 + #endif /* _LINUX_MM_TYPES_H */
34955 +diff -urNp a/include/linux/module.h b/include/linux/module.h
34956 +--- a/include/linux/module.h 2008-08-20 11:16:13.000000000 -0700
34957 ++++ b/include/linux/module.h 2008-08-20 18:36:57.000000000 -0700
34958 +@@ -296,16 +296,16 @@ struct module
34959 + int (*init)(void);
34960 +
34961 + /* If this is non-NULL, vfree after init() returns */
34962 +- void *module_init;
34963 ++ void *module_init_rx, *module_init_rw;
34964 +
34965 + /* Here is the actual code + data, vfree'd on unload. */
34966 +- void *module_core;
34967 ++ void *module_core_rx, *module_core_rw;
34968 +
34969 + /* Here are the sizes of the init and core sections */
34970 +- unsigned long init_size, core_size;
34971 ++ unsigned long init_size_rw, core_size_rw;
34972 +
34973 + /* The size of the executable code in each section. */
34974 +- unsigned long init_text_size, core_text_size;
34975 ++ unsigned long init_size_rx, core_size_rx;
34976 +
34977 + /* The handle returned from unwind_add_table. */
34978 + void *unwind_info;
34979 +diff -urNp a/include/linux/moduleloader.h b/include/linux/moduleloader.h
34980 +--- a/include/linux/moduleloader.h 2008-08-20 11:16:13.000000000 -0700
34981 ++++ b/include/linux/moduleloader.h 2008-08-20 18:36:57.000000000 -0700
34982 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
34983 + sections. Returns NULL on failure. */
34984 + void *module_alloc(unsigned long size);
34985 +
34986 ++#ifdef CONFIG_PAX_KERNEXEC
34987 ++void *module_alloc_exec(unsigned long size);
34988 ++#else
34989 ++#define module_alloc_exec(x) module_alloc(x)
34990 ++#endif
34991 ++
34992 + /* Free memory returned from module_alloc. */
34993 + void module_free(struct module *mod, void *module_region);
34994 +
34995 ++#ifdef CONFIG_PAX_KERNEXEC
34996 ++void module_free_exec(struct module *mod, void *module_region);
34997 ++#else
34998 ++#define module_free_exec(x, y) module_free(x, y)
34999 ++#endif
35000 ++
35001 + /* Apply the given relocation to the (simplified) ELF. Return -error
35002 + or 0. */
35003 + int apply_relocate(Elf_Shdr *sechdrs,
35004 +diff -urNp a/include/linux/namei.h b/include/linux/namei.h
35005 +--- a/include/linux/namei.h 2008-08-20 11:16:13.000000000 -0700
35006 ++++ b/include/linux/namei.h 2008-08-20 18:36:57.000000000 -0700
35007 +@@ -21,7 +21,7 @@ struct nameidata {
35008 + unsigned int flags;
35009 + int last_type;
35010 + unsigned depth;
35011 +- char *saved_names[MAX_NESTED_LINKS + 1];
35012 ++ const char *saved_names[MAX_NESTED_LINKS + 1];
35013 +
35014 + /* Intent data */
35015 + union {
35016 +@@ -83,12 +83,12 @@ extern int follow_up(struct vfsmount **,
35017 + extern struct dentry *lock_rename(struct dentry *, struct dentry *);
35018 + extern void unlock_rename(struct dentry *, struct dentry *);
35019 +
35020 +-static inline void nd_set_link(struct nameidata *nd, char *path)
35021 ++static inline void nd_set_link(struct nameidata *nd, const char *path)
35022 + {
35023 + nd->saved_names[nd->depth] = path;
35024 + }
35025 +
35026 +-static inline char *nd_get_link(struct nameidata *nd)
35027 ++static inline const char *nd_get_link(struct nameidata *nd)
35028 + {
35029 + return nd->saved_names[nd->depth];
35030 + }
35031 +diff -urNp a/include/linux/percpu.h b/include/linux/percpu.h
35032 +--- a/include/linux/percpu.h 2008-08-20 11:16:13.000000000 -0700
35033 ++++ b/include/linux/percpu.h 2008-08-20 18:36:57.000000000 -0700
35034 +@@ -38,7 +38,7 @@
35035 + #endif
35036 +
35037 + #define PERCPU_ENOUGH_ROOM \
35038 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
35039 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
35040 + #endif /* PERCPU_ENOUGH_ROOM */
35041 +
35042 + /*
35043 +diff -urNp a/include/linux/poison.h b/include/linux/poison.h
35044 +--- a/include/linux/poison.h 2008-08-20 11:16:13.000000000 -0700
35045 ++++ b/include/linux/poison.h 2008-08-20 18:36:57.000000000 -0700
35046 +@@ -7,8 +7,8 @@
35047 + * under normal circumstances, used to verify that nobody uses
35048 + * non-initialized list entries.
35049 + */
35050 +-#define LIST_POISON1 ((void *) 0x00100100)
35051 +-#define LIST_POISON2 ((void *) 0x00200200)
35052 ++#define LIST_POISON1 ((void *) 0xFF1001FFFF1001FFULL)
35053 ++#define LIST_POISON2 ((void *) 0xFF2002FFFF2002FFULL)
35054 +
35055 + /********** mm/slab.c **********/
35056 + /*
35057 +diff -urNp a/include/linux/random.h b/include/linux/random.h
35058 +--- a/include/linux/random.h 2008-08-20 11:16:13.000000000 -0700
35059 ++++ b/include/linux/random.h 2008-08-20 18:36:57.000000000 -0700
35060 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
35061 + u32 random32(void);
35062 + void srandom32(u32 seed);
35063 +
35064 ++static inline unsigned long pax_get_random_long(void)
35065 ++{
35066 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
35067 ++}
35068 ++
35069 + #endif /* __KERNEL___ */
35070 +
35071 + #endif /* _LINUX_RANDOM_H */
35072 +diff -urNp a/include/linux/sched.h b/include/linux/sched.h
35073 +--- a/include/linux/sched.h 2008-08-20 11:16:13.000000000 -0700
35074 ++++ b/include/linux/sched.h 2008-08-20 18:36:57.000000000 -0700
35075 +@@ -97,6 +97,7 @@ struct exec_domain;
35076 + struct futex_pi_state;
35077 + struct robust_list_head;
35078 + struct bio;
35079 ++struct linux_binprm;
35080 +
35081 + /*
35082 + * List of flags we want to share for kernel threads,
35083 +@@ -542,6 +543,15 @@ struct signal_struct {
35084 + unsigned audit_tty;
35085 + struct tty_audit_buf *tty_audit_buf;
35086 + #endif
35087 ++
35088 ++#ifdef CONFIG_GRKERNSEC
35089 ++ u32 curr_ip;
35090 ++ u32 gr_saddr;
35091 ++ u32 gr_daddr;
35092 ++ u16 gr_sport;
35093 ++ u16 gr_dport;
35094 ++ u8 used_accept:1;
35095 ++#endif
35096 + };
35097 +
35098 + /* Context switch must be unlocked if interrupts are to be enabled */
35099 +@@ -993,7 +1003,7 @@ struct sched_rt_entity {
35100 +
35101 + struct task_struct {
35102 + volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
35103 +- void *stack;
35104 ++ struct thread_info *stack;
35105 + atomic_t usage;
35106 + unsigned int flags; /* per process flags, defined below */
35107 + unsigned int ptrace;
35108 +@@ -1063,10 +1073,9 @@ struct task_struct {
35109 + pid_t pid;
35110 + pid_t tgid;
35111 +
35112 +-#ifdef CONFIG_CC_STACKPROTECTOR
35113 + /* Canary value for the -fstack-protector gcc feature */
35114 + unsigned long stack_canary;
35115 +-#endif
35116 ++
35117 + /*
35118 + * pointers to (original) parent process, youngest child, younger sibling,
35119 + * older sibling, respectively. (p->father can be replaced with
35120 +@@ -1087,8 +1096,8 @@ struct task_struct {
35121 + struct list_head thread_group;
35122 +
35123 + struct completion *vfork_done; /* for vfork() */
35124 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
35125 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
35126 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
35127 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
35128 +
35129 + unsigned int rt_priority;
35130 + cputime_t utime, stime, utimescaled, stimescaled;
35131 +@@ -1271,8 +1280,60 @@ struct task_struct {
35132 + int latency_record_count;
35133 + struct latency_record latency_record[LT_SAVECOUNT];
35134 + #endif
35135 ++
35136 ++#ifdef CONFIG_GRKERNSEC
35137 ++ /* grsecurity */
35138 ++ struct acl_subject_label *acl;
35139 ++ struct acl_role_label *role;
35140 ++ struct file *exec_file;
35141 ++ u16 acl_role_id;
35142 ++ u8 acl_sp_role;
35143 ++ u8 is_writable;
35144 ++ u8 brute;
35145 ++#endif
35146 ++
35147 + };
35148 +
35149 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
35150 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
35151 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
35152 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
35153 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
35154 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
35155 ++
35156 ++#ifdef CONFIG_PAX_SOFTMODE
35157 ++extern unsigned int pax_softmode;
35158 ++#endif
35159 ++
35160 ++extern int pax_check_flags(unsigned long *);
35161 ++
35162 ++/* if tsk != current then task_lock must be held on it */
35163 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
35164 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
35165 ++{
35166 ++ if (likely(tsk->mm))
35167 ++ return tsk->mm->pax_flags;
35168 ++ else
35169 ++ return 0UL;
35170 ++}
35171 ++
35172 ++/* if tsk != current then task_lock must be held on it */
35173 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
35174 ++{
35175 ++ if (likely(tsk->mm)) {
35176 ++ tsk->mm->pax_flags = flags;
35177 ++ return 0;
35178 ++ }
35179 ++ return -EINVAL;
35180 ++}
35181 ++#endif
35182 ++
35183 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
35184 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
35185 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
35186 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
35187 ++#endif
35188 ++
35189 + /*
35190 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
35191 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
35192 +@@ -1775,7 +1836,7 @@ extern void __cleanup_signal(struct sign
35193 + extern void __cleanup_sighand(struct sighand_struct *);
35194 + extern void exit_itimers(struct signal_struct *);
35195 +
35196 +-extern NORET_TYPE void do_group_exit(int);
35197 ++extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
35198 +
35199 + extern void daemonize(const char *, ...);
35200 + extern int allow_signal(int);
35201 +@@ -1877,8 +1938,8 @@ static inline void unlock_task_sighand(s
35202 +
35203 + #ifndef __HAVE_THREAD_FUNCTIONS
35204 +
35205 +-#define task_thread_info(task) ((struct thread_info *)(task)->stack)
35206 +-#define task_stack_page(task) ((task)->stack)
35207 ++#define task_thread_info(task) ((task)->stack)
35208 ++#define task_stack_page(task) ((void *)(task)->stack)
35209 +
35210 + static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
35211 + {
35212 +@@ -2026,6 +2087,12 @@ extern void arch_pick_mmap_layout(struct
35213 + static inline void arch_pick_mmap_layout(struct mm_struct *mm)
35214 + {
35215 + mm->mmap_base = TASK_UNMAPPED_BASE;
35216 ++
35217 ++#ifdef CONFIG_PAX_RANDMMAP
35218 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
35219 ++ mm->mmap_base += mm->delta_mmap;
35220 ++#endif
35221 ++
35222 + mm->get_unmapped_area = arch_get_unmapped_area;
35223 + mm->unmap_area = arch_unmap_area;
35224 + }
35225 +diff -urNp a/include/linux/screen_info.h b/include/linux/screen_info.h
35226 +--- a/include/linux/screen_info.h 2008-08-20 11:16:13.000000000 -0700
35227 ++++ b/include/linux/screen_info.h 2008-08-20 18:36:57.000000000 -0700
35228 +@@ -42,7 +42,8 @@ struct screen_info {
35229 + __u16 pages; /* 0x32 */
35230 + __u16 vesa_attributes; /* 0x34 */
35231 + __u32 capabilities; /* 0x36 */
35232 +- __u8 _reserved[6]; /* 0x3a */
35233 ++ __u16 vesapm_size; /* 0x3a */
35234 ++ __u8 _reserved[4]; /* 0x3c */
35235 + } __attribute__((packed));
35236 +
35237 + #define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
35238 +diff -urNp a/include/linux/shm.h b/include/linux/shm.h
35239 +--- a/include/linux/shm.h 2008-08-20 11:16:13.000000000 -0700
35240 ++++ b/include/linux/shm.h 2008-08-20 18:36:57.000000000 -0700
35241 +@@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
35242 + pid_t shm_cprid;
35243 + pid_t shm_lprid;
35244 + struct user_struct *mlock_user;
35245 ++#ifdef CONFIG_GRKERNSEC
35246 ++ time_t shm_createtime;
35247 ++ pid_t shm_lapid;
35248 ++#endif
35249 + };
35250 +
35251 + /* shm_mode upper byte flags */
35252 +diff -urNp a/include/linux/sysctl.h b/include/linux/sysctl.h
35253 +--- a/include/linux/sysctl.h 2008-08-20 11:16:13.000000000 -0700
35254 ++++ b/include/linux/sysctl.h 2008-08-20 18:36:57.000000000 -0700
35255 +@@ -163,9 +163,21 @@ enum
35256 + KERN_MAX_LOCK_DEPTH=74,
35257 + KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
35258 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
35259 +-};
35260 ++#ifdef CONFIG_GRKERNSEC
35261 ++ KERN_GRSECURITY=98, /* grsecurity */
35262 ++#endif
35263 ++
35264 ++#ifdef CONFIG_PAX_SOFTMODE
35265 ++ KERN_PAX=99, /* PaX control */
35266 ++#endif
35267 +
35268 ++};
35269 +
35270 ++#ifdef CONFIG_PAX_SOFTMODE
35271 ++enum {
35272 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
35273 ++};
35274 ++#endif
35275 +
35276 + /* CTL_VM names: */
35277 + enum
35278 +diff -urNp a/include/linux/uaccess.h b/include/linux/uaccess.h
35279 +--- a/include/linux/uaccess.h 2008-08-20 11:16:13.000000000 -0700
35280 ++++ b/include/linux/uaccess.h 2008-08-20 18:36:57.000000000 -0700
35281 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
35282 + long ret; \
35283 + mm_segment_t old_fs = get_fs(); \
35284 + \
35285 +- set_fs(KERNEL_DS); \
35286 + pagefault_disable(); \
35287 ++ set_fs(KERNEL_DS); \
35288 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
35289 +- pagefault_enable(); \
35290 + set_fs(old_fs); \
35291 ++ pagefault_enable(); \
35292 + ret; \
35293 + })
35294 +
35295 +diff -urNp a/include/linux/udf_fs.h b/include/linux/udf_fs.h
35296 +--- a/include/linux/udf_fs.h 2008-08-20 11:16:13.000000000 -0700
35297 ++++ b/include/linux/udf_fs.h 2008-08-20 18:36:57.000000000 -0700
35298 +@@ -42,7 +42,7 @@
35299 + printk (f, ##a); \
35300 + } while (0)
35301 + #else
35302 +-#define udf_debug(f, a...) /**/
35303 ++#define udf_debug(f, a...) do {} while (0)
35304 + #endif
35305 +
35306 + #define udf_info(f, a...) \
35307 +diff -urNp a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
35308 +--- a/include/net/sctp/sctp.h 2008-08-20 11:16:13.000000000 -0700
35309 ++++ b/include/net/sctp/sctp.h 2008-08-20 18:36:57.000000000 -0700
35310 +@@ -309,8 +309,8 @@ extern int sctp_debug_flag;
35311 +
35312 + #else /* SCTP_DEBUG */
35313 +
35314 +-#define SCTP_DEBUG_PRINTK(whatever...)
35315 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
35316 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
35317 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
35318 + #define SCTP_ENABLE_DEBUG
35319 + #define SCTP_DISABLE_DEBUG
35320 + #define SCTP_ASSERT(expr, str, func)
35321 +diff -urNp a/include/sound/core.h b/include/sound/core.h
35322 +--- a/include/sound/core.h 2008-08-20 11:16:13.000000000 -0700
35323 ++++ b/include/sound/core.h 2008-08-20 18:36:57.000000000 -0700
35324 +@@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
35325 +
35326 + #else /* !CONFIG_SND_DEBUG */
35327 +
35328 +-#define snd_printd(fmt, args...) /* nothing */
35329 ++#define snd_printd(fmt, args...) do {} while (0)
35330 + #define snd_assert(expr, args...) (void)(expr)
35331 +-#define snd_BUG() /* nothing */
35332 ++#define snd_BUG() do {} while (0)
35333 +
35334 + #endif /* CONFIG_SND_DEBUG */
35335 +
35336 +@@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
35337 + */
35338 + #define snd_printdd(format, args...) snd_printk(format, ##args)
35339 + #else
35340 +-#define snd_printdd(format, args...) /* nothing */
35341 ++#define snd_printdd(format, args...) do {} while (0)
35342 + #endif
35343 +
35344 +
35345 +diff -urNp a/init/Kconfig b/init/Kconfig
35346 +--- a/init/Kconfig 2008-08-20 11:16:13.000000000 -0700
35347 ++++ b/init/Kconfig 2008-08-20 18:36:57.000000000 -0700
35348 +@@ -539,6 +539,7 @@ config SYSCTL_SYSCALL
35349 + config KALLSYMS
35350 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
35351 + default y
35352 ++ depends on !GRKERNSEC_HIDESYM
35353 + help
35354 + Say Y here to let the kernel print out symbolic crash information and
35355 + symbolic stack backtraces. This increases the size of the kernel
35356 +diff -urNp a/init/do_mounts.c b/init/do_mounts.c
35357 +--- a/init/do_mounts.c 2008-08-20 11:16:13.000000000 -0700
35358 ++++ b/init/do_mounts.c 2008-08-20 18:36:57.000000000 -0700
35359 +@@ -188,11 +188,11 @@ static void __init get_fs_names(char *pa
35360 +
35361 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
35362 + {
35363 +- int err = sys_mount(name, "/root", fs, flags, data);
35364 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
35365 + if (err)
35366 + return err;
35367 +
35368 +- sys_chdir("/root");
35369 ++ sys_chdir((char __user *)"/root");
35370 + ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
35371 + printk("VFS: Mounted root (%s filesystem)%s.\n",
35372 + current->fs->pwd.mnt->mnt_sb->s_type->name,
35373 +@@ -278,18 +278,18 @@ void __init change_floppy(char *fmt, ...
35374 + va_start(args, fmt);
35375 + vsprintf(buf, fmt, args);
35376 + va_end(args);
35377 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
35378 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
35379 + if (fd >= 0) {
35380 + sys_ioctl(fd, FDEJECT, 0);
35381 + sys_close(fd);
35382 + }
35383 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
35384 +- fd = sys_open("/dev/console", O_RDWR, 0);
35385 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
35386 + if (fd >= 0) {
35387 + sys_ioctl(fd, TCGETS, (long)&termios);
35388 + termios.c_lflag &= ~ICANON;
35389 + sys_ioctl(fd, TCSETSF, (long)&termios);
35390 +- sys_read(fd, &c, 1);
35391 ++ sys_read(fd, (char __user *)&c, 1);
35392 + termios.c_lflag |= ICANON;
35393 + sys_ioctl(fd, TCSETSF, (long)&termios);
35394 + sys_close(fd);
35395 +@@ -375,7 +375,7 @@ void __init prepare_namespace(void)
35396 +
35397 + mount_root();
35398 + out:
35399 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
35400 +- sys_chroot(".");
35401 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
35402 ++ sys_chroot((char __user *)".");
35403 + }
35404 +
35405 +diff -urNp a/init/do_mounts.h b/init/do_mounts.h
35406 +--- a/init/do_mounts.h 2008-08-20 11:16:13.000000000 -0700
35407 ++++ b/init/do_mounts.h 2008-08-20 18:36:57.000000000 -0700
35408 +@@ -15,15 +15,15 @@ extern char *root_device_name;
35409 +
35410 + static inline int create_dev(char *name, dev_t dev)
35411 + {
35412 +- sys_unlink(name);
35413 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
35414 ++ sys_unlink((char __user *)name);
35415 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
35416 + }
35417 +
35418 + #if BITS_PER_LONG == 32
35419 + static inline u32 bstat(char *name)
35420 + {
35421 + struct stat64 stat;
35422 +- if (sys_stat64(name, &stat) != 0)
35423 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
35424 + return 0;
35425 + if (!S_ISBLK(stat.st_mode))
35426 + return 0;
35427 +diff -urNp a/init/do_mounts_md.c b/init/do_mounts_md.c
35428 +--- a/init/do_mounts_md.c 2008-08-20 11:16:13.000000000 -0700
35429 ++++ b/init/do_mounts_md.c 2008-08-20 18:36:57.000000000 -0700
35430 +@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
35431 + partitioned ? "_d" : "", minor,
35432 + md_setup_args[ent].device_names);
35433 +
35434 +- fd = sys_open(name, 0, 0);
35435 ++ fd = sys_open((char __user *)name, 0, 0);
35436 + if (fd < 0) {
35437 + printk(KERN_ERR "md: open failed - cannot start "
35438 + "array %s\n", name);
35439 +@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
35440 + * array without it
35441 + */
35442 + sys_close(fd);
35443 +- fd = sys_open(name, 0, 0);
35444 ++ fd = sys_open((char __user *)name, 0, 0);
35445 + sys_ioctl(fd, BLKRRPART, 0);
35446 + }
35447 + sys_close(fd);
35448 +@@ -271,7 +271,7 @@ void __init md_run_setup(void)
35449 + if (raid_noautodetect)
35450 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
35451 + else {
35452 +- int fd = sys_open("/dev/md0", 0, 0);
35453 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
35454 + if (fd >= 0) {
35455 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
35456 + sys_close(fd);
35457 +diff -urNp a/init/initramfs.c b/init/initramfs.c
35458 +--- a/init/initramfs.c 2008-08-20 11:16:13.000000000 -0700
35459 ++++ b/init/initramfs.c 2008-08-20 18:36:57.000000000 -0700
35460 +@@ -240,7 +240,7 @@ static int __init maybe_link(void)
35461 + if (nlink >= 2) {
35462 + char *old = find_link(major, minor, ino, mode, collected);
35463 + if (old)
35464 +- return (sys_link(old, collected) < 0) ? -1 : 1;
35465 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
35466 + }
35467 + return 0;
35468 + }
35469 +@@ -249,11 +249,11 @@ static void __init clean_path(char *path
35470 + {
35471 + struct stat st;
35472 +
35473 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
35474 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
35475 + if (S_ISDIR(st.st_mode))
35476 +- sys_rmdir(path);
35477 ++ sys_rmdir((char __user *)path);
35478 + else
35479 +- sys_unlink(path);
35480 ++ sys_unlink((char __user *)path);
35481 + }
35482 + }
35483 +
35484 +@@ -276,7 +276,7 @@ static int __init do_name(void)
35485 + int openflags = O_WRONLY|O_CREAT;
35486 + if (ml != 1)
35487 + openflags |= O_TRUNC;
35488 +- wfd = sys_open(collected, openflags, mode);
35489 ++ wfd = sys_open((char __user *)collected, openflags, mode);
35490 +
35491 + if (wfd >= 0) {
35492 + sys_fchown(wfd, uid, gid);
35493 +@@ -285,15 +285,15 @@ static int __init do_name(void)
35494 + }
35495 + }
35496 + } else if (S_ISDIR(mode)) {
35497 +- sys_mkdir(collected, mode);
35498 +- sys_chown(collected, uid, gid);
35499 +- sys_chmod(collected, mode);
35500 ++ sys_mkdir((char __user *)collected, mode);
35501 ++ sys_chown((char __user *)collected, uid, gid);
35502 ++ sys_chmod((char __user *)collected, mode);
35503 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
35504 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
35505 + if (maybe_link() == 0) {
35506 +- sys_mknod(collected, mode, rdev);
35507 +- sys_chown(collected, uid, gid);
35508 +- sys_chmod(collected, mode);
35509 ++ sys_mknod((char __user *)collected, mode, rdev);
35510 ++ sys_chown((char __user *)collected, uid, gid);
35511 ++ sys_chmod((char __user *)collected, mode);
35512 + }
35513 + }
35514 + return 0;
35515 +@@ -302,13 +302,13 @@ static int __init do_name(void)
35516 + static int __init do_copy(void)
35517 + {
35518 + if (count >= body_len) {
35519 +- sys_write(wfd, victim, body_len);
35520 ++ sys_write(wfd, (char __user *)victim, body_len);
35521 + sys_close(wfd);
35522 + eat(body_len);
35523 + state = SkipIt;
35524 + return 0;
35525 + } else {
35526 +- sys_write(wfd, victim, count);
35527 ++ sys_write(wfd, (char __user *)victim, count);
35528 + body_len -= count;
35529 + eat(count);
35530 + return 1;
35531 +@@ -319,8 +319,8 @@ static int __init do_symlink(void)
35532 + {
35533 + collected[N_ALIGN(name_len) + body_len] = '\0';
35534 + clean_path(collected, 0);
35535 +- sys_symlink(collected + N_ALIGN(name_len), collected);
35536 +- sys_lchown(collected, uid, gid);
35537 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
35538 ++ sys_lchown((char __user *)collected, uid, gid);
35539 + state = SkipIt;
35540 + next_state = Reset;
35541 + return 0;
35542 +diff -urNp a/init/main.c b/init/main.c
35543 +--- a/init/main.c 2008-08-20 11:16:13.000000000 -0700
35544 ++++ b/init/main.c 2008-08-20 18:36:57.000000000 -0700
35545 +@@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
35546 + #ifdef CONFIG_TC
35547 + extern void tc_init(void);
35548 + #endif
35549 ++extern void grsecurity_init(void);
35550 +
35551 + enum system_states system_state;
35552 + EXPORT_SYMBOL(system_state);
35553 +@@ -187,6 +188,40 @@ static int __init set_reset_devices(char
35554 +
35555 + __setup("reset_devices", set_reset_devices);
35556 +
35557 ++#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
35558 ++static int __init setup_pax_nouderef(char *str)
35559 ++{
35560 ++ unsigned int cpu;
35561 ++
35562 ++#ifdef CONFIG_PAX_KERNEXEC
35563 ++ unsigned long cr0;
35564 ++
35565 ++ pax_open_kernel(cr0);
35566 ++#endif
35567 ++
35568 ++ for (cpu = 0; cpu < NR_CPUS; cpu++)
35569 ++ get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
35570 ++
35571 ++#ifdef CONFIG_PAX_KERNEXEC
35572 ++ pax_close_kernel(cr0);
35573 ++#endif
35574 ++
35575 ++ return 1;
35576 ++}
35577 ++__setup("pax_nouderef", setup_pax_nouderef);
35578 ++#endif
35579 ++
35580 ++#ifdef CONFIG_PAX_SOFTMODE
35581 ++unsigned int pax_softmode;
35582 ++
35583 ++static int __init setup_pax_softmode(char *str)
35584 ++{
35585 ++ get_option(&str, &pax_softmode);
35586 ++ return 1;
35587 ++}
35588 ++__setup("pax_softmode=", setup_pax_softmode);
35589 ++#endif
35590 ++
35591 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
35592 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
35593 + static const char *panic_later, *panic_param;
35594 +@@ -364,7 +399,7 @@ static inline void smp_prepare_cpus(unsi
35595 + #else
35596 +
35597 + #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
35598 +-unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
35599 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
35600 +
35601 + EXPORT_SYMBOL(__per_cpu_offset);
35602 +
35603 +@@ -668,7 +703,7 @@ static void __init do_initcalls(void)
35604 +
35605 + for (call = __initcall_start; call < __initcall_end; call++) {
35606 + ktime_t t0, t1, delta;
35607 +- char *msg = NULL;
35608 ++ const char *msg1 = "", *msg2 = "";
35609 + char msgbuf[40];
35610 + int result;
35611 +
35612 +@@ -697,23 +732,22 @@ static void __init do_initcalls(void)
35613 + (unsigned long) *call);
35614 + }
35615 +
35616 +- if (result && result != -ENODEV && initcall_debug) {
35617 +- sprintf(msgbuf, "error code %d", result);
35618 +- msg = msgbuf;
35619 +- }
35620 ++ msgbuf[0] = 0;
35621 ++ if (result && result != -ENODEV && initcall_debug)
35622 ++ sprintf(msgbuf, " error code %d", result);
35623 + if (preempt_count() != count) {
35624 +- msg = "preemption imbalance";
35625 ++ msg1 = " preemption imbalance";
35626 + preempt_count() = count;
35627 + }
35628 + if (irqs_disabled()) {
35629 +- msg = "disabled interrupts";
35630 ++ msg2 = " disabled interrupts";
35631 + local_irq_enable();
35632 + }
35633 +- if (msg) {
35634 ++ if (msgbuf[0] || *msg1 || *msg2) {
35635 + printk(KERN_WARNING "initcall at 0x%p", *call);
35636 + print_fn_descriptor_symbol(": %s()",
35637 + (unsigned long) *call);
35638 +- printk(": returned with %s\n", msg);
35639 ++ printk(": returned with%s%s%s\n", msgbuf, msg1, msg2);
35640 + }
35641 + }
35642 +
35643 +@@ -848,6 +882,8 @@ static int __init kernel_init(void * unu
35644 + prepare_namespace();
35645 + }
35646 +
35647 ++ grsecurity_init();
35648 ++
35649 + /*
35650 + * Ok, we have completed the initial bootup, and
35651 + * we're essentially up and running. Get rid of the
35652 +diff -urNp a/init/noinitramfs.c b/init/noinitramfs.c
35653 +--- a/init/noinitramfs.c 2008-08-20 11:16:13.000000000 -0700
35654 ++++ b/init/noinitramfs.c 2008-08-20 18:36:57.000000000 -0700
35655 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
35656 + {
35657 + int err;
35658 +
35659 +- err = sys_mkdir("/dev", 0755);
35660 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
35661 + if (err < 0)
35662 + goto out;
35663 +
35664 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
35665 + if (err < 0)
35666 + goto out;
35667 +
35668 +- err = sys_mkdir("/root", 0700);
35669 ++ err = sys_mkdir((const char __user *)"/root", 0700);
35670 + if (err < 0)
35671 + goto out;
35672 +
35673 +diff -urNp a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
35674 +--- a/ipc/ipc_sysctl.c 2008-08-20 11:16:13.000000000 -0700
35675 ++++ b/ipc/ipc_sysctl.c 2008-08-20 18:36:57.000000000 -0700
35676 +@@ -158,7 +158,7 @@ static struct ctl_table ipc_kern_table[]
35677 + .proc_handler = proc_ipc_dointvec,
35678 + .strategy = sysctl_ipc_data,
35679 + },
35680 +- {}
35681 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35682 + };
35683 +
35684 + static struct ctl_table ipc_root_table[] = {
35685 +@@ -168,7 +168,7 @@ static struct ctl_table ipc_root_table[]
35686 + .mode = 0555,
35687 + .child = ipc_kern_table,
35688 + },
35689 +- {}
35690 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35691 + };
35692 +
35693 + static int __init ipc_sysctl_init(void)
35694 +diff -urNp a/ipc/msg.c b/ipc/msg.c
35695 +--- a/ipc/msg.c 2008-08-20 11:16:13.000000000 -0700
35696 ++++ b/ipc/msg.c 2008-08-20 18:36:57.000000000 -0700
35697 +@@ -37,6 +37,7 @@
35698 + #include <linux/rwsem.h>
35699 + #include <linux/nsproxy.h>
35700 + #include <linux/ipc_namespace.h>
35701 ++#include <linux/grsecurity.h>
35702 +
35703 + #include <asm/current.h>
35704 + #include <asm/uaccess.h>
35705 +@@ -293,6 +294,7 @@ asmlinkage long sys_msgget(key_t key, in
35706 + struct ipc_namespace *ns;
35707 + struct ipc_ops msg_ops;
35708 + struct ipc_params msg_params;
35709 ++ long err;
35710 +
35711 + ns = current->nsproxy->ipc_ns;
35712 +
35713 +@@ -303,7 +305,11 @@ asmlinkage long sys_msgget(key_t key, in
35714 + msg_params.key = key;
35715 + msg_params.flg = msgflg;
35716 +
35717 +- return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
35718 ++ err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
35719 ++
35720 ++ gr_log_msgget(err, msgflg);
35721 ++
35722 ++ return err;
35723 + }
35724 +
35725 + static inline unsigned long
35726 +@@ -564,6 +570,7 @@ asmlinkage long sys_msgctl(int msqid, in
35727 + break;
35728 + }
35729 + case IPC_RMID:
35730 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
35731 + freeque(ns, &msq->q_perm);
35732 + break;
35733 + }
35734 +diff -urNp a/ipc/sem.c b/ipc/sem.c
35735 +--- a/ipc/sem.c 2008-08-20 11:16:13.000000000 -0700
35736 ++++ b/ipc/sem.c 2008-08-20 18:36:57.000000000 -0700
35737 +@@ -83,6 +83,7 @@
35738 + #include <linux/rwsem.h>
35739 + #include <linux/nsproxy.h>
35740 + #include <linux/ipc_namespace.h>
35741 ++#include <linux/grsecurity.h>
35742 +
35743 + #include <asm/uaccess.h>
35744 + #include "util.h"
35745 +@@ -312,6 +313,7 @@ asmlinkage long sys_semget(key_t key, in
35746 + struct ipc_namespace *ns;
35747 + struct ipc_ops sem_ops;
35748 + struct ipc_params sem_params;
35749 ++ long err;
35750 +
35751 + ns = current->nsproxy->ipc_ns;
35752 +
35753 +@@ -326,7 +328,11 @@ asmlinkage long sys_semget(key_t key, in
35754 + sem_params.flg = semflg;
35755 + sem_params.u.nsems = nsems;
35756 +
35757 +- return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
35758 ++ err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
35759 ++
35760 ++ gr_log_semget(err, semflg);
35761 ++
35762 ++ return err;
35763 + }
35764 +
35765 + /* Manage the doubly linked list sma->sem_pending as a FIFO:
35766 +@@ -909,6 +915,7 @@ static int semctl_down(struct ipc_namesp
35767 +
35768 + switch(cmd){
35769 + case IPC_RMID:
35770 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
35771 + freeary(ns, ipcp);
35772 + err = 0;
35773 + break;
35774 +diff -urNp a/ipc/shm.c b/ipc/shm.c
35775 +--- a/ipc/shm.c 2008-08-20 11:16:13.000000000 -0700
35776 ++++ b/ipc/shm.c 2008-08-20 18:36:57.000000000 -0700
35777 +@@ -39,6 +39,7 @@
35778 + #include <linux/nsproxy.h>
35779 + #include <linux/mount.h>
35780 + #include <linux/ipc_namespace.h>
35781 ++#include <linux/grsecurity.h>
35782 +
35783 + #include <asm/uaccess.h>
35784 +
35785 +@@ -70,6 +71,14 @@ static void shm_destroy (struct ipc_name
35786 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
35787 + #endif
35788 +
35789 ++#ifdef CONFIG_GRKERNSEC
35790 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
35791 ++ const time_t shm_createtime, const uid_t cuid,
35792 ++ const int shmid);
35793 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
35794 ++ const time_t shm_createtime);
35795 ++#endif
35796 ++
35797 + void shm_init_ns(struct ipc_namespace *ns)
35798 + {
35799 + ns->shm_ctlmax = SHMMAX;
35800 +@@ -88,6 +97,8 @@ static void do_shm_rmid(struct ipc_names
35801 + struct shmid_kernel *shp;
35802 + shp = container_of(ipcp, struct shmid_kernel, shm_perm);
35803 +
35804 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
35805 ++
35806 + if (shp->shm_nattch){
35807 + shp->shm_perm.mode |= SHM_DEST;
35808 + /* Do not find it any more */
35809 +@@ -428,6 +439,14 @@ static int newseg(struct ipc_namespace *
35810 + shp->shm_lprid = 0;
35811 + shp->shm_atim = shp->shm_dtim = 0;
35812 + shp->shm_ctim = get_seconds();
35813 ++#ifdef CONFIG_GRKERNSEC
35814 ++ {
35815 ++ struct timespec timeval;
35816 ++ do_posix_clock_monotonic_gettime(&timeval);
35817 ++
35818 ++ shp->shm_createtime = timeval.tv_sec;
35819 ++ }
35820 ++#endif
35821 + shp->shm_segsz = size;
35822 + shp->shm_nattch = 0;
35823 + shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
35824 +@@ -482,6 +501,7 @@ asmlinkage long sys_shmget (key_t key, s
35825 + struct ipc_namespace *ns;
35826 + struct ipc_ops shm_ops;
35827 + struct ipc_params shm_params;
35828 ++ long err;
35829 +
35830 + ns = current->nsproxy->ipc_ns;
35831 +
35832 +@@ -493,7 +513,11 @@ asmlinkage long sys_shmget (key_t key, s
35833 + shm_params.flg = shmflg;
35834 + shm_params.u.size = size;
35835 +
35836 +- return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
35837 ++ err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
35838 ++
35839 ++ gr_log_shmget(err, shmflg, size);
35840 ++
35841 ++ return err;
35842 + }
35843 +
35844 + static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
35845 +@@ -959,9 +983,21 @@ long do_shmat(int shmid, char __user *sh
35846 + if (err)
35847 + goto out_unlock;
35848 +
35849 ++#ifdef CONFIG_GRKERNSEC
35850 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
35851 ++ shp->shm_perm.cuid, shmid) ||
35852 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
35853 ++ err = -EACCES;
35854 ++ goto out_unlock;
35855 ++ }
35856 ++#endif
35857 ++
35858 + path.dentry = dget(shp->shm_file->f_path.dentry);
35859 + path.mnt = shp->shm_file->f_path.mnt;
35860 + shp->shm_nattch++;
35861 ++#ifdef CONFIG_GRKERNSEC
35862 ++ shp->shm_lapid = current->pid;
35863 ++#endif
35864 + size = i_size_read(path.dentry->d_inode);
35865 + shm_unlock(shp);
35866 +
35867 +diff -urNp a/kernel/acct.c b/kernel/acct.c
35868 +--- a/kernel/acct.c 2008-08-20 11:16:13.000000000 -0700
35869 ++++ b/kernel/acct.c 2008-08-20 18:36:57.000000000 -0700
35870 +@@ -519,7 +519,7 @@ static void do_acct_process(struct pid_n
35871 + */
35872 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
35873 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
35874 +- file->f_op->write(file, (char *)&ac,
35875 ++ file->f_op->write(file, (char __user *)&ac,
35876 + sizeof(acct_t), &file->f_pos);
35877 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
35878 + set_fs(fs);
35879 +diff -urNp a/kernel/capability.c b/kernel/capability.c
35880 +--- a/kernel/capability.c 2008-08-20 11:16:13.000000000 -0700
35881 ++++ b/kernel/capability.c 2008-08-20 18:36:57.000000000 -0700
35882 +@@ -13,6 +13,7 @@
35883 + #include <linux/security.h>
35884 + #include <linux/syscalls.h>
35885 + #include <linux/pid_namespace.h>
35886 ++#include <linux/grsecurity.h>
35887 + #include <asm/uaccess.h>
35888 +
35889 + /*
35890 +@@ -363,15 +364,25 @@ out:
35891 +
35892 + int __capable(struct task_struct *t, int cap)
35893 + {
35894 +- if (security_capable(t, cap) == 0) {
35895 ++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
35896 + t->flags |= PF_SUPERPRIV;
35897 + return 1;
35898 + }
35899 + return 0;
35900 + }
35901 +
35902 ++int capable_nolog(int cap)
35903 ++{
35904 ++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
35905 ++ current->flags |= PF_SUPERPRIV;
35906 ++ return 1;
35907 ++ }
35908 ++ return 0;
35909 ++}
35910 ++
35911 + int capable(int cap)
35912 + {
35913 + return __capable(current, cap);
35914 + }
35915 + EXPORT_SYMBOL(capable);
35916 ++EXPORT_SYMBOL(capable_nolog);
35917 +diff -urNp a/kernel/configs.c b/kernel/configs.c
35918 +--- a/kernel/configs.c 2008-08-20 11:16:13.000000000 -0700
35919 ++++ b/kernel/configs.c 2008-08-20 18:36:57.000000000 -0700
35920 +@@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
35921 + struct proc_dir_entry *entry;
35922 +
35923 + /* create the current config file */
35924 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
35925 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
35926 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
35927 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
35928 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
35929 ++#endif
35930 ++#else
35931 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
35932 + &proc_root);
35933 ++#endif
35934 + if (!entry)
35935 + return -ENOMEM;
35936 +
35937 +diff -urNp a/kernel/cpu.c b/kernel/cpu.c
35938 +--- a/kernel/cpu.c 2008-08-20 11:16:13.000000000 -0700
35939 ++++ b/kernel/cpu.c 2008-08-20 18:36:57.000000000 -0700
35940 +@@ -18,7 +18,7 @@
35941 + /* Serializes the updates to cpu_online_map, cpu_present_map */
35942 + static DEFINE_MUTEX(cpu_add_remove_lock);
35943 +
35944 +-static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
35945 ++static RAW_NOTIFIER_HEAD(cpu_chain);
35946 +
35947 + /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
35948 + * Should always be manipulated under cpu_add_remove_lock
35949 +@@ -136,7 +136,7 @@ static void cpu_hotplug_done(void)
35950 + mutex_unlock(&cpu_hotplug.lock);
35951 + }
35952 + /* Need to know about CPUs going up/down? */
35953 +-int __cpuinit register_cpu_notifier(struct notifier_block *nb)
35954 ++int register_cpu_notifier(struct notifier_block *nb)
35955 + {
35956 + int ret;
35957 + cpu_maps_update_begin();
35958 +diff -urNp a/kernel/exit.c b/kernel/exit.c
35959 +--- a/kernel/exit.c 2008-08-20 11:16:13.000000000 -0700
35960 ++++ b/kernel/exit.c 2008-08-20 18:36:57.000000000 -0700
35961 +@@ -44,6 +44,11 @@
35962 + #include <linux/resource.h>
35963 + #include <linux/blkdev.h>
35964 + #include <linux/task_io_accounting_ops.h>
35965 ++#include <linux/grsecurity.h>
35966 ++
35967 ++#ifdef CONFIG_GRKERNSEC
35968 ++extern rwlock_t grsec_exec_file_lock;
35969 ++#endif
35970 +
35971 + #include <asm/uaccess.h>
35972 + #include <asm/unistd.h>
35973 +@@ -120,6 +125,7 @@ static void __exit_signal(struct task_st
35974 +
35975 + __unhash_process(tsk);
35976 +
35977 ++ gr_del_task_from_ip_table(tsk);
35978 + tsk->signal = NULL;
35979 + tsk->sighand = NULL;
35980 + spin_unlock(&sighand->siglock);
35981 +@@ -301,12 +307,23 @@ static void reparent_to_kthreadd(void)
35982 + {
35983 + write_lock_irq(&tasklist_lock);
35984 +
35985 ++#ifdef CONFIG_GRKERNSEC
35986 ++ write_lock(&grsec_exec_file_lock);
35987 ++ if (current->exec_file) {
35988 ++ fput(current->exec_file);
35989 ++ current->exec_file = NULL;
35990 ++ }
35991 ++ write_unlock(&grsec_exec_file_lock);
35992 ++#endif
35993 ++
35994 + ptrace_unlink(current);
35995 + /* Reparent to init */
35996 + remove_parent(current);
35997 + current->real_parent = current->parent = kthreadd_task;
35998 + add_parent(current);
35999 +
36000 ++ gr_set_kernel_label(current);
36001 ++
36002 + /* Set the exit signal to SIGCHLD so we signal init on exit */
36003 + current->exit_signal = SIGCHLD;
36004 +
36005 +@@ -402,6 +419,17 @@ void daemonize(const char *name, ...)
36006 + vsnprintf(current->comm, sizeof(current->comm), name, args);
36007 + va_end(args);
36008 +
36009 ++#ifdef CONFIG_GRKERNSEC
36010 ++ write_lock(&grsec_exec_file_lock);
36011 ++ if (current->exec_file) {
36012 ++ fput(current->exec_file);
36013 ++ current->exec_file = NULL;
36014 ++ }
36015 ++ write_unlock(&grsec_exec_file_lock);
36016 ++#endif
36017 ++
36018 ++ gr_set_kernel_label(current);
36019 ++
36020 + /*
36021 + * If we were started as result of loading a module, close all of the
36022 + * user space pages. We don't need them, and if we didn't close them
36023 +@@ -962,6 +990,9 @@ NORET_TYPE void do_exit(long code)
36024 + tsk->exit_code = code;
36025 + taskstats_exit(tsk, group_dead);
36026 +
36027 ++ gr_acl_handle_psacct(tsk, code);
36028 ++ gr_acl_handle_exit();
36029 ++
36030 + exit_mm(tsk);
36031 +
36032 + if (group_dead)
36033 +@@ -1171,7 +1202,7 @@ static int wait_task_zombie(struct task_
36034 + if (unlikely(noreap)) {
36035 + uid_t uid = p->uid;
36036 + int exit_code = p->exit_code;
36037 +- int why, status;
36038 ++ int why;
36039 +
36040 + get_task_struct(p);
36041 + read_unlock(&tasklist_lock);
36042 +diff -urNp a/kernel/fork.c b/kernel/fork.c
36043 +--- a/kernel/fork.c 2008-08-20 11:16:13.000000000 -0700
36044 ++++ b/kernel/fork.c 2008-08-20 18:36:57.000000000 -0700
36045 +@@ -53,6 +53,7 @@
36046 + #include <linux/tty.h>
36047 + #include <linux/proc_fs.h>
36048 + #include <linux/blkdev.h>
36049 ++#include <linux/grsecurity.h>
36050 +
36051 + #include <asm/pgtable.h>
36052 + #include <asm/pgalloc.h>
36053 +@@ -194,7 +195,7 @@ static struct task_struct *dup_task_stru
36054 + setup_thread_stack(tsk, orig);
36055 +
36056 + #ifdef CONFIG_CC_STACKPROTECTOR
36057 +- tsk->stack_canary = get_random_int();
36058 ++ tsk->stack_canary = pax_get_random_long();
36059 + #endif
36060 +
36061 + /* One for us, one for whoever does the "release_task()" (usually parent) */
36062 +@@ -226,8 +227,8 @@ static int dup_mmap(struct mm_struct *mm
36063 + mm->locked_vm = 0;
36064 + mm->mmap = NULL;
36065 + mm->mmap_cache = NULL;
36066 +- mm->free_area_cache = oldmm->mmap_base;
36067 +- mm->cached_hole_size = ~0UL;
36068 ++ mm->free_area_cache = oldmm->free_area_cache;
36069 ++ mm->cached_hole_size = oldmm->cached_hole_size;
36070 + mm->map_count = 0;
36071 + cpus_clear(mm->cpu_vm_mask);
36072 + mm->mm_rb = RB_ROOT;
36073 +@@ -264,6 +265,7 @@ static int dup_mmap(struct mm_struct *mm
36074 + tmp->vm_flags &= ~VM_LOCKED;
36075 + tmp->vm_mm = mm;
36076 + tmp->vm_next = NULL;
36077 ++ tmp->vm_mirror = NULL;
36078 + anon_vma_link(tmp);
36079 + file = tmp->vm_file;
36080 + if (file) {
36081 +@@ -300,6 +302,31 @@ static int dup_mmap(struct mm_struct *mm
36082 + if (retval)
36083 + goto out;
36084 + }
36085 ++
36086 ++#ifdef CONFIG_PAX_SEGMEXEC
36087 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
36088 ++ struct vm_area_struct *mpnt_m;
36089 ++
36090 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
36091 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
36092 ++
36093 ++ if (!mpnt->vm_mirror)
36094 ++ continue;
36095 ++
36096 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
36097 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
36098 ++ mpnt->vm_mirror = mpnt_m;
36099 ++ } else {
36100 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
36101 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
36102 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
36103 ++ mpnt->vm_mirror->vm_mirror = mpnt;
36104 ++ }
36105 ++ }
36106 ++ BUG_ON(mpnt_m);
36107 ++ }
36108 ++#endif
36109 ++
36110 + /* a new mm has just been created */
36111 + arch_dup_mmap(oldmm, mm);
36112 + retval = 0;
36113 +@@ -482,7 +509,7 @@ void mm_release(struct task_struct *tsk,
36114 + if (tsk->clear_child_tid
36115 + && !(tsk->flags & PF_SIGNALED)
36116 + && atomic_read(&mm->mm_users) > 1) {
36117 +- u32 __user * tidptr = tsk->clear_child_tid;
36118 ++ pid_t __user * tidptr = tsk->clear_child_tid;
36119 + tsk->clear_child_tid = NULL;
36120 +
36121 + /*
36122 +@@ -490,7 +517,7 @@ void mm_release(struct task_struct *tsk,
36123 + * not set up a proper pointer then tough luck.
36124 + */
36125 + put_user(0, tidptr);
36126 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
36127 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
36128 + }
36129 + }
36130 +
36131 +@@ -1046,6 +1073,9 @@ static struct task_struct *copy_process(
36132 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
36133 + #endif
36134 + retval = -EAGAIN;
36135 ++
36136 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
36137 ++
36138 + if (atomic_read(&p->user->processes) >=
36139 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
36140 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
36141 +@@ -1212,6 +1242,8 @@ static struct task_struct *copy_process(
36142 + if (clone_flags & CLONE_THREAD)
36143 + p->tgid = current->tgid;
36144 +
36145 ++ gr_copy_label(p);
36146 ++
36147 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
36148 + /*
36149 + * Clear TID on mm_release()?
36150 +@@ -1401,6 +1433,8 @@ bad_fork_cleanup_count:
36151 + bad_fork_free:
36152 + free_task(p);
36153 + fork_out:
36154 ++ gr_log_forkfail(retval);
36155 ++
36156 + return ERR_PTR(retval);
36157 + }
36158 +
36159 +@@ -1493,6 +1527,8 @@ long do_fork(unsigned long clone_flags,
36160 + if (clone_flags & CLONE_PARENT_SETTID)
36161 + put_user(nr, parent_tidptr);
36162 +
36163 ++ gr_handle_brute_check();
36164 ++
36165 + if (clone_flags & CLONE_VFORK) {
36166 + p->vfork_done = &vfork;
36167 + init_completion(&vfork);
36168 +diff -urNp a/kernel/futex.c b/kernel/futex.c
36169 +--- a/kernel/futex.c 2008-08-20 11:16:13.000000000 -0700
36170 ++++ b/kernel/futex.c 2008-08-20 18:36:57.000000000 -0700
36171 +@@ -195,6 +195,11 @@ static int get_futex_key(u32 __user *uad
36172 + struct page *page;
36173 + int err;
36174 +
36175 ++#ifdef CONFIG_PAX_SEGMEXEC
36176 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
36177 ++ return -EFAULT;
36178 ++#endif
36179 ++
36180 + /*
36181 + * The futex address must be "naturally" aligned.
36182 + */
36183 +@@ -221,8 +226,8 @@ static int get_futex_key(u32 __user *uad
36184 + * The futex is hashed differently depending on whether
36185 + * it's in a shared or private mapping. So check vma first.
36186 + */
36187 +- vma = find_extend_vma(mm, address);
36188 +- if (unlikely(!vma))
36189 ++ vma = find_vma(mm, address);
36190 ++ if (unlikely(!vma || address < vma->vm_start))
36191 + return -EFAULT;
36192 +
36193 + /*
36194 +@@ -2032,7 +2037,7 @@ retry:
36195 + */
36196 + static inline int fetch_robust_entry(struct robust_list __user **entry,
36197 + struct robust_list __user * __user *head,
36198 +- int *pi)
36199 ++ unsigned int *pi)
36200 + {
36201 + unsigned long uentry;
36202 +
36203 +diff -urNp a/kernel/irq/handle.c b/kernel/irq/handle.c
36204 +--- a/kernel/irq/handle.c 2008-08-20 11:16:13.000000000 -0700
36205 ++++ b/kernel/irq/handle.c 2008-08-20 18:36:57.000000000 -0700
36206 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
36207 + .depth = 1,
36208 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
36209 + #ifdef CONFIG_SMP
36210 +- .affinity = CPU_MASK_ALL
36211 ++ .affinity = CPU_MASK_ALL,
36212 ++ .cpu = 0,
36213 + #endif
36214 + }
36215 + };
36216 +diff -urNp a/kernel/kallsyms.c b/kernel/kallsyms.c
36217 +--- a/kernel/kallsyms.c 2008-08-20 11:16:13.000000000 -0700
36218 ++++ b/kernel/kallsyms.c 2008-08-20 18:36:57.000000000 -0700
36219 +@@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
36220 +
36221 + static inline int is_kernel(unsigned long addr)
36222 + {
36223 ++
36224 ++#ifdef CONFIG_PAX_KERNEXEC
36225 ++
36226 ++#ifdef CONFIG_MODULES
36227 ++ if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
36228 ++ ktla_ktva(addr) < (unsigned long)MODULES_END)
36229 ++ return 0;
36230 ++#endif
36231 ++
36232 ++ if (is_kernel_inittext(addr))
36233 ++ return 1;
36234 ++#endif
36235 ++
36236 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
36237 + return 1;
36238 + return in_gate_area_no_task(addr);
36239 +@@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
36240 +
36241 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
36242 + {
36243 +- iter->name[0] = '\0';
36244 + iter->nameoff = get_symbol_offset(new_pos);
36245 + iter->pos = new_pos;
36246 + }
36247 +@@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
36248 + struct kallsym_iter *iter;
36249 + int ret;
36250 +
36251 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
36252 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
36253 + if (!iter)
36254 + return -ENOMEM;
36255 + reset_iter(iter, 0);
36256 +@@ -474,7 +486,15 @@ static int __init kallsyms_init(void)
36257 + {
36258 + struct proc_dir_entry *entry;
36259 +
36260 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
36261 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
36262 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
36263 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
36264 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
36265 ++#endif
36266 ++#else
36267 + entry = create_proc_entry("kallsyms", 0444, NULL);
36268 ++#endif
36269 + if (entry)
36270 + entry->proc_fops = &kallsyms_operations;
36271 + return 0;
36272 +diff -urNp a/kernel/kmod.c b/kernel/kmod.c
36273 +--- a/kernel/kmod.c 2008-08-20 11:16:13.000000000 -0700
36274 ++++ b/kernel/kmod.c 2008-08-20 18:36:57.000000000 -0700
36275 +@@ -107,7 +107,7 @@ int request_module(const char *fmt, ...)
36276 + return -ENOMEM;
36277 + }
36278 +
36279 +- ret = call_usermodehelper(modprobe_path, argv, envp, 1);
36280 ++ ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
36281 + atomic_dec(&kmod_concurrent);
36282 + return ret;
36283 + }
36284 +diff -urNp a/kernel/kprobes.c b/kernel/kprobes.c
36285 +--- a/kernel/kprobes.c 2008-08-20 11:16:13.000000000 -0700
36286 ++++ b/kernel/kprobes.c 2008-08-20 18:36:57.000000000 -0700
36287 +@@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
36288 + * kernel image and loaded module images reside. This is required
36289 + * so x86_64 can correctly handle the %rip-relative fixups.
36290 + */
36291 +- kip->insns = module_alloc(PAGE_SIZE);
36292 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
36293 + if (!kip->insns) {
36294 + kfree(kip);
36295 + return NULL;
36296 +@@ -194,7 +194,7 @@ static int __kprobes collect_one_slot(st
36297 + hlist_add_head(&kip->hlist,
36298 + &kprobe_insn_pages);
36299 + } else {
36300 +- module_free(NULL, kip->insns);
36301 ++ module_free_exec(NULL, kip->insns);
36302 + kfree(kip);
36303 + }
36304 + return 1;
36305 +diff -urNp a/kernel/lockdep.c b/kernel/lockdep.c
36306 +--- a/kernel/lockdep.c 2008-08-20 11:16:13.000000000 -0700
36307 ++++ b/kernel/lockdep.c 2008-08-20 18:36:57.000000000 -0700
36308 +@@ -598,6 +598,10 @@ static int static_obj(void *obj)
36309 + int i;
36310 + #endif
36311 +
36312 ++#ifdef CONFIG_PAX_KERNEXEC
36313 ++ start = (unsigned long )&_data;
36314 ++#endif
36315 ++
36316 + /*
36317 + * static variable?
36318 + */
36319 +@@ -609,9 +613,12 @@ static int static_obj(void *obj)
36320 + * percpu var?
36321 + */
36322 + for_each_possible_cpu(i) {
36323 ++#ifdef CONFIG_X86_32
36324 ++ start = per_cpu_offset(i);
36325 ++#else
36326 + start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
36327 +- end = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
36328 +- + per_cpu_offset(i);
36329 ++#endif
36330 ++ end = start + PERCPU_ENOUGH_ROOM;
36331 +
36332 + if ((addr >= start) && (addr < end))
36333 + return 1;
36334 +diff -urNp a/kernel/module.c b/kernel/module.c
36335 +--- a/kernel/module.c 2008-08-20 11:16:13.000000000 -0700
36336 ++++ b/kernel/module.c 2008-08-20 18:36:57.000000000 -0700
36337 +@@ -45,6 +45,11 @@
36338 + #include <asm/uaccess.h>
36339 + #include <asm/semaphore.h>
36340 + #include <asm/cacheflush.h>
36341 ++
36342 ++#ifdef CONFIG_PAX_KERNEXEC
36343 ++#include <asm/desc.h>
36344 ++#endif
36345 ++
36346 + #include <linux/license.h>
36347 + #include <asm/sections.h>
36348 +
36349 +@@ -71,6 +76,8 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
36350 +
36351 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
36352 +
36353 ++extern int gr_check_modstop(void);
36354 ++
36355 + int register_module_notifier(struct notifier_block * nb)
36356 + {
36357 + return blocking_notifier_chain_register(&module_notify_list, nb);
36358 +@@ -344,6 +351,8 @@ static inline unsigned int block_size(in
36359 + return val;
36360 + }
36361 +
36362 ++EXPORT_SYMBOL(__per_cpu_start);
36363 ++
36364 + static void *percpu_modalloc(unsigned long size, unsigned long align,
36365 + const char *name)
36366 + {
36367 +@@ -351,7 +360,7 @@ static void *percpu_modalloc(unsigned lo
36368 + unsigned int i;
36369 + void *ptr;
36370 +
36371 +- if (align > PAGE_SIZE) {
36372 ++ if (align-1 >= PAGE_SIZE) {
36373 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
36374 + name, align, PAGE_SIZE);
36375 + align = PAGE_SIZE;
36376 +@@ -433,7 +442,11 @@ static void percpu_modcopy(void *pcpudes
36377 + int cpu;
36378 +
36379 + for_each_possible_cpu(cpu)
36380 ++#ifdef CONFIG_X86_32
36381 ++ memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
36382 ++#else
36383 + memcpy(pcpudest + per_cpu_offset(cpu), from, size);
36384 ++#endif
36385 + }
36386 +
36387 + static int percpu_modinit(void)
36388 +@@ -684,6 +697,9 @@ sys_delete_module(const char __user *nam
36389 + char name[MODULE_NAME_LEN];
36390 + int ret, forced = 0;
36391 +
36392 ++ if (gr_check_modstop())
36393 ++ return -EPERM;
36394 ++
36395 + if (!capable(CAP_SYS_MODULE))
36396 + return -EPERM;
36397 +
36398 +@@ -1347,16 +1363,19 @@ static void free_module(struct module *m
36399 + module_unload_free(mod);
36400 +
36401 + /* This may be NULL, but that's OK */
36402 +- module_free(mod, mod->module_init);
36403 ++ module_free(mod, mod->module_init_rw);
36404 ++ module_free_exec(mod, mod->module_init_rx);
36405 + kfree(mod->args);
36406 + if (mod->percpu)
36407 + percpu_modfree(mod->percpu);
36408 +
36409 + /* Free lock-classes: */
36410 +- lockdep_free_key_range(mod->module_core, mod->core_size);
36411 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
36412 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
36413 +
36414 + /* Finally, free the core (containing the module structure) */
36415 +- module_free(mod, mod->module_core);
36416 ++ module_free_exec(mod, mod->module_core_rx);
36417 ++ module_free(mod, mod->module_core_rw);
36418 + }
36419 +
36420 + void *__symbol_get(const char *symbol)
36421 +@@ -1421,10 +1440,14 @@ static int simplify_symbols(Elf_Shdr *se
36422 + struct module *mod)
36423 + {
36424 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
36425 +- unsigned long secbase;
36426 ++ unsigned long secbase, symbol;
36427 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
36428 + int ret = 0;
36429 +
36430 ++#ifdef CONFIG_PAX_KERNEXEC
36431 ++ unsigned long cr0;
36432 ++#endif
36433 ++
36434 + for (i = 1; i < n; i++) {
36435 + switch (sym[i].st_shndx) {
36436 + case SHN_COMMON:
36437 +@@ -1443,10 +1466,19 @@ static int simplify_symbols(Elf_Shdr *se
36438 + break;
36439 +
36440 + case SHN_UNDEF:
36441 +- sym[i].st_value
36442 +- = resolve_symbol(sechdrs, versindex,
36443 ++ symbol = resolve_symbol(sechdrs, versindex,
36444 + strtab + sym[i].st_name, mod);
36445 +
36446 ++#ifdef CONFIG_PAX_KERNEXEC
36447 ++ pax_open_kernel(cr0);
36448 ++#endif
36449 ++
36450 ++ sym[i].st_value = symbol;
36451 ++
36452 ++#ifdef CONFIG_PAX_KERNEXEC
36453 ++ pax_close_kernel(cr0);
36454 ++#endif
36455 ++
36456 + /* Ok if resolved. */
36457 + if (!IS_ERR_VALUE(sym[i].st_value))
36458 + break;
36459 +@@ -1461,11 +1493,27 @@ static int simplify_symbols(Elf_Shdr *se
36460 +
36461 + default:
36462 + /* Divert to percpu allocation if a percpu var. */
36463 +- if (sym[i].st_shndx == pcpuindex)
36464 ++ if (sym[i].st_shndx == pcpuindex) {
36465 ++
36466 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
36467 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
36468 ++#else
36469 + secbase = (unsigned long)mod->percpu;
36470 +- else
36471 ++#endif
36472 ++
36473 ++ } else
36474 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
36475 ++
36476 ++#ifdef CONFIG_PAX_KERNEXEC
36477 ++ pax_open_kernel(cr0);
36478 ++#endif
36479 ++
36480 + sym[i].st_value += secbase;
36481 ++
36482 ++#ifdef CONFIG_PAX_KERNEXEC
36483 ++ pax_close_kernel(cr0);
36484 ++#endif
36485 ++
36486 + break;
36487 + }
36488 + }
36489 +@@ -1517,11 +1565,14 @@ static void layout_sections(struct modul
36490 + || strncmp(secstrings + s->sh_name,
36491 + ".init", 5) == 0)
36492 + continue;
36493 +- s->sh_entsize = get_offset(&mod->core_size, s);
36494 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
36495 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
36496 ++ else
36497 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
36498 + DEBUGP("\t%s\n", secstrings + s->sh_name);
36499 + }
36500 + if (m == 0)
36501 +- mod->core_text_size = mod->core_size;
36502 ++ mod->core_size_rx = mod->core_size_rx;
36503 + }
36504 +
36505 + DEBUGP("Init section allocation order:\n");
36506 +@@ -1535,12 +1586,15 @@ static void layout_sections(struct modul
36507 + || strncmp(secstrings + s->sh_name,
36508 + ".init", 5) != 0)
36509 + continue;
36510 +- s->sh_entsize = (get_offset(&mod->init_size, s)
36511 +- | INIT_OFFSET_MASK);
36512 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
36513 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
36514 ++ else
36515 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
36516 ++ s->sh_entsize |= INIT_OFFSET_MASK;
36517 + DEBUGP("\t%s\n", secstrings + s->sh_name);
36518 + }
36519 + if (m == 0)
36520 +- mod->init_text_size = mod->init_size;
36521 ++ mod->init_size_rx = mod->init_size_rx;
36522 + }
36523 + }
36524 +
36525 +@@ -1667,14 +1721,31 @@ static void add_kallsyms(struct module *
36526 + {
36527 + unsigned int i;
36528 +
36529 ++#ifdef CONFIG_PAX_KERNEXEC
36530 ++ unsigned long cr0;
36531 ++#endif
36532 ++
36533 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
36534 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
36535 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
36536 +
36537 + /* Set types up while we still have access to sections. */
36538 +- for (i = 0; i < mod->num_symtab; i++)
36539 +- mod->symtab[i].st_info
36540 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
36541 ++
36542 ++ for (i = 0; i < mod->num_symtab; i++) {
36543 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
36544 ++
36545 ++#ifdef CONFIG_PAX_KERNEXEC
36546 ++ pax_open_kernel(cr0);
36547 ++#endif
36548 ++
36549 ++ mod->symtab[i].st_info = type;
36550 ++
36551 ++#ifdef CONFIG_PAX_KERNEXEC
36552 ++ pax_close_kernel(cr0);
36553 ++#endif
36554 ++
36555 ++ }
36556 ++
36557 + }
36558 + #else
36559 + static inline void add_kallsyms(struct module *mod,
36560 +@@ -1724,6 +1795,10 @@ static struct module *load_module(void _
36561 + struct exception_table_entry *extable;
36562 + mm_segment_t old_fs;
36563 +
36564 ++#ifdef CONFIG_PAX_KERNEXEC
36565 ++ unsigned long cr0;
36566 ++#endif
36567 ++
36568 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
36569 + umod, len, uargs);
36570 + if (len < sizeof(*hdr))
36571 +@@ -1882,21 +1957,57 @@ static struct module *load_module(void _
36572 + layout_sections(mod, hdr, sechdrs, secstrings);
36573 +
36574 + /* Do the allocs. */
36575 +- ptr = module_alloc(mod->core_size);
36576 ++ ptr = module_alloc(mod->core_size_rw);
36577 + if (!ptr) {
36578 + err = -ENOMEM;
36579 + goto free_percpu;
36580 + }
36581 +- memset(ptr, 0, mod->core_size);
36582 +- mod->module_core = ptr;
36583 ++ memset(ptr, 0, mod->core_size_rw);
36584 ++ mod->module_core_rw = ptr;
36585 ++
36586 ++ ptr = module_alloc(mod->init_size_rw);
36587 ++ if (!ptr && mod->init_size_rw) {
36588 ++ err = -ENOMEM;
36589 ++ goto free_core_rw;
36590 ++ }
36591 ++ memset(ptr, 0, mod->init_size_rw);
36592 ++ mod->module_init_rw = ptr;
36593 ++
36594 ++ ptr = module_alloc_exec(mod->core_size_rx);
36595 ++ if (!ptr) {
36596 ++ err = -ENOMEM;
36597 ++ goto free_init_rw;
36598 ++ }
36599 +
36600 +- ptr = module_alloc(mod->init_size);
36601 +- if (!ptr && mod->init_size) {
36602 ++#ifdef CONFIG_PAX_KERNEXEC
36603 ++ pax_open_kernel(cr0);
36604 ++#endif
36605 ++
36606 ++ memset(ptr, 0, mod->core_size_rx);
36607 ++
36608 ++#ifdef CONFIG_PAX_KERNEXEC
36609 ++ pax_close_kernel(cr0);
36610 ++#endif
36611 ++
36612 ++ mod->module_core_rx = ptr;
36613 ++
36614 ++ ptr = module_alloc_exec(mod->init_size_rx);
36615 ++ if (!ptr && mod->init_size_rx) {
36616 + err = -ENOMEM;
36617 +- goto free_core;
36618 ++ goto free_core_rx;
36619 + }
36620 +- memset(ptr, 0, mod->init_size);
36621 +- mod->module_init = ptr;
36622 ++
36623 ++#ifdef CONFIG_PAX_KERNEXEC
36624 ++ pax_open_kernel(cr0);
36625 ++#endif
36626 ++
36627 ++ memset(ptr, 0, mod->init_size_rx);
36628 ++
36629 ++#ifdef CONFIG_PAX_KERNEXEC
36630 ++ pax_close_kernel(cr0);
36631 ++#endif
36632 ++
36633 ++ mod->module_init_rx = ptr;
36634 +
36635 + /* Transfer each section which specifies SHF_ALLOC */
36636 + DEBUGP("final section addresses:\n");
36637 +@@ -1906,17 +2017,41 @@ static struct module *load_module(void _
36638 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
36639 + continue;
36640 +
36641 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
36642 +- dest = mod->module_init
36643 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36644 +- else
36645 +- dest = mod->module_core + sechdrs[i].sh_entsize;
36646 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
36647 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
36648 ++ dest = mod->module_init_rw
36649 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36650 ++ else
36651 ++ dest = mod->module_init_rx
36652 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36653 ++ } else {
36654 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
36655 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
36656 ++ else
36657 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
36658 ++ }
36659 ++
36660 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
36661 +
36662 +- if (sechdrs[i].sh_type != SHT_NOBITS)
36663 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
36664 +- sechdrs[i].sh_size);
36665 ++#ifdef CONFIG_PAX_KERNEXEC
36666 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
36667 ++ pax_open_kernel(cr0);
36668 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
36669 ++ pax_close_kernel(cr0);
36670 ++ } else
36671 ++#endif
36672 ++
36673 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
36674 ++ }
36675 + /* Update sh_addr to point to copy in image. */
36676 +- sechdrs[i].sh_addr = (unsigned long)dest;
36677 ++
36678 ++#ifdef CONFIG_PAX_KERNEXEC
36679 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
36680 ++ sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
36681 ++ else
36682 ++#endif
36683 ++
36684 ++ sechdrs[i].sh_addr = (unsigned long)dest;
36685 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
36686 + }
36687 + /* Module has been moved. */
36688 +@@ -2057,12 +2192,12 @@ static struct module *load_module(void _
36689 + * Do it before processing of module parameters, so the module
36690 + * can provide parameter accessor functions of its own.
36691 + */
36692 +- if (mod->module_init)
36693 +- flush_icache_range((unsigned long)mod->module_init,
36694 +- (unsigned long)mod->module_init
36695 +- + mod->init_size);
36696 +- flush_icache_range((unsigned long)mod->module_core,
36697 +- (unsigned long)mod->module_core + mod->core_size);
36698 ++ if (mod->module_init_rx)
36699 ++ flush_icache_range((unsigned long)mod->module_init_rx,
36700 ++ (unsigned long)mod->module_init_rx
36701 ++ + mod->init_size_rx);
36702 ++ flush_icache_range((unsigned long)mod->module_core_rx,
36703 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
36704 +
36705 + set_fs(old_fs);
36706 +
36707 +@@ -2115,9 +2250,13 @@ static struct module *load_module(void _
36708 + kobject_put(&mod->mkobj.kobj);
36709 + free_unload:
36710 + module_unload_free(mod);
36711 +- module_free(mod, mod->module_init);
36712 +- free_core:
36713 +- module_free(mod, mod->module_core);
36714 ++ module_free_exec(mod, mod->module_init_rx);
36715 ++ free_core_rx:
36716 ++ module_free_exec(mod, mod->module_core_rx);
36717 ++ free_init_rw:
36718 ++ module_free(mod, mod->module_init_rw);
36719 ++ free_core_rw:
36720 ++ module_free(mod, mod->module_core_rw);
36721 + free_percpu:
36722 + if (percpu)
36723 + percpu_modfree(percpu);
36724 +@@ -2142,6 +2281,9 @@ sys_init_module(void __user *umod,
36725 + struct module *mod;
36726 + int ret = 0;
36727 +
36728 ++ if (gr_check_modstop())
36729 ++ return -EPERM;
36730 ++
36731 + /* Must have permission */
36732 + if (!capable(CAP_SYS_MODULE))
36733 + return -EPERM;
36734 +@@ -2195,10 +2337,12 @@ sys_init_module(void __user *umod,
36735 + /* Drop initial reference. */
36736 + module_put(mod);
36737 + unwind_remove_table(mod->unwind_info, 1);
36738 +- module_free(mod, mod->module_init);
36739 +- mod->module_init = NULL;
36740 +- mod->init_size = 0;
36741 +- mod->init_text_size = 0;
36742 ++ module_free(mod, mod->module_init_rw);
36743 ++ module_free_exec(mod, mod->module_init_rx);
36744 ++ mod->module_init_rw = NULL;
36745 ++ mod->module_init_rx = NULL;
36746 ++ mod->init_size_rw = 0;
36747 ++ mod->init_size_rx = 0;
36748 + mutex_unlock(&module_mutex);
36749 +
36750 + return 0;
36751 +@@ -2206,6 +2350,13 @@ sys_init_module(void __user *umod,
36752 +
36753 + static inline int within(unsigned long addr, void *start, unsigned long size)
36754 + {
36755 ++
36756 ++#ifdef CONFIG_PAX_KERNEXEC
36757 ++ if (ktla_ktva(addr) >= (unsigned long)start &&
36758 ++ ktla_ktva(addr) < (unsigned long)start + size)
36759 ++ return 1;
36760 ++#endif
36761 ++
36762 + return ((void *)addr >= start && (void *)addr < start + size);
36763 + }
36764 +
36765 +@@ -2229,10 +2380,14 @@ static const char *get_ksymbol(struct mo
36766 + unsigned long nextval;
36767 +
36768 + /* At worse, next value is at end of module */
36769 +- if (within(addr, mod->module_init, mod->init_size))
36770 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
36771 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
36772 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
36773 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
36774 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
36775 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
36776 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
36777 + else
36778 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
36779 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
36780 +
36781 + /* Scan for closest preceeding symbol, and next symbol. (ELF
36782 + starts real symbols at 1). */
36783 +@@ -2277,8 +2432,10 @@ const char *module_address_lookup(unsign
36784 +
36785 + preempt_disable();
36786 + list_for_each_entry(mod, &modules, list) {
36787 +- if (within(addr, mod->module_init, mod->init_size)
36788 +- || within(addr, mod->module_core, mod->core_size)) {
36789 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36790 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36791 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36792 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36793 + if (modname)
36794 + *modname = mod->name;
36795 + ret = get_ksymbol(mod, addr, size, offset);
36796 +@@ -2300,8 +2457,10 @@ int lookup_module_symbol_name(unsigned l
36797 +
36798 + preempt_disable();
36799 + list_for_each_entry(mod, &modules, list) {
36800 +- if (within(addr, mod->module_init, mod->init_size) ||
36801 +- within(addr, mod->module_core, mod->core_size)) {
36802 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36803 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36804 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36805 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36806 + const char *sym;
36807 +
36808 + sym = get_ksymbol(mod, addr, NULL, NULL);
36809 +@@ -2324,8 +2483,10 @@ int lookup_module_symbol_attrs(unsigned
36810 +
36811 + preempt_disable();
36812 + list_for_each_entry(mod, &modules, list) {
36813 +- if (within(addr, mod->module_init, mod->init_size) ||
36814 +- within(addr, mod->module_core, mod->core_size)) {
36815 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36816 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36817 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36818 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36819 + const char *sym;
36820 +
36821 + sym = get_ksymbol(mod, addr, size, offset);
36822 +@@ -2456,7 +2617,7 @@ static int m_show(struct seq_file *m, vo
36823 + char buf[8];
36824 +
36825 + seq_printf(m, "%s %lu",
36826 +- mod->name, mod->init_size + mod->core_size);
36827 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
36828 + print_unload_info(m, mod);
36829 +
36830 + /* Informative for users. */
36831 +@@ -2465,7 +2626,7 @@ static int m_show(struct seq_file *m, vo
36832 + mod->state == MODULE_STATE_COMING ? "Loading":
36833 + "Live");
36834 + /* Used by oprofile and other similar tools. */
36835 +- seq_printf(m, " 0x%p", mod->module_core);
36836 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
36837 +
36838 + /* Taints info */
36839 + if (mod->taints)
36840 +@@ -2521,7 +2682,8 @@ int is_module_address(unsigned long addr
36841 + preempt_disable();
36842 +
36843 + list_for_each_entry(mod, &modules, list) {
36844 +- if (within(addr, mod->module_core, mod->core_size)) {
36845 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
36846 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36847 + preempt_enable();
36848 + return 1;
36849 + }
36850 +@@ -2539,8 +2701,8 @@ struct module *__module_text_address(uns
36851 + struct module *mod;
36852 +
36853 + list_for_each_entry(mod, &modules, list)
36854 +- if (within(addr, mod->module_init, mod->init_text_size)
36855 +- || within(addr, mod->module_core, mod->core_text_size))
36856 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
36857 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
36858 + return mod;
36859 + return NULL;
36860 + }
36861 +diff -urNp a/kernel/mutex.c b/kernel/mutex.c
36862 +--- a/kernel/mutex.c 2008-08-20 11:16:13.000000000 -0700
36863 ++++ b/kernel/mutex.c 2008-08-20 18:36:57.000000000 -0700
36864 +@@ -82,7 +82,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
36865 + *
36866 + * This function is similar to (but not equivalent to) down().
36867 + */
36868 +-void inline __sched mutex_lock(struct mutex *lock)
36869 ++inline void __sched mutex_lock(struct mutex *lock)
36870 + {
36871 + might_sleep();
36872 + /*
36873 +diff -urNp a/kernel/panic.c b/kernel/panic.c
36874 +--- a/kernel/panic.c 2008-08-20 11:16:13.000000000 -0700
36875 ++++ b/kernel/panic.c 2008-08-20 18:36:57.000000000 -0700
36876 +@@ -323,6 +323,8 @@ EXPORT_SYMBOL(warn_on_slowpath);
36877 + */
36878 + void __stack_chk_fail(void)
36879 + {
36880 ++ print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
36881 ++ dump_stack();
36882 + panic("stack-protector: Kernel stack is corrupted");
36883 + }
36884 + EXPORT_SYMBOL(__stack_chk_fail);
36885 +diff -urNp a/kernel/pid.c b/kernel/pid.c
36886 +--- a/kernel/pid.c 2008-08-20 11:16:13.000000000 -0700
36887 ++++ b/kernel/pid.c 2008-08-20 18:36:57.000000000 -0700
36888 +@@ -35,6 +35,7 @@
36889 + #include <linux/pid_namespace.h>
36890 + #include <linux/init_task.h>
36891 + #include <linux/syscalls.h>
36892 ++#include <linux/grsecurity.h>
36893 +
36894 + #define pid_hashfn(nr, ns) \
36895 + hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
36896 +@@ -44,7 +45,7 @@ struct pid init_struct_pid = INIT_STRUCT
36897 +
36898 + int pid_max = PID_MAX_DEFAULT;
36899 +
36900 +-#define RESERVED_PIDS 300
36901 ++#define RESERVED_PIDS 500
36902 +
36903 + int pid_max_min = RESERVED_PIDS + 1;
36904 + int pid_max_max = PID_MAX_LIMIT;
36905 +@@ -375,7 +376,14 @@ EXPORT_SYMBOL(pid_task);
36906 + struct task_struct *find_task_by_pid_type_ns(int type, int nr,
36907 + struct pid_namespace *ns)
36908 + {
36909 +- return pid_task(find_pid_ns(nr, ns), type);
36910 ++ struct task_struct *task;
36911 ++
36912 ++ task = pid_task(find_pid_ns(nr, ns), type);
36913 ++
36914 ++ if (gr_pid_is_chrooted(task))
36915 ++ return NULL;
36916 ++
36917 ++ return task;
36918 + }
36919 +
36920 + EXPORT_SYMBOL(find_task_by_pid_type_ns);
36921 +diff -urNp a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
36922 +--- a/kernel/posix-cpu-timers.c 2008-08-20 11:16:13.000000000 -0700
36923 ++++ b/kernel/posix-cpu-timers.c 2008-08-20 18:36:57.000000000 -0700
36924 +@@ -6,6 +6,7 @@
36925 + #include <linux/posix-timers.h>
36926 + #include <asm/uaccess.h>
36927 + #include <linux/errno.h>
36928 ++#include <linux/grsecurity.h>
36929 +
36930 + static int check_clock(const clockid_t which_clock)
36931 + {
36932 +@@ -1174,6 +1175,7 @@ static void check_process_timers(struct
36933 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
36934 + return;
36935 + }
36936 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
36937 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
36938 + /*
36939 + * At the soft limit, send a SIGXCPU every second.
36940 +diff -urNp a/kernel/power/poweroff.c b/kernel/power/poweroff.c
36941 +--- a/kernel/power/poweroff.c 2008-08-20 11:16:13.000000000 -0700
36942 ++++ b/kernel/power/poweroff.c 2008-08-20 18:36:57.000000000 -0700
36943 +@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
36944 + .enable_mask = SYSRQ_ENABLE_BOOT,
36945 + };
36946 +
36947 +-static int pm_sysrq_init(void)
36948 ++static int __init pm_sysrq_init(void)
36949 + {
36950 + register_sysrq_key('o', &sysrq_poweroff_op);
36951 + return 0;
36952 +diff -urNp a/kernel/printk.c b/kernel/printk.c
36953 +--- a/kernel/printk.c 2008-08-20 11:16:13.000000000 -0700
36954 ++++ b/kernel/printk.c 2008-08-20 18:36:57.000000000 -0700
36955 +@@ -32,6 +32,7 @@
36956 + #include <linux/security.h>
36957 + #include <linux/bootmem.h>
36958 + #include <linux/syscalls.h>
36959 ++#include <linux/grsecurity.h>
36960 +
36961 + #include <asm/uaccess.h>
36962 +
36963 +@@ -299,6 +300,11 @@ int do_syslog(int type, char __user *buf
36964 + char c;
36965 + int error = 0;
36966 +
36967 ++#ifdef CONFIG_GRKERNSEC_DMESG
36968 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
36969 ++ return -EPERM;
36970 ++#endif
36971 ++
36972 + error = security_syslog(type);
36973 + if (error)
36974 + return error;
36975 +diff -urNp a/kernel/ptrace.c b/kernel/ptrace.c
36976 +--- a/kernel/ptrace.c 2008-08-20 11:16:13.000000000 -0700
36977 ++++ b/kernel/ptrace.c 2008-08-20 18:36:57.000000000 -0700
36978 +@@ -21,6 +21,7 @@
36979 + #include <linux/audit.h>
36980 + #include <linux/pid_namespace.h>
36981 + #include <linux/syscalls.h>
36982 ++#include <linux/grsecurity.h>
36983 +
36984 + #include <asm/pgtable.h>
36985 + #include <asm/uaccess.h>
36986 +@@ -140,12 +141,12 @@ int __ptrace_may_attach(struct task_stru
36987 + (current->uid != task->uid) ||
36988 + (current->gid != task->egid) ||
36989 + (current->gid != task->sgid) ||
36990 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
36991 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
36992 + return -EPERM;
36993 + smp_rmb();
36994 + if (task->mm)
36995 + dumpable = get_dumpable(task->mm);
36996 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
36997 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
36998 + return -EPERM;
36999 +
37000 + return security_ptrace(current, task);
37001 +@@ -203,7 +204,7 @@ repeat:
37002 +
37003 + /* Go */
37004 + task->ptrace |= PT_PTRACED;
37005 +- if (capable(CAP_SYS_PTRACE))
37006 ++ if (capable_nolog(CAP_SYS_PTRACE))
37007 + task->ptrace |= PT_PTRACE_CAP;
37008 +
37009 + __ptrace_link(task, current);
37010 +@@ -577,6 +578,11 @@ asmlinkage long sys_ptrace(long request,
37011 + if (ret < 0)
37012 + goto out_put_task_struct;
37013 +
37014 ++ if (gr_handle_ptrace(child, request)) {
37015 ++ ret = -EPERM;
37016 ++ goto out_put_task_struct;
37017 ++ }
37018 ++
37019 + ret = arch_ptrace(child, request, addr, data);
37020 + if (ret < 0)
37021 + goto out_put_task_struct;
37022 +diff -urNp a/kernel/relay.c b/kernel/relay.c
37023 +--- a/kernel/relay.c 2008-08-20 11:16:13.000000000 -0700
37024 ++++ b/kernel/relay.c 2008-08-20 18:36:57.000000000 -0700
37025 +@@ -1150,7 +1150,7 @@ static int subbuf_splice_actor(struct fi
37026 + return 0;
37027 +
37028 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
37029 +- if (ret < 0 || ret < total_len)
37030 ++ if ((int)ret < 0 || ret < total_len)
37031 + return ret;
37032 +
37033 + if (read_start + ret == nonpad_end)
37034 +diff -urNp a/kernel/resource.c b/kernel/resource.c
37035 +--- a/kernel/resource.c 2008-08-20 11:16:13.000000000 -0700
37036 ++++ b/kernel/resource.c 2008-08-20 18:36:57.000000000 -0700
37037 +@@ -133,10 +133,27 @@ static int __init ioresources_init(void)
37038 + {
37039 + struct proc_dir_entry *entry;
37040 +
37041 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
37042 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
37043 ++ entry = create_proc_entry("ioports", S_IRUSR, NULL);
37044 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
37045 ++ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
37046 ++#endif
37047 ++#else
37048 + entry = create_proc_entry("ioports", 0, NULL);
37049 ++#endif
37050 + if (entry)
37051 + entry->proc_fops = &proc_ioports_operations;
37052 ++
37053 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
37054 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
37055 ++ entry = create_proc_entry("iomem", S_IRUSR, NULL);
37056 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
37057 ++ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
37058 ++#endif
37059 ++#else
37060 + entry = create_proc_entry("iomem", 0, NULL);
37061 ++#endif
37062 + if (entry)
37063 + entry->proc_fops = &proc_iomem_operations;
37064 + return 0;
37065 +diff -urNp a/kernel/sched.c b/kernel/sched.c
37066 +--- a/kernel/sched.c 2008-08-20 11:16:13.000000000 -0700
37067 ++++ b/kernel/sched.c 2008-08-20 18:36:57.000000000 -0700
37068 +@@ -66,6 +66,7 @@
37069 + #include <linux/unistd.h>
37070 + #include <linux/pagemap.h>
37071 + #include <linux/hrtimer.h>
37072 ++#include <linux/grsecurity.h>
37073 +
37074 + #include <asm/tlb.h>
37075 + #include <asm/irq_regs.h>
37076 +@@ -4499,7 +4500,8 @@ asmlinkage long sys_nice(int increment)
37077 + if (nice > 19)
37078 + nice = 19;
37079 +
37080 +- if (increment < 0 && !can_nice(current, nice))
37081 ++ if (increment < 0 && (!can_nice(current, nice) ||
37082 ++ gr_handle_chroot_nice()))
37083 + return -EPERM;
37084 +
37085 + retval = security_task_setnice(current, nice);
37086 +@@ -5742,7 +5744,7 @@ static struct ctl_table sd_ctl_dir[] = {
37087 + .procname = "sched_domain",
37088 + .mode = 0555,
37089 + },
37090 +- {0, },
37091 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37092 + };
37093 +
37094 + static struct ctl_table sd_ctl_root[] = {
37095 +@@ -5752,7 +5754,7 @@ static struct ctl_table sd_ctl_root[] =
37096 + .mode = 0555,
37097 + .child = sd_ctl_dir,
37098 + },
37099 +- {0, },
37100 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37101 + };
37102 +
37103 + static struct ctl_table *sd_alloc_ctl_entry(int n)
37104 +diff -urNp a/kernel/signal.c b/kernel/signal.c
37105 +--- a/kernel/signal.c 2008-08-20 11:16:13.000000000 -0700
37106 ++++ b/kernel/signal.c 2008-08-20 18:36:57.000000000 -0700
37107 +@@ -25,6 +25,7 @@
37108 + #include <linux/capability.h>
37109 + #include <linux/freezer.h>
37110 + #include <linux/pid_namespace.h>
37111 ++#include <linux/grsecurity.h>
37112 + #include <linux/nsproxy.h>
37113 +
37114 + #include <asm/param.h>
37115 +@@ -540,7 +541,9 @@ static int check_kill_permission(int sig
37116 + && (current->euid ^ t->suid) && (current->euid ^ t->uid)
37117 + && (current->uid ^ t->suid) && (current->uid ^ t->uid)
37118 + && !capable(CAP_KILL))
37119 +- return error;
37120 ++ return error;
37121 ++ if (gr_handle_signal(t, sig))
37122 ++ return error;
37123 + }
37124 +
37125 + return security_task_kill(t, info, sig, 0);
37126 +@@ -757,7 +760,7 @@ static int __init setup_print_fatal_sign
37127 +
37128 + __setup("print-fatal-signals=", setup_print_fatal_signals);
37129 +
37130 +-static int
37131 ++int
37132 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
37133 + {
37134 + int ret = 0;
37135 +@@ -811,8 +814,12 @@ force_sig_info(int sig, struct siginfo *
37136 + }
37137 + }
37138 + ret = specific_send_sig_info(sig, info, t);
37139 ++
37140 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
37141 +
37142 ++ gr_log_signal(sig, t);
37143 ++ gr_handle_crash(t, sig);
37144 ++
37145 + return ret;
37146 + }
37147 +
37148 +@@ -1012,6 +1019,8 @@ int group_send_sig_info(int sig, struct
37149 + ret = __group_send_sig_info(sig, info, p);
37150 + unlock_task_sighand(p, &flags);
37151 + }
37152 ++ if (!ret)
37153 ++ gr_log_signal(sig, p);
37154 + }
37155 +
37156 + return ret;
37157 +diff -urNp a/kernel/softirq.c b/kernel/softirq.c
37158 +--- a/kernel/softirq.c 2008-08-20 11:16:13.000000000 -0700
37159 ++++ b/kernel/softirq.c 2008-08-20 18:36:57.000000000 -0700
37160 +@@ -475,9 +475,9 @@ void tasklet_kill(struct tasklet_struct
37161 + printk("Attempt to kill tasklet from interrupt\n");
37162 +
37163 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
37164 +- do
37165 ++ do {
37166 + yield();
37167 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
37168 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
37169 + }
37170 + tasklet_unlock_wait(t);
37171 + clear_bit(TASKLET_STATE_SCHED, &t->state);
37172 +diff -urNp a/kernel/sys.c b/kernel/sys.c
37173 +--- a/kernel/sys.c 2008-08-20 11:16:13.000000000 -0700
37174 ++++ b/kernel/sys.c 2008-08-20 18:36:57.000000000 -0700
37175 +@@ -33,6 +33,7 @@
37176 + #include <linux/task_io_accounting_ops.h>
37177 + #include <linux/seccomp.h>
37178 + #include <linux/cpu.h>
37179 ++#include <linux/grsecurity.h>
37180 +
37181 + #include <linux/compat.h>
37182 + #include <linux/syscalls.h>
37183 +@@ -119,6 +120,12 @@ static int set_one_prio(struct task_stru
37184 + error = -EACCES;
37185 + goto out;
37186 + }
37187 ++
37188 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
37189 ++ error = -EACCES;
37190 ++ goto out;
37191 ++ }
37192 ++
37193 + no_nice = security_task_setnice(p, niceval);
37194 + if (no_nice) {
37195 + error = no_nice;
37196 +@@ -175,10 +182,10 @@ asmlinkage long sys_setpriority(int whic
37197 + if ((who != current->uid) && !(user = find_user(who)))
37198 + goto out_unlock; /* No processes for this user */
37199 +
37200 +- do_each_thread(g, p)
37201 ++ do_each_thread(g, p) {
37202 + if (p->uid == who)
37203 + error = set_one_prio(p, niceval, error);
37204 +- while_each_thread(g, p);
37205 ++ } while_each_thread(g, p);
37206 + if (who != current->uid)
37207 + free_uid(user); /* For find_user() */
37208 + break;
37209 +@@ -237,13 +244,13 @@ asmlinkage long sys_getpriority(int whic
37210 + if ((who != current->uid) && !(user = find_user(who)))
37211 + goto out_unlock; /* No processes for this user */
37212 +
37213 +- do_each_thread(g, p)
37214 ++ do_each_thread(g, p) {
37215 + if (p->uid == who) {
37216 + niceval = 20 - task_nice(p);
37217 + if (niceval > retval)
37218 + retval = niceval;
37219 + }
37220 +- while_each_thread(g, p);
37221 ++ } while_each_thread(g, p);
37222 + if (who != current->uid)
37223 + free_uid(user); /* for find_user() */
37224 + break;
37225 +@@ -508,6 +515,10 @@ asmlinkage long sys_setregid(gid_t rgid,
37226 + else
37227 + return -EPERM;
37228 + }
37229 ++
37230 ++ if (gr_check_group_change(new_rgid, new_egid, -1))
37231 ++ return -EPERM;
37232 ++
37233 + if (new_egid != old_egid) {
37234 + set_dumpable(current->mm, suid_dumpable);
37235 + smp_wmb();
37236 +@@ -515,6 +526,9 @@ asmlinkage long sys_setregid(gid_t rgid,
37237 + if (rgid != (gid_t) -1 ||
37238 + (egid != (gid_t) -1 && egid != old_rgid))
37239 + current->sgid = new_egid;
37240 ++
37241 ++ gr_set_role_label(current, current->uid, new_rgid);
37242 ++
37243 + current->fsgid = new_egid;
37244 + current->egid = new_egid;
37245 + current->gid = new_rgid;
37246 +@@ -537,11 +551,17 @@ asmlinkage long sys_setgid(gid_t gid)
37247 + if (retval)
37248 + return retval;
37249 +
37250 ++ if (gr_check_group_change(gid, gid, gid))
37251 ++ return -EPERM;
37252 ++
37253 + if (capable(CAP_SETGID)) {
37254 + if (old_egid != gid) {
37255 + set_dumpable(current->mm, suid_dumpable);
37256 + smp_wmb();
37257 + }
37258 ++
37259 ++ gr_set_role_label(current, current->uid, gid);
37260 ++
37261 + current->gid = current->egid = current->sgid = current->fsgid = gid;
37262 + } else if ((gid == current->gid) || (gid == current->sgid)) {
37263 + if (old_egid != gid) {
37264 +@@ -579,6 +599,9 @@ static int set_user(uid_t new_ruid, int
37265 + set_dumpable(current->mm, suid_dumpable);
37266 + smp_wmb();
37267 + }
37268 ++
37269 ++ gr_set_role_label(current, new_ruid, current->gid);
37270 ++
37271 + current->uid = new_ruid;
37272 + return 0;
37273 + }
37274 +@@ -628,6 +651,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
37275 + return -EPERM;
37276 + }
37277 +
37278 ++ if (gr_check_user_change(new_ruid, new_euid, -1))
37279 ++ return -EPERM;
37280 ++
37281 + if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
37282 + return -EAGAIN;
37283 +
37284 +@@ -674,6 +700,12 @@ asmlinkage long sys_setuid(uid_t uid)
37285 + old_suid = current->suid;
37286 + new_suid = old_suid;
37287 +
37288 ++ if (gr_check_crash_uid(uid))
37289 ++ return -EPERM;
37290 ++
37291 ++ if (gr_check_user_change(uid, uid, uid))
37292 ++ return -EPERM;
37293 ++
37294 + if (capable(CAP_SETUID)) {
37295 + if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
37296 + return -EAGAIN;
37297 +@@ -721,6 +753,10 @@ asmlinkage long sys_setresuid(uid_t ruid
37298 + (suid != current->euid) && (suid != current->suid))
37299 + return -EPERM;
37300 + }
37301 ++
37302 ++ if (gr_check_user_change(ruid, euid, -1))
37303 ++ return -EPERM;
37304 ++
37305 + if (ruid != (uid_t) -1) {
37306 + if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
37307 + return -EAGAIN;
37308 +@@ -775,6 +811,10 @@ asmlinkage long sys_setresgid(gid_t rgid
37309 + (sgid != current->egid) && (sgid != current->sgid))
37310 + return -EPERM;
37311 + }
37312 ++
37313 ++ if (gr_check_group_change(rgid, egid, -1))
37314 ++ return -EPERM;
37315 ++
37316 + if (egid != (gid_t) -1) {
37317 + if (egid != current->egid) {
37318 + set_dumpable(current->mm, suid_dumpable);
37319 +@@ -783,8 +823,10 @@ asmlinkage long sys_setresgid(gid_t rgid
37320 + current->egid = egid;
37321 + }
37322 + current->fsgid = current->egid;
37323 +- if (rgid != (gid_t) -1)
37324 ++ if (rgid != (gid_t) -1) {
37325 ++ gr_set_role_label(current, current->uid, rgid);
37326 + current->gid = rgid;
37327 ++ }
37328 + if (sgid != (gid_t) -1)
37329 + current->sgid = sgid;
37330 +
37331 +@@ -819,6 +861,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
37332 + if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
37333 + return old_fsuid;
37334 +
37335 ++ if (gr_check_user_change(-1, -1, uid))
37336 ++ return old_fsuid;
37337 ++
37338 + if (uid == current->uid || uid == current->euid ||
37339 + uid == current->suid || uid == current->fsuid ||
37340 + capable(CAP_SETUID)) {
37341 +@@ -851,6 +896,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
37342 + if (gid == current->gid || gid == current->egid ||
37343 + gid == current->sgid || gid == current->fsgid ||
37344 + capable(CAP_SETGID)) {
37345 ++ if (gr_check_group_change(-1, -1, gid))
37346 ++ return old_fsgid;
37347 ++
37348 + if (gid != old_fsgid) {
37349 + set_dumpable(current->mm, suid_dumpable);
37350 + smp_wmb();
37351 +@@ -932,7 +980,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
37352 + write_lock_irq(&tasklist_lock);
37353 +
37354 + err = -ESRCH;
37355 +- p = find_task_by_vpid(pid);
37356 ++ /* grsec: replaced find_task_by_vpid with equivalent call which
37357 ++ lacks the chroot restriction
37358 ++ */
37359 ++ p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
37360 + if (!p)
37361 + goto out;
37362 +
37363 +@@ -1647,7 +1698,7 @@ asmlinkage long sys_prctl(int option, un
37364 + error = get_dumpable(current->mm);
37365 + break;
37366 + case PR_SET_DUMPABLE:
37367 +- if (arg2 < 0 || arg2 > 1) {
37368 ++ if (arg2 > 1) {
37369 + error = -EINVAL;
37370 + break;
37371 + }
37372 +diff -urNp a/kernel/sysctl.c b/kernel/sysctl.c
37373 +--- a/kernel/sysctl.c 2008-08-20 11:16:13.000000000 -0700
37374 ++++ b/kernel/sysctl.c 2008-08-20 18:36:57.000000000 -0700
37375 +@@ -58,6 +58,13 @@
37376 + static int deprecated_sysctl_warning(struct __sysctl_args *args);
37377 +
37378 + #if defined(CONFIG_SYSCTL)
37379 ++#include <linux/grsecurity.h>
37380 ++#include <linux/grinternal.h>
37381 ++
37382 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
37383 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
37384 ++ const int op);
37385 ++extern int gr_handle_chroot_sysctl(const int op);
37386 +
37387 + /* External variables not in a header file. */
37388 + extern int C_A_D;
37389 +@@ -156,6 +163,7 @@ static int proc_do_cad_pid(struct ctl_ta
37390 + static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
37391 + void __user *buffer, size_t *lenp, loff_t *ppos);
37392 + #endif
37393 ++extern ctl_table grsecurity_table[];
37394 +
37395 + static struct ctl_table root_table[];
37396 + static struct ctl_table_root sysctl_table_root;
37397 +@@ -183,6 +191,21 @@ extern struct ctl_table inotify_table[];
37398 + int sysctl_legacy_va_layout;
37399 + #endif
37400 +
37401 ++#ifdef CONFIG_PAX_SOFTMODE
37402 ++static ctl_table pax_table[] = {
37403 ++ {
37404 ++ .ctl_name = CTL_UNNUMBERED,
37405 ++ .procname = "softmode",
37406 ++ .data = &pax_softmode,
37407 ++ .maxlen = sizeof(unsigned int),
37408 ++ .mode = 0600,
37409 ++ .proc_handler = &proc_dointvec,
37410 ++ },
37411 ++
37412 ++ { .ctl_name = 0 }
37413 ++};
37414 ++#endif
37415 ++
37416 + extern int prove_locking;
37417 + extern int lock_stat;
37418 +
37419 +@@ -219,6 +242,7 @@ static struct ctl_table root_table[] = {
37420 + .mode = 0555,
37421 + .child = dev_table,
37422 + },
37423 ++
37424 + /*
37425 + * NOTE: do not add new entries to this table unless you have read
37426 + * Documentation/sysctl/ctl_unnumbered.txt
37427 +@@ -820,6 +844,24 @@ static struct ctl_table kern_table[] = {
37428 + .proc_handler = &proc_dostring,
37429 + .strategy = &sysctl_string,
37430 + },
37431 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
37432 ++ {
37433 ++ .ctl_name = CTL_UNNUMBERED,
37434 ++ .procname = "grsecurity",
37435 ++ .mode = 0500,
37436 ++ .child = grsecurity_table,
37437 ++ },
37438 ++#endif
37439 ++
37440 ++#ifdef CONFIG_PAX_SOFTMODE
37441 ++ {
37442 ++ .ctl_name = CTL_UNNUMBERED,
37443 ++ .procname = "pax",
37444 ++ .mode = 0500,
37445 ++ .child = pax_table,
37446 ++ },
37447 ++#endif
37448 ++
37449 + /*
37450 + * NOTE: do not add new entries to this table unless you have read
37451 + * Documentation/sysctl/ctl_unnumbered.txt
37452 +@@ -1507,6 +1549,25 @@ static int test_perm(int mode, int op)
37453 + int sysctl_perm(struct ctl_table *table, int op)
37454 + {
37455 + int error;
37456 ++ if (table->parent != NULL && table->parent->procname != NULL &&
37457 ++ table->procname != NULL &&
37458 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
37459 ++ return -EACCES;
37460 ++ if (gr_handle_chroot_sysctl(op))
37461 ++ return -EACCES;
37462 ++ error = gr_handle_sysctl(table, op);
37463 ++ if (error)
37464 ++ return error;
37465 ++ error = security_sysctl(table, op);
37466 ++ if (error)
37467 ++ return error;
37468 ++ return test_perm(table->mode, op);
37469 ++}
37470 ++
37471 ++int sysctl_perm_nochk(ctl_table *table, int op)
37472 ++{
37473 ++ int error;
37474 ++
37475 + error = security_sysctl(table, op);
37476 + if (error)
37477 + return error;
37478 +@@ -1531,13 +1592,14 @@ repeat:
37479 + if (n == table->ctl_name) {
37480 + int error;
37481 + if (table->child) {
37482 +- if (sysctl_perm(table, 001))
37483 ++ if (sysctl_perm_nochk(table, 001))
37484 + return -EPERM;
37485 + name++;
37486 + nlen--;
37487 + table = table->child;
37488 + goto repeat;
37489 + }
37490 ++
37491 + error = do_sysctl_strategy(table, name, nlen,
37492 + oldval, oldlenp,
37493 + newval, newlen);
37494 +diff -urNp a/kernel/time.c b/kernel/time.c
37495 +--- a/kernel/time.c 2008-08-20 11:16:13.000000000 -0700
37496 ++++ b/kernel/time.c 2008-08-20 18:36:57.000000000 -0700
37497 +@@ -35,6 +35,7 @@
37498 + #include <linux/syscalls.h>
37499 + #include <linux/security.h>
37500 + #include <linux/fs.h>
37501 ++#include <linux/grsecurity.h>
37502 +
37503 + #include <asm/uaccess.h>
37504 + #include <asm/unistd.h>
37505 +@@ -90,6 +91,9 @@ asmlinkage long sys_stime(time_t __user
37506 + return err;
37507 +
37508 + do_settimeofday(&tv);
37509 ++
37510 ++ gr_log_timechange();
37511 ++
37512 + return 0;
37513 + }
37514 +
37515 +@@ -198,6 +202,8 @@ asmlinkage long sys_settimeofday(struct
37516 + return -EFAULT;
37517 + }
37518 +
37519 ++ gr_log_timechange();
37520 ++
37521 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
37522 + }
37523 +
37524 +@@ -236,7 +242,7 @@ EXPORT_SYMBOL(current_fs_time);
37525 + * Avoid unnecessary multiplications/divisions in the
37526 + * two most common HZ cases:
37527 + */
37528 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
37529 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
37530 + {
37531 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
37532 + return (MSEC_PER_SEC / HZ) * j;
37533 +@@ -252,7 +258,7 @@ unsigned int inline jiffies_to_msecs(con
37534 + }
37535 + EXPORT_SYMBOL(jiffies_to_msecs);
37536 +
37537 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
37538 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
37539 + {
37540 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
37541 + return (USEC_PER_SEC / HZ) * j;
37542 +diff -urNp a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c
37543 +--- a/kernel/utsname_sysctl.c 2008-08-20 11:16:13.000000000 -0700
37544 ++++ b/kernel/utsname_sysctl.c 2008-08-20 18:36:57.000000000 -0700
37545 +@@ -125,7 +125,7 @@ static struct ctl_table uts_kern_table[]
37546 + .proc_handler = proc_do_uts_string,
37547 + .strategy = sysctl_uts_string,
37548 + },
37549 +- {}
37550 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37551 + };
37552 +
37553 + static struct ctl_table uts_root_table[] = {
37554 +@@ -135,7 +135,7 @@ static struct ctl_table uts_root_table[]
37555 + .mode = 0555,
37556 + .child = uts_kern_table,
37557 + },
37558 +- {}
37559 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37560 + };
37561 +
37562 + static int __init utsname_sysctl_init(void)
37563 +diff -urNp a/lib/radix-tree.c b/lib/radix-tree.c
37564 +--- a/lib/radix-tree.c 2008-08-20 11:16:13.000000000 -0700
37565 ++++ b/lib/radix-tree.c 2008-08-20 18:36:57.000000000 -0700
37566 +@@ -81,7 +81,7 @@ struct radix_tree_preload {
37567 + int nr;
37568 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
37569 + };
37570 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
37571 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
37572 +
37573 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
37574 + {
37575 +diff -urNp a/localversion-grsec b/localversion-grsec
37576 +--- a/localversion-grsec 1969-12-31 16:00:00.000000000 -0800
37577 ++++ b/localversion-grsec 2008-08-20 18:36:57.000000000 -0700
37578 +@@ -0,0 +1 @@
37579 ++-grsec
37580 +diff -urNp a/mm/filemap.c b/mm/filemap.c
37581 +--- a/mm/filemap.c 2008-08-20 11:16:13.000000000 -0700
37582 ++++ b/mm/filemap.c 2008-08-20 18:36:57.000000000 -0700
37583 +@@ -33,6 +33,7 @@
37584 + #include <linux/cpuset.h>
37585 + #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
37586 + #include <linux/memcontrol.h>
37587 ++#include <linux/grsecurity.h>
37588 + #include "internal.h"
37589 +
37590 + /*
37591 +@@ -1481,7 +1482,7 @@ int generic_file_mmap(struct file * file
37592 + struct address_space *mapping = file->f_mapping;
37593 +
37594 + if (!mapping->a_ops->readpage)
37595 +- return -ENOEXEC;
37596 ++ return -ENODEV;
37597 + file_accessed(file);
37598 + vma->vm_ops = &generic_file_vm_ops;
37599 + vma->vm_flags |= VM_CAN_NONLINEAR;
37600 +@@ -1841,6 +1842,7 @@ inline int generic_write_checks(struct f
37601 + *pos = i_size_read(inode);
37602 +
37603 + if (limit != RLIM_INFINITY) {
37604 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
37605 + if (*pos >= limit) {
37606 + send_sig(SIGXFSZ, current, 0);
37607 + return -EFBIG;
37608 +diff -urNp a/mm/fremap.c b/mm/fremap.c
37609 +--- a/mm/fremap.c 2008-08-20 11:16:13.000000000 -0700
37610 ++++ b/mm/fremap.c 2008-08-20 18:36:57.000000000 -0700
37611 +@@ -150,6 +150,13 @@ asmlinkage long sys_remap_file_pages(uns
37612 + retry:
37613 + vma = find_vma(mm, start);
37614 +
37615 ++#ifdef CONFIG_PAX_SEGMEXEC
37616 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
37617 ++ up_read(&mm->mmap_sem);
37618 ++ return err;
37619 ++ }
37620 ++#endif
37621 ++
37622 + /*
37623 + * Make sure the vma is shared, that it supports prefaulting,
37624 + * and that the remapped range is valid and fully within
37625 +diff -urNp a/mm/hugetlb.c b/mm/hugetlb.c
37626 +--- a/mm/hugetlb.c 2008-08-20 11:16:13.000000000 -0700
37627 ++++ b/mm/hugetlb.c 2008-08-20 18:36:57.000000000 -0700
37628 +@@ -847,6 +847,26 @@ void unmap_hugepage_range(struct vm_area
37629 + }
37630 + }
37631 +
37632 ++#ifdef CONFIG_PAX_SEGMEXEC
37633 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
37634 ++{
37635 ++ struct mm_struct *mm = vma->vm_mm;
37636 ++ struct vm_area_struct *vma_m;
37637 ++ unsigned long address_m;
37638 ++ pte_t *ptep_m;
37639 ++
37640 ++ vma_m = pax_find_mirror_vma(vma);
37641 ++ if (!vma_m)
37642 ++ return;
37643 ++
37644 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37645 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37646 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
37647 ++ get_page(page_m);
37648 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
37649 ++}
37650 ++#endif
37651 ++
37652 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
37653 + unsigned long address, pte_t *ptep, pte_t pte)
37654 + {
37655 +@@ -881,6 +901,11 @@ static int hugetlb_cow(struct mm_struct
37656 + /* Break COW */
37657 + set_huge_pte_at(mm, address, ptep,
37658 + make_huge_pte(vma, new_page, 1));
37659 ++
37660 ++#ifdef CONFIG_PAX_SEGMEXEC
37661 ++ pax_mirror_huge_pte(vma, address, new_page);
37662 ++#endif
37663 ++
37664 + /* Make the old page be freed below */
37665 + new_page = old_page;
37666 + }
37667 +@@ -953,6 +978,10 @@ retry:
37668 + && (vma->vm_flags & VM_SHARED)));
37669 + set_huge_pte_at(mm, address, ptep, new_pte);
37670 +
37671 ++#ifdef CONFIG_PAX_SEGMEXEC
37672 ++ pax_mirror_huge_pte(vma, address, page);
37673 ++#endif
37674 ++
37675 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
37676 + /* Optimization, do the COW without a second fault */
37677 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
37678 +@@ -978,6 +1007,27 @@ int hugetlb_fault(struct mm_struct *mm,
37679 + int ret;
37680 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
37681 +
37682 ++#ifdef CONFIG_PAX_SEGMEXEC
37683 ++ struct vm_area_struct *vma_m;
37684 ++
37685 ++ vma_m = pax_find_mirror_vma(vma);
37686 ++ if (vma_m) {
37687 ++ unsigned long address_m;
37688 ++
37689 ++ if (vma->vm_start > vma_m->vm_start) {
37690 ++ address_m = address;
37691 ++ address -= SEGMEXEC_TASK_SIZE;
37692 ++ vma = vma_m;
37693 ++ } else
37694 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37695 ++
37696 ++ if (!huge_pte_alloc(mm, address_m))
37697 ++ return VM_FAULT_OOM;
37698 ++ address_m &= HPAGE_MASK;
37699 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
37700 ++ }
37701 ++#endif
37702 ++
37703 + ptep = huge_pte_alloc(mm, address);
37704 + if (!ptep)
37705 + return VM_FAULT_OOM;
37706 +diff -urNp a/mm/madvise.c b/mm/madvise.c
37707 +--- a/mm/madvise.c 2008-08-20 11:16:13.000000000 -0700
37708 ++++ b/mm/madvise.c 2008-08-20 18:36:57.000000000 -0700
37709 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
37710 + pgoff_t pgoff;
37711 + int new_flags = vma->vm_flags;
37712 +
37713 ++#ifdef CONFIG_PAX_SEGMEXEC
37714 ++ struct vm_area_struct *vma_m;
37715 ++#endif
37716 ++
37717 + switch (behavior) {
37718 + case MADV_NORMAL:
37719 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
37720 +@@ -92,6 +96,13 @@ success:
37721 + /*
37722 + * vm_flags is protected by the mmap_sem held in write mode.
37723 + */
37724 ++
37725 ++#ifdef CONFIG_PAX_SEGMEXEC
37726 ++ vma_m = pax_find_mirror_vma(vma);
37727 ++ if (vma_m)
37728 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
37729 ++#endif
37730 ++
37731 + vma->vm_flags = new_flags;
37732 +
37733 + out:
37734 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
37735 +
37736 + case MADV_DONTNEED:
37737 + error = madvise_dontneed(vma, prev, start, end);
37738 ++
37739 ++#ifdef CONFIG_PAX_SEGMEXEC
37740 ++ if (!error) {
37741 ++ struct vm_area_struct *vma_m, *prev_m;
37742 ++
37743 ++ vma_m = pax_find_mirror_vma(vma);
37744 ++ if (vma_m)
37745 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
37746 ++ }
37747 ++#endif
37748 ++
37749 + break;
37750 +
37751 + default:
37752 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
37753 + if (end < start)
37754 + goto out;
37755 +
37756 ++#ifdef CONFIG_PAX_SEGMEXEC
37757 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
37758 ++ if (end > SEGMEXEC_TASK_SIZE)
37759 ++ goto out;
37760 ++ } else
37761 ++#endif
37762 ++
37763 ++ if (end > TASK_SIZE)
37764 ++ goto out;
37765 ++
37766 + error = 0;
37767 + if (end == start)
37768 + goto out;
37769 +diff -urNp a/mm/memory.c b/mm/memory.c
37770 +--- a/mm/memory.c 2008-08-20 11:16:13.000000000 -0700
37771 ++++ b/mm/memory.c 2008-08-20 18:36:57.000000000 -0700
37772 +@@ -51,6 +51,7 @@
37773 + #include <linux/init.h>
37774 + #include <linux/writeback.h>
37775 + #include <linux/memcontrol.h>
37776 ++#include <linux/grsecurity.h>
37777 +
37778 + #include <asm/pgalloc.h>
37779 + #include <asm/uaccess.h>
37780 +@@ -1026,11 +1027,11 @@ int get_user_pages(struct task_struct *t
37781 + vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
37782 + i = 0;
37783 +
37784 +- do {
37785 ++ while (len) {
37786 + struct vm_area_struct *vma;
37787 + unsigned int foll_flags;
37788 +
37789 +- vma = find_extend_vma(mm, start);
37790 ++ vma = find_vma(mm, start);
37791 + if (!vma && in_gate_area(tsk, start)) {
37792 + unsigned long pg = start & PAGE_MASK;
37793 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
37794 +@@ -1070,7 +1071,7 @@ int get_user_pages(struct task_struct *t
37795 + continue;
37796 + }
37797 +
37798 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
37799 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
37800 + || !(vm_flags & vma->vm_flags))
37801 + return i ? : -EFAULT;
37802 +
37803 +@@ -1143,7 +1144,7 @@ int get_user_pages(struct task_struct *t
37804 + start += PAGE_SIZE;
37805 + len--;
37806 + } while (len && start < vma->vm_end);
37807 +- } while (len);
37808 ++ }
37809 + return i;
37810 + }
37811 + EXPORT_SYMBOL(get_user_pages);
37812 +@@ -1569,6 +1570,186 @@ static inline void cow_user_page(struct
37813 + copy_user_highpage(dst, src, va, vma);
37814 + }
37815 +
37816 ++#ifdef CONFIG_PAX_SEGMEXEC
37817 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
37818 ++{
37819 ++ struct mm_struct *mm = vma->vm_mm;
37820 ++ spinlock_t *ptl;
37821 ++ pte_t *pte, entry;
37822 ++
37823 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
37824 ++ entry = *pte;
37825 ++ if (!pte_present(entry)) {
37826 ++ if (!pte_none(entry)) {
37827 ++ BUG_ON(pte_file(entry));
37828 ++ free_swap_and_cache(pte_to_swp_entry(entry));
37829 ++ pte_clear_not_present_full(mm, address, pte, 0);
37830 ++ }
37831 ++ } else {
37832 ++ struct page *page;
37833 ++
37834 ++ flush_cache_page(vma, address, pte_pfn(entry));
37835 ++ entry = ptep_clear_flush(vma, address, pte);
37836 ++ BUG_ON(pte_dirty(entry));
37837 ++ page = vm_normal_page(vma, address, entry);
37838 ++ if (page) {
37839 ++ update_hiwater_rss(mm);
37840 ++ if (PageAnon(page))
37841 ++ dec_mm_counter(mm, anon_rss);
37842 ++ else
37843 ++ dec_mm_counter(mm, file_rss);
37844 ++ page_remove_rmap(page, vma);
37845 ++ page_cache_release(page);
37846 ++ }
37847 ++ }
37848 ++ pte_unmap_unlock(pte, ptl);
37849 ++}
37850 ++
37851 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
37852 ++ *
37853 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
37854 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
37855 ++ */
37856 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
37857 ++{
37858 ++ struct mm_struct *mm = vma->vm_mm;
37859 ++ unsigned long address_m;
37860 ++ spinlock_t *ptl_m;
37861 ++ struct vm_area_struct *vma_m;
37862 ++ pmd_t *pmd_m;
37863 ++ pte_t *pte_m, entry_m;
37864 ++
37865 ++ BUG_ON(!page_m || !PageAnon(page_m));
37866 ++
37867 ++ vma_m = pax_find_mirror_vma(vma);
37868 ++ if (!vma_m)
37869 ++ return;
37870 ++
37871 ++ BUG_ON(!PageLocked(page_m));
37872 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37873 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37874 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37875 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37876 ++ ptl_m = pte_lockptr(mm, pmd_m);
37877 ++ if (ptl != ptl_m) {
37878 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37879 ++ if (!pte_none(*pte_m))
37880 ++ goto out;
37881 ++ }
37882 ++
37883 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
37884 ++ page_cache_get(page_m);
37885 ++ page_add_anon_rmap(page_m, vma_m, address_m);
37886 ++ inc_mm_counter(mm, anon_rss);
37887 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37888 ++ update_mmu_cache(vma_m, address_m, entry_m);
37889 ++out:
37890 ++ if (ptl != ptl_m)
37891 ++ spin_unlock(ptl_m);
37892 ++ pte_unmap_nested(pte_m);
37893 ++ unlock_page(page_m);
37894 ++}
37895 ++
37896 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
37897 ++{
37898 ++ struct mm_struct *mm = vma->vm_mm;
37899 ++ unsigned long address_m;
37900 ++ spinlock_t *ptl_m;
37901 ++ struct vm_area_struct *vma_m;
37902 ++ pmd_t *pmd_m;
37903 ++ pte_t *pte_m, entry_m;
37904 ++
37905 ++ BUG_ON(!page_m || PageAnon(page_m));
37906 ++
37907 ++ vma_m = pax_find_mirror_vma(vma);
37908 ++ if (!vma_m)
37909 ++ return;
37910 ++
37911 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37912 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37913 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37914 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37915 ++ ptl_m = pte_lockptr(mm, pmd_m);
37916 ++ if (ptl != ptl_m) {
37917 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37918 ++ if (!pte_none(*pte_m))
37919 ++ goto out;
37920 ++ }
37921 ++
37922 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
37923 ++ page_cache_get(page_m);
37924 ++ page_add_file_rmap(page_m);
37925 ++ inc_mm_counter(mm, file_rss);
37926 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37927 ++ update_mmu_cache(vma_m, address_m, entry_m);
37928 ++out:
37929 ++ if (ptl != ptl_m)
37930 ++ spin_unlock(ptl_m);
37931 ++ pte_unmap_nested(pte_m);
37932 ++}
37933 ++
37934 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
37935 ++{
37936 ++ struct mm_struct *mm = vma->vm_mm;
37937 ++ unsigned long address_m;
37938 ++ spinlock_t *ptl_m;
37939 ++ struct vm_area_struct *vma_m;
37940 ++ pmd_t *pmd_m;
37941 ++ pte_t *pte_m, entry_m;
37942 ++
37943 ++ vma_m = pax_find_mirror_vma(vma);
37944 ++ if (!vma_m)
37945 ++ return;
37946 ++
37947 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37948 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37949 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37950 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37951 ++ ptl_m = pte_lockptr(mm, pmd_m);
37952 ++ if (ptl != ptl_m) {
37953 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37954 ++ if (!pte_none(*pte_m))
37955 ++ goto out;
37956 ++ }
37957 ++
37958 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
37959 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37960 ++out:
37961 ++ if (ptl != ptl_m)
37962 ++ spin_unlock(ptl_m);
37963 ++ pte_unmap_nested(pte_m);
37964 ++}
37965 ++
37966 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
37967 ++{
37968 ++ struct page *page_m;
37969 ++ pte_t entry;
37970 ++
37971 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
37972 ++ goto out;
37973 ++
37974 ++ entry = *pte;
37975 ++ page_m = vm_normal_page(vma, address, entry);
37976 ++ if (!page_m)
37977 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
37978 ++ else if (PageAnon(page_m)) {
37979 ++ if (pax_find_mirror_vma(vma)) {
37980 ++ pte_unmap_unlock(pte, ptl);
37981 ++ lock_page(page_m);
37982 ++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
37983 ++ if (pte_same(entry, *pte))
37984 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
37985 ++ else
37986 ++ unlock_page(page_m);
37987 ++ }
37988 ++ } else
37989 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
37990 ++
37991 ++out:
37992 ++ pte_unmap_unlock(pte, ptl);
37993 ++}
37994 ++#endif
37995 ++
37996 + /*
37997 + * This routine handles present pages, when users try to write
37998 + * to a shared page. It is done by copying the page to a new address
37999 +@@ -1685,6 +1866,12 @@ gotten:
38000 + */
38001 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
38002 + if (likely(pte_same(*page_table, orig_pte))) {
38003 ++
38004 ++#ifdef CONFIG_PAX_SEGMEXEC
38005 ++ if (pax_find_mirror_vma(vma))
38006 ++ BUG_ON(TestSetPageLocked(new_page));
38007 ++#endif
38008 ++
38009 + if (old_page) {
38010 + page_remove_rmap(old_page, vma);
38011 + if (!PageAnon(old_page)) {
38012 +@@ -1708,6 +1895,10 @@ gotten:
38013 + lru_cache_add_active(new_page);
38014 + page_add_new_anon_rmap(new_page, vma, address);
38015 +
38016 ++#ifdef CONFIG_PAX_SEGMEXEC
38017 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
38018 ++#endif
38019 ++
38020 + /* Free the old page.. */
38021 + new_page = old_page;
38022 + ret |= VM_FAULT_WRITE;
38023 +@@ -1967,6 +2158,7 @@ int vmtruncate(struct inode * inode, lof
38024 + unsigned long limit;
38025 +
38026 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
38027 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
38028 + if (limit != RLIM_INFINITY && offset > limit)
38029 + goto out_sig;
38030 + if (offset > inode->i_sb->s_maxbytes)
38031 +@@ -2117,6 +2309,11 @@ static int do_swap_page(struct mm_struct
38032 + swap_free(entry);
38033 + if (vm_swap_full())
38034 + remove_exclusive_swap_page(page);
38035 ++
38036 ++#ifdef CONFIG_PAX_SEGMEXEC
38037 ++ if (write_access || !pax_find_mirror_vma(vma))
38038 ++#endif
38039 ++
38040 + unlock_page(page);
38041 +
38042 + if (write_access) {
38043 +@@ -2128,6 +2325,11 @@ static int do_swap_page(struct mm_struct
38044 +
38045 + /* No need to invalidate - it was non-present before */
38046 + update_mmu_cache(vma, address, pte);
38047 ++
38048 ++#ifdef CONFIG_PAX_SEGMEXEC
38049 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38050 ++#endif
38051 ++
38052 + unlock:
38053 + pte_unmap_unlock(page_table, ptl);
38054 + out:
38055 +@@ -2172,6 +2374,12 @@ static int do_anonymous_page(struct mm_s
38056 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
38057 + if (!pte_none(*page_table))
38058 + goto release;
38059 ++
38060 ++#ifdef CONFIG_PAX_SEGMEXEC
38061 ++ if (pax_find_mirror_vma(vma))
38062 ++ BUG_ON(TestSetPageLocked(page));
38063 ++#endif
38064 ++
38065 + inc_mm_counter(mm, anon_rss);
38066 + lru_cache_add_active(page);
38067 + page_add_new_anon_rmap(page, vma, address);
38068 +@@ -2179,6 +2387,11 @@ static int do_anonymous_page(struct mm_s
38069 +
38070 + /* No need to invalidate - it was non-present before */
38071 + update_mmu_cache(vma, address, entry);
38072 ++
38073 ++#ifdef CONFIG_PAX_SEGMEXEC
38074 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38075 ++#endif
38076 ++
38077 + unlock:
38078 + pte_unmap_unlock(page_table, ptl);
38079 + return 0;
38080 +@@ -2320,6 +2533,12 @@ static int __do_fault(struct mm_struct *
38081 + */
38082 + /* Only go through if we didn't race with anybody else... */
38083 + if (likely(pte_same(*page_table, orig_pte))) {
38084 ++
38085 ++#ifdef CONFIG_PAX_SEGMEXEC
38086 ++ if (anon && pax_find_mirror_vma(vma))
38087 ++ BUG_ON(TestSetPageLocked(page));
38088 ++#endif
38089 ++
38090 + flush_icache_page(vma, page);
38091 + entry = mk_pte(page, vma->vm_page_prot);
38092 + if (flags & FAULT_FLAG_WRITE)
38093 +@@ -2340,6 +2559,14 @@ static int __do_fault(struct mm_struct *
38094 +
38095 + /* no need to invalidate: a not-present page won't be cached */
38096 + update_mmu_cache(vma, address, entry);
38097 ++
38098 ++#ifdef CONFIG_PAX_SEGMEXEC
38099 ++ if (anon)
38100 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38101 ++ else
38102 ++ pax_mirror_file_pte(vma, address, page, ptl);
38103 ++#endif
38104 ++
38105 + } else {
38106 + mem_cgroup_uncharge_page(page);
38107 + if (anon)
38108 +@@ -2423,6 +2650,11 @@ static noinline int do_no_pfn(struct mm_
38109 + if (write_access)
38110 + entry = maybe_mkwrite(pte_mkdirty(entry), vma);
38111 + set_pte_at(mm, address, page_table, entry);
38112 ++
38113 ++#ifdef CONFIG_PAX_SEGMEXEC
38114 ++ pax_mirror_pfn_pte(vma, address, pfn, ptl);
38115 ++#endif
38116 ++
38117 + }
38118 + pte_unmap_unlock(page_table, ptl);
38119 + return 0;
38120 +@@ -2525,6 +2757,12 @@ static inline int handle_pte_fault(struc
38121 + if (write_access)
38122 + flush_tlb_page(vma, address);
38123 + }
38124 ++
38125 ++#ifdef CONFIG_PAX_SEGMEXEC
38126 ++ pax_mirror_pte(vma, address, pte, pmd, ptl);
38127 ++ return 0;
38128 ++#endif
38129 ++
38130 + unlock:
38131 + pte_unmap_unlock(pte, ptl);
38132 + return 0;
38133 +@@ -2541,6 +2779,10 @@ int handle_mm_fault(struct mm_struct *mm
38134 + pmd_t *pmd;
38135 + pte_t *pte;
38136 +
38137 ++#ifdef CONFIG_PAX_SEGMEXEC
38138 ++ struct vm_area_struct *vma_m;
38139 ++#endif
38140 ++
38141 + __set_current_state(TASK_RUNNING);
38142 +
38143 + count_vm_event(PGFAULT);
38144 +@@ -2548,6 +2790,34 @@ int handle_mm_fault(struct mm_struct *mm
38145 + if (unlikely(is_vm_hugetlb_page(vma)))
38146 + return hugetlb_fault(mm, vma, address, write_access);
38147 +
38148 ++#ifdef CONFIG_PAX_SEGMEXEC
38149 ++ vma_m = pax_find_mirror_vma(vma);
38150 ++ if (vma_m) {
38151 ++ unsigned long address_m;
38152 ++ pgd_t *pgd_m;
38153 ++ pud_t *pud_m;
38154 ++ pmd_t *pmd_m;
38155 ++
38156 ++ if (vma->vm_start > vma_m->vm_start) {
38157 ++ address_m = address;
38158 ++ address -= SEGMEXEC_TASK_SIZE;
38159 ++ vma = vma_m;
38160 ++ } else
38161 ++ address_m = address + SEGMEXEC_TASK_SIZE;
38162 ++
38163 ++ pgd_m = pgd_offset(mm, address_m);
38164 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
38165 ++ if (!pud_m)
38166 ++ return VM_FAULT_OOM;
38167 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
38168 ++ if (!pmd_m)
38169 ++ return VM_FAULT_OOM;
38170 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
38171 ++ return VM_FAULT_OOM;
38172 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
38173 ++ }
38174 ++#endif
38175 ++
38176 + pgd = pgd_offset(mm, address);
38177 + pud = pud_alloc(mm, pgd, address);
38178 + if (!pud)
38179 +@@ -2651,7 +2921,7 @@ static int __init gate_vma_init(void)
38180 + gate_vma.vm_start = FIXADDR_USER_START;
38181 + gate_vma.vm_end = FIXADDR_USER_END;
38182 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
38183 +- gate_vma.vm_page_prot = __P101;
38184 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
38185 + /*
38186 + * Make sure the vDSO gets into every core dump.
38187 + * Dumping its contents makes post-mortem fully interpretable later
38188 +diff -urNp a/mm/mempolicy.c b/mm/mempolicy.c
38189 +--- a/mm/mempolicy.c 2008-08-20 11:16:13.000000000 -0700
38190 ++++ b/mm/mempolicy.c 2008-08-20 18:36:57.000000000 -0700
38191 +@@ -433,6 +433,10 @@ static int mbind_range(struct vm_area_st
38192 + struct vm_area_struct *next;
38193 + int err;
38194 +
38195 ++#ifdef CONFIG_PAX_SEGMEXEC
38196 ++ struct vm_area_struct *vma_m;
38197 ++#endif
38198 ++
38199 + err = 0;
38200 + for (; vma && vma->vm_start < end; vma = next) {
38201 + next = vma->vm_next;
38202 +@@ -444,6 +448,16 @@ static int mbind_range(struct vm_area_st
38203 + err = policy_vma(vma, new);
38204 + if (err)
38205 + break;
38206 ++
38207 ++#ifdef CONFIG_PAX_SEGMEXEC
38208 ++ vma_m = pax_find_mirror_vma(vma);
38209 ++ if (vma_m) {
38210 ++ err = policy_vma(vma_m, new);
38211 ++ if (err)
38212 ++ break;
38213 ++ }
38214 ++#endif
38215 ++
38216 + }
38217 + return err;
38218 + }
38219 +@@ -809,6 +823,17 @@ static long do_mbind(unsigned long start
38220 +
38221 + if (end < start)
38222 + return -EINVAL;
38223 ++
38224 ++#ifdef CONFIG_PAX_SEGMEXEC
38225 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
38226 ++ if (end > SEGMEXEC_TASK_SIZE)
38227 ++ return -EINVAL;
38228 ++ } else
38229 ++#endif
38230 ++
38231 ++ if (end > TASK_SIZE)
38232 ++ return -EINVAL;
38233 ++
38234 + if (end == start)
38235 + return 0;
38236 +
38237 +diff -urNp a/mm/mlock.c b/mm/mlock.c
38238 +--- a/mm/mlock.c 2008-08-20 11:16:13.000000000 -0700
38239 ++++ b/mm/mlock.c 2008-08-20 18:36:57.000000000 -0700
38240 +@@ -12,6 +12,7 @@
38241 + #include <linux/syscalls.h>
38242 + #include <linux/sched.h>
38243 + #include <linux/module.h>
38244 ++#include <linux/grsecurity.h>
38245 +
38246 + int can_do_mlock(void)
38247 + {
38248 +@@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
38249 + return -EINVAL;
38250 + if (end == start)
38251 + return 0;
38252 ++
38253 ++#ifdef CONFIG_PAX_SEGMEXEC
38254 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
38255 ++ if (end > SEGMEXEC_TASK_SIZE)
38256 ++ return -EINVAL;
38257 ++ } else
38258 ++#endif
38259 ++
38260 ++ if (end > TASK_SIZE)
38261 ++ return -EINVAL;
38262 ++
38263 + vma = find_vma_prev(current->mm, start, &prev);
38264 + if (!vma || vma->vm_start > start)
38265 + return -ENOMEM;
38266 +@@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long
38267 + lock_limit >>= PAGE_SHIFT;
38268 +
38269 + /* check against resource limits */
38270 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
38271 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
38272 + error = do_mlock(start, len, 1);
38273 + up_write(&current->mm->mmap_sem);
38274 +@@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
38275 + static int do_mlockall(int flags)
38276 + {
38277 + struct vm_area_struct * vma, * prev = NULL;
38278 +- unsigned int def_flags = 0;
38279 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
38280 +
38281 + if (flags & MCL_FUTURE)
38282 +- def_flags = VM_LOCKED;
38283 ++ def_flags |= VM_LOCKED;
38284 + current->mm->def_flags = def_flags;
38285 + if (flags == MCL_FUTURE)
38286 + goto out;
38287 +@@ -182,6 +195,12 @@ static int do_mlockall(int flags)
38288 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
38289 + unsigned int newflags;
38290 +
38291 ++#ifdef CONFIG_PAX_SEGMEXEC
38292 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
38293 ++ break;
38294 ++#endif
38295 ++
38296 ++ BUG_ON(vma->vm_end > TASK_SIZE);
38297 + newflags = vma->vm_flags | VM_LOCKED;
38298 + if (!(flags & MCL_CURRENT))
38299 + newflags &= ~VM_LOCKED;
38300 +@@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
38301 + lock_limit >>= PAGE_SHIFT;
38302 +
38303 + ret = -ENOMEM;
38304 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
38305 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
38306 + capable(CAP_IPC_LOCK))
38307 + ret = do_mlockall(flags);
38308 +diff -urNp a/mm/mmap.c b/mm/mmap.c
38309 +--- a/mm/mmap.c 2008-08-20 11:16:13.000000000 -0700
38310 ++++ b/mm/mmap.c 2008-08-20 18:36:57.000000000 -0700
38311 +@@ -26,6 +26,7 @@
38312 + #include <linux/mount.h>
38313 + #include <linux/mempolicy.h>
38314 + #include <linux/rmap.h>
38315 ++#include <linux/grsecurity.h>
38316 +
38317 + #include <asm/uaccess.h>
38318 + #include <asm/cacheflush.h>
38319 +@@ -40,6 +41,16 @@
38320 + #define arch_rebalance_pgtables(addr, len) (addr)
38321 + #endif
38322 +
38323 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
38324 ++{
38325 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
38326 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
38327 ++ up_read(&mm->mmap_sem);
38328 ++ BUG();
38329 ++ }
38330 ++#endif
38331 ++}
38332 ++
38333 + static void unmap_region(struct mm_struct *mm,
38334 + struct vm_area_struct *vma, struct vm_area_struct *prev,
38335 + unsigned long start, unsigned long end);
38336 +@@ -65,15 +76,23 @@ static void unmap_region(struct mm_struc
38337 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
38338 + *
38339 + */
38340 +-pgprot_t protection_map[16] = {
38341 ++pgprot_t protection_map[16] __read_only = {
38342 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
38343 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
38344 + };
38345 +
38346 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
38347 + {
38348 +- return protection_map[vm_flags &
38349 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38350 ++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38351 ++
38352 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38353 ++ if (!nx_enabled &&
38354 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
38355 ++ (vm_flags & (VM_READ | VM_WRITE)))
38356 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
38357 ++#endif
38358 ++
38359 ++ return prot;
38360 + }
38361 + EXPORT_SYMBOL(vm_get_page_prot);
38362 +
38363 +@@ -228,6 +247,7 @@ static struct vm_area_struct *remove_vma
38364 + struct vm_area_struct *next = vma->vm_next;
38365 +
38366 + might_sleep();
38367 ++ BUG_ON(vma->vm_mirror);
38368 + if (vma->vm_ops && vma->vm_ops->close)
38369 + vma->vm_ops->close(vma);
38370 + if (vma->vm_file)
38371 +@@ -261,6 +281,7 @@ asmlinkage unsigned long sys_brk(unsigne
38372 + * not page aligned -Ram Gupta
38373 + */
38374 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
38375 ++ gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
38376 + if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
38377 + (mm->end_data - mm->start_data) > rlim)
38378 + goto out;
38379 +@@ -362,8 +383,12 @@ find_vma_prepare(struct mm_struct *mm, u
38380 +
38381 + if (vma_tmp->vm_end > addr) {
38382 + vma = vma_tmp;
38383 +- if (vma_tmp->vm_start <= addr)
38384 +- return vma;
38385 ++ if (vma_tmp->vm_start <= addr) {
38386 ++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
38387 ++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
38388 ++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
38389 ++ break;
38390 ++ }
38391 + __rb_link = &__rb_parent->rb_left;
38392 + } else {
38393 + rb_prev = __rb_parent;
38394 +@@ -687,6 +712,12 @@ static int
38395 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
38396 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
38397 + {
38398 ++
38399 ++#ifdef CONFIG_PAX_SEGMEXEC
38400 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
38401 ++ return 0;
38402 ++#endif
38403 ++
38404 + if (is_mergeable_vma(vma, file, vm_flags) &&
38405 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
38406 + if (vma->vm_pgoff == vm_pgoff)
38407 +@@ -706,6 +737,12 @@ static int
38408 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
38409 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
38410 + {
38411 ++
38412 ++#ifdef CONFIG_PAX_SEGMEXEC
38413 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
38414 ++ return 0;
38415 ++#endif
38416 ++
38417 + if (is_mergeable_vma(vma, file, vm_flags) &&
38418 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
38419 + pgoff_t vm_pglen;
38420 +@@ -748,12 +785,19 @@ can_vma_merge_after(struct vm_area_struc
38421 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
38422 + struct vm_area_struct *prev, unsigned long addr,
38423 + unsigned long end, unsigned long vm_flags,
38424 +- struct anon_vma *anon_vma, struct file *file,
38425 ++ struct anon_vma *anon_vma, struct file *file,
38426 + pgoff_t pgoff, struct mempolicy *policy)
38427 + {
38428 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
38429 + struct vm_area_struct *area, *next;
38430 +
38431 ++#ifdef CONFIG_PAX_SEGMEXEC
38432 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
38433 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
38434 ++
38435 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
38436 ++#endif
38437 ++
38438 + /*
38439 + * We later require that vma->vm_flags == vm_flags,
38440 + * so this tests vma->vm_flags & VM_SPECIAL, too.
38441 +@@ -769,6 +813,15 @@ struct vm_area_struct *vma_merge(struct
38442 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
38443 + next = next->vm_next;
38444 +
38445 ++#ifdef CONFIG_PAX_SEGMEXEC
38446 ++ if (prev)
38447 ++ prev_m = pax_find_mirror_vma(prev);
38448 ++ if (area)
38449 ++ area_m = pax_find_mirror_vma(area);
38450 ++ if (next)
38451 ++ next_m = pax_find_mirror_vma(next);
38452 ++#endif
38453 ++
38454 + /*
38455 + * Can it merge with the predecessor?
38456 + */
38457 +@@ -788,9 +841,24 @@ struct vm_area_struct *vma_merge(struct
38458 + /* cases 1, 6 */
38459 + vma_adjust(prev, prev->vm_start,
38460 + next->vm_end, prev->vm_pgoff, NULL);
38461 +- } else /* cases 2, 5, 7 */
38462 ++
38463 ++#ifdef CONFIG_PAX_SEGMEXEC
38464 ++ if (prev_m)
38465 ++ vma_adjust(prev_m, prev_m->vm_start,
38466 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
38467 ++#endif
38468 ++
38469 ++ } else { /* cases 2, 5, 7 */
38470 + vma_adjust(prev, prev->vm_start,
38471 + end, prev->vm_pgoff, NULL);
38472 ++
38473 ++#ifdef CONFIG_PAX_SEGMEXEC
38474 ++ if (prev_m)
38475 ++ vma_adjust(prev_m, prev_m->vm_start,
38476 ++ end_m, prev_m->vm_pgoff, NULL);
38477 ++#endif
38478 ++
38479 ++ }
38480 + return prev;
38481 + }
38482 +
38483 +@@ -801,12 +869,27 @@ struct vm_area_struct *vma_merge(struct
38484 + mpol_equal(policy, vma_policy(next)) &&
38485 + can_vma_merge_before(next, vm_flags,
38486 + anon_vma, file, pgoff+pglen)) {
38487 +- if (prev && addr < prev->vm_end) /* case 4 */
38488 ++ if (prev && addr < prev->vm_end) { /* case 4 */
38489 + vma_adjust(prev, prev->vm_start,
38490 + addr, prev->vm_pgoff, NULL);
38491 +- else /* cases 3, 8 */
38492 ++
38493 ++#ifdef CONFIG_PAX_SEGMEXEC
38494 ++ if (prev_m)
38495 ++ vma_adjust(prev_m, prev_m->vm_start,
38496 ++ addr_m, prev_m->vm_pgoff, NULL);
38497 ++#endif
38498 ++
38499 ++ } else { /* cases 3, 8 */
38500 + vma_adjust(area, addr, next->vm_end,
38501 + next->vm_pgoff - pglen, NULL);
38502 ++
38503 ++#ifdef CONFIG_PAX_SEGMEXEC
38504 ++ if (area_m)
38505 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
38506 ++ next_m->vm_pgoff - pglen, NULL);
38507 ++#endif
38508 ++
38509 ++ }
38510 + return area;
38511 + }
38512 +
38513 +@@ -881,14 +964,11 @@ none:
38514 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
38515 + struct file *file, long pages)
38516 + {
38517 +- const unsigned long stack_flags
38518 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
38519 +-
38520 + if (file) {
38521 + mm->shared_vm += pages;
38522 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
38523 + mm->exec_vm += pages;
38524 +- } else if (flags & stack_flags)
38525 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
38526 + mm->stack_vm += pages;
38527 + if (flags & (VM_RESERVED|VM_IO))
38528 + mm->reserved_vm += pages;
38529 +@@ -916,7 +996,7 @@ unsigned long do_mmap_pgoff(struct file
38530 + * (the exception is when the underlying filesystem is noexec
38531 + * mounted, in which case we dont add PROT_EXEC.)
38532 + */
38533 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
38534 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
38535 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
38536 + prot |= PROT_EXEC;
38537 +
38538 +@@ -926,15 +1006,15 @@ unsigned long do_mmap_pgoff(struct file
38539 + if (!(flags & MAP_FIXED))
38540 + addr = round_hint_to_min(addr);
38541 +
38542 +- error = arch_mmap_check(addr, len, flags);
38543 +- if (error)
38544 +- return error;
38545 +-
38546 + /* Careful about overflows.. */
38547 + len = PAGE_ALIGN(len);
38548 + if (!len || len > TASK_SIZE)
38549 + return -ENOMEM;
38550 +
38551 ++ error = arch_mmap_check(addr, len, flags);
38552 ++ if (error)
38553 ++ return error;
38554 ++
38555 + /* offset overflow? */
38556 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
38557 + return -EOVERFLOW;
38558 +@@ -946,7 +1026,7 @@ unsigned long do_mmap_pgoff(struct file
38559 + /* Obtain the address to map to. we verify (or select) it and ensure
38560 + * that it represents a valid section of the address space.
38561 + */
38562 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
38563 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
38564 + if (addr & ~PAGE_MASK)
38565 + return addr;
38566 +
38567 +@@ -957,6 +1037,26 @@ unsigned long do_mmap_pgoff(struct file
38568 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
38569 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
38570 +
38571 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
38572 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
38573 ++
38574 ++#ifdef CONFIG_PAX_MPROTECT
38575 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
38576 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
38577 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
38578 ++ else
38579 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
38580 ++ }
38581 ++#endif
38582 ++
38583 ++ }
38584 ++#endif
38585 ++
38586 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38587 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
38588 ++ vm_flags &= ~VM_PAGEEXEC;
38589 ++#endif
38590 ++
38591 + if (flags & MAP_LOCKED) {
38592 + if (!can_do_mlock())
38593 + return -EPERM;
38594 +@@ -969,6 +1069,7 @@ unsigned long do_mmap_pgoff(struct file
38595 + locked += mm->locked_vm;
38596 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
38597 + lock_limit >>= PAGE_SHIFT;
38598 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
38599 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
38600 + return -EAGAIN;
38601 + }
38602 +@@ -1037,6 +1138,9 @@ unsigned long do_mmap_pgoff(struct file
38603 + if (error)
38604 + return error;
38605 +
38606 ++ if (!gr_acl_handle_mmap(file, prot))
38607 ++ return -EACCES;
38608 ++
38609 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
38610 + accountable);
38611 + }
38612 +@@ -1050,10 +1154,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
38613 + */
38614 + int vma_wants_writenotify(struct vm_area_struct *vma)
38615 + {
38616 +- unsigned int vm_flags = vma->vm_flags;
38617 ++ unsigned long vm_flags = vma->vm_flags;
38618 +
38619 + /* If it was private or non-writable, the write bit is already clear */
38620 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
38621 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
38622 + return 0;
38623 +
38624 + /* The backer wishes to know when pages are first written to? */
38625 +@@ -1088,14 +1192,24 @@ unsigned long mmap_region(struct file *f
38626 + unsigned long charged = 0;
38627 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
38628 +
38629 ++#ifdef CONFIG_PAX_SEGMEXEC
38630 ++ struct vm_area_struct *vma_m = NULL;
38631 ++#endif
38632 ++
38633 ++ /*
38634 ++ * mm->mmap_sem is required to protect against another thread
38635 ++ * changing the mappings in case we sleep.
38636 ++ */
38637 ++ verify_mm_writelocked(mm);
38638 ++
38639 + /* Clear old maps */
38640 + error = -ENOMEM;
38641 +-munmap_back:
38642 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
38643 + if (vma && vma->vm_start < addr + len) {
38644 + if (do_munmap(mm, addr, len))
38645 + return -ENOMEM;
38646 +- goto munmap_back;
38647 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
38648 ++ BUG_ON(vma && vma->vm_start < addr + len);
38649 + }
38650 +
38651 + /* Check against address space limit. */
38652 +@@ -1139,6 +1253,16 @@ munmap_back:
38653 + goto unacct_error;
38654 + }
38655 +
38656 ++#ifdef CONFIG_PAX_SEGMEXEC
38657 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
38658 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38659 ++ if (!vma_m) {
38660 ++ error = -ENOMEM;
38661 ++ goto free_vma;
38662 ++ }
38663 ++ }
38664 ++#endif
38665 ++
38666 + vma->vm_mm = mm;
38667 + vma->vm_start = addr;
38668 + vma->vm_end = addr + len;
38669 +@@ -1161,6 +1285,14 @@ munmap_back:
38670 + error = file->f_op->mmap(file, vma);
38671 + if (error)
38672 + goto unmap_and_free_vma;
38673 ++
38674 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38675 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
38676 ++ vma->vm_flags |= VM_PAGEEXEC;
38677 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
38678 ++ }
38679 ++#endif
38680 ++
38681 + } else if (vm_flags & VM_SHARED) {
38682 + error = shmem_zero_setup(vma);
38683 + if (error)
38684 +@@ -1191,6 +1323,12 @@ munmap_back:
38685 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
38686 + file = vma->vm_file;
38687 + vma_link(mm, vma, prev, rb_link, rb_parent);
38688 ++
38689 ++#ifdef CONFIG_PAX_SEGMEXEC
38690 ++ if (vma_m)
38691 ++ pax_mirror_vma(vma_m, vma);
38692 ++#endif
38693 ++
38694 + if (correct_wcount)
38695 + atomic_inc(&inode->i_writecount);
38696 + } else {
38697 +@@ -1201,10 +1339,18 @@ munmap_back:
38698 + }
38699 + mpol_free(vma_policy(vma));
38700 + kmem_cache_free(vm_area_cachep, vma);
38701 ++ vma = NULL;
38702 ++
38703 ++#ifdef CONFIG_PAX_SEGMEXEC
38704 ++ if (vma_m)
38705 ++ kmem_cache_free(vm_area_cachep, vma_m);
38706 ++#endif
38707 ++
38708 + }
38709 + out:
38710 + mm->total_vm += len >> PAGE_SHIFT;
38711 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
38712 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
38713 + if (vm_flags & VM_LOCKED) {
38714 + mm->locked_vm += len >> PAGE_SHIFT;
38715 + make_pages_present(addr, addr + len);
38716 +@@ -1223,6 +1369,12 @@ unmap_and_free_vma:
38717 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
38718 + charged = 0;
38719 + free_vma:
38720 ++
38721 ++#ifdef CONFIG_PAX_SEGMEXEC
38722 ++ if (vma_m)
38723 ++ kmem_cache_free(vm_area_cachep, vma_m);
38724 ++#endif
38725 ++
38726 + kmem_cache_free(vm_area_cachep, vma);
38727 + unacct_error:
38728 + if (charged)
38729 +@@ -1256,6 +1408,10 @@ arch_get_unmapped_area(struct file *filp
38730 + if (flags & MAP_FIXED)
38731 + return addr;
38732 +
38733 ++#ifdef CONFIG_PAX_RANDMMAP
38734 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
38735 ++#endif
38736 ++
38737 + if (addr) {
38738 + addr = PAGE_ALIGN(addr);
38739 + vma = find_vma(mm, addr);
38740 +@@ -1264,10 +1420,10 @@ arch_get_unmapped_area(struct file *filp
38741 + return addr;
38742 + }
38743 + if (len > mm->cached_hole_size) {
38744 +- start_addr = addr = mm->free_area_cache;
38745 ++ start_addr = addr = mm->free_area_cache;
38746 + } else {
38747 +- start_addr = addr = TASK_UNMAPPED_BASE;
38748 +- mm->cached_hole_size = 0;
38749 ++ start_addr = addr = mm->mmap_base;
38750 ++ mm->cached_hole_size = 0;
38751 + }
38752 +
38753 + full_search:
38754 +@@ -1278,9 +1434,8 @@ full_search:
38755 + * Start a new search - just in case we missed
38756 + * some holes.
38757 + */
38758 +- if (start_addr != TASK_UNMAPPED_BASE) {
38759 +- addr = TASK_UNMAPPED_BASE;
38760 +- start_addr = addr;
38761 ++ if (start_addr != mm->mmap_base) {
38762 ++ start_addr = addr = mm->mmap_base;
38763 + mm->cached_hole_size = 0;
38764 + goto full_search;
38765 + }
38766 +@@ -1302,10 +1457,16 @@ full_search:
38767 +
38768 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
38769 + {
38770 ++
38771 ++#ifdef CONFIG_PAX_SEGMEXEC
38772 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
38773 ++ return;
38774 ++#endif
38775 ++
38776 + /*
38777 + * Is this a new hole at the lowest possible address?
38778 + */
38779 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
38780 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
38781 + mm->free_area_cache = addr;
38782 + mm->cached_hole_size = ~0UL;
38783 + }
38784 +@@ -1323,7 +1484,7 @@ arch_get_unmapped_area_topdown(struct fi
38785 + {
38786 + struct vm_area_struct *vma;
38787 + struct mm_struct *mm = current->mm;
38788 +- unsigned long addr = addr0;
38789 ++ unsigned long base = mm->mmap_base, addr = addr0;
38790 +
38791 + /* requested length too big for entire address space */
38792 + if (len > TASK_SIZE)
38793 +@@ -1332,6 +1493,10 @@ arch_get_unmapped_area_topdown(struct fi
38794 + if (flags & MAP_FIXED)
38795 + return addr;
38796 +
38797 ++#ifdef CONFIG_PAX_RANDMMAP
38798 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
38799 ++#endif
38800 ++
38801 + /* requesting a specific address */
38802 + if (addr) {
38803 + addr = PAGE_ALIGN(addr);
38804 +@@ -1389,13 +1554,21 @@ bottomup:
38805 + * can happen with large stack limits and large mmap()
38806 + * allocations.
38807 + */
38808 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
38809 ++
38810 ++#ifdef CONFIG_PAX_RANDMMAP
38811 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
38812 ++ mm->mmap_base += mm->delta_mmap;
38813 ++#endif
38814 ++
38815 ++ mm->free_area_cache = mm->mmap_base;
38816 + mm->cached_hole_size = ~0UL;
38817 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
38818 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
38819 + /*
38820 + * Restore the topdown base:
38821 + */
38822 +- mm->free_area_cache = mm->mmap_base;
38823 ++ mm->mmap_base = base;
38824 ++ mm->free_area_cache = base;
38825 + mm->cached_hole_size = ~0UL;
38826 +
38827 + return addr;
38828 +@@ -1404,6 +1577,12 @@ bottomup:
38829 +
38830 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
38831 + {
38832 ++
38833 ++#ifdef CONFIG_PAX_SEGMEXEC
38834 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
38835 ++ return;
38836 ++#endif
38837 ++
38838 + /*
38839 + * Is this a new hole at the highest possible address?
38840 + */
38841 +@@ -1411,8 +1590,10 @@ void arch_unmap_area_topdown(struct mm_s
38842 + mm->free_area_cache = addr;
38843 +
38844 + /* dont allow allocations above current base */
38845 +- if (mm->free_area_cache > mm->mmap_base)
38846 ++ if (mm->free_area_cache > mm->mmap_base) {
38847 + mm->free_area_cache = mm->mmap_base;
38848 ++ mm->cached_hole_size = ~0UL;
38849 ++ }
38850 + }
38851 +
38852 + unsigned long
38853 +@@ -1512,6 +1693,33 @@ out:
38854 + return prev ? prev->vm_next : vma;
38855 + }
38856 +
38857 ++#ifdef CONFIG_PAX_SEGMEXEC
38858 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
38859 ++{
38860 ++ struct vm_area_struct *vma_m;
38861 ++
38862 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
38863 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
38864 ++ BUG_ON(vma->vm_mirror);
38865 ++ return NULL;
38866 ++ }
38867 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
38868 ++ vma_m = vma->vm_mirror;
38869 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
38870 ++ BUG_ON(vma->vm_file != vma_m->vm_file);
38871 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
38872 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
38873 ++
38874 ++#ifdef CONFIG_PAX_MPROTECT
38875 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
38876 ++#else
38877 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
38878 ++#endif
38879 ++
38880 ++ return vma_m;
38881 ++}
38882 ++#endif
38883 ++
38884 + /*
38885 + * Verify that the stack growth is acceptable and
38886 + * update accounting. This is shared with both the
38887 +@@ -1528,6 +1736,7 @@ static int acct_stack_growth(struct vm_a
38888 + return -ENOMEM;
38889 +
38890 + /* Stack limit test */
38891 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
38892 + if (size > rlim[RLIMIT_STACK].rlim_cur)
38893 + return -ENOMEM;
38894 +
38895 +@@ -1537,6 +1746,7 @@ static int acct_stack_growth(struct vm_a
38896 + unsigned long limit;
38897 + locked = mm->locked_vm + grow;
38898 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
38899 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
38900 + if (locked > limit && !capable(CAP_IPC_LOCK))
38901 + return -ENOMEM;
38902 + }
38903 +@@ -1551,7 +1761,7 @@ static int acct_stack_growth(struct vm_a
38904 + * Overcommit.. This must be the final test, as it will
38905 + * update security statistics.
38906 + */
38907 +- if (security_vm_enough_memory(grow))
38908 ++ if (security_vm_enough_memory_mm(mm, grow))
38909 + return -ENOMEM;
38910 +
38911 + /* Ok, everything looks good - let it rip */
38912 +@@ -1572,35 +1782,40 @@ static inline
38913 + #endif
38914 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
38915 + {
38916 +- int error;
38917 ++ int error, locknext;
38918 +
38919 + if (!(vma->vm_flags & VM_GROWSUP))
38920 + return -EFAULT;
38921 +
38922 ++ /* Also guard against wrapping around to address 0. */
38923 ++ if (address < PAGE_ALIGN(address+1))
38924 ++ address = PAGE_ALIGN(address+1);
38925 ++ else
38926 ++ return -ENOMEM;
38927 ++
38928 + /*
38929 + * We must make sure the anon_vma is allocated
38930 + * so that the anon_vma locking is not a noop.
38931 + */
38932 + if (unlikely(anon_vma_prepare(vma)))
38933 + return -ENOMEM;
38934 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
38935 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
38936 ++ return -ENOMEM;
38937 + anon_vma_lock(vma);
38938 ++ if (locknext)
38939 ++ anon_vma_lock(vma->vm_next);
38940 +
38941 + /*
38942 + * vma->vm_start/vm_end cannot change under us because the caller
38943 + * is required to hold the mmap_sem in read mode. We need the
38944 +- * anon_vma lock to serialize against concurrent expand_stacks.
38945 +- * Also guard against wrapping around to address 0.
38946 ++ * anon_vma locks to serialize against concurrent expand_stacks
38947 ++ * and expand_upwards.
38948 + */
38949 +- if (address < PAGE_ALIGN(address+4))
38950 +- address = PAGE_ALIGN(address+4);
38951 +- else {
38952 +- anon_vma_unlock(vma);
38953 +- return -ENOMEM;
38954 +- }
38955 + error = 0;
38956 +
38957 + /* Somebody else might have raced and expanded it already */
38958 +- if (address > vma->vm_end) {
38959 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
38960 + unsigned long size, grow;
38961 +
38962 + size = address - vma->vm_start;
38963 +@@ -1610,6 +1825,8 @@ int expand_upwards(struct vm_area_struct
38964 + if (!error)
38965 + vma->vm_end = address;
38966 + }
38967 ++ if (locknext)
38968 ++ anon_vma_unlock(vma->vm_next);
38969 + anon_vma_unlock(vma);
38970 + return error;
38971 + }
38972 +@@ -1621,7 +1838,8 @@ int expand_upwards(struct vm_area_struct
38973 + static inline int expand_downwards(struct vm_area_struct *vma,
38974 + unsigned long address)
38975 + {
38976 +- int error;
38977 ++ int error, lockprev = 0;
38978 ++ struct vm_area_struct *prev = NULL;
38979 +
38980 + /*
38981 + * We must make sure the anon_vma is allocated
38982 +@@ -1635,6 +1853,15 @@ static inline int expand_downwards(struc
38983 + if (error)
38984 + return error;
38985 +
38986 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
38987 ++ find_vma_prev(vma->vm_mm, address, &prev);
38988 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
38989 ++#endif
38990 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
38991 ++ return -ENOMEM;
38992 ++ if (lockprev)
38993 ++ anon_vma_lock(prev);
38994 ++
38995 + anon_vma_lock(vma);
38996 +
38997 + /*
38998 +@@ -1644,9 +1871,15 @@ static inline int expand_downwards(struc
38999 + */
39000 +
39001 + /* Somebody else might have raced and expanded it already */
39002 +- if (address < vma->vm_start) {
39003 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
39004 + unsigned long size, grow;
39005 +
39006 ++#ifdef CONFIG_PAX_SEGMEXEC
39007 ++ struct vm_area_struct *vma_m;
39008 ++
39009 ++ vma_m = pax_find_mirror_vma(vma);
39010 ++#endif
39011 ++
39012 + size = vma->vm_end - address;
39013 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
39014 +
39015 +@@ -1654,9 +1887,20 @@ static inline int expand_downwards(struc
39016 + if (!error) {
39017 + vma->vm_start = address;
39018 + vma->vm_pgoff -= grow;
39019 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
39020 ++
39021 ++#ifdef CONFIG_PAX_SEGMEXEC
39022 ++ if (vma_m) {
39023 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
39024 ++ vma_m->vm_pgoff -= grow;
39025 ++ }
39026 ++#endif
39027 ++
39028 + }
39029 + }
39030 + anon_vma_unlock(vma);
39031 ++ if (lockprev)
39032 ++ anon_vma_unlock(prev);
39033 + return error;
39034 + }
39035 +
39036 +@@ -1728,6 +1972,13 @@ static void remove_vma_list(struct mm_st
39037 + do {
39038 + long nrpages = vma_pages(vma);
39039 +
39040 ++#ifdef CONFIG_PAX_SEGMEXEC
39041 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
39042 ++ vma = remove_vma(vma);
39043 ++ continue;
39044 ++ }
39045 ++#endif
39046 ++
39047 + mm->total_vm -= nrpages;
39048 + if (vma->vm_flags & VM_LOCKED)
39049 + mm->locked_vm -= nrpages;
39050 +@@ -1774,6 +2025,16 @@ detach_vmas_to_be_unmapped(struct mm_str
39051 +
39052 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
39053 + do {
39054 ++
39055 ++#ifdef CONFIG_PAX_SEGMEXEC
39056 ++ if (vma->vm_mirror) {
39057 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
39058 ++ vma->vm_mirror->vm_mirror = NULL;
39059 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
39060 ++ vma->vm_mirror = NULL;
39061 ++ }
39062 ++#endif
39063 ++
39064 + rb_erase(&vma->vm_rb, &mm->mm_rb);
39065 + mm->map_count--;
39066 + tail_vma = vma;
39067 +@@ -1793,6 +2054,102 @@ detach_vmas_to_be_unmapped(struct mm_str
39068 + * Split a vma into two pieces at address 'addr', a new vma is allocated
39069 + * either for the first part or the tail.
39070 + */
39071 ++
39072 ++#ifdef CONFIG_PAX_SEGMEXEC
39073 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
39074 ++ unsigned long addr, int new_below)
39075 ++{
39076 ++ struct mempolicy *pol;
39077 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
39078 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
39079 ++
39080 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
39081 ++ return -EINVAL;
39082 ++
39083 ++ vma_m = pax_find_mirror_vma(vma);
39084 ++ if (vma_m) {
39085 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
39086 ++ if (mm->map_count >= sysctl_max_map_count-1)
39087 ++ return -ENOMEM;
39088 ++ } else if (mm->map_count >= sysctl_max_map_count)
39089 ++ return -ENOMEM;
39090 ++
39091 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
39092 ++ if (!new)
39093 ++ return -ENOMEM;
39094 ++
39095 ++ if (vma_m) {
39096 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
39097 ++ if (!new_m) {
39098 ++ kmem_cache_free(vm_area_cachep, new);
39099 ++ return -ENOMEM;
39100 ++ }
39101 ++ }
39102 ++
39103 ++ /* most fields are the same, copy all, and then fixup */
39104 ++ *new = *vma;
39105 ++
39106 ++ if (new_below)
39107 ++ new->vm_end = addr;
39108 ++ else {
39109 ++ new->vm_start = addr;
39110 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
39111 ++ }
39112 ++
39113 ++ if (vma_m) {
39114 ++ *new_m = *vma_m;
39115 ++ new_m->vm_mirror = new;
39116 ++ new->vm_mirror = new_m;
39117 ++
39118 ++ if (new_below)
39119 ++ new_m->vm_end = addr_m;
39120 ++ else {
39121 ++ new_m->vm_start = addr_m;
39122 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
39123 ++ }
39124 ++ }
39125 ++
39126 ++ pol = mpol_copy(vma_policy(vma));
39127 ++ if (IS_ERR(pol)) {
39128 ++ if (new_m)
39129 ++ kmem_cache_free(vm_area_cachep, new_m);
39130 ++ kmem_cache_free(vm_area_cachep, new);
39131 ++ return PTR_ERR(pol);
39132 ++ }
39133 ++ vma_set_policy(new, pol);
39134 ++
39135 ++ if (new->vm_file)
39136 ++ get_file(new->vm_file);
39137 ++
39138 ++ if (new->vm_ops && new->vm_ops->open)
39139 ++ new->vm_ops->open(new);
39140 ++
39141 ++ if (new_below)
39142 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
39143 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
39144 ++ else
39145 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
39146 ++
39147 ++ if (vma_m) {
39148 ++ mpol_get(pol);
39149 ++ vma_set_policy(new_m, pol);
39150 ++
39151 ++ if (new_m->vm_file)
39152 ++ get_file(new_m->vm_file);
39153 ++
39154 ++ if (new_m->vm_ops && new_m->vm_ops->open)
39155 ++ new_m->vm_ops->open(new_m);
39156 ++
39157 ++ if (new_below)
39158 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
39159 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
39160 ++ else
39161 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
39162 ++ }
39163 ++
39164 ++ return 0;
39165 ++}
39166 ++#else
39167 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
39168 + unsigned long addr, int new_below)
39169 + {
39170 +@@ -1840,17 +2197,37 @@ int split_vma(struct mm_struct * mm, str
39171 +
39172 + return 0;
39173 + }
39174 ++#endif
39175 +
39176 + /* Munmap is split into 2 main parts -- this part which finds
39177 + * what needs doing, and the areas themselves, which do the
39178 + * work. This now handles partial unmappings.
39179 + * Jeremy Fitzhardinge <jeremy@××××.org>
39180 + */
39181 ++#ifdef CONFIG_PAX_SEGMEXEC
39182 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39183 + {
39184 ++ int ret = __do_munmap(mm, start, len);
39185 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
39186 ++ return ret;
39187 ++
39188 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
39189 ++}
39190 ++
39191 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39192 ++#else
39193 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39194 ++#endif
39195 ++{
39196 + unsigned long end;
39197 + struct vm_area_struct *vma, *prev, *last;
39198 +
39199 ++ /*
39200 ++ * mm->mmap_sem is required to protect against another thread
39201 ++ * changing the mappings in case we sleep.
39202 ++ */
39203 ++ verify_mm_writelocked(mm);
39204 ++
39205 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
39206 + return -EINVAL;
39207 +
39208 +@@ -1900,6 +2277,8 @@ int do_munmap(struct mm_struct *mm, unsi
39209 + /* Fix up all other VM information */
39210 + remove_vma_list(mm, vma);
39211 +
39212 ++ track_exec_limit(mm, start, end, 0UL);
39213 ++
39214 + return 0;
39215 + }
39216 +
39217 +@@ -1912,22 +2291,18 @@ asmlinkage long sys_munmap(unsigned long
39218 +
39219 + profile_munmap(addr);
39220 +
39221 ++#ifdef CONFIG_PAX_SEGMEXEC
39222 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
39223 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
39224 ++ return -EINVAL;
39225 ++#endif
39226 ++
39227 + down_write(&mm->mmap_sem);
39228 + ret = do_munmap(mm, addr, len);
39229 + up_write(&mm->mmap_sem);
39230 + return ret;
39231 + }
39232 +
39233 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
39234 +-{
39235 +-#ifdef CONFIG_DEBUG_VM
39236 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
39237 +- WARN_ON(1);
39238 +- up_read(&mm->mmap_sem);
39239 +- }
39240 +-#endif
39241 +-}
39242 +-
39243 + /*
39244 + * this is really a simplified "do_mmap". it only handles
39245 + * anonymous maps. eventually we may be able to do some
39246 +@@ -1941,6 +2316,11 @@ unsigned long do_brk(unsigned long addr,
39247 + struct rb_node ** rb_link, * rb_parent;
39248 + pgoff_t pgoff = addr >> PAGE_SHIFT;
39249 + int error;
39250 ++ unsigned long charged;
39251 ++
39252 ++#ifdef CONFIG_PAX_SEGMEXEC
39253 ++ struct vm_area_struct *vma_m = NULL;
39254 ++#endif
39255 +
39256 + len = PAGE_ALIGN(len);
39257 + if (!len)
39258 +@@ -1958,19 +2338,34 @@ unsigned long do_brk(unsigned long addr,
39259 +
39260 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
39261 +
39262 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
39263 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
39264 ++ flags &= ~VM_EXEC;
39265 ++
39266 ++#ifdef CONFIG_PAX_MPROTECT
39267 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
39268 ++ flags &= ~VM_MAYEXEC;
39269 ++#endif
39270 ++
39271 ++ }
39272 ++#endif
39273 ++
39274 + error = arch_mmap_check(addr, len, flags);
39275 + if (error)
39276 + return error;
39277 +
39278 ++ charged = len >> PAGE_SHIFT;
39279 ++
39280 + /*
39281 + * mlock MCL_FUTURE?
39282 + */
39283 + if (mm->def_flags & VM_LOCKED) {
39284 + unsigned long locked, lock_limit;
39285 +- locked = len >> PAGE_SHIFT;
39286 ++ locked = charged;
39287 + locked += mm->locked_vm;
39288 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
39289 + lock_limit >>= PAGE_SHIFT;
39290 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
39291 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
39292 + return -EAGAIN;
39293 + }
39294 +@@ -1984,22 +2379,22 @@ unsigned long do_brk(unsigned long addr,
39295 + /*
39296 + * Clear old maps. this also does some error checking for us
39297 + */
39298 +- munmap_back:
39299 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
39300 + if (vma && vma->vm_start < addr + len) {
39301 + if (do_munmap(mm, addr, len))
39302 + return -ENOMEM;
39303 +- goto munmap_back;
39304 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
39305 ++ BUG_ON(vma && vma->vm_start < addr + len);
39306 + }
39307 +
39308 + /* Check against address space limits *after* clearing old maps... */
39309 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
39310 ++ if (!may_expand_vm(mm, charged))
39311 + return -ENOMEM;
39312 +
39313 + if (mm->map_count > sysctl_max_map_count)
39314 + return -ENOMEM;
39315 +
39316 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
39317 ++ if (security_vm_enough_memory(charged))
39318 + return -ENOMEM;
39319 +
39320 + /* Can we just expand an old private anonymous mapping? */
39321 +@@ -2012,10 +2407,21 @@ unsigned long do_brk(unsigned long addr,
39322 + */
39323 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39324 + if (!vma) {
39325 +- vm_unacct_memory(len >> PAGE_SHIFT);
39326 ++ vm_unacct_memory(charged);
39327 + return -ENOMEM;
39328 + }
39329 +
39330 ++#ifdef CONFIG_PAX_SEGMEXEC
39331 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
39332 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39333 ++ if (!vma_m) {
39334 ++ kmem_cache_free(vm_area_cachep, vma);
39335 ++ vm_unacct_memory(charged);
39336 ++ return -ENOMEM;
39337 ++ }
39338 ++ }
39339 ++#endif
39340 ++
39341 + vma->vm_mm = mm;
39342 + vma->vm_start = addr;
39343 + vma->vm_end = addr + len;
39344 +@@ -2023,12 +2429,19 @@ unsigned long do_brk(unsigned long addr,
39345 + vma->vm_flags = flags;
39346 + vma->vm_page_prot = vm_get_page_prot(flags);
39347 + vma_link(mm, vma, prev, rb_link, rb_parent);
39348 ++
39349 ++#ifdef CONFIG_PAX_SEGMEXEC
39350 ++ if (vma_m)
39351 ++ pax_mirror_vma(vma_m, vma);
39352 ++#endif
39353 ++
39354 + out:
39355 +- mm->total_vm += len >> PAGE_SHIFT;
39356 ++ mm->total_vm += charged;
39357 + if (flags & VM_LOCKED) {
39358 +- mm->locked_vm += len >> PAGE_SHIFT;
39359 ++ mm->locked_vm += charged;
39360 + make_pages_present(addr, addr + len);
39361 + }
39362 ++ track_exec_limit(mm, addr, addr + len, flags);
39363 + return addr;
39364 + }
39365 +
39366 +@@ -2059,8 +2472,10 @@ void exit_mmap(struct mm_struct *mm)
39367 + * Walk the list again, actually closing and freeing it,
39368 + * with preemption enabled, without holding any MM locks.
39369 + */
39370 +- while (vma)
39371 ++ while (vma) {
39372 ++ vma->vm_mirror = NULL;
39373 + vma = remove_vma(vma);
39374 ++ }
39375 +
39376 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
39377 + }
39378 +@@ -2074,6 +2489,10 @@ int insert_vm_struct(struct mm_struct *
39379 + struct vm_area_struct * __vma, * prev;
39380 + struct rb_node ** rb_link, * rb_parent;
39381 +
39382 ++#ifdef CONFIG_PAX_SEGMEXEC
39383 ++ struct vm_area_struct *vma_m = NULL;
39384 ++#endif
39385 ++
39386 + /*
39387 + * The vm_pgoff of a purely anonymous vma should be irrelevant
39388 + * until its first write fault, when page's anon_vma and index
39389 +@@ -2096,7 +2515,22 @@ int insert_vm_struct(struct mm_struct *
39390 + if ((vma->vm_flags & VM_ACCOUNT) &&
39391 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
39392 + return -ENOMEM;
39393 ++
39394 ++#ifdef CONFIG_PAX_SEGMEXEC
39395 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
39396 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39397 ++ if (!vma_m)
39398 ++ return -ENOMEM;
39399 ++ }
39400 ++#endif
39401 ++
39402 + vma_link(mm, vma, prev, rb_link, rb_parent);
39403 ++
39404 ++#ifdef CONFIG_PAX_SEGMEXEC
39405 ++ if (vma_m)
39406 ++ pax_mirror_vma(vma_m, vma);
39407 ++#endif
39408 ++
39409 + return 0;
39410 + }
39411 +
39412 +@@ -2114,6 +2548,8 @@ struct vm_area_struct *copy_vma(struct v
39413 + struct rb_node **rb_link, *rb_parent;
39414 + struct mempolicy *pol;
39415 +
39416 ++ BUG_ON(vma->vm_mirror);
39417 ++
39418 + /*
39419 + * If anonymous vma has not yet been faulted, update new pgoff
39420 + * to match new location, to increase its chance of merging.
39421 +@@ -2154,6 +2590,35 @@ struct vm_area_struct *copy_vma(struct v
39422 + return new_vma;
39423 + }
39424 +
39425 ++#ifdef CONFIG_PAX_SEGMEXEC
39426 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
39427 ++{
39428 ++ struct vm_area_struct *prev_m;
39429 ++ struct rb_node **rb_link_m, *rb_parent_m;
39430 ++ struct mempolicy *pol_m;
39431 ++
39432 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
39433 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
39434 ++ BUG_ON(!vma_mpol_equal(vma, vma_m));
39435 ++ *vma_m = *vma;
39436 ++ pol_m = vma_policy(vma);
39437 ++ mpol_get(pol_m);
39438 ++ vma_set_policy(vma_m, pol_m);
39439 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
39440 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
39441 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
39442 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
39443 ++ if (vma_m->vm_file)
39444 ++ get_file(vma_m->vm_file);
39445 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
39446 ++ vma_m->vm_ops->open(vma_m);
39447 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
39448 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
39449 ++ vma_m->vm_mirror = vma;
39450 ++ vma->vm_mirror = vma_m;
39451 ++}
39452 ++#endif
39453 ++
39454 + /*
39455 + * Return true if the calling process may expand its vm space by the passed
39456 + * number of pages
39457 +@@ -2164,7 +2629,7 @@ int may_expand_vm(struct mm_struct *mm,
39458 + unsigned long lim;
39459 +
39460 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
39461 +-
39462 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
39463 + if (cur + npages > lim)
39464 + return 0;
39465 + return 1;
39466 +@@ -2233,6 +2698,15 @@ int install_special_mapping(struct mm_st
39467 + vma->vm_start = addr;
39468 + vma->vm_end = addr + len;
39469 +
39470 ++#ifdef CONFIG_PAX_MPROTECT
39471 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
39472 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
39473 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
39474 ++ else
39475 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
39476 ++ }
39477 ++#endif
39478 ++
39479 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
39480 + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
39481 +
39482 +diff -urNp a/mm/mprotect.c b/mm/mprotect.c
39483 +--- a/mm/mprotect.c 2008-08-20 11:16:13.000000000 -0700
39484 ++++ b/mm/mprotect.c 2008-08-20 18:36:57.000000000 -0700
39485 +@@ -21,10 +21,17 @@
39486 + #include <linux/syscalls.h>
39487 + #include <linux/swap.h>
39488 + #include <linux/swapops.h>
39489 ++#include <linux/grsecurity.h>
39490 ++
39491 ++#ifdef CONFIG_PAX_MPROTECT
39492 ++#include <linux/elf.h>
39493 ++#endif
39494 ++
39495 + #include <asm/uaccess.h>
39496 + #include <asm/pgtable.h>
39497 + #include <asm/cacheflush.h>
39498 + #include <asm/tlbflush.h>
39499 ++#include <asm/mmu_context.h>
39500 +
39501 + static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
39502 + unsigned long addr, unsigned long end, pgprot_t newprot,
39503 +@@ -127,6 +134,48 @@ static void change_protection(struct vm_
39504 + flush_tlb_range(vma, start, end);
39505 + }
39506 +
39507 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
39508 ++/* called while holding the mmap semaphor for writing except stack expansion */
39509 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
39510 ++{
39511 ++ unsigned long oldlimit, newlimit = 0UL;
39512 ++
39513 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
39514 ++ return;
39515 ++
39516 ++ spin_lock(&mm->page_table_lock);
39517 ++ oldlimit = mm->context.user_cs_limit;
39518 ++ if ((prot & VM_EXEC) && oldlimit < end)
39519 ++ /* USER_CS limit moved up */
39520 ++ newlimit = end;
39521 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
39522 ++ /* USER_CS limit moved down */
39523 ++ newlimit = start;
39524 ++
39525 ++ if (newlimit) {
39526 ++ mm->context.user_cs_limit = newlimit;
39527 ++
39528 ++#ifdef CONFIG_SMP
39529 ++ wmb();
39530 ++ cpus_clear(mm->context.cpu_user_cs_mask);
39531 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
39532 ++#endif
39533 ++
39534 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
39535 ++ }
39536 ++ spin_unlock(&mm->page_table_lock);
39537 ++ if (newlimit == end) {
39538 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
39539 ++
39540 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
39541 ++ if (is_vm_hugetlb_page(vma))
39542 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
39543 ++ else
39544 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
39545 ++ }
39546 ++}
39547 ++#endif
39548 ++
39549 + int
39550 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
39551 + unsigned long start, unsigned long end, unsigned long newflags)
39552 +@@ -139,6 +188,14 @@ mprotect_fixup(struct vm_area_struct *vm
39553 + int error;
39554 + int dirty_accountable = 0;
39555 +
39556 ++#ifdef CONFIG_PAX_SEGMEXEC
39557 ++ struct vm_area_struct *vma_m = NULL;
39558 ++ unsigned long start_m, end_m;
39559 ++
39560 ++ start_m = start + SEGMEXEC_TASK_SIZE;
39561 ++ end_m = end + SEGMEXEC_TASK_SIZE;
39562 ++#endif
39563 ++
39564 + if (newflags == oldflags) {
39565 + *pprev = vma;
39566 + return 0;
39567 +@@ -161,6 +218,38 @@ mprotect_fixup(struct vm_area_struct *vm
39568 + }
39569 + }
39570 +
39571 ++#ifdef CONFIG_PAX_SEGMEXEC
39572 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
39573 ++ if (start != vma->vm_start) {
39574 ++ error = split_vma(mm, vma, start, 1);
39575 ++ if (error)
39576 ++ goto fail;
39577 ++ BUG_ON(!*pprev || (*pprev)->vm_next == vma);
39578 ++ *pprev = (*pprev)->vm_next;
39579 ++ }
39580 ++
39581 ++ if (end != vma->vm_end) {
39582 ++ error = split_vma(mm, vma, end, 0);
39583 ++ if (error)
39584 ++ goto fail;
39585 ++ }
39586 ++
39587 ++ if (pax_find_mirror_vma(vma)) {
39588 ++ error = __do_munmap(mm, start_m, end_m - start_m);
39589 ++ if (error)
39590 ++ goto fail;
39591 ++ } else {
39592 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39593 ++ if (!vma_m) {
39594 ++ error = -ENOMEM;
39595 ++ goto fail;
39596 ++ }
39597 ++ vma->vm_flags = newflags;
39598 ++ pax_mirror_vma(vma_m, vma);
39599 ++ }
39600 ++ }
39601 ++#endif
39602 ++
39603 + /*
39604 + * First try to merge with previous and/or next vma.
39605 + */
39606 +@@ -211,6 +300,70 @@ fail:
39607 + return error;
39608 + }
39609 +
39610 ++#ifdef CONFIG_PAX_MPROTECT
39611 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
39612 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
39613 ++ *
39614 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
39615 ++ * basis because we want to allow the common case and not the special ones.
39616 ++ */
39617 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
39618 ++{
39619 ++ struct elfhdr elf_h;
39620 ++ struct elf_phdr elf_p;
39621 ++ elf_addr_t dyn_offset = 0UL;
39622 ++ elf_dyn dyn;
39623 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
39624 ++
39625 ++#ifndef CONFIG_PAX_NOELFRELOCS
39626 ++ if ((vma->vm_start != start) ||
39627 ++ !vma->vm_file ||
39628 ++ !(vma->vm_flags & VM_MAYEXEC) ||
39629 ++ (vma->vm_flags & VM_MAYNOTWRITE))
39630 ++#endif
39631 ++
39632 ++ return;
39633 ++
39634 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
39635 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
39636 ++
39637 ++#ifdef CONFIG_PAX_ETEXECRELOCS
39638 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
39639 ++#else
39640 ++ elf_h.e_type != ET_DYN ||
39641 ++#endif
39642 ++
39643 ++ !elf_check_arch(&elf_h) ||
39644 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
39645 ++ elf_h.e_phnum > j)
39646 ++ return;
39647 ++
39648 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
39649 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
39650 ++ return;
39651 ++ if (elf_p.p_type == PT_DYNAMIC) {
39652 ++ dyn_offset = elf_p.p_offset;
39653 ++ j = i;
39654 ++ }
39655 ++ }
39656 ++ if (elf_h.e_phnum <= j)
39657 ++ return;
39658 ++
39659 ++ i = 0UL;
39660 ++ do {
39661 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
39662 ++ return;
39663 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
39664 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
39665 ++ gr_log_textrel(vma);
39666 ++ return;
39667 ++ }
39668 ++ i++;
39669 ++ } while (dyn.d_tag != DT_NULL);
39670 ++ return;
39671 ++}
39672 ++#endif
39673 ++
39674 + asmlinkage long
39675 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39676 + {
39677 +@@ -230,6 +383,17 @@ sys_mprotect(unsigned long start, size_t
39678 + end = start + len;
39679 + if (end <= start)
39680 + return -ENOMEM;
39681 ++
39682 ++#ifdef CONFIG_PAX_SEGMEXEC
39683 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
39684 ++ if (end > SEGMEXEC_TASK_SIZE)
39685 ++ return -EINVAL;
39686 ++ } else
39687 ++#endif
39688 ++
39689 ++ if (end > TASK_SIZE)
39690 ++ return -EINVAL;
39691 ++
39692 + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
39693 + return -EINVAL;
39694 +
39695 +@@ -237,7 +401,7 @@ sys_mprotect(unsigned long start, size_t
39696 + /*
39697 + * Does the application expect PROT_READ to imply PROT_EXEC:
39698 + */
39699 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
39700 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
39701 + prot |= PROT_EXEC;
39702 +
39703 + vm_flags = calc_vm_prot_bits(prot);
39704 +@@ -269,6 +433,16 @@ sys_mprotect(unsigned long start, size_t
39705 + if (start > vma->vm_start)
39706 + prev = vma;
39707 +
39708 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
39709 ++ error = -EACCES;
39710 ++ goto out;
39711 ++ }
39712 ++
39713 ++#ifdef CONFIG_PAX_MPROTECT
39714 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
39715 ++ pax_handle_maywrite(vma, start);
39716 ++#endif
39717 ++
39718 + for (nstart = start ; ; ) {
39719 + unsigned long newflags;
39720 +
39721 +@@ -282,6 +456,12 @@ sys_mprotect(unsigned long start, size_t
39722 + goto out;
39723 + }
39724 +
39725 ++#ifdef CONFIG_PAX_MPROTECT
39726 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
39727 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
39728 ++ newflags &= ~VM_MAYWRITE;
39729 ++#endif
39730 ++
39731 + error = security_file_mprotect(vma, reqprot, prot);
39732 + if (error)
39733 + goto out;
39734 +@@ -292,6 +472,9 @@ sys_mprotect(unsigned long start, size_t
39735 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
39736 + if (error)
39737 + goto out;
39738 ++
39739 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
39740 ++
39741 + nstart = tmp;
39742 +
39743 + if (nstart < prev->vm_end)
39744 +diff -urNp a/mm/mremap.c b/mm/mremap.c
39745 +--- a/mm/mremap.c 2008-08-20 11:16:13.000000000 -0700
39746 ++++ b/mm/mremap.c 2008-08-20 18:36:57.000000000 -0700
39747 +@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
39748 + continue;
39749 + pte = ptep_clear_flush(vma, old_addr, old_pte);
39750 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
39751 ++
39752 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
39753 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
39754 ++ pte = pte_exprotect(pte);
39755 ++#endif
39756 ++
39757 + set_pte_at(mm, new_addr, new_pte, pte);
39758 + }
39759 +
39760 +@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
39761 + struct vm_area_struct *vma;
39762 + unsigned long ret = -EINVAL;
39763 + unsigned long charged = 0;
39764 ++ unsigned long pax_task_size = TASK_SIZE;
39765 +
39766 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
39767 + goto out;
39768 +@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
39769 + if (!new_len)
39770 + goto out;
39771 +
39772 ++#ifdef CONFIG_PAX_SEGMEXEC
39773 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
39774 ++ pax_task_size = SEGMEXEC_TASK_SIZE;
39775 ++#endif
39776 ++
39777 ++ if (new_len > pax_task_size || addr > pax_task_size-new_len ||
39778 ++ old_len > pax_task_size || addr > pax_task_size-old_len)
39779 ++ goto out;
39780 ++
39781 + /* new_addr is only valid if MREMAP_FIXED is specified */
39782 + if (flags & MREMAP_FIXED) {
39783 + if (new_addr & ~PAGE_MASK)
39784 +@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
39785 + if (!(flags & MREMAP_MAYMOVE))
39786 + goto out;
39787 +
39788 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
39789 ++ if (new_addr > pax_task_size - new_len)
39790 + goto out;
39791 +
39792 + /* Check if the location we're moving into overlaps the
39793 + * old location at all, and fail if it does.
39794 + */
39795 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
39796 +- goto out;
39797 +-
39798 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
39799 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
39800 + goto out;
39801 +
39802 + ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
39803 +@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
39804 + ret = -EINVAL;
39805 + goto out;
39806 + }
39807 ++
39808 ++#ifdef CONFIG_PAX_SEGMEXEC
39809 ++ if (pax_find_mirror_vma(vma)) {
39810 ++ ret = -EINVAL;
39811 ++ goto out;
39812 ++ }
39813 ++#endif
39814 ++
39815 + /* We can't remap across vm area boundaries */
39816 + if (old_len > vma->vm_end - addr)
39817 + goto out;
39818 +@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
39819 + if (old_len == vma->vm_end - addr &&
39820 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
39821 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
39822 +- unsigned long max_addr = TASK_SIZE;
39823 ++ unsigned long max_addr = pax_task_size;
39824 + if (vma->vm_next)
39825 + max_addr = vma->vm_next->vm_start;
39826 + /* can we just expand the current mapping? */
39827 +@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
39828 + addr + new_len);
39829 + }
39830 + ret = addr;
39831 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
39832 + goto out;
39833 + }
39834 + }
39835 +@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
39836 + */
39837 + ret = -ENOMEM;
39838 + if (flags & MREMAP_MAYMOVE) {
39839 ++ unsigned long map_flags = 0;
39840 + if (!(flags & MREMAP_FIXED)) {
39841 +- unsigned long map_flags = 0;
39842 + if (vma->vm_flags & VM_MAYSHARE)
39843 + map_flags |= MAP_SHARED;
39844 +
39845 +@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
39846 + if (ret)
39847 + goto out;
39848 + }
39849 ++ map_flags = vma->vm_flags;
39850 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
39851 ++ if (!(ret & ~PAGE_MASK)) {
39852 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
39853 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
39854 ++ }
39855 + }
39856 + out:
39857 + if (ret & ~PAGE_MASK)
39858 +diff -urNp a/mm/nommu.c b/mm/nommu.c
39859 +--- a/mm/nommu.c 2008-08-20 11:16:13.000000000 -0700
39860 ++++ b/mm/nommu.c 2008-08-20 18:36:57.000000000 -0700
39861 +@@ -405,15 +405,6 @@ struct vm_area_struct *find_vma(struct m
39862 + }
39863 + EXPORT_SYMBOL(find_vma);
39864 +
39865 +-/*
39866 +- * find a VMA
39867 +- * - we don't extend stack VMAs under NOMMU conditions
39868 +- */
39869 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
39870 +-{
39871 +- return find_vma(mm, addr);
39872 +-}
39873 +-
39874 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
39875 + {
39876 + return -ENOMEM;
39877 +diff -urNp a/mm/page_alloc.c b/mm/page_alloc.c
39878 +--- a/mm/page_alloc.c 2008-08-20 11:16:13.000000000 -0700
39879 ++++ b/mm/page_alloc.c 2008-08-20 18:36:57.000000000 -0700
39880 +@@ -514,9 +514,20 @@ static void free_pages_bulk(struct zone
39881 +
39882 + static void free_one_page(struct zone *zone, struct page *page, int order)
39883 + {
39884 ++
39885 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39886 ++ unsigned long index = 1UL << order;
39887 ++#endif
39888 ++
39889 + spin_lock(&zone->lock);
39890 + zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
39891 + zone->pages_scanned = 0;
39892 ++
39893 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39894 ++ for (; index; --index)
39895 ++ sanitize_highpage(page + index - 1);
39896 ++#endif
39897 ++
39898 + __free_one_page(page, zone, order);
39899 + spin_unlock(&zone->lock);
39900 + }
39901 +@@ -641,8 +652,10 @@ static int prep_new_page(struct page *pa
39902 + arch_alloc_page(page, order);
39903 + kernel_map_pages(page, 1 << order, 1);
39904 +
39905 ++#ifndef CONFIG_PAX_MEMORY_SANITIZE
39906 + if (gfp_flags & __GFP_ZERO)
39907 + prep_zero_page(page, order, gfp_flags);
39908 ++#endif
39909 +
39910 + if (order && (gfp_flags & __GFP_COMP))
39911 + prep_compound_page(page, order);
39912 +@@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
39913 + list_add(&page->lru, &pcp->list);
39914 + set_page_private(page, get_pageblock_migratetype(page));
39915 + pcp->count++;
39916 ++
39917 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39918 ++ sanitize_highpage(page);
39919 ++#endif
39920 ++
39921 + if (pcp->count >= pcp->high) {
39922 + free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
39923 + pcp->count -= pcp->batch;
39924 +diff -urNp a/mm/rmap.c b/mm/rmap.c
39925 +--- a/mm/rmap.c 2008-08-20 11:16:13.000000000 -0700
39926 ++++ b/mm/rmap.c 2008-08-20 18:36:57.000000000 -0700
39927 +@@ -64,6 +64,10 @@ int anon_vma_prepare(struct vm_area_stru
39928 + struct mm_struct *mm = vma->vm_mm;
39929 + struct anon_vma *allocated, *locked;
39930 +
39931 ++#ifdef CONFIG_PAX_SEGMEXEC
39932 ++ struct vm_area_struct *vma_m;
39933 ++#endif
39934 ++
39935 + anon_vma = find_mergeable_anon_vma(vma);
39936 + if (anon_vma) {
39937 + allocated = NULL;
39938 +@@ -80,6 +84,15 @@ int anon_vma_prepare(struct vm_area_stru
39939 + /* page_table_lock to protect against threads */
39940 + spin_lock(&mm->page_table_lock);
39941 + if (likely(!vma->anon_vma)) {
39942 ++
39943 ++#ifdef CONFIG_PAX_SEGMEXEC
39944 ++ vma_m = pax_find_mirror_vma(vma);
39945 ++ if (vma_m) {
39946 ++ vma_m->anon_vma = anon_vma;
39947 ++ __anon_vma_link(vma_m);
39948 ++ }
39949 ++#endif
39950 ++
39951 + vma->anon_vma = anon_vma;
39952 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
39953 + allocated = NULL;
39954 +diff -urNp a/mm/shmem.c b/mm/shmem.c
39955 +--- a/mm/shmem.c 2008-08-20 11:16:13.000000000 -0700
39956 ++++ b/mm/shmem.c 2008-08-20 18:36:57.000000000 -0700
39957 +@@ -2518,7 +2518,7 @@ static struct file_system_type tmpfs_fs_
39958 + .get_sb = shmem_get_sb,
39959 + .kill_sb = kill_litter_super,
39960 + };
39961 +-static struct vfsmount *shm_mnt;
39962 ++struct vfsmount *shm_mnt;
39963 +
39964 + static int __init init_tmpfs(void)
39965 + {
39966 +diff -urNp a/mm/slab.c b/mm/slab.c
39967 +--- a/mm/slab.c 2008-08-20 11:16:13.000000000 -0700
39968 ++++ b/mm/slab.c 2008-08-20 18:36:57.000000000 -0700
39969 +@@ -305,7 +305,7 @@ struct kmem_list3 {
39970 + * Need this for bootstrapping a per node allocator.
39971 + */
39972 + #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
39973 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
39974 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
39975 + #define CACHE_CACHE 0
39976 + #define SIZE_AC MAX_NUMNODES
39977 + #define SIZE_L3 (2 * MAX_NUMNODES)
39978 +@@ -654,14 +654,14 @@ struct cache_names {
39979 + static struct cache_names __initdata cache_names[] = {
39980 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
39981 + #include <linux/kmalloc_sizes.h>
39982 +- {NULL,}
39983 ++ {NULL, NULL}
39984 + #undef CACHE
39985 + };
39986 +
39987 + static struct arraycache_init initarray_cache __initdata =
39988 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
39989 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
39990 + static struct arraycache_init initarray_generic =
39991 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
39992 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
39993 +
39994 + /* internal cache of cache description objs */
39995 + static struct kmem_cache cache_cache = {
39996 +@@ -3007,7 +3007,7 @@ retry:
39997 + * there must be at least one object available for
39998 + * allocation.
39999 + */
40000 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
40001 ++ BUG_ON(slabp->inuse >= cachep->num);
40002 +
40003 + while (slabp->inuse < cachep->num && batchcount--) {
40004 + STATS_INC_ALLOCED(cachep);
40005 +diff -urNp a/mm/swap.c b/mm/swap.c
40006 +--- a/mm/swap.c 2008-08-20 11:16:13.000000000 -0700
40007 ++++ b/mm/swap.c 2008-08-20 18:36:57.000000000 -0700
40008 +@@ -34,9 +34,9 @@
40009 + /* How many pages do we try to swap or page in/out together? */
40010 + int page_cluster;
40011 +
40012 +-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
40013 +-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
40014 +-static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
40015 ++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
40016 ++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
40017 ++static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
40018 +
40019 + /*
40020 + * This path almost never happens for VM activity - pages are normally
40021 +diff -urNp a/mm/tiny-shmem.c b/mm/tiny-shmem.c
40022 +--- a/mm/tiny-shmem.c 2008-08-20 11:16:13.000000000 -0700
40023 ++++ b/mm/tiny-shmem.c 2008-08-20 18:36:57.000000000 -0700
40024 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
40025 + .kill_sb = kill_litter_super,
40026 + };
40027 +
40028 +-static struct vfsmount *shm_mnt;
40029 ++struct vfsmount *shm_mnt;
40030 +
40031 + static int __init init_tmpfs(void)
40032 + {
40033 +diff -urNp a/mm/vmalloc.c b/mm/vmalloc.c
40034 +--- a/mm/vmalloc.c 2008-08-20 11:16:13.000000000 -0700
40035 ++++ b/mm/vmalloc.c 2008-08-20 18:36:57.000000000 -0700
40036 +@@ -246,20 +246,15 @@ static struct vm_struct *__get_vm_area_n
40037 + (unsigned long)tmp->addr, align);
40038 + continue;
40039 + }
40040 +- if ((size + addr) < addr)
40041 +- goto out;
40042 + if (size + addr <= (unsigned long)tmp->addr)
40043 +- goto found;
40044 ++ break;
40045 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
40046 +- if (addr > end - size)
40047 +- goto out;
40048 + }
40049 + if ((size + addr) < addr)
40050 + goto out;
40051 + if (addr > end - size)
40052 + goto out;
40053 +
40054 +-found:
40055 + area->next = *p;
40056 + *p = area;
40057 +
40058 +diff -urNp a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
40059 +--- a/net/bridge/br_stp_if.c 2008-08-20 11:16:13.000000000 -0700
40060 ++++ b/net/bridge/br_stp_if.c 2008-08-20 18:36:57.000000000 -0700
40061 +@@ -148,7 +148,7 @@ static void br_stp_stop(struct net_bridg
40062 + char *envp[] = { NULL };
40063 +
40064 + if (br->stp_enabled == BR_USER_STP) {
40065 +- r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
40066 ++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
40067 + printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
40068 + br->dev->name, r);
40069 +
40070 +diff -urNp a/net/core/flow.c b/net/core/flow.c
40071 +--- a/net/core/flow.c 2008-08-20 11:16:13.000000000 -0700
40072 ++++ b/net/core/flow.c 2008-08-20 18:36:57.000000000 -0700
40073 +@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
40074 +
40075 + static u32 flow_hash_shift;
40076 + #define flow_hash_size (1 << flow_hash_shift)
40077 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
40078 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
40079 +
40080 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
40081 +
40082 +@@ -53,7 +53,7 @@ struct flow_percpu_info {
40083 + u32 hash_rnd;
40084 + int count;
40085 + };
40086 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
40087 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
40088 +
40089 + #define flow_hash_rnd_recalc(cpu) \
40090 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
40091 +@@ -70,7 +70,7 @@ struct flow_flush_info {
40092 + atomic_t cpuleft;
40093 + struct completion completion;
40094 + };
40095 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
40096 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
40097 +
40098 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
40099 +
40100 +diff -urNp a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
40101 +--- a/net/dccp/ccids/ccid3.c 2008-08-20 11:16:13.000000000 -0700
40102 ++++ b/net/dccp/ccids/ccid3.c 2008-08-20 18:36:57.000000000 -0700
40103 +@@ -43,7 +43,7 @@
40104 + static int ccid3_debug;
40105 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
40106 + #else
40107 +-#define ccid3_pr_debug(format, a...)
40108 ++#define ccid3_pr_debug(format, a...) do {} while (0)
40109 + #endif
40110 +
40111 + /*
40112 +diff -urNp a/net/dccp/dccp.h b/net/dccp/dccp.h
40113 +--- a/net/dccp/dccp.h 2008-08-20 11:16:13.000000000 -0700
40114 ++++ b/net/dccp/dccp.h 2008-08-20 18:36:57.000000000 -0700
40115 +@@ -43,8 +43,8 @@ extern int dccp_debug;
40116 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
40117 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
40118 + #else
40119 +-#define dccp_pr_debug(format, a...)
40120 +-#define dccp_pr_debug_cat(format, a...)
40121 ++#define dccp_pr_debug(format, a...) do {} while (0)
40122 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
40123 + #endif
40124 +
40125 + extern struct inet_hashinfo dccp_hashinfo;
40126 +diff -urNp a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
40127 +--- a/net/ipv4/inet_connection_sock.c 2008-08-20 11:16:13.000000000 -0700
40128 ++++ b/net/ipv4/inet_connection_sock.c 2008-08-20 18:36:57.000000000 -0700
40129 +@@ -15,6 +15,7 @@
40130 +
40131 + #include <linux/module.h>
40132 + #include <linux/jhash.h>
40133 ++#include <linux/grsecurity.h>
40134 +
40135 + #include <net/inet_connection_sock.h>
40136 + #include <net/inet_hashtables.h>
40137 +diff -urNp a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
40138 +--- a/net/ipv4/inet_hashtables.c 2008-08-20 11:16:13.000000000 -0700
40139 ++++ b/net/ipv4/inet_hashtables.c 2008-08-20 18:36:57.000000000 -0700
40140 +@@ -18,11 +18,14 @@
40141 + #include <linux/sched.h>
40142 + #include <linux/slab.h>
40143 + #include <linux/wait.h>
40144 ++#include <linux/grsecurity.h>
40145 +
40146 + #include <net/inet_connection_sock.h>
40147 + #include <net/inet_hashtables.h>
40148 + #include <net/ip.h>
40149 +
40150 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
40151 ++
40152 + /*
40153 + * Allocate and initialize a new local port bind bucket.
40154 + * The bindhash mutex for snum's hash chain must be held here.
40155 +@@ -467,6 +470,8 @@ ok:
40156 + }
40157 + spin_unlock(&head->lock);
40158 +
40159 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
40160 ++
40161 + if (tw) {
40162 + inet_twsk_deschedule(tw, death_row);
40163 + inet_twsk_put(tw);
40164 +diff -urNp a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
40165 +--- a/net/ipv4/netfilter/Kconfig 2008-08-20 11:16:13.000000000 -0700
40166 ++++ b/net/ipv4/netfilter/Kconfig 2008-08-20 18:36:57.000000000 -0700
40167 +@@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
40168 + If you want to compile it as a module, say M here and read
40169 + <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
40170 +
40171 ++config IP_NF_MATCH_STEALTH
40172 ++ tristate "stealth match support"
40173 ++ depends on IP_NF_IPTABLES
40174 ++ help
40175 ++ Enabling this option will drop all syn packets coming to unserved tcp
40176 ++ ports as well as all packets coming to unserved udp ports. If you
40177 ++ are using your system to route any type of packets (ie. via NAT)
40178 ++ you should put this module at the end of your ruleset, since it will
40179 ++ drop packets that aren't going to ports that are listening on your
40180 ++ machine itself, it doesn't take into account that the packet might be
40181 ++ destined for someone on your internal network if you're using NAT for
40182 ++ instance.
40183 ++
40184 ++ To compile it as a module, choose M here. If unsure, say N.
40185 ++
40186 + # `filter', generic and specific targets
40187 + config IP_NF_FILTER
40188 + tristate "Packet filtering"
40189 +@@ -380,4 +395,3 @@ config IP_NF_ARP_MANGLE
40190 + hardware and network addresses.
40191 +
40192 + endmenu
40193 +-
40194 +diff -urNp a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
40195 +--- a/net/ipv4/netfilter/Makefile 2008-08-20 11:16:13.000000000 -0700
40196 ++++ b/net/ipv4/netfilter/Makefile 2008-08-20 18:36:57.000000000 -0700
40197 +@@ -55,6 +55,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
40198 + obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
40199 + obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
40200 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
40201 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
40202 + obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
40203 + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
40204 +
40205 +diff -urNp a/net/ipv4/netfilter/ipt_stealth.c b/net/ipv4/netfilter/ipt_stealth.c
40206 +--- a/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 16:00:00.000000000 -0800
40207 ++++ b/net/ipv4/netfilter/ipt_stealth.c 2008-08-20 18:36:57.000000000 -0700
40208 +@@ -0,0 +1,114 @@
40209 ++/* Kernel module to add stealth support.
40210 ++ *
40211 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
40212 ++ *
40213 ++ */
40214 ++
40215 ++#include <linux/kernel.h>
40216 ++#include <linux/module.h>
40217 ++#include <linux/skbuff.h>
40218 ++#include <linux/net.h>
40219 ++#include <linux/sched.h>
40220 ++#include <linux/inet.h>
40221 ++#include <linux/stddef.h>
40222 ++
40223 ++#include <net/ip.h>
40224 ++#include <net/sock.h>
40225 ++#include <net/tcp.h>
40226 ++#include <net/udp.h>
40227 ++#include <net/route.h>
40228 ++#include <net/inet_common.h>
40229 ++
40230 ++#include <linux/netfilter_ipv4/ip_tables.h>
40231 ++
40232 ++MODULE_LICENSE("GPL");
40233 ++
40234 ++extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
40235 ++
40236 ++static bool
40237 ++match(const struct sk_buff *skb,
40238 ++ const struct net_device *in,
40239 ++ const struct net_device *out,
40240 ++ const struct xt_match *match,
40241 ++ const void *matchinfo,
40242 ++ int offset,
40243 ++ unsigned int protoff,
40244 ++ bool *hotdrop)
40245 ++{
40246 ++ struct iphdr *ip = ip_hdr(skb);
40247 ++ struct tcphdr th;
40248 ++ struct udphdr uh;
40249 ++ struct sock *sk = NULL;
40250 ++
40251 ++ if (!ip || offset) return false;
40252 ++
40253 ++ switch(ip->protocol) {
40254 ++ case IPPROTO_TCP:
40255 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
40256 ++ *hotdrop = true;
40257 ++ return false;
40258 ++ }
40259 ++ if (!(th.syn && !th.ack)) return false;
40260 ++ sk = inet_lookup_listener(skb->dev->nd_net, &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
40261 ++ break;
40262 ++ case IPPROTO_UDP:
40263 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
40264 ++ *hotdrop = true;
40265 ++ return false;
40266 ++ }
40267 ++ sk = udp_v4_lookup(skb->dev->nd_net, ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
40268 ++ break;
40269 ++ default:
40270 ++ return false;
40271 ++ }
40272 ++
40273 ++ if(!sk) // port is being listened on, match this
40274 ++ return true;
40275 ++ else {
40276 ++ sock_put(sk);
40277 ++ return false;
40278 ++ }
40279 ++}
40280 ++
40281 ++/* Called when user tries to insert an entry of this type. */
40282 ++static bool
40283 ++checkentry(const char *tablename,
40284 ++ const void *nip,
40285 ++ const struct xt_match *match,
40286 ++ void *matchinfo,
40287 ++ unsigned int hook_mask)
40288 ++{
40289 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
40290 ++
40291 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
40292 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
40293 ++ && (hook_mask & (1 << NF_INET_LOCAL_IN)))
40294 ++ return true;
40295 ++
40296 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
40297 ++
40298 ++ return false;
40299 ++}
40300 ++
40301 ++
40302 ++static struct xt_match stealth_match __read_mostly = {
40303 ++ .name = "stealth",
40304 ++ .family = AF_INET,
40305 ++ .match = match,
40306 ++ .checkentry = checkentry,
40307 ++ .destroy = NULL,
40308 ++ .me = THIS_MODULE
40309 ++};
40310 ++
40311 ++static int __init init(void)
40312 ++{
40313 ++ return xt_register_match(&stealth_match);
40314 ++}
40315 ++
40316 ++static void __exit fini(void)
40317 ++{
40318 ++ xt_unregister_match(&stealth_match);
40319 ++}
40320 ++
40321 ++module_init(init);
40322 ++module_exit(fini);
40323 +diff -urNp a/net/ipv4/tcp.c b/net/ipv4/tcp.c
40324 +--- a/net/ipv4/tcp.c 2008-08-20 11:16:13.000000000 -0700
40325 ++++ b/net/ipv4/tcp.c 2008-08-20 18:36:57.000000000 -0700
40326 +@@ -1206,7 +1206,8 @@ int tcp_read_sock(struct sock *sk, read_
40327 + return -ENOTCONN;
40328 + while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
40329 + if (offset < skb->len) {
40330 +- size_t used, len;
40331 ++ int used;
40332 ++ size_t len;
40333 +
40334 + len = skb->len - offset;
40335 + /* Stop reading if we hit a patch of urgent data */
40336 +diff -urNp a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
40337 +--- a/net/ipv4/tcp_ipv4.c 2008-08-20 11:16:13.000000000 -0700
40338 ++++ b/net/ipv4/tcp_ipv4.c 2008-08-20 18:36:57.000000000 -0700
40339 +@@ -61,6 +61,7 @@
40340 + #include <linux/jhash.h>
40341 + #include <linux/init.h>
40342 + #include <linux/times.h>
40343 ++#include <linux/grsecurity.h>
40344 +
40345 + #include <net/net_namespace.h>
40346 + #include <net/icmp.h>
40347 +diff -urNp a/net/ipv4/udp.c b/net/ipv4/udp.c
40348 +--- a/net/ipv4/udp.c 2008-08-20 11:16:13.000000000 -0700
40349 ++++ b/net/ipv4/udp.c 2008-08-20 18:36:57.000000000 -0700
40350 +@@ -99,6 +99,7 @@
40351 + #include <linux/skbuff.h>
40352 + #include <linux/proc_fs.h>
40353 + #include <linux/seq_file.h>
40354 ++#include <linux/grsecurity.h>
40355 + #include <net/net_namespace.h>
40356 + #include <net/icmp.h>
40357 + #include <net/route.h>
40358 +@@ -106,6 +107,11 @@
40359 + #include <net/xfrm.h>
40360 + #include "udp_impl.h"
40361 +
40362 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
40363 ++ const struct sk_buff *skb);
40364 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
40365 ++ const struct sockaddr_in *addr);
40366 ++
40367 + /*
40368 + * Snmp MIB for the UDP layer
40369 + */
40370 +@@ -314,6 +320,13 @@ static struct sock *__udp4_lib_lookup(st
40371 + return result;
40372 + }
40373 +
40374 ++struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
40375 ++ __be32 daddr, __be16 dport, int dif)
40376 ++{
40377 ++ return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
40378 ++}
40379 ++
40380 ++
40381 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
40382 + __be16 loc_port, __be32 loc_addr,
40383 + __be16 rmt_port, __be32 rmt_addr,
40384 +@@ -600,9 +613,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
40385 + dport = usin->sin_port;
40386 + if (dport == 0)
40387 + return -EINVAL;
40388 ++
40389 ++ if (!gr_search_udp_sendmsg(sk, usin))
40390 ++ return -EPERM;
40391 + } else {
40392 + if (sk->sk_state != TCP_ESTABLISHED)
40393 + return -EDESTADDRREQ;
40394 ++
40395 ++ if (!gr_search_udp_sendmsg(sk, NULL))
40396 ++ return -EPERM;
40397 ++
40398 + daddr = inet->daddr;
40399 + dport = inet->dport;
40400 + /* Open fast path for connected socket.
40401 +@@ -864,6 +884,11 @@ try_again:
40402 + if (!skb)
40403 + goto out;
40404 +
40405 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
40406 ++ err = -EPERM;
40407 ++ goto out_free;
40408 ++ }
40409 ++
40410 + ulen = skb->len - sizeof(struct udphdr);
40411 + copied = len;
40412 + if (copied > ulen)
40413 +diff -urNp a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
40414 +--- a/net/ipv6/exthdrs.c 2008-08-20 11:16:13.000000000 -0700
40415 ++++ b/net/ipv6/exthdrs.c 2008-08-20 18:36:57.000000000 -0700
40416 +@@ -626,7 +626,7 @@ static struct tlvtype_proc tlvprochopopt
40417 + .type = IPV6_TLV_JUMBO,
40418 + .func = ipv6_hop_jumbo,
40419 + },
40420 +- { -1, }
40421 ++ { -1, NULL }
40422 + };
40423 +
40424 + int ipv6_parse_hopopts(struct sk_buff *skb)
40425 +diff -urNp a/net/ipv6/raw.c b/net/ipv6/raw.c
40426 +--- a/net/ipv6/raw.c 2008-08-20 11:16:13.000000000 -0700
40427 ++++ b/net/ipv6/raw.c 2008-08-20 18:36:57.000000000 -0700
40428 +@@ -617,7 +617,7 @@ out:
40429 + return err;
40430 + }
40431 +
40432 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
40433 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
40434 + struct flowi *fl, struct rt6_info *rt,
40435 + unsigned int flags)
40436 + {
40437 +diff -urNp a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
40438 +--- a/net/irda/ircomm/ircomm_tty.c 2008-08-20 11:16:13.000000000 -0700
40439 ++++ b/net/irda/ircomm/ircomm_tty.c 2008-08-20 18:36:57.000000000 -0700
40440 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
40441 + IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
40442 +
40443 + line = tty->index;
40444 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
40445 ++ if (line >= IRCOMM_TTY_PORTS) {
40446 + return -ENODEV;
40447 + }
40448 +
40449 +diff -urNp a/net/mac80211/regdomain.c b/net/mac80211/regdomain.c
40450 +--- a/net/mac80211/regdomain.c 2008-08-20 11:16:13.000000000 -0700
40451 ++++ b/net/mac80211/regdomain.c 2008-08-20 18:36:57.000000000 -0700
40452 +@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
40453 + { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
40454 + { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
40455 + { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
40456 +- { 0 }
40457 ++ { 0, 0, 0, 0 }
40458 + };
40459 +
40460 + static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
40461 + { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
40462 + { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
40463 + { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
40464 +- { 0 }
40465 ++ { 0, 0, 0, 0 }
40466 + };
40467 +
40468 +
40469 +diff -urNp a/net/sctp/socket.c b/net/sctp/socket.c
40470 +--- a/net/sctp/socket.c 2008-08-20 11:16:13.000000000 -0700
40471 ++++ b/net/sctp/socket.c 2008-08-20 18:36:57.000000000 -0700
40472 +@@ -1391,7 +1391,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
40473 + struct sctp_sndrcvinfo *sinfo;
40474 + struct sctp_initmsg *sinit;
40475 + sctp_assoc_t associd = 0;
40476 +- sctp_cmsgs_t cmsgs = { NULL };
40477 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
40478 + int err;
40479 + sctp_scope_t scope;
40480 + long timeo;
40481 +diff -urNp a/net/socket.c b/net/socket.c
40482 +--- a/net/socket.c 2008-08-20 11:16:13.000000000 -0700
40483 ++++ b/net/socket.c 2008-08-20 18:36:57.000000000 -0700
40484 +@@ -85,6 +85,7 @@
40485 + #include <linux/audit.h>
40486 + #include <linux/wireless.h>
40487 + #include <linux/nsproxy.h>
40488 ++#include <linux/in.h>
40489 +
40490 + #include <asm/uaccess.h>
40491 + #include <asm/unistd.h>
40492 +@@ -94,6 +95,21 @@
40493 + #include <net/sock.h>
40494 + #include <linux/netfilter.h>
40495 +
40496 ++extern void gr_attach_curr_ip(const struct sock *sk);
40497 ++extern int gr_handle_sock_all(const int family, const int type,
40498 ++ const int protocol);
40499 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
40500 ++extern int gr_handle_sock_server_other(const struct socket *sck);
40501 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
40502 ++extern int gr_search_connect(const struct socket * sock,
40503 ++ const struct sockaddr_in * addr);
40504 ++extern int gr_search_bind(const struct socket * sock,
40505 ++ const struct sockaddr_in * addr);
40506 ++extern int gr_search_listen(const struct socket * sock);
40507 ++extern int gr_search_accept(const struct socket * sock);
40508 ++extern int gr_search_socket(const int domain, const int type,
40509 ++ const int protocol);
40510 ++
40511 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
40512 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
40513 + unsigned long nr_segs, loff_t pos);
40514 +@@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
40515 + mnt);
40516 + }
40517 +
40518 +-static struct vfsmount *sock_mnt __read_mostly;
40519 ++struct vfsmount *sock_mnt __read_mostly;
40520 +
40521 + static struct file_system_type sock_fs_type = {
40522 + .name = "sockfs",
40523 +@@ -1218,6 +1234,16 @@ asmlinkage long sys_socket(int family, i
40524 + int retval;
40525 + struct socket *sock;
40526 +
40527 ++ if(!gr_search_socket(family, type, protocol)) {
40528 ++ retval = -EACCES;
40529 ++ goto out;
40530 ++ }
40531 ++
40532 ++ if (gr_handle_sock_all(family, type, protocol)) {
40533 ++ retval = -EACCES;
40534 ++ goto out;
40535 ++ }
40536 ++
40537 + retval = sock_create(family, type, protocol, &sock);
40538 + if (retval < 0)
40539 + goto out;
40540 +@@ -1348,6 +1374,12 @@ asmlinkage long sys_bind(int fd, struct
40541 + if (sock) {
40542 + err = move_addr_to_kernel(umyaddr, addrlen, address);
40543 + if (err >= 0) {
40544 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
40545 ++ gr_handle_sock_server((struct sockaddr *)address)) {
40546 ++ err = -EACCES;
40547 ++ goto error;
40548 ++ }
40549 ++
40550 + err = security_socket_bind(sock,
40551 + (struct sockaddr *)address,
40552 + addrlen);
40553 +@@ -1356,6 +1388,7 @@ asmlinkage long sys_bind(int fd, struct
40554 + (struct sockaddr *)
40555 + address, addrlen);
40556 + }
40557 ++error:
40558 + fput_light(sock->file, fput_needed);
40559 + }
40560 + return err;
40561 +@@ -1379,10 +1412,17 @@ asmlinkage long sys_listen(int fd, int b
40562 + if ((unsigned)backlog > somaxconn)
40563 + backlog = somaxconn;
40564 +
40565 ++ if (gr_handle_sock_server_other(sock) ||
40566 ++ !gr_search_listen(sock)) {
40567 ++ err = -EPERM;
40568 ++ goto error;
40569 ++ }
40570 ++
40571 + err = security_socket_listen(sock, backlog);
40572 + if (!err)
40573 + err = sock->ops->listen(sock, backlog);
40574 +
40575 ++error:
40576 + fput_light(sock->file, fput_needed);
40577 + }
40578 + return err;
40579 +@@ -1419,6 +1459,13 @@ asmlinkage long sys_accept(int fd, struc
40580 + newsock->type = sock->type;
40581 + newsock->ops = sock->ops;
40582 +
40583 ++ if (gr_handle_sock_server_other(sock) ||
40584 ++ !gr_search_accept(sock)) {
40585 ++ err = -EPERM;
40586 ++ sock_release(newsock);
40587 ++ goto out_put;
40588 ++ }
40589 ++
40590 + /*
40591 + * We don't need try_module_get here, as the listening socket (sock)
40592 + * has the protocol module (sock->ops->owner) held.
40593 +@@ -1462,6 +1509,7 @@ asmlinkage long sys_accept(int fd, struc
40594 + err = newfd;
40595 +
40596 + security_socket_post_accept(sock, newsock);
40597 ++ gr_attach_curr_ip(newsock->sk);
40598 +
40599 + out_put:
40600 + fput_light(sock->file, fput_needed);
40601 +@@ -1495,6 +1543,7 @@ asmlinkage long sys_connect(int fd, stru
40602 + {
40603 + struct socket *sock;
40604 + char address[MAX_SOCK_ADDR];
40605 ++ struct sockaddr *sck;
40606 + int err, fput_needed;
40607 +
40608 + sock = sockfd_lookup_light(fd, &err, &fput_needed);
40609 +@@ -1504,6 +1553,13 @@ asmlinkage long sys_connect(int fd, stru
40610 + if (err < 0)
40611 + goto out_put;
40612 +
40613 ++ sck = (struct sockaddr *)address;
40614 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
40615 ++ gr_handle_sock_client(sck)) {
40616 ++ err = -EACCES;
40617 ++ goto out_put;
40618 ++ }
40619 ++
40620 + err =
40621 + security_socket_connect(sock, (struct sockaddr *)address, addrlen);
40622 + if (err)
40623 +@@ -1770,6 +1826,7 @@ asmlinkage long sys_shutdown(int fd, int
40624 + err = sock->ops->shutdown(sock, how);
40625 + fput_light(sock->file, fput_needed);
40626 + }
40627 ++
40628 + return err;
40629 + }
40630 +
40631 +diff -urNp a/net/unix/af_unix.c b/net/unix/af_unix.c
40632 +--- a/net/unix/af_unix.c 2008-08-20 11:16:13.000000000 -0700
40633 ++++ b/net/unix/af_unix.c 2008-08-20 18:36:57.000000000 -0700
40634 +@@ -116,6 +116,7 @@
40635 + #include <linux/mount.h>
40636 + #include <net/checksum.h>
40637 + #include <linux/security.h>
40638 ++#include <linux/grsecurity.h>
40639 +
40640 + static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
40641 + static DEFINE_SPINLOCK(unix_table_lock);
40642 +@@ -720,6 +721,12 @@ static struct sock *unix_find_other(stru
40643 + err = -ECONNREFUSED;
40644 + if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
40645 + goto put_fail;
40646 ++
40647 ++ if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
40648 ++ err = -EACCES;
40649 ++ goto put_fail;
40650 ++ }
40651 ++
40652 + u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
40653 + if (!u)
40654 + goto put_fail;
40655 +@@ -740,6 +747,13 @@ static struct sock *unix_find_other(stru
40656 + if (u) {
40657 + struct dentry *dentry;
40658 + dentry = unix_sk(u)->dentry;
40659 ++
40660 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
40661 ++ err = -EPERM;
40662 ++ sock_put(u);
40663 ++ goto fail;
40664 ++ }
40665 ++
40666 + if (dentry)
40667 + touch_atime(unix_sk(u)->mnt, dentry);
40668 + } else
40669 +@@ -819,9 +833,18 @@ static int unix_bind(struct socket *sock
40670 + */
40671 + mode = S_IFSOCK |
40672 + (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
40673 ++
40674 ++ if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
40675 ++ err = -EACCES;
40676 ++ goto out_mknod_dput;
40677 ++ }
40678 ++
40679 + err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
40680 + if (err)
40681 + goto out_mknod_dput;
40682 ++
40683 ++ gr_handle_create(dentry, nd.path.mnt);
40684 ++
40685 + mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
40686 + dput(nd.path.dentry);
40687 + nd.path.dentry = dentry;
40688 +@@ -839,6 +862,10 @@ static int unix_bind(struct socket *sock
40689 + goto out_unlock;
40690 + }
40691 +
40692 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
40693 ++ sk->sk_peercred.pid = current->pid;
40694 ++#endif
40695 ++
40696 + list = &unix_socket_table[addr->hash];
40697 + } else {
40698 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
40699 +diff -urNp a/scripts/pnmtologo.c b/scripts/pnmtologo.c
40700 +--- a/scripts/pnmtologo.c 2008-08-20 11:16:13.000000000 -0700
40701 ++++ b/scripts/pnmtologo.c 2008-08-20 18:36:57.000000000 -0700
40702 +@@ -237,14 +237,14 @@ static void write_header(void)
40703 + fprintf(out, " * Linux logo %s\n", logoname);
40704 + fputs(" */\n\n", out);
40705 + fputs("#include <linux/linux_logo.h>\n\n", out);
40706 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
40707 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
40708 + logoname);
40709 + }
40710 +
40711 + static void write_footer(void)
40712 + {
40713 + fputs("\n};\n\n", out);
40714 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
40715 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
40716 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
40717 + fprintf(out, " .width\t= %d,\n", logo_width);
40718 + fprintf(out, " .height\t= %d,\n", logo_height);
40719 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
40720 + fputs("\n};\n\n", out);
40721 +
40722 + /* write logo clut */
40723 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
40724 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
40725 + logoname);
40726 + write_hex_cnt = 0;
40727 + for (i = 0; i < logo_clutsize; i++) {
40728 +diff -urNp a/security/Kconfig b/security/Kconfig
40729 +--- a/security/Kconfig 2008-08-20 11:16:13.000000000 -0700
40730 ++++ b/security/Kconfig 2008-08-20 18:36:57.000000000 -0700
40731 +@@ -4,6 +4,429 @@
40732 +
40733 + menu "Security options"
40734 +
40735 ++source grsecurity/Kconfig
40736 ++
40737 ++menu "PaX"
40738 ++
40739 ++config PAX
40740 ++ bool "Enable various PaX features"
40741 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
40742 ++ help
40743 ++ This allows you to enable various PaX features. PaX adds
40744 ++ intrusion prevention mechanisms to the kernel that reduce
40745 ++ the risks posed by exploitable memory corruption bugs.
40746 ++
40747 ++menu "PaX Control"
40748 ++ depends on PAX
40749 ++
40750 ++config PAX_SOFTMODE
40751 ++ bool 'Support soft mode'
40752 ++ help
40753 ++ Enabling this option will allow you to run PaX in soft mode, that
40754 ++ is, PaX features will not be enforced by default, only on executables
40755 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
40756 ++ is the only way to mark executables for soft mode use.
40757 ++
40758 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
40759 ++ line option on boot. Furthermore you can control various PaX features
40760 ++ at runtime via the entries in /proc/sys/kernel/pax.
40761 ++
40762 ++config PAX_EI_PAX
40763 ++ bool 'Use legacy ELF header marking'
40764 ++ help
40765 ++ Enabling this option will allow you to control PaX features on
40766 ++ a per executable basis via the 'chpax' utility available at
40767 ++ http://pax.grsecurity.net/. The control flags will be read from
40768 ++ an otherwise reserved part of the ELF header. This marking has
40769 ++ numerous drawbacks (no support for soft-mode, toolchain does not
40770 ++ know about the non-standard use of the ELF header) therefore it
40771 ++ has been deprecated in favour of PT_PAX_FLAGS support.
40772 ++
40773 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
40774 ++ program header then you MUST enable this option otherwise they
40775 ++ will not get any protection.
40776 ++
40777 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
40778 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
40779 ++
40780 ++config PAX_PT_PAX_FLAGS
40781 ++ bool 'Use ELF program header marking'
40782 ++ help
40783 ++ Enabling this option will allow you to control PaX features on
40784 ++ a per executable basis via the 'paxctl' utility available at
40785 ++ http://pax.grsecurity.net/. The control flags will be read from
40786 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
40787 ++ has the benefits of supporting both soft mode and being fully
40788 ++ integrated into the toolchain (the binutils patch is available
40789 ++ from http://pax.grsecurity.net).
40790 ++
40791 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
40792 ++ program header then you MUST enable the EI_PAX marking support
40793 ++ otherwise they will not get any protection.
40794 ++
40795 ++ Note that if you enable the legacy EI_PAX marking support as well,
40796 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
40797 ++
40798 ++choice
40799 ++ prompt 'MAC system integration'
40800 ++ default PAX_HAVE_ACL_FLAGS
40801 ++ help
40802 ++ Mandatory Access Control systems have the option of controlling
40803 ++ PaX flags on a per executable basis, choose the method supported
40804 ++ by your particular system.
40805 ++
40806 ++ - "none": if your MAC system does not interact with PaX,
40807 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
40808 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
40809 ++
40810 ++ NOTE: this option is for developers/integrators only.
40811 ++
40812 ++ config PAX_NO_ACL_FLAGS
40813 ++ bool 'none'
40814 ++
40815 ++ config PAX_HAVE_ACL_FLAGS
40816 ++ bool 'direct'
40817 ++
40818 ++ config PAX_HOOK_ACL_FLAGS
40819 ++ bool 'hook'
40820 ++endchoice
40821 ++
40822 ++endmenu
40823 ++
40824 ++menu "Non-executable pages"
40825 ++ depends on PAX
40826 ++
40827 ++config PAX_NOEXEC
40828 ++ bool "Enforce non-executable pages"
40829 ++ 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)
40830 ++ help
40831 ++ By design some architectures do not allow for protecting memory
40832 ++ pages against execution or even if they do, Linux does not make
40833 ++ use of this feature. In practice this means that if a page is
40834 ++ readable (such as the stack or heap) it is also executable.
40835 ++
40836 ++ There is a well known exploit technique that makes use of this
40837 ++ fact and a common programming mistake where an attacker can
40838 ++ introduce code of his choice somewhere in the attacked program's
40839 ++ memory (typically the stack or the heap) and then execute it.
40840 ++
40841 ++ If the attacked program was running with different (typically
40842 ++ higher) privileges than that of the attacker, then he can elevate
40843 ++ his own privilege level (e.g. get a root shell, write to files for
40844 ++ which he does not have write access to, etc).
40845 ++
40846 ++ Enabling this option will let you choose from various features
40847 ++ that prevent the injection and execution of 'foreign' code in
40848 ++ a program.
40849 ++
40850 ++ This will also break programs that rely on the old behaviour and
40851 ++ expect that dynamically allocated memory via the malloc() family
40852 ++ of functions is executable (which it is not). Notable examples
40853 ++ are the XFree86 4.x server, the java runtime and wine.
40854 ++
40855 ++config PAX_PAGEEXEC
40856 ++ bool "Paging based non-executable pages"
40857 ++ 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)
40858 ++ help
40859 ++ This implementation is based on the paging feature of the CPU.
40860 ++ On i386 without hardware non-executable bit support there is a
40861 ++ variable but usually low performance impact, however on Intel's
40862 ++ P4 core based CPUs it is very high so you should not enable this
40863 ++ for kernels meant to be used on such CPUs.
40864 ++
40865 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
40866 ++ with hardware non-executable bit support there is no performance
40867 ++ impact, on ppc the impact is negligible.
40868 ++
40869 ++ Note that several architectures require various emulations due to
40870 ++ badly designed userland ABIs, this will cause a performance impact
40871 ++ but will disappear as soon as userland is fixed (e.g., ppc users
40872 ++ can make use of the secure-plt feature found in binutils).
40873 ++
40874 ++config PAX_SEGMEXEC
40875 ++ bool "Segmentation based non-executable pages"
40876 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
40877 ++ help
40878 ++ This implementation is based on the segmentation feature of the
40879 ++ CPU and has a very small performance impact, however applications
40880 ++ will be limited to a 1.5 GB address space instead of the normal
40881 ++ 3 GB.
40882 ++
40883 ++config PAX_EMUTRAMP
40884 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
40885 ++ default y if PARISC || PPC32
40886 ++ help
40887 ++ There are some programs and libraries that for one reason or
40888 ++ another attempt to execute special small code snippets from
40889 ++ non-executable memory pages. Most notable examples are the
40890 ++ signal handler return code generated by the kernel itself and
40891 ++ the GCC trampolines.
40892 ++
40893 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
40894 ++ such programs will no longer work under your kernel.
40895 ++
40896 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
40897 ++ utilities to enable trampoline emulation for the affected programs
40898 ++ yet still have the protection provided by the non-executable pages.
40899 ++
40900 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
40901 ++ well, otherwise your system will not even boot.
40902 ++
40903 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
40904 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
40905 ++ for the affected files.
40906 ++
40907 ++ NOTE: enabling this feature *may* open up a loophole in the
40908 ++ protection provided by non-executable pages that an attacker
40909 ++ could abuse. Therefore the best solution is to not have any
40910 ++ files on your system that would require this option. This can
40911 ++ be achieved by not using libc5 (which relies on the kernel
40912 ++ signal handler return code) and not using or rewriting programs
40913 ++ that make use of the nested function implementation of GCC.
40914 ++ Skilled users can just fix GCC itself so that it implements
40915 ++ nested function calls in a way that does not interfere with PaX.
40916 ++
40917 ++config PAX_EMUSIGRT
40918 ++ bool "Automatically emulate sigreturn trampolines"
40919 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
40920 ++ default y
40921 ++ help
40922 ++ Enabling this option will have the kernel automatically detect
40923 ++ and emulate signal return trampolines executing on the stack
40924 ++ that would otherwise lead to task termination.
40925 ++
40926 ++ This solution is intended as a temporary one for users with
40927 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
40928 ++ Modula-3 runtime, etc) or executables linked to such, basically
40929 ++ everything that does not specify its own SA_RESTORER function in
40930 ++ normal executable memory like glibc 2.1+ does.
40931 ++
40932 ++ On parisc and ppc you MUST enable this option, otherwise your
40933 ++ system will not even boot.
40934 ++
40935 ++ NOTE: this feature cannot be disabled on a per executable basis
40936 ++ and since it *does* open up a loophole in the protection provided
40937 ++ by non-executable pages, the best solution is to not have any
40938 ++ files on your system that would require this option.
40939 ++
40940 ++config PAX_MPROTECT
40941 ++ bool "Restrict mprotect()"
40942 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
40943 ++ help
40944 ++ Enabling this option will prevent programs from
40945 ++ - changing the executable status of memory pages that were
40946 ++ not originally created as executable,
40947 ++ - making read-only executable pages writable again,
40948 ++ - creating executable pages from anonymous memory.
40949 ++
40950 ++ You should say Y here to complete the protection provided by
40951 ++ the enforcement of non-executable pages.
40952 ++
40953 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
40954 ++ this feature on a per file basis.
40955 ++
40956 ++config PAX_NOELFRELOCS
40957 ++ bool "Disallow ELF text relocations"
40958 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
40959 ++ help
40960 ++ Non-executable pages and mprotect() restrictions are effective
40961 ++ in preventing the introduction of new executable code into an
40962 ++ attacked task's address space. There remain only two venues
40963 ++ for this kind of attack: if the attacker can execute already
40964 ++ existing code in the attacked task then he can either have it
40965 ++ create and mmap() a file containing his code or have it mmap()
40966 ++ an already existing ELF library that does not have position
40967 ++ independent code in it and use mprotect() on it to make it
40968 ++ writable and copy his code there. While protecting against
40969 ++ the former approach is beyond PaX, the latter can be prevented
40970 ++ by having only PIC ELF libraries on one's system (which do not
40971 ++ need to relocate their code). If you are sure this is your case,
40972 ++ then enable this option otherwise be careful as you may not even
40973 ++ be able to boot or log on your system (for example, some PAM
40974 ++ modules are erroneously compiled as non-PIC by default).
40975 ++
40976 ++ NOTE: if you are using dynamic ELF executables (as suggested
40977 ++ when using ASLR) then you must have made sure that you linked
40978 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
40979 ++ referenced there has already been updated to support this).
40980 ++
40981 ++config PAX_ETEXECRELOCS
40982 ++ bool "Allow ELF ET_EXEC text relocations"
40983 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
40984 ++ default y
40985 ++ help
40986 ++ On some architectures there are incorrectly created applications
40987 ++ that require text relocations and would not work without enabling
40988 ++ this option. If you are an alpha, ia64 or parisc user, you should
40989 ++ enable this option and disable it once you have made sure that
40990 ++ none of your applications need it.
40991 ++
40992 ++config PAX_EMUPLT
40993 ++ bool "Automatically emulate ELF PLT"
40994 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
40995 ++ default y
40996 ++ help
40997 ++ Enabling this option will have the kernel automatically detect
40998 ++ and emulate the Procedure Linkage Table entries in ELF files.
40999 ++ On some architectures such entries are in writable memory, and
41000 ++ become non-executable leading to task termination. Therefore
41001 ++ it is mandatory that you enable this option on alpha, parisc,
41002 ++ ppc (if secure-plt is not used throughout in userland), sparc
41003 ++ and sparc64, otherwise your system would not even boot.
41004 ++
41005 ++ NOTE: this feature *does* open up a loophole in the protection
41006 ++ provided by the non-executable pages, therefore the proper
41007 ++ solution is to modify the toolchain to produce a PLT that does
41008 ++ not need to be writable.
41009 ++
41010 ++config PAX_DLRESOLVE
41011 ++ bool
41012 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
41013 ++ default y
41014 ++
41015 ++config PAX_SYSCALL
41016 ++ bool
41017 ++ depends on PAX_PAGEEXEC && PPC32
41018 ++ default y
41019 ++
41020 ++config PAX_KERNEXEC
41021 ++ bool "Enforce non-executable kernel pages"
41022 ++ depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
41023 ++ help
41024 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
41025 ++ that is, enabling this option will make it harder to inject
41026 ++ and execute 'foreign' code in kernel memory itself.
41027 ++
41028 ++endmenu
41029 ++
41030 ++menu "Address Space Layout Randomization"
41031 ++ depends on PAX
41032 ++
41033 ++config PAX_ASLR
41034 ++ bool "Address Space Layout Randomization"
41035 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
41036 ++ help
41037 ++ Many if not most exploit techniques rely on the knowledge of
41038 ++ certain addresses in the attacked program. The following options
41039 ++ will allow the kernel to apply a certain amount of randomization
41040 ++ to specific parts of the program thereby forcing an attacker to
41041 ++ guess them in most cases. Any failed guess will most likely crash
41042 ++ the attacked program which allows the kernel to detect such attempts
41043 ++ and react on them. PaX itself provides no reaction mechanisms,
41044 ++ instead it is strongly encouraged that you make use of Nergal's
41045 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
41046 ++ (http://www.grsecurity.net/) built-in crash detection features or
41047 ++ develop one yourself.
41048 ++
41049 ++ By saying Y here you can choose to randomize the following areas:
41050 ++ - top of the task's kernel stack
41051 ++ - top of the task's userland stack
41052 ++ - base address for mmap() requests that do not specify one
41053 ++ (this includes all libraries)
41054 ++ - base address of the main executable
41055 ++
41056 ++ It is strongly recommended to say Y here as address space layout
41057 ++ randomization has negligible impact on performance yet it provides
41058 ++ a very effective protection.
41059 ++
41060 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
41061 ++ this feature on a per file basis.
41062 ++
41063 ++config PAX_RANDKSTACK
41064 ++ bool "Randomize kernel stack base"
41065 ++ depends on PAX_ASLR && X86_TSC && X86_32
41066 ++ help
41067 ++ By saying Y here the kernel will randomize every task's kernel
41068 ++ stack on every system call. This will not only force an attacker
41069 ++ to guess it but also prevent him from making use of possible
41070 ++ leaked information about it.
41071 ++
41072 ++ Since the kernel stack is a rather scarce resource, randomization
41073 ++ may cause unexpected stack overflows, therefore you should very
41074 ++ carefully test your system. Note that once enabled in the kernel
41075 ++ configuration, this feature cannot be disabled on a per file basis.
41076 ++
41077 ++config PAX_RANDUSTACK
41078 ++ bool "Randomize user stack base"
41079 ++ depends on PAX_ASLR
41080 ++ help
41081 ++ By saying Y here the kernel will randomize every task's userland
41082 ++ stack. The randomization is done in two steps where the second
41083 ++ one may apply a big amount of shift to the top of the stack and
41084 ++ cause problems for programs that want to use lots of memory (more
41085 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
41086 ++ For this reason the second step can be controlled by 'chpax' or
41087 ++ 'paxctl' on a per file basis.
41088 ++
41089 ++config PAX_RANDMMAP
41090 ++ bool "Randomize mmap() base"
41091 ++ depends on PAX_ASLR
41092 ++ help
41093 ++ By saying Y here the kernel will use a randomized base address for
41094 ++ mmap() requests that do not specify one themselves. As a result
41095 ++ all dynamically loaded libraries will appear at random addresses
41096 ++ and therefore be harder to exploit by a technique where an attacker
41097 ++ attempts to execute library code for his purposes (e.g. spawn a
41098 ++ shell from an exploited program that is running at an elevated
41099 ++ privilege level).
41100 ++
41101 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
41102 ++ base address will be randomized as well, completing the full
41103 ++ randomization of the address space layout. Attacking such programs
41104 ++ becomes a guess game. You can find an example of doing this at
41105 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
41106 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
41107 ++
41108 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
41109 ++ feature on a per file basis.
41110 ++
41111 ++endmenu
41112 ++
41113 ++menu "Miscellaneous hardening features"
41114 ++
41115 ++config PAX_MEMORY_SANITIZE
41116 ++ bool "Sanitize all freed memory"
41117 ++ help
41118 ++ By saying Y here the kernel will erase memory pages as soon as they
41119 ++ are freed. This in turn reduces the lifetime of data stored in the
41120 ++ pages, making it less likely that sensitive information such as
41121 ++ passwords, cryptographic secrets, etc stay in memory for too long.
41122 ++
41123 ++ This is especially useful for programs whose runtime is short, long
41124 ++ lived processes and the kernel itself benefit from this as long as
41125 ++ they operate on whole memory pages and ensure timely freeing of pages
41126 ++ that may hold sensitive information.
41127 ++
41128 ++ The tradeoff is performance impact, on a single CPU system kernel
41129 ++ compilation sees a 3% slowdown, other systems and workloads may vary
41130 ++ and you are advised to test this feature on your expected workload
41131 ++ before deploying it.
41132 ++
41133 ++ Note that this feature does not protect data stored in live pages,
41134 ++ e.g., process memory swapped to disk may stay there for a long time.
41135 ++
41136 ++config PAX_MEMORY_UDEREF
41137 ++ bool "Prevent invalid userland pointer dereference"
41138 ++ depends on X86_32 && !COMPAT_VDSO
41139 ++ help
41140 ++ By saying Y here the kernel will be prevented from dereferencing
41141 ++ userland pointers in contexts where the kernel expects only kernel
41142 ++ pointers. This is both a useful runtime debugging feature and a
41143 ++ security measure that prevents exploiting a class of kernel bugs.
41144 ++
41145 ++ The tradeoff is that some virtualization solutions may experience
41146 ++ a huge slowdown and therefore you should not enable this feature
41147 ++ for kernels meant to run in such environments. Whether a given VM
41148 ++ solution is affected or not is best determined by simply trying it
41149 ++ out, the performance impact will be obvious right on boot as this
41150 ++ mechanism engages from very early on. A good rule of thumb is that
41151 ++ VMs running on CPUs without hardware virtualization support (i.e.,
41152 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
41153 ++
41154 ++endmenu
41155 ++
41156 ++endmenu
41157 ++
41158 + config KEYS
41159 + bool "Enable access key retention support"
41160 + help
41161 +diff -urNp a/security/commoncap.c b/security/commoncap.c
41162 +--- a/security/commoncap.c 2008-08-20 11:16:13.000000000 -0700
41163 ++++ b/security/commoncap.c 2008-08-20 18:36:57.000000000 -0700
41164 +@@ -24,15 +24,18 @@
41165 + #include <linux/hugetlb.h>
41166 + #include <linux/mount.h>
41167 + #include <linux/sched.h>
41168 ++#include <linux/grsecurity.h>
41169 +
41170 + /* Global security state */
41171 +
41172 + unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
41173 + EXPORT_SYMBOL(securebits);
41174 +
41175 ++extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
41176 ++
41177 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
41178 + {
41179 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
41180 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
41181 + return 0;
41182 + }
41183 +
41184 +@@ -54,7 +57,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
41185 + int cap_capable (struct task_struct *tsk, int cap)
41186 + {
41187 + /* Derived from include/linux/sched.h:capable. */
41188 +- if (cap_raised(tsk->cap_effective, cap))
41189 ++ if (cap_raised (tsk->cap_effective, cap))
41190 ++ return 0;
41191 ++ return -EPERM;
41192 ++}
41193 ++
41194 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
41195 ++{
41196 ++ /* tsk = current for all callers */
41197 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
41198 + return 0;
41199 + return -EPERM;
41200 + }
41201 +@@ -352,8 +363,11 @@ void cap_bprm_apply_creds (struct linux_
41202 + }
41203 + }
41204 +
41205 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
41206 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
41207 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
41208 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
41209 ++
41210 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
41211 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
41212 +
41213 + /* For init, we want to retain the capabilities set
41214 + * in the init_task struct. Thus we skip the usual
41215 +@@ -366,6 +380,8 @@ void cap_bprm_apply_creds (struct linux_
41216 + cap_clear(current->cap_effective);
41217 + }
41218 +
41219 ++ gr_handle_chroot_caps(current);
41220 ++
41221 + /* AUD: Audit candidate if current->cap_effective is set */
41222 +
41223 + current->keep_capabilities = 0;
41224 +@@ -592,7 +608,7 @@ int cap_vm_enough_memory(struct mm_struc
41225 + {
41226 + int cap_sys_admin = 0;
41227 +
41228 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
41229 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
41230 + cap_sys_admin = 1;
41231 + return __vm_enough_memory(mm, pages, cap_sys_admin);
41232 + }
41233 +diff -urNp a/security/dummy.c b/security/dummy.c
41234 +--- a/security/dummy.c 2008-08-20 11:16:13.000000000 -0700
41235 ++++ b/security/dummy.c 2008-08-20 18:36:57.000000000 -0700
41236 +@@ -27,6 +27,7 @@
41237 + #include <linux/hugetlb.h>
41238 + #include <linux/ptrace.h>
41239 + #include <linux/file.h>
41240 ++#include <linux/grsecurity.h>
41241 +
41242 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
41243 + {
41244 +@@ -140,8 +141,11 @@ static void dummy_bprm_apply_creds (stru
41245 + }
41246 + }
41247 +
41248 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
41249 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
41250 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
41251 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
41252 ++
41253 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
41254 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
41255 +
41256 + dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
41257 + }
41258 +diff -urNp a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
41259 +--- a/sound/core/oss/pcm_oss.c 2008-08-20 11:16:13.000000000 -0700
41260 ++++ b/sound/core/oss/pcm_oss.c 2008-08-20 18:36:57.000000000 -0700
41261 +@@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
41262 + }
41263 + }
41264 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
41265 +-#define snd_pcm_oss_proc_init(pcm)
41266 +-#define snd_pcm_oss_proc_done(pcm)
41267 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
41268 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
41269 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
41270 +
41271 + /*
41272 +diff -urNp a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h
41273 +--- a/sound/core/seq/seq_lock.h 2008-08-20 11:16:13.000000000 -0700
41274 ++++ b/sound/core/seq/seq_lock.h 2008-08-20 18:36:57.000000000 -0700
41275 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
41276 + #else /* SMP || CONFIG_SND_DEBUG */
41277 +
41278 + typedef spinlock_t snd_use_lock_t; /* dummy */
41279 +-#define snd_use_lock_init(lockp) /**/
41280 +-#define snd_use_lock_use(lockp) /**/
41281 +-#define snd_use_lock_free(lockp) /**/
41282 +-#define snd_use_lock_sync(lockp) /**/
41283 ++#define snd_use_lock_init(lockp) do {} while (0)
41284 ++#define snd_use_lock_use(lockp) do {} while (0)
41285 ++#define snd_use_lock_free(lockp) do {} while (0)
41286 ++#define snd_use_lock_sync(lockp) do {} while (0)
41287 +
41288 + #endif /* SMP || CONFIG_SND_DEBUG */
41289 +
41290 +diff -urNp a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
41291 +--- a/sound/pci/ac97/ac97_patch.c 2008-08-20 11:16:13.000000000 -0700
41292 ++++ b/sound/pci/ac97/ac97_patch.c 2008-08-20 18:36:57.000000000 -0700
41293 +@@ -1486,7 +1486,7 @@ static const struct snd_ac97_res_table a
41294 + { AC97_VIDEO, 0x9f1f },
41295 + { AC97_AUX, 0x9f1f },
41296 + { AC97_PCM, 0x9f1f },
41297 +- { } /* terminator */
41298 ++ { 0, 0 } /* terminator */
41299 + };
41300 +
41301 + static int patch_ad1819(struct snd_ac97 * ac97)
41302 +@@ -3564,7 +3564,7 @@ static struct snd_ac97_res_table lm4550_
41303 + { AC97_AUX, 0x1f1f },
41304 + { AC97_PCM, 0x1f1f },
41305 + { AC97_REC_GAIN, 0x0f0f },
41306 +- { } /* terminator */
41307 ++ { 0, 0 } /* terminator */
41308 + };
41309 +
41310 + static int patch_lm4550(struct snd_ac97 *ac97)
41311 +diff -urNp a/sound/pci/ens1370.c b/sound/pci/ens1370.c
41312 +--- a/sound/pci/ens1370.c 2008-08-20 11:16:13.000000000 -0700
41313 ++++ b/sound/pci/ens1370.c 2008-08-20 18:36:57.000000000 -0700
41314 +@@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
41315 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
41316 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
41317 + #endif
41318 +- { 0, }
41319 ++ { 0, 0, 0, 0, 0, 0, 0 }
41320 + };
41321 +
41322 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
41323 +diff -urNp a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
41324 +--- a/sound/pci/intel8x0.c 2008-08-20 11:16:13.000000000 -0700
41325 ++++ b/sound/pci/intel8x0.c 2008-08-20 18:36:57.000000000 -0700
41326 +@@ -435,7 +435,7 @@ static struct pci_device_id snd_intel8x0
41327 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
41328 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
41329 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
41330 +- { 0, }
41331 ++ { 0, 0, 0, 0, 0, 0, 0 }
41332 + };
41333 +
41334 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
41335 +@@ -2057,7 +2057,7 @@ static struct ac97_quirk ac97_quirks[] _
41336 + .type = AC97_TUNE_HP_ONLY
41337 + },
41338 + #endif
41339 +- { } /* terminator */
41340 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
41341 + };
41342 +
41343 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
41344 +diff -urNp a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
41345 +--- a/sound/pci/intel8x0m.c 2008-08-20 11:16:13.000000000 -0700
41346 ++++ b/sound/pci/intel8x0m.c 2008-08-20 18:36:57.000000000 -0700
41347 +@@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
41348 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
41349 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
41350 + #endif
41351 +- { 0, }
41352 ++ { 0, 0, 0, 0, 0, 0, 0 }
41353 + };
41354 +
41355 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
41356 +@@ -1260,7 +1260,7 @@ static struct shortname_table {
41357 + { 0x5455, "ALi M5455" },
41358 + { 0x746d, "AMD AMD8111" },
41359 + #endif
41360 +- { 0 },
41361 ++ { 0, NULL },
41362 + };
41363 +
41364 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
41365 +diff -urNp a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
41366 +--- a/virt/kvm/kvm_main.c 2008-08-20 11:16:13.000000000 -0700
41367 ++++ b/virt/kvm/kvm_main.c 2008-08-20 18:36:57.000000000 -0700
41368 +@@ -1077,6 +1077,9 @@ static struct miscdevice kvm_dev = {
41369 + KVM_MINOR,
41370 + "kvm",
41371 + &kvm_chardev_ops,
41372 ++ {NULL, NULL},
41373 ++ NULL,
41374 ++ NULL
41375 + };
41376 +
41377 + static void hardware_enable(void *junk)
41378
41379 Added: hardened/2.6/tags/2.6.25-14/4421_grsec-remove-localversion-grsec.patch
41380 ===================================================================
41381 --- hardened/2.6/tags/2.6.25-14/4421_grsec-remove-localversion-grsec.patch (rev 0)
41382 +++ hardened/2.6/tags/2.6.25-14/4421_grsec-remove-localversion-grsec.patch 2009-01-21 00:09:46 UTC (rev 1481)
41383 @@ -0,0 +1,9 @@
41384 +From: Kerin Millar <kerframil@×××××.com>
41385 +
41386 +Remove grsecurity's localversion-grsec file as it is inconsistent with
41387 +Gentoo's kernel practices and naming scheme.
41388 +
41389 +--- a/localversion-grsec 2008-02-24 14:26:59.000000000 +0000
41390 ++++ b/localversion-grsec 1970-01-01 01:00:00.000000000 +0100
41391 +@@ -1 +0,0 @@
41392 +--grsec
41393
41394 Added: hardened/2.6/tags/2.6.25-14/4422_grsec-mute-warnings.patch
41395 ===================================================================
41396 --- hardened/2.6/tags/2.6.25-14/4422_grsec-mute-warnings.patch (rev 0)
41397 +++ hardened/2.6/tags/2.6.25-14/4422_grsec-mute-warnings.patch 2009-01-21 00:09:46 UTC (rev 1481)
41398 @@ -0,0 +1,28 @@
41399 +From: Gordon Malm <gengor@g.o>
41400 +
41401 +Updated patch for kernel series 2.6.24.
41402 +
41403 +The credits/description from the original version of this patch remain accurate
41404 +and are included below.
41405 +
41406 +---
41407 +From: Alexander Gabert <gaberta@××××××××.de>
41408 +
41409 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
41410 +It removes the -W options added by the patch and restores the original
41411 +warning flags of vanilla kernel versions.
41412 +
41413 +Acked-by: Christian Heim <phreak@g.o>
41414 +---
41415 +
41416 +--- a/Makefile
41417 ++++ b/Makefile
41418 +@@ -214,7 +214,7 @@
41419 +
41420 + HOSTCC = gcc
41421 + HOSTCXX = g++
41422 +-HOSTCFLAGS = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
41423 ++HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
41424 + HOSTCXXFLAGS = -O2
41425 +
41426 + # Decide whether to build built-in, modular, or both.
41427
41428 Added: hardened/2.6/tags/2.6.25-14/4425_grsec-pax-without-grsec.patch
41429 ===================================================================
41430 --- hardened/2.6/tags/2.6.25-14/4425_grsec-pax-without-grsec.patch (rev 0)
41431 +++ hardened/2.6/tags/2.6.25-14/4425_grsec-pax-without-grsec.patch 2009-01-21 00:09:46 UTC (rev 1481)
41432 @@ -0,0 +1,47 @@
41433 +From: Gordon Malm <gengor@g.o>
41434 +
41435 +Allow PaX options to be selected without first selecting CONFIG_GRKERNSEC.
41436 +
41437 +This patch has been updated to keep current with newer kernel versions.
41438 +The original version of this patch contained no credits/description.
41439 +
41440 +--- a/security/Kconfig
41441 ++++ b/security/Kconfig
41442 +@@ -10,7 +10,7 @@ menu "PaX"
41443 +
41444 + config PAX
41445 + bool "Enable various PaX features"
41446 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
41447 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
41448 + help
41449 + This allows you to enable various PaX features. PaX adds
41450 + intrusion prevention mechanisms to the kernel that reduce
41451 +--- a/arch/x86/mm/fault.c
41452 ++++ b/arch/x86/mm/fault.c
41453 +@@ -422,10 +422,12 @@ static void show_fault_oops(struct pt_re
41454 + #else
41455 + if (init_mm.start_code <= address && address < init_mm.end_code)
41456 + #endif
41457 ++#ifdef CONFIG_GRKERNSEC
41458 + if (current->signal->curr_ip)
41459 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
41460 + NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
41461 + else
41462 ++#endif
41463 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
41464 + current->comm, task_pid_nr(current), current->uid, current->euid);
41465 + #endif
41466 +--- a/fs/exec.c
41467 ++++ b/fs/exec.c
41468 +@@ -1691,9 +1691,11 @@ void pax_report_fault(struct pt_regs *re
41469 + }
41470 + up_read(&mm->mmap_sem);
41471 + }
41472 ++#ifdef CONFIG_GRKERNSEC
41473 + if (tsk->signal->curr_ip)
41474 + 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);
41475 + else
41476 ++#endif
41477 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
41478 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
41479 + "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
41480
41481 Added: hardened/2.6/tags/2.6.25-14/4430_grsec-kconfig-default-gids.patch
41482 ===================================================================
41483 --- hardened/2.6/tags/2.6.25-14/4430_grsec-kconfig-default-gids.patch (rev 0)
41484 +++ hardened/2.6/tags/2.6.25-14/4430_grsec-kconfig-default-gids.patch 2009-01-21 00:09:46 UTC (rev 1481)
41485 @@ -0,0 +1,76 @@
41486 +From: Kerin Millar <kerframil@×××××.com>
41487 +
41488 +grsecurity contains a number of options which allow certain protections
41489 +to be applied to or exempted from members of a given group. However, the
41490 +default GIDs specified in the upstream patch are entirely arbitrary and
41491 +there is no telling which (if any) groups the GIDs will correlate with
41492 +on an end-user's system. Because some users don't pay a great deal of
41493 +attention to the finer points of kernel configuration, it is probably
41494 +wise to specify some reasonable defaults so as to stop careless users
41495 +from shooting themselves in the foot.
41496 +
41497 +--- a/grsecurity/Kconfig
41498 ++++ b/grsecurity/Kconfig
41499 +@@ -352,7 +564,7 @@
41500 + config GRKERNSEC_PROC_GID
41501 + int "GID for special group"
41502 + depends on GRKERNSEC_PROC_USERGROUP
41503 +- default 1001
41504 ++ default 10
41505 +
41506 + config GRKERNSEC_PROC_ADD
41507 + bool "Additional restrictions"
41508 +@@ -547,7 +759,7 @@
41509 + config GRKERNSEC_AUDIT_GID
41510 + int "GID for auditing"
41511 + depends on GRKERNSEC_AUDIT_GROUP
41512 +- default 1007
41513 ++ default 100
41514 +
41515 + config GRKERNSEC_EXECLOG
41516 + bool "Exec logging"
41517 +@@ -700,7 +912,7 @@
41518 + config GRKERNSEC_TPE_GID
41519 + int "GID for untrusted users"
41520 + depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
41521 +- default 1005
41522 ++ default 100
41523 + help
41524 + If you have selected the "Invert GID option" above, setting this
41525 + GID determines what group TPE restrictions will be *disabled* for.
41526 +@@ -712,7 +924,7 @@
41527 + config GRKERNSEC_TPE_GID
41528 + int "GID for trusted users"
41529 + depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
41530 +- default 1005
41531 ++ default 10
41532 + help
41533 + If you have selected the "Invert GID option" above, setting this
41534 + GID determines what group TPE restrictions will be *disabled* for.
41535 +@@ -754,7 +966,7 @@
41536 + config GRKERNSEC_SOCKET_ALL_GID
41537 + int "GID to deny all sockets for"
41538 + depends on GRKERNSEC_SOCKET_ALL
41539 +- default 1004
41540 ++ default 65534
41541 + help
41542 + Here you can choose the GID to disable socket access for. Remember to
41543 + add the users you want socket access disabled for to the GID
41544 +@@ -775,7 +987,7 @@
41545 + config GRKERNSEC_SOCKET_CLIENT_GID
41546 + int "GID to deny client sockets for"
41547 + depends on GRKERNSEC_SOCKET_CLIENT
41548 +- default 1003
41549 ++ default 65534
41550 + help
41551 + Here you can choose the GID to disable client socket access for.
41552 + Remember to add the users you want client socket access disabled for to
41553 +@@ -793,7 +1005,7 @@
41554 + config GRKERNSEC_SOCKET_SERVER_GID
41555 + int "GID to deny server sockets for"
41556 + depends on GRKERNSEC_SOCKET_SERVER
41557 +- default 1002
41558 ++ default 65534
41559 + help
41560 + Here you can choose the GID to disable server socket access for.
41561 + Remember to add the users you want server socket access disabled for to
41562
41563 Added: hardened/2.6/tags/2.6.25-14/4435_grsec-kconfig-gentoo.patch
41564 ===================================================================
41565 --- hardened/2.6/tags/2.6.25-14/4435_grsec-kconfig-gentoo.patch (rev 0)
41566 +++ hardened/2.6/tags/2.6.25-14/4435_grsec-kconfig-gentoo.patch 2009-01-21 00:09:46 UTC (rev 1481)
41567 @@ -0,0 +1,241 @@
41568 +From: Gordon Malm <gengor@g.o>
41569 +From: Kerin Millar <kerframil@×××××.com>
41570 +
41571 +Add Hardened Gentoo [server/workstation] predefined grsecurity
41572 +levels. They're designed to provide a comparitively high level of
41573 +security while remaining generally suitable for as great a majority
41574 +of the userbase as possible (particularly new users).
41575 +
41576 +Make Hardened Gentoo [workstation] predefined grsecurity level the
41577 +default. The Hardened Gentoo [server] level is more restrictive
41578 +and conflicts with some software and thus would be less suitable.
41579 +
41580 +The original version of this patch was conceived and created by:
41581 +Ned Ludd <solar@g.o>
41582 +
41583 +--- a/grsecurity/Kconfig
41584 ++++ b/grsecurity/Kconfig
41585 +@@ -20,7 +20,7 @@
41586 + choice
41587 + prompt "Security Level"
41588 + depends on GRKERNSEC
41589 +- default GRKERNSEC_CUSTOM
41590 ++ default GRKERNSEC_HARDENED_WORKSTATION
41591 +
41592 + config GRKERNSEC_LOW
41593 + bool "Low"
41594 +@@ -181,6 +181,214 @@
41595 + - Mount/unmount/remount logging
41596 + - Kernel symbol hiding
41597 + - Prevention of memory exhaustion-based exploits
41598 ++
41599 ++config GRKERNSEC_HARDENED_SERVER
41600 ++ bool "Hardened Gentoo [server]"
41601 ++ select GRKERNSEC_AUDIT_MOUNT
41602 ++ select GRKERNSEC_BRUTE
41603 ++ select GRKERNSEC_CHROOT
41604 ++ select GRKERNSEC_CHROOT_CAPS
41605 ++ select GRKERNSEC_CHROOT_CHDIR
41606 ++ select GRKERNSEC_CHROOT_CHMOD
41607 ++ select GRKERNSEC_CHROOT_DOUBLE
41608 ++ select GRKERNSEC_CHROOT_FCHDIR
41609 ++ select GRKERNSEC_CHROOT_FINDTASK
41610 ++ select GRKERNSEC_CHROOT_MKNOD
41611 ++ select GRKERNSEC_CHROOT_MOUNT
41612 ++ select GRKERNSEC_CHROOT_NICE
41613 ++ select GRKERNSEC_CHROOT_PIVOT
41614 ++ select GRKERNSEC_CHROOT_SHMAT
41615 ++ select GRKERNSEC_CHROOT_SYSCTL
41616 ++ select GRKERNSEC_CHROOT_UNIX
41617 ++ select GRKERNSEC_DMESG
41618 ++ select GRKERNSEC_EXECVE
41619 ++ select GRKERNSEC_FIFO
41620 ++ select GRKERNSEC_FORKFAIL
41621 ++ select GRKERNSEC_HIDESYM
41622 ++ select GRKERNSEC_IO if (X86)
41623 ++ select GRKERNSEC_KMEM
41624 ++ select GRKERNSEC_LINK
41625 ++ select GRKERNSEC_MODSTOP if (MODULES)
41626 ++ select GRKERNSEC_PROC
41627 ++ select GRKERNSEC_PROC_ADD
41628 ++ select GRKERNSEC_PROC_IPADDR
41629 ++ select GRKERNSEC_PROC_MEMMAP
41630 ++ select GRKERNSEC_PROC_USERGROUP
41631 ++ select GRKERNSEC_RANDNET
41632 ++ select GRKERNSEC_RESLOG
41633 ++ select GRKERNSEC_SIGNAL
41634 ++# select GRKERNSEC_SOCKET
41635 ++# select GRKERNSEC_SOCKET_SERVER
41636 ++ select GRKERNSEC_SYSCTL
41637 ++ select GRKERNSEC_SYSCTL_ON
41638 ++ select GRKERNSEC_TIME
41639 ++ select PAX
41640 ++ select PAX_ASLR
41641 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
41642 ++ select PAX_EI_PAX
41643 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41644 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
41645 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
41646 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
41647 ++ select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
41648 ++ select PAX_MEMORY_SANITIZE
41649 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO)
41650 ++ select PAX_MPROTECT if (!PPC64)
41651 ++ select PAX_HAVE_ACL_FLAGS
41652 ++ select PAX_NOELFRELOCS if (X86)
41653 ++ select PAX_NOEXEC
41654 ++ select PAX_PAGEEXEC
41655 ++ select PAX_PT_PAX_FLAGS
41656 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
41657 ++ select PAX_RANDMMAP
41658 ++ select PAX_RANDUSTACK
41659 ++ select PAX_SEGMEXEC if (X86_32)
41660 ++ select PAX_SYSCALL if (PPC32)
41661 ++ help
41662 ++ If you say Y here, a configuration will be used that is endorsed by
41663 ++ the Hardened Gentoo project. Therefore, many of the protections
41664 ++ made available by grsecurity and PaX will be enabled.
41665 ++
41666 ++ Hardened Gentoo's pre-defined security levels are designed to provide
41667 ++ a high level of security while minimizing incompatibilities with the
41668 ++ majority of available software. For further information, please
41669 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
41670 ++ well as the Hardened Gentoo Primer at
41671 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
41672 ++
41673 ++ This Hardened Gentoo [server] level is identical to the
41674 ++ Hardened Gentoo [workstation] level, but with the GRKERNSEC_IO,
41675 ++ PAX_KERNEXEC and PAX_NOELFRELOCS security features enabled.
41676 ++ Accordingly, this is the preferred security level if the system will
41677 ++ not be utilizing software incompatible with the aforementioned
41678 ++ grsecurity/PaX features.
41679 ++
41680 ++ You may wish to emerge paxctl, a utility which allows you to toggle
41681 ++ PaX features on problematic binaries on an individual basis. Note that
41682 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
41683 ++ Translated, this means that if you wish to toggle PaX features on
41684 ++ binaries provided by applications that are distributed only in binary
41685 ++ format (rather than being built locally from sources), you will need to
41686 ++ run paxctl -C on the binaries beforehand so as to inject the missing
41687 ++ headers.
41688 ++
41689 ++ When this level is selected, some options cannot be changed. However,
41690 ++ you may opt to fully customize the options that are selected by
41691 ++ choosing "Custom" in the Security Level menu. You may find it helpful
41692 ++ to inherit the options selected by the "Hardened Gentoo [server]"
41693 ++ security level as a starting point for further configuration. To
41694 ++ accomplish this, select this security level then exit the menuconfig
41695 ++ interface, saving changes when prompted. Then, run make menuconfig
41696 ++ again and select the "Custom" level.
41697 ++
41698 ++ Note that this security level probably should not be used if the
41699 ++ target system is a 32bit x86 virtualized guest. If you intend to run
41700 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
41701 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
41702 ++ impact on performance.
41703 ++
41704 ++config GRKERNSEC_HARDENED_WORKSTATION
41705 ++ bool "Hardened Gentoo [workstation]"
41706 ++ select GRKERNSEC_AUDIT_MOUNT
41707 ++ select GRKERNSEC_BRUTE
41708 ++ select GRKERNSEC_CHROOT
41709 ++ select GRKERNSEC_CHROOT_CAPS
41710 ++ select GRKERNSEC_CHROOT_CHDIR
41711 ++ select GRKERNSEC_CHROOT_CHMOD
41712 ++ select GRKERNSEC_CHROOT_DOUBLE
41713 ++ select GRKERNSEC_CHROOT_FCHDIR
41714 ++ select GRKERNSEC_CHROOT_FINDTASK
41715 ++ select GRKERNSEC_CHROOT_MKNOD
41716 ++ select GRKERNSEC_CHROOT_MOUNT
41717 ++ select GRKERNSEC_CHROOT_NICE
41718 ++ select GRKERNSEC_CHROOT_PIVOT
41719 ++ select GRKERNSEC_CHROOT_SHMAT
41720 ++ select GRKERNSEC_CHROOT_SYSCTL
41721 ++ select GRKERNSEC_CHROOT_UNIX
41722 ++ select GRKERNSEC_DMESG
41723 ++ select GRKERNSEC_EXECVE
41724 ++ select GRKERNSEC_FIFO
41725 ++ select GRKERNSEC_FORKFAIL
41726 ++ select GRKERNSEC_HIDESYM
41727 ++ select GRKERNSEC_KMEM
41728 ++ select GRKERNSEC_LINK
41729 ++ select GRKERNSEC_MODSTOP if (MODULES)
41730 ++ select GRKERNSEC_PROC
41731 ++ select GRKERNSEC_PROC_ADD
41732 ++ select GRKERNSEC_PROC_IPADDR
41733 ++ select GRKERNSEC_PROC_MEMMAP
41734 ++ select GRKERNSEC_PROC_USERGROUP
41735 ++ select GRKERNSEC_RANDNET
41736 ++ select GRKERNSEC_RESLOG
41737 ++ select GRKERNSEC_SIGNAL
41738 ++# select GRKERNSEC_SOCKET
41739 ++# select GRKERNSEC_SOCKET_SERVER
41740 ++ select GRKERNSEC_SYSCTL
41741 ++ select GRKERNSEC_SYSCTL_ON
41742 ++ select GRKERNSEC_TIME
41743 ++ select PAX
41744 ++ select PAX_ASLR
41745 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
41746 ++ select PAX_EI_PAX
41747 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41748 ++ select PAX_EMUSIGRT if (PARISC || PPC32)
41749 ++ select PAX_EMUTRAMP if (PARISC || PPC32)
41750 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
41751 ++ select PAX_MEMORY_SANITIZE
41752 ++ select PAX_MEMORY_UDEREF if (X86_32 && !COMPAT_VDSO)
41753 ++ select PAX_MPROTECT if (!PPC64)
41754 ++ select PAX_HAVE_ACL_FLAGS
41755 ++ select PAX_NOEXEC
41756 ++ select PAX_PAGEEXEC
41757 ++ select PAX_PT_PAX_FLAGS
41758 ++ select PAX_RANDKSTACK if (X86_32 && X86_TSC)
41759 ++ select PAX_RANDMMAP
41760 ++ select PAX_RANDUSTACK
41761 ++ select PAX_SEGMEXEC if (X86_32)
41762 ++ select PAX_SYSCALL if (PPC32)
41763 ++ help
41764 ++ If you say Y here, a configuration will be used that is endorsed by
41765 ++ the Hardened Gentoo project. Therefore, many of the protections
41766 ++ made available by grsecurity and PaX will be enabled.
41767 ++
41768 ++ Hardened Gentoo's pre-defined security levels are designed to provide
41769 ++ a high level of security while minimizing incompatibilities with the
41770 ++ majority of available software. For further information, please
41771 ++ view <http://www.grsecurity.net> and <http://pax.grsecurity.net> as
41772 ++ well as the Hardened Gentoo Primer at
41773 ++ <http://www.gentoo.org/proj/en/hardened/primer.xml>.
41774 ++
41775 ++ This Hardened Gentoo [workstation] level is designed for machines
41776 ++ which are intended to run software not compatible with the
41777 ++ GRKERNSEC_IO, PAX_KERNEXEC and PAX_NOELFRELOCS features of grsecurity.
41778 ++ Accordingly, this security level is suitable for use with the X server
41779 ++ "Xorg" and/or any system that will act as host OS to the virtualization
41780 ++ softwares vmware-server or virtualbox.
41781 ++
41782 ++ You may wish to emerge paxctl, a utility which allows you to toggle
41783 ++ PaX features on problematic binaries on an individual basis. Note that
41784 ++ this only works for ELF binaries that contain a PT_PAX_FLAGS header.
41785 ++ Translated, this means that if you wish to toggle PaX features on
41786 ++ binaries provided by applications that are distributed only in binary
41787 ++ format (rather than being built locally from sources), you will need to
41788 ++ run paxctl -C on the binaries beforehand so as to inject the missing
41789 ++ headers.
41790 ++
41791 ++ When this level is selected, some options cannot be changed. However,
41792 ++ you may opt to fully customize the options that are selected by
41793 ++ choosing "Custom" in the Security Level menu. You may find it helpful
41794 ++ to inherit the options selected by the "Hardened Gentoo [workstation]"
41795 ++ security level as a starting point for further configuration. To
41796 ++ accomplish this, select this security level then exit the menuconfig
41797 ++ interface, saving changes when prompted. Then, run make menuconfig
41798 ++ again and select the "Custom" level.
41799 ++
41800 ++ Note that this security level probably should not be used if the
41801 ++ target system is a 32bit x86 virtualized guest. If you intend to run
41802 ++ the kernel in a 32bit x86 virtualized guest you will likely need to
41803 ++ disable the PAX_MEMORY_UDEREF option in order to avoid an unacceptable
41804 ++ impact on performance.
41805 ++
41806 + config GRKERNSEC_CUSTOM
41807 + bool "Custom"
41808 + help
41809
41810 Added: hardened/2.6/tags/2.6.25-14/4440_selinux-avc_audit-log-curr_ip.patch
41811 ===================================================================
41812 --- hardened/2.6/tags/2.6.25-14/4440_selinux-avc_audit-log-curr_ip.patch (rev 0)
41813 +++ hardened/2.6/tags/2.6.25-14/4440_selinux-avc_audit-log-curr_ip.patch 2009-01-21 00:09:46 UTC (rev 1481)
41814 @@ -0,0 +1,65 @@
41815 +From: Gordon Malm <gengor@g.o>
41816 +
41817 +This is a reworked version of the original
41818 +*_selinux-avc_audit-log-curr_ip.patch carried in earlier releases of
41819 +hardened-sources.
41820 +
41821 +Dropping the patch, or simply fixing the #ifdef of the original patch
41822 +could break automated logging setups so this route was necessary.
41823 +
41824 +Suggestions for improving the help text are welcome.
41825 +
41826 +The original patch's description is still accurate and included below.
41827 +
41828 +---
41829 +Provides support for a new field ipaddr within the SELinux
41830 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
41831 +provided by grSecurity patch to be applied before.
41832 +
41833 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
41834 +---
41835 +
41836 +--- a/grsecurity/Kconfig
41837 ++++ b/grsecurity/Kconfig
41838 +@@ -1044,6 +1044,27 @@ endmenu
41839 + menu "Logging Options"
41840 + depends on GRKERNSEC
41841 +
41842 ++config GRKERNSEC_SELINUX_AVC_LOG_IPADDR
41843 ++ def_bool n
41844 ++ prompt "Add source IP address to SELinux AVC log messages"
41845 ++ depends on GRKERNSEC && SECURITY_SELINUX
41846 ++ help
41847 ++ If you say Y here, a new field "ipaddr=" will be added to many SELinux
41848 ++ AVC log messages. The value of this field in any given message
41849 ++ represents the source IP address of the remote machine/user that created
41850 ++ the offending process.
41851 ++
41852 ++ This information is sourced from task_struct->curr_ip provided by
41853 ++ grsecurity's GRKERNSEC top-level configuration option. One limitation
41854 ++ is that only IPv4 is supported.
41855 ++
41856 ++ In many instances SELinux AVC log messages already log a superior level
41857 ++ of information that also includes source port and destination ip/port.
41858 ++ Additionally, SELinux's AVC log code supports IPv6.
41859 ++
41860 ++ However, grsecurity's task_struct->curr_ip will sometimes (often?)
41861 ++ provide the offender's IP address where stock SELinux logging fails to.
41862 ++
41863 + config GRKERNSEC_FLOODTIME
41864 + int "Seconds in between log messages (minimum)"
41865 + default 10
41866 +--- a/security/selinux/avc.c
41867 ++++ b/security/selinux/avc.c
41868 +@@ -202,6 +202,11 @@ static void avc_dump_query(struct audit_
41869 + char *scontext;
41870 + u32 scontext_len;
41871 +
41872 ++#ifdef CONFIG_GRKERNSEC_SELINUX_AVC_LOG_IPADDR
41873 ++ if (current->signal->curr_ip)
41874 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
41875 ++#endif
41876 ++
41877 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
41878 + if (rc)
41879 + audit_log_format(ab, "ssid=%d", ssid);
41880
41881 Added: hardened/2.6/tags/2.6.25-14/4445_disable-compat_vdso.patch
41882 ===================================================================
41883 --- hardened/2.6/tags/2.6.25-14/4445_disable-compat_vdso.patch (rev 0)
41884 +++ hardened/2.6/tags/2.6.25-14/4445_disable-compat_vdso.patch 2009-01-21 00:09:46 UTC (rev 1481)
41885 @@ -0,0 +1,74 @@
41886 +From: Gordon Malm <gengor@g.o>
41887 +From: Kerin Millar <kerframil@×××××.com>
41888 +
41889 +COMPAT_VDSO is inappropriate for any modern Hardened Gentoo system. It
41890 +conflicts with various parts of PaX, crashing the system if enabled
41891 +while PaX's NOEXEC or UDEREF features are active. Moreover, it prevents
41892 +a number of important PaX options from appearing in the configuration
41893 +menu, including all PaX NOEXEC implementations. Unfortunately, the
41894 +reason for the disappearance of these PaX configuration options is
41895 +often far from obvious to inexperienced users.
41896 +
41897 +Therefore, we disable the COMPAT_VDSO menu entry entirely. However,
41898 +COMPAT_VDSO operation can still be enabled via bootparam and sysctl
41899 +interfaces. Consequently, we must also disable the ability to select
41900 +COMPAT_VDSO operation at boot or runtime. Here we patch the kernel so
41901 +that selecting COMPAT_VDSO operation at boot/runtime has no effect if
41902 +conflicting PaX options are enabled, leaving VDSO_ENABLED operation
41903 +intact.
41904 +
41905 +Closes bug: http://bugs.gentoo.org/show_bug.cgi?id=210138
41906 +
41907 +--- a/arch/x86/Kconfig
41908 ++++ b/arch/x86/Kconfig
41909 +@@ -1215,16 +1215,7 @@ config HOTPLUG_CPU
41910 +
41911 + config COMPAT_VDSO
41912 + def_bool n
41913 +- prompt "Compat VDSO support"
41914 + depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
41915 +- help
41916 +- Map the 32-bit VDSO to the predictable old-style address too.
41917 +- ---help---
41918 +- Say N here if you are running a sufficiently recent glibc
41919 +- version (2.3.3 or later), to remove the high-mapped
41920 +- VDSO mapping and to exclusively use the randomized VDSO.
41921 +-
41922 +- If unsure, say Y.
41923 +
41924 + endmenu
41925 +
41926 +--- a/arch/x86/vdso/vdso32-setup.c
41927 ++++ b/arch/x86/vdso/vdso32-setup.c
41928 +@@ -333,17 +333,21 @@ int arch_setup_additional_pages(struct l
41929 +
41930 + map_compat_vdso(compat);
41931 +
41932 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
41933 + if (compat)
41934 + addr = VDSO_HIGH_BASE;
41935 + else {
41936 ++#endif
41937 + addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
41938 + if (IS_ERR_VALUE(addr)) {
41939 + ret = addr;
41940 + goto up_fail;
41941 + }
41942 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
41943 + }
41944 +
41945 + if (compat_uses_vma || !compat) {
41946 ++#endif
41947 + /*
41948 + * MAYWRITE to allow gdb to COW and set breakpoints
41949 + *
41950 +@@ -361,7 +365,9 @@ int arch_setup_additional_pages(struct l
41951 +
41952 + if (ret)
41953 + goto up_fail;
41954 ++#if !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
41955 + }
41956 ++#endif
41957 +
41958 + current->mm->context.vdso = addr;
41959 + current_thread_info()->sysenter_return =
41960
41961 Added: hardened/2.6/tags/2.6.25-14/4450_pax-remove-read_implies_exec-for-pax-binaries.patch
41962 ===================================================================
41963 --- hardened/2.6/tags/2.6.25-14/4450_pax-remove-read_implies_exec-for-pax-binaries.patch (rev 0)
41964 +++ hardened/2.6/tags/2.6.25-14/4450_pax-remove-read_implies_exec-for-pax-binaries.patch 2009-01-21 00:09:46 UTC (rev 1481)
41965 @@ -0,0 +1,30 @@
41966 +From: Gordon Malm <gengor@g.o>
41967 +
41968 +Remove READ_IMPLIES_EXEC personality for PaX controlled binaries.
41969 +
41970 +This fixes problems that can occur when a binary has neither PT_PAX or
41971 +GNU_STACK ELF program headers on a system without an EI_PAX enabled kernel.
41972 +
41973 +See also: http://forums.grsecurity.net/viewtopic.php?f=3&t=2023
41974 +
41975 +Thanks to nixnut <nixnut@g.o> and Kerin Millar <kerframil@×××××.com>
41976 +for bringing it to my attention.
41977 +
41978 +This patch is present in upstream grsecurity patches as of
41979 +pax-linux-2.6.26.3-test19.patch.
41980 +
41981 +--- a/fs/binfmt_elf.c
41982 ++++ b/fs/binfmt_elf.c
41983 +@@ -993,9 +993,10 @@ static int load_elf_binary(struct linux_
41984 + SET_PERSONALITY(loc->elf_ex, 0);
41985 +
41986 + #if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
41987 +- if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
41988 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
41989 + executable_stack = EXSTACK_DISABLE_X;
41990 +- else
41991 ++ current->personality &= ~READ_IMPLIES_EXEC;
41992 ++ } else
41993 + #endif
41994 +
41995 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
41996
41997 Added: hardened/2.6/tags/2.6.25-14/4455_pax-fix-uvesafb-compile-and-misc.patch
41998 ===================================================================
41999 --- hardened/2.6/tags/2.6.25-14/4455_pax-fix-uvesafb-compile-and-misc.patch (rev 0)
42000 +++ hardened/2.6/tags/2.6.25-14/4455_pax-fix-uvesafb-compile-and-misc.patch 2009-01-21 00:09:46 UTC (rev 1481)
42001 @@ -0,0 +1,112 @@
42002 +From: Gordon Malm <gengor@g.o>
42003 +
42004 +Fix compilation and miscellaneous other problems in uvesafb.
42005 +
42006 +Fixes bug #245427.
42007 +
42008 +More info @ http://forums.grsecurity.net/viewtopic.php?f=1&t=2016
42009 +
42010 +This patch is present in upstream grsecurity patches as of
42011 +pax-linux-2.6.26-test7.patch.
42012 +
42013 +--- a/drivers/video/uvesafb.c
42014 ++++ b/drivers/video/uvesafb.c
42015 +@@ -561,25 +561,25 @@ static int __devinit uvesafb_vbe_getpmi(
42016 + {
42017 + int i, err;
42018 +
42019 +-#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42020 +- u8 *pmi_code;
42021 +- unsigned long cr0;
42022 +-#endif
42023 +-
42024 + uvesafb_reset(task);
42025 + task->t.regs.eax = 0x4f0a;
42026 + task->t.regs.ebx = 0x0;
42027 + err = uvesafb_exec(task);
42028 +
42029 +- par->pmi_setpal = par->ypan = 0;
42030 +- if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000)
42031 +- return 0;
42032 ++ if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
42033 ++ par->pmi_setpal = par->ypan = 0;
42034 ++ } else {
42035 +
42036 +-#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42037 +- pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
42038 +- if (pmi_code) {
42039 +-#elif !defined(CONFIG_PAX_KERNEXEC)
42040 +- if (1) {
42041 ++#ifdef CONFIG_PAX_KERNEXEC
42042 ++#ifdef CONFIG_MODULES
42043 ++ unsigned long cr0;
42044 ++
42045 ++ par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
42046 ++#endif
42047 ++ if (!par->pmi_code) {
42048 ++ par->pmi_setpal = par->ypan = 0;
42049 ++ return 0;
42050 ++ }
42051 + #endif
42052 +
42053 + par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
42054 +@@ -587,18 +587,14 @@ static int __devinit uvesafb_vbe_getpmi(
42055 +
42056 + #if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42057 + pax_open_kernel(cr0);
42058 +- memcpy(pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
42059 ++ memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
42060 + pax_close_kernel(cr0);
42061 +-#else
42062 +- pmi_code = par->pmi_base;
42063 +-#endif
42064 +-
42065 +- par->pmi_start = pmi_code + par->pmi_base[1];
42066 +- par->pmi_pal = pmi_code + par->pmi_base[2];
42067 +
42068 +-#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42069 +- par->pmi_start = ktva_ktla(par->pmi_start);
42070 +- par->pmi_pal = ktva_ktla(par->pmi_pal);
42071 ++ par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
42072 ++ par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
42073 ++#else
42074 ++ par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
42075 ++ par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
42076 + #endif
42077 +
42078 + printk(KERN_INFO "uvesafb: protected mode interface info at "
42079 +@@ -1855,6 +1851,11 @@ out:
42080 + if (par->vbe_modes)
42081 + kfree(par->vbe_modes);
42082 +
42083 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42084 ++ if (par->pmi_code)
42085 ++ module_free_exec(NULL, par->pmi_code);
42086 ++#endif
42087 ++
42088 + framebuffer_release(info);
42089 + return err;
42090 + }
42091 +@@ -1881,6 +1882,12 @@ static int uvesafb_remove(struct platfor
42092 + kfree(par->vbe_state_orig);
42093 + if (par->vbe_state_saved)
42094 + kfree(par->vbe_state_saved);
42095 ++
42096 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
42097 ++ if (par->pmi_code)
42098 ++ module_free_exec(NULL, par->pmi_code);
42099 ++#endif
42100 ++
42101 + }
42102 +
42103 + framebuffer_release(info);
42104 +--- a/include/video/uvesafb.h
42105 ++++ b/include/video/uvesafb.h
42106 +@@ -175,6 +175,7 @@ struct uvesafb_par {
42107 + u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
42108 + u8 pmi_setpal; /* PMI for palette changes */
42109 + u16 *pmi_base; /* protected mode interface location */
42110 ++ u8 *pmi_code; /* protected mode code location */
42111 + void *pmi_start;
42112 + void *pmi_pal;
42113 + u8 *vbe_state_orig; /*
42114
42115 Added: hardened/2.6/tags/2.6.25-14/4460_pax-fix-mmap-BUG_ON-task-size-check.patch
42116 ===================================================================
42117 --- hardened/2.6/tags/2.6.25-14/4460_pax-fix-mmap-BUG_ON-task-size-check.patch (rev 0)
42118 +++ hardened/2.6/tags/2.6.25-14/4460_pax-fix-mmap-BUG_ON-task-size-check.patch 2009-01-21 00:09:46 UTC (rev 1481)
42119 @@ -0,0 +1,22 @@
42120 +From: Gordon Malm <gengor@g.o>
42121 +
42122 +Fix incorrect vma task size check under SEGMEXEC.
42123 +
42124 +Fixes bug #246607.
42125 +
42126 +Thanks to Hugo Mildenberger for reporting and PaX Team for the fix.
42127 +
42128 +This patch is present in upstream grsecurity patches as of
42129 +pax-linux-2.6.27.7-test22.patch.
42130 +
42131 +--- a/mm/mmap.c
42132 ++++ b/mm/mmap.c
42133 +@@ -1703,7 +1703,7 @@ struct vm_area_struct *pax_find_mirror_v
42134 + BUG_ON(vma->vm_mirror);
42135 + return NULL;
42136 + }
42137 +- BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
42138 ++ BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
42139 + vma_m = vma->vm_mirror;
42140 + BUG_ON(!vma_m || vma_m->vm_mirror != vma);
42141 + BUG_ON(vma->vm_file != vma_m->vm_file);