Gentoo Archives: gentoo-commits

From: "Christian Heim (phreak)" <phreak@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] hardened r95 - in hardened-sources/2.6/tags: . 2.6.23-5
Date: Wed, 30 Apr 2008 11:45:06
Message-Id: E1JrAg5-0001GE-R8@stork.gentoo.org
1 Author: phreak
2 Date: 2008-04-30 11:40:48 +0000 (Wed, 30 Apr 2008)
3 New Revision: 95
4
5 Added:
6 hardened-sources/2.6/tags/2.6.23-5/
7 hardened-sources/2.6/tags/2.6.23-5/4105_dm-bbr.patch
8 hardened-sources/2.6/tags/2.6.23-5/4300_squashfs-3.2-r2.patch
9 hardened-sources/2.6/tags/2.6.23-5/4405_alpha-sysctl-uac.patch
10 hardened-sources/2.6/tags/2.6.23-5/4450_grsec-2.1.11-2.6.23.15-20080210.patch
11 hardened-sources/2.6/tags/2.6.23-5/4455_grsec-2.1.10-mute-warnings.patch
12 hardened-sources/2.6/tags/2.6.23-5/4460_grsec-2.1.10-pax_curr_ip-fixes.patch
13 hardened-sources/2.6/tags/2.6.23-5/4465_grsec-kconfig-gentoo.patch
14 hardened-sources/2.6/tags/2.6.23-5/4470_selinux-avc_audit-log-curr_ip.patch
15 hardened-sources/2.6/tags/2.6.23-5/4475_compat_vdso-defconfig.patch
16 hardened-sources/2.6/tags/2.6.23-5/4480_x86_64-bogus-acpi-symbols-defconfig.patch
17 Log:
18 Importing patchset for 2.6.23-5 (from hardened-patches-2.6.23-5.extras.tar.bz2).
19
20 Added: hardened-sources/2.6/tags/2.6.23-5/4105_dm-bbr.patch
21 ===================================================================
22 --- hardened-sources/2.6/tags/2.6.23-5/4105_dm-bbr.patch (rev 0)
23 +++ hardened-sources/2.6/tags/2.6.23-5/4105_dm-bbr.patch 2008-04-30 11:40:48 UTC (rev 95)
24 @@ -0,0 +1,1181 @@
25 +BBR Target, updated by dsd@g.o
26 +
27 +Incomplete changelog:
28 + 2007/07/08: updated for new API in 2.6.22
29 +
30 +--- a/drivers/md/Kconfig
31 ++++ b/drivers/md/Kconfig
32 +@@ -276,4 +276,15 @@ config DM_DELAY
33 +
34 + If unsure, say N.
35 +
36 ++config BLK_DEV_DM_BBR
37 ++ tristate "Bad Block Relocation Device Target (EXPERIMENTAL)"
38 ++ depends on BLK_DEV_DM && EXPERIMENTAL
39 ++ ---help---
40 ++ Support for devices with software-based bad-block-relocation.
41 ++
42 ++ To compile this as a module, choose M here: the module will be
43 ++ called dm-bbr.
44 ++
45 ++ If unsure, say N.
46 ++
47 + endif # MD
48 +--- a/drivers/md/Makefile
49 ++++ b/drivers/md/Makefile
50 +@@ -39,6 +39,7 @@ obj-$(CONFIG_DM_MULTIPATH_RDAC) += dm-rd
51 + obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o
52 + obj-$(CONFIG_DM_MIRROR) += dm-mirror.o
53 + obj-$(CONFIG_DM_ZERO) += dm-zero.o
54 ++obj-$(CONFIG_BLK_DEV_DM_BBR) += dm-bbr.o
55 +
56 + quiet_cmd_unroll = UNROLL $@
57 + cmd_unroll = $(PERL) $(srctree)/$(src)/unroll.pl $(UNROLL) \
58 +--- /dev/null
59 ++++ b/drivers/md/dm-bbr.c
60 +@@ -0,0 +1,1012 @@
61 ++/*
62 ++ * (C) Copyright IBM Corp. 2002, 2004
63 ++ *
64 ++ * This program is free software; you can redistribute it and/or modify
65 ++ * it under the terms of the GNU General Public License as published by
66 ++ * the Free Software Foundation; either version 2 of the License, or
67 ++ * (at your option) any later version.
68 ++ *
69 ++ * This program is distributed in the hope that it will be useful,
70 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
71 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
72 ++ * the GNU General Public License for more details.
73 ++ *
74 ++ * You should have received a copy of the GNU General Public License
75 ++ * along with this program; if not, write to the Free Software
76 ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
77 ++ *
78 ++ * linux/drivers/md/dm-bbr.c
79 ++ *
80 ++ * Bad-block-relocation (BBR) target for device-mapper.
81 ++ *
82 ++ * The BBR target is designed to remap I/O write failures to another safe
83 ++ * location on disk. Note that most disk drives have BBR built into them,
84 ++ * this means that our software BBR will be only activated when all hardware
85 ++ * BBR replacement sectors have been used.
86 ++ */
87 ++
88 ++#include <linux/module.h>
89 ++#include <linux/init.h>
90 ++#include <linux/bio.h>
91 ++#include <linux/spinlock.h>
92 ++#include <linux/slab.h>
93 ++#include <linux/mempool.h>
94 ++#include <linux/workqueue.h>
95 ++#include <linux/vmalloc.h>
96 ++
97 ++#include "dm.h"
98 ++#include "dm-bio-list.h"
99 ++#include "dm-bio-record.h"
100 ++#include "dm-bbr.h"
101 ++#include "dm-io.h"
102 ++
103 ++#define DM_MSG_PREFIX "bbr"
104 ++#define SECTOR_SIZE (1 << SECTOR_SHIFT)
105 ++
106 ++static struct workqueue_struct *dm_bbr_wq = NULL;
107 ++static void bbr_remap_handler(struct work_struct *work);
108 ++static struct kmem_cache *bbr_remap_cache;
109 ++static struct kmem_cache *bbr_io_cache;
110 ++static mempool_t *bbr_io_pool;
111 ++
112 ++/**
113 ++ * bbr_binary_tree_destroy
114 ++ *
115 ++ * Destroy the binary tree.
116 ++ **/
117 ++static void bbr_binary_tree_destroy(struct bbr_runtime_remap *root)
118 ++{
119 ++ struct bbr_runtime_remap **link = NULL;
120 ++ struct bbr_runtime_remap *node = root;
121 ++
122 ++ while (node) {
123 ++ if (node->left) {
124 ++ link = &node->left;
125 ++ node = node->left;
126 ++ continue;
127 ++ }
128 ++ if (node->right) {
129 ++ link = &node->right;
130 ++ node = node->right;
131 ++ continue;
132 ++ }
133 ++
134 ++ kmem_cache_free(bbr_remap_cache, node);
135 ++ if (node == root) {
136 ++ /* If root is deleted, we're done. */
137 ++ break;
138 ++ }
139 ++
140 ++ /* Back to root. */
141 ++ node = root;
142 ++ *link = NULL;
143 ++ }
144 ++}
145 ++
146 ++static void bbr_free_remap(struct bbr_private *bbr_id)
147 ++{
148 ++ spin_lock_irq(&bbr_id->remap_root_lock);
149 ++ bbr_binary_tree_destroy(bbr_id->remap_root);
150 ++ bbr_id->remap_root = NULL;
151 ++ spin_unlock_irq(&bbr_id->remap_root_lock);
152 ++}
153 ++
154 ++static struct bbr_private *bbr_alloc_private(void)
155 ++{
156 ++ struct bbr_private *bbr_id;
157 ++
158 ++ bbr_id = kzalloc(sizeof(*bbr_id), GFP_KERNEL);
159 ++ if (bbr_id == NULL)
160 ++ return NULL;
161 ++
162 ++ INIT_WORK(&bbr_id->remap_work, bbr_remap_handler);
163 ++ spin_lock_init(&bbr_id->remap_root_lock);
164 ++ spin_lock_init(&bbr_id->remap_ios_lock);
165 ++ bbr_id->in_use_replacement_blks = (atomic_t) ATOMIC_INIT(0);
166 ++
167 ++ return bbr_id;
168 ++}
169 ++
170 ++static void bbr_free_private(struct bbr_private *bbr_id)
171 ++{
172 ++ vfree(bbr_id->bbr_table);
173 ++ bbr_free_remap(bbr_id);
174 ++ kfree(bbr_id);
175 ++}
176 ++
177 ++static u32 crc_table[256];
178 ++static u32 crc_table_built = 0;
179 ++
180 ++static void build_crc_table(void)
181 ++{
182 ++ u32 i, j, crc;
183 ++
184 ++ for (i = 0; i <= 255; i++) {
185 ++ crc = i;
186 ++ for (j = 8; j > 0; j--) {
187 ++ if (crc & 1)
188 ++ crc = (crc >> 1) ^ CRC_POLYNOMIAL;
189 ++ else
190 ++ crc >>= 1;
191 ++ }
192 ++ crc_table[i] = crc;
193 ++ }
194 ++ crc_table_built = 1;
195 ++}
196 ++
197 ++static u32 calculate_crc(u32 crc, void *buffer, u32 buffersize)
198 ++{
199 ++ unsigned char *current_byte;
200 ++ u32 temp1, temp2, i;
201 ++
202 ++ current_byte = (unsigned char *) buffer;
203 ++ /* Make sure the crc table is available */
204 ++ if (!crc_table_built)
205 ++ build_crc_table();
206 ++ /* Process each byte in the buffer. */
207 ++ for (i = 0; i < buffersize; i++) {
208 ++ temp1 = (crc >> 8) & 0x00FFFFFF;
209 ++ temp2 = crc_table[(crc ^ (u32) * current_byte) &
210 ++ (u32) 0xff];
211 ++ current_byte++;
212 ++ crc = temp1 ^ temp2;
213 ++ }
214 ++ return crc;
215 ++}
216 ++
217 ++/**
218 ++ * le_bbr_table_sector_to_cpu
219 ++ *
220 ++ * Convert bbr meta data from on-disk (LE) format
221 ++ * to the native cpu endian format.
222 ++ **/
223 ++static void le_bbr_table_sector_to_cpu(struct bbr_table *p)
224 ++{
225 ++ int i;
226 ++ p->signature = le32_to_cpup(&p->signature);
227 ++ p->crc = le32_to_cpup(&p->crc);
228 ++ p->sequence_number = le32_to_cpup(&p->sequence_number);
229 ++ p->in_use_cnt = le32_to_cpup(&p->in_use_cnt);
230 ++ for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) {
231 ++ p->entries[i].bad_sect =
232 ++ le64_to_cpup(&p->entries[i].bad_sect);
233 ++ p->entries[i].replacement_sect =
234 ++ le64_to_cpup(&p->entries[i].replacement_sect);
235 ++ }
236 ++}
237 ++
238 ++/**
239 ++ * cpu_bbr_table_sector_to_le
240 ++ *
241 ++ * Convert bbr meta data from cpu endian format to on-disk (LE) format
242 ++ **/
243 ++static void cpu_bbr_table_sector_to_le(struct bbr_table *p,
244 ++ struct bbr_table *le)
245 ++{
246 ++ int i;
247 ++ le->signature = cpu_to_le32p(&p->signature);
248 ++ le->crc = cpu_to_le32p(&p->crc);
249 ++ le->sequence_number = cpu_to_le32p(&p->sequence_number);
250 ++ le->in_use_cnt = cpu_to_le32p(&p->in_use_cnt);
251 ++ for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) {
252 ++ le->entries[i].bad_sect =
253 ++ cpu_to_le64p(&p->entries[i].bad_sect);
254 ++ le->entries[i].replacement_sect =
255 ++ cpu_to_le64p(&p->entries[i].replacement_sect);
256 ++ }
257 ++}
258 ++
259 ++/**
260 ++ * validate_bbr_table_sector
261 ++ *
262 ++ * Check the specified BBR table sector for a valid signature and CRC. If it's
263 ++ * valid, endian-convert the table sector.
264 ++ **/
265 ++static int validate_bbr_table_sector(struct bbr_table *p)
266 ++{
267 ++ int org_crc, final_crc;
268 ++
269 ++ if (le32_to_cpup(&p->signature) != BBR_TABLE_SIGNATURE) {
270 ++ DMERR("BBR table signature doesn't match!");
271 ++ DMERR("Found 0x%x. Expecting 0x%x",
272 ++ le32_to_cpup(&p->signature), BBR_TABLE_SIGNATURE);
273 ++ return -EINVAL;
274 ++ }
275 ++
276 ++ if (!p->crc) {
277 ++ DMERR("BBR table sector has no CRC!");
278 ++ return -EINVAL;
279 ++ }
280 ++
281 ++ org_crc = le32_to_cpup(&p->crc);
282 ++ p->crc = 0;
283 ++ final_crc = calculate_crc(INITIAL_CRC, (void *)p, sizeof(*p));
284 ++ if (final_crc != org_crc) {
285 ++ DMERR("CRC failed!");
286 ++ DMERR("Found 0x%x. Expecting 0x%x",
287 ++ org_crc, final_crc);
288 ++ return -EINVAL;
289 ++ }
290 ++
291 ++ p->crc = cpu_to_le32p(&org_crc);
292 ++ le_bbr_table_sector_to_cpu(p);
293 ++
294 ++ return 0;
295 ++}
296 ++
297 ++/**
298 ++ * bbr_binary_tree_insert
299 ++ *
300 ++ * Insert a node into the binary tree.
301 ++ **/
302 ++static void bbr_binary_tree_insert(struct bbr_runtime_remap **root,
303 ++ struct bbr_runtime_remap *newnode)
304 ++{
305 ++ struct bbr_runtime_remap **node = root;
306 ++ while (node && *node) {
307 ++ node = (newnode->remap.bad_sect > (*node)->remap.bad_sect) ?
308 ++ &(*node)->right : &(*node)->left;
309 ++ }
310 ++
311 ++ newnode->left = newnode->right = NULL;
312 ++ *node = newnode;
313 ++}
314 ++
315 ++/**
316 ++ * bbr_binary_search
317 ++ *
318 ++ * Search for a node that contains bad_sect == lsn.
319 ++ **/
320 ++static struct bbr_runtime_remap *bbr_binary_search(
321 ++ struct bbr_runtime_remap *root,
322 ++ u64 lsn)
323 ++{
324 ++ struct bbr_runtime_remap *node = root;
325 ++ while (node) {
326 ++ if (node->remap.bad_sect == lsn)
327 ++ break;
328 ++
329 ++ node = (lsn > node->remap.bad_sect) ? node->right : node->left;
330 ++ }
331 ++ return node;
332 ++}
333 ++
334 ++/**
335 ++ * bbr_insert_remap_entry
336 ++ *
337 ++ * Create a new remap entry and add it to the binary tree for this node.
338 ++ **/
339 ++static int bbr_insert_remap_entry(struct bbr_private *bbr_id,
340 ++ struct bbr_table_entry *new_bbr_entry)
341 ++{
342 ++ struct bbr_runtime_remap *newnode;
343 ++
344 ++ newnode = kmem_cache_alloc(bbr_remap_cache, GFP_NOIO);
345 ++ if (!newnode) {
346 ++ DMERR("Could not allocate from remap cache!");
347 ++ return -ENOMEM;
348 ++ }
349 ++ newnode->remap.bad_sect = new_bbr_entry->bad_sect;
350 ++ newnode->remap.replacement_sect = new_bbr_entry->replacement_sect;
351 ++ spin_lock_irq(&bbr_id->remap_root_lock);
352 ++ bbr_binary_tree_insert(&bbr_id->remap_root, newnode);
353 ++ spin_unlock_irq(&bbr_id->remap_root_lock);
354 ++ return 0;
355 ++}
356 ++
357 ++/**
358 ++ * bbr_table_to_remap_list
359 ++ *
360 ++ * The on-disk bbr table is sorted by the replacement sector LBA. In order to
361 ++ * improve run time performance, the in memory remap list must be sorted by
362 ++ * the bad sector LBA. This function is called at discovery time to initialize
363 ++ * the remap list. This function assumes that at least one copy of meta data
364 ++ * is valid.
365 ++ **/
366 ++static u32 bbr_table_to_remap_list(struct bbr_private *bbr_id)
367 ++{
368 ++ u32 in_use_blks = 0;
369 ++ int i, j;
370 ++ struct bbr_table *p;
371 ++
372 ++ for (i = 0, p = bbr_id->bbr_table;
373 ++ i < bbr_id->nr_sects_bbr_table;
374 ++ i++, p++) {
375 ++ if (!p->in_use_cnt)
376 ++ break;
377 ++
378 ++ in_use_blks += p->in_use_cnt;
379 ++ for (j = 0; j < p->in_use_cnt; j++)
380 ++ bbr_insert_remap_entry(bbr_id, &p->entries[j]);
381 ++ }
382 ++ if (in_use_blks) {
383 ++ char b[32];
384 ++ DMWARN("There are %u BBR entries for device %s",
385 ++ in_use_blks, format_dev_t(b, bbr_id->dev->bdev->bd_dev));
386 ++ }
387 ++
388 ++ return in_use_blks;
389 ++}
390 ++
391 ++/**
392 ++ * bbr_search_remap_entry
393 ++ *
394 ++ * Search remap entry for the specified sector. If found, return a pointer to
395 ++ * the table entry. Otherwise, return NULL.
396 ++ **/
397 ++static struct bbr_table_entry *bbr_search_remap_entry(
398 ++ struct bbr_private *bbr_id,
399 ++ u64 lsn)
400 ++{
401 ++ struct bbr_runtime_remap *p;
402 ++
403 ++ spin_lock_irq(&bbr_id->remap_root_lock);
404 ++ p = bbr_binary_search(bbr_id->remap_root, lsn);
405 ++ spin_unlock_irq(&bbr_id->remap_root_lock);
406 ++ return (p) ? &p->remap : NULL;
407 ++}
408 ++
409 ++/**
410 ++ * bbr_remap
411 ++ *
412 ++ * If *lsn is in the remap table, return TRUE and modify *lsn,
413 ++ * else, return FALSE.
414 ++ **/
415 ++static int bbr_remap(struct bbr_private *bbr_id,
416 ++ u64 *lsn)
417 ++{
418 ++ struct bbr_table_entry *e;
419 ++
420 ++ if (atomic_read(&bbr_id->in_use_replacement_blks)) {
421 ++ e = bbr_search_remap_entry(bbr_id, *lsn);
422 ++ if (e) {
423 ++ *lsn = e->replacement_sect;
424 ++ return 1;
425 ++ }
426 ++ }
427 ++ return 0;
428 ++}
429 ++
430 ++/**
431 ++ * bbr_remap_probe
432 ++ *
433 ++ * If any of the sectors in the range [lsn, lsn+nr_sects] are in the remap
434 ++ * table return TRUE, Else, return FALSE.
435 ++ **/
436 ++static int bbr_remap_probe(struct bbr_private *bbr_id,
437 ++ u64 lsn, u64 nr_sects)
438 ++{
439 ++ u64 tmp, cnt;
440 ++
441 ++ if (atomic_read(&bbr_id->in_use_replacement_blks)) {
442 ++ for (cnt = 0, tmp = lsn;
443 ++ cnt < nr_sects;
444 ++ cnt += bbr_id->blksize_in_sects, tmp = lsn + cnt) {
445 ++ if (bbr_remap(bbr_id,&tmp))
446 ++ return 1;
447 ++ }
448 ++ }
449 ++ return 0;
450 ++}
451 ++
452 ++static int rw_table(struct bbr_private *bbr_id, void *vma,
453 ++ struct io_region *ptr, int rw)
454 ++{
455 ++ bbr_id->vma_io_req.bi_rw = rw;
456 ++ bbr_id->vma_io_req.mem.ptr.vma = vma;
457 ++ bbr_id->vma_io_req.notify.fn = NULL;
458 ++
459 ++ return dm_io(&bbr_id->vma_io_req, 1, ptr, NULL);
460 ++}
461 ++
462 ++static int io_sync(struct bbr_private *bbr_id, struct page_list *pl,
463 ++ unsigned offset, struct io_region *ptr, int rw)
464 ++{
465 ++ bbr_id->page_io_req.bi_rw = rw;
466 ++ bbr_id->page_io_req.mem.ptr.pl = pl;
467 ++ bbr_id->page_io_req.mem.offset = offset;
468 ++ bbr_id->page_io_req.notify.fn = NULL;
469 ++
470 ++ return dm_io(&bbr_id->page_io_req, 1, ptr, NULL);
471 ++}
472 ++
473 ++/**
474 ++ * bbr_setup
475 ++ *
476 ++ * Read the remap tables from disk and set up the initial remap tree.
477 ++ **/
478 ++static int bbr_setup(struct bbr_private *bbr_id)
479 ++{
480 ++ struct bbr_table *table = bbr_id->bbr_table;
481 ++ struct io_region job;
482 ++ int i, rc = 0;
483 ++
484 ++ job.bdev = bbr_id->dev->bdev;
485 ++ job.count = 1;
486 ++
487 ++ /* Read and verify each BBR table sector individually. */
488 ++ for (i = 0; i < bbr_id->nr_sects_bbr_table; i++, table++) {
489 ++ job.sector = bbr_id->lba_table1 + i;
490 ++ rc = rw_table(bbr_id, table, &job, READ);
491 ++ if (rc && bbr_id->lba_table2) {
492 ++ job.sector = bbr_id->lba_table2 + i;
493 ++ rc = rw_table(bbr_id, table, &job, READ);
494 ++ }
495 ++ if (rc)
496 ++ goto out;
497 ++
498 ++ rc = validate_bbr_table_sector(table);
499 ++ if (rc)
500 ++ goto out;
501 ++ }
502 ++ atomic_set(&bbr_id->in_use_replacement_blks,
503 ++ bbr_table_to_remap_list(bbr_id));
504 ++
505 ++out:
506 ++ if (rc)
507 ++ DMERR("error during device setup: %d", rc);
508 ++ return rc;
509 ++}
510 ++
511 ++/**
512 ++ * bbr_io_remap_error
513 ++ * @bbr_id: Private data for the BBR node.
514 ++ * @rw: READ or WRITE.
515 ++ * @starting_lsn: Starting sector of request to remap.
516 ++ * @count: Number of sectors in the request.
517 ++ * @page: Page containing the data for the request.
518 ++ * @offset: Byte-offset of the data within the page.
519 ++ *
520 ++ * For the requested range, try to write each sector individually. For each
521 ++ * sector that fails, find the next available remap location and write the
522 ++ * data to that new location. Then update the table and write both copies
523 ++ * of the table to disk. Finally, update the in-memory mapping and do any
524 ++ * other necessary bookkeeping.
525 ++ **/
526 ++static int bbr_io_remap_error(struct bbr_private *bbr_id,
527 ++ int rw,
528 ++ u64 starting_lsn,
529 ++ u64 count,
530 ++ struct page *page,
531 ++ unsigned int offset)
532 ++{
533 ++ struct bbr_table *bbr_table;
534 ++ struct io_region job;
535 ++ struct page_list pl;
536 ++ unsigned long table_sector_index;
537 ++ unsigned long table_sector_offset;
538 ++ unsigned long index;
539 ++ u64 lsn, new_lsn;
540 ++ char b[32];
541 ++ int rc;
542 ++
543 ++ job.bdev = bbr_id->dev->bdev;
544 ++ job.count = 1;
545 ++ pl.page = page;
546 ++ pl.next = NULL;
547 ++
548 ++ /* For each sector in the request. */
549 ++ for (lsn = 0; lsn < count; lsn++, offset += SECTOR_SIZE) {
550 ++ job.sector = starting_lsn + lsn;
551 ++ rc = io_sync(bbr_id, &pl, offset, &job, rw);
552 ++ while (rc) {
553 ++ /* Find the next available relocation sector. */
554 ++ new_lsn = atomic_read(&bbr_id->in_use_replacement_blks);
555 ++ if (new_lsn >= bbr_id->nr_replacement_blks) {
556 ++ /* No more replacement sectors available. */
557 ++ return -EIO;
558 ++ }
559 ++ new_lsn += bbr_id->start_replacement_sect;
560 ++
561 ++ /* Write the data to its new location. */
562 ++ DMWARN("device %s: Trying to remap bad sector "PFU64" to sector "PFU64,
563 ++ format_dev_t(b, bbr_id->dev->bdev->bd_dev),
564 ++ starting_lsn + lsn, new_lsn);
565 ++ job.sector = new_lsn;
566 ++ rc = io_sync(bbr_id, &pl, offset, &job, rw);
567 ++ if (rc) {
568 ++ /* This replacement sector is bad.
569 ++ * Try the next one.
570 ++ */
571 ++ DMERR("device %s: replacement sector "PFU64" is bad. Skipping.",
572 ++ format_dev_t(b, bbr_id->dev->bdev->bd_dev), new_lsn);
573 ++ atomic_inc(&bbr_id->in_use_replacement_blks);
574 ++ continue;
575 ++ }
576 ++
577 ++ /* Add this new entry to the on-disk table. */
578 ++ table_sector_index = new_lsn -
579 ++ bbr_id->start_replacement_sect;
580 ++ table_sector_offset = table_sector_index /
581 ++ BBR_ENTRIES_PER_SECT;
582 ++ index = table_sector_index % BBR_ENTRIES_PER_SECT;
583 ++
584 ++ bbr_table = &bbr_id->bbr_table[table_sector_offset];
585 ++ bbr_table->entries[index].bad_sect = starting_lsn + lsn;
586 ++ bbr_table->entries[index].replacement_sect = new_lsn;
587 ++ bbr_table->in_use_cnt++;
588 ++ bbr_table->sequence_number++;
589 ++ bbr_table->crc = 0;
590 ++ bbr_table->crc = calculate_crc(INITIAL_CRC,
591 ++ bbr_table,
592 ++ sizeof(struct bbr_table));
593 ++
594 ++ /* Write the table to disk. */
595 ++ cpu_bbr_table_sector_to_le(bbr_table, bbr_table);
596 ++ if (bbr_id->lba_table1) {
597 ++ job.sector = bbr_id->lba_table1 + table_sector_offset;
598 ++ rc = rw_table(bbr_id, bbr_table, &job, WRITE);
599 ++ }
600 ++ if (bbr_id->lba_table2) {
601 ++ job.sector = bbr_id->lba_table2 + table_sector_offset;
602 ++ rc |= rw_table(bbr_id, bbr_table, &job, WRITE);
603 ++ }
604 ++ le_bbr_table_sector_to_cpu(bbr_table);
605 ++
606 ++ if (rc) {
607 ++ /* Error writing one of the tables to disk. */
608 ++ DMERR("device %s: error updating BBR tables on disk.",
609 ++ format_dev_t(b, bbr_id->dev->bdev->bd_dev));
610 ++ return rc;
611 ++ }
612 ++
613 ++ /* Insert a new entry in the remapping binary-tree. */
614 ++ rc = bbr_insert_remap_entry(bbr_id,
615 ++ &bbr_table->entries[index]);
616 ++ if (rc) {
617 ++ DMERR("device %s: error adding new entry to remap tree.",
618 ++ format_dev_t(b, bbr_id->dev->bdev->bd_dev));
619 ++ return rc;
620 ++ }
621 ++
622 ++ atomic_inc(&bbr_id->in_use_replacement_blks);
623 ++ }
624 ++ }
625 ++
626 ++ return 0;
627 ++}
628 ++
629 ++/**
630 ++ * bbr_io_process_request
631 ++ *
632 ++ * For each sector in this request, check if the sector has already
633 ++ * been remapped. If so, process all previous sectors in the request,
634 ++ * followed by the remapped sector. Then reset the starting lsn and
635 ++ * count, and keep going with the rest of the request as if it were
636 ++ * a whole new request. If any of the sync_io's return an error,
637 ++ * call the remapper to relocate the bad sector(s).
638 ++ *
639 ++ * 2.5 Note: When switching over to bio's for the I/O path, we have made
640 ++ * the assumption that the I/O request described by the bio is one
641 ++ * virtually contiguous piece of memory (even though the bio vector
642 ++ * describes it using a series of physical page addresses).
643 ++ **/
644 ++static int bbr_io_process_request(struct bbr_private *bbr_id,
645 ++ struct bio *bio)
646 ++{
647 ++ struct io_region job;
648 ++ u64 starting_lsn = bio->bi_sector;
649 ++ u64 count, lsn, remapped_lsn;
650 ++ struct page_list pl;
651 ++ unsigned int offset;
652 ++ int i, rw = bio_data_dir(bio);
653 ++ int rc = 0;
654 ++
655 ++ job.bdev = bbr_id->dev->bdev;
656 ++ pl.next = NULL;
657 ++
658 ++ /* Each bio can contain multiple vectors, each with a different page.
659 ++ * Treat each vector as a separate request.
660 ++ */
661 ++ /* KMC: Is this the right way to walk the bvec list? */
662 ++ for (i = 0;
663 ++ i < bio->bi_vcnt;
664 ++ i++, bio->bi_idx++, starting_lsn += count) {
665 ++
666 ++ /* Bvec info: number of sectors, page,
667 ++ * and byte-offset within page.
668 ++ */
669 ++ count = bio_iovec(bio)->bv_len >> SECTOR_SHIFT;
670 ++ pl.page = bio_iovec(bio)->bv_page;
671 ++ offset = bio_iovec(bio)->bv_offset;
672 ++
673 ++ /* For each sector in this bvec, check if the sector has
674 ++ * already been remapped. If so, process all previous sectors
675 ++ * in this request, followed by the remapped sector. Then reset
676 ++ * the starting lsn and count and keep going with the rest of
677 ++ * the request as if it were a whole new request.
678 ++ */
679 ++ for (lsn = 0; lsn < count; lsn++) {
680 ++ remapped_lsn = starting_lsn + lsn;
681 ++ rc = bbr_remap(bbr_id, &remapped_lsn);
682 ++ if (!rc) {
683 ++ /* This sector is fine. */
684 ++ continue;
685 ++ }
686 ++
687 ++ /* Process all sectors in the request up to this one. */
688 ++ if (lsn > 0) {
689 ++ job.sector = starting_lsn;
690 ++ job.count = lsn;
691 ++ rc = io_sync(bbr_id, &pl, offset, &job, rw);
692 ++ if (rc) {
693 ++ /* If this I/O failed, then one of the
694 ++ * sectors in this request needs to be
695 ++ * relocated.
696 ++ */
697 ++ rc = bbr_io_remap_error(bbr_id, rw,
698 ++ starting_lsn,
699 ++ lsn, pl.page,
700 ++ offset);
701 ++ if (rc) {
702 ++ /* KMC: Return? Or continue to next bvec? */
703 ++ return rc;
704 ++ }
705 ++ }
706 ++ offset += (lsn << SECTOR_SHIFT);
707 ++ }
708 ++
709 ++ /* Process the remapped sector. */
710 ++ job.sector = remapped_lsn;
711 ++ job.count = 1;
712 ++ rc = io_sync(bbr_id, &pl, offset, &job, rw);
713 ++ if (rc) {
714 ++ /* BUGBUG - Need more processing if this caused
715 ++ * an error. If this I/O failed, then the
716 ++ * existing remap is now bad, and we need to
717 ++ * find a new remap. Can't use
718 ++ * bbr_io_remap_error(), because the existing
719 ++ * map entry needs to be changed, not added
720 ++ * again, and the original table entry also
721 ++ * needs to be changed.
722 ++ */
723 ++ return rc;
724 ++ }
725 ++
726 ++ starting_lsn += (lsn + 1);
727 ++ count -= (lsn + 1);
728 ++ lsn = -1;
729 ++ offset += SECTOR_SIZE;
730 ++ }
731 ++
732 ++ /* Check for any remaining sectors after the last split. This
733 ++ * could potentially be the whole request, but that should be a
734 ++ * rare case because requests should only be processed by the
735 ++ * thread if we know an error occurred or they contained one or
736 ++ * more remapped sectors.
737 ++ */
738 ++ if (count) {
739 ++ job.sector = starting_lsn;
740 ++ job.count = count;
741 ++ rc = io_sync(bbr_id, &pl, offset, &job, rw);
742 ++ if (rc) {
743 ++ /* If this I/O failed, then one of the sectors
744 ++ * in this request needs to be relocated.
745 ++ */
746 ++ rc = bbr_io_remap_error(bbr_id, rw, starting_lsn,
747 ++ count, pl.page, offset);
748 ++ if (rc) {
749 ++ /* KMC: Return? Or continue to next bvec? */
750 ++ return rc;
751 ++ }
752 ++ }
753 ++ }
754 ++ }
755 ++
756 ++ return 0;
757 ++}
758 ++
759 ++static void bbr_io_process_requests(struct bbr_private *bbr_id,
760 ++ struct bio *bio)
761 ++{
762 ++ struct bio *next;
763 ++ int rc;
764 ++
765 ++ while (bio) {
766 ++ next = bio->bi_next;
767 ++ bio->bi_next = NULL;
768 ++
769 ++ rc = bbr_io_process_request(bbr_id, bio);
770 ++
771 ++ bio_endio(bio, bio->bi_size, rc);
772 ++
773 ++ bio = next;
774 ++ }
775 ++}
776 ++
777 ++/**
778 ++ * bbr_remap_handler
779 ++ *
780 ++ * This is the handler for the bbr work-queue.
781 ++ *
782 ++ * I/O requests should only be sent to this handler if we know that:
783 ++ * a) the request contains at least one remapped sector.
784 ++ * or
785 ++ * b) the request caused an error on the normal I/O path.
786 ++ *
787 ++ * This function uses synchronous I/O, so sending a request to this
788 ++ * thread that doesn't need special processing will cause severe
789 ++ * performance degredation.
790 ++ **/
791 ++static void bbr_remap_handler(struct work_struct *work)
792 ++{
793 ++ struct bbr_private *bbr_id =
794 ++ container_of(work, struct bbr_private, remap_work);
795 ++ struct bio *bio;
796 ++ unsigned long flags;
797 ++
798 ++ spin_lock_irqsave(&bbr_id->remap_ios_lock, flags);
799 ++ bio = bio_list_get(&bbr_id->remap_ios);
800 ++ spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags);
801 ++
802 ++ bbr_io_process_requests(bbr_id, bio);
803 ++}
804 ++
805 ++/**
806 ++ * bbr_endio
807 ++ *
808 ++ * This is the callback for normal write requests. Check for an error
809 ++ * during the I/O, and send to the thread for processing if necessary.
810 ++ **/
811 ++static int bbr_endio(struct dm_target *ti, struct bio *bio,
812 ++ int error, union map_info *map_context)
813 ++{
814 ++ struct bbr_private *bbr_id = ti->private;
815 ++ struct dm_bio_details *bbr_io = map_context->ptr;
816 ++
817 ++ if (error && bbr_io) {
818 ++ unsigned long flags;
819 ++ char b[32];
820 ++
821 ++ dm_bio_restore(bbr_io, bio);
822 ++ map_context->ptr = NULL;
823 ++
824 ++ DMERR("device %s: I/O failure on sector %lu. "
825 ++ "Scheduling for retry.",
826 ++ format_dev_t(b, bbr_id->dev->bdev->bd_dev),
827 ++ (unsigned long)bio->bi_sector);
828 ++
829 ++ spin_lock_irqsave(&bbr_id->remap_ios_lock, flags);
830 ++ bio_list_add(&bbr_id->remap_ios, bio);
831 ++ spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags);
832 ++
833 ++ queue_work(dm_bbr_wq, &bbr_id->remap_work);
834 ++
835 ++ error = 1;
836 ++ }
837 ++
838 ++ if (bbr_io)
839 ++ mempool_free(bbr_io, bbr_io_pool);
840 ++
841 ++ return error;
842 ++}
843 ++
844 ++/**
845 ++ * Construct a bbr mapping
846 ++ **/
847 ++static int bbr_ctr(struct dm_target *ti, unsigned int argc, char **argv)
848 ++{
849 ++ struct bbr_private *bbr_id;
850 ++ unsigned long block_size;
851 ++ char *end;
852 ++ int rc = -EINVAL;
853 ++
854 ++ if (argc != 8) {
855 ++ ti->error = "dm-bbr requires exactly 8 arguments: "
856 ++ "device offset table1_lsn table2_lsn table_size start_replacement nr_replacement_blks block_size";
857 ++ goto out1;
858 ++ }
859 ++
860 ++ bbr_id = bbr_alloc_private();
861 ++ if (!bbr_id) {
862 ++ ti->error = "dm-bbr: Error allocating bbr private data.";
863 ++ goto out1;
864 ++ }
865 ++
866 ++ bbr_id->offset = simple_strtoull(argv[1], &end, 10);
867 ++ bbr_id->lba_table1 = simple_strtoull(argv[2], &end, 10);
868 ++ bbr_id->lba_table2 = simple_strtoull(argv[3], &end, 10);
869 ++ bbr_id->nr_sects_bbr_table = simple_strtoull(argv[4], &end, 10);
870 ++ bbr_id->start_replacement_sect = simple_strtoull(argv[5], &end, 10);
871 ++ bbr_id->nr_replacement_blks = simple_strtoull(argv[6], &end, 10);
872 ++ block_size = simple_strtoul(argv[7], &end, 10);
873 ++ bbr_id->blksize_in_sects = (block_size >> SECTOR_SHIFT);
874 ++
875 ++ bbr_id->vma_io_req.mem.type = DM_IO_VMA;
876 ++ bbr_id->vma_io_req.client = dm_io_client_create(1);
877 ++ if (IS_ERR(bbr_id->vma_io_req.client)) {
878 ++ rc = PTR_ERR(bbr_id->vma_io_req.client);
879 ++ DMWARN("couldn't allocate disk VMA io client");
880 ++ goto out2;
881 ++ }
882 ++
883 ++ bbr_id->page_io_req.mem.type = DM_IO_PAGE_LIST;
884 ++ bbr_id->page_io_req.client = dm_io_client_create(1);
885 ++ if (IS_ERR(bbr_id->page_io_req.client)) {
886 ++ rc = PTR_ERR(bbr_id->page_io_req.client);
887 ++ DMWARN("couldn't allocate pagelist io client");
888 ++ goto out3;
889 ++ }
890 ++
891 ++ bbr_id->bbr_table = vmalloc(bbr_id->nr_sects_bbr_table << SECTOR_SHIFT);
892 ++ if (!bbr_id->bbr_table) {
893 ++ ti->error = "dm-bbr: Error allocating bbr table.";
894 ++ goto out4;
895 ++ }
896 ++
897 ++ if (dm_get_device(ti, argv[0], 0, ti->len,
898 ++ dm_table_get_mode(ti->table), &bbr_id->dev)) {
899 ++ ti->error = "dm-bbr: Device lookup failed";
900 ++ goto out4;
901 ++ }
902 ++
903 ++ rc = bbr_setup(bbr_id);
904 ++ if (rc) {
905 ++ ti->error = "dm-bbr: Device setup failed";
906 ++ goto out5;
907 ++ }
908 ++
909 ++ ti->private = bbr_id;
910 ++ return 0;
911 ++
912 ++out5:
913 ++ dm_put_device(ti, bbr_id->dev);
914 ++out4:
915 ++ dm_io_client_destroy(bbr_id->page_io_req.client);
916 ++out3:
917 ++ dm_io_client_destroy(bbr_id->vma_io_req.client);
918 ++out2:
919 ++ bbr_free_private(bbr_id);
920 ++out1:
921 ++ return rc;
922 ++}
923 ++
924 ++static void bbr_dtr(struct dm_target *ti)
925 ++{
926 ++ struct bbr_private *bbr_id = ti->private;
927 ++
928 ++ dm_put_device(ti, bbr_id->dev);
929 ++ dm_io_client_destroy(bbr_id->page_io_req.client);
930 ++ dm_io_client_destroy(bbr_id->vma_io_req.client);
931 ++ bbr_free_private(bbr_id);
932 ++}
933 ++
934 ++static int bbr_map(struct dm_target *ti, struct bio *bio,
935 ++ union map_info *map_context)
936 ++{
937 ++ struct bbr_private *bbr_id = ti->private;
938 ++ struct dm_bio_details *bbr_io;
939 ++ unsigned long flags;
940 ++ int rc = 1;
941 ++
942 ++ bio->bi_sector += bbr_id->offset;
943 ++
944 ++ if (atomic_read(&bbr_id->in_use_replacement_blks) == 0 ||
945 ++ !bbr_remap_probe(bbr_id, bio->bi_sector, bio_sectors(bio))) {
946 ++ /* No existing remaps or this request doesn't
947 ++ * contain any remapped sectors.
948 ++ */
949 ++ bio->bi_bdev = bbr_id->dev->bdev;
950 ++
951 ++ bbr_io = mempool_alloc(bbr_io_pool, GFP_NOIO);
952 ++ dm_bio_record(bbr_io, bio);
953 ++ map_context->ptr = bbr_io;
954 ++ } else {
955 ++ /* This request has at least one remapped sector.
956 ++ * Give it to the work-queue for processing.
957 ++ */
958 ++ map_context->ptr = NULL;
959 ++ spin_lock_irqsave(&bbr_id->remap_ios_lock, flags);
960 ++ bio_list_add(&bbr_id->remap_ios, bio);
961 ++ spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags);
962 ++
963 ++ queue_work(dm_bbr_wq, &bbr_id->remap_work);
964 ++ rc = 0;
965 ++ }
966 ++
967 ++ return rc;
968 ++}
969 ++
970 ++static int bbr_status(struct dm_target *ti, status_type_t type,
971 ++ char *result, unsigned int maxlen)
972 ++{
973 ++ struct bbr_private *bbr_id = ti->private;
974 ++ char b[BDEVNAME_SIZE];
975 ++
976 ++ switch (type) {
977 ++ case STATUSTYPE_INFO:
978 ++ result[0] = '\0';
979 ++ break;
980 ++
981 ++ case STATUSTYPE_TABLE:
982 ++ snprintf(result, maxlen, "%s "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" %u",
983 ++ format_dev_t(b, bbr_id->dev->bdev->bd_dev),
984 ++ bbr_id->offset, bbr_id->lba_table1, bbr_id->lba_table2,
985 ++ bbr_id->nr_sects_bbr_table,
986 ++ bbr_id->start_replacement_sect,
987 ++ bbr_id->nr_replacement_blks,
988 ++ bbr_id->blksize_in_sects << SECTOR_SHIFT);
989 ++ break;
990 ++ }
991 ++ return 0;
992 ++}
993 ++
994 ++static struct target_type bbr_target = {
995 ++ .name = "bbr",
996 ++ .version= {1, 0, 1},
997 ++ .module = THIS_MODULE,
998 ++ .ctr = bbr_ctr,
999 ++ .dtr = bbr_dtr,
1000 ++ .map = bbr_map,
1001 ++ .end_io = bbr_endio,
1002 ++ .status = bbr_status,
1003 ++};
1004 ++
1005 ++int __init dm_bbr_init(void)
1006 ++{
1007 ++ int rc;
1008 ++
1009 ++ rc = dm_register_target(&bbr_target);
1010 ++ if (rc) {
1011 ++ DMERR("error registering target.");
1012 ++ goto err1;
1013 ++ }
1014 ++
1015 ++ bbr_remap_cache = kmem_cache_create("bbr-remap",
1016 ++ sizeof(struct bbr_runtime_remap),
1017 ++ 0, SLAB_HWCACHE_ALIGN, NULL);
1018 ++ if (!bbr_remap_cache) {
1019 ++ DMERR("error creating remap cache.");
1020 ++ rc = ENOMEM;
1021 ++ goto err2;
1022 ++ }
1023 ++
1024 ++ bbr_io_cache = kmem_cache_create("bbr-io", sizeof(struct dm_bio_details),
1025 ++ 0, SLAB_HWCACHE_ALIGN, NULL);
1026 ++ if (!bbr_io_cache) {
1027 ++ DMERR("error creating io cache.");
1028 ++ rc = ENOMEM;
1029 ++ goto err3;
1030 ++ }
1031 ++
1032 ++ bbr_io_pool = mempool_create(256, mempool_alloc_slab,
1033 ++ mempool_free_slab, bbr_io_cache);
1034 ++ if (!bbr_io_pool) {
1035 ++ DMERR("error creating io mempool.");
1036 ++ rc = ENOMEM;
1037 ++ goto err4;
1038 ++ }
1039 ++
1040 ++ dm_bbr_wq = create_workqueue("dm-bbr");
1041 ++ if (!dm_bbr_wq) {
1042 ++ DMERR("error creating work-queue.");
1043 ++ rc = ENOMEM;
1044 ++ goto err5;
1045 ++ }
1046 ++
1047 ++ return 0;
1048 ++
1049 ++err5:
1050 ++ mempool_destroy(bbr_io_pool);
1051 ++err4:
1052 ++ kmem_cache_destroy(bbr_io_cache);
1053 ++err3:
1054 ++ kmem_cache_destroy(bbr_remap_cache);
1055 ++err2:
1056 ++ dm_unregister_target(&bbr_target);
1057 ++err1:
1058 ++ return rc;
1059 ++}
1060 ++
1061 ++void __exit dm_bbr_exit(void)
1062 ++{
1063 ++ destroy_workqueue(dm_bbr_wq);
1064 ++ mempool_destroy(bbr_io_pool);
1065 ++ kmem_cache_destroy(bbr_io_cache);
1066 ++ kmem_cache_destroy(bbr_remap_cache);
1067 ++ dm_unregister_target(&bbr_target);
1068 ++}
1069 ++
1070 ++module_init(dm_bbr_init);
1071 ++module_exit(dm_bbr_exit);
1072 ++MODULE_LICENSE("GPL");
1073 +--- /dev/null
1074 ++++ b/drivers/md/dm-bbr.h
1075 +@@ -0,0 +1,130 @@
1076 ++/*
1077 ++ * (C) Copyright IBM Corp. 2002, 2004
1078 ++ *
1079 ++ * This program is free software; you can redistribute it and/or modify
1080 ++ * it under the terms of the GNU General Public License as published by
1081 ++ * the Free Software Foundation; either version 2 of the License, or
1082 ++ * (at your option) any later version.
1083 ++ *
1084 ++ * This program is distributed in the hope that it will be useful,
1085 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1086 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
1087 ++ * the GNU General Public License for more details.
1088 ++ *
1089 ++ * You should have received a copy of the GNU General Public License
1090 ++ * along with this program; if not, write to the Free Software
1091 ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1092 ++ *
1093 ++ * linux/drivers/md/dm-bbr.h
1094 ++ *
1095 ++ * Bad-block-relocation (BBR) target for device-mapper.
1096 ++ *
1097 ++ * The BBR target is designed to remap I/O write failures to another safe
1098 ++ * location on disk. Note that most disk drives have BBR built into them,
1099 ++ * this means that our software BBR will be only activated when all hardware
1100 ++ * BBR replacement sectors have been used.
1101 ++ */
1102 ++
1103 ++#include "dm-io.h"
1104 ++
1105 ++#define BBR_TABLE_SIGNATURE 0x42627254 /* BbrT */
1106 ++#define BBR_ENTRIES_PER_SECT 31
1107 ++#define INITIAL_CRC 0xFFFFFFFF
1108 ++#define CRC_POLYNOMIAL 0xEDB88320L
1109 ++
1110 ++/**
1111 ++ * Macros to cleanly print 64-bit numbers on both 32-bit and 64-bit machines.
1112 ++ * Use these in place of %Ld, %Lu, and %Lx.
1113 ++ **/
1114 ++#if BITS_PER_LONG > 32
1115 ++#define PFU64 "%llu"
1116 ++#else
1117 ++#define PFU64 "%Lu"
1118 ++#endif
1119 ++
1120 ++/**
1121 ++ * struct bbr_table_entry
1122 ++ * @bad_sect: LBA of bad location.
1123 ++ * @replacement_sect: LBA of new location.
1124 ++ *
1125 ++ * Structure to describe one BBR remap.
1126 ++ **/
1127 ++struct bbr_table_entry {
1128 ++ u64 bad_sect;
1129 ++ u64 replacement_sect;
1130 ++};
1131 ++
1132 ++/**
1133 ++ * struct bbr_table
1134 ++ * @signature: Signature on each BBR table sector.
1135 ++ * @crc: CRC for this table sector.
1136 ++ * @sequence_number: Used to resolve conflicts when primary and secondary
1137 ++ * tables do not match.
1138 ++ * @in_use_cnt: Number of in-use table entries.
1139 ++ * @entries: Actual table of remaps.
1140 ++ *
1141 ++ * Structure to describe each sector of the metadata table. Each sector in this
1142 ++ * table can describe 31 remapped sectors.
1143 ++ **/
1144 ++struct bbr_table {
1145 ++ u32 signature;
1146 ++ u32 crc;
1147 ++ u32 sequence_number;
1148 ++ u32 in_use_cnt;
1149 ++ struct bbr_table_entry entries[BBR_ENTRIES_PER_SECT];
1150 ++};
1151 ++
1152 ++/**
1153 ++ * struct bbr_runtime_remap
1154 ++ *
1155 ++ * Node in the binary tree used to keep track of remaps.
1156 ++ **/
1157 ++struct bbr_runtime_remap {
1158 ++ struct bbr_table_entry remap;
1159 ++ struct bbr_runtime_remap *left;
1160 ++ struct bbr_runtime_remap *right;
1161 ++};
1162 ++
1163 ++/**
1164 ++ * struct bbr_private
1165 ++ * @dev: Info about underlying device.
1166 ++ * @bbr_table: Copy of metadata table.
1167 ++ * @remap_root: Binary tree containing all remaps.
1168 ++ * @remap_root_lock: Lock for the binary tree.
1169 ++ * @remap_work: For adding work items to the work-queue.
1170 ++ * @remap_ios: List of I/Os for the work-queue to handle.
1171 ++ * @remap_ios_lock: Lock for the remap_ios list.
1172 ++ * @offset: LBA of data area.
1173 ++ * @lba_table1: LBA of primary BBR table.
1174 ++ * @lba_table2: LBA of secondary BBR table.
1175 ++ * @nr_sects_bbr_table: Size of each BBR table.
1176 ++ * @nr_replacement_blks: Number of replacement blocks.
1177 ++ * @start_replacement_sect: LBA of start of replacement blocks.
1178 ++ * @blksize_in_sects: Size of each block.
1179 ++ * @in_use_replacement_blks: Current number of remapped blocks.
1180 ++ *
1181 ++ * Private data for each BBR target.
1182 ++ **/
1183 ++struct bbr_private {
1184 ++ struct dm_dev *dev;
1185 ++ struct bbr_table *bbr_table;
1186 ++ struct bbr_runtime_remap *remap_root;
1187 ++ spinlock_t remap_root_lock;
1188 ++
1189 ++ struct dm_io_request vma_io_req;
1190 ++ struct dm_io_request page_io_req;
1191 ++
1192 ++ struct work_struct remap_work;
1193 ++ struct bio_list remap_ios;
1194 ++ spinlock_t remap_ios_lock;
1195 ++
1196 ++ u64 offset;
1197 ++ u64 lba_table1;
1198 ++ u64 lba_table2;
1199 ++ u64 nr_sects_bbr_table;
1200 ++ u64 start_replacement_sect;
1201 ++ u64 nr_replacement_blks;
1202 ++ u32 blksize_in_sects;
1203 ++ atomic_t in_use_replacement_blks;
1204 ++};
1205 ++
1206
1207 Added: hardened-sources/2.6/tags/2.6.23-5/4300_squashfs-3.2-r2.patch
1208 ===================================================================
1209 --- hardened-sources/2.6/tags/2.6.23-5/4300_squashfs-3.2-r2.patch (rev 0)
1210 +++ hardened-sources/2.6/tags/2.6.23-5/4300_squashfs-3.2-r2.patch 2008-04-30 11:40:48 UTC (rev 95)
1211 @@ -0,0 +1,4389 @@
1212 +---
1213 + fs/Kconfig | 65 +
1214 + fs/Makefile | 1
1215 + fs/squashfs/Makefile | 7
1216 + fs/squashfs/inode.c | 2327 +++++++++++++++++++++++++++++++++++++++++
1217 + fs/squashfs/squashfs.h | 87 +
1218 + fs/squashfs/squashfs2_0.c | 742 +++++++++++++
1219 + include/linux/squashfs_fs.h | 934 ++++++++++++++++
1220 + include/linux/squashfs_fs_i.h | 45
1221 + include/linux/squashfs_fs_sb.h | 74 +
1222 + init/do_mounts_rd.c | 16
1223 + 10 files changed, 4298 insertions(+)
1224 +
1225 +--- a/fs/Kconfig
1226 ++++ b/fs/Kconfig
1227 +@@ -1364,6 +1364,71 @@ config CRAMFS
1228 +
1229 + If unsure, say N.
1230 +
1231 ++config SQUASHFS
1232 ++ tristate "SquashFS 3.2 - Squashed file system support"
1233 ++ select ZLIB_INFLATE
1234 ++ help
1235 ++ Saying Y here includes support for SquashFS 3.2 (a Compressed Read-Only File
1236 ++ System). Squashfs is a highly compressed read-only filesystem for Linux.
1237 ++ It uses zlib compression to compress both files, inodes and directories.
1238 ++ Inodes in the system are very small and all blocks are packed to minimise
1239 ++ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
1240 ++ SquashFS 3.1 supports 64 bit filesystems and files (larger than 4GB), full
1241 ++ uid/gid information, hard links and timestamps.
1242 ++
1243 ++ Squashfs is intended for general read-only filesystem use, for archival
1244 ++ use (i.e. in cases where a .tar.gz file may be used), and in embedded
1245 ++ systems where low overhead is needed. Further information and filesystem tools
1246 ++ are available from http://squashfs.sourceforge.net.
1247 ++
1248 ++ If you want to compile this as a module ( = code which can be
1249 ++ inserted in and removed from the running kernel whenever you want),
1250 ++ say M here and read <file:Documentation/modules.txt>. The module
1251 ++ will be called squashfs. Note that the root file system (the one
1252 ++ containing the directory /) cannot be compiled as a module.
1253 ++
1254 ++ If unsure, say N.
1255 ++
1256 ++config SQUASHFS_EMBEDDED
1257 ++
1258 ++ bool "Additional options for memory-constrained systems"
1259 ++ depends on SQUASHFS
1260 ++ default n
1261 ++ help
1262 ++ Saying Y here allows you to specify cache sizes and how Squashfs
1263 ++ allocates memory. This is only intended for memory constrained
1264 ++ systems.
1265 ++
1266 ++ If unsure, say N.
1267 ++
1268 ++config SQUASHFS_FRAGMENT_CACHE_SIZE
1269 ++ int "Number of fragments cached" if SQUASHFS_EMBEDDED
1270 ++ depends on SQUASHFS
1271 ++ default "3"
1272 ++ help
1273 ++ By default SquashFS caches the last 3 fragments read from
1274 ++ the filesystem. Increasing this amount may mean SquashFS
1275 ++ has to re-read fragments less often from disk, at the expense
1276 ++ of extra system memory. Decreasing this amount will mean
1277 ++ SquashFS uses less memory at the expense of extra reads from disk.
1278 ++
1279 ++ Note there must be at least one cached fragment. Anything
1280 ++ much more than three will probably not make much difference.
1281 ++
1282 ++config SQUASHFS_VMALLOC
1283 ++ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
1284 ++ depends on SQUASHFS
1285 ++ default n
1286 ++ help
1287 ++ By default SquashFS uses kmalloc to obtain fragment cache memory.
1288 ++ Kmalloc memory is the standard kernel allocator, but it can fail
1289 ++ on memory constrained systems. Because of the way Vmalloc works,
1290 ++ Vmalloc can succeed when kmalloc fails. Specifying this option
1291 ++ will make SquashFS always use Vmalloc to allocate the
1292 ++ fragment cache memory.
1293 ++
1294 ++ If unsure, say N.
1295 ++
1296 + config VXFS_FS
1297 + tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
1298 + depends on BLOCK
1299 +--- a/fs/Makefile
1300 ++++ b/fs/Makefile
1301 +@@ -72,6 +72,7 @@ obj-$(CONFIG_JBD) += jbd/
1302 + obj-$(CONFIG_JBD2) += jbd2/
1303 + obj-$(CONFIG_EXT2_FS) += ext2/
1304 + obj-$(CONFIG_CRAMFS) += cramfs/
1305 ++obj-$(CONFIG_SQUASHFS) += squashfs/
1306 + obj-$(CONFIG_RAMFS) += ramfs/
1307 + obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
1308 + obj-$(CONFIG_CODA_FS) += coda/
1309 +--- /dev/null
1310 ++++ b/fs/squashfs/Makefile
1311 +@@ -0,0 +1,7 @@
1312 ++#
1313 ++# Makefile for the linux squashfs routines.
1314 ++#
1315 ++
1316 ++obj-$(CONFIG_SQUASHFS) += squashfs.o
1317 ++squashfs-y += inode.o
1318 ++squashfs-y += squashfs2_0.o
1319 +--- /dev/null
1320 ++++ b/fs/squashfs/inode.c
1321 +@@ -0,0 +1,2329 @@
1322 ++/*
1323 ++ * Squashfs - a compressed read only filesystem for Linux
1324 ++ *
1325 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
1326 ++ * Phillip Lougher <phillip@×××××××××××.uk>
1327 ++ *
1328 ++ * This program is free software; you can redistribute it and/or
1329 ++ * modify it under the terms of the GNU General Public License
1330 ++ * as published by the Free Software Foundation; either version 2,
1331 ++ * or (at your option) any later version.
1332 ++ *
1333 ++ * This program is distributed in the hope that it will be useful,
1334 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1335 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1336 ++ * GNU General Public License for more details.
1337 ++ *
1338 ++ * You should have received a copy of the GNU General Public License
1339 ++ * along with this program; if not, write to the Free Software
1340 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1341 ++ *
1342 ++ * inode.c
1343 ++ */
1344 ++
1345 ++#include <linux/squashfs_fs.h>
1346 ++#include <linux/module.h>
1347 ++#include <linux/zlib.h>
1348 ++#include <linux/exportfs.h>
1349 ++#include <linux/fs.h>
1350 ++#include <linux/squashfs_fs_sb.h>
1351 ++#include <linux/squashfs_fs_i.h>
1352 ++#include <linux/buffer_head.h>
1353 ++#include <linux/vfs.h>
1354 ++#include <linux/vmalloc.h>
1355 ++#include <linux/smp_lock.h>
1356 ++#include <linux/sched.h>
1357 ++
1358 ++#include "squashfs.h"
1359 ++
1360 ++static void vfs_read_inode(struct inode *i);
1361 ++static struct dentry *squashfs_get_parent(struct dentry *child);
1362 ++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode);
1363 ++static int squashfs_statfs(struct dentry *, struct kstatfs *);
1364 ++static int squashfs_symlink_readpage(struct file *file, struct page *page);
1365 ++static long long read_blocklist(struct inode *inode, int index,
1366 ++ int readahead_blks, char *block_list,
1367 ++ unsigned short **block_p, unsigned int *bsize);
1368 ++static int squashfs_readpage(struct file *file, struct page *page);
1369 ++static int squashfs_readpage4K(struct file *file, struct page *page);
1370 ++static int squashfs_readdir(struct file *, void *, filldir_t);
1371 ++static struct dentry *squashfs_lookup(struct inode *, struct dentry *,
1372 ++ struct nameidata *);
1373 ++static int squashfs_remount(struct super_block *s, int *flags, char *data);
1374 ++static void squashfs_put_super(struct super_block *);
1375 ++static int squashfs_get_sb(struct file_system_type *,int, const char *, void *,
1376 ++ struct vfsmount *);
1377 ++static struct inode *squashfs_alloc_inode(struct super_block *sb);
1378 ++static void squashfs_destroy_inode(struct inode *inode);
1379 ++static int init_inodecache(void);
1380 ++static void destroy_inodecache(void);
1381 ++
1382 ++static struct file_system_type squashfs_fs_type = {
1383 ++ .owner = THIS_MODULE,
1384 ++ .name = "squashfs",
1385 ++ .get_sb = squashfs_get_sb,
1386 ++ .kill_sb = kill_block_super,
1387 ++ .fs_flags = FS_REQUIRES_DEV
1388 ++};
1389 ++
1390 ++static const unsigned char squashfs_filetype_table[] = {
1391 ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
1392 ++};
1393 ++
1394 ++static struct super_operations squashfs_super_ops = {
1395 ++ .alloc_inode = squashfs_alloc_inode,
1396 ++ .destroy_inode = squashfs_destroy_inode,
1397 ++ .statfs = squashfs_statfs,
1398 ++ .put_super = squashfs_put_super,
1399 ++ .remount_fs = squashfs_remount
1400 ++};
1401 ++
1402 ++static struct super_operations squashfs_export_super_ops = {
1403 ++ .alloc_inode = squashfs_alloc_inode,
1404 ++ .destroy_inode = squashfs_destroy_inode,
1405 ++ .statfs = squashfs_statfs,
1406 ++ .put_super = squashfs_put_super,
1407 ++ .read_inode = vfs_read_inode
1408 ++};
1409 ++
1410 ++static struct export_operations squashfs_export_ops = {
1411 ++ .get_parent = squashfs_get_parent
1412 ++};
1413 ++
1414 ++SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = {
1415 ++ .readpage = squashfs_symlink_readpage
1416 ++};
1417 ++
1418 ++SQSH_EXTERN const struct address_space_operations squashfs_aops = {
1419 ++ .readpage = squashfs_readpage
1420 ++};
1421 ++
1422 ++SQSH_EXTERN const struct address_space_operations squashfs_aops_4K = {
1423 ++ .readpage = squashfs_readpage4K
1424 ++};
1425 ++
1426 ++static const struct file_operations squashfs_dir_ops = {
1427 ++ .read = generic_read_dir,
1428 ++ .readdir = squashfs_readdir
1429 ++};
1430 ++
1431 ++SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = {
1432 ++ .lookup = squashfs_lookup
1433 ++};
1434 ++
1435 ++
1436 ++static struct buffer_head *get_block_length(struct super_block *s,
1437 ++ int *cur_index, int *offset, int *c_byte)
1438 ++{
1439 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1440 ++ unsigned short temp;
1441 ++ struct buffer_head *bh;
1442 ++
1443 ++ if (!(bh = sb_bread(s, *cur_index)))
1444 ++ goto out;
1445 ++
1446 ++ if (msblk->devblksize - *offset == 1) {
1447 ++ if (msblk->swap)
1448 ++ ((unsigned char *) &temp)[1] = *((unsigned char *)
1449 ++ (bh->b_data + *offset));
1450 ++ else
1451 ++ ((unsigned char *) &temp)[0] = *((unsigned char *)
1452 ++ (bh->b_data + *offset));
1453 ++ brelse(bh);
1454 ++ if (!(bh = sb_bread(s, ++(*cur_index))))
1455 ++ goto out;
1456 ++ if (msblk->swap)
1457 ++ ((unsigned char *) &temp)[0] = *((unsigned char *)
1458 ++ bh->b_data);
1459 ++ else
1460 ++ ((unsigned char *) &temp)[1] = *((unsigned char *)
1461 ++ bh->b_data);
1462 ++ *c_byte = temp;
1463 ++ *offset = 1;
1464 ++ } else {
1465 ++ if (msblk->swap) {
1466 ++ ((unsigned char *) &temp)[1] = *((unsigned char *)
1467 ++ (bh->b_data + *offset));
1468 ++ ((unsigned char *) &temp)[0] = *((unsigned char *)
1469 ++ (bh->b_data + *offset + 1));
1470 ++ } else {
1471 ++ ((unsigned char *) &temp)[0] = *((unsigned char *)
1472 ++ (bh->b_data + *offset));
1473 ++ ((unsigned char *) &temp)[1] = *((unsigned char *)
1474 ++ (bh->b_data + *offset + 1));
1475 ++ }
1476 ++ *c_byte = temp;
1477 ++ *offset += 2;
1478 ++ }
1479 ++
1480 ++ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
1481 ++ if (*offset == msblk->devblksize) {
1482 ++ brelse(bh);
1483 ++ if (!(bh = sb_bread(s, ++(*cur_index))))
1484 ++ goto out;
1485 ++ *offset = 0;
1486 ++ }
1487 ++ if (*((unsigned char *) (bh->b_data + *offset)) !=
1488 ++ SQUASHFS_MARKER_BYTE) {
1489 ++ ERROR("Metadata block marker corrupt @ %x\n",
1490 ++ *cur_index);
1491 ++ brelse(bh);
1492 ++ goto out;
1493 ++ }
1494 ++ (*offset)++;
1495 ++ }
1496 ++ return bh;
1497 ++
1498 ++out:
1499 ++ return NULL;
1500 ++}
1501 ++
1502 ++
1503 ++SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer,
1504 ++ long long index, unsigned int length,
1505 ++ long long *next_index, int srclength)
1506 ++{
1507 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1508 ++ struct squashfs_super_block *sblk = &msblk->sblk;
1509 ++ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >>
1510 ++ msblk->devblksize_log2) + 2];
1511 ++ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
1512 ++ unsigned int cur_index = index >> msblk->devblksize_log2;
1513 ++ int bytes, avail_bytes, b = 0, k = 0;
1514 ++ unsigned int compressed;
1515 ++ unsigned int c_byte = length;
1516 ++
1517 ++ if (c_byte) {
1518 ++ bytes = msblk->devblksize - offset;
1519 ++ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
1520 ++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
1521 ++
1522 ++ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed
1523 ++ ? "" : "un", (unsigned int) c_byte, srclength);
1524 ++
1525 ++ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
1526 ++ goto read_failure;
1527 ++
1528 ++ if (!(bh[0] = sb_getblk(s, cur_index)))
1529 ++ goto block_release;
1530 ++
1531 ++ for (b = 1; bytes < c_byte; b++) {
1532 ++ if (!(bh[b] = sb_getblk(s, ++cur_index)))
1533 ++ goto block_release;
1534 ++ bytes += msblk->devblksize;
1535 ++ }
1536 ++ ll_rw_block(READ, b, bh);
1537 ++ } else {
1538 ++ if (index < 0 || (index + 2) > sblk->bytes_used)
1539 ++ goto read_failure;
1540 ++
1541 ++ if (!(bh[0] = get_block_length(s, &cur_index, &offset,
1542 ++ &c_byte)))
1543 ++ goto read_failure;
1544 ++
1545 ++ bytes = msblk->devblksize - offset;
1546 ++ compressed = SQUASHFS_COMPRESSED(c_byte);
1547 ++ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
1548 ++
1549 ++ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
1550 ++ ? "" : "un", (unsigned int) c_byte);
1551 ++
1552 ++ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
1553 ++ goto read_failure;
1554 ++
1555 ++ for (b = 1; bytes < c_byte; b++) {
1556 ++ if (!(bh[b] = sb_getblk(s, ++cur_index)))
1557 ++ goto block_release;
1558 ++ bytes += msblk->devblksize;
1559 ++ }
1560 ++ ll_rw_block(READ, b - 1, bh + 1);
1561 ++ }
1562 ++
1563 ++ if (compressed) {
1564 ++ int zlib_err = 0;
1565 ++
1566 ++ /*
1567 ++ * uncompress block
1568 ++ */
1569 ++
1570 ++ mutex_lock(&msblk->read_data_mutex);
1571 ++
1572 ++ msblk->stream.next_out = buffer;
1573 ++ msblk->stream.avail_out = srclength;
1574 ++
1575 ++ for (bytes = 0; k < b; k++) {
1576 ++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
1577 ++ msblk->devblksize - offset :
1578 ++ c_byte - bytes;
1579 ++ wait_on_buffer(bh[k]);
1580 ++ if (!buffer_uptodate(bh[k]))
1581 ++ goto release_mutex;
1582 ++
1583 ++ msblk->stream.next_in = bh[k]->b_data + offset;
1584 ++ msblk->stream.avail_in = avail_bytes;
1585 ++
1586 ++ if (k == 0) {
1587 ++ zlib_err = zlib_inflateInit(&msblk->stream);
1588 ++ if (zlib_err != Z_OK) {
1589 ++ ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n",
1590 ++ zlib_err, srclength);
1591 ++ goto release_mutex;
1592 ++ }
1593 ++
1594 ++ if (avail_bytes == 0) {
1595 ++ offset = 0;
1596 ++ brelse(bh[k]);
1597 ++ continue;
1598 ++ }
1599 ++ }
1600 ++
1601 ++ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
1602 ++ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
1603 ++ ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n",
1604 ++ zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out);
1605 ++ goto release_mutex;
1606 ++ }
1607 ++
1608 ++ bytes += avail_bytes;
1609 ++ offset = 0;
1610 ++ brelse(bh[k]);
1611 ++ }
1612 ++
1613 ++ if (zlib_err != Z_STREAM_END)
1614 ++ goto release_mutex;
1615 ++
1616 ++ zlib_err = zlib_inflateEnd(&msblk->stream);
1617 ++ if (zlib_err != Z_OK) {
1618 ++ ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n",
1619 ++ zlib_err, srclength);
1620 ++ goto release_mutex;
1621 ++ }
1622 ++ bytes = msblk->stream.total_out;
1623 ++ mutex_unlock(&msblk->read_data_mutex);
1624 ++ } else {
1625 ++ int i;
1626 ++
1627 ++ for(i = 0; i < b; i++) {
1628 ++ wait_on_buffer(bh[i]);
1629 ++ if(!buffer_uptodate(bh[i]))
1630 ++ goto block_release;
1631 ++ }
1632 ++
1633 ++ for (bytes = 0; k < b; k++) {
1634 ++ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
1635 ++ msblk->devblksize - offset :
1636 ++ c_byte - bytes;
1637 ++ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
1638 ++ bytes += avail_bytes;
1639 ++ offset = 0;
1640 ++ brelse(bh[k]);
1641 ++ }
1642 ++ }
1643 ++
1644 ++ if (next_index)
1645 ++ *next_index = index + c_byte + (length ? 0 :
1646 ++ (SQUASHFS_CHECK_DATA(msblk->sblk.flags)
1647 ++ ? 3 : 2));
1648 ++ return bytes;
1649 ++
1650 ++release_mutex:
1651 ++ mutex_unlock(&msblk->read_data_mutex);
1652 ++
1653 ++block_release:
1654 ++ for (; k < b; k++)
1655 ++ brelse(bh[k]);
1656 ++
1657 ++read_failure:
1658 ++ ERROR("sb_bread failed reading block 0x%x\n", cur_index);
1659 ++ return 0;
1660 ++}
1661 ++
1662 ++
1663 ++SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer,
1664 ++ long long block, unsigned int offset,
1665 ++ int length, long long *next_block,
1666 ++ unsigned int *next_offset)
1667 ++{
1668 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1669 ++ int n, i, bytes, return_length = length;
1670 ++ long long next_index;
1671 ++
1672 ++ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
1673 ++
1674 ++ while ( 1 ) {
1675 ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
1676 ++ if (msblk->block_cache[i].block == block)
1677 ++ break;
1678 ++
1679 ++ mutex_lock(&msblk->block_cache_mutex);
1680 ++
1681 ++ if (i == SQUASHFS_CACHED_BLKS) {
1682 ++ /* read inode header block */
1683 ++ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS;
1684 ++ n ; n --, i = (i + 1) %
1685 ++ SQUASHFS_CACHED_BLKS)
1686 ++ if (msblk->block_cache[i].block !=
1687 ++ SQUASHFS_USED_BLK)
1688 ++ break;
1689 ++
1690 ++ if (n == 0) {
1691 ++ wait_queue_t wait;
1692 ++
1693 ++ init_waitqueue_entry(&wait, current);
1694 ++ add_wait_queue(&msblk->waitq, &wait);
1695 ++ set_current_state(TASK_UNINTERRUPTIBLE);
1696 ++ mutex_unlock(&msblk->block_cache_mutex);
1697 ++ schedule();
1698 ++ set_current_state(TASK_RUNNING);
1699 ++ remove_wait_queue(&msblk->waitq, &wait);
1700 ++ continue;
1701 ++ }
1702 ++ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS;
1703 ++
1704 ++ if (msblk->block_cache[i].block ==
1705 ++ SQUASHFS_INVALID_BLK) {
1706 ++ if (!(msblk->block_cache[i].data =
1707 ++ kmalloc(SQUASHFS_METADATA_SIZE,
1708 ++ GFP_KERNEL))) {
1709 ++ ERROR("Failed to allocate cache"
1710 ++ "block\n");
1711 ++ mutex_unlock(&msblk->block_cache_mutex);
1712 ++ goto out;
1713 ++ }
1714 ++ }
1715 ++
1716 ++ msblk->block_cache[i].block = SQUASHFS_USED_BLK;
1717 ++ mutex_unlock(&msblk->block_cache_mutex);
1718 ++
1719 ++ msblk->block_cache[i].length = squashfs_read_data(s,
1720 ++ msblk->block_cache[i].data, block, 0, &next_index, SQUASHFS_METADATA_SIZE);
1721 ++ if (msblk->block_cache[i].length == 0) {
1722 ++ ERROR("Unable to read cache block [%llx:%x]\n",
1723 ++ block, offset);
1724 ++ mutex_lock(&msblk->block_cache_mutex);
1725 ++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
1726 ++ kfree(msblk->block_cache[i].data);
1727 ++ wake_up(&msblk->waitq);
1728 ++ mutex_unlock(&msblk->block_cache_mutex);
1729 ++ goto out;
1730 ++ }
1731 ++
1732 ++ mutex_lock(&msblk->block_cache_mutex);
1733 ++ wake_up(&msblk->waitq);
1734 ++ msblk->block_cache[i].block = block;
1735 ++ msblk->block_cache[i].next_index = next_index;
1736 ++ TRACE("Read cache block [%llx:%x]\n", block, offset);
1737 ++ }
1738 ++
1739 ++ if (msblk->block_cache[i].block != block) {
1740 ++ mutex_unlock(&msblk->block_cache_mutex);
1741 ++ continue;
1742 ++ }
1743 ++
1744 ++ bytes = msblk->block_cache[i].length - offset;
1745 ++
1746 ++ if (bytes < 1) {
1747 ++ mutex_unlock(&msblk->block_cache_mutex);
1748 ++ goto out;
1749 ++ } else if (bytes >= length) {
1750 ++ if (buffer)
1751 ++ memcpy(buffer, msblk->block_cache[i].data +
1752 ++ offset, length);
1753 ++ if (msblk->block_cache[i].length - offset == length) {
1754 ++ *next_block = msblk->block_cache[i].next_index;
1755 ++ *next_offset = 0;
1756 ++ } else {
1757 ++ *next_block = block;
1758 ++ *next_offset = offset + length;
1759 ++ }
1760 ++ mutex_unlock(&msblk->block_cache_mutex);
1761 ++ goto finish;
1762 ++ } else {
1763 ++ if (buffer) {
1764 ++ memcpy(buffer, msblk->block_cache[i].data +
1765 ++ offset, bytes);
1766 ++ buffer += bytes;
1767 ++ }
1768 ++ block = msblk->block_cache[i].next_index;
1769 ++ mutex_unlock(&msblk->block_cache_mutex);
1770 ++ length -= bytes;
1771 ++ offset = 0;
1772 ++ }
1773 ++ }
1774 ++
1775 ++finish:
1776 ++ return return_length;
1777 ++out:
1778 ++ return 0;
1779 ++}
1780 ++
1781 ++
1782 ++static int get_fragment_location(struct super_block *s, unsigned int fragment,
1783 ++ long long *fragment_start_block,
1784 ++ unsigned int *fragment_size)
1785 ++{
1786 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1787 ++ long long start_block =
1788 ++ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
1789 ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
1790 ++ struct squashfs_fragment_entry fragment_entry;
1791 ++
1792 ++ if (msblk->swap) {
1793 ++ struct squashfs_fragment_entry sfragment_entry;
1794 ++
1795 ++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
1796 ++ start_block, offset,
1797 ++ sizeof(sfragment_entry), &start_block,
1798 ++ &offset))
1799 ++ goto out;
1800 ++ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
1801 ++ } else
1802 ++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
1803 ++ start_block, offset,
1804 ++ sizeof(fragment_entry), &start_block,
1805 ++ &offset))
1806 ++ goto out;
1807 ++
1808 ++ *fragment_start_block = fragment_entry.start_block;
1809 ++ *fragment_size = fragment_entry.size;
1810 ++
1811 ++ return 1;
1812 ++
1813 ++out:
1814 ++ return 0;
1815 ++}
1816 ++
1817 ++
1818 ++SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
1819 ++ squashfs_fragment_cache *fragment)
1820 ++{
1821 ++ mutex_lock(&msblk->fragment_mutex);
1822 ++ fragment->locked --;
1823 ++ wake_up(&msblk->fragment_wait_queue);
1824 ++ mutex_unlock(&msblk->fragment_mutex);
1825 ++}
1826 ++
1827 ++
1828 ++SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block
1829 ++ *s, long long start_block,
1830 ++ int length)
1831 ++{
1832 ++ int i, n;
1833 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1834 ++ struct squashfs_super_block *sblk = &msblk->sblk;
1835 ++
1836 ++ while ( 1 ) {
1837 ++ mutex_lock(&msblk->fragment_mutex);
1838 ++
1839 ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
1840 ++ msblk->fragment[i].block != start_block; i++);
1841 ++
1842 ++ if (i == SQUASHFS_CACHED_FRAGMENTS) {
1843 ++ for (i = msblk->next_fragment, n =
1844 ++ SQUASHFS_CACHED_FRAGMENTS; n &&
1845 ++ msblk->fragment[i].locked; n--, i = (i + 1) %
1846 ++ SQUASHFS_CACHED_FRAGMENTS);
1847 ++
1848 ++ if (n == 0) {
1849 ++ wait_queue_t wait;
1850 ++
1851 ++ init_waitqueue_entry(&wait, current);
1852 ++ add_wait_queue(&msblk->fragment_wait_queue,
1853 ++ &wait);
1854 ++ set_current_state(TASK_UNINTERRUPTIBLE);
1855 ++ mutex_unlock(&msblk->fragment_mutex);
1856 ++ schedule();
1857 ++ set_current_state(TASK_RUNNING);
1858 ++ remove_wait_queue(&msblk->fragment_wait_queue,
1859 ++ &wait);
1860 ++ continue;
1861 ++ }
1862 ++ msblk->next_fragment = (msblk->next_fragment + 1) %
1863 ++ SQUASHFS_CACHED_FRAGMENTS;
1864 ++
1865 ++ if (msblk->fragment[i].data == NULL)
1866 ++ if (!(msblk->fragment[i].data = SQUASHFS_ALLOC
1867 ++ (SQUASHFS_FILE_MAX_SIZE))) {
1868 ++ ERROR("Failed to allocate fragment "
1869 ++ "cache block\n");
1870 ++ mutex_unlock(&msblk->fragment_mutex);
1871 ++ goto out;
1872 ++ }
1873 ++
1874 ++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
1875 ++ msblk->fragment[i].locked = 1;
1876 ++ mutex_unlock(&msblk->fragment_mutex);
1877 ++
1878 ++ if (!(msblk->fragment[i].length = squashfs_read_data(s,
1879 ++ msblk->fragment[i].data,
1880 ++ start_block, length, NULL, sblk->block_size))) {
1881 ++ ERROR("Unable to read fragment cache block "
1882 ++ "[%llx]\n", start_block);
1883 ++ msblk->fragment[i].locked = 0;
1884 ++ smp_mb();
1885 ++ goto out;
1886 ++ }
1887 ++
1888 ++ mutex_lock(&msblk->fragment_mutex);
1889 ++ msblk->fragment[i].block = start_block;
1890 ++ TRACE("New fragment %d, start block %lld, locked %d\n",
1891 ++ i, msblk->fragment[i].block,
1892 ++ msblk->fragment[i].locked);
1893 ++ mutex_unlock(&msblk->fragment_mutex);
1894 ++ break;
1895 ++ }
1896 ++
1897 ++ msblk->fragment[i].locked++;
1898 ++ mutex_unlock(&msblk->fragment_mutex);
1899 ++ TRACE("Got fragment %d, start block %lld, locked %d\n", i,
1900 ++ msblk->fragment[i].block,
1901 ++ msblk->fragment[i].locked);
1902 ++ break;
1903 ++ }
1904 ++
1905 ++ return &msblk->fragment[i];
1906 ++
1907 ++out:
1908 ++ return NULL;
1909 ++}
1910 ++
1911 ++
1912 ++static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
1913 ++ struct squashfs_base_inode_header *inodeb)
1914 ++{
1915 ++ i->i_ino = inodeb->inode_number;
1916 ++ i->i_mtime.tv_sec = inodeb->mtime;
1917 ++ i->i_atime.tv_sec = inodeb->mtime;
1918 ++ i->i_ctime.tv_sec = inodeb->mtime;
1919 ++ i->i_uid = msblk->uid[inodeb->uid];
1920 ++ i->i_mode = inodeb->mode;
1921 ++ i->i_size = 0;
1922 ++ if (inodeb->guid == SQUASHFS_GUIDS)
1923 ++ i->i_gid = i->i_uid;
1924 ++ else
1925 ++ i->i_gid = msblk->guid[inodeb->guid];
1926 ++}
1927 ++
1928 ++
1929 ++static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino)
1930 ++{
1931 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1932 ++ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)];
1933 ++ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1);
1934 ++ squashfs_inode_t inode;
1935 ++
1936 ++ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino);
1937 ++
1938 ++ if (msblk->swap) {
1939 ++ squashfs_inode_t sinode;
1940 ++
1941 ++ if (!squashfs_get_cached_block(s, (char *) &sinode, start, offset,
1942 ++ sizeof(sinode), &start, &offset))
1943 ++ goto out;
1944 ++ SQUASHFS_SWAP_INODE_T((&inode), &sinode);
1945 ++ } else if (!squashfs_get_cached_block(s, (char *) &inode, start, offset,
1946 ++ sizeof(inode), &start, &offset))
1947 ++ goto out;
1948 ++
1949 ++ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode);
1950 ++
1951 ++ return inode;
1952 ++
1953 ++out:
1954 ++ return SQUASHFS_INVALID_BLK;
1955 ++}
1956 ++
1957 ++
1958 ++static void vfs_read_inode(struct inode *i)
1959 ++{
1960 ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
1961 ++ squashfs_inode_t inode = squashfs_inode_lookup(i->i_sb, i->i_ino);
1962 ++
1963 ++ TRACE("Entered vfs_read_inode\n");
1964 ++
1965 ++ if(inode != SQUASHFS_INVALID_BLK)
1966 ++ (msblk->read_inode)(i, inode);
1967 ++}
1968 ++
1969 ++
1970 ++static struct dentry *squashfs_get_parent(struct dentry *child)
1971 ++{
1972 ++ struct inode *i = child->d_inode;
1973 ++ struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
1974 ++ struct dentry *rv;
1975 ++
1976 ++ TRACE("Entered squashfs_get_parent\n");
1977 ++
1978 ++ if(parent == NULL) {
1979 ++ rv = ERR_PTR(-EACCES);
1980 ++ goto out;
1981 ++ }
1982 ++
1983 ++ rv = d_alloc_anon(parent);
1984 ++ if(rv == NULL)
1985 ++ rv = ERR_PTR(-ENOMEM);
1986 ++
1987 ++out:
1988 ++ return rv;
1989 ++}
1990 ++
1991 ++
1992 ++SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number)
1993 ++{
1994 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
1995 ++ struct inode *i = iget_locked(s, inode_number);
1996 ++
1997 ++ TRACE("Entered squashfs_iget\n");
1998 ++
1999 ++ if(i && (i->i_state & I_NEW)) {
2000 ++ (msblk->read_inode)(i, inode);
2001 ++ unlock_new_inode(i);
2002 ++ }
2003 ++
2004 ++ return i;
2005 ++}
2006 ++
2007 ++
2008 ++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode)
2009 ++{
2010 ++ struct super_block *s = i->i_sb;
2011 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
2012 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2013 ++ long long block = SQUASHFS_INODE_BLK(inode) +
2014 ++ sblk->inode_table_start;
2015 ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
2016 ++ long long next_block;
2017 ++ unsigned int next_offset;
2018 ++ union squashfs_inode_header id, sid;
2019 ++ struct squashfs_base_inode_header *inodeb = &id.base,
2020 ++ *sinodeb = &sid.base;
2021 ++
2022 ++ TRACE("Entered squashfs_read_inode\n");
2023 ++
2024 ++ if (msblk->swap) {
2025 ++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
2026 ++ offset, sizeof(*sinodeb), &next_block,
2027 ++ &next_offset))
2028 ++ goto failed_read;
2029 ++ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb,
2030 ++ sizeof(*sinodeb));
2031 ++ } else
2032 ++ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
2033 ++ offset, sizeof(*inodeb), &next_block,
2034 ++ &next_offset))
2035 ++ goto failed_read;
2036 ++
2037 ++ squashfs_new_inode(msblk, i, inodeb);
2038 ++
2039 ++ switch(inodeb->inode_type) {
2040 ++ case SQUASHFS_FILE_TYPE: {
2041 ++ unsigned int frag_size;
2042 ++ long long frag_blk;
2043 ++ struct squashfs_reg_inode_header *inodep = &id.reg;
2044 ++ struct squashfs_reg_inode_header *sinodep = &sid.reg;
2045 ++
2046 ++ if (msblk->swap) {
2047 ++ if (!squashfs_get_cached_block(s, (char *)
2048 ++ sinodep, block, offset,
2049 ++ sizeof(*sinodep), &next_block,
2050 ++ &next_offset))
2051 ++ goto failed_read;
2052 ++ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
2053 ++ } else
2054 ++ if (!squashfs_get_cached_block(s, (char *)
2055 ++ inodep, block, offset,
2056 ++ sizeof(*inodep), &next_block,
2057 ++ &next_offset))
2058 ++ goto failed_read;
2059 ++
2060 ++ frag_blk = SQUASHFS_INVALID_BLK;
2061 ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
2062 ++ !get_fragment_location(s,
2063 ++ inodep->fragment, &frag_blk, &frag_size))
2064 ++ goto failed_read;
2065 ++
2066 ++ i->i_nlink = 1;
2067 ++ i->i_size = inodep->file_size;
2068 ++ i->i_fop = &generic_ro_fops;
2069 ++ i->i_mode |= S_IFREG;
2070 ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
2071 ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
2072 ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
2073 ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
2074 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
2075 ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
2076 ++ SQUASHFS_I(i)->offset = next_offset;
2077 ++ if (sblk->block_size > 4096)
2078 ++ i->i_data.a_ops = &squashfs_aops;
2079 ++ else
2080 ++ i->i_data.a_ops = &squashfs_aops_4K;
2081 ++
2082 ++ TRACE("File inode %x:%x, start_block %llx, "
2083 ++ "block_list_start %llx, offset %x\n",
2084 ++ SQUASHFS_INODE_BLK(inode), offset,
2085 ++ inodep->start_block, next_block,
2086 ++ next_offset);
2087 ++ break;
2088 ++ }
2089 ++ case SQUASHFS_LREG_TYPE: {
2090 ++ unsigned int frag_size;
2091 ++ long long frag_blk;
2092 ++ struct squashfs_lreg_inode_header *inodep = &id.lreg;
2093 ++ struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
2094 ++
2095 ++ if (msblk->swap) {
2096 ++ if (!squashfs_get_cached_block(s, (char *)
2097 ++ sinodep, block, offset,
2098 ++ sizeof(*sinodep), &next_block,
2099 ++ &next_offset))
2100 ++ goto failed_read;
2101 ++ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
2102 ++ } else
2103 ++ if (!squashfs_get_cached_block(s, (char *)
2104 ++ inodep, block, offset,
2105 ++ sizeof(*inodep), &next_block,
2106 ++ &next_offset))
2107 ++ goto failed_read;
2108 ++
2109 ++ frag_blk = SQUASHFS_INVALID_BLK;
2110 ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
2111 ++ !get_fragment_location(s,
2112 ++ inodep->fragment, &frag_blk, &frag_size))
2113 ++ goto failed_read;
2114 ++
2115 ++ i->i_nlink = inodep->nlink;
2116 ++ i->i_size = inodep->file_size;
2117 ++ i->i_fop = &generic_ro_fops;
2118 ++ i->i_mode |= S_IFREG;
2119 ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
2120 ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
2121 ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
2122 ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
2123 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
2124 ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
2125 ++ SQUASHFS_I(i)->offset = next_offset;
2126 ++ if (sblk->block_size > 4096)
2127 ++ i->i_data.a_ops = &squashfs_aops;
2128 ++ else
2129 ++ i->i_data.a_ops = &squashfs_aops_4K;
2130 ++
2131 ++ TRACE("File inode %x:%x, start_block %llx, "
2132 ++ "block_list_start %llx, offset %x\n",
2133 ++ SQUASHFS_INODE_BLK(inode), offset,
2134 ++ inodep->start_block, next_block,
2135 ++ next_offset);
2136 ++ break;
2137 ++ }
2138 ++ case SQUASHFS_DIR_TYPE: {
2139 ++ struct squashfs_dir_inode_header *inodep = &id.dir;
2140 ++ struct squashfs_dir_inode_header *sinodep = &sid.dir;
2141 ++
2142 ++ if (msblk->swap) {
2143 ++ if (!squashfs_get_cached_block(s, (char *)
2144 ++ sinodep, block, offset,
2145 ++ sizeof(*sinodep), &next_block,
2146 ++ &next_offset))
2147 ++ goto failed_read;
2148 ++ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
2149 ++ } else
2150 ++ if (!squashfs_get_cached_block(s, (char *)
2151 ++ inodep, block, offset,
2152 ++ sizeof(*inodep), &next_block,
2153 ++ &next_offset))
2154 ++ goto failed_read;
2155 ++
2156 ++ i->i_nlink = inodep->nlink;
2157 ++ i->i_size = inodep->file_size;
2158 ++ i->i_op = &squashfs_dir_inode_ops;
2159 ++ i->i_fop = &squashfs_dir_ops;
2160 ++ i->i_mode |= S_IFDIR;
2161 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
2162 ++ SQUASHFS_I(i)->offset = inodep->offset;
2163 ++ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
2164 ++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
2165 ++
2166 ++ TRACE("Directory inode %x:%x, start_block %x, offset "
2167 ++ "%x\n", SQUASHFS_INODE_BLK(inode),
2168 ++ offset, inodep->start_block,
2169 ++ inodep->offset);
2170 ++ break;
2171 ++ }
2172 ++ case SQUASHFS_LDIR_TYPE: {
2173 ++ struct squashfs_ldir_inode_header *inodep = &id.ldir;
2174 ++ struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
2175 ++
2176 ++ if (msblk->swap) {
2177 ++ if (!squashfs_get_cached_block(s, (char *)
2178 ++ sinodep, block, offset,
2179 ++ sizeof(*sinodep), &next_block,
2180 ++ &next_offset))
2181 ++ goto failed_read;
2182 ++ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep,
2183 ++ sinodep);
2184 ++ } else
2185 ++ if (!squashfs_get_cached_block(s, (char *)
2186 ++ inodep, block, offset,
2187 ++ sizeof(*inodep), &next_block,
2188 ++ &next_offset))
2189 ++ goto failed_read;
2190 ++
2191 ++ i->i_nlink = inodep->nlink;
2192 ++ i->i_size = inodep->file_size;
2193 ++ i->i_op = &squashfs_dir_inode_ops;
2194 ++ i->i_fop = &squashfs_dir_ops;
2195 ++ i->i_mode |= S_IFDIR;
2196 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
2197 ++ SQUASHFS_I(i)->offset = inodep->offset;
2198 ++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
2199 ++ SQUASHFS_I(i)->u.s2.directory_index_offset =
2200 ++ next_offset;
2201 ++ SQUASHFS_I(i)->u.s2.directory_index_count =
2202 ++ inodep->i_count;
2203 ++ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
2204 ++
2205 ++ TRACE("Long directory inode %x:%x, start_block %x, "
2206 ++ "offset %x\n",
2207 ++ SQUASHFS_INODE_BLK(inode), offset,
2208 ++ inodep->start_block, inodep->offset);
2209 ++ break;
2210 ++ }
2211 ++ case SQUASHFS_SYMLINK_TYPE: {
2212 ++ struct squashfs_symlink_inode_header *inodep =
2213 ++ &id.symlink;
2214 ++ struct squashfs_symlink_inode_header *sinodep =
2215 ++ &sid.symlink;
2216 ++
2217 ++ if (msblk->swap) {
2218 ++ if (!squashfs_get_cached_block(s, (char *)
2219 ++ sinodep, block, offset,
2220 ++ sizeof(*sinodep), &next_block,
2221 ++ &next_offset))
2222 ++ goto failed_read;
2223 ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep,
2224 ++ sinodep);
2225 ++ } else
2226 ++ if (!squashfs_get_cached_block(s, (char *)
2227 ++ inodep, block, offset,
2228 ++ sizeof(*inodep), &next_block,
2229 ++ &next_offset))
2230 ++ goto failed_read;
2231 ++
2232 ++ i->i_nlink = inodep->nlink;
2233 ++ i->i_size = inodep->symlink_size;
2234 ++ i->i_op = &page_symlink_inode_operations;
2235 ++ i->i_data.a_ops = &squashfs_symlink_aops;
2236 ++ i->i_mode |= S_IFLNK;
2237 ++ SQUASHFS_I(i)->start_block = next_block;
2238 ++ SQUASHFS_I(i)->offset = next_offset;
2239 ++
2240 ++ TRACE("Symbolic link inode %x:%x, start_block %llx, "
2241 ++ "offset %x\n",
2242 ++ SQUASHFS_INODE_BLK(inode), offset,
2243 ++ next_block, next_offset);
2244 ++ break;
2245 ++ }
2246 ++ case SQUASHFS_BLKDEV_TYPE:
2247 ++ case SQUASHFS_CHRDEV_TYPE: {
2248 ++ struct squashfs_dev_inode_header *inodep = &id.dev;
2249 ++ struct squashfs_dev_inode_header *sinodep = &sid.dev;
2250 ++
2251 ++ if (msblk->swap) {
2252 ++ if (!squashfs_get_cached_block(s, (char *)
2253 ++ sinodep, block, offset,
2254 ++ sizeof(*sinodep), &next_block,
2255 ++ &next_offset))
2256 ++ goto failed_read;
2257 ++ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
2258 ++ } else
2259 ++ if (!squashfs_get_cached_block(s, (char *)
2260 ++ inodep, block, offset,
2261 ++ sizeof(*inodep), &next_block,
2262 ++ &next_offset))
2263 ++ goto failed_read;
2264 ++
2265 ++ i->i_nlink = inodep->nlink;
2266 ++ i->i_mode |= (inodeb->inode_type ==
2267 ++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
2268 ++ S_IFBLK;
2269 ++ init_special_inode(i, i->i_mode,
2270 ++ old_decode_dev(inodep->rdev));
2271 ++
2272 ++ TRACE("Device inode %x:%x, rdev %x\n",
2273 ++ SQUASHFS_INODE_BLK(inode), offset,
2274 ++ inodep->rdev);
2275 ++ break;
2276 ++ }
2277 ++ case SQUASHFS_FIFO_TYPE:
2278 ++ case SQUASHFS_SOCKET_TYPE: {
2279 ++ struct squashfs_ipc_inode_header *inodep = &id.ipc;
2280 ++ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
2281 ++
2282 ++ if (msblk->swap) {
2283 ++ if (!squashfs_get_cached_block(s, (char *)
2284 ++ sinodep, block, offset,
2285 ++ sizeof(*sinodep), &next_block,
2286 ++ &next_offset))
2287 ++ goto failed_read;
2288 ++ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
2289 ++ } else
2290 ++ if (!squashfs_get_cached_block(s, (char *)
2291 ++ inodep, block, offset,
2292 ++ sizeof(*inodep), &next_block,
2293 ++ &next_offset))
2294 ++ goto failed_read;
2295 ++
2296 ++ i->i_nlink = inodep->nlink;
2297 ++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
2298 ++ ? S_IFIFO : S_IFSOCK;
2299 ++ init_special_inode(i, i->i_mode, 0);
2300 ++ break;
2301 ++ }
2302 ++ default:
2303 ++ ERROR("Unknown inode type %d in squashfs_iget!\n",
2304 ++ inodeb->inode_type);
2305 ++ goto failed_read1;
2306 ++ }
2307 ++
2308 ++ return 1;
2309 ++
2310 ++failed_read:
2311 ++ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
2312 ++
2313 ++failed_read1:
2314 ++ make_bad_inode(i);
2315 ++ return 0;
2316 ++}
2317 ++
2318 ++
2319 ++static int read_inode_lookup_table(struct super_block *s)
2320 ++{
2321 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
2322 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2323 ++ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes);
2324 ++
2325 ++ TRACE("In read_inode_lookup_table, length %d\n", length);
2326 ++
2327 ++ /* Allocate inode lookup table */
2328 ++ if (!(msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL))) {
2329 ++ ERROR("Failed to allocate inode lookup table\n");
2330 ++ return 0;
2331 ++ }
2332 ++
2333 ++ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table,
2334 ++ sblk->lookup_table_start, length |
2335 ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
2336 ++ ERROR("unable to read inode lookup table\n");
2337 ++ return 0;
2338 ++ }
2339 ++
2340 ++ if (msblk->swap) {
2341 ++ int i;
2342 ++ long long block;
2343 ++
2344 ++ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) {
2345 ++ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block),
2346 ++ &msblk->inode_lookup_table[i], 1);
2347 ++ msblk->inode_lookup_table[i] = block;
2348 ++ }
2349 ++ }
2350 ++
2351 ++ return 1;
2352 ++}
2353 ++
2354 ++
2355 ++static int read_fragment_index_table(struct super_block *s)
2356 ++{
2357 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
2358 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2359 ++ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments);
2360 ++
2361 ++ if(length == 0)
2362 ++ return 1;
2363 ++
2364 ++ /* Allocate fragment index table */
2365 ++ if (!(msblk->fragment_index = kmalloc(length, GFP_KERNEL))) {
2366 ++ ERROR("Failed to allocate fragment index table\n");
2367 ++ return 0;
2368 ++ }
2369 ++
2370 ++ if (!squashfs_read_data(s, (char *) msblk->fragment_index,
2371 ++ sblk->fragment_table_start, length |
2372 ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
2373 ++ ERROR("unable to read fragment index table\n");
2374 ++ return 0;
2375 ++ }
2376 ++
2377 ++ if (msblk->swap) {
2378 ++ int i;
2379 ++ long long fragment;
2380 ++
2381 ++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) {
2382 ++ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
2383 ++ &msblk->fragment_index[i], 1);
2384 ++ msblk->fragment_index[i] = fragment;
2385 ++ }
2386 ++ }
2387 ++
2388 ++ return 1;
2389 ++}
2390 ++
2391 ++
2392 ++static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
2393 ++{
2394 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2395 ++
2396 ++ msblk->read_inode = squashfs_read_inode;
2397 ++ msblk->read_blocklist = read_blocklist;
2398 ++ msblk->read_fragment_index_table = read_fragment_index_table;
2399 ++
2400 ++ if (sblk->s_major == 1) {
2401 ++ if (!squashfs_1_0_supported(msblk)) {
2402 ++ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
2403 ++ "are unsupported\n");
2404 ++ SERROR("Please recompile with "
2405 ++ "Squashfs 1.0 support enabled\n");
2406 ++ return 0;
2407 ++ }
2408 ++ } else if (sblk->s_major == 2) {
2409 ++ if (!squashfs_2_0_supported(msblk)) {
2410 ++ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
2411 ++ "are unsupported\n");
2412 ++ SERROR("Please recompile with "
2413 ++ "Squashfs 2.0 support enabled\n");
2414 ++ return 0;
2415 ++ }
2416 ++ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
2417 ++ SQUASHFS_MINOR) {
2418 ++ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
2419 ++ "filesystem\n", sblk->s_major, sblk->s_minor);
2420 ++ SERROR("Please update your kernel\n");
2421 ++ return 0;
2422 ++ }
2423 ++
2424 ++ return 1;
2425 ++}
2426 ++
2427 ++
2428 ++static int squashfs_fill_super(struct super_block *s, void *data, int silent)
2429 ++{
2430 ++ struct squashfs_sb_info *msblk;
2431 ++ struct squashfs_super_block *sblk;
2432 ++ int i;
2433 ++ char b[BDEVNAME_SIZE];
2434 ++ struct inode *root;
2435 ++
2436 ++ TRACE("Entered squashfs_read_superblock\n");
2437 ++
2438 ++ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),
2439 ++ GFP_KERNEL))) {
2440 ++ ERROR("Failed to allocate superblock\n");
2441 ++ goto failure;
2442 ++ }
2443 ++ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));
2444 ++ msblk = s->s_fs_info;
2445 ++ if (!(msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
2446 ++ ERROR("Failed to allocate zlib workspace\n");
2447 ++ goto failure;
2448 ++ }
2449 ++ sblk = &msblk->sblk;
2450 ++
2451 ++ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
2452 ++ msblk->devblksize_log2 = ffz(~msblk->devblksize);
2453 ++
2454 ++ mutex_init(&msblk->read_data_mutex);
2455 ++ mutex_init(&msblk->read_page_mutex);
2456 ++ mutex_init(&msblk->block_cache_mutex);
2457 ++ mutex_init(&msblk->fragment_mutex);
2458 ++ mutex_init(&msblk->meta_index_mutex);
2459 ++
2460 ++ init_waitqueue_head(&msblk->waitq);
2461 ++ init_waitqueue_head(&msblk->fragment_wait_queue);
2462 ++
2463 ++ sblk->bytes_used = sizeof(struct squashfs_super_block);
2464 ++ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
2465 ++ sizeof(struct squashfs_super_block) |
2466 ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) {
2467 ++ SERROR("unable to read superblock\n");
2468 ++ goto failed_mount;
2469 ++ }
2470 ++
2471 ++ /* Check it is a SQUASHFS superblock */
2472 ++ msblk->swap = 0;
2473 ++ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
2474 ++ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
2475 ++ struct squashfs_super_block ssblk;
2476 ++
2477 ++ WARNING("Mounting a different endian SQUASHFS "
2478 ++ "filesystem on %s\n", bdevname(s->s_bdev, b));
2479 ++
2480 ++ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
2481 ++ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
2482 ++ msblk->swap = 1;
2483 ++ } else {
2484 ++ SERROR("Can't find a SQUASHFS superblock on %s\n",
2485 ++ bdevname(s->s_bdev, b));
2486 ++ goto failed_mount;
2487 ++ }
2488 ++ }
2489 ++
2490 ++ /* Check the MAJOR & MINOR versions */
2491 ++ if(!supported_squashfs_filesystem(msblk, silent))
2492 ++ goto failed_mount;
2493 ++
2494 ++ /* Check the filesystem does not extend beyond the end of the
2495 ++ block device */
2496 ++ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
2497 ++ goto failed_mount;
2498 ++
2499 ++ /* Check the root inode for sanity */
2500 ++ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
2501 ++ goto failed_mount;
2502 ++
2503 ++ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
2504 ++ TRACE("Inodes are %scompressed\n",
2505 ++ SQUASHFS_UNCOMPRESSED_INODES
2506 ++ (sblk->flags) ? "un" : "");
2507 ++ TRACE("Data is %scompressed\n",
2508 ++ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
2509 ++ ? "un" : "");
2510 ++ TRACE("Check data is %s present in the filesystem\n",
2511 ++ SQUASHFS_CHECK_DATA(sblk->flags) ?
2512 ++ "" : "not");
2513 ++ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
2514 ++ TRACE("Block size %d\n", sblk->block_size);
2515 ++ TRACE("Number of inodes %d\n", sblk->inodes);
2516 ++ if (sblk->s_major > 1)
2517 ++ TRACE("Number of fragments %d\n", sblk->fragments);
2518 ++ TRACE("Number of uids %d\n", sblk->no_uids);
2519 ++ TRACE("Number of gids %d\n", sblk->no_guids);
2520 ++ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
2521 ++ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
2522 ++ if (sblk->s_major > 1)
2523 ++ TRACE("sblk->fragment_table_start %llx\n",
2524 ++ sblk->fragment_table_start);
2525 ++ TRACE("sblk->uid_start %llx\n", sblk->uid_start);
2526 ++
2527 ++ s->s_flags |= MS_RDONLY;
2528 ++ s->s_op = &squashfs_super_ops;
2529 ++
2530 ++ /* Init inode_table block pointer array */
2531 ++ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
2532 ++ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {
2533 ++ ERROR("Failed to allocate block cache\n");
2534 ++ goto failed_mount;
2535 ++ }
2536 ++
2537 ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
2538 ++ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
2539 ++
2540 ++ msblk->next_cache = 0;
2541 ++
2542 ++ /* Allocate read_page block */
2543 ++ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
2544 ++ ERROR("Failed to allocate read_page block\n");
2545 ++ goto failed_mount;
2546 ++ }
2547 ++
2548 ++ /* Allocate uid and gid tables */
2549 ++ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *
2550 ++ sizeof(unsigned int), GFP_KERNEL))) {
2551 ++ ERROR("Failed to allocate uid/gid table\n");
2552 ++ goto failed_mount;
2553 ++ }
2554 ++ msblk->guid = msblk->uid + sblk->no_uids;
2555 ++
2556 ++ if (msblk->swap) {
2557 ++ unsigned int suid[sblk->no_uids + sblk->no_guids];
2558 ++
2559 ++ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start,
2560 ++ ((sblk->no_uids + sblk->no_guids) *
2561 ++ sizeof(unsigned int)) |
2562 ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) {
2563 ++ ERROR("unable to read uid/gid table\n");
2564 ++ goto failed_mount;
2565 ++ }
2566 ++
2567 ++ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids +
2568 ++ sblk->no_guids), (sizeof(unsigned int) * 8));
2569 ++ } else
2570 ++ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start,
2571 ++ ((sblk->no_uids + sblk->no_guids) *
2572 ++ sizeof(unsigned int)) |
2573 ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) {
2574 ++ ERROR("unable to read uid/gid table\n");
2575 ++ goto failed_mount;
2576 ++ }
2577 ++
2578 ++
2579 ++ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
2580 ++ goto allocate_root;
2581 ++
2582 ++ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *
2583 ++ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {
2584 ++ ERROR("Failed to allocate fragment block cache\n");
2585 ++ goto failed_mount;
2586 ++ }
2587 ++
2588 ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
2589 ++ msblk->fragment[i].locked = 0;
2590 ++ msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
2591 ++ msblk->fragment[i].data = NULL;
2592 ++ }
2593 ++
2594 ++ msblk->next_fragment = 0;
2595 ++
2596 ++ /* Allocate and read fragment index table */
2597 ++ if (msblk->read_fragment_index_table(s) == 0)
2598 ++ goto failed_mount;
2599 ++
2600 ++ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
2601 ++ goto allocate_root;
2602 ++
2603 ++ /* Allocate and read inode lookup table */
2604 ++ if (read_inode_lookup_table(s) == 0)
2605 ++ goto failed_mount;
2606 ++
2607 ++ s->s_op = &squashfs_export_super_ops;
2608 ++ s->s_export_op = &squashfs_export_ops;
2609 ++
2610 ++allocate_root:
2611 ++ root = new_inode(s);
2612 ++ if ((msblk->read_inode)(root, sblk->root_inode) == 0)
2613 ++ goto failed_mount;
2614 ++ insert_inode_hash(root);
2615 ++
2616 ++ if ((s->s_root = d_alloc_root(root)) == NULL) {
2617 ++ ERROR("Root inode create failed\n");
2618 ++ iput(root);
2619 ++ goto failed_mount;
2620 ++ }
2621 ++
2622 ++ TRACE("Leaving squashfs_read_super\n");
2623 ++ return 0;
2624 ++
2625 ++failed_mount:
2626 ++ kfree(msblk->inode_lookup_table);
2627 ++ kfree(msblk->fragment_index);
2628 ++ kfree(msblk->fragment);
2629 ++ kfree(msblk->uid);
2630 ++ kfree(msblk->read_page);
2631 ++ kfree(msblk->block_cache);
2632 ++ kfree(msblk->fragment_index_2);
2633 ++ vfree(msblk->stream.workspace);
2634 ++ kfree(s->s_fs_info);
2635 ++ s->s_fs_info = NULL;
2636 ++ return -EINVAL;
2637 ++
2638 ++failure:
2639 ++ return -ENOMEM;
2640 ++}
2641 ++
2642 ++
2643 ++static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
2644 ++{
2645 ++ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
2646 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2647 ++
2648 ++ TRACE("Entered squashfs_statfs\n");
2649 ++
2650 ++ buf->f_type = SQUASHFS_MAGIC;
2651 ++ buf->f_bsize = sblk->block_size;
2652 ++ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
2653 ++ buf->f_bfree = buf->f_bavail = 0;
2654 ++ buf->f_files = sblk->inodes;
2655 ++ buf->f_ffree = 0;
2656 ++ buf->f_namelen = SQUASHFS_NAME_LEN;
2657 ++
2658 ++ return 0;
2659 ++}
2660 ++
2661 ++
2662 ++static int squashfs_symlink_readpage(struct file *file, struct page *page)
2663 ++{
2664 ++ struct inode *inode = page->mapping->host;
2665 ++ int index = page->index << PAGE_CACHE_SHIFT, length, bytes;
2666 ++ long long block = SQUASHFS_I(inode)->start_block;
2667 ++ int offset = SQUASHFS_I(inode)->offset;
2668 ++ void *pageaddr = kmap(page);
2669 ++
2670 ++ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
2671 ++ "%llx, offset %x\n", page->index,
2672 ++ SQUASHFS_I(inode)->start_block,
2673 ++ SQUASHFS_I(inode)->offset);
2674 ++
2675 ++ for (length = 0; length < index; length += bytes) {
2676 ++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL,
2677 ++ block, offset, PAGE_CACHE_SIZE, &block,
2678 ++ &offset))) {
2679 ++ ERROR("Unable to read symbolic link [%llx:%x]\n", block,
2680 ++ offset);
2681 ++ goto skip_read;
2682 ++ }
2683 ++ }
2684 ++
2685 ++ if (length != index) {
2686 ++ ERROR("(squashfs_symlink_readpage) length != index\n");
2687 ++ bytes = 0;
2688 ++ goto skip_read;
2689 ++ }
2690 ++
2691 ++ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE :
2692 ++ i_size_read(inode) - length;
2693 ++
2694 ++ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block,
2695 ++ offset, bytes, &block, &offset)))
2696 ++ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset);
2697 ++
2698 ++skip_read:
2699 ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
2700 ++ kunmap(page);
2701 ++ flush_dcache_page(page);
2702 ++ SetPageUptodate(page);
2703 ++ unlock_page(page);
2704 ++
2705 ++ return 0;
2706 ++}
2707 ++
2708 ++
2709 ++struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
2710 ++{
2711 ++ struct meta_index *meta = NULL;
2712 ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
2713 ++ int i;
2714 ++
2715 ++ mutex_lock(&msblk->meta_index_mutex);
2716 ++
2717 ++ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
2718 ++
2719 ++ if(msblk->meta_index == NULL)
2720 ++ goto not_allocated;
2721 ++
2722 ++ for (i = 0; i < SQUASHFS_META_NUMBER; i ++)
2723 ++ if (msblk->meta_index[i].inode_number == inode->i_ino &&
2724 ++ msblk->meta_index[i].offset >= offset &&
2725 ++ msblk->meta_index[i].offset <= index &&
2726 ++ msblk->meta_index[i].locked == 0) {
2727 ++ TRACE("locate_meta_index: entry %d, offset %d\n", i,
2728 ++ msblk->meta_index[i].offset);
2729 ++ meta = &msblk->meta_index[i];
2730 ++ offset = meta->offset;
2731 ++ }
2732 ++
2733 ++ if (meta)
2734 ++ meta->locked = 1;
2735 ++
2736 ++not_allocated:
2737 ++ mutex_unlock(&msblk->meta_index_mutex);
2738 ++
2739 ++ return meta;
2740 ++}
2741 ++
2742 ++
2743 ++struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
2744 ++{
2745 ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
2746 ++ struct meta_index *meta = NULL;
2747 ++ int i;
2748 ++
2749 ++ mutex_lock(&msblk->meta_index_mutex);
2750 ++
2751 ++ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
2752 ++
2753 ++ if(msblk->meta_index == NULL) {
2754 ++ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) *
2755 ++ SQUASHFS_META_NUMBER, GFP_KERNEL))) {
2756 ++ ERROR("Failed to allocate meta_index\n");
2757 ++ goto failed;
2758 ++ }
2759 ++ for(i = 0; i < SQUASHFS_META_NUMBER; i++) {
2760 ++ msblk->meta_index[i].inode_number = 0;
2761 ++ msblk->meta_index[i].locked = 0;
2762 ++ }
2763 ++ msblk->next_meta_index = 0;
2764 ++ }
2765 ++
2766 ++ for(i = SQUASHFS_META_NUMBER; i &&
2767 ++ msblk->meta_index[msblk->next_meta_index].locked; i --)
2768 ++ msblk->next_meta_index = (msblk->next_meta_index + 1) %
2769 ++ SQUASHFS_META_NUMBER;
2770 ++
2771 ++ if(i == 0) {
2772 ++ TRACE("empty_meta_index: failed!\n");
2773 ++ goto failed;
2774 ++ }
2775 ++
2776 ++ TRACE("empty_meta_index: returned meta entry %d, %p\n",
2777 ++ msblk->next_meta_index,
2778 ++ &msblk->meta_index[msblk->next_meta_index]);
2779 ++
2780 ++ meta = &msblk->meta_index[msblk->next_meta_index];
2781 ++ msblk->next_meta_index = (msblk->next_meta_index + 1) %
2782 ++ SQUASHFS_META_NUMBER;
2783 ++
2784 ++ meta->inode_number = inode->i_ino;
2785 ++ meta->offset = offset;
2786 ++ meta->skip = skip;
2787 ++ meta->entries = 0;
2788 ++ meta->locked = 1;
2789 ++
2790 ++failed:
2791 ++ mutex_unlock(&msblk->meta_index_mutex);
2792 ++ return meta;
2793 ++}
2794 ++
2795 ++
2796 ++void release_meta_index(struct inode *inode, struct meta_index *meta)
2797 ++{
2798 ++ meta->locked = 0;
2799 ++ smp_mb();
2800 ++}
2801 ++
2802 ++
2803 ++static int read_block_index(struct super_block *s, int blocks, char *block_list,
2804 ++ long long *start_block, int *offset)
2805 ++{
2806 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
2807 ++ unsigned int *block_listp;
2808 ++ int block = 0;
2809 ++
2810 ++ if (msblk->swap) {
2811 ++ char sblock_list[blocks << 2];
2812 ++
2813 ++ if (!squashfs_get_cached_block(s, sblock_list, *start_block,
2814 ++ *offset, blocks << 2, start_block, offset)) {
2815 ++ ERROR("Unable to read block list [%llx:%x]\n",
2816 ++ *start_block, *offset);
2817 ++ goto failure;
2818 ++ }
2819 ++ SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
2820 ++ ((unsigned int *)sblock_list), blocks);
2821 ++ } else
2822 ++ if (!squashfs_get_cached_block(s, block_list, *start_block,
2823 ++ *offset, blocks << 2, start_block, offset)) {
2824 ++ ERROR("Unable to read block list [%llx:%x]\n",
2825 ++ *start_block, *offset);
2826 ++ goto failure;
2827 ++ }
2828 ++
2829 ++ for (block_listp = (unsigned int *) block_list; blocks;
2830 ++ block_listp++, blocks --)
2831 ++ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
2832 ++
2833 ++ return block;
2834 ++
2835 ++failure:
2836 ++ return -1;
2837 ++}
2838 ++
2839 ++
2840 ++#define SIZE 256
2841 ++
2842 ++static inline int calculate_skip(int blocks) {
2843 ++ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
2844 ++ return skip >= 7 ? 7 : skip + 1;
2845 ++}
2846 ++
2847 ++
2848 ++static int get_meta_index(struct inode *inode, int index,
2849 ++ long long *index_block, int *index_offset,
2850 ++ long long *data_block, char *block_list)
2851 ++{
2852 ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
2853 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2854 ++ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
2855 ++ int offset = 0;
2856 ++ struct meta_index *meta;
2857 ++ struct meta_entry *meta_entry;
2858 ++ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
2859 ++ int cur_offset = SQUASHFS_I(inode)->offset;
2860 ++ long long cur_data_block = SQUASHFS_I(inode)->start_block;
2861 ++ int i;
2862 ++
2863 ++ index /= SQUASHFS_META_INDEXES * skip;
2864 ++
2865 ++ while ( offset < index ) {
2866 ++ meta = locate_meta_index(inode, index, offset + 1);
2867 ++
2868 ++ if (meta == NULL) {
2869 ++ if ((meta = empty_meta_index(inode, offset + 1,
2870 ++ skip)) == NULL)
2871 ++ goto all_done;
2872 ++ } else {
2873 ++ if(meta->entries == 0)
2874 ++ goto failed;
2875 ++ offset = index < meta->offset + meta->entries ? index :
2876 ++ meta->offset + meta->entries - 1;
2877 ++ meta_entry = &meta->meta_entry[offset - meta->offset];
2878 ++ cur_index_block = meta_entry->index_block + sblk->inode_table_start;
2879 ++ cur_offset = meta_entry->offset;
2880 ++ cur_data_block = meta_entry->data_block;
2881 ++ TRACE("get_meta_index: offset %d, meta->offset %d, "
2882 ++ "meta->entries %d\n", offset, meta->offset,
2883 ++ meta->entries);
2884 ++ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
2885 ++ " data_block 0x%llx\n", cur_index_block,
2886 ++ cur_offset, cur_data_block);
2887 ++ }
2888 ++
2889 ++ for (i = meta->offset + meta->entries; i <= index &&
2890 ++ i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
2891 ++ int blocks = skip * SQUASHFS_META_INDEXES;
2892 ++
2893 ++ while (blocks) {
2894 ++ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) :
2895 ++ blocks;
2896 ++ int res = read_block_index(inode->i_sb, block,
2897 ++ block_list, &cur_index_block,
2898 ++ &cur_offset);
2899 ++
2900 ++ if (res == -1)
2901 ++ goto failed;
2902 ++
2903 ++ cur_data_block += res;
2904 ++ blocks -= block;
2905 ++ }
2906 ++
2907 ++ meta_entry = &meta->meta_entry[i - meta->offset];
2908 ++ meta_entry->index_block = cur_index_block - sblk->inode_table_start;
2909 ++ meta_entry->offset = cur_offset;
2910 ++ meta_entry->data_block = cur_data_block;
2911 ++ meta->entries ++;
2912 ++ offset ++;
2913 ++ }
2914 ++
2915 ++ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
2916 ++ meta->offset, meta->entries);
2917 ++
2918 ++ release_meta_index(inode, meta);
2919 ++ }
2920 ++
2921 ++all_done:
2922 ++ *index_block = cur_index_block;
2923 ++ *index_offset = cur_offset;
2924 ++ *data_block = cur_data_block;
2925 ++
2926 ++ return offset * SQUASHFS_META_INDEXES * skip;
2927 ++
2928 ++failed:
2929 ++ release_meta_index(inode, meta);
2930 ++ return -1;
2931 ++}
2932 ++
2933 ++
2934 ++static long long read_blocklist(struct inode *inode, int index,
2935 ++ int readahead_blks, char *block_list,
2936 ++ unsigned short **block_p, unsigned int *bsize)
2937 ++{
2938 ++ long long block_ptr;
2939 ++ int offset;
2940 ++ long long block;
2941 ++ int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
2942 ++ block_list);
2943 ++
2944 ++ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
2945 ++ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset,
2946 ++ block);
2947 ++
2948 ++ if(res == -1)
2949 ++ goto failure;
2950 ++
2951 ++ index -= res;
2952 ++
2953 ++ while ( index ) {
2954 ++ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
2955 ++ int res = read_block_index(inode->i_sb, blocks, block_list,
2956 ++ &block_ptr, &offset);
2957 ++ if (res == -1)
2958 ++ goto failure;
2959 ++ block += res;
2960 ++ index -= blocks;
2961 ++ }
2962 ++
2963 ++ if (read_block_index(inode->i_sb, 1, block_list,
2964 ++ &block_ptr, &offset) == -1)
2965 ++ goto failure;
2966 ++ *bsize = *((unsigned int *) block_list);
2967 ++
2968 ++ return block;
2969 ++
2970 ++failure:
2971 ++ return 0;
2972 ++}
2973 ++
2974 ++
2975 ++static int squashfs_readpage(struct file *file, struct page *page)
2976 ++{
2977 ++ struct inode *inode = page->mapping->host;
2978 ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
2979 ++ struct squashfs_super_block *sblk = &msblk->sblk;
2980 ++ unsigned char *block_list;
2981 ++ long long block;
2982 ++ unsigned int bsize, i = 0, bytes = 0, byte_offset = 0;
2983 ++ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
2984 ++ void *pageaddr;
2985 ++ struct squashfs_fragment_cache *fragment = NULL;
2986 ++ char *data_ptr = msblk->read_page;
2987 ++
2988 ++ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
2989 ++ int start_index = page->index & ~mask;
2990 ++ int end_index = start_index | mask;
2991 ++
2992 ++ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
2993 ++ page->index,
2994 ++ SQUASHFS_I(inode)->start_block);
2995 ++
2996 ++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) {
2997 ++ ERROR("Failed to allocate block_list\n");
2998 ++ goto skip_read;
2999 ++ }
3000 ++
3001 ++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
3002 ++ PAGE_CACHE_SHIFT))
3003 ++ goto skip_read;
3004 ++
3005 ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3006 ++ || index < (i_size_read(inode) >>
3007 ++ sblk->block_log)) {
3008 ++ if ((block = (msblk->read_blocklist)(inode, index, 1,
3009 ++ block_list, NULL, &bsize)) == 0)
3010 ++ goto skip_read;
3011 ++
3012 ++ mutex_lock(&msblk->read_page_mutex);
3013 ++
3014 ++ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
3015 ++ block, bsize, NULL, sblk->block_size))) {
3016 ++ ERROR("Unable to read page, block %llx, size %x\n", block,
3017 ++ bsize);
3018 ++ mutex_unlock(&msblk->read_page_mutex);
3019 ++ goto skip_read;
3020 ++ }
3021 ++ } else {
3022 ++ if ((fragment = get_cached_fragment(inode->i_sb,
3023 ++ SQUASHFS_I(inode)->
3024 ++ u.s1.fragment_start_block,
3025 ++ SQUASHFS_I(inode)->u.s1.fragment_size))
3026 ++ == NULL) {
3027 ++ ERROR("Unable to read page, block %llx, size %x\n",
3028 ++ SQUASHFS_I(inode)->
3029 ++ u.s1.fragment_start_block,
3030 ++ (int) SQUASHFS_I(inode)->
3031 ++ u.s1.fragment_size);
3032 ++ goto skip_read;
3033 ++ }
3034 ++ bytes = SQUASHFS_I(inode)->u.s1.fragment_offset +
3035 ++ (i_size_read(inode) & (sblk->block_size
3036 ++ - 1));
3037 ++ byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset;
3038 ++ data_ptr = fragment->data;
3039 ++ }
3040 ++
3041 ++ for (i = start_index; i <= end_index && byte_offset < bytes;
3042 ++ i++, byte_offset += PAGE_CACHE_SIZE) {
3043 ++ struct page *push_page;
3044 ++ int avail = (bytes - byte_offset) > PAGE_CACHE_SIZE ?
3045 ++ PAGE_CACHE_SIZE : bytes - byte_offset;
3046 ++
3047 ++ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n",
3048 ++ bytes, i, byte_offset, avail);
3049 ++
3050 ++ push_page = (i == page->index) ? page :
3051 ++ grab_cache_page_nowait(page->mapping, i);
3052 ++
3053 ++ if (!push_page)
3054 ++ continue;
3055 ++
3056 ++ if (PageUptodate(push_page))
3057 ++ goto skip_page;
3058 ++
3059 ++ pageaddr = kmap_atomic(push_page, KM_USER0);
3060 ++ memcpy(pageaddr, data_ptr + byte_offset, avail);
3061 ++ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
3062 ++ kunmap_atomic(pageaddr, KM_USER0);
3063 ++ flush_dcache_page(push_page);
3064 ++ SetPageUptodate(push_page);
3065 ++skip_page:
3066 ++ unlock_page(push_page);
3067 ++ if(i != page->index)
3068 ++ page_cache_release(push_page);
3069 ++ }
3070 ++
3071 ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3072 ++ || index < (i_size_read(inode) >>
3073 ++ sblk->block_log))
3074 ++ mutex_unlock(&msblk->read_page_mutex);
3075 ++ else
3076 ++ release_cached_fragment(msblk, fragment);
3077 ++
3078 ++ kfree(block_list);
3079 ++ return 0;
3080 ++
3081 ++skip_read:
3082 ++ pageaddr = kmap_atomic(page, KM_USER0);
3083 ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
3084 ++ kunmap_atomic(pageaddr, KM_USER0);
3085 ++ flush_dcache_page(page);
3086 ++ SetPageUptodate(page);
3087 ++ unlock_page(page);
3088 ++
3089 ++ kfree(block_list);
3090 ++ return 0;
3091 ++}
3092 ++
3093 ++
3094 ++static int squashfs_readpage4K(struct file *file, struct page *page)
3095 ++{
3096 ++ struct inode *inode = page->mapping->host;
3097 ++ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3098 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3099 ++ unsigned char *block_list;
3100 ++ long long block;
3101 ++ unsigned int bsize, bytes = 0;
3102 ++ void *pageaddr;
3103 ++
3104 ++ TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n",
3105 ++ page->index,
3106 ++ SQUASHFS_I(inode)->start_block);
3107 ++
3108 ++ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
3109 ++ PAGE_CACHE_SHIFT)) {
3110 ++ block_list = NULL;
3111 ++ goto skip_read;
3112 ++ }
3113 ++
3114 ++ if (!(block_list = kmalloc(SIZE, GFP_KERNEL))) {
3115 ++ ERROR("Failed to allocate block_list\n");
3116 ++ goto skip_read;
3117 ++ }
3118 ++
3119 ++ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3120 ++ || page->index < (i_size_read(inode) >>
3121 ++ sblk->block_log)) {
3122 ++ block = (msblk->read_blocklist)(inode, page->index, 1,
3123 ++ block_list, NULL, &bsize);
3124 ++ if(block == 0)
3125 ++ goto skip_read;
3126 ++
3127 ++ mutex_lock(&msblk->read_page_mutex);
3128 ++ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
3129 ++ bsize, NULL, sblk->block_size);
3130 ++ if (bytes) {
3131 ++ pageaddr = kmap_atomic(page, KM_USER0);
3132 ++ memcpy(pageaddr, msblk->read_page, bytes);
3133 ++ kunmap_atomic(pageaddr, KM_USER0);
3134 ++ } else
3135 ++ ERROR("Unable to read page, block %llx, size %x\n",
3136 ++ block, bsize);
3137 ++ mutex_unlock(&msblk->read_page_mutex);
3138 ++ } else {
3139 ++ struct squashfs_fragment_cache *fragment =
3140 ++ get_cached_fragment(inode->i_sb,
3141 ++ SQUASHFS_I(inode)->
3142 ++ u.s1.fragment_start_block,
3143 ++ SQUASHFS_I(inode)-> u.s1.fragment_size);
3144 ++ if (fragment) {
3145 ++ bytes = i_size_read(inode) & (sblk->block_size - 1);
3146 ++ pageaddr = kmap_atomic(page, KM_USER0);
3147 ++ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)->
3148 ++ u.s1.fragment_offset, bytes);
3149 ++ kunmap_atomic(pageaddr, KM_USER0);
3150 ++ release_cached_fragment(msblk, fragment);
3151 ++ } else
3152 ++ ERROR("Unable to read page, block %llx, size %x\n",
3153 ++ SQUASHFS_I(inode)->
3154 ++ u.s1.fragment_start_block, (int)
3155 ++ SQUASHFS_I(inode)-> u.s1.fragment_size);
3156 ++ }
3157 ++
3158 ++skip_read:
3159 ++ pageaddr = kmap_atomic(page, KM_USER0);
3160 ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
3161 ++ kunmap_atomic(pageaddr, KM_USER0);
3162 ++ flush_dcache_page(page);
3163 ++ SetPageUptodate(page);
3164 ++ unlock_page(page);
3165 ++
3166 ++ kfree(block_list);
3167 ++ return 0;
3168 ++}
3169 ++
3170 ++
3171 ++static int get_dir_index_using_offset(struct super_block *s, long long
3172 ++ *next_block, unsigned int *next_offset,
3173 ++ long long index_start,
3174 ++ unsigned int index_offset, int i_count,
3175 ++ long long f_pos)
3176 ++{
3177 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
3178 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3179 ++ int i, length = 0;
3180 ++ struct squashfs_dir_index index;
3181 ++
3182 ++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
3183 ++ i_count, (unsigned int) f_pos);
3184 ++
3185 ++ f_pos =- 3;
3186 ++ if (f_pos == 0)
3187 ++ goto finish;
3188 ++
3189 ++ for (i = 0; i < i_count; i++) {
3190 ++ if (msblk->swap) {
3191 ++ struct squashfs_dir_index sindex;
3192 ++ squashfs_get_cached_block(s, (char *) &sindex,
3193 ++ index_start, index_offset,
3194 ++ sizeof(sindex), &index_start,
3195 ++ &index_offset);
3196 ++ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
3197 ++ } else
3198 ++ squashfs_get_cached_block(s, (char *) &index,
3199 ++ index_start, index_offset,
3200 ++ sizeof(index), &index_start,
3201 ++ &index_offset);
3202 ++
3203 ++ if (index.index > f_pos)
3204 ++ break;
3205 ++
3206 ++ squashfs_get_cached_block(s, NULL, index_start, index_offset,
3207 ++ index.size + 1, &index_start,
3208 ++ &index_offset);
3209 ++
3210 ++ length = index.index;
3211 ++ *next_block = index.start_block + sblk->directory_table_start;
3212 ++ }
3213 ++
3214 ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
3215 ++
3216 ++finish:
3217 ++ return length + 3;
3218 ++}
3219 ++
3220 ++
3221 ++static int get_dir_index_using_name(struct super_block *s, long long
3222 ++ *next_block, unsigned int *next_offset,
3223 ++ long long index_start,
3224 ++ unsigned int index_offset, int i_count,
3225 ++ const char *name, int size)
3226 ++{
3227 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
3228 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3229 ++ int i, length = 0;
3230 ++ struct squashfs_dir_index *index;
3231 ++ char *str;
3232 ++
3233 ++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
3234 ++
3235 ++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
3236 ++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
3237 ++ ERROR("Failed to allocate squashfs_dir_index\n");
3238 ++ goto failure;
3239 ++ }
3240 ++
3241 ++ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1);
3242 ++ strncpy(str, name, size);
3243 ++ str[size] = '\0';
3244 ++
3245 ++ for (i = 0; i < i_count; i++) {
3246 ++ if (msblk->swap) {
3247 ++ struct squashfs_dir_index sindex;
3248 ++ squashfs_get_cached_block(s, (char *) &sindex,
3249 ++ index_start, index_offset,
3250 ++ sizeof(sindex), &index_start,
3251 ++ &index_offset);
3252 ++ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
3253 ++ } else
3254 ++ squashfs_get_cached_block(s, (char *) index,
3255 ++ index_start, index_offset,
3256 ++ sizeof(struct squashfs_dir_index),
3257 ++ &index_start, &index_offset);
3258 ++
3259 ++ squashfs_get_cached_block(s, index->name, index_start,
3260 ++ index_offset, index->size + 1,
3261 ++ &index_start, &index_offset);
3262 ++
3263 ++ index->name[index->size + 1] = '\0';
3264 ++
3265 ++ if (strcmp(index->name, str) > 0)
3266 ++ break;
3267 ++
3268 ++ length = index->index;
3269 ++ *next_block = index->start_block + sblk->directory_table_start;
3270 ++ }
3271 ++
3272 ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
3273 ++ kfree(str);
3274 ++failure:
3275 ++ return length + 3;
3276 ++}
3277 ++
3278 ++
3279 ++static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
3280 ++{
3281 ++ struct inode *i = file->f_dentry->d_inode;
3282 ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
3283 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3284 ++ long long next_block = SQUASHFS_I(i)->start_block +
3285 ++ sblk->directory_table_start;
3286 ++ int next_offset = SQUASHFS_I(i)->offset, length = 0,
3287 ++ dir_count;
3288 ++ struct squashfs_dir_header dirh;
3289 ++ struct squashfs_dir_entry *dire;
3290 ++
3291 ++ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
3292 ++
3293 ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
3294 ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
3295 ++ ERROR("Failed to allocate squashfs_dir_entry\n");
3296 ++ goto finish;
3297 ++ }
3298 ++
3299 ++ while(file->f_pos < 3) {
3300 ++ char *name;
3301 ++ int size, i_ino;
3302 ++
3303 ++ if(file->f_pos == 0) {
3304 ++ name = ".";
3305 ++ size = 1;
3306 ++ i_ino = i->i_ino;
3307 ++ } else {
3308 ++ name = "..";
3309 ++ size = 2;
3310 ++ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
3311 ++ }
3312 ++ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
3313 ++ (unsigned int) dirent, name, size, (int)
3314 ++ file->f_pos, i_ino,
3315 ++ squashfs_filetype_table[1]);
3316 ++
3317 ++ if (filldir(dirent, name, size,
3318 ++ file->f_pos, i_ino,
3319 ++ squashfs_filetype_table[1]) < 0) {
3320 ++ TRACE("Filldir returned less than 0\n");
3321 ++ goto finish;
3322 ++ }
3323 ++ file->f_pos += size;
3324 ++ }
3325 ++
3326 ++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
3327 ++ SQUASHFS_I(i)->u.s2.directory_index_start,
3328 ++ SQUASHFS_I(i)->u.s2.directory_index_offset,
3329 ++ SQUASHFS_I(i)->u.s2.directory_index_count,
3330 ++ file->f_pos);
3331 ++
3332 ++ while (length < i_size_read(i)) {
3333 ++ /* read directory header */
3334 ++ if (msblk->swap) {
3335 ++ struct squashfs_dir_header sdirh;
3336 ++
3337 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
3338 ++ next_block, next_offset, sizeof(sdirh),
3339 ++ &next_block, &next_offset))
3340 ++ goto failed_read;
3341 ++
3342 ++ length += sizeof(sdirh);
3343 ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
3344 ++ } else {
3345 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
3346 ++ next_block, next_offset, sizeof(dirh),
3347 ++ &next_block, &next_offset))
3348 ++ goto failed_read;
3349 ++
3350 ++ length += sizeof(dirh);
3351 ++ }
3352 ++
3353 ++ dir_count = dirh.count + 1;
3354 ++ while (dir_count--) {
3355 ++ if (msblk->swap) {
3356 ++ struct squashfs_dir_entry sdire;
3357 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
3358 ++ &sdire, next_block, next_offset,
3359 ++ sizeof(sdire), &next_block,
3360 ++ &next_offset))
3361 ++ goto failed_read;
3362 ++
3363 ++ length += sizeof(sdire);
3364 ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
3365 ++ } else {
3366 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
3367 ++ dire, next_block, next_offset,
3368 ++ sizeof(*dire), &next_block,
3369 ++ &next_offset))
3370 ++ goto failed_read;
3371 ++
3372 ++ length += sizeof(*dire);
3373 ++ }
3374 ++
3375 ++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
3376 ++ next_block, next_offset,
3377 ++ dire->size + 1, &next_block,
3378 ++ &next_offset))
3379 ++ goto failed_read;
3380 ++
3381 ++ length += dire->size + 1;
3382 ++
3383 ++ if (file->f_pos >= length)
3384 ++ continue;
3385 ++
3386 ++ dire->name[dire->size + 1] = '\0';
3387 ++
3388 ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
3389 ++ (unsigned int) dirent, dire->name,
3390 ++ dire->size + 1, (int) file->f_pos,
3391 ++ dirh.start_block, dire->offset,
3392 ++ dirh.inode_number + dire->inode_number,
3393 ++ squashfs_filetype_table[dire->type]);
3394 ++
3395 ++ if (filldir(dirent, dire->name, dire->size + 1,
3396 ++ file->f_pos,
3397 ++ dirh.inode_number + dire->inode_number,
3398 ++ squashfs_filetype_table[dire->type])
3399 ++ < 0) {
3400 ++ TRACE("Filldir returned less than 0\n");
3401 ++ goto finish;
3402 ++ }
3403 ++ file->f_pos = length;
3404 ++ }
3405 ++ }
3406 ++
3407 ++finish:
3408 ++ kfree(dire);
3409 ++ return 0;
3410 ++
3411 ++failed_read:
3412 ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
3413 ++ next_offset);
3414 ++ kfree(dire);
3415 ++ return 0;
3416 ++}
3417 ++
3418 ++
3419 ++static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
3420 ++ struct nameidata *nd)
3421 ++{
3422 ++ const unsigned char *name = dentry->d_name.name;
3423 ++ int len = dentry->d_name.len;
3424 ++ struct inode *inode = NULL;
3425 ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
3426 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3427 ++ long long next_block = SQUASHFS_I(i)->start_block +
3428 ++ sblk->directory_table_start;
3429 ++ int next_offset = SQUASHFS_I(i)->offset, length = 0,
3430 ++ dir_count;
3431 ++ struct squashfs_dir_header dirh;
3432 ++ struct squashfs_dir_entry *dire;
3433 ++
3434 ++ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
3435 ++
3436 ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
3437 ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
3438 ++ ERROR("Failed to allocate squashfs_dir_entry\n");
3439 ++ goto exit_lookup;
3440 ++ }
3441 ++
3442 ++ if (len > SQUASHFS_NAME_LEN)
3443 ++ goto exit_lookup;
3444 ++
3445 ++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
3446 ++ SQUASHFS_I(i)->u.s2.directory_index_start,
3447 ++ SQUASHFS_I(i)->u.s2.directory_index_offset,
3448 ++ SQUASHFS_I(i)->u.s2.directory_index_count, name,
3449 ++ len);
3450 ++
3451 ++ while (length < i_size_read(i)) {
3452 ++ /* read directory header */
3453 ++ if (msblk->swap) {
3454 ++ struct squashfs_dir_header sdirh;
3455 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
3456 ++ next_block, next_offset, sizeof(sdirh),
3457 ++ &next_block, &next_offset))
3458 ++ goto failed_read;
3459 ++
3460 ++ length += sizeof(sdirh);
3461 ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
3462 ++ } else {
3463 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
3464 ++ next_block, next_offset, sizeof(dirh),
3465 ++ &next_block, &next_offset))
3466 ++ goto failed_read;
3467 ++
3468 ++ length += sizeof(dirh);
3469 ++ }
3470 ++
3471 ++ dir_count = dirh.count + 1;
3472 ++ while (dir_count--) {
3473 ++ if (msblk->swap) {
3474 ++ struct squashfs_dir_entry sdire;
3475 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
3476 ++ &sdire, next_block,next_offset,
3477 ++ sizeof(sdire), &next_block,
3478 ++ &next_offset))
3479 ++ goto failed_read;
3480 ++
3481 ++ length += sizeof(sdire);
3482 ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
3483 ++ } else {
3484 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
3485 ++ dire, next_block,next_offset,
3486 ++ sizeof(*dire), &next_block,
3487 ++ &next_offset))
3488 ++ goto failed_read;
3489 ++
3490 ++ length += sizeof(*dire);
3491 ++ }
3492 ++
3493 ++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
3494 ++ next_block, next_offset, dire->size + 1,
3495 ++ &next_block, &next_offset))
3496 ++ goto failed_read;
3497 ++
3498 ++ length += dire->size + 1;
3499 ++
3500 ++ if (name[0] < dire->name[0])
3501 ++ goto exit_lookup;
3502 ++
3503 ++ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) {
3504 ++ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block,
3505 ++ dire->offset);
3506 ++
3507 ++ TRACE("calling squashfs_iget for directory "
3508 ++ "entry %s, inode %x:%x, %d\n", name,
3509 ++ dirh.start_block, dire->offset,
3510 ++ dirh.inode_number + dire->inode_number);
3511 ++
3512 ++ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number);
3513 ++
3514 ++ goto exit_lookup;
3515 ++ }
3516 ++ }
3517 ++ }
3518 ++
3519 ++exit_lookup:
3520 ++ kfree(dire);
3521 ++ if (inode)
3522 ++ return d_splice_alias(inode, dentry);
3523 ++ d_add(dentry, inode);
3524 ++ return ERR_PTR(0);
3525 ++
3526 ++failed_read:
3527 ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
3528 ++ next_offset);
3529 ++ goto exit_lookup;
3530 ++}
3531 ++
3532 ++
3533 ++static int squashfs_remount(struct super_block *s, int *flags, char *data)
3534 ++{
3535 ++ *flags |= MS_RDONLY;
3536 ++ return 0;
3537 ++}
3538 ++
3539 ++
3540 ++static void squashfs_put_super(struct super_block *s)
3541 ++{
3542 ++ int i;
3543 ++
3544 ++ if (s->s_fs_info) {
3545 ++ struct squashfs_sb_info *sbi = s->s_fs_info;
3546 ++ if (sbi->block_cache)
3547 ++ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
3548 ++ if (sbi->block_cache[i].block !=
3549 ++ SQUASHFS_INVALID_BLK)
3550 ++ kfree(sbi->block_cache[i].data);
3551 ++ if (sbi->fragment)
3552 ++ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++)
3553 ++ SQUASHFS_FREE(sbi->fragment[i].data);
3554 ++ kfree(sbi->fragment);
3555 ++ kfree(sbi->block_cache);
3556 ++ kfree(sbi->read_page);
3557 ++ kfree(sbi->uid);
3558 ++ kfree(sbi->fragment_index);
3559 ++ kfree(sbi->fragment_index_2);
3560 ++ kfree(sbi->meta_index);
3561 ++ vfree(sbi->stream.workspace);
3562 ++ kfree(s->s_fs_info);
3563 ++ s->s_fs_info = NULL;
3564 ++ }
3565 ++}
3566 ++
3567 ++
3568 ++static int squashfs_get_sb(struct file_system_type *fs_type, int flags,
3569 ++ const char *dev_name, void *data,
3570 ++ struct vfsmount *mnt)
3571 ++{
3572 ++ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super,
3573 ++ mnt);
3574 ++}
3575 ++
3576 ++
3577 ++static int __init init_squashfs_fs(void)
3578 ++{
3579 ++ int err = init_inodecache();
3580 ++ if (err)
3581 ++ goto out;
3582 ++
3583 ++ printk(KERN_INFO "squashfs: version 3.2-r2 (2007/01/15) "
3584 ++ "Phillip Lougher\n");
3585 ++
3586 ++ if ((err = register_filesystem(&squashfs_fs_type)))
3587 ++ destroy_inodecache();
3588 ++
3589 ++out:
3590 ++ return err;
3591 ++}
3592 ++
3593 ++
3594 ++static void __exit exit_squashfs_fs(void)
3595 ++{
3596 ++ unregister_filesystem(&squashfs_fs_type);
3597 ++ destroy_inodecache();
3598 ++}
3599 ++
3600 ++
3601 ++static struct kmem_cache * squashfs_inode_cachep;
3602 ++
3603 ++
3604 ++static struct inode *squashfs_alloc_inode(struct super_block *sb)
3605 ++{
3606 ++ struct squashfs_inode_info *ei;
3607 ++ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
3608 ++ if (!ei)
3609 ++ return NULL;
3610 ++ return &ei->vfs_inode;
3611 ++}
3612 ++
3613 ++
3614 ++static void squashfs_destroy_inode(struct inode *inode)
3615 ++{
3616 ++ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
3617 ++}
3618 ++
3619 ++
3620 ++static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
3621 ++{
3622 ++ struct squashfs_inode_info *ei = foo;
3623 ++
3624 ++ inode_init_once(&ei->vfs_inode);
3625 ++}
3626 ++
3627 ++
3628 ++static int __init init_inodecache(void)
3629 ++{
3630 ++ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
3631 ++ sizeof(struct squashfs_inode_info),
3632 ++ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
3633 ++ init_once);
3634 ++ if (squashfs_inode_cachep == NULL)
3635 ++ return -ENOMEM;
3636 ++ return 0;
3637 ++}
3638 ++
3639 ++
3640 ++static void destroy_inodecache(void)
3641 ++{
3642 ++ kmem_cache_destroy(squashfs_inode_cachep);
3643 ++}
3644 ++
3645 ++
3646 ++module_init(init_squashfs_fs);
3647 ++module_exit(exit_squashfs_fs);
3648 ++MODULE_DESCRIPTION("squashfs 3.2-r2, a compressed read-only filesystem");
3649 ++MODULE_AUTHOR("Phillip Lougher <phillip@×××××××××××.uk>");
3650 ++MODULE_LICENSE("GPL");
3651 +--- /dev/null
3652 ++++ b/fs/squashfs/squashfs.h
3653 +@@ -0,0 +1,87 @@
3654 ++/*
3655 ++ * Squashfs - a compressed read only filesystem for Linux
3656 ++ *
3657 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
3658 ++ * Phillip Lougher <phillip@×××××××××××.uk>
3659 ++ *
3660 ++ * This program is free software; you can redistribute it and/or
3661 ++ * modify it under the terms of the GNU General Public License
3662 ++ * as published by the Free Software Foundation; either version 2,
3663 ++ * or (at your option) any later version.
3664 ++ *
3665 ++ * This program is distributed in the hope that it will be useful,
3666 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3667 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3668 ++ * GNU General Public License for more details.
3669 ++ *
3670 ++ * You should have received a copy of the GNU General Public License
3671 ++ * along with this program; if not, write to the Free Software
3672 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3673 ++ *
3674 ++ * squashfs.h
3675 ++ */
3676 ++
3677 ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3678 ++#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3679 ++#endif
3680 ++
3681 ++#ifdef SQUASHFS_TRACE
3682 ++#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
3683 ++#else
3684 ++#define TRACE(s, args...) {}
3685 ++#endif
3686 ++
3687 ++#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args)
3688 ++
3689 ++#define SERROR(s, args...) do { \
3690 ++ if (!silent) \
3691 ++ printk(KERN_ERR "SQUASHFS error: "s, ## args);\
3692 ++ } while(0)
3693 ++
3694 ++#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args)
3695 ++
3696 ++static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
3697 ++{
3698 ++ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
3699 ++}
3700 ++
3701 ++#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY)
3702 ++#define SQSH_EXTERN
3703 ++extern unsigned int squashfs_read_data(struct super_block *s, char *buffer,
3704 ++ long long index, unsigned int length,
3705 ++ long long *next_index, int srclength);
3706 ++extern int squashfs_get_cached_block(struct super_block *s, char *buffer,
3707 ++ long long block, unsigned int offset,
3708 ++ int length, long long *next_block,
3709 ++ unsigned int *next_offset);
3710 ++extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct
3711 ++ squashfs_fragment_cache *fragment);
3712 ++extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block
3713 ++ *s, long long start_block,
3714 ++ int length);
3715 ++extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number);
3716 ++extern const struct address_space_operations squashfs_symlink_aops;
3717 ++extern const struct address_space_operations squashfs_aops;
3718 ++extern const struct address_space_operations squashfs_aops_4K;
3719 ++extern struct inode_operations squashfs_dir_inode_ops;
3720 ++#else
3721 ++#define SQSH_EXTERN static
3722 ++#endif
3723 ++
3724 ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
3725 ++extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
3726 ++#else
3727 ++static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
3728 ++{
3729 ++ return 0;
3730 ++}
3731 ++#endif
3732 ++
3733 ++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
3734 ++extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
3735 ++#else
3736 ++static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
3737 ++{
3738 ++ return 0;
3739 ++}
3740 ++#endif
3741 +--- /dev/null
3742 ++++ b/fs/squashfs/squashfs2_0.c
3743 +@@ -0,0 +1,742 @@
3744 ++/*
3745 ++ * Squashfs - a compressed read only filesystem for Linux
3746 ++ *
3747 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
3748 ++ * Phillip Lougher <phillip@×××××××××××.uk>
3749 ++ *
3750 ++ * This program is free software; you can redistribute it and/or
3751 ++ * modify it under the terms of the GNU General Public License
3752 ++ * as published by the Free Software Foundation; either version 2,
3753 ++ * or (at your option) any later version.
3754 ++ *
3755 ++ * This program is distributed in the hope that it will be useful,
3756 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3757 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3758 ++ * GNU General Public License for more details.
3759 ++ *
3760 ++ * You should have received a copy of the GNU General Public License
3761 ++ * along with this program; if not, write to the Free Software
3762 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3763 ++ *
3764 ++ * squashfs2_0.c
3765 ++ */
3766 ++
3767 ++#include <linux/squashfs_fs.h>
3768 ++#include <linux/module.h>
3769 ++#include <linux/zlib.h>
3770 ++#include <linux/fs.h>
3771 ++#include <linux/squashfs_fs_sb.h>
3772 ++#include <linux/squashfs_fs_i.h>
3773 ++
3774 ++#include "squashfs.h"
3775 ++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
3776 ++static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
3777 ++ struct nameidata *);
3778 ++
3779 ++static struct file_operations squashfs_dir_ops_2 = {
3780 ++ .read = generic_read_dir,
3781 ++ .readdir = squashfs_readdir_2
3782 ++};
3783 ++
3784 ++static struct inode_operations squashfs_dir_inode_ops_2 = {
3785 ++ .lookup = squashfs_lookup_2
3786 ++};
3787 ++
3788 ++static unsigned char squashfs_filetype_table[] = {
3789 ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
3790 ++};
3791 ++
3792 ++static int read_fragment_index_table_2(struct super_block *s)
3793 ++{
3794 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
3795 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3796 ++
3797 ++ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
3798 ++ (sblk->fragments), GFP_KERNEL))) {
3799 ++ ERROR("Failed to allocate uid/gid table\n");
3800 ++ return 0;
3801 ++ }
3802 ++
3803 ++ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
3804 ++ !squashfs_read_data(s, (char *)
3805 ++ msblk->fragment_index_2,
3806 ++ sblk->fragment_table_start,
3807 ++ SQUASHFS_FRAGMENT_INDEX_BYTES_2
3808 ++ (sblk->fragments) |
3809 ++ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) {
3810 ++ ERROR("unable to read fragment index table\n");
3811 ++ return 0;
3812 ++ }
3813 ++
3814 ++ if (msblk->swap) {
3815 ++ int i;
3816 ++ unsigned int fragment;
3817 ++
3818 ++ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
3819 ++ i++) {
3820 ++ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
3821 ++ &msblk->fragment_index_2[i], 1);
3822 ++ msblk->fragment_index_2[i] = fragment;
3823 ++ }
3824 ++ }
3825 ++
3826 ++ return 1;
3827 ++}
3828 ++
3829 ++
3830 ++static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
3831 ++ long long *fragment_start_block,
3832 ++ unsigned int *fragment_size)
3833 ++{
3834 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
3835 ++ long long start_block =
3836 ++ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
3837 ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
3838 ++ struct squashfs_fragment_entry_2 fragment_entry;
3839 ++
3840 ++ if (msblk->swap) {
3841 ++ struct squashfs_fragment_entry_2 sfragment_entry;
3842 ++
3843 ++ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
3844 ++ start_block, offset,
3845 ++ sizeof(sfragment_entry), &start_block,
3846 ++ &offset))
3847 ++ goto out;
3848 ++ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
3849 ++ } else
3850 ++ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
3851 ++ start_block, offset,
3852 ++ sizeof(fragment_entry), &start_block,
3853 ++ &offset))
3854 ++ goto out;
3855 ++
3856 ++ *fragment_start_block = fragment_entry.start_block;
3857 ++ *fragment_size = fragment_entry.size;
3858 ++
3859 ++ return 1;
3860 ++
3861 ++out:
3862 ++ return 0;
3863 ++}
3864 ++
3865 ++
3866 ++static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
3867 ++ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
3868 ++{
3869 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3870 ++
3871 ++ i->i_ino = ino;
3872 ++ i->i_mtime.tv_sec = sblk->mkfs_time;
3873 ++ i->i_atime.tv_sec = sblk->mkfs_time;
3874 ++ i->i_ctime.tv_sec = sblk->mkfs_time;
3875 ++ i->i_uid = msblk->uid[inodeb->uid];
3876 ++ i->i_mode = inodeb->mode;
3877 ++ i->i_nlink = 1;
3878 ++ i->i_size = 0;
3879 ++ if (inodeb->guid == SQUASHFS_GUIDS)
3880 ++ i->i_gid = i->i_uid;
3881 ++ else
3882 ++ i->i_gid = msblk->guid[inodeb->guid];
3883 ++}
3884 ++
3885 ++
3886 ++static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode)
3887 ++{
3888 ++ struct super_block *s = i->i_sb;
3889 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
3890 ++ struct squashfs_super_block *sblk = &msblk->sblk;
3891 ++ unsigned int block = SQUASHFS_INODE_BLK(inode) +
3892 ++ sblk->inode_table_start;
3893 ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
3894 ++ unsigned int ino = i->i_ino;
3895 ++ long long next_block;
3896 ++ unsigned int next_offset;
3897 ++ union squashfs_inode_header_2 id, sid;
3898 ++ struct squashfs_base_inode_header_2 *inodeb = &id.base,
3899 ++ *sinodeb = &sid.base;
3900 ++
3901 ++ TRACE("Entered squashfs_iget\n");
3902 ++
3903 ++ if (msblk->swap) {
3904 ++ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
3905 ++ offset, sizeof(*sinodeb), &next_block,
3906 ++ &next_offset))
3907 ++ goto failed_read;
3908 ++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
3909 ++ sizeof(*sinodeb));
3910 ++ } else
3911 ++ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
3912 ++ offset, sizeof(*inodeb), &next_block,
3913 ++ &next_offset))
3914 ++ goto failed_read;
3915 ++
3916 ++ squashfs_new_inode(msblk, i, inodeb, ino);
3917 ++
3918 ++ switch(inodeb->inode_type) {
3919 ++ case SQUASHFS_FILE_TYPE: {
3920 ++ struct squashfs_reg_inode_header_2 *inodep = &id.reg;
3921 ++ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
3922 ++ long long frag_blk;
3923 ++ unsigned int frag_size = 0;
3924 ++
3925 ++ if (msblk->swap) {
3926 ++ if (!squashfs_get_cached_block(s, (char *)
3927 ++ sinodep, block, offset,
3928 ++ sizeof(*sinodep), &next_block,
3929 ++ &next_offset))
3930 ++ goto failed_read;
3931 ++ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
3932 ++ } else
3933 ++ if (!squashfs_get_cached_block(s, (char *)
3934 ++ inodep, block, offset,
3935 ++ sizeof(*inodep), &next_block,
3936 ++ &next_offset))
3937 ++ goto failed_read;
3938 ++
3939 ++ frag_blk = SQUASHFS_INVALID_BLK;
3940 ++ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
3941 ++ !get_fragment_location_2(s,
3942 ++ inodep->fragment, &frag_blk, &frag_size))
3943 ++ goto failed_read;
3944 ++
3945 ++ i->i_size = inodep->file_size;
3946 ++ i->i_fop = &generic_ro_fops;
3947 ++ i->i_mode |= S_IFREG;
3948 ++ i->i_mtime.tv_sec = inodep->mtime;
3949 ++ i->i_atime.tv_sec = inodep->mtime;
3950 ++ i->i_ctime.tv_sec = inodep->mtime;
3951 ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
3952 ++ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3953 ++ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3954 ++ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3955 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
3956 ++ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3957 ++ SQUASHFS_I(i)->offset = next_offset;
3958 ++ if (sblk->block_size > 4096)
3959 ++ i->i_data.a_ops = &squashfs_aops;
3960 ++ else
3961 ++ i->i_data.a_ops = &squashfs_aops_4K;
3962 ++
3963 ++ TRACE("File inode %x:%x, start_block %x, "
3964 ++ "block_list_start %llx, offset %x\n",
3965 ++ SQUASHFS_INODE_BLK(inode), offset,
3966 ++ inodep->start_block, next_block,
3967 ++ next_offset);
3968 ++ break;
3969 ++ }
3970 ++ case SQUASHFS_DIR_TYPE: {
3971 ++ struct squashfs_dir_inode_header_2 *inodep = &id.dir;
3972 ++ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
3973 ++
3974 ++ if (msblk->swap) {
3975 ++ if (!squashfs_get_cached_block(s, (char *)
3976 ++ sinodep, block, offset,
3977 ++ sizeof(*sinodep), &next_block,
3978 ++ &next_offset))
3979 ++ goto failed_read;
3980 ++ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
3981 ++ } else
3982 ++ if (!squashfs_get_cached_block(s, (char *)
3983 ++ inodep, block, offset,
3984 ++ sizeof(*inodep), &next_block,
3985 ++ &next_offset))
3986 ++ goto failed_read;
3987 ++
3988 ++ i->i_size = inodep->file_size;
3989 ++ i->i_op = &squashfs_dir_inode_ops_2;
3990 ++ i->i_fop = &squashfs_dir_ops_2;
3991 ++ i->i_mode |= S_IFDIR;
3992 ++ i->i_mtime.tv_sec = inodep->mtime;
3993 ++ i->i_atime.tv_sec = inodep->mtime;
3994 ++ i->i_ctime.tv_sec = inodep->mtime;
3995 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
3996 ++ SQUASHFS_I(i)->offset = inodep->offset;
3997 ++ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
3998 ++ SQUASHFS_I(i)->u.s2.parent_inode = 0;
3999 ++
4000 ++ TRACE("Directory inode %x:%x, start_block %x, offset "
4001 ++ "%x\n", SQUASHFS_INODE_BLK(inode),
4002 ++ offset, inodep->start_block,
4003 ++ inodep->offset);
4004 ++ break;
4005 ++ }
4006 ++ case SQUASHFS_LDIR_TYPE: {
4007 ++ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
4008 ++ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
4009 ++
4010 ++ if (msblk->swap) {
4011 ++ if (!squashfs_get_cached_block(s, (char *)
4012 ++ sinodep, block, offset,
4013 ++ sizeof(*sinodep), &next_block,
4014 ++ &next_offset))
4015 ++ goto failed_read;
4016 ++ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
4017 ++ sinodep);
4018 ++ } else
4019 ++ if (!squashfs_get_cached_block(s, (char *)
4020 ++ inodep, block, offset,
4021 ++ sizeof(*inodep), &next_block,
4022 ++ &next_offset))
4023 ++ goto failed_read;
4024 ++
4025 ++ i->i_size = inodep->file_size;
4026 ++ i->i_op = &squashfs_dir_inode_ops_2;
4027 ++ i->i_fop = &squashfs_dir_ops_2;
4028 ++ i->i_mode |= S_IFDIR;
4029 ++ i->i_mtime.tv_sec = inodep->mtime;
4030 ++ i->i_atime.tv_sec = inodep->mtime;
4031 ++ i->i_ctime.tv_sec = inodep->mtime;
4032 ++ SQUASHFS_I(i)->start_block = inodep->start_block;
4033 ++ SQUASHFS_I(i)->offset = inodep->offset;
4034 ++ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
4035 ++ SQUASHFS_I(i)->u.s2.directory_index_offset =
4036 ++ next_offset;
4037 ++ SQUASHFS_I(i)->u.s2.directory_index_count =
4038 ++ inodep->i_count;
4039 ++ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4040 ++
4041 ++ TRACE("Long directory inode %x:%x, start_block %x, "
4042 ++ "offset %x\n",
4043 ++ SQUASHFS_INODE_BLK(inode), offset,
4044 ++ inodep->start_block, inodep->offset);
4045 ++ break;
4046 ++ }
4047 ++ case SQUASHFS_SYMLINK_TYPE: {
4048 ++ struct squashfs_symlink_inode_header_2 *inodep =
4049 ++ &id.symlink;
4050 ++ struct squashfs_symlink_inode_header_2 *sinodep =
4051 ++ &sid.symlink;
4052 ++
4053 ++ if (msblk->swap) {
4054 ++ if (!squashfs_get_cached_block(s, (char *)
4055 ++ sinodep, block, offset,
4056 ++ sizeof(*sinodep), &next_block,
4057 ++ &next_offset))
4058 ++ goto failed_read;
4059 ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
4060 ++ sinodep);
4061 ++ } else
4062 ++ if (!squashfs_get_cached_block(s, (char *)
4063 ++ inodep, block, offset,
4064 ++ sizeof(*inodep), &next_block,
4065 ++ &next_offset))
4066 ++ goto failed_read;
4067 ++
4068 ++ i->i_size = inodep->symlink_size;
4069 ++ i->i_op = &page_symlink_inode_operations;
4070 ++ i->i_data.a_ops = &squashfs_symlink_aops;
4071 ++ i->i_mode |= S_IFLNK;
4072 ++ SQUASHFS_I(i)->start_block = next_block;
4073 ++ SQUASHFS_I(i)->offset = next_offset;
4074 ++
4075 ++ TRACE("Symbolic link inode %x:%x, start_block %llx, "
4076 ++ "offset %x\n",
4077 ++ SQUASHFS_INODE_BLK(inode), offset,
4078 ++ next_block, next_offset);
4079 ++ break;
4080 ++ }
4081 ++ case SQUASHFS_BLKDEV_TYPE:
4082 ++ case SQUASHFS_CHRDEV_TYPE: {
4083 ++ struct squashfs_dev_inode_header_2 *inodep = &id.dev;
4084 ++ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
4085 ++
4086 ++ if (msblk->swap) {
4087 ++ if (!squashfs_get_cached_block(s, (char *)
4088 ++ sinodep, block, offset,
4089 ++ sizeof(*sinodep), &next_block,
4090 ++ &next_offset))
4091 ++ goto failed_read;
4092 ++ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
4093 ++ } else
4094 ++ if (!squashfs_get_cached_block(s, (char *)
4095 ++ inodep, block, offset,
4096 ++ sizeof(*inodep), &next_block,
4097 ++ &next_offset))
4098 ++ goto failed_read;
4099 ++
4100 ++ i->i_mode |= (inodeb->inode_type ==
4101 ++ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
4102 ++ S_IFBLK;
4103 ++ init_special_inode(i, i->i_mode,
4104 ++ old_decode_dev(inodep->rdev));
4105 ++
4106 ++ TRACE("Device inode %x:%x, rdev %x\n",
4107 ++ SQUASHFS_INODE_BLK(inode), offset,
4108 ++ inodep->rdev);
4109 ++ break;
4110 ++ }
4111 ++ case SQUASHFS_FIFO_TYPE:
4112 ++ case SQUASHFS_SOCKET_TYPE: {
4113 ++
4114 ++ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4115 ++ ? S_IFIFO : S_IFSOCK;
4116 ++ init_special_inode(i, i->i_mode, 0);
4117 ++ break;
4118 ++ }
4119 ++ default:
4120 ++ ERROR("Unknown inode type %d in squashfs_iget!\n",
4121 ++ inodeb->inode_type);
4122 ++ goto failed_read1;
4123 ++ }
4124 ++
4125 ++ return 1;
4126 ++
4127 ++failed_read:
4128 ++ ERROR("Unable to read inode [%x:%x]\n", block, offset);
4129 ++
4130 ++failed_read1:
4131 ++ return 0;
4132 ++}
4133 ++
4134 ++
4135 ++static int get_dir_index_using_offset(struct super_block *s, long long
4136 ++ *next_block, unsigned int *next_offset,
4137 ++ long long index_start,
4138 ++ unsigned int index_offset, int i_count,
4139 ++ long long f_pos)
4140 ++{
4141 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
4142 ++ struct squashfs_super_block *sblk = &msblk->sblk;
4143 ++ int i, length = 0;
4144 ++ struct squashfs_dir_index_2 index;
4145 ++
4146 ++ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
4147 ++ i_count, (unsigned int) f_pos);
4148 ++
4149 ++ if (f_pos == 0)
4150 ++ goto finish;
4151 ++
4152 ++ for (i = 0; i < i_count; i++) {
4153 ++ if (msblk->swap) {
4154 ++ struct squashfs_dir_index_2 sindex;
4155 ++ squashfs_get_cached_block(s, (char *) &sindex,
4156 ++ index_start, index_offset,
4157 ++ sizeof(sindex), &index_start,
4158 ++ &index_offset);
4159 ++ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
4160 ++ } else
4161 ++ squashfs_get_cached_block(s, (char *) &index,
4162 ++ index_start, index_offset,
4163 ++ sizeof(index), &index_start,
4164 ++ &index_offset);
4165 ++
4166 ++ if (index.index > f_pos)
4167 ++ break;
4168 ++
4169 ++ squashfs_get_cached_block(s, NULL, index_start, index_offset,
4170 ++ index.size + 1, &index_start,
4171 ++ &index_offset);
4172 ++
4173 ++ length = index.index;
4174 ++ *next_block = index.start_block + sblk->directory_table_start;
4175 ++ }
4176 ++
4177 ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4178 ++
4179 ++finish:
4180 ++ return length;
4181 ++}
4182 ++
4183 ++
4184 ++static int get_dir_index_using_name(struct super_block *s, long long
4185 ++ *next_block, unsigned int *next_offset,
4186 ++ long long index_start,
4187 ++ unsigned int index_offset, int i_count,
4188 ++ const char *name, int size)
4189 ++{
4190 ++ struct squashfs_sb_info *msblk = s->s_fs_info;
4191 ++ struct squashfs_super_block *sblk = &msblk->sblk;
4192 ++ int i, length = 0;
4193 ++ struct squashfs_dir_index_2 *index;
4194 ++ char *str;
4195 ++
4196 ++ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4197 ++
4198 ++ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
4199 ++ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
4200 ++ ERROR("Failed to allocate squashfs_dir_index\n");
4201 ++ goto failure;
4202 ++ }
4203 ++
4204 ++ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1);
4205 ++ strncpy(str, name, size);
4206 ++ str[size] = '\0';
4207 ++
4208 ++ for (i = 0; i < i_count; i++) {
4209 ++ if (msblk->swap) {
4210 ++ struct squashfs_dir_index_2 sindex;
4211 ++ squashfs_get_cached_block(s, (char *) &sindex,
4212 ++ index_start, index_offset,
4213 ++ sizeof(sindex), &index_start,
4214 ++ &index_offset);
4215 ++ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
4216 ++ } else
4217 ++ squashfs_get_cached_block(s, (char *) index,
4218 ++ index_start, index_offset,
4219 ++ sizeof(struct squashfs_dir_index_2),
4220 ++ &index_start, &index_offset);
4221 ++
4222 ++ squashfs_get_cached_block(s, index->name, index_start,
4223 ++ index_offset, index->size + 1,
4224 ++ &index_start, &index_offset);
4225 ++
4226 ++ index->name[index->size + 1] = '\0';
4227 ++
4228 ++ if (strcmp(index->name, str) > 0)
4229 ++ break;
4230 ++
4231 ++ length = index->index;
4232 ++ *next_block = index->start_block + sblk->directory_table_start;
4233 ++ }
4234 ++
4235 ++ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4236 ++ kfree(str);
4237 ++failure:
4238 ++ return length;
4239 ++}
4240 ++
4241 ++
4242 ++static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
4243 ++{
4244 ++ struct inode *i = file->f_dentry->d_inode;
4245 ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4246 ++ struct squashfs_super_block *sblk = &msblk->sblk;
4247 ++ long long next_block = SQUASHFS_I(i)->start_block +
4248 ++ sblk->directory_table_start;
4249 ++ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4250 ++ dir_count;
4251 ++ struct squashfs_dir_header_2 dirh;
4252 ++ struct squashfs_dir_entry_2 *dire;
4253 ++
4254 ++ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
4255 ++
4256 ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4257 ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4258 ++ ERROR("Failed to allocate squashfs_dir_entry\n");
4259 ++ goto finish;
4260 ++ }
4261 ++
4262 ++ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
4263 ++ SQUASHFS_I(i)->u.s2.directory_index_start,
4264 ++ SQUASHFS_I(i)->u.s2.directory_index_offset,
4265 ++ SQUASHFS_I(i)->u.s2.directory_index_count,
4266 ++ file->f_pos);
4267 ++
4268 ++ while (length < i_size_read(i)) {
4269 ++ /* read directory header */
4270 ++ if (msblk->swap) {
4271 ++ struct squashfs_dir_header_2 sdirh;
4272 ++
4273 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4274 ++ next_block, next_offset, sizeof(sdirh),
4275 ++ &next_block, &next_offset))
4276 ++ goto failed_read;
4277 ++
4278 ++ length += sizeof(sdirh);
4279 ++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4280 ++ } else {
4281 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4282 ++ next_block, next_offset, sizeof(dirh),
4283 ++ &next_block, &next_offset))
4284 ++ goto failed_read;
4285 ++
4286 ++ length += sizeof(dirh);
4287 ++ }
4288 ++
4289 ++ dir_count = dirh.count + 1;
4290 ++ while (dir_count--) {
4291 ++ if (msblk->swap) {
4292 ++ struct squashfs_dir_entry_2 sdire;
4293 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
4294 ++ &sdire, next_block, next_offset,
4295 ++ sizeof(sdire), &next_block,
4296 ++ &next_offset))
4297 ++ goto failed_read;
4298 ++
4299 ++ length += sizeof(sdire);
4300 ++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4301 ++ } else {
4302 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
4303 ++ dire, next_block, next_offset,
4304 ++ sizeof(*dire), &next_block,
4305 ++ &next_offset))
4306 ++ goto failed_read;
4307 ++
4308 ++ length += sizeof(*dire);
4309 ++ }
4310 ++
4311 ++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4312 ++ next_block, next_offset,
4313 ++ dire->size + 1, &next_block,
4314 ++ &next_offset))
4315 ++ goto failed_read;
4316 ++
4317 ++ length += dire->size + 1;
4318 ++
4319 ++ if (file->f_pos >= length)
4320 ++ continue;
4321 ++
4322 ++ dire->name[dire->size + 1] = '\0';
4323 ++
4324 ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
4325 ++ (unsigned int) dirent, dire->name,
4326 ++ dire->size + 1, (int) file->f_pos,
4327 ++ dirh.start_block, dire->offset,
4328 ++ squashfs_filetype_table[dire->type]);
4329 ++
4330 ++ if (filldir(dirent, dire->name, dire->size + 1,
4331 ++ file->f_pos, SQUASHFS_MK_VFS_INODE(
4332 ++ dirh.start_block, dire->offset),
4333 ++ squashfs_filetype_table[dire->type])
4334 ++ < 0) {
4335 ++ TRACE("Filldir returned less than 0\n");
4336 ++ goto finish;
4337 ++ }
4338 ++ file->f_pos = length;
4339 ++ }
4340 ++ }
4341 ++
4342 ++finish:
4343 ++ kfree(dire);
4344 ++ return 0;
4345 ++
4346 ++failed_read:
4347 ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4348 ++ next_offset);
4349 ++ kfree(dire);
4350 ++ return 0;
4351 ++}
4352 ++
4353 ++
4354 ++static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
4355 ++ struct nameidata *nd)
4356 ++{
4357 ++ const unsigned char *name = dentry->d_name.name;
4358 ++ int len = dentry->d_name.len;
4359 ++ struct inode *inode = NULL;
4360 ++ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4361 ++ struct squashfs_super_block *sblk = &msblk->sblk;
4362 ++ long long next_block = SQUASHFS_I(i)->start_block +
4363 ++ sblk->directory_table_start;
4364 ++ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4365 ++ dir_count;
4366 ++ struct squashfs_dir_header_2 dirh;
4367 ++ struct squashfs_dir_entry_2 *dire;
4368 ++ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
4369 ++
4370 ++ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset);
4371 ++
4372 ++ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4373 ++ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4374 ++ ERROR("Failed to allocate squashfs_dir_entry\n");
4375 ++ goto exit_loop;
4376 ++ }
4377 ++
4378 ++ if (len > SQUASHFS_NAME_LEN)
4379 ++ goto exit_loop;
4380 ++
4381 ++ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4382 ++ SQUASHFS_I(i)->u.s2.directory_index_start,
4383 ++ SQUASHFS_I(i)->u.s2.directory_index_offset,
4384 ++ SQUASHFS_I(i)->u.s2.directory_index_count, name,
4385 ++ len);
4386 ++
4387 ++ while (length < i_size_read(i)) {
4388 ++ /* read directory header */
4389 ++ if (msblk->swap) {
4390 ++ struct squashfs_dir_header_2 sdirh;
4391 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4392 ++ next_block, next_offset, sizeof(sdirh),
4393 ++ &next_block, &next_offset))
4394 ++ goto failed_read;
4395 ++
4396 ++ length += sizeof(sdirh);
4397 ++ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4398 ++ } else {
4399 ++ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4400 ++ next_block, next_offset, sizeof(dirh),
4401 ++ &next_block, &next_offset))
4402 ++ goto failed_read;
4403 ++
4404 ++ length += sizeof(dirh);
4405 ++ }
4406 ++
4407 ++ dir_count = dirh.count + 1;
4408 ++ while (dir_count--) {
4409 ++ if (msblk->swap) {
4410 ++ struct squashfs_dir_entry_2 sdire;
4411 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
4412 ++ &sdire, next_block,next_offset,
4413 ++ sizeof(sdire), &next_block,
4414 ++ &next_offset))
4415 ++ goto failed_read;
4416 ++
4417 ++ length += sizeof(sdire);
4418 ++ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4419 ++ } else {
4420 ++ if (!squashfs_get_cached_block(i->i_sb, (char *)
4421 ++ dire, next_block,next_offset,
4422 ++ sizeof(*dire), &next_block,
4423 ++ &next_offset))
4424 ++ goto failed_read;
4425 ++
4426 ++ length += sizeof(*dire);
4427 ++ }
4428 ++
4429 ++ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4430 ++ next_block, next_offset, dire->size + 1,
4431 ++ &next_block, &next_offset))
4432 ++ goto failed_read;
4433 ++
4434 ++ length += dire->size + 1;
4435 ++
4436 ++ if (sorted && name[0] < dire->name[0])
4437 ++ goto exit_loop;
4438 ++
4439 ++ if ((len == dire->size + 1) && !strncmp(name,
4440 ++ dire->name, len)) {
4441 ++ squashfs_inode_t ino =
4442 ++ SQUASHFS_MKINODE(dirh.start_block,
4443 ++ dire->offset);
4444 ++ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block,
4445 ++ dire->offset);
4446 ++
4447 ++ TRACE("calling squashfs_iget for directory "
4448 ++ "entry %s, inode %x:%x, %lld\n", name,
4449 ++ dirh.start_block, dire->offset, ino);
4450 ++
4451 ++ inode = squashfs_iget(i->i_sb, ino, inode_number);
4452 ++
4453 ++ goto exit_loop;
4454 ++ }
4455 ++ }
4456 ++ }
4457 ++
4458 ++exit_loop:
4459 ++ kfree(dire);
4460 ++ d_add(dentry, inode);
4461 ++ return ERR_PTR(0);
4462 ++
4463 ++failed_read:
4464 ++ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4465 ++ next_offset);
4466 ++ goto exit_loop;
4467 ++}
4468 ++
4469 ++
4470 ++int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
4471 ++{
4472 ++ struct squashfs_super_block *sblk = &msblk->sblk;
4473 ++
4474 ++ msblk->read_inode = squashfs_read_inode_2;
4475 ++ msblk->read_fragment_index_table = read_fragment_index_table_2;
4476 ++
4477 ++ sblk->bytes_used = sblk->bytes_used_2;
4478 ++ sblk->uid_start = sblk->uid_start_2;
4479 ++ sblk->guid_start = sblk->guid_start_2;
4480 ++ sblk->inode_table_start = sblk->inode_table_start_2;
4481 ++ sblk->directory_table_start = sblk->directory_table_start_2;
4482 ++ sblk->fragment_table_start = sblk->fragment_table_start_2;
4483 ++
4484 ++ return 1;
4485 ++}
4486 +--- /dev/null
4487 ++++ b/include/linux/squashfs_fs.h
4488 +@@ -0,0 +1,934 @@
4489 ++#ifndef SQUASHFS_FS
4490 ++#define SQUASHFS_FS
4491 ++
4492 ++/*
4493 ++ * Squashfs
4494 ++ *
4495 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
4496 ++ * Phillip Lougher <phillip@×××××××××××.uk>
4497 ++ *
4498 ++ * This program is free software; you can redistribute it and/or
4499 ++ * modify it under the terms of the GNU General Public License
4500 ++ * as published by the Free Software Foundation; either version 2,
4501 ++ * or (at your option) any later version.
4502 ++ *
4503 ++ * This program is distributed in the hope that it will be useful,
4504 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4505 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4506 ++ * GNU General Public License for more details.
4507 ++ *
4508 ++ * You should have received a copy of the GNU General Public License
4509 ++ * along with this program; if not, write to the Free Software
4510 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4511 ++ *
4512 ++ * squashfs_fs.h
4513 ++ */
4514 ++
4515 ++#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
4516 ++#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
4517 ++#endif
4518 ++
4519 ++#ifdef CONFIG_SQUASHFS_VMALLOC
4520 ++#define SQUASHFS_ALLOC(a) vmalloc(a)
4521 ++#define SQUASHFS_FREE(a) vfree(a)
4522 ++#else
4523 ++#define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL)
4524 ++#define SQUASHFS_FREE(a) kfree(a)
4525 ++#endif
4526 ++#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
4527 ++#define SQUASHFS_MAJOR 3
4528 ++#define SQUASHFS_MINOR 0
4529 ++#define SQUASHFS_MAGIC 0x73717368
4530 ++#define SQUASHFS_MAGIC_SWAP 0x68737173
4531 ++#define SQUASHFS_START 0
4532 ++
4533 ++/* size of metadata (inode and directory) blocks */
4534 ++#define SQUASHFS_METADATA_SIZE 8192
4535 ++#define SQUASHFS_METADATA_LOG 13
4536 ++
4537 ++/* default size of data blocks */
4538 ++#define SQUASHFS_FILE_SIZE 65536
4539 ++#define SQUASHFS_FILE_LOG 16
4540 ++
4541 ++#define SQUASHFS_FILE_MAX_SIZE 65536
4542 ++
4543 ++/* Max number of uids and gids */
4544 ++#define SQUASHFS_UIDS 256
4545 ++#define SQUASHFS_GUIDS 255
4546 ++
4547 ++/* Max length of filename (not 255) */
4548 ++#define SQUASHFS_NAME_LEN 256
4549 ++
4550 ++#define SQUASHFS_INVALID ((long long) 0xffffffffffff)
4551 ++#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
4552 ++#define SQUASHFS_INVALID_BLK ((long long) -1)
4553 ++#define SQUASHFS_USED_BLK ((long long) -2)
4554 ++
4555 ++/* Filesystem flags */
4556 ++#define SQUASHFS_NOI 0
4557 ++#define SQUASHFS_NOD 1
4558 ++#define SQUASHFS_CHECK 2
4559 ++#define SQUASHFS_NOF 3
4560 ++#define SQUASHFS_NO_FRAG 4
4561 ++#define SQUASHFS_ALWAYS_FRAG 5
4562 ++#define SQUASHFS_DUPLICATE 6
4563 ++#define SQUASHFS_EXPORT 7
4564 ++
4565 ++#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
4566 ++
4567 ++#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
4568 ++ SQUASHFS_NOI)
4569 ++
4570 ++#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
4571 ++ SQUASHFS_NOD)
4572 ++
4573 ++#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
4574 ++ SQUASHFS_NOF)
4575 ++
4576 ++#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
4577 ++ SQUASHFS_NO_FRAG)
4578 ++
4579 ++#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
4580 ++ SQUASHFS_ALWAYS_FRAG)
4581 ++
4582 ++#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
4583 ++ SQUASHFS_DUPLICATE)
4584 ++
4585 ++#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
4586 ++ SQUASHFS_EXPORT)
4587 ++
4588 ++#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
4589 ++ SQUASHFS_CHECK)
4590 ++
4591 ++#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
4592 ++ duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \
4593 ++ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
4594 ++ (duplicate_checking << 6) | (exportable << 7))
4595 ++
4596 ++/* Max number of types and file types */
4597 ++#define SQUASHFS_DIR_TYPE 1
4598 ++#define SQUASHFS_FILE_TYPE 2
4599 ++#define SQUASHFS_SYMLINK_TYPE 3
4600 ++#define SQUASHFS_BLKDEV_TYPE 4
4601 ++#define SQUASHFS_CHRDEV_TYPE 5
4602 ++#define SQUASHFS_FIFO_TYPE 6
4603 ++#define SQUASHFS_SOCKET_TYPE 7
4604 ++#define SQUASHFS_LDIR_TYPE 8
4605 ++#define SQUASHFS_LREG_TYPE 9
4606 ++
4607 ++/* 1.0 filesystem type definitions */
4608 ++#define SQUASHFS_TYPES 5
4609 ++#define SQUASHFS_IPC_TYPE 0
4610 ++
4611 ++/* Flag whether block is compressed or uncompressed, bit is set if block is
4612 ++ * uncompressed */
4613 ++#define SQUASHFS_COMPRESSED_BIT (1 << 15)
4614 ++
4615 ++#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
4616 ++ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
4617 ++
4618 ++#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
4619 ++
4620 ++#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
4621 ++
4622 ++#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \
4623 ++ ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \
4624 ++ ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK)
4625 ++
4626 ++#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
4627 ++
4628 ++/*
4629 ++ * Inode number ops. Inodes consist of a compressed block number, and an
4630 ++ * uncompressed offset within that block
4631 ++ */
4632 ++#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
4633 ++
4634 ++#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
4635 ++
4636 ++#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
4637 ++ << 16) + (B)))
4638 ++
4639 ++/* Compute 32 bit VFS inode number from squashfs inode number */
4640 ++#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
4641 ++ ((b) >> 2) + 1))
4642 ++/* XXX */
4643 ++
4644 ++/* Translate between VFS mode and squashfs mode */
4645 ++#define SQUASHFS_MODE(a) ((a) & 0xfff)
4646 ++
4647 ++/* fragment and fragment table defines */
4648 ++#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry))
4649 ++
4650 ++#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
4651 ++ SQUASHFS_METADATA_SIZE)
4652 ++
4653 ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
4654 ++ SQUASHFS_METADATA_SIZE)
4655 ++
4656 ++#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
4657 ++ SQUASHFS_METADATA_SIZE - 1) / \
4658 ++ SQUASHFS_METADATA_SIZE)
4659 ++
4660 ++#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
4661 ++ sizeof(long long))
4662 ++
4663 ++/* inode lookup table defines */
4664 ++#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t))
4665 ++
4666 ++#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
4667 ++ SQUASHFS_METADATA_SIZE)
4668 ++
4669 ++#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
4670 ++ SQUASHFS_METADATA_SIZE)
4671 ++
4672 ++#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
4673 ++ SQUASHFS_METADATA_SIZE - 1) / \
4674 ++ SQUASHFS_METADATA_SIZE)
4675 ++
4676 ++#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
4677 ++ sizeof(long long))
4678 ++
4679 ++/* cached data constants for filesystem */
4680 ++#define SQUASHFS_CACHED_BLKS 8
4681 ++
4682 ++#define SQUASHFS_MAX_FILE_SIZE_LOG 64
4683 ++
4684 ++#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
4685 ++ (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
4686 ++
4687 ++#define SQUASHFS_MARKER_BYTE 0xff
4688 ++
4689 ++/* meta index cache */
4690 ++#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
4691 ++#define SQUASHFS_META_ENTRIES 31
4692 ++#define SQUASHFS_META_NUMBER 8
4693 ++#define SQUASHFS_SLOTS 4
4694 ++
4695 ++struct meta_entry {
4696 ++ long long data_block;
4697 ++ unsigned int index_block;
4698 ++ unsigned short offset;
4699 ++ unsigned short pad;
4700 ++};
4701 ++
4702 ++struct meta_index {
4703 ++ unsigned int inode_number;
4704 ++ unsigned int offset;
4705 ++ unsigned short entries;
4706 ++ unsigned short skip;
4707 ++ unsigned short locked;
4708 ++ unsigned short pad;
4709 ++ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
4710 ++};
4711 ++
4712 ++
4713 ++/*
4714 ++ * definitions for structures on disk
4715 ++ */
4716 ++
4717 ++typedef long long squashfs_block_t;
4718 ++typedef long long squashfs_inode_t;
4719 ++
4720 ++struct squashfs_super_block {
4721 ++ unsigned int s_magic;
4722 ++ unsigned int inodes;
4723 ++ unsigned int bytes_used_2;
4724 ++ unsigned int uid_start_2;
4725 ++ unsigned int guid_start_2;
4726 ++ unsigned int inode_table_start_2;
4727 ++ unsigned int directory_table_start_2;
4728 ++ unsigned int s_major:16;
4729 ++ unsigned int s_minor:16;
4730 ++ unsigned int block_size_1:16;
4731 ++ unsigned int block_log:16;
4732 ++ unsigned int flags:8;
4733 ++ unsigned int no_uids:8;
4734 ++ unsigned int no_guids:8;
4735 ++ unsigned int mkfs_time /* time of filesystem creation */;
4736 ++ squashfs_inode_t root_inode;
4737 ++ unsigned int block_size;
4738 ++ unsigned int fragments;
4739 ++ unsigned int fragment_table_start_2;
4740 ++ long long bytes_used;
4741 ++ long long uid_start;
4742 ++ long long guid_start;
4743 ++ long long inode_table_start;
4744 ++ long long directory_table_start;
4745 ++ long long fragment_table_start;
4746 ++ long long lookup_table_start;
4747 ++} __attribute__ ((packed));
4748 ++
4749 ++struct squashfs_dir_index {
4750 ++ unsigned int index;
4751 ++ unsigned int start_block;
4752 ++ unsigned char size;
4753 ++ unsigned char name[0];
4754 ++} __attribute__ ((packed));
4755 ++
4756 ++#define SQUASHFS_BASE_INODE_HEADER \
4757 ++ unsigned int inode_type:4; \
4758 ++ unsigned int mode:12; \
4759 ++ unsigned int uid:8; \
4760 ++ unsigned int guid:8; \
4761 ++ unsigned int mtime; \
4762 ++ unsigned int inode_number;
4763 ++
4764 ++struct squashfs_base_inode_header {
4765 ++ SQUASHFS_BASE_INODE_HEADER;
4766 ++} __attribute__ ((packed));
4767 ++
4768 ++struct squashfs_ipc_inode_header {
4769 ++ SQUASHFS_BASE_INODE_HEADER;
4770 ++ unsigned int nlink;
4771 ++} __attribute__ ((packed));
4772 ++
4773 ++struct squashfs_dev_inode_header {
4774 ++ SQUASHFS_BASE_INODE_HEADER;
4775 ++ unsigned int nlink;
4776 ++ unsigned short rdev;
4777 ++} __attribute__ ((packed));
4778 ++
4779 ++struct squashfs_symlink_inode_header {
4780 ++ SQUASHFS_BASE_INODE_HEADER;
4781 ++ unsigned int nlink;
4782 ++ unsigned short symlink_size;
4783 ++ char symlink[0];
4784 ++} __attribute__ ((packed));
4785 ++
4786 ++struct squashfs_reg_inode_header {
4787 ++ SQUASHFS_BASE_INODE_HEADER;
4788 ++ squashfs_block_t start_block;
4789 ++ unsigned int fragment;
4790 ++ unsigned int offset;
4791 ++ unsigned int file_size;
4792 ++ unsigned short block_list[0];
4793 ++} __attribute__ ((packed));
4794 ++
4795 ++struct squashfs_lreg_inode_header {
4796 ++ SQUASHFS_BASE_INODE_HEADER;
4797 ++ unsigned int nlink;
4798 ++ squashfs_block_t start_block;
4799 ++ unsigned int fragment;
4800 ++ unsigned int offset;
4801 ++ long long file_size;
4802 ++ unsigned short block_list[0];
4803 ++} __attribute__ ((packed));
4804 ++
4805 ++struct squashfs_dir_inode_header {
4806 ++ SQUASHFS_BASE_INODE_HEADER;
4807 ++ unsigned int nlink;
4808 ++ unsigned int file_size:19;
4809 ++ unsigned int offset:13;
4810 ++ unsigned int start_block;
4811 ++ unsigned int parent_inode;
4812 ++} __attribute__ ((packed));
4813 ++
4814 ++struct squashfs_ldir_inode_header {
4815 ++ SQUASHFS_BASE_INODE_HEADER;
4816 ++ unsigned int nlink;
4817 ++ unsigned int file_size:27;
4818 ++ unsigned int offset:13;
4819 ++ unsigned int start_block;
4820 ++ unsigned int i_count:16;
4821 ++ unsigned int parent_inode;
4822 ++ struct squashfs_dir_index index[0];
4823 ++} __attribute__ ((packed));
4824 ++
4825 ++union squashfs_inode_header {
4826 ++ struct squashfs_base_inode_header base;
4827 ++ struct squashfs_dev_inode_header dev;
4828 ++ struct squashfs_symlink_inode_header symlink;
4829 ++ struct squashfs_reg_inode_header reg;
4830 ++ struct squashfs_lreg_inode_header lreg;
4831 ++ struct squashfs_dir_inode_header dir;
4832 ++ struct squashfs_ldir_inode_header ldir;
4833 ++ struct squashfs_ipc_inode_header ipc;
4834 ++};
4835 ++
4836 ++struct squashfs_dir_entry {
4837 ++ unsigned int offset:13;
4838 ++ unsigned int type:3;
4839 ++ unsigned int size:8;
4840 ++ int inode_number:16;
4841 ++ char name[0];
4842 ++} __attribute__ ((packed));
4843 ++
4844 ++struct squashfs_dir_header {
4845 ++ unsigned int count:8;
4846 ++ unsigned int start_block;
4847 ++ unsigned int inode_number;
4848 ++} __attribute__ ((packed));
4849 ++
4850 ++struct squashfs_fragment_entry {
4851 ++ long long start_block;
4852 ++ unsigned int size;
4853 ++ unsigned int pending;
4854 ++} __attribute__ ((packed));
4855 ++
4856 ++extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
4857 ++extern int squashfs_uncompress_init(void);
4858 ++extern int squashfs_uncompress_exit(void);
4859 ++
4860 ++/*
4861 ++ * macros to convert each packed bitfield structure from little endian to big
4862 ++ * endian and vice versa. These are needed when creating or using a filesystem
4863 ++ * on a machine with different byte ordering to the target architecture.
4864 ++ *
4865 ++ */
4866 ++
4867 ++#define SQUASHFS_SWAP_START \
4868 ++ int bits;\
4869 ++ int b_pos;\
4870 ++ unsigned long long val;\
4871 ++ unsigned char *s;\
4872 ++ unsigned char *d;
4873 ++
4874 ++#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
4875 ++ SQUASHFS_SWAP_START\
4876 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
4877 ++ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
4878 ++ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
4879 ++ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
4880 ++ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
4881 ++ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
4882 ++ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
4883 ++ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
4884 ++ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
4885 ++ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
4886 ++ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
4887 ++ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
4888 ++ SQUASHFS_SWAP((s)->flags, d, 288, 8);\
4889 ++ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
4890 ++ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
4891 ++ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
4892 ++ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
4893 ++ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
4894 ++ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
4895 ++ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
4896 ++ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
4897 ++ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
4898 ++ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
4899 ++ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
4900 ++ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
4901 ++ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
4902 ++ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\
4903 ++}
4904 ++
4905 ++#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
4906 ++ SQUASHFS_MEMSET(s, d, n);\
4907 ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
4908 ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
4909 ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
4910 ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
4911 ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
4912 ++ SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
4913 ++
4914 ++#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
4915 ++ SQUASHFS_SWAP_START\
4916 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
4917 ++}
4918 ++
4919 ++#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
4920 ++ SQUASHFS_SWAP_START\
4921 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4922 ++ sizeof(struct squashfs_ipc_inode_header))\
4923 ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
4924 ++}
4925 ++
4926 ++#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
4927 ++ SQUASHFS_SWAP_START\
4928 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4929 ++ sizeof(struct squashfs_dev_inode_header)); \
4930 ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
4931 ++ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
4932 ++}
4933 ++
4934 ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
4935 ++ SQUASHFS_SWAP_START\
4936 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4937 ++ sizeof(struct squashfs_symlink_inode_header));\
4938 ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
4939 ++ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
4940 ++}
4941 ++
4942 ++#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
4943 ++ SQUASHFS_SWAP_START\
4944 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4945 ++ sizeof(struct squashfs_reg_inode_header));\
4946 ++ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
4947 ++ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
4948 ++ SQUASHFS_SWAP((s)->offset, d, 192, 32);\
4949 ++ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
4950 ++}
4951 ++
4952 ++#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
4953 ++ SQUASHFS_SWAP_START\
4954 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4955 ++ sizeof(struct squashfs_lreg_inode_header));\
4956 ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
4957 ++ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
4958 ++ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
4959 ++ SQUASHFS_SWAP((s)->offset, d, 224, 32);\
4960 ++ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
4961 ++}
4962 ++
4963 ++#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
4964 ++ SQUASHFS_SWAP_START\
4965 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4966 ++ sizeof(struct squashfs_dir_inode_header));\
4967 ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
4968 ++ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
4969 ++ SQUASHFS_SWAP((s)->offset, d, 147, 13);\
4970 ++ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
4971 ++ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
4972 ++}
4973 ++
4974 ++#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
4975 ++ SQUASHFS_SWAP_START\
4976 ++ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
4977 ++ sizeof(struct squashfs_ldir_inode_header));\
4978 ++ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
4979 ++ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
4980 ++ SQUASHFS_SWAP((s)->offset, d, 155, 13);\
4981 ++ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
4982 ++ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
4983 ++ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
4984 ++}
4985 ++
4986 ++#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
4987 ++ SQUASHFS_SWAP_START\
4988 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
4989 ++ SQUASHFS_SWAP((s)->index, d, 0, 32);\
4990 ++ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
4991 ++ SQUASHFS_SWAP((s)->size, d, 64, 8);\
4992 ++}
4993 ++
4994 ++#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
4995 ++ SQUASHFS_SWAP_START\
4996 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
4997 ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\
4998 ++ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
4999 ++ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
5000 ++}
5001 ++
5002 ++#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
5003 ++ SQUASHFS_SWAP_START\
5004 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
5005 ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
5006 ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\
5007 ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\
5008 ++ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
5009 ++}
5010 ++
5011 ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
5012 ++ SQUASHFS_SWAP_START\
5013 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
5014 ++ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
5015 ++ SQUASHFS_SWAP((s)->size, d, 64, 32);\
5016 ++}
5017 ++
5018 ++#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1)
5019 ++
5020 ++#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
5021 ++ int entry;\
5022 ++ int bit_position;\
5023 ++ SQUASHFS_SWAP_START\
5024 ++ SQUASHFS_MEMSET(s, d, n * 2);\
5025 ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
5026 ++ 16)\
5027 ++ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
5028 ++}
5029 ++
5030 ++#define SQUASHFS_SWAP_INTS(s, d, n) {\
5031 ++ int entry;\
5032 ++ int bit_position;\
5033 ++ SQUASHFS_SWAP_START\
5034 ++ SQUASHFS_MEMSET(s, d, n * 4);\
5035 ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
5036 ++ 32)\
5037 ++ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
5038 ++}
5039 ++
5040 ++#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
5041 ++ int entry;\
5042 ++ int bit_position;\
5043 ++ SQUASHFS_SWAP_START\
5044 ++ SQUASHFS_MEMSET(s, d, n * 8);\
5045 ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
5046 ++ 64)\
5047 ++ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
5048 ++}
5049 ++
5050 ++#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
5051 ++ int entry;\
5052 ++ int bit_position;\
5053 ++ SQUASHFS_SWAP_START\
5054 ++ SQUASHFS_MEMSET(s, d, n * bits / 8);\
5055 ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
5056 ++ bits)\
5057 ++ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
5058 ++}
5059 ++
5060 ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
5061 ++#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
5062 ++
5063 ++#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5064 ++
5065 ++struct squashfs_base_inode_header_1 {
5066 ++ unsigned int inode_type:4;
5067 ++ unsigned int mode:12; /* protection */
5068 ++ unsigned int uid:4; /* index into uid table */
5069 ++ unsigned int guid:4; /* index into guid table */
5070 ++} __attribute__ ((packed));
5071 ++
5072 ++struct squashfs_ipc_inode_header_1 {
5073 ++ unsigned int inode_type:4;
5074 ++ unsigned int mode:12; /* protection */
5075 ++ unsigned int uid:4; /* index into uid table */
5076 ++ unsigned int guid:4; /* index into guid table */
5077 ++ unsigned int type:4;
5078 ++ unsigned int offset:4;
5079 ++} __attribute__ ((packed));
5080 ++
5081 ++struct squashfs_dev_inode_header_1 {
5082 ++ unsigned int inode_type:4;
5083 ++ unsigned int mode:12; /* protection */
5084 ++ unsigned int uid:4; /* index into uid table */
5085 ++ unsigned int guid:4; /* index into guid table */
5086 ++ unsigned short rdev;
5087 ++} __attribute__ ((packed));
5088 ++
5089 ++struct squashfs_symlink_inode_header_1 {
5090 ++ unsigned int inode_type:4;
5091 ++ unsigned int mode:12; /* protection */
5092 ++ unsigned int uid:4; /* index into uid table */
5093 ++ unsigned int guid:4; /* index into guid table */
5094 ++ unsigned short symlink_size;
5095 ++ char symlink[0];
5096 ++} __attribute__ ((packed));
5097 ++
5098 ++struct squashfs_reg_inode_header_1 {
5099 ++ unsigned int inode_type:4;
5100 ++ unsigned int mode:12; /* protection */
5101 ++ unsigned int uid:4; /* index into uid table */
5102 ++ unsigned int guid:4; /* index into guid table */
5103 ++ unsigned int mtime;
5104 ++ unsigned int start_block;
5105 ++ unsigned int file_size:32;
5106 ++ unsigned short block_list[0];
5107 ++} __attribute__ ((packed));
5108 ++
5109 ++struct squashfs_dir_inode_header_1 {
5110 ++ unsigned int inode_type:4;
5111 ++ unsigned int mode:12; /* protection */
5112 ++ unsigned int uid:4; /* index into uid table */
5113 ++ unsigned int guid:4; /* index into guid table */
5114 ++ unsigned int file_size:19;
5115 ++ unsigned int offset:13;
5116 ++ unsigned int mtime;
5117 ++ unsigned int start_block:24;
5118 ++} __attribute__ ((packed));
5119 ++
5120 ++#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
5121 ++ SQUASHFS_MEMSET(s, d, n);\
5122 ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
5123 ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
5124 ++ SQUASHFS_SWAP((s)->uid, d, 16, 4);\
5125 ++ SQUASHFS_SWAP((s)->guid, d, 20, 4);
5126 ++
5127 ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
5128 ++ SQUASHFS_SWAP_START\
5129 ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
5130 ++}
5131 ++
5132 ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
5133 ++ SQUASHFS_SWAP_START\
5134 ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
5135 ++ sizeof(struct squashfs_ipc_inode_header_1));\
5136 ++ SQUASHFS_SWAP((s)->type, d, 24, 4);\
5137 ++ SQUASHFS_SWAP((s)->offset, d, 28, 4);\
5138 ++}
5139 ++
5140 ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
5141 ++ SQUASHFS_SWAP_START\
5142 ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
5143 ++ sizeof(struct squashfs_dev_inode_header_1));\
5144 ++ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
5145 ++}
5146 ++
5147 ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
5148 ++ SQUASHFS_SWAP_START\
5149 ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
5150 ++ sizeof(struct squashfs_symlink_inode_header_1));\
5151 ++ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
5152 ++}
5153 ++
5154 ++#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
5155 ++ SQUASHFS_SWAP_START\
5156 ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
5157 ++ sizeof(struct squashfs_reg_inode_header_1));\
5158 ++ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
5159 ++ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
5160 ++ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
5161 ++}
5162 ++
5163 ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
5164 ++ SQUASHFS_SWAP_START\
5165 ++ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
5166 ++ sizeof(struct squashfs_dir_inode_header_1));\
5167 ++ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
5168 ++ SQUASHFS_SWAP((s)->offset, d, 43, 13);\
5169 ++ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
5170 ++ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
5171 ++}
5172 ++
5173 ++#endif
5174 ++
5175 ++#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5176 ++
5177 ++struct squashfs_dir_index_2 {
5178 ++ unsigned int index:27;
5179 ++ unsigned int start_block:29;
5180 ++ unsigned char size;
5181 ++ unsigned char name[0];
5182 ++} __attribute__ ((packed));
5183 ++
5184 ++struct squashfs_base_inode_header_2 {
5185 ++ unsigned int inode_type:4;
5186 ++ unsigned int mode:12; /* protection */
5187 ++ unsigned int uid:8; /* index into uid table */
5188 ++ unsigned int guid:8; /* index into guid table */
5189 ++} __attribute__ ((packed));
5190 ++
5191 ++struct squashfs_ipc_inode_header_2 {
5192 ++ unsigned int inode_type:4;
5193 ++ unsigned int mode:12; /* protection */
5194 ++ unsigned int uid:8; /* index into uid table */
5195 ++ unsigned int guid:8; /* index into guid table */
5196 ++} __attribute__ ((packed));
5197 ++
5198 ++struct squashfs_dev_inode_header_2 {
5199 ++ unsigned int inode_type:4;
5200 ++ unsigned int mode:12; /* protection */
5201 ++ unsigned int uid:8; /* index into uid table */
5202 ++ unsigned int guid:8; /* index into guid table */
5203 ++ unsigned short rdev;
5204 ++} __attribute__ ((packed));
5205 ++
5206 ++struct squashfs_symlink_inode_header_2 {
5207 ++ unsigned int inode_type:4;
5208 ++ unsigned int mode:12; /* protection */
5209 ++ unsigned int uid:8; /* index into uid table */
5210 ++ unsigned int guid:8; /* index into guid table */
5211 ++ unsigned short symlink_size;
5212 ++ char symlink[0];
5213 ++} __attribute__ ((packed));
5214 ++
5215 ++struct squashfs_reg_inode_header_2 {
5216 ++ unsigned int inode_type:4;
5217 ++ unsigned int mode:12; /* protection */
5218 ++ unsigned int uid:8; /* index into uid table */
5219 ++ unsigned int guid:8; /* index into guid table */
5220 ++ unsigned int mtime;
5221 ++ unsigned int start_block;
5222 ++ unsigned int fragment;
5223 ++ unsigned int offset;
5224 ++ unsigned int file_size:32;
5225 ++ unsigned short block_list[0];
5226 ++} __attribute__ ((packed));
5227 ++
5228 ++struct squashfs_dir_inode_header_2 {
5229 ++ unsigned int inode_type:4;
5230 ++ unsigned int mode:12; /* protection */
5231 ++ unsigned int uid:8; /* index into uid table */
5232 ++ unsigned int guid:8; /* index into guid table */
5233 ++ unsigned int file_size:19;
5234 ++ unsigned int offset:13;
5235 ++ unsigned int mtime;
5236 ++ unsigned int start_block:24;
5237 ++} __attribute__ ((packed));
5238 ++
5239 ++struct squashfs_ldir_inode_header_2 {
5240 ++ unsigned int inode_type:4;
5241 ++ unsigned int mode:12; /* protection */
5242 ++ unsigned int uid:8; /* index into uid table */
5243 ++ unsigned int guid:8; /* index into guid table */
5244 ++ unsigned int file_size:27;
5245 ++ unsigned int offset:13;
5246 ++ unsigned int mtime;
5247 ++ unsigned int start_block:24;
5248 ++ unsigned int i_count:16;
5249 ++ struct squashfs_dir_index_2 index[0];
5250 ++} __attribute__ ((packed));
5251 ++
5252 ++union squashfs_inode_header_2 {
5253 ++ struct squashfs_base_inode_header_2 base;
5254 ++ struct squashfs_dev_inode_header_2 dev;
5255 ++ struct squashfs_symlink_inode_header_2 symlink;
5256 ++ struct squashfs_reg_inode_header_2 reg;
5257 ++ struct squashfs_dir_inode_header_2 dir;
5258 ++ struct squashfs_ldir_inode_header_2 ldir;
5259 ++ struct squashfs_ipc_inode_header_2 ipc;
5260 ++};
5261 ++
5262 ++struct squashfs_dir_header_2 {
5263 ++ unsigned int count:8;
5264 ++ unsigned int start_block:24;
5265 ++} __attribute__ ((packed));
5266 ++
5267 ++struct squashfs_dir_entry_2 {
5268 ++ unsigned int offset:13;
5269 ++ unsigned int type:3;
5270 ++ unsigned int size:8;
5271 ++ char name[0];
5272 ++} __attribute__ ((packed));
5273 ++
5274 ++struct squashfs_fragment_entry_2 {
5275 ++ unsigned int start_block;
5276 ++ unsigned int size;
5277 ++} __attribute__ ((packed));
5278 ++
5279 ++#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
5280 ++ SQUASHFS_MEMSET(s, d, n);\
5281 ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
5282 ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
5283 ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
5284 ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
5285 ++
5286 ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
5287 ++ SQUASHFS_SWAP_START\
5288 ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
5289 ++}
5290 ++
5291 ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
5292 ++ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
5293 ++
5294 ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
5295 ++ SQUASHFS_SWAP_START\
5296 ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
5297 ++ sizeof(struct squashfs_dev_inode_header_2)); \
5298 ++ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
5299 ++}
5300 ++
5301 ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
5302 ++ SQUASHFS_SWAP_START\
5303 ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
5304 ++ sizeof(struct squashfs_symlink_inode_header_2));\
5305 ++ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
5306 ++}
5307 ++
5308 ++#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
5309 ++ SQUASHFS_SWAP_START\
5310 ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
5311 ++ sizeof(struct squashfs_reg_inode_header_2));\
5312 ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
5313 ++ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
5314 ++ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
5315 ++ SQUASHFS_SWAP((s)->offset, d, 128, 32);\
5316 ++ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
5317 ++}
5318 ++
5319 ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
5320 ++ SQUASHFS_SWAP_START\
5321 ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
5322 ++ sizeof(struct squashfs_dir_inode_header_2));\
5323 ++ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
5324 ++ SQUASHFS_SWAP((s)->offset, d, 51, 13);\
5325 ++ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
5326 ++ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
5327 ++}
5328 ++
5329 ++#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
5330 ++ SQUASHFS_SWAP_START\
5331 ++ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
5332 ++ sizeof(struct squashfs_ldir_inode_header_2));\
5333 ++ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
5334 ++ SQUASHFS_SWAP((s)->offset, d, 59, 13);\
5335 ++ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
5336 ++ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
5337 ++ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
5338 ++}
5339 ++
5340 ++#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
5341 ++ SQUASHFS_SWAP_START\
5342 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
5343 ++ SQUASHFS_SWAP((s)->index, d, 0, 27);\
5344 ++ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
5345 ++ SQUASHFS_SWAP((s)->size, d, 56, 8);\
5346 ++}
5347 ++#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
5348 ++ SQUASHFS_SWAP_START\
5349 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
5350 ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\
5351 ++ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
5352 ++}
5353 ++
5354 ++#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
5355 ++ SQUASHFS_SWAP_START\
5356 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
5357 ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
5358 ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\
5359 ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\
5360 ++}
5361 ++
5362 ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
5363 ++ SQUASHFS_SWAP_START\
5364 ++ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
5365 ++ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
5366 ++ SQUASHFS_SWAP((s)->size, d, 32, 32);\
5367 ++}
5368 ++
5369 ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
5370 ++
5371 ++/* fragment and fragment table defines */
5372 ++#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
5373 ++
5374 ++#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
5375 ++ SQUASHFS_METADATA_SIZE)
5376 ++
5377 ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
5378 ++ SQUASHFS_METADATA_SIZE)
5379 ++
5380 ++#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
5381 ++ SQUASHFS_METADATA_SIZE - 1) / \
5382 ++ SQUASHFS_METADATA_SIZE)
5383 ++
5384 ++#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
5385 ++ sizeof(int))
5386 ++
5387 ++#endif
5388 ++
5389 ++#ifdef __KERNEL__
5390 ++
5391 ++/*
5392 ++ * macros used to swap each structure entry, taking into account
5393 ++ * bitfields and different bitfield placing conventions on differing
5394 ++ * architectures
5395 ++ */
5396 ++
5397 ++#include <asm/byteorder.h>
5398 ++
5399 ++#ifdef __BIG_ENDIAN
5400 ++ /* convert from little endian to big endian */
5401 ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
5402 ++ tbits, b_pos)
5403 ++#else
5404 ++ /* convert from big endian to little endian */
5405 ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
5406 ++ tbits, 64 - tbits - b_pos)
5407 ++#endif
5408 ++
5409 ++#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
5410 ++ b_pos = pos % 8;\
5411 ++ val = 0;\
5412 ++ s = (unsigned char *)p + (pos / 8);\
5413 ++ d = ((unsigned char *) &val) + 7;\
5414 ++ for(bits = 0; bits < (tbits + b_pos); bits += 8) \
5415 ++ *d-- = *s++;\
5416 ++ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
5417 ++}
5418 ++
5419 ++#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
5420 ++
5421 ++#endif
5422 ++#endif
5423 +--- /dev/null
5424 ++++ b/include/linux/squashfs_fs_i.h
5425 +@@ -0,0 +1,45 @@
5426 ++#ifndef SQUASHFS_FS_I
5427 ++#define SQUASHFS_FS_I
5428 ++/*
5429 ++ * Squashfs
5430 ++ *
5431 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
5432 ++ * Phillip Lougher <phillip@×××××××××××.uk>
5433 ++ *
5434 ++ * This program is free software; you can redistribute it and/or
5435 ++ * modify it under the terms of the GNU General Public License
5436 ++ * as published by the Free Software Foundation; either version 2,
5437 ++ * or (at your option) any later version.
5438 ++ *
5439 ++ * This program is distributed in the hope that it will be useful,
5440 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5441 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5442 ++ * GNU General Public License for more details.
5443 ++ *
5444 ++ * You should have received a copy of the GNU General Public License
5445 ++ * along with this program; if not, write to the Free Software
5446 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5447 ++ *
5448 ++ * squashfs_fs_i.h
5449 ++ */
5450 ++
5451 ++struct squashfs_inode_info {
5452 ++ long long start_block;
5453 ++ unsigned int offset;
5454 ++ union {
5455 ++ struct {
5456 ++ long long fragment_start_block;
5457 ++ unsigned int fragment_size;
5458 ++ unsigned int fragment_offset;
5459 ++ long long block_list_start;
5460 ++ } s1;
5461 ++ struct {
5462 ++ long long directory_index_start;
5463 ++ unsigned int directory_index_offset;
5464 ++ unsigned int directory_index_count;
5465 ++ unsigned int parent_inode;
5466 ++ } s2;
5467 ++ } u;
5468 ++ struct inode vfs_inode;
5469 ++};
5470 ++#endif
5471 +--- /dev/null
5472 ++++ b/include/linux/squashfs_fs_sb.h
5473 +@@ -0,0 +1,74 @@
5474 ++#ifndef SQUASHFS_FS_SB
5475 ++#define SQUASHFS_FS_SB
5476 ++/*
5477 ++ * Squashfs
5478 ++ *
5479 ++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
5480 ++ * Phillip Lougher <phillip@×××××××××××.uk>
5481 ++ *
5482 ++ * This program is free software; you can redistribute it and/or
5483 ++ * modify it under the terms of the GNU General Public License
5484 ++ * as published by the Free Software Foundation; either version 2,
5485 ++ * or (at your option) any later version.
5486 ++ *
5487 ++ * This program is distributed in the hope that it will be useful,
5488 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5489 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5490 ++ * GNU General Public License for more details.
5491 ++ *
5492 ++ * You should have received a copy of the GNU General Public License
5493 ++ * along with this program; if not, write to the Free Software
5494 ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5495 ++ *
5496 ++ * squashfs_fs_sb.h
5497 ++ */
5498 ++
5499 ++#include <linux/squashfs_fs.h>
5500 ++
5501 ++struct squashfs_cache {
5502 ++ long long block;
5503 ++ int length;
5504 ++ long long next_index;
5505 ++ char *data;
5506 ++};
5507 ++
5508 ++struct squashfs_fragment_cache {
5509 ++ long long block;
5510 ++ int length;
5511 ++ unsigned int locked;
5512 ++ char *data;
5513 ++};
5514 ++
5515 ++struct squashfs_sb_info {
5516 ++ struct squashfs_super_block sblk;
5517 ++ int devblksize;
5518 ++ int devblksize_log2;
5519 ++ int swap;
5520 ++ struct squashfs_cache *block_cache;
5521 ++ struct squashfs_fragment_cache *fragment;
5522 ++ int next_cache;
5523 ++ int next_fragment;
5524 ++ int next_meta_index;
5525 ++ unsigned int *uid;
5526 ++ unsigned int *guid;
5527 ++ long long *fragment_index;
5528 ++ unsigned int *fragment_index_2;
5529 ++ char *read_page;
5530 ++ struct mutex read_data_mutex;
5531 ++ struct mutex read_page_mutex;
5532 ++ struct mutex block_cache_mutex;
5533 ++ struct mutex fragment_mutex;
5534 ++ struct mutex meta_index_mutex;
5535 ++ wait_queue_head_t waitq;
5536 ++ wait_queue_head_t fragment_wait_queue;
5537 ++ struct meta_index *meta_index;
5538 ++ z_stream stream;
5539 ++ long long *inode_lookup_table;
5540 ++ int (*read_inode)(struct inode *i, squashfs_inode_t \
5541 ++ inode);
5542 ++ long long (*read_blocklist)(struct inode *inode, int \
5543 ++ index, int readahead_blks, char *block_list, \
5544 ++ unsigned short **block_p, unsigned int *bsize);
5545 ++ int (*read_fragment_index_table)(struct super_block *s);
5546 ++};
5547 ++#endif
5548 +--- a/init/do_mounts_rd.c
5549 ++++ b/init/do_mounts_rd.c
5550 +@@ -5,6 +5,7 @@
5551 + #include <linux/ext2_fs.h>
5552 + #include <linux/romfs_fs.h>
5553 + #include <linux/cramfs_fs.h>
5554 ++#include <linux/squashfs_fs.h>
5555 + #include <linux/initrd.h>
5556 + #include <linux/string.h>
5557 +
5558 +@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
5559 + * numbers could not be found.
5560 + *
5561 + * We currently check for the following magic numbers:
5562 ++ * squashfs
5563 + * minix
5564 + * ext2
5565 + * romfs
5566 +@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
5567 + struct ext2_super_block *ext2sb;
5568 + struct romfs_super_block *romfsb;
5569 + struct cramfs_super *cramfsb;
5570 ++ struct squashfs_super_block *squashfsb;
5571 + int nblocks = -1;
5572 + unsigned char *buf;
5573 +
5574 +@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
5575 + ext2sb = (struct ext2_super_block *) buf;
5576 + romfsb = (struct romfs_super_block *) buf;
5577 + cramfsb = (struct cramfs_super *) buf;
5578 ++ squashfsb = (struct squashfs_super_block *) buf;
5579 + memset(buf, 0xe5, size);
5580 +
5581 + /*
5582 +@@ -101,6 +105,18 @@ identify_ramdisk_image(int fd, int start
5583 + goto done;
5584 + }
5585 +
5586 ++ /* squashfs is at block zero too */
5587 ++ if (squashfsb->s_magic == SQUASHFS_MAGIC) {
5588 ++ printk(KERN_NOTICE
5589 ++ "RAMDISK: squashfs filesystem found at block %d\n",
5590 ++ start_block);
5591 ++ if (squashfsb->s_major < 3)
5592 ++ nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
5593 ++ else
5594 ++ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
5595 ++ goto done;
5596 ++ }
5597 ++
5598 + /*
5599 + * Read block 1 to test for minix and ext2 superblock
5600 + */
5601
5602 Added: hardened-sources/2.6/tags/2.6.23-5/4405_alpha-sysctl-uac.patch
5603 ===================================================================
5604 --- hardened-sources/2.6/tags/2.6.23-5/4405_alpha-sysctl-uac.patch (rev 0)
5605 +++ hardened-sources/2.6/tags/2.6.23-5/4405_alpha-sysctl-uac.patch 2008-04-30 11:40:48 UTC (rev 95)
5606 @@ -0,0 +1,187 @@
5607 +---
5608 + arch/alpha/Kconfig | 26 ++++++++++++++++++++++++
5609 + arch/alpha/kernel/traps.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++
5610 + include/linux/sysctl.h | 14 +++++++++++++
5611 + kernel/sysctl.c | 12 ++++++++++-
5612 + 4 files changed, 100 insertions(+), 1 deletion(-)
5613 +
5614 +--- a/arch/alpha/Kconfig
5615 ++++ b/arch/alpha/Kconfig
5616 +@@ -616,6 +616,32 @@ config VERBOSE_MCHECK_ON
5617 +
5618 + Take the default (1) unless you want more control or more info.
5619 +
5620 ++config ALPHA_UAC_SYSCTL
5621 ++ bool "Configure UAC policy via sysctl"
5622 ++ depends on SYSCTL
5623 ++ default y
5624 ++ ---help---
5625 ++ Configuring the UAC (unaligned access control) policy on a Linux
5626 ++ system usually involves setting a compile time define. If you say
5627 ++ Y here, you will be able to modify the UAC policy at runtime using
5628 ++ the /proc interface.
5629 ++
5630 ++ The UAC policy defines the action Linux should take when an
5631 ++ unaligned memory access occurs. The action can include printing a
5632 ++ warning message (NOPRINT), sending a signal to the offending
5633 ++ program to help developers debug their applications (SIGBUS), or
5634 ++ disabling the transparent fixing (NOFIX).
5635 ++
5636 ++ The sysctls will be initialized to the compile-time defined UAC
5637 ++ policy. You can change these manually, or with the sysctl(8)
5638 ++ userspace utility.
5639 ++
5640 ++ To disable the warning messages at runtime, you would use
5641 ++
5642 ++ echo 1 > /proc/sys/kernel/uac/noprint
5643 ++
5644 ++ This is pretty harmless. Say Y if you're not sure.
5645 ++
5646 + source "drivers/pci/Kconfig"
5647 + source "drivers/eisa/Kconfig"
5648 +
5649 +--- a/arch/alpha/kernel/traps.c
5650 ++++ b/arch/alpha/kernel/traps.c
5651 +@@ -14,6 +14,7 @@
5652 + #include <linux/delay.h>
5653 + #include <linux/smp_lock.h>
5654 + #include <linux/module.h>
5655 ++#include <linux/sysctl.h>
5656 + #include <linux/init.h>
5657 + #include <linux/kallsyms.h>
5658 +
5659 +@@ -102,6 +103,38 @@ static char * ireg_name[] = {"v0", "t0",
5660 + "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
5661 + #endif
5662 +
5663 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
5664 ++static struct ctl_table_header *uac_sysctl_header;
5665 ++
5666 ++static int enabled_noprint = 0;
5667 ++static int enabled_sigbus = 0;
5668 ++static int enabled_nofix = 0;
5669 ++
5670 ++ctl_table uac_table[] = {
5671 ++ {KERN_UAC_NOPRINT, "noprint", &enabled_noprint, sizeof (int), 0644, NULL, NULL, &proc_dointvec},
5672 ++ {KERN_UAC_SIGBUS, "sigbus", &enabled_sigbus, sizeof (int), 0644, NULL, NULL, &proc_dointvec},
5673 ++ {KERN_UAC_NOFIX, "nofix", &enabled_nofix, sizeof (int), 0644, NULL, NULL, &proc_dointvec},
5674 ++ {0}
5675 ++};
5676 ++
5677 ++static int __init init_uac_sysctl(void)
5678 ++{
5679 ++ /* Initialize sysctls with the #defined UAC policy */
5680 ++ enabled_noprint = (test_thread_flag (TIF_UAC_NOPRINT)) ? 1 : 0;
5681 ++ enabled_sigbus = (test_thread_flag (TIF_UAC_SIGBUS)) ? 1 : 0;
5682 ++ enabled_nofix = (test_thread_flag (TIF_UAC_NOFIX)) ? 1 : 0;
5683 ++
5684 ++ /* save this for later so we can clean up */
5685 ++ uac_sysctl_header = register_sysctl_table(uac_table);
5686 ++ return 0;
5687 ++}
5688 ++
5689 ++static void __exit exit_uac_sysctl(void)
5690 ++{
5691 ++ unregister_sysctl_table(uac_sysctl_header);
5692 ++}
5693 ++#endif
5694 ++
5695 + static void
5696 + dik_show_code(unsigned int *pc)
5697 + {
5698 +@@ -780,7 +813,11 @@ do_entUnaUser(void __user * va, unsigned
5699 + /* Check the UAC bits to decide what the user wants us to do
5700 + with the unaliged access. */
5701 +
5702 ++#ifndef CONFIG_ALPHA_UAC_SYSCTL
5703 + if (!test_thread_flag (TIF_UAC_NOPRINT)) {
5704 ++#else /* CONFIG_ALPHA_UAC_SYSCTL */
5705 ++ if (!(enabled_noprint)) {
5706 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
5707 + if (cnt >= 5 && jiffies - last_time > 5*HZ) {
5708 + cnt = 0;
5709 + }
5710 +@@ -791,10 +828,18 @@ do_entUnaUser(void __user * va, unsigned
5711 + }
5712 + last_time = jiffies;
5713 + }
5714 ++#ifndef CONFIG_ALPHA_UAC_SYSCTL
5715 + if (test_thread_flag (TIF_UAC_SIGBUS))
5716 ++#else /* CONFIG_ALPHA_UAC_SYSCTL */
5717 ++ if (enabled_sigbus)
5718 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
5719 + goto give_sigbus;
5720 + /* Not sure why you'd want to use this, but... */
5721 ++#ifndef CONFIG_ALPHA_UAC_SYSCTL
5722 + if (test_thread_flag (TIF_UAC_NOFIX))
5723 ++#else /* CONFIG_ALPHA_UAC_SYSCTL */
5724 ++ if (enabled_nofix)
5725 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
5726 + return;
5727 +
5728 + /* Don't bother reading ds in the access check since we already
5729 +@@ -1089,3 +1134,7 @@ trap_init(void)
5730 + wrent(entSys, 5);
5731 + wrent(entDbg, 6);
5732 + }
5733 ++
5734 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
5735 ++__initcall(init_uac_sysctl);
5736 ++#endif
5737 +--- a/include/linux/sysctl.h
5738 ++++ b/include/linux/sysctl.h
5739 +@@ -165,6 +165,9 @@ enum
5740 + KERN_MAX_LOCK_DEPTH=74,
5741 + KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
5742 + KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
5743 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
5744 ++ KERN_UAC_POLICY=78, /* int: Alpha unaligned access control policy flags */
5745 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
5746 + };
5747 +
5748 +
5749 +@@ -258,6 +261,17 @@ enum
5750 + PTY_NR=2
5751 + };
5752 +
5753 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
5754 ++/* /proc/sys/kernel/uac */
5755 ++enum
5756 ++{
5757 ++ /* UAC policy on Alpha */
5758 ++ KERN_UAC_NOPRINT=1, /* int: printk() on unaligned access */
5759 ++ KERN_UAC_SIGBUS=2, /* int: send SIGBUS on unaligned access */
5760 ++ KERN_UAC_NOFIX=3, /* int: don't fix the unaligned access */
5761 ++};
5762 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
5763 ++
5764 + /* /proc/sys/bus/isa */
5765 + enum
5766 + {
5767 +--- a/kernel/sysctl.c
5768 ++++ b/kernel/sysctl.c
5769 +@@ -155,6 +155,9 @@ extern ctl_table pty_table[];
5770 + #ifdef CONFIG_INOTIFY_USER
5771 + extern ctl_table inotify_table[];
5772 + #endif
5773 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
5774 ++extern ctl_table uac_table[];
5775 ++#endif
5776 +
5777 + #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
5778 + int sysctl_legacy_va_layout;
5779 +@@ -208,6 +211,14 @@ static ctl_table root_table[] = {
5780 + * NOTE: do not add new entries to this table unless you have read
5781 + * Documentation/sysctl/ctl_unnumbered.txt
5782 + */
5783 ++#ifdef CONFIG_ALPHA_UAC_SYSCTL
5784 ++ {
5785 ++ .ctl_name = KERN_UAC_POLICY,
5786 ++ .procname = "uac",
5787 ++ .mode = 0555,
5788 ++ .child = uac_table,
5789 ++ },
5790 ++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
5791 + { .ctl_name = 0 }
5792 + };
5793 +
5794
5795 Added: hardened-sources/2.6/tags/2.6.23-5/4450_grsec-2.1.11-2.6.23.15-20080210.patch
5796 ===================================================================
5797 --- hardened-sources/2.6/tags/2.6.23-5/4450_grsec-2.1.11-2.6.23.15-20080210.patch (rev 0)
5798 +++ hardened-sources/2.6/tags/2.6.23-5/4450_grsec-2.1.11-2.6.23.15-20080210.patch 2008-04-30 11:40:48 UTC (rev 95)
5799 @@ -0,0 +1,35665 @@
5800 +grsecurity-2.1.11-2.6.23.14-200801231800 forward ported to 2.6.23.15 for
5801 +the Hardened Gentoo project. Thanks to pipacs for some advice concerning
5802 +mmap.c changes.
5803 +
5804 +Signed-off-by: Kerin Millar <kerframil@×××××.com>
5805 +
5806 +diff -Nurp linux-2.6.23.15/Documentation/dontdiff linux-2.6.23.15-grsec/Documentation/dontdiff
5807 +--- linux-2.6.23.15/Documentation/dontdiff 2007-10-09 21:31:38.000000000 +0100
5808 ++++ linux-2.6.23.15-grsec/Documentation/dontdiff 2008-02-11 10:37:44.000000000 +0000
5809 +@@ -176,14 +176,18 @@ times.h*
5810 + tkparse
5811 + trix_boot.h
5812 + utsrelease.h*
5813 ++vdso.lds
5814 + version.h*
5815 + vmlinux
5816 + vmlinux-*
5817 + vmlinux.aout
5818 ++vmlinux.bin.all
5819 + vmlinux.lds
5820 ++vmlinux.relocs
5821 + vsyscall.lds
5822 + wanxlfw.inc
5823 + uImage
5824 + unifdef
5825 ++utsrelease.h
5826 + zImage*
5827 + zconf.hash.c
5828 +diff -Nurp linux-2.6.23.15/Makefile linux-2.6.23.15-grsec/Makefile
5829 +--- linux-2.6.23.15/Makefile 2008-02-11 10:36:03.000000000 +0000
5830 ++++ linux-2.6.23.15-grsec/Makefile 2008-02-11 10:37:44.000000000 +0000
5831 +@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
5832 +
5833 + CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
5834 +
5835 +-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
5836 ++CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
5837 + -fno-strict-aliasing -fno-common \
5838 + -Werror-implicit-function-declaration
5839 + AFLAGS := -D__ASSEMBLY__
5840 +@@ -560,7 +560,7 @@ export mod_strip_cmd
5841 +
5842 +
5843 + ifeq ($(KBUILD_EXTMOD),)
5844 +-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
5845 ++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
5846 +
5847 + vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
5848 + $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
5849 +diff -Nurp linux-2.6.23.15/arch/alpha/kernel/module.c linux-2.6.23.15-grsec/arch/alpha/kernel/module.c
5850 +--- linux-2.6.23.15/arch/alpha/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
5851 ++++ linux-2.6.23.15-grsec/arch/alpha/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
5852 +@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
5853 +
5854 + /* The small sections were sorted to the end of the segment.
5855 + The following should definitely cover them. */
5856 +- gp = (u64)me->module_core + me->core_size - 0x8000;
5857 ++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
5858 + got = sechdrs[me->arch.gotsecindex].sh_addr;
5859 +
5860 + for (i = 0; i < n; i++) {
5861 +diff -Nurp linux-2.6.23.15/arch/alpha/kernel/osf_sys.c linux-2.6.23.15-grsec/arch/alpha/kernel/osf_sys.c
5862 +--- linux-2.6.23.15/arch/alpha/kernel/osf_sys.c 2007-10-09 21:31:38.000000000 +0100
5863 ++++ linux-2.6.23.15-grsec/arch/alpha/kernel/osf_sys.c 2008-02-11 10:37:44.000000000 +0000
5864 +@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
5865 + merely specific addresses, but regions of memory -- perhaps
5866 + this feature should be incorporated into all ports? */
5867 +
5868 ++#ifdef CONFIG_PAX_RANDMMAP
5869 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
5870 ++#endif
5871 ++
5872 + if (addr) {
5873 + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
5874 + if (addr != (unsigned long) -ENOMEM)
5875 +@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
5876 + }
5877 +
5878 + /* Next, try allocating at TASK_UNMAPPED_BASE. */
5879 +- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
5880 +- len, limit);
5881 ++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
5882 ++
5883 + if (addr != (unsigned long) -ENOMEM)
5884 + return addr;
5885 +
5886 +diff -Nurp linux-2.6.23.15/arch/alpha/kernel/ptrace.c linux-2.6.23.15-grsec/arch/alpha/kernel/ptrace.c
5887 +--- linux-2.6.23.15/arch/alpha/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
5888 ++++ linux-2.6.23.15-grsec/arch/alpha/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
5889 +@@ -15,6 +15,7 @@
5890 + #include <linux/slab.h>
5891 + #include <linux/security.h>
5892 + #include <linux/signal.h>
5893 ++#include <linux/grsecurity.h>
5894 +
5895 + #include <asm/uaccess.h>
5896 + #include <asm/pgtable.h>
5897 +@@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo
5898 + goto out_notsk;
5899 + }
5900 +
5901 ++ if (gr_handle_ptrace(child, request)) {
5902 ++ ret = -EPERM;
5903 ++ goto out;
5904 ++ }
5905 ++
5906 + if (request == PTRACE_ATTACH) {
5907 + ret = ptrace_attach(child);
5908 + goto out;
5909 +diff -Nurp linux-2.6.23.15/arch/alpha/mm/fault.c linux-2.6.23.15-grsec/arch/alpha/mm/fault.c
5910 +--- linux-2.6.23.15/arch/alpha/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
5911 ++++ linux-2.6.23.15-grsec/arch/alpha/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
5912 +@@ -23,6 +23,7 @@
5913 + #include <linux/smp.h>
5914 + #include <linux/interrupt.h>
5915 + #include <linux/module.h>
5916 ++#include <linux/binfmts.h>
5917 +
5918 + #include <asm/system.h>
5919 + #include <asm/uaccess.h>
5920 +@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
5921 + __reload_thread(pcb);
5922 + }
5923 +
5924 ++#ifdef CONFIG_PAX_PAGEEXEC
5925 ++/*
5926 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
5927 ++ *
5928 ++ * returns 1 when task should be killed
5929 ++ * 2 when patched PLT trampoline was detected
5930 ++ * 3 when unpatched PLT trampoline was detected
5931 ++ */
5932 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
5933 ++{
5934 ++
5935 ++#ifdef CONFIG_PAX_EMUPLT
5936 ++ int err;
5937 ++
5938 ++ do { /* PaX: patched PLT emulation #1 */
5939 ++ unsigned int ldah, ldq, jmp;
5940 ++
5941 ++ err = get_user(ldah, (unsigned int *)regs->pc);
5942 ++ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
5943 ++ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
5944 ++
5945 ++ if (err)
5946 ++ break;
5947 ++
5948 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
5949 ++ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
5950 ++ jmp == 0x6BFB0000U)
5951 ++ {
5952 ++ unsigned long r27, addr;
5953 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
5954 ++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
5955 ++
5956 ++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
5957 ++ err = get_user(r27, (unsigned long *)addr);
5958 ++ if (err)
5959 ++ break;
5960 ++
5961 ++ regs->r27 = r27;
5962 ++ regs->pc = r27;
5963 ++ return 2;
5964 ++ }
5965 ++ } while (0);
5966 ++
5967 ++ do { /* PaX: patched PLT emulation #2 */
5968 ++ unsigned int ldah, lda, br;
5969 ++
5970 ++ err = get_user(ldah, (unsigned int *)regs->pc);
5971 ++ err |= get_user(lda, (unsigned int *)(regs->pc+4));
5972 ++ err |= get_user(br, (unsigned int *)(regs->pc+8));
5973 ++
5974 ++ if (err)
5975 ++ break;
5976 ++
5977 ++ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
5978 ++ (lda & 0xFFFF0000U) == 0xA77B0000U &&
5979 ++ (br & 0xFFE00000U) == 0xC3E00000U)
5980 ++ {
5981 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
5982 ++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
5983 ++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
5984 ++
5985 ++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
5986 ++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
5987 ++ return 2;
5988 ++ }
5989 ++ } while (0);
5990 ++
5991 ++ do { /* PaX: unpatched PLT emulation */
5992 ++ unsigned int br;
5993 ++
5994 ++ err = get_user(br, (unsigned int *)regs->pc);
5995 ++
5996 ++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
5997 ++ unsigned int br2, ldq, nop, jmp;
5998 ++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
5999 ++
6000 ++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
6001 ++ err = get_user(br2, (unsigned int *)addr);
6002 ++ err |= get_user(ldq, (unsigned int *)(addr+4));
6003 ++ err |= get_user(nop, (unsigned int *)(addr+8));
6004 ++ err |= get_user(jmp, (unsigned int *)(addr+12));
6005 ++ err |= get_user(resolver, (unsigned long *)(addr+16));
6006 ++
6007 ++ if (err)
6008 ++ break;
6009 ++
6010 ++ if (br2 == 0xC3600000U &&
6011 ++ ldq == 0xA77B000CU &&
6012 ++ nop == 0x47FF041FU &&
6013 ++ jmp == 0x6B7B0000U)
6014 ++ {
6015 ++ regs->r28 = regs->pc+4;
6016 ++ regs->r27 = addr+16;
6017 ++ regs->pc = resolver;
6018 ++ return 3;
6019 ++ }
6020 ++ }
6021 ++ } while (0);
6022 ++#endif
6023 ++
6024 ++ return 1;
6025 ++}
6026 ++
6027 ++void pax_report_insns(void *pc, void *sp)
6028 ++{
6029 ++ unsigned long i;
6030 ++
6031 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6032 ++ for (i = 0; i < 5; i++) {
6033 ++ unsigned int c;
6034 ++ if (get_user(c, (unsigned int *)pc+i))
6035 ++ printk("???????? ");
6036 ++ else
6037 ++ printk("%08x ", c);
6038 ++ }
6039 ++ printk("\n");
6040 ++}
6041 ++#endif
6042 +
6043 + /*
6044 + * This routine handles page faults. It determines the address,
6045 +@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
6046 + good_area:
6047 + si_code = SEGV_ACCERR;
6048 + if (cause < 0) {
6049 +- if (!(vma->vm_flags & VM_EXEC))
6050 ++ if (!(vma->vm_flags & VM_EXEC)) {
6051 ++
6052 ++#ifdef CONFIG_PAX_PAGEEXEC
6053 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
6054 ++ goto bad_area;
6055 ++
6056 ++ up_read(&mm->mmap_sem);
6057 ++ switch (pax_handle_fetch_fault(regs)) {
6058 ++
6059 ++#ifdef CONFIG_PAX_EMUPLT
6060 ++ case 2:
6061 ++ case 3:
6062 ++ return;
6063 ++#endif
6064 ++
6065 ++ }
6066 ++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
6067 ++ do_exit(SIGKILL);
6068 ++#else
6069 + goto bad_area;
6070 ++#endif
6071 ++
6072 ++ }
6073 + } else if (!cause) {
6074 + /* Allow reads even for write-only mappings */
6075 + if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
6076 +diff -Nurp linux-2.6.23.15/arch/arm/mm/mmap.c linux-2.6.23.15-grsec/arch/arm/mm/mmap.c
6077 +--- linux-2.6.23.15/arch/arm/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
6078 ++++ linux-2.6.23.15-grsec/arch/arm/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
6079 +@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
6080 + if (len > TASK_SIZE)
6081 + return -ENOMEM;
6082 +
6083 ++#ifdef CONFIG_PAX_RANDMMAP
6084 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6085 ++#endif
6086 ++
6087 + if (addr) {
6088 + if (do_align)
6089 + addr = COLOUR_ALIGN(addr, pgoff);
6090 +@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
6091 + return addr;
6092 + }
6093 + if (len > mm->cached_hole_size) {
6094 +- start_addr = addr = mm->free_area_cache;
6095 ++ start_addr = addr = mm->free_area_cache;
6096 + } else {
6097 +- start_addr = addr = TASK_UNMAPPED_BASE;
6098 +- mm->cached_hole_size = 0;
6099 ++ start_addr = addr = mm->mmap_base;
6100 ++ mm->cached_hole_size = 0;
6101 + }
6102 +
6103 + full_search:
6104 +@@ -91,8 +95,8 @@ full_search:
6105 + * Start a new search - just in case we missed
6106 + * some holes.
6107 + */
6108 +- if (start_addr != TASK_UNMAPPED_BASE) {
6109 +- start_addr = addr = TASK_UNMAPPED_BASE;
6110 ++ if (start_addr != mm->mmap_base) {
6111 ++ start_addr = addr = mm->mmap_base;
6112 + mm->cached_hole_size = 0;
6113 + goto full_search;
6114 + }
6115 +diff -Nurp linux-2.6.23.15/arch/avr32/mm/fault.c linux-2.6.23.15-grsec/arch/avr32/mm/fault.c
6116 +--- linux-2.6.23.15/arch/avr32/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
6117 ++++ linux-2.6.23.15-grsec/arch/avr32/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
6118 +@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
6119 +
6120 + int exception_trace = 1;
6121 +
6122 ++#ifdef CONFIG_PAX_PAGEEXEC
6123 ++void pax_report_insns(void *pc, void *sp)
6124 ++{
6125 ++ unsigned long i;
6126 ++
6127 ++ printk(KERN_ERR "PAX: bytes at PC: ");
6128 ++ for (i = 0; i < 20; i++) {
6129 ++ unsigned char c;
6130 ++ if (get_user(c, (unsigned char *)pc+i))
6131 ++ printk("???????? ");
6132 ++ else
6133 ++ printk("%02x ", c);
6134 ++ }
6135 ++ printk("\n");
6136 ++}
6137 ++#endif
6138 ++
6139 + /*
6140 + * This routine handles page faults. It determines the address and the
6141 + * problem, and then passes it off to one of the appropriate routines.
6142 +@@ -157,6 +174,16 @@ bad_area:
6143 + up_read(&mm->mmap_sem);
6144 +
6145 + if (user_mode(regs)) {
6146 ++
6147 ++#ifdef CONFIG_PAX_PAGEEXEC
6148 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6149 ++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
6150 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
6151 ++ do_exit(SIGKILL);
6152 ++ }
6153 ++ }
6154 ++#endif
6155 ++
6156 + if (exception_trace && printk_ratelimit())
6157 + printk("%s%s[%d]: segfault at %08lx pc %08lx "
6158 + "sp %08lx ecr %lu\n",
6159 +diff -Nurp linux-2.6.23.15/arch/i386/Kconfig linux-2.6.23.15-grsec/arch/i386/Kconfig
6160 +--- linux-2.6.23.15/arch/i386/Kconfig 2007-10-09 21:31:38.000000000 +0100
6161 ++++ linux-2.6.23.15-grsec/arch/i386/Kconfig 2008-02-11 10:37:44.000000000 +0000
6162 +@@ -592,7 +592,7 @@ config PAGE_OFFSET
6163 + hex
6164 + default 0xB0000000 if VMSPLIT_3G_OPT
6165 + default 0x80000000 if VMSPLIT_2G
6166 +- default 0x78000000 if VMSPLIT_2G_OPT
6167 ++ default 0x70000000 if VMSPLIT_2G_OPT
6168 + default 0x40000000 if VMSPLIT_1G
6169 + default 0xC0000000
6170 +
6171 +@@ -831,7 +831,7 @@ config CRASH_DUMP
6172 + config PHYSICAL_START
6173 + hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
6174 + default "0x1000000" if X86_NUMAQ
6175 +- default "0x100000"
6176 ++ default "0x200000"
6177 + help
6178 + This gives the physical address where the kernel is loaded.
6179 +
6180 +@@ -916,7 +916,7 @@ config HOTPLUG_CPU
6181 +
6182 + config COMPAT_VDSO
6183 + bool "Compat VDSO support"
6184 +- default y
6185 ++ default n
6186 + help
6187 + Map the VDSO to the predictable old-style address too.
6188 + ---help---
6189 +@@ -1092,7 +1092,7 @@ config PCI
6190 + choice
6191 + prompt "PCI access mode"
6192 + depends on PCI && !X86_VISWS
6193 +- default PCI_GOANY
6194 ++ default PCI_GODIRECT
6195 + ---help---
6196 + On PCI systems, the BIOS can be used to detect the PCI devices and
6197 + determine their configuration. However, some old PCI motherboards
6198 +diff -Nurp linux-2.6.23.15/arch/i386/Kconfig.cpu linux-2.6.23.15-grsec/arch/i386/Kconfig.cpu
6199 +--- linux-2.6.23.15/arch/i386/Kconfig.cpu 2007-10-09 21:31:38.000000000 +0100
6200 ++++ linux-2.6.23.15-grsec/arch/i386/Kconfig.cpu 2008-02-11 10:37:44.000000000 +0000
6201 +@@ -274,7 +274,7 @@ config X86_PPRO_FENCE
6202 +
6203 + config X86_F00F_BUG
6204 + bool
6205 +- depends on M586MMX || M586TSC || M586 || M486 || M386
6206 ++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
6207 + default y
6208 +
6209 + config X86_WP_WORKS_OK
6210 +@@ -299,7 +299,7 @@ config X86_POPAD_OK
6211 +
6212 + config X86_ALIGNMENT_16
6213 + bool
6214 +- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
6215 ++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
6216 + default y
6217 +
6218 + config X86_GOOD_APIC
6219 +diff -Nurp linux-2.6.23.15/arch/i386/Kconfig.debug linux-2.6.23.15-grsec/arch/i386/Kconfig.debug
6220 +--- linux-2.6.23.15/arch/i386/Kconfig.debug 2007-10-09 21:31:38.000000000 +0100
6221 ++++ linux-2.6.23.15-grsec/arch/i386/Kconfig.debug 2008-02-11 10:37:44.000000000 +0000
6222 +@@ -46,16 +46,6 @@ config DEBUG_PAGEALLOC
6223 + This results in a large slowdown, but helps to find certain types
6224 + of memory corruptions.
6225 +
6226 +-config DEBUG_RODATA
6227 +- bool "Write protect kernel read-only data structures"
6228 +- depends on DEBUG_KERNEL
6229 +- help
6230 +- Mark the kernel read-only data as write-protected in the pagetables,
6231 +- in order to catch accidental (and incorrect) writes to such const
6232 +- data. This option may have a slight performance impact because a
6233 +- portion of the kernel code won't be covered by a 2MB TLB anymore.
6234 +- If in doubt, say "N".
6235 +-
6236 + config 4KSTACKS
6237 + bool "Use 4Kb for kernel stacks instead of 8Kb"
6238 + depends on DEBUG_KERNEL
6239 +diff -Nurp linux-2.6.23.15/arch/i386/boot/bitops.h linux-2.6.23.15-grsec/arch/i386/boot/bitops.h
6240 +--- linux-2.6.23.15/arch/i386/boot/bitops.h 2007-10-09 21:31:38.000000000 +0100
6241 ++++ linux-2.6.23.15-grsec/arch/i386/boot/bitops.h 2008-02-11 10:37:44.000000000 +0000
6242 +@@ -28,7 +28,7 @@ static inline int variable_test_bit(int
6243 + u8 v;
6244 + const u32 *p = (const u32 *)addr;
6245 +
6246 +- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
6247 ++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
6248 + return v;
6249 + }
6250 +
6251 +@@ -39,7 +39,7 @@ static inline int variable_test_bit(int
6252 +
6253 + static inline void set_bit(int nr, void *addr)
6254 + {
6255 +- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
6256 ++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
6257 + }
6258 +
6259 + #endif /* BOOT_BITOPS_H */
6260 +diff -Nurp linux-2.6.23.15/arch/i386/boot/boot.h linux-2.6.23.15-grsec/arch/i386/boot/boot.h
6261 +--- linux-2.6.23.15/arch/i386/boot/boot.h 2008-02-11 10:36:03.000000000 +0000
6262 ++++ linux-2.6.23.15-grsec/arch/i386/boot/boot.h 2008-02-11 10:37:44.000000000 +0000
6263 +@@ -78,7 +78,7 @@ static inline void io_delay(void)
6264 + static inline u16 ds(void)
6265 + {
6266 + u16 seg;
6267 +- asm("movw %%ds,%0" : "=rm" (seg));
6268 ++ asm volatile("movw %%ds,%0" : "=rm" (seg));
6269 + return seg;
6270 + }
6271 +
6272 +@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t
6273 + static inline int memcmp(const void *s1, const void *s2, size_t len)
6274 + {
6275 + u8 diff;
6276 +- asm("repe; cmpsb; setnz %0"
6277 ++ asm volatile("repe; cmpsb; setnz %0"
6278 + : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
6279 + return diff;
6280 + }
6281 +diff -Nurp linux-2.6.23.15/arch/i386/boot/compressed/head.S linux-2.6.23.15-grsec/arch/i386/boot/compressed/head.S
6282 +--- linux-2.6.23.15/arch/i386/boot/compressed/head.S 2007-10-09 21:31:38.000000000 +0100
6283 ++++ linux-2.6.23.15-grsec/arch/i386/boot/compressed/head.S 2008-02-11 10:37:44.000000000 +0000
6284 +@@ -159,9 +159,8 @@ relocated:
6285 + */
6286 +
6287 + 1: subl $4, %edi
6288 +- movl 0(%edi), %ecx
6289 +- testl %ecx, %ecx
6290 +- jz 2f
6291 ++ movl (%edi), %ecx
6292 ++ jecxz 2f
6293 + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
6294 + jmp 1b
6295 + 2:
6296 +diff -Nurp linux-2.6.23.15/arch/i386/boot/compressed/relocs.c linux-2.6.23.15-grsec/arch/i386/boot/compressed/relocs.c
6297 +--- linux-2.6.23.15/arch/i386/boot/compressed/relocs.c 2007-10-09 21:31:38.000000000 +0100
6298 ++++ linux-2.6.23.15-grsec/arch/i386/boot/compressed/relocs.c 2008-02-11 10:37:44.000000000 +0000
6299 +@@ -10,9 +10,13 @@
6300 + #define USE_BSD
6301 + #include <endian.h>
6302 +
6303 ++#include "../../../../include/linux/autoconf.h"
6304 ++
6305 ++#define MAX_PHDRS 100
6306 + #define MAX_SHDRS 100
6307 + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
6308 + static Elf32_Ehdr ehdr;
6309 ++static Elf32_Phdr phdr[MAX_PHDRS];
6310 + static Elf32_Shdr shdr[MAX_SHDRS];
6311 + static Elf32_Sym *symtab[MAX_SHDRS];
6312 + static Elf32_Rel *reltab[MAX_SHDRS];
6313 +@@ -246,6 +250,34 @@ static void read_ehdr(FILE *fp)
6314 + }
6315 + }
6316 +
6317 ++static void read_phdrs(FILE *fp)
6318 ++{
6319 ++ int i;
6320 ++ if (ehdr.e_phnum > MAX_PHDRS) {
6321 ++ die("%d program headers supported: %d\n",
6322 ++ ehdr.e_phnum, MAX_PHDRS);
6323 ++ }
6324 ++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
6325 ++ die("Seek to %d failed: %s\n",
6326 ++ ehdr.e_phoff, strerror(errno));
6327 ++ }
6328 ++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) {
6329 ++ die("Cannot read ELF program headers: %s\n",
6330 ++ strerror(errno));
6331 ++ }
6332 ++ for(i = 0; i < ehdr.e_phnum; i++) {
6333 ++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type);
6334 ++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset);
6335 ++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr);
6336 ++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr);
6337 ++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz);
6338 ++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz);
6339 ++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags);
6340 ++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align);
6341 ++ }
6342 ++
6343 ++}
6344 ++
6345 + static void read_shdrs(FILE *fp)
6346 + {
6347 + int i;
6348 +@@ -332,6 +364,8 @@ static void read_symtabs(FILE *fp)
6349 + static void read_relocs(FILE *fp)
6350 + {
6351 + int i,j;
6352 ++ uint32_t base;
6353 ++
6354 + for(i = 0; i < ehdr.e_shnum; i++) {
6355 + if (shdr[i].sh_type != SHT_REL) {
6356 + continue;
6357 +@@ -349,8 +383,17 @@ static void read_relocs(FILE *fp)
6358 + die("Cannot read symbol table: %s\n",
6359 + strerror(errno));
6360 + }
6361 ++ base = 0;
6362 ++ for (j = 0; j < ehdr.e_phnum; j++) {
6363 ++ if (phdr[j].p_type != PT_LOAD )
6364 ++ continue;
6365 ++ 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)
6366 ++ continue;
6367 ++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
6368 ++ break;
6369 ++ }
6370 + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) {
6371 +- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset);
6372 ++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base;
6373 + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info);
6374 + }
6375 + }
6376 +@@ -487,6 +530,27 @@ static void walk_relocs(void (*visit)(El
6377 + if (sym->st_shndx == SHN_ABS) {
6378 + continue;
6379 + }
6380 ++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
6381 ++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) {
6382 ++ continue;
6383 ++ }
6384 ++#ifdef CONFIG_PAX_KERNEXEC
6385 ++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
6386 ++ if (!strcmp(sec_name(sym->st_shndx), ".init.text")) {
6387 ++ continue;
6388 ++ }
6389 ++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) {
6390 ++ continue;
6391 ++ }
6392 ++ if (!strcmp(sec_name(sym->st_shndx), ".text.head"))
6393 ++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
6394 ++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET")) {
6395 ++ continue;
6396 ++ }
6397 ++ if (!strcmp(sec_name(sym->st_shndx), ".text")) {
6398 ++ continue;
6399 ++ }
6400 ++#endif
6401 + if (r_type == R_386_PC32) {
6402 + /* PC relative relocations don't need to be adjusted */
6403 + }
6404 +@@ -614,6 +678,7 @@ int main(int argc, char **argv)
6405 + fname, strerror(errno));
6406 + }
6407 + read_ehdr(fp);
6408 ++ read_phdrs(fp);
6409 + read_shdrs(fp);
6410 + read_strtabs(fp);
6411 + read_symtabs(fp);
6412 +diff -Nurp linux-2.6.23.15/arch/i386/boot/cpucheck.c linux-2.6.23.15-grsec/arch/i386/boot/cpucheck.c
6413 +--- linux-2.6.23.15/arch/i386/boot/cpucheck.c 2007-10-09 21:31:38.000000000 +0100
6414 ++++ linux-2.6.23.15-grsec/arch/i386/boot/cpucheck.c 2008-02-11 10:37:44.000000000 +0000
6415 +@@ -90,7 +90,7 @@ static int has_fpu(void)
6416 + u16 fcw = -1, fsw = -1;
6417 + u32 cr0;
6418 +
6419 +- asm("movl %%cr0,%0" : "=r" (cr0));
6420 ++ asm volatile("movl %%cr0,%0" : "=r" (cr0));
6421 + if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
6422 + cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
6423 + asm volatile("movl %0,%%cr0" : : "r" (cr0));
6424 +@@ -106,7 +106,7 @@ static int has_eflag(u32 mask)
6425 + {
6426 + u32 f0, f1;
6427 +
6428 +- asm("pushfl ; "
6429 ++ asm volatile("pushfl ; "
6430 + "pushfl ; "
6431 + "popl %0 ; "
6432 + "movl %0,%1 ; "
6433 +@@ -131,7 +131,7 @@ static void get_flags(void)
6434 + set_bit(X86_FEATURE_FPU, cpu.flags);
6435 +
6436 + if (has_eflag(X86_EFLAGS_ID)) {
6437 +- asm("cpuid"
6438 ++ asm volatile("cpuid"
6439 + : "=a" (max_intel_level),
6440 + "=b" (cpu_vendor[0]),
6441 + "=d" (cpu_vendor[1]),
6442 +@@ -140,7 +140,7 @@ static void get_flags(void)
6443 +
6444 + if (max_intel_level >= 0x00000001 &&
6445 + max_intel_level <= 0x0000ffff) {
6446 +- asm("cpuid"
6447 ++ asm volatile("cpuid"
6448 + : "=a" (tfms),
6449 + "=c" (cpu.flags[4]),
6450 + "=d" (cpu.flags[0])
6451 +@@ -152,7 +152,7 @@ static void get_flags(void)
6452 + cpu.model += ((tfms >> 16) & 0xf) << 4;
6453 + }
6454 +
6455 +- asm("cpuid"
6456 ++ asm volatile("cpuid"
6457 + : "=a" (max_amd_level)
6458 + : "a" (0x80000000)
6459 + : "ebx", "ecx", "edx");
6460 +@@ -160,7 +160,7 @@ static void get_flags(void)
6461 + if (max_amd_level >= 0x80000001 &&
6462 + max_amd_level <= 0x8000ffff) {
6463 + u32 eax = 0x80000001;
6464 +- asm("cpuid"
6465 ++ asm volatile("cpuid"
6466 + : "+a" (eax),
6467 + "=c" (cpu.flags[6]),
6468 + "=d" (cpu.flags[1])
6469 +@@ -219,9 +219,9 @@ int check_cpu(int *cpu_level_ptr, int *r
6470 + u32 ecx = MSR_K7_HWCR;
6471 + u32 eax, edx;
6472 +
6473 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6474 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6475 + eax &= ~(1 << 15);
6476 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6477 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6478 +
6479 + get_flags(); /* Make sure it really did something */
6480 + err = check_flags();
6481 +@@ -234,9 +234,9 @@ int check_cpu(int *cpu_level_ptr, int *r
6482 + u32 ecx = MSR_VIA_FCR;
6483 + u32 eax, edx;
6484 +
6485 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6486 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6487 + eax |= (1<<1)|(1<<7);
6488 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6489 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6490 +
6491 + set_bit(X86_FEATURE_CX8, cpu.flags);
6492 + err = check_flags();
6493 +@@ -247,12 +247,12 @@ int check_cpu(int *cpu_level_ptr, int *r
6494 + u32 eax, edx;
6495 + u32 level = 1;
6496 +
6497 +- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6498 +- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
6499 +- asm("cpuid"
6500 ++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
6501 ++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
6502 ++ asm volatile("cpuid"
6503 + : "+a" (level), "=d" (cpu.flags[0])
6504 + : : "ecx", "ebx");
6505 +- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6506 ++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
6507 +
6508 + err = check_flags();
6509 + }
6510 +diff -Nurp linux-2.6.23.15/arch/i386/boot/edd.c linux-2.6.23.15-grsec/arch/i386/boot/edd.c
6511 +--- linux-2.6.23.15/arch/i386/boot/edd.c 2007-10-09 21:31:38.000000000 +0100
6512 ++++ linux-2.6.23.15-grsec/arch/i386/boot/edd.c 2008-02-11 10:37:44.000000000 +0000
6513 +@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct
6514 + ax = 0x4100;
6515 + bx = EDDMAGIC1;
6516 + dx = devno;
6517 +- asm("pushfl; stc; int $0x13; setc %%al; popfl"
6518 ++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
6519 + : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
6520 + : : "esi", "edi");
6521 +
6522 +@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct
6523 + ei->params.length = sizeof(ei->params);
6524 + ax = 0x4800;
6525 + dx = devno;
6526 +- asm("pushfl; int $0x13; popfl"
6527 ++ asm volatile("pushfl; int $0x13; popfl"
6528 + : "+a" (ax), "+d" (dx), "=m" (ei->params)
6529 + : "S" (&ei->params)
6530 + : "ebx", "ecx", "edi");
6531 +@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct
6532 + ax = 0x0800;
6533 + dx = devno;
6534 + di = 0;
6535 +- asm("pushw %%es; "
6536 ++ asm volatile("pushw %%es; "
6537 + "movw %%di,%%es; "
6538 + "pushfl; stc; int $0x13; setc %%al; popfl; "
6539 + "popw %%es"
6540 +diff -Nurp linux-2.6.23.15/arch/i386/boot/main.c linux-2.6.23.15-grsec/arch/i386/boot/main.c
6541 +--- linux-2.6.23.15/arch/i386/boot/main.c 2007-10-09 21:31:38.000000000 +0100
6542 ++++ linux-2.6.23.15-grsec/arch/i386/boot/main.c 2008-02-11 10:37:44.000000000 +0000
6543 +@@ -77,7 +77,7 @@ static void keyboard_set_repeat(void)
6544 + */
6545 + static void query_ist(void)
6546 + {
6547 +- asm("int $0x15"
6548 ++ asm volatile("int $0x15"
6549 + : "=a" (boot_params.ist_info.signature),
6550 + "=b" (boot_params.ist_info.command),
6551 + "=c" (boot_params.ist_info.event),
6552 +diff -Nurp linux-2.6.23.15/arch/i386/boot/mca.c linux-2.6.23.15-grsec/arch/i386/boot/mca.c
6553 +--- linux-2.6.23.15/arch/i386/boot/mca.c 2007-10-09 21:31:38.000000000 +0100
6554 ++++ linux-2.6.23.15-grsec/arch/i386/boot/mca.c 2008-02-11 10:37:44.000000000 +0000
6555 +@@ -21,7 +21,7 @@ int query_mca(void)
6556 + u8 err;
6557 + u16 es, bx, len;
6558 +
6559 +- asm("pushw %%es ; "
6560 ++ asm volatile("pushw %%es ; "
6561 + "int $0x15 ; "
6562 + "setc %0 ; "
6563 + "movw %%es, %1 ; "
6564 +diff -Nurp linux-2.6.23.15/arch/i386/boot/memory.c linux-2.6.23.15-grsec/arch/i386/boot/memory.c
6565 +--- linux-2.6.23.15/arch/i386/boot/memory.c 2007-10-09 21:31:38.000000000 +0100
6566 ++++ linux-2.6.23.15-grsec/arch/i386/boot/memory.c 2008-02-11 10:37:44.000000000 +0000
6567 +@@ -32,7 +32,7 @@ static int detect_memory_e820(void)
6568 + /* Important: %edx is clobbered by some BIOSes,
6569 + so it must be either used for the error output
6570 + or explicitly marked clobbered. */
6571 +- asm("int $0x15; setc %0"
6572 ++ asm volatile("int $0x15; setc %0"
6573 + : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
6574 + "=m" (*desc)
6575 + : "D" (desc), "d" (SMAP), "a" (0xe820));
6576 +@@ -64,7 +64,7 @@ static int detect_memory_e801(void)
6577 +
6578 + bx = cx = dx = 0;
6579 + ax = 0xe801;
6580 +- asm("stc; int $0x15; setc %0"
6581 ++ asm volatile("stc; int $0x15; setc %0"
6582 + : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
6583 +
6584 + if (err)
6585 +@@ -94,7 +94,7 @@ static int detect_memory_88(void)
6586 + u8 err;
6587 +
6588 + ax = 0x8800;
6589 +- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
6590 ++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
6591 +
6592 + boot_params.screen_info.ext_mem_k = ax;
6593 +
6594 +diff -Nurp linux-2.6.23.15/arch/i386/boot/video-vesa.c linux-2.6.23.15-grsec/arch/i386/boot/video-vesa.c
6595 +--- linux-2.6.23.15/arch/i386/boot/video-vesa.c 2008-02-11 10:36:03.000000000 +0000
6596 ++++ linux-2.6.23.15-grsec/arch/i386/boot/video-vesa.c 2008-02-11 10:37:44.000000000 +0000
6597 +@@ -41,7 +41,7 @@ static int vesa_probe(void)
6598 +
6599 + ax = 0x4f00;
6600 + di = (size_t)&vginfo;
6601 +- asm(INT10
6602 ++ asm volatile(INT10
6603 + : "+a" (ax), "+D" (di), "=m" (vginfo)
6604 + : : "ebx", "ecx", "edx", "esi");
6605 +
6606 +@@ -68,7 +68,7 @@ static int vesa_probe(void)
6607 + ax = 0x4f01;
6608 + cx = mode;
6609 + di = (size_t)&vminfo;
6610 +- asm(INT10
6611 ++ asm volatile(INT10
6612 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
6613 + : : "ebx", "edx", "esi");
6614 +
6615 +@@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf
6616 + ax = 0x4f01;
6617 + cx = vesa_mode;
6618 + di = (size_t)&vminfo;
6619 +- asm(INT10
6620 ++ asm volatile(INT10
6621 + : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
6622 + : : "ebx", "edx", "esi");
6623 +
6624 +@@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void)
6625 + /* Save the VESA protected mode info */
6626 + static void vesa_store_pm_info(void)
6627 + {
6628 +- u16 ax, bx, di, es;
6629 ++ u16 ax, bx, cx, di, es;
6630 +
6631 + ax = 0x4f0a;
6632 +- bx = di = 0;
6633 +- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
6634 +- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
6635 +- : : "ecx", "esi");
6636 ++ bx = cx = di = 0;
6637 ++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
6638 ++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
6639 ++ : : "esi");
6640 +
6641 + if (ax != 0x004f)
6642 + return;
6643 +
6644 + boot_params.screen_info.vesapm_seg = es;
6645 + boot_params.screen_info.vesapm_off = di;
6646 ++ boot_params.screen_info.vesapm_size = cx;
6647 + }
6648 +
6649 + /*
6650 +@@ -259,7 +260,7 @@ void vesa_store_edid(void)
6651 + /* Note: The VBE DDC spec is different from the main VESA spec;
6652 + we genuinely have to assume all registers are destroyed here. */
6653 +
6654 +- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
6655 ++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
6656 + : "+a" (ax), "+b" (bx)
6657 + : "c" (cx), "D" (di)
6658 + : "esi");
6659 +@@ -275,7 +276,7 @@ void vesa_store_edid(void)
6660 + cx = 0; /* Controller 0 */
6661 + dx = 0; /* EDID block number */
6662 + di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
6663 +- asm(INT10
6664 ++ asm volatile(INT10
6665 + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
6666 + : "c" (cx), "D" (di)
6667 + : "esi");
6668 +diff -Nurp linux-2.6.23.15/arch/i386/boot/video-vga.c linux-2.6.23.15-grsec/arch/i386/boot/video-vga.c
6669 +--- linux-2.6.23.15/arch/i386/boot/video-vga.c 2007-10-09 21:31:38.000000000 +0100
6670 ++++ linux-2.6.23.15-grsec/arch/i386/boot/video-vga.c 2008-02-11 10:37:44.000000000 +0000
6671 +@@ -225,7 +225,7 @@ static int vga_probe(void)
6672 + };
6673 + u8 vga_flag;
6674 +
6675 +- asm(INT10
6676 ++ asm volatile(INT10
6677 + : "=b" (boot_params.screen_info.orig_video_ega_bx)
6678 + : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
6679 + : "ecx", "edx", "esi", "edi");
6680 +@@ -233,7 +233,7 @@ static int vga_probe(void)
6681 + /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
6682 + if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) {
6683 + /* EGA/VGA */
6684 +- asm(INT10
6685 ++ asm volatile(INT10
6686 + : "=a" (vga_flag)
6687 + : "a" (0x1a00)
6688 + : "ebx", "ecx", "edx", "esi", "edi");
6689 +diff -Nurp linux-2.6.23.15/arch/i386/boot/video.c linux-2.6.23.15-grsec/arch/i386/boot/video.c
6690 +--- linux-2.6.23.15/arch/i386/boot/video.c 2008-02-11 10:36:03.000000000 +0000
6691 ++++ linux-2.6.23.15-grsec/arch/i386/boot/video.c 2008-02-11 10:37:44.000000000 +0000
6692 +@@ -40,7 +40,7 @@ static void store_cursor_position(void)
6693 +
6694 + ax = 0x0300;
6695 + bx = 0;
6696 +- asm(INT10
6697 ++ asm volatile(INT10
6698 + : "=d" (curpos), "+a" (ax), "+b" (bx)
6699 + : : "ecx", "esi", "edi");
6700 +
6701 +@@ -55,7 +55,7 @@ static void store_video_mode(void)
6702 + /* N.B.: the saving of the video page here is a bit silly,
6703 + since we pretty much assume page 0 everywhere. */
6704 + ax = 0x0f00;
6705 +- asm(INT10
6706 ++ asm volatile(INT10
6707 + : "+a" (ax), "=b" (page)
6708 + : : "ecx", "edx", "esi", "edi");
6709 +
6710 +diff -Nurp linux-2.6.23.15/arch/i386/boot/voyager.c linux-2.6.23.15-grsec/arch/i386/boot/voyager.c
6711 +--- linux-2.6.23.15/arch/i386/boot/voyager.c 2007-10-09 21:31:38.000000000 +0100
6712 ++++ linux-2.6.23.15-grsec/arch/i386/boot/voyager.c 2008-02-11 10:37:44.000000000 +0000
6713 +@@ -27,7 +27,7 @@ int query_voyager(void)
6714 +
6715 + data_ptr[0] = 0xff; /* Flag on config not found(?) */
6716 +
6717 +- asm("pushw %%es ; "
6718 ++ asm volatile("pushw %%es ; "
6719 + "int $0x15 ; "
6720 + "setc %0 ; "
6721 + "movw %%es, %1 ; "
6722 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/acpi/boot.c linux-2.6.23.15-grsec/arch/i386/kernel/acpi/boot.c
6723 +--- linux-2.6.23.15/arch/i386/kernel/acpi/boot.c 2007-10-09 21:31:38.000000000 +0100
6724 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/boot.c 2008-02-11 10:37:44.000000000 +0000
6725 +@@ -1123,7 +1123,7 @@ static struct dmi_system_id __initdata a
6726 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
6727 + },
6728 + },
6729 +- {}
6730 ++ { NULL, NULL, {{0, NULL}}, NULL}
6731 + };
6732 +
6733 + #endif /* __i386__ */
6734 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/acpi/sleep.c linux-2.6.23.15-grsec/arch/i386/kernel/acpi/sleep.c
6735 +--- linux-2.6.23.15/arch/i386/kernel/acpi/sleep.c 2007-10-09 21:31:38.000000000 +0100
6736 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/sleep.c 2008-02-11 10:37:44.000000000 +0000
6737 +@@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a
6738 + DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
6739 + },
6740 + },
6741 +- {}
6742 ++ { NULL, NULL, {{0, NULL}}, NULL}
6743 + };
6744 +
6745 + static int __init acpisleep_dmi_init(void)
6746 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/acpi/wakeup.S linux-2.6.23.15-grsec/arch/i386/kernel/acpi/wakeup.S
6747 +--- linux-2.6.23.15/arch/i386/kernel/acpi/wakeup.S 2007-10-09 21:31:38.000000000 +0100
6748 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/wakeup.S 2008-02-11 10:37:44.000000000 +0000
6749 +@@ -2,6 +2,7 @@
6750 + #include <linux/linkage.h>
6751 + #include <asm/segment.h>
6752 + #include <asm/page.h>
6753 ++#include <asm/msr-index.h>
6754 +
6755 + #
6756 + # wakeup_code runs in real mode, and at unknown address (determined at run-time).
6757 +@@ -84,7 +85,7 @@ wakeup_code:
6758 + # restore efer setting
6759 + movl real_save_efer_edx - wakeup_code, %edx
6760 + movl real_save_efer_eax - wakeup_code, %eax
6761 +- mov $0xc0000080, %ecx
6762 ++ mov $MSR_EFER, %ecx
6763 + wrmsr
6764 + 4:
6765 + # make sure %cr4 is set correctly (features, etc)
6766 +@@ -209,13 +210,11 @@ wakeup_pmode_return:
6767 + # and restore the stack ... but you need gdt for this to work
6768 + movl saved_context_esp, %esp
6769 +
6770 +- movl %cs:saved_magic, %eax
6771 +- cmpl $0x12345678, %eax
6772 ++ cmpl $0x12345678, saved_magic
6773 + jne bogus_magic
6774 +
6775 + # jump to place where we left off
6776 +- movl saved_eip,%eax
6777 +- jmp *%eax
6778 ++ jmp *(saved_eip)
6779 +
6780 + bogus_magic:
6781 + movw $0x0e00 + 'B', 0xb8018
6782 +@@ -247,7 +246,7 @@ ENTRY(acpi_copy_wakeup_routine)
6783 + # save efer setting
6784 + pushl %eax
6785 + movl %eax, %ebx
6786 +- mov $0xc0000080, %ecx
6787 ++ mov $MSR_EFER, %ecx
6788 + rdmsr
6789 + movl %edx, real_save_efer_edx - wakeup_start (%ebx)
6790 + movl %eax, real_save_efer_eax - wakeup_start (%ebx)
6791 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/alternative.c linux-2.6.23.15-grsec/arch/i386/kernel/alternative.c
6792 +--- linux-2.6.23.15/arch/i386/kernel/alternative.c 2007-10-09 21:31:38.000000000 +0100
6793 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/alternative.c 2008-02-11 10:37:44.000000000 +0000
6794 +@@ -443,7 +443,20 @@ void __init alternative_instructions(voi
6795 + */
6796 + void __kprobes text_poke(void *addr, unsigned char *opcode, int len)
6797 + {
6798 ++
6799 ++#ifdef CONFIG_PAX_KERNEXEC
6800 ++ unsigned long cr0;
6801 ++
6802 ++ pax_open_kernel(cr0);
6803 ++#endif
6804 ++
6805 ++ addr += __KERNEL_TEXT_OFFSET;
6806 + memcpy(addr, opcode, len);
6807 ++
6808 ++#ifdef CONFIG_PAX_KERNEXEC
6809 ++ pax_close_kernel(cr0);
6810 ++#endif
6811 ++
6812 + sync_core();
6813 + /* Could also do a CLFLUSH here to speed up CPU recovery; but
6814 + that causes hangs on some VIA CPUs. */
6815 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/apm.c linux-2.6.23.15-grsec/arch/i386/kernel/apm.c
6816 +--- linux-2.6.23.15/arch/i386/kernel/apm.c 2008-02-11 10:36:03.000000000 +0000
6817 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/apm.c 2008-02-11 10:37:44.000000000 +0000
6818 +@@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
6819 + static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
6820 + static struct apm_user * user_list;
6821 + static DEFINE_SPINLOCK(user_list_lock);
6822 +-static const struct desc_struct bad_bios_desc = { 0, 0x00409200 };
6823 ++static const struct desc_struct bad_bios_desc = { 0, 0x00409300 };
6824 +
6825 + static const char driver_version[] = "1.16ac"; /* no spaces */
6826 +
6827 +@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb
6828 + struct desc_struct save_desc_40;
6829 + struct desc_struct *gdt;
6830 +
6831 ++#ifdef CONFIG_PAX_KERNEXEC
6832 ++ unsigned long cr0;
6833 ++#endif
6834 ++
6835 + cpus = apm_save_cpus();
6836 +
6837 + cpu = get_cpu();
6838 + gdt = get_cpu_gdt_table(cpu);
6839 + save_desc_40 = gdt[0x40 / 8];
6840 ++
6841 ++#ifdef CONFIG_PAX_KERNEXEC
6842 ++ pax_open_kernel(cr0);
6843 ++#endif
6844 ++
6845 + gdt[0x40 / 8] = bad_bios_desc;
6846 +
6847 ++#ifdef CONFIG_PAX_KERNEXEC
6848 ++ pax_close_kernel(cr0);
6849 ++#endif
6850 ++
6851 + apm_irq_save(flags);
6852 + APM_DO_SAVE_SEGS;
6853 + apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
6854 + APM_DO_RESTORE_SEGS;
6855 + apm_irq_restore(flags);
6856 ++
6857 ++#ifdef CONFIG_PAX_KERNEXEC
6858 ++ pax_open_kernel(cr0);
6859 ++#endif
6860 ++
6861 + gdt[0x40 / 8] = save_desc_40;
6862 ++
6863 ++#ifdef CONFIG_PAX_KERNEXEC
6864 ++ pax_close_kernel(cr0);
6865 ++#endif
6866 ++
6867 + put_cpu();
6868 + apm_restore_cpus(cpus);
6869 +
6870 +@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func,
6871 + struct desc_struct save_desc_40;
6872 + struct desc_struct *gdt;
6873 +
6874 ++#ifdef CONFIG_PAX_KERNEXEC
6875 ++ unsigned long cr0;
6876 ++#endif
6877 ++
6878 + cpus = apm_save_cpus();
6879 +
6880 + cpu = get_cpu();
6881 + gdt = get_cpu_gdt_table(cpu);
6882 + save_desc_40 = gdt[0x40 / 8];
6883 ++
6884 ++#ifdef CONFIG_PAX_KERNEXEC
6885 ++ pax_open_kernel(cr0);
6886 ++#endif
6887 ++
6888 + gdt[0x40 / 8] = bad_bios_desc;
6889 +
6890 ++#ifdef CONFIG_PAX_KERNEXEC
6891 ++ pax_close_kernel(cr0);
6892 ++#endif
6893 ++
6894 + apm_irq_save(flags);
6895 + APM_DO_SAVE_SEGS;
6896 + error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
6897 + APM_DO_RESTORE_SEGS;
6898 + apm_irq_restore(flags);
6899 ++
6900 ++#ifdef CONFIG_PAX_KERNEXEC
6901 ++ pax_open_kernel(cr0);
6902 ++#endif
6903 ++
6904 + gdt[0x40 / 8] = save_desc_40;
6905 ++
6906 ++#ifdef CONFIG_PAX_KERNEXEC
6907 ++ pax_close_kernel(cr0);
6908 ++#endif
6909 ++
6910 + put_cpu();
6911 + apm_restore_cpus(cpus);
6912 + return error;
6913 +@@ -924,7 +970,7 @@ recalc:
6914 +
6915 + static void apm_power_off(void)
6916 + {
6917 +- unsigned char po_bios_call[] = {
6918 ++ const unsigned char po_bios_call[] = {
6919 + 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
6920 + 0x8e, 0xd0, /* movw ax,ss */
6921 + 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
6922 +@@ -1864,7 +1910,10 @@ static const struct file_operations apm_
6923 + static struct miscdevice apm_device = {
6924 + APM_MINOR_DEV,
6925 + "apm_bios",
6926 +- &apm_bios_fops
6927 ++ &apm_bios_fops,
6928 ++ {NULL, NULL},
6929 ++ NULL,
6930 ++ NULL
6931 + };
6932 +
6933 +
6934 +@@ -1974,210 +2023,210 @@ static struct dmi_system_id __initdata a
6935 + print_if_true,
6936 + KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
6937 + { DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
6938 +- DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
6939 ++ DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL
6940 + },
6941 + { /* Handle problems with APM on the C600 */
6942 + broken_ps2_resume, "Dell Latitude C600",
6943 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
6944 +- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
6945 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL
6946 + },
6947 + { /* Allow interrupts during suspend on Dell Latitude laptops*/
6948 + set_apm_ints, "Dell Latitude",
6949 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
6950 +- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
6951 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL
6952 + },
6953 + { /* APM crashes */
6954 + apm_is_horked, "Dell Inspiron 2500",
6955 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
6956 + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
6957 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
6958 +- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
6959 ++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
6960 + },
6961 + { /* Allow interrupts during suspend on Dell Inspiron laptops*/
6962 + set_apm_ints, "Dell Inspiron", {
6963 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
6964 +- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
6965 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL
6966 + },
6967 + { /* Handle problems with APM on Inspiron 5000e */
6968 + broken_apm_power, "Dell Inspiron 5000e",
6969 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
6970 + DMI_MATCH(DMI_BIOS_VERSION, "A04"),
6971 +- DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
6972 ++ DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL
6973 + },
6974 + { /* Handle problems with APM on Inspiron 2500 */
6975 + broken_apm_power, "Dell Inspiron 2500",
6976 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
6977 + DMI_MATCH(DMI_BIOS_VERSION, "A12"),
6978 +- DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
6979 ++ DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL
6980 + },
6981 + { /* APM crashes */
6982 + apm_is_horked, "Dell Dimension 4100",
6983 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
6984 + DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
6985 + DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
6986 +- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
6987 ++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
6988 + },
6989 + { /* Allow interrupts during suspend on Compaq Laptops*/
6990 + set_apm_ints, "Compaq 12XL125",
6991 + { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
6992 + DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
6993 + DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
6994 +- DMI_MATCH(DMI_BIOS_VERSION,"4.06"), },
6995 ++ DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL
6996 + },
6997 + { /* Allow interrupts during APM or the clock goes slow */
6998 + set_apm_ints, "ASUSTeK",
6999 + { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
7000 +- DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
7001 ++ DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL
7002 + },
7003 + { /* APM blows on shutdown */
7004 + apm_is_horked, "ABIT KX7-333[R]",
7005 + { DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
7006 +- DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
7007 ++ DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL
7008 + },
7009 + { /* APM crashes */
7010 + apm_is_horked, "Trigem Delhi3",
7011 + { DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
7012 +- DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
7013 ++ DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL
7014 + },
7015 + { /* APM crashes */
7016 + apm_is_horked, "Fujitsu-Siemens",
7017 + { DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
7018 +- DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
7019 ++ DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL
7020 + },
7021 + { /* APM crashes */
7022 + apm_is_horked_d850md, "Intel D850MD",
7023 + { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
7024 +- DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
7025 ++ DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL
7026 + },
7027 + { /* APM crashes */
7028 + apm_is_horked, "Intel D810EMO",
7029 + { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
7030 +- DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
7031 ++ DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL
7032 + },
7033 + { /* APM crashes */
7034 + apm_is_horked, "Dell XPS-Z",
7035 + { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
7036 + DMI_MATCH(DMI_BIOS_VERSION, "A11"),
7037 +- DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
7038 ++ DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL
7039 + },
7040 + { /* APM crashes */
7041 + apm_is_horked, "Sharp PC-PJ/AX",
7042 + { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
7043 + DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
7044 + DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
7045 +- DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), },
7046 ++ DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL
7047 + },
7048 + { /* APM crashes */
7049 + apm_is_horked, "Dell Inspiron 2500",
7050 + { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
7051 + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
7052 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
7053 +- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
7054 ++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
7055 + },
7056 + { /* APM idle hangs */
7057 + apm_likes_to_melt, "Jabil AMD",
7058 + { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
7059 +- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
7060 ++ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL
7061 + },
7062 + { /* APM idle hangs */
7063 + apm_likes_to_melt, "AMI Bios",
7064 + { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
7065 +- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
7066 ++ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL
7067 + },
7068 + { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
7069 + swab_apm_power_in_minutes, "Sony VAIO",
7070 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7071 + DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
7072 +- DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
7073 ++ DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL
7074 + },
7075 + { /* Handle problems with APM on Sony Vaio PCG-N505VX */
7076 + swab_apm_power_in_minutes, "Sony VAIO",
7077 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7078 + DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
7079 +- DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
7080 ++ DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL
7081 + },
7082 + { /* Handle problems with APM on Sony Vaio PCG-XG29 */
7083 + swab_apm_power_in_minutes, "Sony VAIO",
7084 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7085 + DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
7086 +- DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
7087 ++ DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL
7088 + },
7089 + { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
7090 + swab_apm_power_in_minutes, "Sony VAIO",
7091 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7092 + DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
7093 +- DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
7094 ++ DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL
7095 + },
7096 + { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
7097 + swab_apm_power_in_minutes, "Sony VAIO",
7098 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7099 + DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
7100 +- DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
7101 ++ DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL
7102 + },
7103 + { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
7104 + swab_apm_power_in_minutes, "Sony VAIO",
7105 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7106 + DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
7107 +- DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
7108 ++ DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL
7109 + },
7110 + { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
7111 + swab_apm_power_in_minutes, "Sony VAIO",
7112 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7113 + DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
7114 +- DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
7115 ++ DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL
7116 + },
7117 + { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
7118 + swab_apm_power_in_minutes, "Sony VAIO",
7119 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7120 + DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
7121 +- DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
7122 ++ DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL
7123 + },
7124 + { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
7125 + swab_apm_power_in_minutes, "Sony VAIO",
7126 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7127 + DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
7128 +- DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
7129 ++ DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL
7130 + },
7131 + { /* Handle problems with APM on Sony Vaio PCG-F104K */
7132 + swab_apm_power_in_minutes, "Sony VAIO",
7133 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7134 + DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
7135 +- DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
7136 ++ DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL
7137 + },
7138 +
7139 + { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
7140 + swab_apm_power_in_minutes, "Sony VAIO",
7141 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7142 + DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
7143 +- DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
7144 ++ DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL
7145 + },
7146 + { /* Handle problems with APM on Sony Vaio PCG-C1VE */
7147 + swab_apm_power_in_minutes, "Sony VAIO",
7148 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7149 + DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
7150 +- DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
7151 ++ DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL
7152 + },
7153 + { /* Handle problems with APM on Sony Vaio PCG-C1VE */
7154 + swab_apm_power_in_minutes, "Sony VAIO",
7155 + { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
7156 + DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
7157 +- DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
7158 ++ DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL
7159 + },
7160 + { /* broken PM poweroff bios */
7161 + set_realmode_power_off, "Award Software v4.60 PGMA",
7162 + { DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
7163 + DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
7164 +- DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
7165 ++ DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL
7166 + },
7167 +
7168 + /* Generic per vendor APM settings */
7169 +
7170 + { /* Allow interrupts during suspend on IBM laptops */
7171 + set_apm_ints, "IBM",
7172 +- { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
7173 ++ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL
7174 + },
7175 +
7176 +- { }
7177 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
7178 + };
7179 +
7180 + /*
7181 +@@ -2196,6 +2245,10 @@ static int __init apm_init(void)
7182 + struct desc_struct *gdt;
7183 + int err;
7184 +
7185 ++#ifdef CONFIG_PAX_KERNEXEC
7186 ++ unsigned long cr0;
7187 ++#endif
7188 ++
7189 + dmi_check_system(apm_dmi_table);
7190 +
7191 + if (apm_info.bios.version == 0 || paravirt_enabled()) {
7192 +@@ -2269,9 +2322,18 @@ static int __init apm_init(void)
7193 + * This is for buggy BIOS's that refer to (real mode) segment 0x40
7194 + * even though they are called in protected mode.
7195 + */
7196 ++
7197 ++#ifdef CONFIG_PAX_KERNEXEC
7198 ++ pax_open_kernel(cr0);
7199 ++#endif
7200 ++
7201 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
7202 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
7203 +
7204 ++#ifdef CONFIG_PAX_KERNEXEC
7205 ++ pax_close_kernel(cr0);
7206 ++#endif
7207 ++
7208 + /*
7209 + * Set up the long jump entry point to the APM BIOS, which is called
7210 + * from inline assembly.
7211 +@@ -2290,6 +2352,11 @@ static int __init apm_init(void)
7212 + * code to that CPU.
7213 + */
7214 + gdt = get_cpu_gdt_table(0);
7215 ++
7216 ++#ifdef CONFIG_PAX_KERNEXEC
7217 ++ pax_open_kernel(cr0);
7218 ++#endif
7219 ++
7220 + set_base(gdt[APM_CS >> 3],
7221 + __va((unsigned long)apm_info.bios.cseg << 4));
7222 + set_base(gdt[APM_CS_16 >> 3],
7223 +@@ -2297,6 +2364,10 @@ static int __init apm_init(void)
7224 + set_base(gdt[APM_DS >> 3],
7225 + __va((unsigned long)apm_info.bios.dseg << 4));
7226 +
7227 ++#ifdef CONFIG_PAX_KERNEXEC
7228 ++ pax_close_kernel(cr0);
7229 ++#endif
7230 ++
7231 + apm_proc = create_proc_entry("apm", 0, NULL);
7232 + if (apm_proc)
7233 + apm_proc->proc_fops = &apm_file_ops;
7234 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/asm-offsets.c linux-2.6.23.15-grsec/arch/i386/kernel/asm-offsets.c
7235 +--- linux-2.6.23.15/arch/i386/kernel/asm-offsets.c 2007-10-09 21:31:38.000000000 +0100
7236 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/asm-offsets.c 2008-02-11 10:37:44.000000000 +0000
7237 +@@ -109,6 +109,7 @@ void foo(void)
7238 + DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
7239 + DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
7240 + DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
7241 ++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
7242 +
7243 + DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
7244 +
7245 +@@ -122,6 +123,7 @@ void foo(void)
7246 + OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
7247 + OFFSET(PARAVIRT_iret, paravirt_ops, iret);
7248 + OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
7249 ++ OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0);
7250 + #endif
7251 +
7252 + #ifdef CONFIG_XEN
7253 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/common.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/common.c
7254 +--- linux-2.6.23.15/arch/i386/kernel/cpu/common.c 2007-10-09 21:31:38.000000000 +0100
7255 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/common.c 2008-02-11 10:37:44.000000000 +0000
7256 +@@ -4,7 +4,6 @@
7257 + #include <linux/smp.h>
7258 + #include <linux/module.h>
7259 + #include <linux/percpu.h>
7260 +-#include <linux/bootmem.h>
7261 + #include <asm/semaphore.h>
7262 + #include <asm/processor.h>
7263 + #include <asm/i387.h>
7264 +@@ -21,39 +20,15 @@
7265 +
7266 + #include "cpu.h"
7267 +
7268 +-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
7269 +- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
7270 +- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
7271 +- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
7272 +- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
7273 +- /*
7274 +- * Segments used for calling PnP BIOS have byte granularity.
7275 +- * They code segments and data segments have fixed 64k limits,
7276 +- * the transfer segment sizes are set at run time.
7277 +- */
7278 +- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
7279 +- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
7280 +- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
7281 +- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
7282 +- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
7283 +- /*
7284 +- * The APM segments have byte granularity and their bases
7285 +- * are set at run time. All have 64k limits.
7286 +- */
7287 +- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
7288 +- /* 16-bit code */
7289 +- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
7290 +- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
7291 +-
7292 +- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
7293 +- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
7294 +-} };
7295 +-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
7296 +-
7297 + static int cachesize_override __cpuinitdata = -1;
7298 + static int disable_x86_fxsr __cpuinitdata;
7299 + static int disable_x86_serial_nr __cpuinitdata = 1;
7300 +-static int disable_x86_sep __cpuinitdata;
7301 ++
7302 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
7303 ++int disable_x86_sep __cpuinitdata = 1;
7304 ++#else
7305 ++int disable_x86_sep __cpuinitdata;
7306 ++#endif
7307 +
7308 + struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
7309 +
7310 +@@ -261,10 +236,10 @@ static int __cpuinit have_cpuid_p(void)
7311 + void __init cpu_detect(struct cpuinfo_x86 *c)
7312 + {
7313 + /* Get vendor name */
7314 +- cpuid(0x00000000, &c->cpuid_level,
7315 +- (int *)&c->x86_vendor_id[0],
7316 +- (int *)&c->x86_vendor_id[8],
7317 +- (int *)&c->x86_vendor_id[4]);
7318 ++ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
7319 ++ (unsigned int *)&c->x86_vendor_id[0],
7320 ++ (unsigned int *)&c->x86_vendor_id[8],
7321 ++ (unsigned int *)&c->x86_vendor_id[4]);
7322 +
7323 + c->x86 = 4;
7324 + if (c->cpuid_level >= 0x00000001) {
7325 +@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
7326 +
7327 + static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
7328 + {
7329 +- u32 tfms, xlvl;
7330 +- int ebx;
7331 ++ u32 tfms, xlvl, ebx;
7332 +
7333 + if (have_cpuid_p()) {
7334 + /* Get vendor name */
7335 +- cpuid(0x00000000, &c->cpuid_level,
7336 +- (int *)&c->x86_vendor_id[0],
7337 +- (int *)&c->x86_vendor_id[8],
7338 +- (int *)&c->x86_vendor_id[4]);
7339 ++ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
7340 ++ (unsigned int *)&c->x86_vendor_id[0],
7341 ++ (unsigned int *)&c->x86_vendor_id[8],
7342 ++ (unsigned int *)&c->x86_vendor_id[4]);
7343 +
7344 + get_cpu_vendor(c, 0);
7345 + /* Initialize the standard set of capabilities */
7346 +@@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
7347 + {
7348 + struct Xgt_desc_struct gdt_descr;
7349 +
7350 +- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
7351 ++ gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
7352 + gdt_descr.size = GDT_SIZE - 1;
7353 + load_gdt(&gdt_descr);
7354 + asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
7355 +@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
7356 + {
7357 + int cpu = smp_processor_id();
7358 + struct task_struct *curr = current;
7359 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
7360 ++ struct tss_struct *t = init_tss + cpu;
7361 + struct thread_struct *thread = &curr->thread;
7362 +
7363 + if (cpu_test_and_set(cpu, cpu_initialized)) {
7364 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
7365 +--- linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-10-09 21:31:38.000000000 +0100
7366 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-02-11 10:37:44.000000000 +0000
7367 +@@ -549,7 +549,7 @@ static struct dmi_system_id sw_any_bug_d
7368 + DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
7369 + },
7370 + },
7371 +- { }
7372 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7373 + };
7374 + #endif
7375 +
7376 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
7377 +--- linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-10-09 21:31:38.000000000 +0100
7378 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2008-02-11 10:37:44.000000000 +0000
7379 +@@ -223,7 +223,7 @@ static struct cpu_model models[] =
7380 + { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
7381 + { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
7382 +
7383 +- { NULL, }
7384 ++ { NULL, NULL, 0, NULL}
7385 + };
7386 + #undef _BANIAS
7387 + #undef BANIAS
7388 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/intel_cacheinfo.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/intel_cacheinfo.c
7389 +--- linux-2.6.23.15/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-10-09 21:31:38.000000000 +0100
7390 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/intel_cacheinfo.c 2008-02-11 10:37:44.000000000 +0000
7391 +@@ -351,8 +351,8 @@ unsigned int __cpuinit init_intel_cachei
7392 + */
7393 + if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
7394 + /* supports eax=2 call */
7395 +- int i, j, n;
7396 +- int regs[4];
7397 ++ int j, n;
7398 ++ unsigned int regs[4];
7399 + unsigned char *dp = (unsigned char *)regs;
7400 + int only_trace = 0;
7401 +
7402 +@@ -367,7 +367,7 @@ unsigned int __cpuinit init_intel_cachei
7403 +
7404 + /* If bit 31 is set, this is an unknown format */
7405 + for ( j = 0 ; j < 3 ; j++ ) {
7406 +- if ( regs[j] < 0 ) regs[j] = 0;
7407 ++ if ( (int)regs[j] < 0 ) regs[j] = 0;
7408 + }
7409 +
7410 + /* Byte 0 is level count, not a descriptor */
7411 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/mcheck/therm_throt.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mcheck/therm_throt.c
7412 +--- linux-2.6.23.15/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-10-09 21:31:38.000000000 +0100
7413 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mcheck/therm_throt.c 2008-02-11 10:37:44.000000000 +0000
7414 +@@ -152,7 +152,7 @@ static __cpuinit int thermal_throttle_cp
7415 + return NOTIFY_OK;
7416 + }
7417 +
7418 +-static struct notifier_block thermal_throttle_cpu_notifier =
7419 ++static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier =
7420 + {
7421 + .notifier_call = thermal_throttle_cpu_callback,
7422 + };
7423 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mtrr/generic.c
7424 +--- linux-2.6.23.15/arch/i386/kernel/cpu/mtrr/generic.c 2007-10-09 21:31:38.000000000 +0100
7425 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mtrr/generic.c 2008-02-11 10:37:44.000000000 +0000
7426 +@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra
7427 + { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
7428 + { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
7429 + { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
7430 +- {}
7431 ++ { 0, 0 }
7432 + };
7433 +
7434 + static unsigned long smp_changes_mask;
7435 +-static struct mtrr_state mtrr_state = {};
7436 ++static struct mtrr_state mtrr_state;
7437 +
7438 + #undef MODULE_PARAM_PREFIX
7439 + #define MODULE_PARAM_PREFIX "mtrr."
7440 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/crash.c linux-2.6.23.15-grsec/arch/i386/kernel/crash.c
7441 +--- linux-2.6.23.15/arch/i386/kernel/crash.c 2007-10-09 21:31:38.000000000 +0100
7442 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/crash.c 2008-02-11 10:37:44.000000000 +0000
7443 +@@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not
7444 + return NOTIFY_STOP;
7445 + local_irq_disable();
7446 +
7447 +- if (!user_mode_vm(regs)) {
7448 ++ if (!user_mode(regs)) {
7449 + crash_fixup_ss_esp(&fixed_regs, regs);
7450 + regs = &fixed_regs;
7451 + }
7452 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/doublefault.c linux-2.6.23.15-grsec/arch/i386/kernel/doublefault.c
7453 +--- linux-2.6.23.15/arch/i386/kernel/doublefault.c 2007-10-09 21:31:38.000000000 +0100
7454 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/doublefault.c 2008-02-11 10:37:44.000000000 +0000
7455 +@@ -11,17 +11,17 @@
7456 +
7457 + #define DOUBLEFAULT_STACKSIZE (1024)
7458 + static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
7459 +-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
7460 ++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
7461 +
7462 + #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
7463 +
7464 + static void doublefault_fn(void)
7465 + {
7466 +- struct Xgt_desc_struct gdt_desc = {0, 0};
7467 ++ struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
7468 + unsigned long gdt, tss;
7469 +
7470 + store_gdt(&gdt_desc);
7471 +- gdt = gdt_desc.address;
7472 ++ gdt = (unsigned long)gdt_desc.address;
7473 +
7474 + printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
7475 +
7476 +@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
7477 + /* 0x2 bit is always set */
7478 + .eflags = X86_EFLAGS_SF | 0x2,
7479 + .esp = STACK_START,
7480 +- .es = __USER_DS,
7481 ++ .es = __KERNEL_DS,
7482 + .cs = __KERNEL_CS,
7483 + .ss = __KERNEL_DS,
7484 +- .ds = __USER_DS,
7485 ++ .ds = __KERNEL_DS,
7486 + .fs = __KERNEL_PERCPU,
7487 +
7488 + .__cr3 = __pa(swapper_pg_dir)
7489 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/efi.c linux-2.6.23.15-grsec/arch/i386/kernel/efi.c
7490 +--- linux-2.6.23.15/arch/i386/kernel/efi.c 2007-10-09 21:31:38.000000000 +0100
7491 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/efi.c 2008-02-11 10:37:44.000000000 +0000
7492 +@@ -63,45 +63,23 @@ extern void * boot_ioremap(unsigned long
7493 +
7494 + static unsigned long efi_rt_eflags;
7495 + static DEFINE_SPINLOCK(efi_rt_lock);
7496 +-static pgd_t efi_bak_pg_dir_pointer[2];
7497 ++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
7498 +
7499 + static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
7500 + {
7501 +- unsigned long cr4;
7502 +- unsigned long temp;
7503 + struct Xgt_desc_struct gdt_descr;
7504 +
7505 + spin_lock(&efi_rt_lock);
7506 + local_irq_save(efi_rt_eflags);
7507 +
7508 +- /*
7509 +- * If I don't have PSE, I should just duplicate two entries in page
7510 +- * directory. If I have PSE, I just need to duplicate one entry in
7511 +- * page directory.
7512 +- */
7513 +- cr4 = read_cr4();
7514 +-
7515 +- if (cr4 & X86_CR4_PSE) {
7516 +- efi_bak_pg_dir_pointer[0].pgd =
7517 +- swapper_pg_dir[pgd_index(0)].pgd;
7518 +- swapper_pg_dir[0].pgd =
7519 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
7520 +- } else {
7521 +- efi_bak_pg_dir_pointer[0].pgd =
7522 +- swapper_pg_dir[pgd_index(0)].pgd;
7523 +- efi_bak_pg_dir_pointer[1].pgd =
7524 +- swapper_pg_dir[pgd_index(0x400000)].pgd;
7525 +- swapper_pg_dir[pgd_index(0)].pgd =
7526 +- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
7527 +- temp = PAGE_OFFSET + 0x400000;
7528 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
7529 +- swapper_pg_dir[pgd_index(temp)].pgd;
7530 +- }
7531 ++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
7532 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
7533 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
7534 +
7535 + /*
7536 + * After the lock is released, the original page table is restored.
7537 + */
7538 +- local_flush_tlb();
7539 ++ __flush_tlb_all();
7540 +
7541 + gdt_descr.address = __pa(get_cpu_gdt_table(0));
7542 + gdt_descr.size = GDT_SIZE - 1;
7543 +@@ -110,35 +88,23 @@ static void efi_call_phys_prelog(void) _
7544 +
7545 + static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
7546 + {
7547 +- unsigned long cr4;
7548 + struct Xgt_desc_struct gdt_descr;
7549 +
7550 +- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
7551 ++ gdt_descr.address = get_cpu_gdt_table(0);
7552 + gdt_descr.size = GDT_SIZE - 1;
7553 + load_gdt(&gdt_descr);
7554 +-
7555 +- cr4 = read_cr4();
7556 +-
7557 +- if (cr4 & X86_CR4_PSE) {
7558 +- swapper_pg_dir[pgd_index(0)].pgd =
7559 +- efi_bak_pg_dir_pointer[0].pgd;
7560 +- } else {
7561 +- swapper_pg_dir[pgd_index(0)].pgd =
7562 +- efi_bak_pg_dir_pointer[0].pgd;
7563 +- swapper_pg_dir[pgd_index(0x400000)].pgd =
7564 +- efi_bak_pg_dir_pointer[1].pgd;
7565 +- }
7566 ++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
7567 +
7568 + /*
7569 + * After the lock is released, the original page table is restored.
7570 + */
7571 +- local_flush_tlb();
7572 ++ __flush_tlb_all();
7573 +
7574 + local_irq_restore(efi_rt_eflags);
7575 + spin_unlock(&efi_rt_lock);
7576 + }
7577 +
7578 +-static efi_status_t
7579 ++static efi_status_t __init
7580 + phys_efi_set_virtual_address_map(unsigned long memory_map_size,
7581 + unsigned long descriptor_size,
7582 + u32 descriptor_version,
7583 +@@ -154,7 +120,7 @@ phys_efi_set_virtual_address_map(unsigne
7584 + return status;
7585 + }
7586 +
7587 +-static efi_status_t
7588 ++static efi_status_t __init
7589 + phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
7590 + {
7591 + efi_status_t status;
7592 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/efi_stub.S linux-2.6.23.15-grsec/arch/i386/kernel/efi_stub.S
7593 +--- linux-2.6.23.15/arch/i386/kernel/efi_stub.S 2007-10-09 21:31:38.000000000 +0100
7594 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/efi_stub.S 2008-02-11 10:37:44.000000000 +0000
7595 +@@ -6,6 +6,7 @@
7596 + */
7597 +
7598 + #include <linux/linkage.h>
7599 ++#include <linux/init.h>
7600 + #include <asm/page.h>
7601 +
7602 + /*
7603 +@@ -20,7 +21,7 @@
7604 + * service functions will comply with gcc calling convention, too.
7605 + */
7606 +
7607 +-.text
7608 ++__INIT
7609 + ENTRY(efi_call_phys)
7610 + /*
7611 + * 0. The function can only be called in Linux kernel. So CS has been
7612 +@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
7613 + * The mapping of lower virtual memory has been created in prelog and
7614 + * epilog.
7615 + */
7616 +- movl $1f, %edx
7617 +- subl $__PAGE_OFFSET, %edx
7618 +- jmp *%edx
7619 ++ jmp 1f-__PAGE_OFFSET
7620 + 1:
7621 +
7622 + /*
7623 +@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
7624 + * parameter 2, ..., param n. To make things easy, we save the return
7625 + * address of efi_call_phys in a global variable.
7626 + */
7627 +- popl %edx
7628 +- movl %edx, saved_return_addr
7629 +- /* get the function pointer into ECX*/
7630 +- popl %ecx
7631 +- movl %ecx, efi_rt_function_ptr
7632 +- movl $2f, %edx
7633 +- subl $__PAGE_OFFSET, %edx
7634 +- pushl %edx
7635 ++ popl (saved_return_addr)
7636 ++ popl (efi_rt_function_ptr)
7637 +
7638 + /*
7639 + * 3. Clear PG bit in %CR0.
7640 +@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
7641 + /*
7642 + * 5. Call the physical function.
7643 + */
7644 +- jmp *%ecx
7645 ++ call *(efi_rt_function_ptr-__PAGE_OFFSET)
7646 +
7647 +-2:
7648 + /*
7649 + * 6. After EFI runtime service returns, control will return to
7650 + * following instruction. We'd better readjust stack pointer first.
7651 +@@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
7652 + movl %cr0, %edx
7653 + orl $0x80000000, %edx
7654 + movl %edx, %cr0
7655 +- jmp 1f
7656 +-1:
7657 ++
7658 + /*
7659 + * 8. Now restore the virtual mode from flat mode by
7660 + * adding EIP with PAGE_OFFSET.
7661 + */
7662 +- movl $1f, %edx
7663 +- jmp *%edx
7664 ++ jmp 1f+__PAGE_OFFSET
7665 + 1:
7666 +
7667 + /*
7668 + * 9. Balance the stack. And because EAX contain the return value,
7669 + * we'd better not clobber it.
7670 + */
7671 +- leal efi_rt_function_ptr, %edx
7672 +- movl (%edx), %ecx
7673 +- pushl %ecx
7674 ++ pushl (efi_rt_function_ptr)
7675 +
7676 + /*
7677 +- * 10. Push the saved return address onto the stack and return.
7678 ++ * 10. Return to the saved return address.
7679 + */
7680 +- leal saved_return_addr, %edx
7681 +- movl (%edx), %ecx
7682 +- pushl %ecx
7683 +- ret
7684 ++ jmpl *(saved_return_addr)
7685 + .previous
7686 +
7687 +-.data
7688 ++__INITDATA
7689 + saved_return_addr:
7690 + .long 0
7691 + efi_rt_function_ptr:
7692 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/entry.S linux-2.6.23.15-grsec/arch/i386/kernel/entry.S
7693 +--- linux-2.6.23.15/arch/i386/kernel/entry.S 2007-10-09 21:31:38.000000000 +0100
7694 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/entry.S 2008-02-11 10:37:44.000000000 +0000
7695 +@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
7696 + #define resume_userspace_sig resume_userspace
7697 + #endif
7698 +
7699 +-#define SAVE_ALL \
7700 ++#define __SAVE_ALL(_DS) \
7701 + cld; \
7702 + pushl %fs; \
7703 + CFI_ADJUST_CFA_OFFSET 4;\
7704 +@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
7705 + pushl %ebx; \
7706 + CFI_ADJUST_CFA_OFFSET 4;\
7707 + CFI_REL_OFFSET ebx, 0;\
7708 +- movl $(__USER_DS), %edx; \
7709 ++ movl $(_DS), %edx; \
7710 + movl %edx, %ds; \
7711 + movl %edx, %es; \
7712 + movl $(__KERNEL_PERCPU), %edx; \
7713 + movl %edx, %fs
7714 +
7715 ++#ifdef CONFIG_PAX_KERNEXEC
7716 ++#define SAVE_ALL \
7717 ++ __SAVE_ALL(__KERNEL_DS); \
7718 ++ GET_CR0_INTO_EDX; \
7719 ++ movl %edx, %esi; \
7720 ++ orl $X86_CR0_WP, %edx; \
7721 ++ xorl %edx, %esi; \
7722 ++ SET_CR0_FROM_EDX
7723 ++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
7724 ++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
7725 ++#else
7726 ++#define SAVE_ALL __SAVE_ALL(__USER_DS)
7727 ++#endif
7728 ++
7729 + #define RESTORE_INT_REGS \
7730 + popl %ebx; \
7731 + CFI_ADJUST_CFA_OFFSET -4;\
7732 +@@ -248,7 +262,17 @@ check_userspace:
7733 + movb PT_CS(%esp), %al
7734 + andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
7735 + cmpl $USER_RPL, %eax
7736 ++
7737 ++#ifdef CONFIG_PAX_KERNEXEC
7738 ++ jae resume_userspace
7739 ++
7740 ++ GET_CR0_INTO_EDX
7741 ++ xorl %esi, %edx
7742 ++ SET_CR0_FROM_EDX
7743 ++ jmp resume_kernel
7744 ++#else
7745 + jb resume_kernel # not returning to v8086 or userspace
7746 ++#endif
7747 +
7748 + ENTRY(resume_userspace)
7749 + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
7750 +@@ -307,10 +331,9 @@ sysenter_past_esp:
7751 + /*CFI_REL_OFFSET cs, 0*/
7752 + /*
7753 + * Push current_thread_info()->sysenter_return to the stack.
7754 +- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
7755 +- * pushed above; +8 corresponds to copy_thread's esp0 setting.
7756 + */
7757 +- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
7758 ++ GET_THREAD_INFO(%ebp)
7759 ++ pushl TI_sysenter_return(%ebp)
7760 + CFI_ADJUST_CFA_OFFSET 4
7761 + CFI_REL_OFFSET eip, 0
7762 +
7763 +@@ -318,9 +341,17 @@ sysenter_past_esp:
7764 + * Load the potential sixth argument from user stack.
7765 + * Careful about security.
7766 + */
7767 ++ movl 12(%esp),%ebp
7768 ++
7769 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
7770 ++ mov 16(%esp),%ds
7771 ++1: movl %ds:(%ebp),%ebp
7772 ++#else
7773 + cmpl $__PAGE_OFFSET-3,%ebp
7774 + jae syscall_fault
7775 + 1: movl (%ebp),%ebp
7776 ++#endif
7777 ++
7778 + .section __ex_table,"a"
7779 + .align 4
7780 + .long 1b,syscall_fault
7781 +@@ -343,20 +374,37 @@ sysenter_past_esp:
7782 + movl TI_flags(%ebp), %ecx
7783 + testw $_TIF_ALLWORK_MASK, %cx
7784 + jne syscall_exit_work
7785 ++
7786 ++#ifdef CONFIG_PAX_RANDKSTACK
7787 ++ pushl %eax
7788 ++ CFI_ADJUST_CFA_OFFSET 4
7789 ++ call pax_randomize_kstack
7790 ++ popl %eax
7791 ++ CFI_ADJUST_CFA_OFFSET -4
7792 ++#endif
7793 ++
7794 + /* if something modifies registers it must also disable sysexit */
7795 + movl PT_EIP(%esp), %edx
7796 + movl PT_OLDESP(%esp), %ecx
7797 + xorl %ebp,%ebp
7798 + TRACE_IRQS_ON
7799 + 1: mov PT_FS(%esp), %fs
7800 ++2: mov PT_DS(%esp), %ds
7801 ++3: mov PT_ES(%esp), %es
7802 + ENABLE_INTERRUPTS_SYSEXIT
7803 + CFI_ENDPROC
7804 + .pushsection .fixup,"ax"
7805 +-2: movl $0,PT_FS(%esp)
7806 ++4: movl $0,PT_FS(%esp)
7807 + jmp 1b
7808 ++5: movl $0,PT_DS(%esp)
7809 ++ jmp 2b
7810 ++6: movl $0,PT_ES(%esp)
7811 ++ jmp 3b
7812 + .section __ex_table,"a"
7813 + .align 4
7814 +- .long 1b,2b
7815 ++ .long 1b,4b
7816 ++ .long 2b,5b
7817 ++ .long 3b,6b
7818 + .popsection
7819 + ENDPROC(sysenter_entry)
7820 +
7821 +@@ -389,6 +437,10 @@ no_singlestep:
7822 + testw $_TIF_ALLWORK_MASK, %cx # current->work
7823 + jne syscall_exit_work
7824 +
7825 ++#ifdef CONFIG_PAX_RANDKSTACK
7826 ++ call pax_randomize_kstack
7827 ++#endif
7828 ++
7829 + restore_all:
7830 + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
7831 + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
7832 +@@ -552,17 +604,24 @@ syscall_badsys:
7833 + END(syscall_badsys)
7834 + CFI_ENDPROC
7835 +
7836 +-#define FIXUP_ESPFIX_STACK \
7837 +- /* since we are on a wrong stack, we cant make it a C code :( */ \
7838 +- PER_CPU(gdt_page, %ebx); \
7839 +- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
7840 +- addl %esp, %eax; \
7841 +- pushl $__KERNEL_DS; \
7842 +- CFI_ADJUST_CFA_OFFSET 4; \
7843 +- pushl %eax; \
7844 +- CFI_ADJUST_CFA_OFFSET 4; \
7845 +- lss (%esp), %esp; \
7846 ++.macro FIXUP_ESPFIX_STACK
7847 ++ /* since we are on a wrong stack, we cant make it a C code :( */
7848 ++#ifdef CONFIG_SMP
7849 ++ movl PER_CPU_VAR(cpu_number), %ebx;
7850 ++ shll $PAGE_SHIFT_asm, %ebx;
7851 ++ addl $cpu_gdt_table, %ebx;
7852 ++#else
7853 ++ movl $cpu_gdt_table, %ebx;
7854 ++#endif
7855 ++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
7856 ++ addl %esp, %eax;
7857 ++ pushl $__KERNEL_DS;
7858 ++ CFI_ADJUST_CFA_OFFSET 4;
7859 ++ pushl %eax;
7860 ++ CFI_ADJUST_CFA_OFFSET 4;
7861 ++ lss (%esp), %esp;
7862 + CFI_ADJUST_CFA_OFFSET -8;
7863 ++.endm
7864 + #define UNWIND_ESPFIX_STACK \
7865 + movl %ss, %eax; \
7866 + /* see if on espfix stack */ \
7867 +@@ -579,7 +638,7 @@ END(syscall_badsys)
7868 + * Build the entry stubs and pointer table with
7869 + * some assembler magic.
7870 + */
7871 +-.data
7872 ++.section .rodata,"a",@progbits
7873 + ENTRY(interrupt)
7874 + .text
7875 +
7876 +@@ -679,12 +738,21 @@ error_code:
7877 + popl %ecx
7878 + CFI_ADJUST_CFA_OFFSET -4
7879 + /*CFI_REGISTER es, ecx*/
7880 ++
7881 ++#ifdef CONFIG_PAX_KERNEXEC
7882 ++ GET_CR0_INTO_EDX
7883 ++ movl %edx, %esi
7884 ++ orl $X86_CR0_WP, %edx
7885 ++ xorl %edx, %esi
7886 ++ SET_CR0_FROM_EDX
7887 ++#endif
7888 ++
7889 + movl PT_FS(%esp), %edi # get the function address
7890 + movl PT_ORIG_EAX(%esp), %edx # get the error code
7891 + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
7892 + mov %ecx, PT_FS(%esp)
7893 + /*CFI_REL_OFFSET fs, ES*/
7894 +- movl $(__USER_DS), %ecx
7895 ++ movl $(__KERNEL_DS), %ecx
7896 + movl %ecx, %ds
7897 + movl %ecx, %es
7898 + movl %esp,%eax # pt_regs pointer
7899 +@@ -818,6 +886,13 @@ nmi_stack_correct:
7900 + xorl %edx,%edx # zero error code
7901 + movl %esp,%eax # pt_regs pointer
7902 + call do_nmi
7903 ++
7904 ++#ifdef CONFIG_PAX_KERNEXEC
7905 ++ GET_CR0_INTO_EDX
7906 ++ xorl %esi, %edx
7907 ++ SET_CR0_FROM_EDX
7908 ++#endif
7909 ++
7910 + jmp restore_nocheck_notrace
7911 + CFI_ENDPROC
7912 +
7913 +@@ -858,6 +933,13 @@ nmi_espfix_stack:
7914 + FIXUP_ESPFIX_STACK # %eax == %esp
7915 + xorl %edx,%edx # zero error code
7916 + call do_nmi
7917 ++
7918 ++#ifdef CONFIG_PAX_KERNEXEC
7919 ++ GET_CR0_INTO_EDX
7920 ++ xorl %esi, %edx
7921 ++ SET_CR0_FROM_EDX
7922 ++#endif
7923 ++
7924 + RESTORE_REGS
7925 + lss 12+4(%esp), %esp # back to espfix stack
7926 + CFI_ADJUST_CFA_OFFSET -24
7927 +@@ -1106,7 +1188,6 @@ ENDPROC(xen_failsafe_callback)
7928 +
7929 + #endif /* CONFIG_XEN */
7930 +
7931 +-.section .rodata,"a"
7932 + #include "syscall_table.S"
7933 +
7934 + syscall_table_size=(.-sys_call_table)
7935 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/head.S linux-2.6.23.15-grsec/arch/i386/kernel/head.S
7936 +--- linux-2.6.23.15/arch/i386/kernel/head.S 2007-10-09 21:31:38.000000000 +0100
7937 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/head.S 2008-02-11 10:37:44.000000000 +0000
7938 +@@ -18,6 +18,7 @@
7939 + #include <asm/thread_info.h>
7940 + #include <asm/asm-offsets.h>
7941 + #include <asm/setup.h>
7942 ++#include <asm/msr-index.h>
7943 +
7944 + /*
7945 + * References to members of the new_cpu_data structure.
7946 +@@ -51,17 +52,22 @@
7947 + */
7948 + LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
7949 +
7950 +-#if PTRS_PER_PMD > 1
7951 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
7952 +-#else
7953 +-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
7954 +-#endif
7955 ++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
7956 + BOOTBITMAP_SIZE = LOW_PAGES / 8
7957 + ALLOCATOR_SLOP = 4
7958 +
7959 + INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
7960 +
7961 + /*
7962 ++ * Real beginning of normal "text" segment
7963 ++ */
7964 ++ENTRY(stext)
7965 ++ENTRY(_stext)
7966 ++
7967 ++.section .text.startup,"ax",@progbits
7968 ++ ljmp $(__BOOT_CS),$phys_startup_32
7969 ++
7970 ++/*
7971 + * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
7972 + * %esi points to the real-mode code as a 32-bit pointer.
7973 + * CS and DS must be 4 GB flat segments, but we don't depend on
7974 +@@ -69,6 +75,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE +
7975 + * can.
7976 + */
7977 + .section .text.head,"ax",@progbits
7978 ++
7979 ++#ifdef CONFIG_PAX_KERNEXEC
7980 ++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
7981 ++.fill 4096,1,0xcc
7982 ++#endif
7983 ++
7984 + ENTRY(startup_32)
7985 +
7986 + /*
7987 +@@ -82,6 +94,43 @@ ENTRY(startup_32)
7988 + movl %eax,%fs
7989 + movl %eax,%gs
7990 +
7991 ++ movl $__per_cpu_start,%eax
7992 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
7993 ++ rorl $16,%eax
7994 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
7995 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
7996 ++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax
7997 ++ subl $__per_cpu_start,%eax
7998 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
7999 ++
8000 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
8001 ++ /* check for VMware */
8002 ++ movl $0x564d5868,%eax
8003 ++ xorl %ebx,%ebx
8004 ++ movl $0xa,%ecx
8005 ++ movl $0x5658,%edx
8006 ++ in (%dx),%eax
8007 ++ cmpl $0x564d5868,%ebx
8008 ++ jz 1f
8009 ++
8010 ++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
8011 ++ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
8012 ++1:
8013 ++#endif
8014 ++
8015 ++#ifdef CONFIG_PAX_KERNEXEC
8016 ++ movl $KERNEL_TEXT_OFFSET,%eax
8017 ++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
8018 ++ rorl $16,%eax
8019 ++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
8020 ++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
8021 ++
8022 ++ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
8023 ++ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
8024 ++ rorl $16,%eax
8025 ++ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
8026 ++#endif
8027 ++
8028 + /*
8029 + * Clear BSS first so that there are no surprises...
8030 + * No need to cld as DF is already clear from cld above...
8031 +@@ -129,24 +178,42 @@ ENTRY(startup_32)
8032 + * Warning: don't use %esi or the stack in this code. However, %esp
8033 + * can be used as a GPR if you really need it...
8034 + */
8035 +-page_pde_offset = (__PAGE_OFFSET >> 20);
8036 +-
8037 ++#ifdef CONFIG_X86_PAE
8038 ++page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
8039 ++#else
8040 ++page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
8041 ++#endif
8042 + movl $(pg0 - __PAGE_OFFSET), %edi
8043 ++#ifdef CONFIG_X86_PAE
8044 ++ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
8045 ++#else
8046 + movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
8047 +- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
8048 ++#endif
8049 ++ movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */
8050 + 10:
8051 +- leal 0x007(%edi),%ecx /* Create PDE entry */
8052 ++ leal 0x063(%edi),%ecx /* Create PDE entry */
8053 + movl %ecx,(%edx) /* Store identity PDE entry */
8054 + movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
8055 ++#ifdef CONFIG_X86_PAE
8056 ++ movl $0,4(%edx)
8057 ++ movl $0,page_pde_offset+4(%edx)
8058 ++ addl $8,%edx
8059 ++ movl $512, %ecx
8060 ++#else
8061 + addl $4,%edx
8062 + movl $1024, %ecx
8063 ++#endif
8064 + 11:
8065 + stosl
8066 ++#ifdef CONFIG_X86_PAE
8067 ++ movl $0,(%edi)
8068 ++ addl $4,%edi
8069 ++#endif
8070 + addl $0x1000,%eax
8071 + loop 11b
8072 + /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
8073 +- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
8074 +- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
8075 ++ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
8076 ++ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
8077 + cmpl %ebp,%eax
8078 + jb 10b
8079 + movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
8080 +@@ -167,10 +234,12 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
8081 + #endif
8082 +
8083 + /* Do an early initialization of the fixmap area */
8084 +- movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
8085 +- movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax
8086 +- addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
8087 +- movl %eax, 4092(%edx)
8088 ++ /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */
8089 ++#ifdef CONFIG_X86_PAE
8090 ++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8)
8091 ++#else
8092 ++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4)
8093 ++#endif
8094 +
8095 + #ifdef CONFIG_SMP
8096 + ENTRY(startup_32_smp)
8097 +@@ -181,6 +250,11 @@ ENTRY(startup_32_smp)
8098 + movl %eax,%fs
8099 + movl %eax,%gs
8100 +
8101 ++ /* This is a secondary processor (AP) */
8102 ++ xorl %ebx,%ebx
8103 ++ incl %ebx
8104 ++#endif /* CONFIG_SMP */
8105 ++
8106 + /*
8107 + * New page tables may be in 4Mbyte page mode and may
8108 + * be using the global pages.
8109 +@@ -196,42 +270,47 @@ ENTRY(startup_32_smp)
8110 + * not yet offset PAGE_OFFSET..
8111 + */
8112 + #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
8113 ++3:
8114 + movl cr4_bits,%edx
8115 + andl %edx,%edx
8116 +- jz 6f
8117 ++ jz 5f
8118 + movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
8119 + orl %edx,%eax
8120 + movl %eax,%cr4
8121 +
8122 +- btl $5, %eax # check if PAE is enabled
8123 +- jnc 6f
8124 ++#ifdef CONFIG_X86_PAE
8125 ++ movl %ebx,%edi
8126 +
8127 + /* Check if extended functions are implemented */
8128 + movl $0x80000000, %eax
8129 + cpuid
8130 + cmpl $0x80000000, %eax
8131 +- jbe 6f
8132 ++ jbe 4f
8133 + mov $0x80000001, %eax
8134 + cpuid
8135 + /* Execute Disable bit supported? */
8136 + btl $20, %edx
8137 +- jnc 6f
8138 ++ jnc 4f
8139 +
8140 + /* Setup EFER (Extended Feature Enable Register) */
8141 +- movl $0xc0000080, %ecx
8142 ++ movl $MSR_EFER, %ecx
8143 + rdmsr
8144 +
8145 + btsl $11, %eax
8146 + /* Make changes effective */
8147 + wrmsr
8148 +
8149 +-6:
8150 +- /* This is a secondary processor (AP) */
8151 +- xorl %ebx,%ebx
8152 +- incl %ebx
8153 ++ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
8154 ++ movl $1,nx_enabled-__PAGE_OFFSET
8155 +
8156 +-#endif /* CONFIG_SMP */
8157 +-3:
8158 ++#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
8159 ++ movl $0,disable_x86_sep-__PAGE_OFFSET
8160 ++#endif
8161 ++
8162 ++4:
8163 ++ movl %edi,%ebx
8164 ++#endif
8165 ++5:
8166 +
8167 + /*
8168 + * Enable paging
8169 +@@ -256,9 +335,7 @@ ENTRY(startup_32_smp)
8170 +
8171 + #ifdef CONFIG_SMP
8172 + andl %ebx,%ebx
8173 +- jz 1f /* Initial CPU cleans BSS */
8174 +- jmp checkCPUtype
8175 +-1:
8176 ++ jnz checkCPUtype /* Initial CPU cleans BSS */
8177 + #endif /* CONFIG_SMP */
8178 +
8179 + /*
8180 +@@ -335,12 +412,12 @@ is386: movl $2,%ecx # set MP
8181 + ljmp $(__KERNEL_CS),$1f
8182 + 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
8183 + movl %eax,%ss # after changing gdt.
8184 +- movl %eax,%fs # gets reset once there's real percpu
8185 +-
8186 +- movl $(__USER_DS),%eax # DS/ES contains default USER segment
8187 + movl %eax,%ds
8188 + movl %eax,%es
8189 +
8190 ++ movl $(__KERNEL_PERCPU), %eax
8191 ++ movl %eax,%fs # set this cpu's percpu
8192 ++
8193 + xorl %eax,%eax # Clear GS and LDT
8194 + movl %eax,%gs
8195 + lldt %ax
8196 +@@ -351,11 +428,7 @@ is386: movl $2,%ecx # set MP
8197 + movb ready, %cl
8198 + movb $1, ready
8199 + cmpb $0,%cl # the first CPU calls start_kernel
8200 +- je 1f
8201 +- movl $(__KERNEL_PERCPU), %eax
8202 +- movl %eax,%fs # set this cpu's percpu
8203 +- jmp initialize_secondary # all other CPUs call initialize_secondary
8204 +-1:
8205 ++ jne initialize_secondary # all other CPUs call initialize_secondary
8206 + #endif /* CONFIG_SMP */
8207 + jmp start_kernel
8208 +
8209 +@@ -441,8 +514,8 @@ early_page_fault:
8210 + jmp early_fault
8211 +
8212 + early_fault:
8213 +- cld
8214 + #ifdef CONFIG_PRINTK
8215 ++ cld
8216 + movl $(__KERNEL_DS),%eax
8217 + movl %eax,%ds
8218 + movl %eax,%es
8219 +@@ -466,8 +539,8 @@ hlt_loop:
8220 + /* This is the default interrupt "handler" :-) */
8221 + ALIGN
8222 + ignore_int:
8223 +- cld
8224 + #ifdef CONFIG_PRINTK
8225 ++ cld
8226 + pushl %eax
8227 + pushl %ecx
8228 + pushl %edx
8229 +@@ -498,31 +571,58 @@ ignore_int:
8230 + #endif
8231 + iret
8232 +
8233 +-.section .text
8234 +-/*
8235 +- * Real beginning of normal "text" segment
8236 +- */
8237 +-ENTRY(stext)
8238 +-ENTRY(_stext)
8239 +-
8240 + /*
8241 + * BSS section
8242 + */
8243 +-.section ".bss.page_aligned","wa"
8244 ++.section .swapper_pg_dir,"a",@progbits
8245 + .align PAGE_SIZE_asm
8246 + ENTRY(swapper_pg_dir)
8247 ++#ifdef CONFIG_X86_PAE
8248 ++ .long swapper_pm_dir-__PAGE_OFFSET+1
8249 ++ .long 0
8250 ++ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
8251 ++ .long 0
8252 ++ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
8253 ++ .long 0
8254 ++ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
8255 ++ .long 0
8256 ++#else
8257 + .fill 1024,4,0
8258 ++#endif
8259 ++
8260 ++.section .swapper_pm_dir,"a",@progbits
8261 ++#ifdef CONFIG_X86_PAE
8262 ++ENTRY(swapper_pm_dir)
8263 ++ .fill 512,8,0
8264 ++ .fill 512,8,0
8265 ++ .fill 512,8,0
8266 ++ .fill 512,8,0
8267 ++#endif
8268 ++
8269 + ENTRY(swapper_pg_pmd)
8270 + .fill 1024,4,0
8271 ++
8272 ++.section .empty_zero_page,"a",@progbits
8273 + ENTRY(empty_zero_page)
8274 + .fill 4096,1,0
8275 +
8276 + /*
8277 ++ * The IDT has to be page-aligned to simplify the Pentium
8278 ++ * F0 0F bug workaround.. We have a special link segment
8279 ++ * for this.
8280 ++ */
8281 ++.section .idt,"a",@progbits
8282 ++ENTRY(idt_table)
8283 ++ .fill 256,8,0
8284 ++
8285 ++/*
8286 + * This starts the data section.
8287 + */
8288 + .data
8289 ++
8290 ++.section .rodata,"a",@progbits
8291 + ENTRY(stack_start)
8292 +- .long init_thread_union+THREAD_SIZE
8293 ++ .long init_thread_union+THREAD_SIZE-8
8294 + .long __BOOT_DS
8295 +
8296 + ready: .byte 0
8297 +@@ -565,7 +665,7 @@ idt_descr:
8298 + .word 0 # 32 bit align gdt_desc.address
8299 + ENTRY(early_gdt_descr)
8300 + .word GDT_ENTRIES*8-1
8301 +- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
8302 ++ .long cpu_gdt_table /* Overwritten for secondary CPUs */
8303 +
8304 + /*
8305 + * The boot_gdt must mirror the equivalent in setup.S and is
8306 +@@ -574,5 +674,61 @@ ENTRY(early_gdt_descr)
8307 + .align L1_CACHE_BYTES
8308 + ENTRY(boot_gdt)
8309 + .fill GDT_ENTRY_BOOT_CS,8,0
8310 +- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
8311 +- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
8312 ++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
8313 ++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
8314 ++
8315 ++ .align PAGE_SIZE_asm
8316 ++ENTRY(cpu_gdt_table)
8317 ++ .quad 0x0000000000000000 /* NULL descriptor */
8318 ++ .quad 0x0000000000000000 /* 0x0b reserved */
8319 ++ .quad 0x0000000000000000 /* 0x13 reserved */
8320 ++ .quad 0x0000000000000000 /* 0x1b reserved */
8321 ++ .quad 0x0000000000000000 /* 0x20 unused */
8322 ++ .quad 0x0000000000000000 /* 0x28 unused */
8323 ++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
8324 ++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
8325 ++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
8326 ++ .quad 0x0000000000000000 /* 0x4b reserved */
8327 ++ .quad 0x0000000000000000 /* 0x53 reserved */
8328 ++ .quad 0x0000000000000000 /* 0x5b reserved */
8329 ++
8330 ++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
8331 ++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
8332 ++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
8333 ++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
8334 ++
8335 ++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
8336 ++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
8337 ++
8338 ++ /*
8339 ++ * Segments used for calling PnP BIOS have byte granularity.
8340 ++ * The code segments and data segments have fixed 64k limits,
8341 ++ * the transfer segment sizes are set at run time.
8342 ++ */
8343 ++ .quad 0x00409b000000ffff /* 0x90 32-bit code */
8344 ++ .quad 0x00009b000000ffff /* 0x98 16-bit code */
8345 ++ .quad 0x000093000000ffff /* 0xa0 16-bit data */
8346 ++ .quad 0x0000930000000000 /* 0xa8 16-bit data */
8347 ++ .quad 0x0000930000000000 /* 0xb0 16-bit data */
8348 ++
8349 ++ /*
8350 ++ * The APM segments have byte granularity and their bases
8351 ++ * are set at run time. All have 64k limits.
8352 ++ */
8353 ++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
8354 ++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
8355 ++ .quad 0x004093000000ffff /* 0xc8 APM DS data */
8356 ++
8357 ++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
8358 ++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
8359 ++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
8360 ++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
8361 ++ .quad 0x0000000000000000 /* 0xf0 - unused */
8362 ++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
8363 ++
8364 ++ /* Be sure this is zeroed to avoid false validations in Xen */
8365 ++ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
8366 ++
8367 ++#ifdef CONFIG_SMP
8368 ++ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
8369 ++#endif
8370 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/hpet.c linux-2.6.23.15-grsec/arch/i386/kernel/hpet.c
8371 +--- linux-2.6.23.15/arch/i386/kernel/hpet.c 2007-10-09 21:31:38.000000000 +0100
8372 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/hpet.c 2008-02-11 10:37:44.000000000 +0000
8373 +@@ -96,7 +96,7 @@ static void hpet_reserve_platform_timers
8374 + hd.hd_irq[1] = HPET_LEGACY_RTC;
8375 +
8376 + for (i = 2; i < nrtimers; timer++, i++)
8377 +- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
8378 ++ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
8379 + Tn_INT_ROUTE_CNF_SHIFT;
8380 +
8381 + hpet_alloc(&hd);
8382 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/i386_ksyms.c linux-2.6.23.15-grsec/arch/i386/kernel/i386_ksyms.c
8383 +--- linux-2.6.23.15/arch/i386/kernel/i386_ksyms.c 2007-10-09 21:31:38.000000000 +0100
8384 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/i386_ksyms.c 2008-02-11 10:37:44.000000000 +0000
8385 +@@ -2,12 +2,16 @@
8386 + #include <asm/checksum.h>
8387 + #include <asm/desc.h>
8388 +
8389 ++EXPORT_SYMBOL_GPL(cpu_gdt_table);
8390 ++
8391 + EXPORT_SYMBOL(__down_failed);
8392 + EXPORT_SYMBOL(__down_failed_interruptible);
8393 + EXPORT_SYMBOL(__down_failed_trylock);
8394 + EXPORT_SYMBOL(__up_wakeup);
8395 + /* Networking helper routines. */
8396 + EXPORT_SYMBOL(csum_partial_copy_generic);
8397 ++EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
8398 ++EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
8399 +
8400 + EXPORT_SYMBOL(__get_user_1);
8401 + EXPORT_SYMBOL(__get_user_2);
8402 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/i8259.c linux-2.6.23.15-grsec/arch/i386/kernel/i8259.c
8403 +--- linux-2.6.23.15/arch/i386/kernel/i8259.c 2007-10-09 21:31:38.000000000 +0100
8404 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/i8259.c 2008-02-11 10:37:44.000000000 +0000
8405 +@@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp
8406 + * New motherboards sometimes make IRQ 13 be a PCI interrupt,
8407 + * so allow interrupt sharing.
8408 + */
8409 +-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
8410 ++static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL };
8411 +
8412 + void __init init_ISA_irqs (void)
8413 + {
8414 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/init_task.c linux-2.6.23.15-grsec/arch/i386/kernel/init_task.c
8415 +--- linux-2.6.23.15/arch/i386/kernel/init_task.c 2007-10-09 21:31:38.000000000 +0100
8416 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/init_task.c 2008-02-11 10:37:44.000000000 +0000
8417 +@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
8418 + * per-CPU TSS segments. Threads are completely 'soft' on Linux,
8419 + * no more per-task TSS's.
8420 + */
8421 +-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
8422 ++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
8423 +
8424 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/ioport.c linux-2.6.23.15-grsec/arch/i386/kernel/ioport.c
8425 +--- linux-2.6.23.15/arch/i386/kernel/ioport.c 2007-10-09 21:31:38.000000000 +0100
8426 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/ioport.c 2008-02-11 10:37:44.000000000 +0000
8427 +@@ -16,6 +16,7 @@
8428 + #include <linux/slab.h>
8429 + #include <linux/thread_info.h>
8430 + #include <linux/syscalls.h>
8431 ++#include <linux/grsecurity.h>
8432 +
8433 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
8434 + static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
8435 +@@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
8436 +
8437 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
8438 + return -EINVAL;
8439 ++#ifdef CONFIG_GRKERNSEC_IO
8440 ++ if (turn_on) {
8441 ++ gr_handle_ioperm();
8442 ++#else
8443 + if (turn_on && !capable(CAP_SYS_RAWIO))
8444 ++#endif
8445 + return -EPERM;
8446 +-
8447 ++#ifdef CONFIG_GRKERNSEC_IO
8448 ++ }
8449 ++#endif
8450 + /*
8451 + * If it's the first ioperm() call in this thread's lifetime, set the
8452 + * IO bitmap up. ioperm() is much less timing critical than clone(),
8453 +@@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
8454 + * because the ->io_bitmap_max value must match the bitmap
8455 + * contents:
8456 + */
8457 +- tss = &per_cpu(init_tss, get_cpu());
8458 ++ tss = init_tss + get_cpu();
8459 +
8460 + set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
8461 +
8462 +@@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
8463 + return -EINVAL;
8464 + /* Trying to gain more privileges? */
8465 + if (level > old) {
8466 ++#ifdef CONFIG_GRKERNSEC_IO
8467 ++ gr_handle_iopl();
8468 ++ return -EPERM;
8469 ++#else
8470 + if (!capable(CAP_SYS_RAWIO))
8471 + return -EPERM;
8472 ++#endif
8473 + }
8474 + t->iopl = level << 12;
8475 + regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
8476 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/irq.c linux-2.6.23.15-grsec/arch/i386/kernel/irq.c
8477 +--- linux-2.6.23.15/arch/i386/kernel/irq.c 2007-10-09 21:31:38.000000000 +0100
8478 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/irq.c 2008-02-11 10:37:44.000000000 +0000
8479 +@@ -117,7 +117,7 @@ fastcall unsigned int do_IRQ(struct pt_r
8480 + int arg1, arg2, ebx;
8481 +
8482 + /* build the stack frame on the IRQ stack */
8483 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
8484 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
8485 + irqctx->tinfo.task = curctx->tinfo.task;
8486 + irqctx->tinfo.previous_esp = current_stack_pointer;
8487 +
8488 +@@ -213,7 +213,7 @@ asmlinkage void do_softirq(void)
8489 + irqctx->tinfo.previous_esp = current_stack_pointer;
8490 +
8491 + /* build the stack frame on the softirq stack */
8492 +- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
8493 ++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
8494 +
8495 + asm volatile(
8496 + " xchgl %%ebx,%%esp \n"
8497 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/kprobes.c linux-2.6.23.15-grsec/arch/i386/kernel/kprobes.c
8498 +--- linux-2.6.23.15/arch/i386/kernel/kprobes.c 2007-10-09 21:31:38.000000000 +0100
8499 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/kprobes.c 2008-02-11 10:37:44.000000000 +0000
8500 +@@ -49,9 +49,24 @@ static __always_inline void set_jmp_op(v
8501 + char op;
8502 + long raddr;
8503 + } __attribute__((packed)) *jop;
8504 +- jop = (struct __arch_jmp_op *)from;
8505 ++
8506 ++#ifdef CONFIG_PAX_KERNEXEC
8507 ++ unsigned long cr0;
8508 ++#endif
8509 ++
8510 ++ jop = (struct __arch_jmp_op *)(from + __KERNEL_TEXT_OFFSET);
8511 ++
8512 ++#ifdef CONFIG_PAX_KERNEXEC
8513 ++ pax_open_kernel(cr0);
8514 ++#endif
8515 ++
8516 + jop->raddr = (long)(to) - ((long)(from) + 5);
8517 + jop->op = RELATIVEJUMP_INSTRUCTION;
8518 ++
8519 ++#ifdef CONFIG_PAX_KERNEXEC
8520 ++ pax_close_kernel(cr0);
8521 ++#endif
8522 ++
8523 + }
8524 +
8525 + /*
8526 +@@ -153,14 +168,28 @@ static int __kprobes is_IF_modifier(kpro
8527 +
8528 + int __kprobes arch_prepare_kprobe(struct kprobe *p)
8529 + {
8530 ++
8531 ++#ifdef CONFIG_PAX_KERNEXEC
8532 ++ unsigned long cr0;
8533 ++#endif
8534 ++
8535 + /* insn: must be on special executable page on i386. */
8536 + p->ainsn.insn = get_insn_slot();
8537 + if (!p->ainsn.insn)
8538 + return -ENOMEM;
8539 +
8540 +- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
8541 +- p->opcode = *p->addr;
8542 +- if (can_boost(p->addr)) {
8543 ++#ifdef CONFIG_PAX_KERNEXEC
8544 ++ pax_open_kernel(cr0);
8545 ++#endif
8546 ++
8547 ++ memcpy(p->ainsn.insn, p->addr + __KERNEL_TEXT_OFFSET, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
8548 ++
8549 ++#ifdef CONFIG_PAX_KERNEXEC
8550 ++ pax_close_kernel(cr0);
8551 ++#endif
8552 ++
8553 ++ p->opcode = *(p->addr + __KERNEL_TEXT_OFFSET);
8554 ++ if (can_boost(p->addr + __KERNEL_TEXT_OFFSET)) {
8555 + p->ainsn.boostable = 0;
8556 + } else {
8557 + p->ainsn.boostable = -1;
8558 +@@ -219,7 +248,7 @@ static void __kprobes prepare_singlestep
8559 + if (p->opcode == BREAKPOINT_INSTRUCTION)
8560 + regs->eip = (unsigned long)p->addr;
8561 + else
8562 +- regs->eip = (unsigned long)p->ainsn.insn;
8563 ++ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
8564 + }
8565 +
8566 + /* Called with kretprobe_lock held */
8567 +@@ -325,7 +354,7 @@ ss_probe:
8568 + if (p->ainsn.boostable == 1 && !p->post_handler){
8569 + /* Boost up -- we can execute copied instructions directly */
8570 + reset_current_kprobe();
8571 +- regs->eip = (unsigned long)p->ainsn.insn;
8572 ++ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
8573 + preempt_enable_no_resched();
8574 + return 1;
8575 + }
8576 +@@ -475,7 +504,7 @@ static void __kprobes resume_execution(s
8577 + struct pt_regs *regs, struct kprobe_ctlblk *kcb)
8578 + {
8579 + unsigned long *tos = (unsigned long *)&regs->esp;
8580 +- unsigned long copy_eip = (unsigned long)p->ainsn.insn;
8581 ++ unsigned long copy_eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
8582 + unsigned long orig_eip = (unsigned long)p->addr;
8583 +
8584 + regs->eflags &= ~TF_MASK;
8585 +@@ -648,7 +677,7 @@ int __kprobes kprobe_exceptions_notify(s
8586 + struct die_args *args = (struct die_args *)data;
8587 + int ret = NOTIFY_DONE;
8588 +
8589 +- if (args->regs && user_mode_vm(args->regs))
8590 ++ if (args->regs && user_mode(args->regs))
8591 + return ret;
8592 +
8593 + switch (val) {
8594 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/ldt.c linux-2.6.23.15-grsec/arch/i386/kernel/ldt.c
8595 +--- linux-2.6.23.15/arch/i386/kernel/ldt.c 2007-10-09 21:31:38.000000000 +0100
8596 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/ldt.c 2008-02-11 10:37:44.000000000 +0000
8597 +@@ -58,7 +58,7 @@ static int alloc_ldt(mm_context_t *pc, i
8598 + #ifdef CONFIG_SMP
8599 + cpumask_t mask;
8600 + preempt_disable();
8601 +- load_LDT(pc);
8602 ++ load_LDT_nolock(pc);
8603 + mask = cpumask_of_cpu(smp_processor_id());
8604 + if (!cpus_equal(current->mm->cpu_vm_mask, mask))
8605 + smp_call_function(flush_ldt, NULL, 1, 1);
8606 +@@ -102,6 +102,22 @@ int init_new_context(struct task_struct
8607 + retval = copy_ldt(&mm->context, &old_mm->context);
8608 + up(&old_mm->context.sem);
8609 + }
8610 ++
8611 ++ if (tsk == current) {
8612 ++ mm->context.vdso = ~0UL;
8613 ++
8614 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
8615 ++ mm->context.user_cs_base = 0UL;
8616 ++ mm->context.user_cs_limit = ~0UL;
8617 ++
8618 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
8619 ++ cpus_clear(mm->context.cpu_user_cs_mask);
8620 ++#endif
8621 ++
8622 ++#endif
8623 ++
8624 ++ }
8625 ++
8626 + return retval;
8627 + }
8628 +
8629 +@@ -212,6 +228,13 @@ static int write_ldt(void __user * ptr,
8630 + }
8631 + }
8632 +
8633 ++#ifdef CONFIG_PAX_SEGMEXEC
8634 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
8635 ++ error = -EINVAL;
8636 ++ goto out_unlock;
8637 ++ }
8638 ++#endif
8639 ++
8640 + entry_1 = LDT_entry_a(&ldt_info);
8641 + entry_2 = LDT_entry_b(&ldt_info);
8642 + if (oldmode)
8643 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/machine_kexec.c linux-2.6.23.15-grsec/arch/i386/kernel/machine_kexec.c
8644 +--- linux-2.6.23.15/arch/i386/kernel/machine_kexec.c 2007-10-09 21:31:38.000000000 +0100
8645 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/machine_kexec.c 2008-02-11 10:37:44.000000000 +0000
8646 +@@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
8647 + static u32 kexec_pte0[1024] PAGE_ALIGNED;
8648 + static u32 kexec_pte1[1024] PAGE_ALIGNED;
8649 +
8650 +-static void set_idt(void *newidt, __u16 limit)
8651 ++static void set_idt(struct desc_struct *newidt, __u16 limit)
8652 + {
8653 + struct Xgt_desc_struct curidt;
8654 +
8655 + /* ia32 supports unaliged loads & stores */
8656 + curidt.size = limit;
8657 +- curidt.address = (unsigned long)newidt;
8658 ++ curidt.address = newidt;
8659 +
8660 + load_idt(&curidt);
8661 + };
8662 +
8663 +
8664 +-static void set_gdt(void *newgdt, __u16 limit)
8665 ++static void set_gdt(struct desc_struct *newgdt, __u16 limit)
8666 + {
8667 + struct Xgt_desc_struct curgdt;
8668 +
8669 + /* ia32 supports unaligned loads & stores */
8670 + curgdt.size = limit;
8671 +- curgdt.address = (unsigned long)newgdt;
8672 ++ curgdt.address = newgdt;
8673 +
8674 + load_gdt(&curgdt);
8675 + };
8676 +@@ -110,10 +110,10 @@ NORET_TYPE void machine_kexec(struct kim
8677 + local_irq_disable();
8678 +
8679 + control_page = page_address(image->control_code_page);
8680 +- memcpy(control_page, relocate_kernel, PAGE_SIZE);
8681 ++ memcpy(control_page, relocate_kernel + __KERNEL_TEXT_OFFSET, PAGE_SIZE);
8682 +
8683 + page_list[PA_CONTROL_PAGE] = __pa(control_page);
8684 +- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
8685 ++ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel + __KERNEL_TEXT_OFFSET;
8686 + page_list[PA_PGD] = __pa(kexec_pgd);
8687 + page_list[VA_PGD] = (unsigned long)kexec_pgd;
8688 + #ifdef CONFIG_X86_PAE
8689 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/module.c linux-2.6.23.15-grsec/arch/i386/kernel/module.c
8690 +--- linux-2.6.23.15/arch/i386/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
8691 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
8692 +@@ -23,6 +23,8 @@
8693 + #include <linux/kernel.h>
8694 + #include <linux/bug.h>
8695 +
8696 ++#include <asm/desc.h>
8697 ++
8698 + #if 0
8699 + #define DEBUGP printk
8700 + #else
8701 +@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
8702 + {
8703 + if (size == 0)
8704 + return NULL;
8705 ++
8706 ++#ifdef CONFIG_PAX_KERNEXEC
8707 ++ return vmalloc(size);
8708 ++#else
8709 + return vmalloc_exec(size);
8710 ++#endif
8711 ++
8712 + }
8713 +
8714 ++#ifdef CONFIG_PAX_KERNEXEC
8715 ++void *module_alloc_exec(unsigned long size)
8716 ++{
8717 ++ struct vm_struct *area;
8718 ++
8719 ++ if (size == 0)
8720 ++ return NULL;
8721 ++
8722 ++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
8723 ++ if (area)
8724 ++ return area->addr;
8725 ++
8726 ++ return NULL;
8727 ++}
8728 ++#endif
8729 +
8730 + /* Free memory returned from module_alloc */
8731 + void module_free(struct module *mod, void *module_region)
8732 +@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
8733 + table entries. */
8734 + }
8735 +
8736 ++#ifdef CONFIG_PAX_KERNEXEC
8737 ++void module_free_exec(struct module *mod, void *module_region)
8738 ++{
8739 ++ struct vm_struct **p, *tmp;
8740 ++
8741 ++ if (!module_region)
8742 ++ return;
8743 ++
8744 ++ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
8745 ++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
8746 ++ WARN_ON(1);
8747 ++ return;
8748 ++ }
8749 ++
8750 ++ write_lock(&vmlist_lock);
8751 ++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
8752 ++ if (tmp->addr == module_region)
8753 ++ break;
8754 ++
8755 ++ if (tmp) {
8756 ++ unsigned long cr0;
8757 ++
8758 ++ pax_open_kernel(cr0);
8759 ++ memset(tmp->addr, 0xCC, tmp->size);
8760 ++ pax_close_kernel(cr0);
8761 ++
8762 ++ *p = tmp->next;
8763 ++ kfree(tmp);
8764 ++ }
8765 ++ write_unlock(&vmlist_lock);
8766 ++
8767 ++ if (!tmp) {
8768 ++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
8769 ++ module_region);
8770 ++ WARN_ON(1);
8771 ++ }
8772 ++}
8773 ++#endif
8774 ++
8775 + /* We don't need anything special. */
8776 + int module_frob_arch_sections(Elf_Ehdr *hdr,
8777 + Elf_Shdr *sechdrs,
8778 +@@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
8779 + unsigned int i;
8780 + Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
8781 + Elf32_Sym *sym;
8782 +- uint32_t *location;
8783 ++ uint32_t *plocation, location;
8784 ++
8785 ++#ifdef CONFIG_PAX_KERNEXEC
8786 ++ unsigned long cr0;
8787 ++#endif
8788 +
8789 + DEBUGP("Applying relocate section %u to %u\n", relsec,
8790 + sechdrs[relsec].sh_info);
8791 + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
8792 + /* This is where to make the change */
8793 +- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
8794 +- + rel[i].r_offset;
8795 ++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
8796 ++ location = (uint32_t)plocation;
8797 ++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
8798 ++ plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
8799 + /* This is the symbol it is referring to. Note that all
8800 + undefined symbols have been resolved. */
8801 + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
8802 +@@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
8803 +
8804 + switch (ELF32_R_TYPE(rel[i].r_info)) {
8805 + case R_386_32:
8806 ++
8807 ++#ifdef CONFIG_PAX_KERNEXEC
8808 ++ pax_open_kernel(cr0);
8809 ++#endif
8810 ++
8811 + /* We add the value into the location given */
8812 +- *location += sym->st_value;
8813 ++ *plocation += sym->st_value;
8814 ++
8815 ++#ifdef CONFIG_PAX_KERNEXEC
8816 ++ pax_close_kernel(cr0);
8817 ++#endif
8818 ++
8819 + break;
8820 + case R_386_PC32:
8821 ++
8822 ++#ifdef CONFIG_PAX_KERNEXEC
8823 ++ pax_open_kernel(cr0);
8824 ++#endif
8825 ++
8826 + /* Add the value, subtract its postition */
8827 +- *location += sym->st_value - (uint32_t)location;
8828 ++ *plocation += sym->st_value - location;
8829 ++
8830 ++#ifdef CONFIG_PAX_KERNEXEC
8831 ++ pax_close_kernel(cr0);
8832 ++#endif
8833 ++
8834 + break;
8835 + default:
8836 + printk(KERN_ERR "module %s: Unknown relocation: %u\n",
8837 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/paravirt.c linux-2.6.23.15-grsec/arch/i386/kernel/paravirt.c
8838 +--- linux-2.6.23.15/arch/i386/kernel/paravirt.c 2007-10-09 21:31:38.000000000 +0100
8839 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/paravirt.c 2008-02-11 10:37:44.000000000 +0000
8840 +@@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *insn
8841 + if (insn_len > len || start == NULL)
8842 + insn_len = len;
8843 + else
8844 +- memcpy(insnbuf, start, insn_len);
8845 ++ memcpy(insnbuf, start + __KERNEL_TEXT_OFFSET, insn_len);
8846 +
8847 + return insn_len;
8848 + }
8849 +@@ -273,7 +273,7 @@ int paravirt_disable_iospace(void)
8850 + return ret;
8851 + }
8852 +
8853 +-struct paravirt_ops paravirt_ops = {
8854 ++struct paravirt_ops paravirt_ops __read_only = {
8855 + .name = "bare hardware",
8856 + .paravirt_enabled = 0,
8857 + .kernel_rpl = 0,
8858 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/process.c linux-2.6.23.15-grsec/arch/i386/kernel/process.c
8859 +--- linux-2.6.23.15/arch/i386/kernel/process.c 2007-10-09 21:31:38.000000000 +0100
8860 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/process.c 2008-02-11 10:37:44.000000000 +0000
8861 +@@ -68,15 +68,17 @@ EXPORT_SYMBOL(boot_option_idle_override)
8862 + DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
8863 + EXPORT_PER_CPU_SYMBOL(current_task);
8864 +
8865 ++#ifdef CONFIG_SMP
8866 + DEFINE_PER_CPU(int, cpu_number);
8867 + EXPORT_PER_CPU_SYMBOL(cpu_number);
8868 ++#endif
8869 +
8870 + /*
8871 + * Return saved PC of a blocked thread.
8872 + */
8873 + unsigned long thread_saved_pc(struct task_struct *tsk)
8874 + {
8875 +- return ((unsigned long *)tsk->thread.esp)[3];
8876 ++ return tsk->thread.eip;
8877 + }
8878 +
8879 + /*
8880 +@@ -307,7 +309,7 @@ void show_regs(struct pt_regs * regs)
8881 + printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
8882 + print_symbol("EIP is at %s\n", regs->eip);
8883 +
8884 +- if (user_mode_vm(regs))
8885 ++ if (user_mode(regs))
8886 + printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
8887 + printk(" EFLAGS: %08lx %s (%s %.*s)\n",
8888 + regs->eflags, print_tainted(), init_utsname()->release,
8889 +@@ -358,8 +360,8 @@ int kernel_thread(int (*fn)(void *), voi
8890 + regs.ebx = (unsigned long) fn;
8891 + regs.edx = (unsigned long) arg;
8892 +
8893 +- regs.xds = __USER_DS;
8894 +- regs.xes = __USER_DS;
8895 ++ regs.xds = __KERNEL_DS;
8896 ++ regs.xes = __KERNEL_DS;
8897 + regs.xfs = __KERNEL_PERCPU;
8898 + regs.orig_eax = -1;
8899 + regs.eip = (unsigned long) kernel_thread_helper;
8900 +@@ -381,7 +383,7 @@ void exit_thread(void)
8901 + struct task_struct *tsk = current;
8902 + struct thread_struct *t = &tsk->thread;
8903 + int cpu = get_cpu();
8904 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8905 ++ struct tss_struct *tss = init_tss + cpu;
8906 +
8907 + kfree(t->io_bitmap_ptr);
8908 + t->io_bitmap_ptr = NULL;
8909 +@@ -402,6 +404,7 @@ void flush_thread(void)
8910 + {
8911 + struct task_struct *tsk = current;
8912 +
8913 ++ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
8914 + memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
8915 + memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
8916 + clear_tsk_thread_flag(tsk, TIF_DEBUG);
8917 +@@ -435,7 +438,7 @@ int copy_thread(int nr, unsigned long cl
8918 + struct task_struct *tsk;
8919 + int err;
8920 +
8921 +- childregs = task_pt_regs(p);
8922 ++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
8923 + *childregs = *regs;
8924 + childregs->eax = 0;
8925 + childregs->esp = esp;
8926 +@@ -477,6 +480,11 @@ int copy_thread(int nr, unsigned long cl
8927 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
8928 + goto out;
8929 +
8930 ++#ifdef CONFIG_PAX_SEGMEXEC
8931 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
8932 ++ goto out;
8933 ++#endif
8934 ++
8935 + desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
8936 + desc->a = LDT_entry_a(&info);
8937 + desc->b = LDT_entry_b(&info);
8938 +@@ -663,7 +671,7 @@ struct task_struct fastcall * __switch_t
8939 + struct thread_struct *prev = &prev_p->thread,
8940 + *next = &next_p->thread;
8941 + int cpu = smp_processor_id();
8942 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
8943 ++ struct tss_struct *tss = init_tss + cpu;
8944 +
8945 + /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
8946 +
8947 +@@ -691,6 +699,11 @@ struct task_struct fastcall * __switch_t
8948 + */
8949 + savesegment(gs, prev->gs);
8950 +
8951 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
8952 ++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
8953 ++ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
8954 ++#endif
8955 ++
8956 + /*
8957 + * Load the per-thread Thread-Local Storage descriptor.
8958 + */
8959 +@@ -855,6 +868,12 @@ asmlinkage int sys_set_thread_area(struc
8960 +
8961 + if (copy_from_user(&info, u_info, sizeof(info)))
8962 + return -EFAULT;
8963 ++
8964 ++#ifdef CONFIG_PAX_SEGMEXEC
8965 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
8966 ++ return -EINVAL;
8967 ++#endif
8968 ++
8969 + idx = info.entry_number;
8970 +
8971 + /*
8972 +@@ -943,9 +962,28 @@ asmlinkage int sys_get_thread_area(struc
8973 + return 0;
8974 + }
8975 +
8976 +-unsigned long arch_align_stack(unsigned long sp)
8977 ++#ifdef CONFIG_PAX_RANDKSTACK
8978 ++asmlinkage void pax_randomize_kstack(void)
8979 + {
8980 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8981 +- sp -= get_random_int() % 8192;
8982 +- return sp & ~0xf;
8983 ++ struct tss_struct *tss;
8984 ++ unsigned long time;
8985 ++
8986 ++ if (!randomize_va_space)
8987 ++ return;
8988 ++
8989 ++ tss = init_tss + smp_processor_id();
8990 ++ rdtscl(time);
8991 ++
8992 ++ /* P4 seems to return a 0 LSB, ignore it */
8993 ++#ifdef CONFIG_MPENTIUM4
8994 ++ time &= 0x1EUL;
8995 ++ time <<= 2;
8996 ++#else
8997 ++ time &= 0xFUL;
8998 ++ time <<= 3;
8999 ++#endif
9000 ++
9001 ++ tss->x86_tss.esp0 ^= time;
9002 ++ current->thread.esp0 = tss->x86_tss.esp0;
9003 + }
9004 ++#endif
9005 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/ptrace.c linux-2.6.23.15-grsec/arch/i386/kernel/ptrace.c
9006 +--- linux-2.6.23.15/arch/i386/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
9007 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
9008 +@@ -161,22 +161,20 @@ static unsigned long convert_eip_to_line
9009 + * and APM bios ones we just ignore here.
9010 + */
9011 + if (seg & LDT_SEGMENT) {
9012 +- u32 *desc;
9013 ++ struct desc_struct *desc;
9014 + unsigned long base;
9015 +
9016 + seg &= ~7UL;
9017 +
9018 + down(&child->mm->context.sem);
9019 + if (unlikely((seg >> 3) >= child->mm->context.size))
9020 +- addr = -1L; /* bogus selector, access would fault */
9021 ++ addr = -EINVAL;
9022 + else {
9023 +- desc = child->mm->context.ldt + seg;
9024 +- base = ((desc[0] >> 16) |
9025 +- ((desc[1] & 0xff) << 16) |
9026 +- (desc[1] & 0xff000000));
9027 ++ desc = &child->mm->context.ldt[seg >> 3];
9028 ++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
9029 +
9030 + /* 16-bit code segment? */
9031 +- if (!((desc[1] >> 22) & 1))
9032 ++ if (!((desc->b >> 22) & 1))
9033 + addr &= 0xffff;
9034 + addr += base;
9035 + }
9036 +@@ -191,6 +189,9 @@ static inline int is_setting_trap_flag(s
9037 + unsigned char opcode[15];
9038 + unsigned long addr = convert_eip_to_linear(child, regs);
9039 +
9040 ++ if (addr == -EINVAL)
9041 ++ return 0;
9042 ++
9043 + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
9044 + for (i = 0; i < copied; i++) {
9045 + switch (opcode[i]) {
9046 +@@ -341,6 +342,11 @@ ptrace_set_thread_area(struct task_struc
9047 + if (copy_from_user(&info, user_desc, sizeof(info)))
9048 + return -EFAULT;
9049 +
9050 ++#ifdef CONFIG_PAX_SEGMEXEC
9051 ++ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
9052 ++ return -EINVAL;
9053 ++#endif
9054 ++
9055 + if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
9056 + return -EINVAL;
9057 +
9058 +@@ -420,6 +426,17 @@ long arch_ptrace(struct task_struct *chi
9059 + if(addr == (long) &dummy->u_debugreg[5]) break;
9060 + if(addr < (long) &dummy->u_debugreg[4] &&
9061 + ((unsigned long) data) >= TASK_SIZE-3) break;
9062 ++
9063 ++#ifdef CONFIG_GRKERNSEC
9064 ++ if(addr >= (long) &dummy->u_debugreg[0] &&
9065 ++ addr <= (long) &dummy->u_debugreg[3]){
9066 ++ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
9067 ++ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
9068 ++ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
9069 ++ if((type & 1) && (data & align))
9070 ++ break;
9071 ++ }
9072 ++#endif
9073 +
9074 + /* Sanity-check data. Take one half-byte at once with
9075 + * check = (val >> (16 + 4*i)) & 0xf. It contains the
9076 +@@ -636,7 +653,7 @@ void send_sigtrap(struct task_struct *ts
9077 + info.si_code = TRAP_BRKPT;
9078 +
9079 + /* User-mode eip? */
9080 +- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
9081 ++ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
9082 +
9083 + /* Send us the fakey SIGTRAP */
9084 + force_sig_info(SIGTRAP, &info, tsk);
9085 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/reboot.c linux-2.6.23.15-grsec/arch/i386/kernel/reboot.c
9086 +--- linux-2.6.23.15/arch/i386/kernel/reboot.c 2007-10-09 21:31:38.000000000 +0100
9087 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/reboot.c 2008-02-11 10:37:44.000000000 +0000
9088 +@@ -26,7 +26,7 @@
9089 + void (*pm_power_off)(void);
9090 + EXPORT_SYMBOL(pm_power_off);
9091 +
9092 +-static int reboot_mode;
9093 ++static unsigned short reboot_mode;
9094 + static int reboot_thru_bios;
9095 +
9096 + #ifdef CONFIG_SMP
9097 +@@ -138,7 +138,7 @@ static struct dmi_system_id __initdata r
9098 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
9099 + },
9100 + },
9101 +- { }
9102 ++ { NULL, NULL, {{0, NULL}}, NULL}
9103 + };
9104 +
9105 + static int __init reboot_init(void)
9106 +@@ -156,18 +156,18 @@ core_initcall(reboot_init);
9107 + doesn't work with at least one type of 486 motherboard. It is easy
9108 + to stop this code working; hence the copious comments. */
9109 +
9110 +-static unsigned long long
9111 +-real_mode_gdt_entries [3] =
9112 ++static struct desc_struct
9113 ++real_mode_gdt_entries [3] __read_only =
9114 + {
9115 +- 0x0000000000000000ULL, /* Null descriptor */
9116 +- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
9117 +- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
9118 ++ {0x00000000, 0x00000000}, /* Null descriptor */
9119 ++ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
9120 ++ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
9121 + };
9122 +
9123 +-static struct Xgt_desc_struct
9124 +-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
9125 +-real_mode_idt = { 0x3ff, 0 },
9126 +-no_idt = { 0, 0 };
9127 ++static const struct Xgt_desc_struct
9128 ++real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
9129 ++real_mode_idt = { 0x3ff, NULL, 0 },
9130 ++no_idt = { 0, NULL, 0 };
9131 +
9132 +
9133 + /* This is 16-bit protected mode code to disable paging and the cache,
9134 +@@ -189,7 +189,7 @@ no_idt = { 0, 0 };
9135 + More could be done here to set up the registers as if a CPU reset had
9136 + occurred; hopefully real BIOSs don't assume much. */
9137 +
9138 +-static unsigned char real_mode_switch [] =
9139 ++static const unsigned char real_mode_switch [] =
9140 + {
9141 + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
9142 + 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
9143 +@@ -203,7 +203,7 @@ static unsigned char real_mode_switch []
9144 + 0x24, 0x10, /* f: andb $0x10,al */
9145 + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
9146 + };
9147 +-static unsigned char jump_to_bios [] =
9148 ++static const unsigned char jump_to_bios [] =
9149 + {
9150 + 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
9151 + };
9152 +@@ -213,7 +213,7 @@ static unsigned char jump_to_bios [] =
9153 + * specified by the code and length parameters.
9154 + * We assume that length will aways be less that 100!
9155 + */
9156 +-void machine_real_restart(unsigned char *code, int length)
9157 ++void machine_real_restart(const unsigned char *code, unsigned int length)
9158 + {
9159 + local_irq_disable();
9160 +
9161 +@@ -234,9 +234,8 @@ void machine_real_restart(unsigned char
9162 + /* Remap the kernel at virtual address zero, as well as offset zero
9163 + from the kernel segment. This assumes the kernel segment starts at
9164 + virtual address PAGE_OFFSET. */
9165 +-
9166 +- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
9167 +- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
9168 ++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
9169 ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
9170 +
9171 + /*
9172 + * Use `swapper_pg_dir' as our page directory.
9173 +@@ -249,7 +248,7 @@ void machine_real_restart(unsigned char
9174 + REBOOT.COM programs, and the previous reset routine did this
9175 + too. */
9176 +
9177 +- *((unsigned short *)0x472) = reboot_mode;
9178 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
9179 +
9180 + /* For the switch to real mode, copy some code to low memory. It has
9181 + to be in the first 64k because it is running in 16-bit mode, and it
9182 +@@ -257,9 +256,8 @@ void machine_real_restart(unsigned char
9183 + off paging. Copy it near the end of the first page, out of the way
9184 + of BIOS variables. */
9185 +
9186 +- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
9187 +- real_mode_switch, sizeof (real_mode_switch));
9188 +- memcpy ((void *) (0x1000 - 100), code, length);
9189 ++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
9190 ++ memcpy(__va(0x1000 - 100), code, length);
9191 +
9192 + /* Set up the IDT for real mode. */
9193 +
9194 +@@ -345,7 +343,7 @@ static void native_machine_emergency_res
9195 + __asm__ __volatile__("int3");
9196 + }
9197 + /* rebooting needs to touch the page at absolute addr 0 */
9198 +- *((unsigned short *)__va(0x472)) = reboot_mode;
9199 ++ *(unsigned short *)(__va(0x472)) = reboot_mode;
9200 + for (;;) {
9201 + mach_reboot_fixups(); /* for board specific fixups */
9202 + mach_reboot();
9203 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/setup.c linux-2.6.23.15-grsec/arch/i386/kernel/setup.c
9204 +--- linux-2.6.23.15/arch/i386/kernel/setup.c 2007-10-09 21:31:38.000000000 +0100
9205 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/setup.c 2008-02-11 10:37:44.000000000 +0000
9206 +@@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
9207 + struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
9208 + EXPORT_SYMBOL(boot_cpu_data);
9209 +
9210 ++#ifdef CONFIG_X86_PAE
9211 ++unsigned long mmu_cr4_features = X86_CR4_PAE;
9212 ++#else
9213 + unsigned long mmu_cr4_features;
9214 ++#endif
9215 +
9216 + /* for MCA, but anyone else can use it if they want */
9217 + unsigned int machine_id;
9218 +@@ -395,8 +399,8 @@ void __init setup_bootmem_allocator(void
9219 + * the (very unlikely) case of us accidentally initializing the
9220 + * bootmem allocator with an invalid RAM area.
9221 + */
9222 +- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
9223 +- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
9224 ++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
9225 ++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
9226 +
9227 + /*
9228 + * reserve physical page 0 - it's a special BIOS page on many boxes,
9229 +@@ -549,14 +553,14 @@ void __init setup_arch(char **cmdline_p)
9230 +
9231 + if (!MOUNT_ROOT_RDONLY)
9232 + root_mountflags &= ~MS_RDONLY;
9233 +- init_mm.start_code = (unsigned long) _text;
9234 +- init_mm.end_code = (unsigned long) _etext;
9235 ++ init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
9236 ++ init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
9237 + init_mm.end_data = (unsigned long) _edata;
9238 + init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
9239 +
9240 +- code_resource.start = virt_to_phys(_text);
9241 +- code_resource.end = virt_to_phys(_etext)-1;
9242 +- data_resource.start = virt_to_phys(_etext);
9243 ++ code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
9244 ++ code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
9245 ++ data_resource.start = virt_to_phys(_data);
9246 + data_resource.end = virt_to_phys(_edata)-1;
9247 +
9248 + parse_early_param();
9249 +@@ -651,3 +655,23 @@ void __init setup_arch(char **cmdline_p)
9250 + #endif
9251 + #endif
9252 + }
9253 ++
9254 ++unsigned long __per_cpu_offset[NR_CPUS] __read_only;
9255 ++
9256 ++EXPORT_SYMBOL(__per_cpu_offset);
9257 ++
9258 ++void __init setup_per_cpu_areas(void)
9259 ++{
9260 ++ unsigned long size, i;
9261 ++ char *ptr;
9262 ++
9263 ++ /* Copy section for each CPU (we discard the original) */
9264 ++ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
9265 ++ ptr = alloc_bootmem_pages(size * num_possible_cpus());
9266 ++
9267 ++ for_each_possible_cpu(i) {
9268 ++ __per_cpu_offset[i] = (unsigned long)ptr;
9269 ++ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
9270 ++ ptr += size;
9271 ++ }
9272 ++}
9273 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/signal.c linux-2.6.23.15-grsec/arch/i386/kernel/signal.c
9274 +--- linux-2.6.23.15/arch/i386/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100
9275 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/signal.c 2008-02-11 10:37:44.000000000 +0000
9276 +@@ -357,9 +357,9 @@ static int setup_frame(int sig, struct k
9277 + }
9278 +
9279 + if (current->binfmt->hasvdso)
9280 +- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
9281 ++ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
9282 + else
9283 +- restorer = (void *)&frame->retcode;
9284 ++ restorer = (void __user *)&frame->retcode;
9285 + if (ka->sa.sa_flags & SA_RESTORER)
9286 + restorer = ka->sa.sa_restorer;
9287 +
9288 +@@ -455,7 +455,8 @@ static int setup_rt_frame(int sig, struc
9289 + goto give_sigsegv;
9290 +
9291 + /* Set up to return from userspace. */
9292 +- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
9293 ++
9294 ++ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
9295 + if (ka->sa.sa_flags & SA_RESTORER)
9296 + restorer = ka->sa.sa_restorer;
9297 + err |= __put_user(restorer, &frame->pretcode);
9298 +@@ -588,7 +589,7 @@ static void fastcall do_signal(struct pt
9299 + * before reaching here, so testing against kernel
9300 + * CS suffices.
9301 + */
9302 +- if (!user_mode(regs))
9303 ++ if (!user_mode_novm(regs))
9304 + return;
9305 +
9306 + if (test_thread_flag(TIF_RESTORE_SIGMASK))
9307 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/smp.c linux-2.6.23.15-grsec/arch/i386/kernel/smp.c
9308 +--- linux-2.6.23.15/arch/i386/kernel/smp.c 2007-10-09 21:31:38.000000000 +0100
9309 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/smp.c 2008-02-11 10:37:44.000000000 +0000
9310 +@@ -104,7 +104,7 @@
9311 + * about nothing of note with C stepping upwards.
9312 + */
9313 +
9314 +-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
9315 ++DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
9316 +
9317 + /*
9318 + * the following functions deal with sending IPIs between CPUs.
9319 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/smpboot.c linux-2.6.23.15-grsec/arch/i386/kernel/smpboot.c
9320 +--- linux-2.6.23.15/arch/i386/kernel/smpboot.c 2007-10-09 21:31:38.000000000 +0100
9321 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/smpboot.c 2008-02-11 10:37:44.000000000 +0000
9322 +@@ -118,7 +118,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
9323 + * has made sure it's suitably aligned.
9324 + */
9325 +
9326 +-static unsigned long __devinit setup_trampoline(void)
9327 ++static unsigned long __cpuinit setup_trampoline(void)
9328 + {
9329 + memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
9330 + return virt_to_phys(trampoline_base);
9331 +@@ -772,6 +772,10 @@ static int __cpuinit do_boot_cpu(int api
9332 + unsigned long start_eip;
9333 + unsigned short nmi_high = 0, nmi_low = 0;
9334 +
9335 ++#ifdef CONFIG_PAX_KERNEXEC
9336 ++ unsigned long cr0;
9337 ++#endif
9338 ++
9339 + /*
9340 + * Save current MTRR state in case it was changed since early boot
9341 + * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
9342 +@@ -788,7 +792,16 @@ static int __cpuinit do_boot_cpu(int api
9343 +
9344 + init_gdt(cpu);
9345 + per_cpu(current_task, cpu) = idle;
9346 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9347 ++
9348 ++#ifdef CONFIG_PAX_KERNEXEC
9349 ++ pax_open_kernel(cr0);
9350 ++#endif
9351 ++
9352 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
9353 ++
9354 ++#ifdef CONFIG_PAX_KERNEXEC
9355 ++ pax_close_kernel(cr0);
9356 ++#endif
9357 +
9358 + idle->thread.eip = (unsigned long) start_secondary;
9359 + /* start_eip had better be page-aligned! */
9360 +@@ -1105,7 +1118,7 @@ static void __init smp_boot_cpus(unsigne
9361 + * construct cpu_sibling_map[], so that we can tell sibling CPUs
9362 + * efficiently.
9363 + */
9364 +- for (cpu = 0; cpu < NR_CPUS; cpu++) {
9365 ++ for_each_possible_cpu(cpu) {
9366 + cpus_clear(cpu_sibling_map[cpu]);
9367 + cpus_clear(cpu_core_map[cpu]);
9368 + }
9369 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/smpcommon.c linux-2.6.23.15-grsec/arch/i386/kernel/smpcommon.c
9370 +--- linux-2.6.23.15/arch/i386/kernel/smpcommon.c 2007-10-09 21:31:38.000000000 +0100
9371 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/smpcommon.c 2008-02-11 10:37:44.000000000 +0000
9372 +@@ -3,6 +3,7 @@
9373 + */
9374 + #include <linux/module.h>
9375 + #include <asm/smp.h>
9376 ++#include <asm/sections.h>
9377 +
9378 + DEFINE_PER_CPU(unsigned long, this_cpu_off);
9379 + EXPORT_PER_CPU_SYMBOL(this_cpu_off);
9380 +@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
9381 + {
9382 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
9383 +
9384 +- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
9385 +- (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
9386 +- __per_cpu_offset[cpu], 0xFFFFF,
9387 +- 0x80 | DESCTYPE_S | 0x2, 0x8);
9388 ++#ifdef CONFIG_PAX_KERNEXEC
9389 ++ unsigned long cr0;
9390 ++
9391 ++ pax_open_kernel(cr0);
9392 ++#endif
9393 ++
9394 ++ if (cpu)
9395 ++ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
9396 ++
9397 ++ if (PERCPU_ENOUGH_ROOM <= 64*1024*1024)
9398 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
9399 ++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
9400 ++ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1,
9401 ++ 0x80 | DESCTYPE_S | 0x3, 0x4);
9402 ++ else
9403 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
9404 ++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
9405 ++ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
9406 ++ 0x80 | DESCTYPE_S | 0x3, 0xC);
9407 ++
9408 ++#ifdef CONFIG_PAX_KERNEXEC
9409 ++ pax_close_kernel(cr0);
9410 ++#endif
9411 +
9412 + per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
9413 + per_cpu(cpu_number, cpu) = cpu;
9414 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/sys_i386.c linux-2.6.23.15-grsec/arch/i386/kernel/sys_i386.c
9415 +--- linux-2.6.23.15/arch/i386/kernel/sys_i386.c 2007-10-09 21:31:38.000000000 +0100
9416 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/sys_i386.c 2008-02-11 10:37:44.000000000 +0000
9417 +@@ -41,6 +41,21 @@ asmlinkage int sys_pipe(unsigned long __
9418 + return error;
9419 + }
9420 +
9421 ++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
9422 ++{
9423 ++ unsigned long task_size = TASK_SIZE;
9424 ++
9425 ++#ifdef CONFIG_PAX_SEGMEXEC
9426 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
9427 ++ task_size = SEGMEXEC_TASK_SIZE;
9428 ++#endif
9429 ++
9430 ++ if (len > task_size || addr > task_size - len)
9431 ++ return -EINVAL;
9432 ++
9433 ++ return 0;
9434 ++}
9435 ++
9436 + asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
9437 + unsigned long prot, unsigned long flags,
9438 + unsigned long fd, unsigned long pgoff)
9439 +@@ -100,6 +115,205 @@ out:
9440 + return err;
9441 + }
9442 +
9443 ++unsigned long
9444 ++arch_get_unmapped_area(struct file *filp, unsigned long addr,
9445 ++ unsigned long len, unsigned long pgoff, unsigned long flags)
9446 ++{
9447 ++ struct mm_struct *mm = current->mm;
9448 ++ struct vm_area_struct *vma;
9449 ++ unsigned long start_addr, task_size = TASK_SIZE;
9450 ++
9451 ++#ifdef CONFIG_PAX_SEGMEXEC
9452 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9453 ++ task_size = SEGMEXEC_TASK_SIZE;
9454 ++#endif
9455 ++
9456 ++ if (len > task_size)
9457 ++ return -ENOMEM;
9458 ++
9459 ++ if (flags & MAP_FIXED)
9460 ++ return addr;
9461 ++
9462 ++#ifdef CONFIG_PAX_RANDMMAP
9463 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9464 ++#endif
9465 ++
9466 ++ if (addr) {
9467 ++ addr = PAGE_ALIGN(addr);
9468 ++ vma = find_vma(mm, addr);
9469 ++ if (task_size - len >= addr &&
9470 ++ (!vma || addr + len <= vma->vm_start))
9471 ++ return addr;
9472 ++ }
9473 ++ if (len > mm->cached_hole_size) {
9474 ++ start_addr = addr = mm->free_area_cache;
9475 ++ } else {
9476 ++ start_addr = addr = mm->mmap_base;
9477 ++ mm->cached_hole_size = 0;
9478 ++ }
9479 ++
9480 ++#ifdef CONFIG_PAX_PAGEEXEC
9481 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
9482 ++ start_addr = 0x00110000UL;
9483 ++
9484 ++#ifdef CONFIG_PAX_RANDMMAP
9485 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9486 ++ start_addr += mm->delta_mmap & 0x03FFF000UL;
9487 ++#endif
9488 ++
9489 ++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
9490 ++ start_addr = addr = mm->mmap_base;
9491 ++ else
9492 ++ addr = start_addr;
9493 ++ }
9494 ++#endif
9495 ++
9496 ++full_search:
9497 ++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
9498 ++ /* At this point: (!vma || addr < vma->vm_end). */
9499 ++ if (task_size - len < addr) {
9500 ++ /*
9501 ++ * Start a new search - just in case we missed
9502 ++ * some holes.
9503 ++ */
9504 ++ if (start_addr != mm->mmap_base) {
9505 ++ start_addr = addr = mm->mmap_base;
9506 ++ mm->cached_hole_size = 0;
9507 ++ goto full_search;
9508 ++ }
9509 ++ return -ENOMEM;
9510 ++ }
9511 ++ if (!vma || addr + len <= vma->vm_start) {
9512 ++ /*
9513 ++ * Remember the place where we stopped the search:
9514 ++ */
9515 ++ mm->free_area_cache = addr + len;
9516 ++ return addr;
9517 ++ }
9518 ++ if (addr + mm->cached_hole_size < vma->vm_start)
9519 ++ mm->cached_hole_size = vma->vm_start - addr;
9520 ++ addr = vma->vm_end;
9521 ++ if (mm->start_brk <= addr && addr < mm->mmap_base) {
9522 ++ start_addr = addr = mm->mmap_base;
9523 ++ mm->cached_hole_size = 0;
9524 ++ goto full_search;
9525 ++ }
9526 ++ }
9527 ++}
9528 ++
9529 ++unsigned long
9530 ++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
9531 ++ const unsigned long len, const unsigned long pgoff,
9532 ++ const unsigned long flags)
9533 ++{
9534 ++ struct vm_area_struct *vma;
9535 ++ struct mm_struct *mm = current->mm;
9536 ++ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
9537 ++
9538 ++#ifdef CONFIG_PAX_SEGMEXEC
9539 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9540 ++ task_size = SEGMEXEC_TASK_SIZE;
9541 ++#endif
9542 ++
9543 ++ /* requested length too big for entire address space */
9544 ++ if (len > task_size)
9545 ++ return -ENOMEM;
9546 ++
9547 ++ if (flags & MAP_FIXED)
9548 ++ return addr;
9549 ++
9550 ++#ifdef CONFIG_PAX_PAGEEXEC
9551 ++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
9552 ++ goto bottomup;
9553 ++#endif
9554 ++
9555 ++#ifdef CONFIG_PAX_RANDMMAP
9556 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9557 ++#endif
9558 ++
9559 ++ /* requesting a specific address */
9560 ++ if (addr) {
9561 ++ addr = PAGE_ALIGN(addr);
9562 ++ vma = find_vma(mm, addr);
9563 ++ if (task_size - len >= addr &&
9564 ++ (!vma || addr + len <= vma->vm_start))
9565 ++ return addr;
9566 ++ }
9567 ++
9568 ++ /* check if free_area_cache is useful for us */
9569 ++ if (len <= mm->cached_hole_size) {
9570 ++ mm->cached_hole_size = 0;
9571 ++ mm->free_area_cache = mm->mmap_base;
9572 ++ }
9573 ++
9574 ++ /* either no address requested or can't fit in requested address hole */
9575 ++ addr = mm->free_area_cache;
9576 ++
9577 ++ /* make sure it can fit in the remaining address space */
9578 ++ if (addr > len) {
9579 ++ vma = find_vma(mm, addr-len);
9580 ++ if (!vma || addr <= vma->vm_start)
9581 ++ /* remember the address as a hint for next time */
9582 ++ return (mm->free_area_cache = addr-len);
9583 ++ }
9584 ++
9585 ++ if (mm->mmap_base < len)
9586 ++ goto bottomup;
9587 ++
9588 ++ addr = mm->mmap_base-len;
9589 ++
9590 ++ do {
9591 ++ /*
9592 ++ * Lookup failure means no vma is above this address,
9593 ++ * else if new region fits below vma->vm_start,
9594 ++ * return with success:
9595 ++ */
9596 ++ vma = find_vma(mm, addr);
9597 ++ if (!vma || addr+len <= vma->vm_start)
9598 ++ /* remember the address as a hint for next time */
9599 ++ return (mm->free_area_cache = addr);
9600 ++
9601 ++ /* remember the largest hole we saw so far */
9602 ++ if (addr + mm->cached_hole_size < vma->vm_start)
9603 ++ mm->cached_hole_size = vma->vm_start - addr;
9604 ++
9605 ++ /* try just below the current vma->vm_start */
9606 ++ addr = vma->vm_start-len;
9607 ++ } while (len < vma->vm_start);
9608 ++
9609 ++bottomup:
9610 ++ /*
9611 ++ * A failed mmap() very likely causes application failure,
9612 ++ * so fall back to the bottom-up function here. This scenario
9613 ++ * can happen with large stack limits and large mmap()
9614 ++ * allocations.
9615 ++ */
9616 ++
9617 ++#ifdef CONFIG_PAX_SEGMEXEC
9618 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
9619 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
9620 ++ else
9621 ++#endif
9622 ++
9623 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
9624 ++
9625 ++#ifdef CONFIG_PAX_RANDMMAP
9626 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
9627 ++ mm->mmap_base += mm->delta_mmap;
9628 ++#endif
9629 ++
9630 ++ mm->free_area_cache = mm->mmap_base;
9631 ++ mm->cached_hole_size = ~0UL;
9632 ++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
9633 ++ /*
9634 ++ * Restore the topdown base:
9635 ++ */
9636 ++ mm->mmap_base = base;
9637 ++ mm->free_area_cache = base;
9638 ++ mm->cached_hole_size = ~0UL;
9639 ++
9640 ++ return addr;
9641 ++}
9642 +
9643 + struct sel_arg_struct {
9644 + unsigned long n;
9645 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/syscall_table.S linux-2.6.23.15-grsec/arch/i386/kernel/syscall_table.S
9646 +--- linux-2.6.23.15/arch/i386/kernel/syscall_table.S 2007-10-09 21:31:38.000000000 +0100
9647 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/syscall_table.S 2008-02-11 10:37:44.000000000 +0000
9648 +@@ -1,3 +1,4 @@
9649 ++.section .rodata,"a",@progbits
9650 + ENTRY(sys_call_table)
9651 + .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
9652 + .long sys_exit
9653 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/sysenter.c linux-2.6.23.15-grsec/arch/i386/kernel/sysenter.c
9654 +--- linux-2.6.23.15/arch/i386/kernel/sysenter.c 2007-10-09 21:31:38.000000000 +0100
9655 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/sysenter.c 2008-02-11 10:37:44.000000000 +0000
9656 +@@ -177,7 +177,7 @@ static __init void relocate_vdso(Elf32_E
9657 + void enable_sep_cpu(void)
9658 + {
9659 + int cpu = get_cpu();
9660 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
9661 ++ struct tss_struct *tss = init_tss + cpu;
9662 +
9663 + if (!boot_cpu_has(X86_FEATURE_SEP)) {
9664 + put_cpu();
9665 +@@ -200,7 +200,7 @@ static int __init gate_vma_init(void)
9666 + gate_vma.vm_start = FIXADDR_USER_START;
9667 + gate_vma.vm_end = FIXADDR_USER_END;
9668 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
9669 +- gate_vma.vm_page_prot = __P101;
9670 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
9671 + /*
9672 + * Make sure the vDSO gets into every core dump.
9673 + * Dumping its contents makes post-mortem fully interpretable later
9674 +@@ -283,7 +283,7 @@ int arch_setup_additional_pages(struct l
9675 + if (compat)
9676 + addr = VDSO_HIGH_BASE;
9677 + else {
9678 +- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
9679 ++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
9680 + if (IS_ERR_VALUE(addr)) {
9681 + ret = addr;
9682 + goto up_fail;
9683 +@@ -308,7 +308,7 @@ int arch_setup_additional_pages(struct l
9684 + goto up_fail;
9685 + }
9686 +
9687 +- current->mm->context.vdso = (void *)addr;
9688 ++ current->mm->context.vdso = addr;
9689 + current_thread_info()->sysenter_return =
9690 + (void *)VDSO_SYM(&SYSENTER_RETURN);
9691 +
9692 +@@ -320,8 +320,14 @@ int arch_setup_additional_pages(struct l
9693 +
9694 + const char *arch_vma_name(struct vm_area_struct *vma)
9695 + {
9696 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
9697 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
9698 + return "[vdso]";
9699 ++
9700 ++#ifdef CONFIG_PAX_SEGMEXEC
9701 ++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
9702 ++ return "[vdso]";
9703 ++#endif
9704 ++
9705 + return NULL;
9706 + }
9707 +
9708 +@@ -330,7 +336,7 @@ struct vm_area_struct *get_gate_vma(stru
9709 + struct mm_struct *mm = tsk->mm;
9710 +
9711 + /* Check to see if this task was created in compat vdso mode */
9712 +- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
9713 ++ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
9714 + return &gate_vma;
9715 + return NULL;
9716 + }
9717 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/time.c linux-2.6.23.15-grsec/arch/i386/kernel/time.c
9718 +--- linux-2.6.23.15/arch/i386/kernel/time.c 2007-10-09 21:31:38.000000000 +0100
9719 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/time.c 2008-02-11 10:37:44.000000000 +0000
9720 +@@ -132,20 +132,30 @@ unsigned long profile_pc(struct pt_regs
9721 + if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
9722 + in_lock_functions(pc)) {
9723 + #ifdef CONFIG_FRAME_POINTER
9724 +- return *(unsigned long *)(regs->ebp + 4);
9725 ++ return *(unsigned long *)(regs->ebp + 4) + __KERNEL_TEXT_OFFSET;
9726 + #else
9727 + unsigned long *sp = (unsigned long *)&regs->esp;
9728 +
9729 + /* Return address is either directly at stack pointer
9730 + or above a saved eflags. Eflags has bits 22-31 zero,
9731 + kernel addresses don't. */
9732 ++
9733 ++#ifdef CONFIG_PAX_KERNEXEC
9734 ++ return sp[0] + __KERNEL_TEXT_OFFSET;
9735 ++#else
9736 + if (sp[0] >> 22)
9737 + return sp[0];
9738 + if (sp[1] >> 22)
9739 + return sp[1];
9740 + #endif
9741 ++
9742 ++#endif
9743 + }
9744 + #endif
9745 ++
9746 ++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
9747 ++ pc += __KERNEL_TEXT_OFFSET;
9748 ++
9749 + return pc;
9750 + }
9751 + EXPORT_SYMBOL(profile_pc);
9752 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/traps.c linux-2.6.23.15-grsec/arch/i386/kernel/traps.c
9753 +--- linux-2.6.23.15/arch/i386/kernel/traps.c 2007-10-09 21:31:38.000000000 +0100
9754 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/traps.c 2008-02-11 10:37:44.000000000 +0000
9755 +@@ -31,6 +31,7 @@
9756 + #include <linux/uaccess.h>
9757 + #include <linux/nmi.h>
9758 + #include <linux/bug.h>
9759 ++#include <linux/binfmts.h>
9760 +
9761 + #ifdef CONFIG_EISA
9762 + #include <linux/ioport.h>
9763 +@@ -70,12 +71,7 @@ asmlinkage int system_call(void);
9764 + /* Do we ignore FPU interrupts ? */
9765 + char ignore_fpu_irq = 0;
9766 +
9767 +-/*
9768 +- * The IDT has to be page-aligned to simplify the Pentium
9769 +- * F0 0F bug workaround.. We have a special link segment
9770 +- * for this.
9771 +- */
9772 +-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
9773 ++extern struct desc_struct idt_table[256];
9774 +
9775 + asmlinkage void divide_error(void);
9776 + asmlinkage void debug(void);
9777 +@@ -297,7 +293,7 @@ void show_registers(struct pt_regs *regs
9778 + esp = (unsigned long) (&regs->esp);
9779 + savesegment(ss, ss);
9780 + savesegment(gs, gs);
9781 +- if (user_mode_vm(regs)) {
9782 ++ if (user_mode(regs)) {
9783 + in_kernel = 0;
9784 + esp = regs->esp;
9785 + ss = regs->xss & 0xffff;
9786 +@@ -329,17 +325,18 @@ void show_registers(struct pt_regs *regs
9787 + unsigned int code_prologue = code_bytes * 43 / 64;
9788 + unsigned int code_len = code_bytes;
9789 + unsigned char c;
9790 ++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
9791 +
9792 + printk("\n" KERN_EMERG "Stack: ");
9793 + show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
9794 +
9795 + printk(KERN_EMERG "Code: ");
9796 +
9797 +- eip = (u8 *)regs->eip - code_prologue;
9798 ++ eip = (u8 *)regs->eip - code_prologue + cs_base;
9799 + if (eip < (u8 *)PAGE_OFFSET ||
9800 + probe_kernel_address(eip, c)) {
9801 + /* try starting at EIP */
9802 +- eip = (u8 *)regs->eip;
9803 ++ eip = (u8 *)regs->eip + cs_base;
9804 + code_len = code_len - code_prologue + 1;
9805 + }
9806 + for (i = 0; i < code_len; i++, eip++) {
9807 +@@ -348,7 +345,7 @@ void show_registers(struct pt_regs *regs
9808 + printk(" Bad EIP value.");
9809 + break;
9810 + }
9811 +- if (eip == (u8 *)regs->eip)
9812 ++ if (eip == (u8 *)regs->eip + cs_base)
9813 + printk("<%02x> ", c);
9814 + else
9815 + printk("%02x ", c);
9816 +@@ -361,6 +358,7 @@ int is_valid_bugaddr(unsigned long eip)
9817 + {
9818 + unsigned short ud2;
9819 +
9820 ++ eip += __KERNEL_TEXT_OFFSET;
9821 + if (eip < PAGE_OFFSET)
9822 + return 0;
9823 + if (probe_kernel_address((unsigned short *)eip, ud2))
9824 +@@ -468,7 +466,7 @@ void die(const char * str, struct pt_reg
9825 +
9826 + static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
9827 + {
9828 +- if (!user_mode_vm(regs))
9829 ++ if (!user_mode(regs))
9830 + die(str, regs, err);
9831 + }
9832 +
9833 +@@ -484,7 +482,7 @@ static void __kprobes do_trap(int trapnr
9834 + goto trap_signal;
9835 + }
9836 +
9837 +- if (!user_mode(regs))
9838 ++ if (!user_mode_novm(regs))
9839 + goto kernel_trap;
9840 +
9841 + trap_signal: {
9842 +@@ -589,7 +587,7 @@ fastcall void __kprobes do_general_prote
9843 + long error_code)
9844 + {
9845 + int cpu = get_cpu();
9846 +- struct tss_struct *tss = &per_cpu(init_tss, cpu);
9847 ++ struct tss_struct *tss = &init_tss[cpu];
9848 + struct thread_struct *thread = &current->thread;
9849 +
9850 + /*
9851 +@@ -622,9 +620,25 @@ fastcall void __kprobes do_general_prote
9852 + if (regs->eflags & VM_MASK)
9853 + goto gp_in_vm86;
9854 +
9855 +- if (!user_mode(regs))
9856 ++ if (!user_mode_novm(regs))
9857 + goto gp_in_kernel;
9858 +
9859 ++#ifdef CONFIG_PAX_PAGEEXEC
9860 ++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
9861 ++ struct mm_struct *mm = current->mm;
9862 ++ unsigned long limit;
9863 ++
9864 ++ down_write(&mm->mmap_sem);
9865 ++ limit = mm->context.user_cs_limit;
9866 ++ if (limit < TASK_SIZE) {
9867 ++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
9868 ++ up_write(&mm->mmap_sem);
9869 ++ return;
9870 ++ }
9871 ++ up_write(&mm->mmap_sem);
9872 ++ }
9873 ++#endif
9874 ++
9875 + current->thread.error_code = error_code;
9876 + current->thread.trap_no = 13;
9877 + if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
9878 +@@ -649,6 +663,13 @@ gp_in_kernel:
9879 + if (notify_die(DIE_GPF, "general protection fault", regs,
9880 + error_code, 13, SIGSEGV) == NOTIFY_STOP)
9881 + return;
9882 ++
9883 ++#ifdef CONFIG_PAX_KERNEXEC
9884 ++ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
9885 ++ die("PAX: suspicious general protection fault", regs, error_code);
9886 ++ else
9887 ++#endif
9888 ++
9889 + die("general protection fault", regs, error_code);
9890 + }
9891 + }
9892 +@@ -738,7 +759,7 @@ void __kprobes die_nmi(struct pt_regs *r
9893 + /* If we are in kernel we are probably nested up pretty bad
9894 + * and might aswell get out now while we still can.
9895 + */
9896 +- if (!user_mode_vm(regs)) {
9897 ++ if (!user_mode(regs)) {
9898 + current->thread.trap_no = 2;
9899 + crash_kexec(regs);
9900 + }
9901 +@@ -885,7 +906,7 @@ fastcall void __kprobes do_debug(struct
9902 + * check for kernel mode by just checking the CPL
9903 + * of CS.
9904 + */
9905 +- if (!user_mode(regs))
9906 ++ if (!user_mode_novm(regs))
9907 + goto clear_TF_reenable;
9908 + }
9909 +
9910 +@@ -1063,18 +1084,14 @@ fastcall void do_spurious_interrupt_bug(
9911 + fastcall unsigned long patch_espfix_desc(unsigned long uesp,
9912 + unsigned long kesp)
9913 + {
9914 +- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
9915 + unsigned long base = (kesp - uesp) & -THREAD_SIZE;
9916 + unsigned long new_kesp = kesp - base;
9917 + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
9918 +- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
9919 ++ __u32 a, b;
9920 ++
9921 + /* Set up base for espfix segment */
9922 +- desc &= 0x00f0ff0000000000ULL;
9923 +- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
9924 +- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
9925 +- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
9926 +- (lim_pages & 0xffff);
9927 +- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
9928 ++ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
9929 ++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
9930 + return new_kesp;
9931 + }
9932 +
9933 +@@ -1123,7 +1140,7 @@ void __init trap_init_f00f_bug(void)
9934 + * Update the IDT descriptor and reload the IDT so that
9935 + * it uses the read-only mapped virtual address.
9936 + */
9937 +- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
9938 ++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
9939 + load_idt(&idt_descr);
9940 + }
9941 + #endif
9942 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/tsc.c linux-2.6.23.15-grsec/arch/i386/kernel/tsc.c
9943 +--- linux-2.6.23.15/arch/i386/kernel/tsc.c 2008-02-11 10:36:03.000000000 +0000
9944 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/tsc.c 2008-02-11 10:37:44.000000000 +0000
9945 +@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b
9946 + DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
9947 + },
9948 + },
9949 +- {}
9950 ++ { NULL, NULL, {{0, NULL}}, NULL}
9951 + };
9952 +
9953 + /*
9954 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/vm86.c linux-2.6.23.15-grsec/arch/i386/kernel/vm86.c
9955 +--- linux-2.6.23.15/arch/i386/kernel/vm86.c 2007-10-09 21:31:38.000000000 +0100
9956 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/vm86.c 2008-02-11 10:37:44.000000000 +0000
9957 +@@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state
9958 + do_exit(SIGSEGV);
9959 + }
9960 +
9961 +- tss = &per_cpu(init_tss, get_cpu());
9962 ++ tss = init_tss + get_cpu();
9963 + current->thread.esp0 = current->thread.saved_esp0;
9964 + current->thread.sysenter_cs = __KERNEL_CS;
9965 + load_esp0(tss, &current->thread);
9966 +@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
9967 + tsk->thread.saved_fs = info->regs32->xfs;
9968 + savesegment(gs, tsk->thread.saved_gs);
9969 +
9970 +- tss = &per_cpu(init_tss, get_cpu());
9971 ++ tss = init_tss + get_cpu();
9972 + tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
9973 + if (cpu_has_sep)
9974 + tsk->thread.sysenter_cs = 0;
9975 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/vmi.c linux-2.6.23.15-grsec/arch/i386/kernel/vmi.c
9976 +--- linux-2.6.23.15/arch/i386/kernel/vmi.c 2007-10-09 21:31:38.000000000 +0100
9977 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/vmi.c 2008-02-11 10:37:44.000000000 +0000
9978 +@@ -98,18 +98,43 @@ static unsigned patch_internal(int call,
9979 + {
9980 + u64 reloc;
9981 + struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
9982 ++
9983 ++#ifdef CONFIG_PAX_KERNEXEC
9984 ++ unsigned long cr0;
9985 ++#endif
9986 ++
9987 + reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
9988 + switch(rel->type) {
9989 + case VMI_RELOCATION_CALL_REL:
9990 + BUG_ON(len < 5);
9991 ++
9992 ++#ifdef CONFIG_PAX_KERNEXEC
9993 ++ pax_open_kernel(cr0);
9994 ++#endif
9995 ++
9996 + *(char *)insnbuf = MNEM_CALL;
9997 + patch_offset(insnbuf, eip, (unsigned long)rel->eip);
9998 ++
9999 ++#ifdef CONFIG_PAX_KERNEXEC
10000 ++ pax_close_kernel(cr0);
10001 ++#endif
10002 ++
10003 + return 5;
10004 +
10005 + case VMI_RELOCATION_JUMP_REL:
10006 + BUG_ON(len < 5);
10007 ++
10008 ++#ifdef CONFIG_PAX_KERNEXEC
10009 ++ pax_open_kernel(cr0);
10010 ++#endif
10011 ++
10012 + *(char *)insnbuf = MNEM_JMP;
10013 + patch_offset(insnbuf, eip, (unsigned long)rel->eip);
10014 ++
10015 ++#ifdef CONFIG_PAX_KERNEXEC
10016 ++ pax_close_kernel(cr0);
10017 ++#endif
10018 ++
10019 + return 5;
10020 +
10021 + case VMI_RELOCATION_NOP:
10022 +@@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud
10023 +
10024 + static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
10025 + {
10026 +- const pte_t pte = { 0 };
10027 ++ const pte_t pte = __pte(0ULL);
10028 + vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
10029 + vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
10030 + }
10031 +
10032 + static void vmi_pmd_clear(pmd_t *pmd)
10033 + {
10034 +- const pte_t pte = { 0 };
10035 ++ const pte_t pte = __pte(0ULL);
10036 + vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
10037 + vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
10038 + }
10039 +@@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
10040 + ap.ss = __KERNEL_DS;
10041 + ap.esp = (unsigned long) start_esp;
10042 +
10043 +- ap.ds = __USER_DS;
10044 +- ap.es = __USER_DS;
10045 ++ ap.ds = __KERNEL_DS;
10046 ++ ap.es = __KERNEL_DS;
10047 + ap.fs = __KERNEL_PERCPU;
10048 + ap.gs = 0;
10049 +
10050 +@@ -726,12 +751,20 @@ static inline int __init activate_vmi(vo
10051 + u64 reloc;
10052 + const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
10053 +
10054 ++#ifdef CONFIG_PAX_KERNEXEC
10055 ++ unsigned long cr0;
10056 ++#endif
10057 ++
10058 + if (call_vrom_func(vmi_rom, vmi_init) != 0) {
10059 + printk(KERN_ERR "VMI ROM failed to initialize!");
10060 + return 0;
10061 + }
10062 + savesegment(cs, kernel_cs);
10063 +
10064 ++#ifdef CONFIG_PAX_KERNEXEC
10065 ++ pax_open_kernel(cr0);
10066 ++#endif
10067 ++
10068 + paravirt_ops.paravirt_enabled = 1;
10069 + paravirt_ops.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
10070 +
10071 +@@ -910,6 +943,10 @@ static inline int __init activate_vmi(vo
10072 +
10073 + para_fill(safe_halt, Halt);
10074 +
10075 ++#ifdef CONFIG_PAX_KERNEXEC
10076 ++ pax_close_kernel(cr0);
10077 ++#endif
10078 ++
10079 + /*
10080 + * Alternative instruction rewriting doesn't happen soon enough
10081 + * to convert VMI_IRET to a call instead of a jump; so we have
10082 +diff -Nurp linux-2.6.23.15/arch/i386/kernel/vmlinux.lds.S linux-2.6.23.15-grsec/arch/i386/kernel/vmlinux.lds.S
10083 +--- linux-2.6.23.15/arch/i386/kernel/vmlinux.lds.S 2007-10-09 21:31:38.000000000 +0100
10084 ++++ linux-2.6.23.15-grsec/arch/i386/kernel/vmlinux.lds.S 2008-02-11 10:37:44.000000000 +0000
10085 +@@ -21,6 +21,13 @@
10086 + #include <asm/page.h>
10087 + #include <asm/cache.h>
10088 + #include <asm/boot.h>
10089 ++#include <asm/segment.h>
10090 ++
10091 ++#ifdef CONFIG_X86_PAE
10092 ++#define PMD_SHIFT 21
10093 ++#else
10094 ++#define PMD_SHIFT 22
10095 ++#endif
10096 +
10097 + OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
10098 + OUTPUT_ARCH(i386)
10099 +@@ -28,22 +35,124 @@ ENTRY(phys_startup_32)
10100 + jiffies = jiffies_64;
10101 +
10102 + PHDRS {
10103 +- text PT_LOAD FLAGS(5); /* R_E */
10104 +- data PT_LOAD FLAGS(7); /* RWE */
10105 +- note PT_NOTE FLAGS(0); /* ___ */
10106 ++ initdata PT_LOAD FLAGS(6); /* RW_ */
10107 ++ percpu PT_LOAD FLAGS(6); /* RW_ */
10108 ++ inittext PT_LOAD FLAGS(5); /* R_E */
10109 ++ text PT_LOAD FLAGS(5); /* R_E */
10110 ++ rodata PT_LOAD FLAGS(4); /* R__ */
10111 ++ data PT_LOAD FLAGS(6); /* RW_ */
10112 ++ note PT_NOTE FLAGS(0); /* ___ */
10113 + }
10114 + SECTIONS
10115 + {
10116 + . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
10117 +- phys_startup_32 = startup_32 - LOAD_OFFSET;
10118 +
10119 +- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
10120 +- _text = .; /* Text and read-only data */
10121 ++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
10122 ++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
10123 ++ *(.text.startup)
10124 ++ } :initdata
10125 ++
10126 ++ /* might get freed after init */
10127 ++ . = ALIGN(4096);
10128 ++ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
10129 ++ __smp_locks = .;
10130 ++ *(.smp_locks)
10131 ++ __smp_locks_end = .;
10132 ++ }
10133 ++ /* will be freed after init
10134 ++ * Following ALIGN() is required to make sure no other data falls on the
10135 ++ * same page where __smp_alt_end is pointing as that page might be freed
10136 ++ * after boot. Always make sure that ALIGN() directive is present after
10137 ++ * the section which contains __smp_alt_end.
10138 ++ */
10139 ++ . = ALIGN(4096);
10140 ++
10141 ++ /* will be freed after init */
10142 ++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
10143 ++ __init_begin = .;
10144 ++ *(.init.data)
10145 ++ }
10146 ++ . = ALIGN(16);
10147 ++ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
10148 ++ __setup_start = .;
10149 ++ *(.init.setup)
10150 ++ __setup_end = .;
10151 ++ }
10152 ++ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
10153 ++ __initcall_start = .;
10154 ++ INITCALLS
10155 ++ __initcall_end = .;
10156 ++ }
10157 ++ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
10158 ++ __con_initcall_start = .;
10159 ++ *(.con_initcall.init)
10160 ++ __con_initcall_end = .;
10161 ++ }
10162 ++ SECURITY_INIT
10163 ++ . = ALIGN(4);
10164 ++ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
10165 ++ __alt_instructions = .;
10166 ++ *(.altinstructions)
10167 ++ __alt_instructions_end = .;
10168 ++ }
10169 ++ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
10170 ++ *(.altinstr_replacement)
10171 ++ }
10172 ++ . = ALIGN(4);
10173 ++ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
10174 ++ __parainstructions = .;
10175 ++ *(.parainstructions)
10176 ++ __parainstructions_end = .;
10177 ++ }
10178 ++ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
10179 ++#if defined(CONFIG_BLK_DEV_INITRD)
10180 ++ . = ALIGN(4096);
10181 ++ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
10182 ++ __initramfs_start = .;
10183 ++ *(.init.ramfs)
10184 ++ __initramfs_end = .;
10185 ++ }
10186 ++#endif
10187 ++ . = ALIGN(4096);
10188 ++ per_cpu_start = .;
10189 ++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
10190 ++ __per_cpu_start = . + per_cpu_start;
10191 ++ LONG(0)
10192 ++ *(.data.percpu)
10193 ++ *(.data.percpu.shared_aligned)
10194 ++ __per_cpu_end = . + per_cpu_start;
10195 ++ } :percpu
10196 ++ . += per_cpu_start;
10197 ++
10198 ++ /* read-only */
10199 ++
10200 ++ . = ALIGN(4096); /* Init code and data */
10201 ++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10202 ++ _sinittext = .;
10203 ++ *(.init.text)
10204 ++ _einittext = .;
10205 ++ } :inittext
10206 ++
10207 ++ /* .exit.text is discard at runtime, not link time, to deal with references
10208 ++ from .altinstructions and .eh_frame */
10209 ++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
10210 ++
10211 ++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10212 ++ BYTE(0)
10213 ++ . = ALIGN(4*1024*1024) - 1;
10214 ++ }
10215 ++
10216 ++ /* freed after init ends here */
10217 ++
10218 ++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10219 ++ __init_end = . + __KERNEL_TEXT_OFFSET;
10220 ++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
10221 ++ _text = .; /* Text and read-only data */
10222 + *(.text.head)
10223 + } :text = 0x9090
10224 +
10225 + /* read-only */
10226 +- .text : AT(ADDR(.text) - LOAD_OFFSET) {
10227 ++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
10228 + TEXT_TEXT
10229 + SCHED_TEXT
10230 + LOCK_TEXT
10231 +@@ -53,16 +162,17 @@ SECTIONS
10232 + _etext = .; /* End of text section */
10233 + } :text = 0x9090
10234 +
10235 +- . = ALIGN(16); /* Exception table */
10236 ++ . += __KERNEL_TEXT_OFFSET;
10237 ++ . = ALIGN(4096); /* Exception table */
10238 + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
10239 + __start___ex_table = .;
10240 + *(__ex_table)
10241 + __stop___ex_table = .;
10242 +- }
10243 ++ } :rodata
10244 +
10245 +- NOTES :text :note
10246 ++ NOTES :rodata :note
10247 +
10248 +- BUG_TABLE :text
10249 ++ BUG_TABLE :rodata
10250 +
10251 + . = ALIGN(4);
10252 + .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
10253 +@@ -73,9 +183,36 @@ SECTIONS
10254 +
10255 + RODATA
10256 +
10257 ++ . = ALIGN(4096);
10258 ++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
10259 ++ *(.idt)
10260 ++ . = ALIGN(4096);
10261 ++ *(.empty_zero_page)
10262 ++ *(.swapper_pm_dir)
10263 ++ *(.swapper_pg_dir)
10264 ++ }
10265 ++
10266 ++#ifdef CONFIG_PAX_KERNEXEC
10267 ++
10268 ++#ifdef CONFIG_MODULES
10269 ++ . = ALIGN(4096);
10270 ++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
10271 ++ MODULES_VADDR = .;
10272 ++ BYTE(0)
10273 ++ . += (6 * 1024 * 1024);
10274 ++ . = ALIGN(1 << PMD_SHIFT) - 1;
10275 ++ MODULES_END = .;
10276 ++ }
10277 ++#else
10278 ++ . = ALIGN(1 << PMD_SHIFT) - 1;
10279 ++#endif
10280 ++
10281 ++#endif
10282 ++
10283 + /* writeable */
10284 + . = ALIGN(4096);
10285 + .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
10286 ++ _data = .;
10287 + DATA_DATA
10288 + CONSTRUCTORS
10289 + } :data
10290 +@@ -91,7 +228,6 @@ SECTIONS
10291 + . = ALIGN(4096);
10292 + .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
10293 + *(.data.page_aligned)
10294 +- *(.data.idt)
10295 + }
10296 +
10297 + . = ALIGN(32);
10298 +@@ -111,86 +247,7 @@ SECTIONS
10299 + *(.data.init_task)
10300 + }
10301 +
10302 +- /* might get freed after init */
10303 +- . = ALIGN(4096);
10304 +- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
10305 +- __smp_locks = .;
10306 +- *(.smp_locks)
10307 +- __smp_locks_end = .;
10308 +- }
10309 +- /* will be freed after init
10310 +- * Following ALIGN() is required to make sure no other data falls on the
10311 +- * same page where __smp_alt_end is pointing as that page might be freed
10312 +- * after boot. Always make sure that ALIGN() directive is present after
10313 +- * the section which contains __smp_alt_end.
10314 +- */
10315 +- . = ALIGN(4096);
10316 +-
10317 +- /* will be freed after init */
10318 +- . = ALIGN(4096); /* Init code and data */
10319 +- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
10320 +- __init_begin = .;
10321 +- _sinittext = .;
10322 +- *(.init.text)
10323 +- _einittext = .;
10324 +- }
10325 +- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
10326 +- . = ALIGN(16);
10327 +- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
10328 +- __setup_start = .;
10329 +- *(.init.setup)
10330 +- __setup_end = .;
10331 +- }
10332 +- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
10333 +- __initcall_start = .;
10334 +- INITCALLS
10335 +- __initcall_end = .;
10336 +- }
10337 +- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
10338 +- __con_initcall_start = .;
10339 +- *(.con_initcall.init)
10340 +- __con_initcall_end = .;
10341 +- }
10342 +- SECURITY_INIT
10343 +- . = ALIGN(4);
10344 +- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
10345 +- __alt_instructions = .;
10346 +- *(.altinstructions)
10347 +- __alt_instructions_end = .;
10348 +- }
10349 +- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
10350 +- *(.altinstr_replacement)
10351 +- }
10352 +- . = ALIGN(4);
10353 +- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
10354 +- __parainstructions = .;
10355 +- *(.parainstructions)
10356 +- __parainstructions_end = .;
10357 +- }
10358 +- /* .exit.text is discard at runtime, not link time, to deal with references
10359 +- from .altinstructions and .eh_frame */
10360 +- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
10361 +- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
10362 +-#if defined(CONFIG_BLK_DEV_INITRD)
10363 +- . = ALIGN(4096);
10364 +- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
10365 +- __initramfs_start = .;
10366 +- *(.init.ramfs)
10367 +- __initramfs_end = .;
10368 +- }
10369 +-#endif
10370 +- . = ALIGN(4096);
10371 +- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
10372 +- __per_cpu_start = .;
10373 +- *(.data.percpu)
10374 +- *(.data.percpu.shared_aligned)
10375 +- __per_cpu_end = .;
10376 +- }
10377 +- . = ALIGN(4096);
10378 +- /* freed after init ends here */
10379 +-
10380 + .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
10381 +- __init_end = .;
10382 + __bss_start = .; /* BSS */
10383 + *(.bss.page_aligned)
10384 + *(.bss)
10385 +diff -Nurp linux-2.6.23.15/arch/i386/lib/checksum.S linux-2.6.23.15-grsec/arch/i386/lib/checksum.S
10386 +--- linux-2.6.23.15/arch/i386/lib/checksum.S 2007-10-09 21:31:38.000000000 +0100
10387 ++++ linux-2.6.23.15-grsec/arch/i386/lib/checksum.S 2008-02-11 10:37:44.000000000 +0000
10388 +@@ -28,7 +28,8 @@
10389 + #include <linux/linkage.h>
10390 + #include <asm/dwarf2.h>
10391 + #include <asm/errno.h>
10392 +-
10393 ++#include <asm/segment.h>
10394 ++
10395 + /*
10396 + * computes a partial checksum, e.g. for TCP/UDP fragments
10397 + */
10398 +@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
10399 +
10400 + #define ARGBASE 16
10401 + #define FP 12
10402 +-
10403 +-ENTRY(csum_partial_copy_generic)
10404 ++
10405 ++ENTRY(csum_partial_copy_generic_to_user)
10406 + CFI_STARTPROC
10407 ++ pushl $(__USER_DS)
10408 ++ CFI_ADJUST_CFA_OFFSET 4
10409 ++ popl %es
10410 ++ CFI_ADJUST_CFA_OFFSET -4
10411 ++ jmp csum_partial_copy_generic
10412 ++
10413 ++ENTRY(csum_partial_copy_generic_from_user)
10414 ++ pushl $(__USER_DS)
10415 ++ CFI_ADJUST_CFA_OFFSET 4
10416 ++ popl %ds
10417 ++ CFI_ADJUST_CFA_OFFSET -4
10418 ++
10419 ++ENTRY(csum_partial_copy_generic)
10420 + subl $4,%esp
10421 + CFI_ADJUST_CFA_OFFSET 4
10422 + pushl %edi
10423 +@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
10424 + jmp 4f
10425 + SRC(1: movw (%esi), %bx )
10426 + addl $2, %esi
10427 +-DST( movw %bx, (%edi) )
10428 ++DST( movw %bx, %es:(%edi) )
10429 + addl $2, %edi
10430 + addw %bx, %ax
10431 + adcl $0, %eax
10432 +@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
10433 + SRC(1: movl (%esi), %ebx )
10434 + SRC( movl 4(%esi), %edx )
10435 + adcl %ebx, %eax
10436 +-DST( movl %ebx, (%edi) )
10437 ++DST( movl %ebx, %es:(%edi) )
10438 + adcl %edx, %eax
10439 +-DST( movl %edx, 4(%edi) )
10440 ++DST( movl %edx, %es:4(%edi) )
10441 +
10442 + SRC( movl 8(%esi), %ebx )
10443 + SRC( movl 12(%esi), %edx )
10444 + adcl %ebx, %eax
10445 +-DST( movl %ebx, 8(%edi) )
10446 ++DST( movl %ebx, %es:8(%edi) )
10447 + adcl %edx, %eax
10448 +-DST( movl %edx, 12(%edi) )
10449 ++DST( movl %edx, %es:12(%edi) )
10450 +
10451 + SRC( movl 16(%esi), %ebx )
10452 + SRC( movl 20(%esi), %edx )
10453 + adcl %ebx, %eax
10454 +-DST( movl %ebx, 16(%edi) )
10455 ++DST( movl %ebx, %es:16(%edi) )
10456 + adcl %edx, %eax
10457 +-DST( movl %edx, 20(%edi) )
10458 ++DST( movl %edx, %es:20(%edi) )
10459 +
10460 + SRC( movl 24(%esi), %ebx )
10461 + SRC( movl 28(%esi), %edx )
10462 + adcl %ebx, %eax
10463 +-DST( movl %ebx, 24(%edi) )
10464 ++DST( movl %ebx, %es:24(%edi) )
10465 + adcl %edx, %eax
10466 +-DST( movl %edx, 28(%edi) )
10467 ++DST( movl %edx, %es:28(%edi) )
10468 +
10469 + lea 32(%esi), %esi
10470 + lea 32(%edi), %edi
10471 +@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
10472 + shrl $2, %edx # This clears CF
10473 + SRC(3: movl (%esi), %ebx )
10474 + adcl %ebx, %eax
10475 +-DST( movl %ebx, (%edi) )
10476 ++DST( movl %ebx, %es:(%edi) )
10477 + lea 4(%esi), %esi
10478 + lea 4(%edi), %edi
10479 + dec %edx
10480 +@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
10481 + jb 5f
10482 + SRC( movw (%esi), %cx )
10483 + leal 2(%esi), %esi
10484 +-DST( movw %cx, (%edi) )
10485 ++DST( movw %cx, %es:(%edi) )
10486 + leal 2(%edi), %edi
10487 + je 6f
10488 + shll $16,%ecx
10489 + SRC(5: movb (%esi), %cl )
10490 +-DST( movb %cl, (%edi) )
10491 ++DST( movb %cl, %es:(%edi) )
10492 + 6: addl %ecx, %eax
10493 + adcl $0, %eax
10494 + 7:
10495 +@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
10496 +
10497 + 6001:
10498 + movl ARGBASE+20(%esp), %ebx # src_err_ptr
10499 +- movl $-EFAULT, (%ebx)
10500 ++ movl $-EFAULT, %ss:(%ebx)
10501 +
10502 + # zero the complete destination - computing the rest
10503 + # is too much work
10504 +@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
10505 +
10506 + 6002:
10507 + movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10508 +- movl $-EFAULT,(%ebx)
10509 ++ movl $-EFAULT,%ss:(%ebx)
10510 + jmp 5000b
10511 +
10512 + .previous
10513 +
10514 ++ pushl %ss
10515 ++ CFI_ADJUST_CFA_OFFSET 4
10516 ++ popl %ds
10517 ++ CFI_ADJUST_CFA_OFFSET -4
10518 ++ pushl %ss
10519 ++ CFI_ADJUST_CFA_OFFSET 4
10520 ++ popl %es
10521 ++ CFI_ADJUST_CFA_OFFSET -4
10522 + popl %ebx
10523 + CFI_ADJUST_CFA_OFFSET -4
10524 + CFI_RESTORE ebx
10525 +@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
10526 + CFI_ADJUST_CFA_OFFSET -4
10527 + ret
10528 + CFI_ENDPROC
10529 +-ENDPROC(csum_partial_copy_generic)
10530 ++ENDPROC(csum_partial_copy_generic_to_user)
10531 +
10532 + #else
10533 +
10534 + /* Version for PentiumII/PPro */
10535 +
10536 + #define ROUND1(x) \
10537 ++ nop; nop; nop; \
10538 + SRC(movl x(%esi), %ebx ) ; \
10539 + addl %ebx, %eax ; \
10540 +- DST(movl %ebx, x(%edi) ) ;
10541 ++ DST(movl %ebx, %es:x(%edi)) ;
10542 +
10543 + #define ROUND(x) \
10544 ++ nop; nop; nop; \
10545 + SRC(movl x(%esi), %ebx ) ; \
10546 + adcl %ebx, %eax ; \
10547 +- DST(movl %ebx, x(%edi) ) ;
10548 ++ DST(movl %ebx, %es:x(%edi)) ;
10549 +
10550 + #define ARGBASE 12
10551 +-
10552 +-ENTRY(csum_partial_copy_generic)
10553 ++
10554 ++ENTRY(csum_partial_copy_generic_to_user)
10555 + CFI_STARTPROC
10556 ++ pushl $(__USER_DS)
10557 ++ CFI_ADJUST_CFA_OFFSET 4
10558 ++ popl %es
10559 ++ CFI_ADJUST_CFA_OFFSET -4
10560 ++ jmp csum_partial_copy_generic
10561 ++
10562 ++ENTRY(csum_partial_copy_generic_from_user)
10563 ++ pushl $(__USER_DS)
10564 ++ CFI_ADJUST_CFA_OFFSET 4
10565 ++ popl %ds
10566 ++ CFI_ADJUST_CFA_OFFSET -4
10567 ++
10568 ++ENTRY(csum_partial_copy_generic)
10569 + pushl %ebx
10570 + CFI_ADJUST_CFA_OFFSET 4
10571 + CFI_REL_OFFSET ebx, 0
10572 +@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
10573 + subl %ebx, %edi
10574 + lea -1(%esi),%edx
10575 + andl $-32,%edx
10576 +- lea 3f(%ebx,%ebx), %ebx
10577 ++ lea 3f(%ebx,%ebx,2), %ebx
10578 + testl %esi, %esi
10579 + jmp *%ebx
10580 + 1: addl $64,%esi
10581 +@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
10582 + jb 5f
10583 + SRC( movw (%esi), %dx )
10584 + leal 2(%esi), %esi
10585 +-DST( movw %dx, (%edi) )
10586 ++DST( movw %dx, %es:(%edi) )
10587 + leal 2(%edi), %edi
10588 + je 6f
10589 + shll $16,%edx
10590 + 5:
10591 + SRC( movb (%esi), %dl )
10592 +-DST( movb %dl, (%edi) )
10593 ++DST( movb %dl, %es:(%edi) )
10594 + 6: addl %edx, %eax
10595 + adcl $0, %eax
10596 + 7:
10597 + .section .fixup, "ax"
10598 + 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
10599 +- movl $-EFAULT, (%ebx)
10600 ++ movl $-EFAULT, %ss:(%ebx)
10601 + # zero the complete destination (computing the rest is too much work)
10602 + movl ARGBASE+8(%esp),%edi # dst
10603 + movl ARGBASE+12(%esp),%ecx # len
10604 +@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
10605 + rep; stosb
10606 + jmp 7b
10607 + 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
10608 +- movl $-EFAULT, (%ebx)
10609 ++ movl $-EFAULT, %ss:(%ebx)
10610 + jmp 7b
10611 + .previous
10612 +
10613 ++ pushl %ss
10614 ++ CFI_ADJUST_CFA_OFFSET 4
10615 ++ popl %ds
10616 ++ CFI_ADJUST_CFA_OFFSET -4
10617 ++ pushl %ss
10618 ++ CFI_ADJUST_CFA_OFFSET 4
10619 ++ popl %es
10620 ++ CFI_ADJUST_CFA_OFFSET -4
10621 + popl %esi
10622 + CFI_ADJUST_CFA_OFFSET -4
10623 + CFI_RESTORE esi
10624 +@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
10625 + CFI_RESTORE ebx
10626 + ret
10627 + CFI_ENDPROC
10628 +-ENDPROC(csum_partial_copy_generic)
10629 ++ENDPROC(csum_partial_copy_generic_to_user)
10630 +
10631 + #undef ROUND
10632 + #undef ROUND1
10633 +diff -Nurp linux-2.6.23.15/arch/i386/lib/getuser.S linux-2.6.23.15-grsec/arch/i386/lib/getuser.S
10634 +--- linux-2.6.23.15/arch/i386/lib/getuser.S 2007-10-09 21:31:38.000000000 +0100
10635 ++++ linux-2.6.23.15-grsec/arch/i386/lib/getuser.S 2008-02-11 10:37:44.000000000 +0000
10636 +@@ -11,7 +11,7 @@
10637 + #include <linux/linkage.h>
10638 + #include <asm/dwarf2.h>
10639 + #include <asm/thread_info.h>
10640 +-
10641 ++#include <asm/segment.h>
10642 +
10643 + /*
10644 + * __get_user_X
10645 +@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
10646 + GET_THREAD_INFO(%edx)
10647 + cmpl TI_addr_limit(%edx),%eax
10648 + jae bad_get_user
10649 ++ pushl $(__USER_DS)
10650 ++ popl %ds
10651 + 1: movzbl (%eax),%edx
10652 ++ pushl %ss
10653 ++ pop %ds
10654 + xorl %eax,%eax
10655 + ret
10656 + CFI_ENDPROC
10657 +@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
10658 + GET_THREAD_INFO(%edx)
10659 + cmpl TI_addr_limit(%edx),%eax
10660 + jae bad_get_user
10661 ++ pushl $(__USER_DS)
10662 ++ popl %ds
10663 + 2: movzwl -1(%eax),%edx
10664 ++ pushl %ss
10665 ++ pop %ds
10666 + xorl %eax,%eax
10667 + ret
10668 + CFI_ENDPROC
10669 +@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
10670 + GET_THREAD_INFO(%edx)
10671 + cmpl TI_addr_limit(%edx),%eax
10672 + jae bad_get_user
10673 ++ pushl $(__USER_DS)
10674 ++ popl %ds
10675 + 3: movl -3(%eax),%edx
10676 ++ pushl %ss
10677 ++ pop %ds
10678 + xorl %eax,%eax
10679 + ret
10680 + CFI_ENDPROC
10681 +@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
10682 +
10683 + bad_get_user:
10684 + CFI_STARTPROC
10685 ++ pushl %ss
10686 ++ pop %ds
10687 + xorl %edx,%edx
10688 + movl $-14,%eax
10689 + ret
10690 +diff -Nurp linux-2.6.23.15/arch/i386/lib/mmx.c linux-2.6.23.15-grsec/arch/i386/lib/mmx.c
10691 +--- linux-2.6.23.15/arch/i386/lib/mmx.c 2007-10-09 21:31:38.000000000 +0100
10692 ++++ linux-2.6.23.15-grsec/arch/i386/lib/mmx.c 2008-02-11 10:37:44.000000000 +0000
10693 +@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
10694 + {
10695 + void *p;
10696 + int i;
10697 ++ unsigned long cr0;
10698 +
10699 + if (unlikely(in_interrupt()))
10700 + return __memcpy(to, from, len);
10701 +@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
10702 + kernel_fpu_begin();
10703 +
10704 + __asm__ __volatile__ (
10705 +- "1: prefetch (%0)\n" /* This set is 28 bytes */
10706 +- " prefetch 64(%0)\n"
10707 +- " prefetch 128(%0)\n"
10708 +- " prefetch 192(%0)\n"
10709 +- " prefetch 256(%0)\n"
10710 ++ "1: prefetch (%1)\n" /* This set is 28 bytes */
10711 ++ " prefetch 64(%1)\n"
10712 ++ " prefetch 128(%1)\n"
10713 ++ " prefetch 192(%1)\n"
10714 ++ " prefetch 256(%1)\n"
10715 + "2: \n"
10716 + ".section .fixup, \"ax\"\n"
10717 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10718 ++ "3: \n"
10719 ++
10720 ++#ifdef CONFIG_PAX_KERNEXEC
10721 ++ " movl %%cr0, %0\n"
10722 ++ " movl %0, %%eax\n"
10723 ++ " andl $0xFFFEFFFF, %%eax\n"
10724 ++ " movl %%eax, %%cr0\n"
10725 ++#endif
10726 ++
10727 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10728 ++
10729 ++#ifdef CONFIG_PAX_KERNEXEC
10730 ++ " movl %0, %%cr0\n"
10731 ++#endif
10732 ++
10733 + " jmp 2b\n"
10734 + ".previous\n"
10735 + ".section __ex_table,\"a\"\n"
10736 + " .align 4\n"
10737 + " .long 1b, 3b\n"
10738 + ".previous"
10739 +- : : "r" (from) );
10740 ++ : "=&r" (cr0) : "r" (from) : "ax");
10741 +
10742 +
10743 + for(; i>5; i--)
10744 + {
10745 + __asm__ __volatile__ (
10746 +- "1: prefetch 320(%0)\n"
10747 +- "2: movq (%0), %%mm0\n"
10748 +- " movq 8(%0), %%mm1\n"
10749 +- " movq 16(%0), %%mm2\n"
10750 +- " movq 24(%0), %%mm3\n"
10751 +- " movq %%mm0, (%1)\n"
10752 +- " movq %%mm1, 8(%1)\n"
10753 +- " movq %%mm2, 16(%1)\n"
10754 +- " movq %%mm3, 24(%1)\n"
10755 +- " movq 32(%0), %%mm0\n"
10756 +- " movq 40(%0), %%mm1\n"
10757 +- " movq 48(%0), %%mm2\n"
10758 +- " movq 56(%0), %%mm3\n"
10759 +- " movq %%mm0, 32(%1)\n"
10760 +- " movq %%mm1, 40(%1)\n"
10761 +- " movq %%mm2, 48(%1)\n"
10762 +- " movq %%mm3, 56(%1)\n"
10763 ++ "1: prefetch 320(%1)\n"
10764 ++ "2: movq (%1), %%mm0\n"
10765 ++ " movq 8(%1), %%mm1\n"
10766 ++ " movq 16(%1), %%mm2\n"
10767 ++ " movq 24(%1), %%mm3\n"
10768 ++ " movq %%mm0, (%2)\n"
10769 ++ " movq %%mm1, 8(%2)\n"
10770 ++ " movq %%mm2, 16(%2)\n"
10771 ++ " movq %%mm3, 24(%2)\n"
10772 ++ " movq 32(%1), %%mm0\n"
10773 ++ " movq 40(%1), %%mm1\n"
10774 ++ " movq 48(%1), %%mm2\n"
10775 ++ " movq 56(%1), %%mm3\n"
10776 ++ " movq %%mm0, 32(%2)\n"
10777 ++ " movq %%mm1, 40(%2)\n"
10778 ++ " movq %%mm2, 48(%2)\n"
10779 ++ " movq %%mm3, 56(%2)\n"
10780 + ".section .fixup, \"ax\"\n"
10781 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10782 ++ "3:\n"
10783 ++
10784 ++#ifdef CONFIG_PAX_KERNEXEC
10785 ++ " movl %%cr0, %0\n"
10786 ++ " movl %0, %%eax\n"
10787 ++ " andl $0xFFFEFFFF, %%eax\n"
10788 ++ " movl %%eax, %%cr0\n"
10789 ++#endif
10790 ++
10791 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10792 ++
10793 ++#ifdef CONFIG_PAX_KERNEXEC
10794 ++ " movl %0, %%cr0\n"
10795 ++#endif
10796 ++
10797 + " jmp 2b\n"
10798 + ".previous\n"
10799 + ".section __ex_table,\"a\"\n"
10800 + " .align 4\n"
10801 + " .long 1b, 3b\n"
10802 + ".previous"
10803 +- : : "r" (from), "r" (to) : "memory");
10804 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10805 + from+=64;
10806 + to+=64;
10807 + }
10808 +@@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
10809 + static void fast_copy_page(void *to, void *from)
10810 + {
10811 + int i;
10812 ++ unsigned long cr0;
10813 +
10814 + kernel_fpu_begin();
10815 +
10816 +@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
10817 + * but that is for later. -AV
10818 + */
10819 + __asm__ __volatile__ (
10820 +- "1: prefetch (%0)\n"
10821 +- " prefetch 64(%0)\n"
10822 +- " prefetch 128(%0)\n"
10823 +- " prefetch 192(%0)\n"
10824 +- " prefetch 256(%0)\n"
10825 ++ "1: prefetch (%1)\n"
10826 ++ " prefetch 64(%1)\n"
10827 ++ " prefetch 128(%1)\n"
10828 ++ " prefetch 192(%1)\n"
10829 ++ " prefetch 256(%1)\n"
10830 + "2: \n"
10831 + ".section .fixup, \"ax\"\n"
10832 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10833 ++ "3: \n"
10834 ++
10835 ++#ifdef CONFIG_PAX_KERNEXEC
10836 ++ " movl %%cr0, %0\n"
10837 ++ " movl %0, %%eax\n"
10838 ++ " andl $0xFFFEFFFF, %%eax\n"
10839 ++ " movl %%eax, %%cr0\n"
10840 ++#endif
10841 ++
10842 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10843 ++
10844 ++#ifdef CONFIG_PAX_KERNEXEC
10845 ++ " movl %0, %%cr0\n"
10846 ++#endif
10847 ++
10848 + " jmp 2b\n"
10849 + ".previous\n"
10850 + ".section __ex_table,\"a\"\n"
10851 + " .align 4\n"
10852 + " .long 1b, 3b\n"
10853 + ".previous"
10854 +- : : "r" (from) );
10855 ++ : "=&r" (cr0) : "r" (from) : "ax");
10856 +
10857 + for(i=0; i<(4096-320)/64; i++)
10858 + {
10859 + __asm__ __volatile__ (
10860 +- "1: prefetch 320(%0)\n"
10861 +- "2: movq (%0), %%mm0\n"
10862 +- " movntq %%mm0, (%1)\n"
10863 +- " movq 8(%0), %%mm1\n"
10864 +- " movntq %%mm1, 8(%1)\n"
10865 +- " movq 16(%0), %%mm2\n"
10866 +- " movntq %%mm2, 16(%1)\n"
10867 +- " movq 24(%0), %%mm3\n"
10868 +- " movntq %%mm3, 24(%1)\n"
10869 +- " movq 32(%0), %%mm4\n"
10870 +- " movntq %%mm4, 32(%1)\n"
10871 +- " movq 40(%0), %%mm5\n"
10872 +- " movntq %%mm5, 40(%1)\n"
10873 +- " movq 48(%0), %%mm6\n"
10874 +- " movntq %%mm6, 48(%1)\n"
10875 +- " movq 56(%0), %%mm7\n"
10876 +- " movntq %%mm7, 56(%1)\n"
10877 ++ "1: prefetch 320(%1)\n"
10878 ++ "2: movq (%1), %%mm0\n"
10879 ++ " movntq %%mm0, (%2)\n"
10880 ++ " movq 8(%1), %%mm1\n"
10881 ++ " movntq %%mm1, 8(%2)\n"
10882 ++ " movq 16(%1), %%mm2\n"
10883 ++ " movntq %%mm2, 16(%2)\n"
10884 ++ " movq 24(%1), %%mm3\n"
10885 ++ " movntq %%mm3, 24(%2)\n"
10886 ++ " movq 32(%1), %%mm4\n"
10887 ++ " movntq %%mm4, 32(%2)\n"
10888 ++ " movq 40(%1), %%mm5\n"
10889 ++ " movntq %%mm5, 40(%2)\n"
10890 ++ " movq 48(%1), %%mm6\n"
10891 ++ " movntq %%mm6, 48(%2)\n"
10892 ++ " movq 56(%1), %%mm7\n"
10893 ++ " movntq %%mm7, 56(%2)\n"
10894 + ".section .fixup, \"ax\"\n"
10895 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10896 ++ "3:\n"
10897 ++
10898 ++#ifdef CONFIG_PAX_KERNEXEC
10899 ++ " movl %%cr0, %0\n"
10900 ++ " movl %0, %%eax\n"
10901 ++ " andl $0xFFFEFFFF, %%eax\n"
10902 ++ " movl %%eax, %%cr0\n"
10903 ++#endif
10904 ++
10905 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
10906 ++
10907 ++#ifdef CONFIG_PAX_KERNEXEC
10908 ++ " movl %0, %%cr0\n"
10909 ++#endif
10910 ++
10911 + " jmp 2b\n"
10912 + ".previous\n"
10913 + ".section __ex_table,\"a\"\n"
10914 + " .align 4\n"
10915 + " .long 1b, 3b\n"
10916 + ".previous"
10917 +- : : "r" (from), "r" (to) : "memory");
10918 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
10919 + from+=64;
10920 + to+=64;
10921 + }
10922 +@@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
10923 + static void fast_copy_page(void *to, void *from)
10924 + {
10925 + int i;
10926 +-
10927 +-
10928 ++ unsigned long cr0;
10929 ++
10930 + kernel_fpu_begin();
10931 +
10932 + __asm__ __volatile__ (
10933 +- "1: prefetch (%0)\n"
10934 +- " prefetch 64(%0)\n"
10935 +- " prefetch 128(%0)\n"
10936 +- " prefetch 192(%0)\n"
10937 +- " prefetch 256(%0)\n"
10938 ++ "1: prefetch (%1)\n"
10939 ++ " prefetch 64(%1)\n"
10940 ++ " prefetch 128(%1)\n"
10941 ++ " prefetch 192(%1)\n"
10942 ++ " prefetch 256(%1)\n"
10943 + "2: \n"
10944 + ".section .fixup, \"ax\"\n"
10945 +- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10946 ++ "3: \n"
10947 ++
10948 ++#ifdef CONFIG_PAX_KERNEXEC
10949 ++ " movl %%cr0, %0\n"
10950 ++ " movl %0, %%eax\n"
10951 ++ " andl $0xFFFEFFFF, %%eax\n"
10952 ++ " movl %%eax, %%cr0\n"
10953 ++#endif
10954 ++
10955 ++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
10956 ++
10957 ++#ifdef CONFIG_PAX_KERNEXEC
10958 ++ " movl %0, %%cr0\n"
10959 ++#endif
10960 ++
10961 + " jmp 2b\n"
10962 + ".previous\n"
10963 + ".section __ex_table,\"a\"\n"
10964 + " .align 4\n"
10965 + " .long 1b, 3b\n"
10966 + ".previous"
10967 +- : : "r" (from) );
10968 ++ : "=&r" (cr0) : "r" (from) : "ax");
10969 +
10970 + for(i=0; i<4096/64; i++)
10971 + {
10972 + __asm__ __volatile__ (
10973 +- "1: prefetch 320(%0)\n"
10974 +- "2: movq (%0), %%mm0\n"
10975 +- " movq 8(%0), %%mm1\n"
10976 +- " movq 16(%0), %%mm2\n"
10977 +- " movq 24(%0), %%mm3\n"
10978 +- " movq %%mm0, (%1)\n"
10979 +- " movq %%mm1, 8(%1)\n"
10980 +- " movq %%mm2, 16(%1)\n"
10981 +- " movq %%mm3, 24(%1)\n"
10982 +- " movq 32(%0), %%mm0\n"
10983 +- " movq 40(%0), %%mm1\n"
10984 +- " movq 48(%0), %%mm2\n"
10985 +- " movq 56(%0), %%mm3\n"
10986 +- " movq %%mm0, 32(%1)\n"
10987 +- " movq %%mm1, 40(%1)\n"
10988 +- " movq %%mm2, 48(%1)\n"
10989 +- " movq %%mm3, 56(%1)\n"
10990 ++ "1: prefetch 320(%1)\n"
10991 ++ "2: movq (%1), %%mm0\n"
10992 ++ " movq 8(%1), %%mm1\n"
10993 ++ " movq 16(%1), %%mm2\n"
10994 ++ " movq 24(%1), %%mm3\n"
10995 ++ " movq %%mm0, (%2)\n"
10996 ++ " movq %%mm1, 8(%2)\n"
10997 ++ " movq %%mm2, 16(%2)\n"
10998 ++ " movq %%mm3, 24(%2)\n"
10999 ++ " movq 32(%1), %%mm0\n"
11000 ++ " movq 40(%1), %%mm1\n"
11001 ++ " movq 48(%1), %%mm2\n"
11002 ++ " movq 56(%1), %%mm3\n"
11003 ++ " movq %%mm0, 32(%2)\n"
11004 ++ " movq %%mm1, 40(%2)\n"
11005 ++ " movq %%mm2, 48(%2)\n"
11006 ++ " movq %%mm3, 56(%2)\n"
11007 + ".section .fixup, \"ax\"\n"
11008 +- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11009 ++ "3:\n"
11010 ++
11011 ++#ifdef CONFIG_PAX_KERNEXEC
11012 ++ " movl %%cr0, %0\n"
11013 ++ " movl %0, %%eax\n"
11014 ++ " andl $0xFFFEFFFF, %%eax\n"
11015 ++ " movl %%eax, %%cr0\n"
11016 ++#endif
11017 ++
11018 ++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
11019 ++
11020 ++#ifdef CONFIG_PAX_KERNEXEC
11021 ++ " movl %0, %%cr0\n"
11022 ++#endif
11023 ++
11024 + " jmp 2b\n"
11025 + ".previous\n"
11026 + ".section __ex_table,\"a\"\n"
11027 + " .align 4\n"
11028 + " .long 1b, 3b\n"
11029 + ".previous"
11030 +- : : "r" (from), "r" (to) : "memory");
11031 ++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
11032 + from+=64;
11033 + to+=64;
11034 + }
11035 +diff -Nurp linux-2.6.23.15/arch/i386/lib/putuser.S linux-2.6.23.15-grsec/arch/i386/lib/putuser.S
11036 +--- linux-2.6.23.15/arch/i386/lib/putuser.S 2007-10-09 21:31:38.000000000 +0100
11037 ++++ linux-2.6.23.15-grsec/arch/i386/lib/putuser.S 2008-02-11 10:37:44.000000000 +0000
11038 +@@ -11,7 +11,7 @@
11039 + #include <linux/linkage.h>
11040 + #include <asm/dwarf2.h>
11041 + #include <asm/thread_info.h>
11042 +-
11043 ++#include <asm/segment.h>
11044 +
11045 + /*
11046 + * __put_user_X
11047 +@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
11048 + ENTER
11049 + cmpl TI_addr_limit(%ebx),%ecx
11050 + jae bad_put_user
11051 ++ pushl $(__USER_DS)
11052 ++ popl %ds
11053 + 1: movb %al,(%ecx)
11054 ++ pushl %ss
11055 ++ popl %ds
11056 + xorl %eax,%eax
11057 + EXIT
11058 + ENDPROC(__put_user_1)
11059 +@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
11060 + subl $1,%ebx
11061 + cmpl %ebx,%ecx
11062 + jae bad_put_user
11063 ++ pushl $(__USER_DS)
11064 ++ popl %ds
11065 + 2: movw %ax,(%ecx)
11066 ++ pushl %ss
11067 ++ popl %ds
11068 + xorl %eax,%eax
11069 + EXIT
11070 + ENDPROC(__put_user_2)
11071 +@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
11072 + subl $3,%ebx
11073 + cmpl %ebx,%ecx
11074 + jae bad_put_user
11075 ++ pushl $(__USER_DS)
11076 ++ popl %ds
11077 + 3: movl %eax,(%ecx)
11078 ++ pushl %ss
11079 ++ popl %ds
11080 + xorl %eax,%eax
11081 + EXIT
11082 + ENDPROC(__put_user_4)
11083 +@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
11084 + subl $7,%ebx
11085 + cmpl %ebx,%ecx
11086 + jae bad_put_user
11087 ++ pushl $(__USER_DS)
11088 ++ popl %ds
11089 + 4: movl %eax,(%ecx)
11090 + 5: movl %edx,4(%ecx)
11091 ++ pushl %ss
11092 ++ popl %ds
11093 + xorl %eax,%eax
11094 + EXIT
11095 + ENDPROC(__put_user_8)
11096 +@@ -85,6 +101,10 @@ bad_put_user:
11097 + CFI_DEF_CFA esp, 2*4
11098 + CFI_OFFSET eip, -1*4
11099 + CFI_OFFSET ebx, -2*4
11100 ++ pushl %ss
11101 ++ CFI_ADJUST_CFA_OFFSET 4
11102 ++ popl %ds
11103 ++ CFI_ADJUST_CFA_OFFSET -4
11104 + movl $-14,%eax
11105 + EXIT
11106 + END(bad_put_user)
11107 +diff -Nurp linux-2.6.23.15/arch/i386/lib/usercopy.c linux-2.6.23.15-grsec/arch/i386/lib/usercopy.c
11108 +--- linux-2.6.23.15/arch/i386/lib/usercopy.c 2007-10-09 21:31:38.000000000 +0100
11109 ++++ linux-2.6.23.15-grsec/arch/i386/lib/usercopy.c 2008-02-11 10:37:44.000000000 +0000
11110 +@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
11111 + * Copy a null terminated string from userspace.
11112 + */
11113 +
11114 +-#define __do_strncpy_from_user(dst,src,count,res) \
11115 +-do { \
11116 +- int __d0, __d1, __d2; \
11117 +- might_sleep(); \
11118 +- __asm__ __volatile__( \
11119 +- " testl %1,%1\n" \
11120 +- " jz 2f\n" \
11121 +- "0: lodsb\n" \
11122 +- " stosb\n" \
11123 +- " testb %%al,%%al\n" \
11124 +- " jz 1f\n" \
11125 +- " decl %1\n" \
11126 +- " jnz 0b\n" \
11127 +- "1: subl %1,%0\n" \
11128 +- "2:\n" \
11129 +- ".section .fixup,\"ax\"\n" \
11130 +- "3: movl %5,%0\n" \
11131 +- " jmp 2b\n" \
11132 +- ".previous\n" \
11133 +- ".section __ex_table,\"a\"\n" \
11134 +- " .align 4\n" \
11135 +- " .long 0b,3b\n" \
11136 +- ".previous" \
11137 +- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
11138 +- "=&D" (__d2) \
11139 +- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
11140 +- : "memory"); \
11141 +-} while (0)
11142 ++static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
11143 ++{
11144 ++ int __d0, __d1, __d2;
11145 ++ long res = -EFAULT;
11146 ++
11147 ++ might_sleep();
11148 ++ __asm__ __volatile__(
11149 ++ " movw %w10,%%ds\n"
11150 ++ " testl %1,%1\n"
11151 ++ " jz 2f\n"
11152 ++ "0: lodsb\n"
11153 ++ " stosb\n"
11154 ++ " testb %%al,%%al\n"
11155 ++ " jz 1f\n"
11156 ++ " decl %1\n"
11157 ++ " jnz 0b\n"
11158 ++ "1: subl %1,%0\n"
11159 ++ "2:\n"
11160 ++ " pushl %%ss\n"
11161 ++ " popl %%ds\n"
11162 ++ ".section .fixup,\"ax\"\n"
11163 ++ "3: movl %5,%0\n"
11164 ++ " jmp 2b\n"
11165 ++ ".previous\n"
11166 ++ ".section __ex_table,\"a\"\n"
11167 ++ " .align 4\n"
11168 ++ " .long 0b,3b\n"
11169 ++ ".previous"
11170 ++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
11171 ++ "=&D" (__d2)
11172 ++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
11173 ++ "r"(__USER_DS)
11174 ++ : "memory");
11175 ++ return res;
11176 ++}
11177 +
11178 + /**
11179 + * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
11180 +@@ -81,9 +88,7 @@ do { \
11181 + long
11182 + __strncpy_from_user(char *dst, const char __user *src, long count)
11183 + {
11184 +- long res;
11185 +- __do_strncpy_from_user(dst, src, count, res);
11186 +- return res;
11187 ++ return __do_strncpy_from_user(dst, src, count);
11188 + }
11189 + EXPORT_SYMBOL(__strncpy_from_user);
11190 +
11191 +@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
11192 + {
11193 + long res = -EFAULT;
11194 + if (access_ok(VERIFY_READ, src, 1))
11195 +- __do_strncpy_from_user(dst, src, count, res);
11196 ++ res = __do_strncpy_from_user(dst, src, count);
11197 + return res;
11198 + }
11199 + EXPORT_SYMBOL(strncpy_from_user);
11200 +@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
11201 + * Zero Userspace
11202 + */
11203 +
11204 +-#define __do_clear_user(addr,size) \
11205 +-do { \
11206 +- int __d0; \
11207 +- might_sleep(); \
11208 +- __asm__ __volatile__( \
11209 +- "0: rep; stosl\n" \
11210 +- " movl %2,%0\n" \
11211 +- "1: rep; stosb\n" \
11212 +- "2:\n" \
11213 +- ".section .fixup,\"ax\"\n" \
11214 +- "3: lea 0(%2,%0,4),%0\n" \
11215 +- " jmp 2b\n" \
11216 +- ".previous\n" \
11217 +- ".section __ex_table,\"a\"\n" \
11218 +- " .align 4\n" \
11219 +- " .long 0b,3b\n" \
11220 +- " .long 1b,2b\n" \
11221 +- ".previous" \
11222 +- : "=&c"(size), "=&D" (__d0) \
11223 +- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
11224 +-} while (0)
11225 ++static unsigned long __do_clear_user(void __user *addr, unsigned long size)
11226 ++{
11227 ++ int __d0;
11228 ++
11229 ++ might_sleep();
11230 ++ __asm__ __volatile__(
11231 ++ " movw %w6,%%es\n"
11232 ++ "0: rep; stosl\n"
11233 ++ " movl %2,%0\n"
11234 ++ "1: rep; stosb\n"
11235 ++ "2:\n"
11236 ++ " pushl %%ss\n"
11237 ++ " popl %%es\n"
11238 ++ ".section .fixup,\"ax\"\n"
11239 ++ "3: lea 0(%2,%0,4),%0\n"
11240 ++ " jmp 2b\n"
11241 ++ ".previous\n"
11242 ++ ".section __ex_table,\"a\"\n"
11243 ++ " .align 4\n"
11244 ++ " .long 0b,3b\n"
11245 ++ " .long 1b,2b\n"
11246 ++ ".previous"
11247 ++ : "=&c"(size), "=&D" (__d0)
11248 ++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
11249 ++ "r"(__USER_DS));
11250 ++ return size;
11251 ++}
11252 +
11253 + /**
11254 + * clear_user: - Zero a block of memory in user space.
11255 +@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
11256 + {
11257 + might_sleep();
11258 + if (access_ok(VERIFY_WRITE, to, n))
11259 +- __do_clear_user(to, n);
11260 ++ n = __do_clear_user(to, n);
11261 + return n;
11262 + }
11263 + EXPORT_SYMBOL(clear_user);
11264 +@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
11265 + unsigned long
11266 + __clear_user(void __user *to, unsigned long n)
11267 + {
11268 +- __do_clear_user(to, n);
11269 +- return n;
11270 ++ return __do_clear_user(to, n);
11271 + }
11272 + EXPORT_SYMBOL(__clear_user);
11273 +
11274 +@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
11275 + might_sleep();
11276 +
11277 + __asm__ __volatile__(
11278 ++ " movw %w8,%%es\n"
11279 + " testl %0, %0\n"
11280 + " jz 3f\n"
11281 +- " andl %0,%%ecx\n"
11282 ++ " movl %0,%%ecx\n"
11283 + "0: repne; scasb\n"
11284 + " setne %%al\n"
11285 + " subl %%ecx,%0\n"
11286 + " addl %0,%%eax\n"
11287 + "1:\n"
11288 ++ " pushl %%ss\n"
11289 ++ " popl %%es\n"
11290 + ".section .fixup,\"ax\"\n"
11291 + "2: xorl %%eax,%%eax\n"
11292 + " jmp 1b\n"
11293 +@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
11294 + " .long 0b,2b\n"
11295 + ".previous"
11296 + :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
11297 +- :"0" (n), "1" (s), "2" (0), "3" (mask)
11298 ++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
11299 + :"cc");
11300 + return res & mask;
11301 + }
11302 +@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
11303 +
11304 + #ifdef CONFIG_X86_INTEL_USERCOPY
11305 + static unsigned long
11306 +-__copy_user_intel(void __user *to, const void *from, unsigned long size)
11307 ++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
11308 ++{
11309 ++ int d0, d1;
11310 ++ __asm__ __volatile__(
11311 ++ " movw %w6, %%es\n"
11312 ++ " .align 2,0x90\n"
11313 ++ "1: movl 32(%4), %%eax\n"
11314 ++ " cmpl $67, %0\n"
11315 ++ " jbe 3f\n"
11316 ++ "2: movl 64(%4), %%eax\n"
11317 ++ " .align 2,0x90\n"
11318 ++ "3: movl 0(%4), %%eax\n"
11319 ++ "4: movl 4(%4), %%edx\n"
11320 ++ "5: movl %%eax, %%es:0(%3)\n"
11321 ++ "6: movl %%edx, %%es:4(%3)\n"
11322 ++ "7: movl 8(%4), %%eax\n"
11323 ++ "8: movl 12(%4),%%edx\n"
11324 ++ "9: movl %%eax, %%es:8(%3)\n"
11325 ++ "10: movl %%edx, %%es:12(%3)\n"
11326 ++ "11: movl 16(%4), %%eax\n"
11327 ++ "12: movl 20(%4), %%edx\n"
11328 ++ "13: movl %%eax, %%es:16(%3)\n"
11329 ++ "14: movl %%edx, %%es:20(%3)\n"
11330 ++ "15: movl 24(%4), %%eax\n"
11331 ++ "16: movl 28(%4), %%edx\n"
11332 ++ "17: movl %%eax, %%es:24(%3)\n"
11333 ++ "18: movl %%edx, %%es:28(%3)\n"
11334 ++ "19: movl 32(%4), %%eax\n"
11335 ++ "20: movl 36(%4), %%edx\n"
11336 ++ "21: movl %%eax, %%es:32(%3)\n"
11337 ++ "22: movl %%edx, %%es:36(%3)\n"
11338 ++ "23: movl 40(%4), %%eax\n"
11339 ++ "24: movl 44(%4), %%edx\n"
11340 ++ "25: movl %%eax, %%es:40(%3)\n"
11341 ++ "26: movl %%edx, %%es:44(%3)\n"
11342 ++ "27: movl 48(%4), %%eax\n"
11343 ++ "28: movl 52(%4), %%edx\n"
11344 ++ "29: movl %%eax, %%es:48(%3)\n"
11345 ++ "30: movl %%edx, %%es:52(%3)\n"
11346 ++ "31: movl 56(%4), %%eax\n"
11347 ++ "32: movl 60(%4), %%edx\n"
11348 ++ "33: movl %%eax, %%es:56(%3)\n"
11349 ++ "34: movl %%edx, %%es:60(%3)\n"
11350 ++ " addl $-64, %0\n"
11351 ++ " addl $64, %4\n"
11352 ++ " addl $64, %3\n"
11353 ++ " cmpl $63, %0\n"
11354 ++ " ja 1b\n"
11355 ++ "35: movl %0, %%eax\n"
11356 ++ " shrl $2, %0\n"
11357 ++ " andl $3, %%eax\n"
11358 ++ " cld\n"
11359 ++ "99: rep; movsl\n"
11360 ++ "36: movl %%eax, %0\n"
11361 ++ "37: rep; movsb\n"
11362 ++ "100:\n"
11363 ++ " pushl %%ss\n"
11364 ++ " popl %%es\n"
11365 ++ ".section .fixup,\"ax\"\n"
11366 ++ "101: lea 0(%%eax,%0,4),%0\n"
11367 ++ " jmp 100b\n"
11368 ++ ".previous\n"
11369 ++ ".section __ex_table,\"a\"\n"
11370 ++ " .align 4\n"
11371 ++ " .long 1b,100b\n"
11372 ++ " .long 2b,100b\n"
11373 ++ " .long 3b,100b\n"
11374 ++ " .long 4b,100b\n"
11375 ++ " .long 5b,100b\n"
11376 ++ " .long 6b,100b\n"
11377 ++ " .long 7b,100b\n"
11378 ++ " .long 8b,100b\n"
11379 ++ " .long 9b,100b\n"
11380 ++ " .long 10b,100b\n"
11381 ++ " .long 11b,100b\n"
11382 ++ " .long 12b,100b\n"
11383 ++ " .long 13b,100b\n"
11384 ++ " .long 14b,100b\n"
11385 ++ " .long 15b,100b\n"
11386 ++ " .long 16b,100b\n"
11387 ++ " .long 17b,100b\n"
11388 ++ " .long 18b,100b\n"
11389 ++ " .long 19b,100b\n"
11390 ++ " .long 20b,100b\n"
11391 ++ " .long 21b,100b\n"
11392 ++ " .long 22b,100b\n"
11393 ++ " .long 23b,100b\n"
11394 ++ " .long 24b,100b\n"
11395 ++ " .long 25b,100b\n"
11396 ++ " .long 26b,100b\n"
11397 ++ " .long 27b,100b\n"
11398 ++ " .long 28b,100b\n"
11399 ++ " .long 29b,100b\n"
11400 ++ " .long 30b,100b\n"
11401 ++ " .long 31b,100b\n"
11402 ++ " .long 32b,100b\n"
11403 ++ " .long 33b,100b\n"
11404 ++ " .long 34b,100b\n"
11405 ++ " .long 35b,100b\n"
11406 ++ " .long 36b,100b\n"
11407 ++ " .long 37b,100b\n"
11408 ++ " .long 99b,101b\n"
11409 ++ ".previous"
11410 ++ : "=&c"(size), "=&D" (d0), "=&S" (d1)
11411 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11412 ++ : "eax", "edx", "memory");
11413 ++ return size;
11414 ++}
11415 ++
11416 ++static unsigned long
11417 ++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
11418 + {
11419 + int d0, d1;
11420 + __asm__ __volatile__(
11421 ++ " movw %w6, %%ds\n"
11422 + " .align 2,0x90\n"
11423 + "1: movl 32(%4), %%eax\n"
11424 + " cmpl $67, %0\n"
11425 +@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
11426 + " .align 2,0x90\n"
11427 + "3: movl 0(%4), %%eax\n"
11428 + "4: movl 4(%4), %%edx\n"
11429 +- "5: movl %%eax, 0(%3)\n"
11430 +- "6: movl %%edx, 4(%3)\n"
11431 ++ "5: movl %%eax, %%es:0(%3)\n"
11432 ++ "6: movl %%edx, %%es:4(%3)\n"
11433 + "7: movl 8(%4), %%eax\n"
11434 + "8: movl 12(%4),%%edx\n"
11435 +- "9: movl %%eax, 8(%3)\n"
11436 +- "10: movl %%edx, 12(%3)\n"
11437 ++ "9: movl %%eax, %%es:8(%3)\n"
11438 ++ "10: movl %%edx, %%es:12(%3)\n"
11439 + "11: movl 16(%4), %%eax\n"
11440 + "12: movl 20(%4), %%edx\n"
11441 +- "13: movl %%eax, 16(%3)\n"
11442 +- "14: movl %%edx, 20(%3)\n"
11443 ++ "13: movl %%eax, %%es:16(%3)\n"
11444 ++ "14: movl %%edx, %%es:20(%3)\n"
11445 + "15: movl 24(%4), %%eax\n"
11446 + "16: movl 28(%4), %%edx\n"
11447 +- "17: movl %%eax, 24(%3)\n"
11448 +- "18: movl %%edx, 28(%3)\n"
11449 ++ "17: movl %%eax, %%es:24(%3)\n"
11450 ++ "18: movl %%edx, %%es:28(%3)\n"
11451 + "19: movl 32(%4), %%eax\n"
11452 + "20: movl 36(%4), %%edx\n"
11453 +- "21: movl %%eax, 32(%3)\n"
11454 +- "22: movl %%edx, 36(%3)\n"
11455 ++ "21: movl %%eax, %%es:32(%3)\n"
11456 ++ "22: movl %%edx, %%es:36(%3)\n"
11457 + "23: movl 40(%4), %%eax\n"
11458 + "24: movl 44(%4), %%edx\n"
11459 +- "25: movl %%eax, 40(%3)\n"
11460 +- "26: movl %%edx, 44(%3)\n"
11461 ++ "25: movl %%eax, %%es:40(%3)\n"
11462 ++ "26: movl %%edx, %%es:44(%3)\n"
11463 + "27: movl 48(%4), %%eax\n"
11464 + "28: movl 52(%4), %%edx\n"
11465 +- "29: movl %%eax, 48(%3)\n"
11466 +- "30: movl %%edx, 52(%3)\n"
11467 ++ "29: movl %%eax, %%es:48(%3)\n"
11468 ++ "30: movl %%edx, %%es:52(%3)\n"
11469 + "31: movl 56(%4), %%eax\n"
11470 + "32: movl 60(%4), %%edx\n"
11471 +- "33: movl %%eax, 56(%3)\n"
11472 +- "34: movl %%edx, 60(%3)\n"
11473 ++ "33: movl %%eax, %%es:56(%3)\n"
11474 ++ "34: movl %%edx, %%es:60(%3)\n"
11475 + " addl $-64, %0\n"
11476 + " addl $64, %4\n"
11477 + " addl $64, %3\n"
11478 +@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
11479 + "36: movl %%eax, %0\n"
11480 + "37: rep; movsb\n"
11481 + "100:\n"
11482 ++ " pushl %%ss\n"
11483 ++ " popl %%ds\n"
11484 + ".section .fixup,\"ax\"\n"
11485 + "101: lea 0(%%eax,%0,4),%0\n"
11486 + " jmp 100b\n"
11487 +@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
11488 + " .long 99b,101b\n"
11489 + ".previous"
11490 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11491 +- : "1"(to), "2"(from), "0"(size)
11492 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11493 + : "eax", "edx", "memory");
11494 + return size;
11495 + }
11496 +@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
11497 + {
11498 + int d0, d1;
11499 + __asm__ __volatile__(
11500 ++ " movw %w6, %%ds\n"
11501 + " .align 2,0x90\n"
11502 + "0: movl 32(%4), %%eax\n"
11503 + " cmpl $67, %0\n"
11504 +@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
11505 + " .align 2,0x90\n"
11506 + "2: movl 0(%4), %%eax\n"
11507 + "21: movl 4(%4), %%edx\n"
11508 +- " movl %%eax, 0(%3)\n"
11509 +- " movl %%edx, 4(%3)\n"
11510 ++ " movl %%eax, %%es:0(%3)\n"
11511 ++ " movl %%edx, %%es:4(%3)\n"
11512 + "3: movl 8(%4), %%eax\n"
11513 + "31: movl 12(%4),%%edx\n"
11514 +- " movl %%eax, 8(%3)\n"
11515 +- " movl %%edx, 12(%3)\n"
11516 ++ " movl %%eax, %%es:8(%3)\n"
11517 ++ " movl %%edx, %%es:12(%3)\n"
11518 + "4: movl 16(%4), %%eax\n"
11519 + "41: movl 20(%4), %%edx\n"
11520 +- " movl %%eax, 16(%3)\n"
11521 +- " movl %%edx, 20(%3)\n"
11522 ++ " movl %%eax, %%es:16(%3)\n"
11523 ++ " movl %%edx, %%es:20(%3)\n"
11524 + "10: movl 24(%4), %%eax\n"
11525 + "51: movl 28(%4), %%edx\n"
11526 +- " movl %%eax, 24(%3)\n"
11527 +- " movl %%edx, 28(%3)\n"
11528 ++ " movl %%eax, %%es:24(%3)\n"
11529 ++ " movl %%edx, %%es:28(%3)\n"
11530 + "11: movl 32(%4), %%eax\n"
11531 + "61: movl 36(%4), %%edx\n"
11532 +- " movl %%eax, 32(%3)\n"
11533 +- " movl %%edx, 36(%3)\n"
11534 ++ " movl %%eax, %%es:32(%3)\n"
11535 ++ " movl %%edx, %%es:36(%3)\n"
11536 + "12: movl 40(%4), %%eax\n"
11537 + "71: movl 44(%4), %%edx\n"
11538 +- " movl %%eax, 40(%3)\n"
11539 +- " movl %%edx, 44(%3)\n"
11540 ++ " movl %%eax, %%es:40(%3)\n"
11541 ++ " movl %%edx, %%es:44(%3)\n"
11542 + "13: movl 48(%4), %%eax\n"
11543 + "81: movl 52(%4), %%edx\n"
11544 +- " movl %%eax, 48(%3)\n"
11545 +- " movl %%edx, 52(%3)\n"
11546 ++ " movl %%eax, %%es:48(%3)\n"
11547 ++ " movl %%edx, %%es:52(%3)\n"
11548 + "14: movl 56(%4), %%eax\n"
11549 + "91: movl 60(%4), %%edx\n"
11550 +- " movl %%eax, 56(%3)\n"
11551 +- " movl %%edx, 60(%3)\n"
11552 ++ " movl %%eax, %%es:56(%3)\n"
11553 ++ " movl %%edx, %%es:60(%3)\n"
11554 + " addl $-64, %0\n"
11555 + " addl $64, %4\n"
11556 + " addl $64, %3\n"
11557 +@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
11558 + " movl %%eax,%0\n"
11559 + "7: rep; movsb\n"
11560 + "8:\n"
11561 ++ " pushl %%ss\n"
11562 ++ " popl %%ds\n"
11563 + ".section .fixup,\"ax\"\n"
11564 + "9: lea 0(%%eax,%0,4),%0\n"
11565 + "16: pushl %0\n"
11566 +@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
11567 + " .long 7b,16b\n"
11568 + ".previous"
11569 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11570 +- : "1"(to), "2"(from), "0"(size)
11571 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11572 + : "eax", "edx", "memory");
11573 + return size;
11574 + }
11575 +@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
11576 + int d0, d1;
11577 +
11578 + __asm__ __volatile__(
11579 ++ " movw %w6, %%ds\n"
11580 + " .align 2,0x90\n"
11581 + "0: movl 32(%4), %%eax\n"
11582 + " cmpl $67, %0\n"
11583 +@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
11584 + " .align 2,0x90\n"
11585 + "2: movl 0(%4), %%eax\n"
11586 + "21: movl 4(%4), %%edx\n"
11587 +- " movnti %%eax, 0(%3)\n"
11588 +- " movnti %%edx, 4(%3)\n"
11589 ++ " movnti %%eax, %%es:0(%3)\n"
11590 ++ " movnti %%edx, %%es:4(%3)\n"
11591 + "3: movl 8(%4), %%eax\n"
11592 + "31: movl 12(%4),%%edx\n"
11593 +- " movnti %%eax, 8(%3)\n"
11594 +- " movnti %%edx, 12(%3)\n"
11595 ++ " movnti %%eax, %%es:8(%3)\n"
11596 ++ " movnti %%edx, %%es:12(%3)\n"
11597 + "4: movl 16(%4), %%eax\n"
11598 + "41: movl 20(%4), %%edx\n"
11599 +- " movnti %%eax, 16(%3)\n"
11600 +- " movnti %%edx, 20(%3)\n"
11601 ++ " movnti %%eax, %%es:16(%3)\n"
11602 ++ " movnti %%edx, %%es:20(%3)\n"
11603 + "10: movl 24(%4), %%eax\n"
11604 + "51: movl 28(%4), %%edx\n"
11605 +- " movnti %%eax, 24(%3)\n"
11606 +- " movnti %%edx, 28(%3)\n"
11607 ++ " movnti %%eax, %%es:24(%3)\n"
11608 ++ " movnti %%edx, %%es:28(%3)\n"
11609 + "11: movl 32(%4), %%eax\n"
11610 + "61: movl 36(%4), %%edx\n"
11611 +- " movnti %%eax, 32(%3)\n"
11612 +- " movnti %%edx, 36(%3)\n"
11613 ++ " movnti %%eax, %%es:32(%3)\n"
11614 ++ " movnti %%edx, %%es:36(%3)\n"
11615 + "12: movl 40(%4), %%eax\n"
11616 + "71: movl 44(%4), %%edx\n"
11617 +- " movnti %%eax, 40(%3)\n"
11618 +- " movnti %%edx, 44(%3)\n"
11619 ++ " movnti %%eax, %%es:40(%3)\n"
11620 ++ " movnti %%edx, %%es:44(%3)\n"
11621 + "13: movl 48(%4), %%eax\n"
11622 + "81: movl 52(%4), %%edx\n"
11623 +- " movnti %%eax, 48(%3)\n"
11624 +- " movnti %%edx, 52(%3)\n"
11625 ++ " movnti %%eax, %%es:48(%3)\n"
11626 ++ " movnti %%edx, %%es:52(%3)\n"
11627 + "14: movl 56(%4), %%eax\n"
11628 + "91: movl 60(%4), %%edx\n"
11629 +- " movnti %%eax, 56(%3)\n"
11630 +- " movnti %%edx, 60(%3)\n"
11631 ++ " movnti %%eax, %%es:56(%3)\n"
11632 ++ " movnti %%edx, %%es:60(%3)\n"
11633 + " addl $-64, %0\n"
11634 + " addl $64, %4\n"
11635 + " addl $64, %3\n"
11636 +@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
11637 + " movl %%eax,%0\n"
11638 + "7: rep; movsb\n"
11639 + "8:\n"
11640 ++ " pushl %%ss\n"
11641 ++ " popl %%ds\n"
11642 + ".section .fixup,\"ax\"\n"
11643 + "9: lea 0(%%eax,%0,4),%0\n"
11644 + "16: pushl %0\n"
11645 +@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
11646 + " .long 7b,16b\n"
11647 + ".previous"
11648 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11649 +- : "1"(to), "2"(from), "0"(size)
11650 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11651 + : "eax", "edx", "memory");
11652 + return size;
11653 + }
11654 +@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
11655 + int d0, d1;
11656 +
11657 + __asm__ __volatile__(
11658 ++ " movw %w6, %%ds\n"
11659 + " .align 2,0x90\n"
11660 + "0: movl 32(%4), %%eax\n"
11661 + " cmpl $67, %0\n"
11662 +@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
11663 + " .align 2,0x90\n"
11664 + "2: movl 0(%4), %%eax\n"
11665 + "21: movl 4(%4), %%edx\n"
11666 +- " movnti %%eax, 0(%3)\n"
11667 +- " movnti %%edx, 4(%3)\n"
11668 ++ " movnti %%eax, %%es:0(%3)\n"
11669 ++ " movnti %%edx, %%es:4(%3)\n"
11670 + "3: movl 8(%4), %%eax\n"
11671 + "31: movl 12(%4),%%edx\n"
11672 +- " movnti %%eax, 8(%3)\n"
11673 +- " movnti %%edx, 12(%3)\n"
11674 ++ " movnti %%eax, %%es:8(%3)\n"
11675 ++ " movnti %%edx, %%es:12(%3)\n"
11676 + "4: movl 16(%4), %%eax\n"
11677 + "41: movl 20(%4), %%edx\n"
11678 +- " movnti %%eax, 16(%3)\n"
11679 +- " movnti %%edx, 20(%3)\n"
11680 ++ " movnti %%eax, %%es:16(%3)\n"
11681 ++ " movnti %%edx, %%es:20(%3)\n"
11682 + "10: movl 24(%4), %%eax\n"
11683 + "51: movl 28(%4), %%edx\n"
11684 +- " movnti %%eax, 24(%3)\n"
11685 +- " movnti %%edx, 28(%3)\n"
11686 ++ " movnti %%eax, %%es:24(%3)\n"
11687 ++ " movnti %%edx, %%es:28(%3)\n"
11688 + "11: movl 32(%4), %%eax\n"
11689 + "61: movl 36(%4), %%edx\n"
11690 +- " movnti %%eax, 32(%3)\n"
11691 +- " movnti %%edx, 36(%3)\n"
11692 ++ " movnti %%eax, %%es:32(%3)\n"
11693 ++ " movnti %%edx, %%es:36(%3)\n"
11694 + "12: movl 40(%4), %%eax\n"
11695 + "71: movl 44(%4), %%edx\n"
11696 +- " movnti %%eax, 40(%3)\n"
11697 +- " movnti %%edx, 44(%3)\n"
11698 ++ " movnti %%eax, %%es:40(%3)\n"
11699 ++ " movnti %%edx, %%es:44(%3)\n"
11700 + "13: movl 48(%4), %%eax\n"
11701 + "81: movl 52(%4), %%edx\n"
11702 +- " movnti %%eax, 48(%3)\n"
11703 +- " movnti %%edx, 52(%3)\n"
11704 ++ " movnti %%eax, %%es:48(%3)\n"
11705 ++ " movnti %%edx, %%es:52(%3)\n"
11706 + "14: movl 56(%4), %%eax\n"
11707 + "91: movl 60(%4), %%edx\n"
11708 +- " movnti %%eax, 56(%3)\n"
11709 +- " movnti %%edx, 60(%3)\n"
11710 ++ " movnti %%eax, %%es:56(%3)\n"
11711 ++ " movnti %%edx, %%es:60(%3)\n"
11712 + " addl $-64, %0\n"
11713 + " addl $64, %4\n"
11714 + " addl $64, %3\n"
11715 +@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
11716 + " movl %%eax,%0\n"
11717 + "7: rep; movsb\n"
11718 + "8:\n"
11719 ++ " pushl %%ss\n"
11720 ++ " popl %%ds\n"
11721 + ".section .fixup,\"ax\"\n"
11722 + "9: lea 0(%%eax,%0,4),%0\n"
11723 + "16: jmp 8b\n"
11724 +@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
11725 + " .long 7b,16b\n"
11726 + ".previous"
11727 + : "=&c"(size), "=&D" (d0), "=&S" (d1)
11728 +- : "1"(to), "2"(from), "0"(size)
11729 ++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
11730 + : "eax", "edx", "memory");
11731 + return size;
11732 + }
11733 +@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
11734 + */
11735 + unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
11736 + unsigned long size);
11737 +-unsigned long __copy_user_intel(void __user *to, const void *from,
11738 ++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
11739 ++ unsigned long size);
11740 ++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
11741 + unsigned long size);
11742 + unsigned long __copy_user_zeroing_intel_nocache(void *to,
11743 + const void __user *from, unsigned long size);
11744 + #endif /* CONFIG_X86_INTEL_USERCOPY */
11745 +
11746 + /* Generic arbitrary sized copy. */
11747 +-#define __copy_user(to,from,size) \
11748 +-do { \
11749 +- int __d0, __d1, __d2; \
11750 +- __asm__ __volatile__( \
11751 +- " cmp $7,%0\n" \
11752 +- " jbe 1f\n" \
11753 +- " movl %1,%0\n" \
11754 +- " negl %0\n" \
11755 +- " andl $7,%0\n" \
11756 +- " subl %0,%3\n" \
11757 +- "4: rep; movsb\n" \
11758 +- " movl %3,%0\n" \
11759 +- " shrl $2,%0\n" \
11760 +- " andl $3,%3\n" \
11761 +- " .align 2,0x90\n" \
11762 +- "0: rep; movsl\n" \
11763 +- " movl %3,%0\n" \
11764 +- "1: rep; movsb\n" \
11765 +- "2:\n" \
11766 +- ".section .fixup,\"ax\"\n" \
11767 +- "5: addl %3,%0\n" \
11768 +- " jmp 2b\n" \
11769 +- "3: lea 0(%3,%0,4),%0\n" \
11770 +- " jmp 2b\n" \
11771 +- ".previous\n" \
11772 +- ".section __ex_table,\"a\"\n" \
11773 +- " .align 4\n" \
11774 +- " .long 4b,5b\n" \
11775 +- " .long 0b,3b\n" \
11776 +- " .long 1b,2b\n" \
11777 +- ".previous" \
11778 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
11779 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
11780 +- : "memory"); \
11781 +-} while (0)
11782 +-
11783 +-#define __copy_user_zeroing(to,from,size) \
11784 +-do { \
11785 +- int __d0, __d1, __d2; \
11786 +- __asm__ __volatile__( \
11787 +- " cmp $7,%0\n" \
11788 +- " jbe 1f\n" \
11789 +- " movl %1,%0\n" \
11790 +- " negl %0\n" \
11791 +- " andl $7,%0\n" \
11792 +- " subl %0,%3\n" \
11793 +- "4: rep; movsb\n" \
11794 +- " movl %3,%0\n" \
11795 +- " shrl $2,%0\n" \
11796 +- " andl $3,%3\n" \
11797 +- " .align 2,0x90\n" \
11798 +- "0: rep; movsl\n" \
11799 +- " movl %3,%0\n" \
11800 +- "1: rep; movsb\n" \
11801 +- "2:\n" \
11802 +- ".section .fixup,\"ax\"\n" \
11803 +- "5: addl %3,%0\n" \
11804 +- " jmp 6f\n" \
11805 +- "3: lea 0(%3,%0,4),%0\n" \
11806 +- "6: pushl %0\n" \
11807 +- " pushl %%eax\n" \
11808 +- " xorl %%eax,%%eax\n" \
11809 +- " rep; stosb\n" \
11810 +- " popl %%eax\n" \
11811 +- " popl %0\n" \
11812 +- " jmp 2b\n" \
11813 +- ".previous\n" \
11814 +- ".section __ex_table,\"a\"\n" \
11815 +- " .align 4\n" \
11816 +- " .long 4b,5b\n" \
11817 +- " .long 0b,3b\n" \
11818 +- " .long 1b,6b\n" \
11819 +- ".previous" \
11820 +- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
11821 +- : "3"(size), "0"(size), "1"(to), "2"(from) \
11822 +- : "memory"); \
11823 +-} while (0)
11824 ++static unsigned long
11825 ++__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
11826 ++{
11827 ++ int __d0, __d1, __d2;
11828 ++
11829 ++ __asm__ __volatile__(
11830 ++ " movw %w8,%%es\n"
11831 ++ " cmp $7,%0\n"
11832 ++ " jbe 1f\n"
11833 ++ " movl %1,%0\n"
11834 ++ " negl %0\n"
11835 ++ " andl $7,%0\n"
11836 ++ " subl %0,%3\n"
11837 ++ "4: rep; movsb\n"
11838 ++ " movl %3,%0\n"
11839 ++ " shrl $2,%0\n"
11840 ++ " andl $3,%3\n"
11841 ++ " .align 2,0x90\n"
11842 ++ "0: rep; movsl\n"
11843 ++ " movl %3,%0\n"
11844 ++ "1: rep; movsb\n"
11845 ++ "2:\n"
11846 ++ " pushl %%ss\n"
11847 ++ " popl %%es\n"
11848 ++ ".section .fixup,\"ax\"\n"
11849 ++ "5: addl %3,%0\n"
11850 ++ " jmp 2b\n"
11851 ++ "3: lea 0(%3,%0,4),%0\n"
11852 ++ " jmp 2b\n"
11853 ++ ".previous\n"
11854 ++ ".section __ex_table,\"a\"\n"
11855 ++ " .align 4\n"
11856 ++ " .long 4b,5b\n"
11857 ++ " .long 0b,3b\n"
11858 ++ " .long 1b,2b\n"
11859 ++ ".previous"
11860 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11861 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11862 ++ : "memory");
11863 ++ return size;
11864 ++}
11865 ++
11866 ++static unsigned long
11867 ++__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
11868 ++{
11869 ++ int __d0, __d1, __d2;
11870 ++
11871 ++ __asm__ __volatile__(
11872 ++ " movw %w8,%%ds\n"
11873 ++ " cmp $7,%0\n"
11874 ++ " jbe 1f\n"
11875 ++ " movl %1,%0\n"
11876 ++ " negl %0\n"
11877 ++ " andl $7,%0\n"
11878 ++ " subl %0,%3\n"
11879 ++ "4: rep; movsb\n"
11880 ++ " movl %3,%0\n"
11881 ++ " shrl $2,%0\n"
11882 ++ " andl $3,%3\n"
11883 ++ " .align 2,0x90\n"
11884 ++ "0: rep; movsl\n"
11885 ++ " movl %3,%0\n"
11886 ++ "1: rep; movsb\n"
11887 ++ "2:\n"
11888 ++ " pushl %%ss\n"
11889 ++ " popl %%ds\n"
11890 ++ ".section .fixup,\"ax\"\n"
11891 ++ "5: addl %3,%0\n"
11892 ++ " jmp 2b\n"
11893 ++ "3: lea 0(%3,%0,4),%0\n"
11894 ++ " jmp 2b\n"
11895 ++ ".previous\n"
11896 ++ ".section __ex_table,\"a\"\n"
11897 ++ " .align 4\n"
11898 ++ " .long 4b,5b\n"
11899 ++ " .long 0b,3b\n"
11900 ++ " .long 1b,2b\n"
11901 ++ ".previous"
11902 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11903 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11904 ++ : "memory");
11905 ++ return size;
11906 ++}
11907 ++
11908 ++static unsigned long
11909 ++__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
11910 ++{
11911 ++ int __d0, __d1, __d2;
11912 ++
11913 ++ __asm__ __volatile__(
11914 ++ " movw %w8,%%ds\n"
11915 ++ " cmp $7,%0\n"
11916 ++ " jbe 1f\n"
11917 ++ " movl %1,%0\n"
11918 ++ " negl %0\n"
11919 ++ " andl $7,%0\n"
11920 ++ " subl %0,%3\n"
11921 ++ "4: rep; movsb\n"
11922 ++ " movl %3,%0\n"
11923 ++ " shrl $2,%0\n"
11924 ++ " andl $3,%3\n"
11925 ++ " .align 2,0x90\n"
11926 ++ "0: rep; movsl\n"
11927 ++ " movl %3,%0\n"
11928 ++ "1: rep; movsb\n"
11929 ++ "2:\n"
11930 ++ " pushl %%ss\n"
11931 ++ " popl %%ds\n"
11932 ++ ".section .fixup,\"ax\"\n"
11933 ++ "5: addl %3,%0\n"
11934 ++ " jmp 6f\n"
11935 ++ "3: lea 0(%3,%0,4),%0\n"
11936 ++ "6: pushl %0\n"
11937 ++ " pushl %%eax\n"
11938 ++ " xorl %%eax,%%eax\n"
11939 ++ " rep; stosb\n"
11940 ++ " popl %%eax\n"
11941 ++ " popl %0\n"
11942 ++ " jmp 2b\n"
11943 ++ ".previous\n"
11944 ++ ".section __ex_table,\"a\"\n"
11945 ++ " .align 4\n"
11946 ++ " .long 4b,5b\n"
11947 ++ " .long 0b,3b\n"
11948 ++ " .long 1b,6b\n"
11949 ++ ".previous"
11950 ++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
11951 ++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
11952 ++ : "memory");
11953 ++ return size;
11954 ++}
11955 +
11956 + unsigned long __copy_to_user_ll(void __user *to, const void *from,
11957 + unsigned long n)
11958 +@@ -774,9 +965,9 @@ survive:
11959 + }
11960 + #endif
11961 + if (movsl_is_ok(to, from, n))
11962 +- __copy_user(to, from, n);
11963 ++ n = __generic_copy_to_user(to, from, n);
11964 + else
11965 +- n = __copy_user_intel(to, from, n);
11966 ++ n = __generic_copy_to_user_intel(to, from, n);
11967 + return n;
11968 + }
11969 + EXPORT_SYMBOL(__copy_to_user_ll);
11970 +@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
11971 + unsigned long n)
11972 + {
11973 + if (movsl_is_ok(to, from, n))
11974 +- __copy_user_zeroing(to, from, n);
11975 ++ n = __copy_user_zeroing(to, from, n);
11976 + else
11977 + n = __copy_user_zeroing_intel(to, from, n);
11978 + return n;
11979 +@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
11980 + unsigned long n)
11981 + {
11982 + if (movsl_is_ok(to, from, n))
11983 +- __copy_user(to, from, n);
11984 ++ n = __generic_copy_from_user(to, from, n);
11985 + else
11986 +- n = __copy_user_intel((void __user *)to,
11987 ++ n = __generic_copy_from_user_intel((void __user *)to,
11988 + (const void *)from, n);
11989 + return n;
11990 + }
11991 +@@ -809,11 +1000,11 @@ unsigned long __copy_from_user_ll_nocach
11992 + {
11993 + #ifdef CONFIG_X86_INTEL_USERCOPY
11994 + if ( n > 64 && cpu_has_xmm2)
11995 +- n = __copy_user_zeroing_intel_nocache(to, from, n);
11996 ++ n = __copy_user_zeroing_intel_nocache(to, from, n);
11997 + else
11998 +- __copy_user_zeroing(to, from, n);
11999 ++ n = __copy_user_zeroing(to, from, n);
12000 + #else
12001 +- __copy_user_zeroing(to, from, n);
12002 ++ n = __copy_user_zeroing(to, from, n);
12003 + #endif
12004 + return n;
12005 + }
12006 +@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
12007 + {
12008 + #ifdef CONFIG_X86_INTEL_USERCOPY
12009 + if ( n > 64 && cpu_has_xmm2)
12010 +- n = __copy_user_intel_nocache(to, from, n);
12011 ++ n = __copy_user_intel_nocache(to, from, n);
12012 + else
12013 +- __copy_user(to, from, n);
12014 ++ n = __generic_copy_from_user(to, from, n);
12015 + #else
12016 +- __copy_user(to, from, n);
12017 ++ n = __generic_copy_from_user(to, from, n);
12018 + #endif
12019 + return n;
12020 + }
12021 +@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
12022 + return n;
12023 + }
12024 + EXPORT_SYMBOL(copy_from_user);
12025 ++
12026 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12027 ++void __set_fs(mm_segment_t x, int cpu)
12028 ++{
12029 ++ unsigned long limit = x.seg;
12030 ++ __u32 a, b;
12031 ++
12032 ++ current_thread_info()->addr_limit = x;
12033 ++ if (likely(limit))
12034 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
12035 ++ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
12036 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
12037 ++}
12038 ++
12039 ++void set_fs(mm_segment_t x)
12040 ++{
12041 ++ __set_fs(x, get_cpu());
12042 ++ put_cpu_no_resched();
12043 ++}
12044 ++#else
12045 ++void set_fs(mm_segment_t x)
12046 ++{
12047 ++ current_thread_info()->addr_limit = x;
12048 ++}
12049 ++#endif
12050 ++
12051 ++EXPORT_SYMBOL(set_fs);
12052 +diff -Nurp linux-2.6.23.15/arch/i386/mach-default/setup.c linux-2.6.23.15-grsec/arch/i386/mach-default/setup.c
12053 +--- linux-2.6.23.15/arch/i386/mach-default/setup.c 2007-10-09 21:31:38.000000000 +0100
12054 ++++ linux-2.6.23.15-grsec/arch/i386/mach-default/setup.c 2008-02-11 10:37:44.000000000 +0000
12055 +@@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void)
12056 + /*
12057 + * IRQ2 is cascade interrupt to second interrupt controller
12058 + */
12059 +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
12060 ++static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
12061 +
12062 + /**
12063 + * intr_init_hook - post gate setup interrupt initialisation
12064 +diff -Nurp linux-2.6.23.15/arch/i386/mach-voyager/voyager_basic.c linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_basic.c
12065 +--- linux-2.6.23.15/arch/i386/mach-voyager/voyager_basic.c 2007-10-09 21:31:38.000000000 +0100
12066 ++++ linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_basic.c 2008-02-11 10:37:44.000000000 +0000
12067 +@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
12068 + __u8 cmos[4];
12069 + ClickMap_t *map;
12070 + unsigned long map_addr;
12071 +- unsigned long old;
12072 ++ pte_t old;
12073 +
12074 + if(region >= CLICK_ENTRIES) {
12075 + printk("Voyager: Illegal ClickMap region %d\n", region);
12076 +@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32
12077 +
12078 + /* steal page 0 for this */
12079 + old = pg0[0];
12080 +- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
12081 ++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
12082 + local_flush_tlb();
12083 + /* now clear everything out but page 0 */
12084 + map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
12085 +diff -Nurp linux-2.6.23.15/arch/i386/mach-voyager/voyager_smp.c linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_smp.c
12086 +--- linux-2.6.23.15/arch/i386/mach-voyager/voyager_smp.c 2007-10-09 21:31:38.000000000 +0100
12087 ++++ linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_smp.c 2008-02-11 10:37:44.000000000 +0000
12088 +@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
12089 + __u32 *hijack_vector;
12090 + __u32 start_phys_address = setup_trampoline();
12091 +
12092 ++#ifdef CONFIG_PAX_KERNEXEC
12093 ++ unsigned long cr0;
12094 ++#endif
12095 ++
12096 + /* There's a clever trick to this: The linux trampoline is
12097 + * compiled to begin at absolute location zero, so make the
12098 + * address zero but have the data segment selector compensate
12099 +@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
12100 +
12101 + init_gdt(cpu);
12102 + per_cpu(current_task, cpu) = idle;
12103 +- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
12104 ++
12105 ++#ifdef CONFIG_PAX_KERNEXEC
12106 ++ pax_open_kernel(cr0);
12107 ++#endif
12108 ++
12109 ++ early_gdt_descr.address = get_cpu_gdt_table(cpu);
12110 ++
12111 ++#ifdef CONFIG_PAX_KERNEXEC
12112 ++ pax_close_kernel(cr0);
12113 ++#endif
12114 ++
12115 + irq_ctx_init(cpu);
12116 +
12117 + /* Note: Don't modify initial ss override */
12118 +@@ -1276,7 +1290,7 @@ smp_local_timer_interrupt(void)
12119 + per_cpu(prof_counter, cpu);
12120 + }
12121 +
12122 +- update_process_times(user_mode_vm(get_irq_regs()));
12123 ++ update_process_times(user_mode(get_irq_regs()));
12124 + }
12125 +
12126 + if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
12127 +diff -Nurp linux-2.6.23.15/arch/i386/mm/boot_ioremap.c linux-2.6.23.15-grsec/arch/i386/mm/boot_ioremap.c
12128 +--- linux-2.6.23.15/arch/i386/mm/boot_ioremap.c 2007-10-09 21:31:38.000000000 +0100
12129 ++++ linux-2.6.23.15-grsec/arch/i386/mm/boot_ioremap.c 2008-02-11 10:37:44.000000000 +0000
12130 +@@ -7,57 +7,37 @@
12131 + * Written by Dave Hansen <haveblue@××××××.com>
12132 + */
12133 +
12134 +-
12135 +-/*
12136 +- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
12137 +- * keeps that from happenning. If anyone has a better way, I'm listening.
12138 +- *
12139 +- * boot_pte_t is defined only if this all works correctly
12140 +- */
12141 +-
12142 +-#undef CONFIG_X86_PAE
12143 + #undef CONFIG_PARAVIRT
12144 + #include <asm/page.h>
12145 + #include <asm/pgtable.h>
12146 + #include <asm/tlbflush.h>
12147 + #include <linux/init.h>
12148 + #include <linux/stddef.h>
12149 +-
12150 +-/*
12151 +- * I'm cheating here. It is known that the two boot PTE pages are
12152 +- * allocated next to each other. I'm pretending that they're just
12153 +- * one big array.
12154 +- */
12155 +-
12156 +-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
12157 +-
12158 +-static unsigned long boot_pte_index(unsigned long vaddr)
12159 +-{
12160 +- return __pa(vaddr) >> PAGE_SHIFT;
12161 +-}
12162 +-
12163 +-static inline boot_pte_t* boot_vaddr_to_pte(void *address)
12164 +-{
12165 +- boot_pte_t* boot_pg = (boot_pte_t*)pg0;
12166 +- return &boot_pg[boot_pte_index((unsigned long)address)];
12167 +-}
12168 ++#include <linux/sched.h>
12169 +
12170 + /*
12171 + * This is only for a caller who is clever enough to page-align
12172 + * phys_addr and virtual_source, and who also has a preference
12173 + * about which virtual address from which to steal ptes
12174 + */
12175 +-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
12176 +- void* virtual_source)
12177 ++static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
12178 ++ char* virtual_source)
12179 + {
12180 +- boot_pte_t* pte;
12181 +- int i;
12182 +- char *vaddr = virtual_source;
12183 ++ pgd_t *pgd;
12184 ++ pud_t *pud;
12185 ++ pmd_t *pmd;
12186 ++ pte_t* pte;
12187 ++ unsigned int i;
12188 ++ unsigned long vaddr = (unsigned long)virtual_source;
12189 ++
12190 ++ pgd = pgd_offset_k(vaddr);
12191 ++ pud = pud_offset(pgd, vaddr);
12192 ++ pmd = pmd_offset(pud, vaddr);
12193 ++ pte = pte_offset_kernel(pmd, vaddr);
12194 +
12195 +- pte = boot_vaddr_to_pte(virtual_source);
12196 + for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
12197 + set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
12198 +- __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
12199 ++ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
12200 + }
12201 + }
12202 +
12203 +diff -Nurp linux-2.6.23.15/arch/i386/mm/extable.c linux-2.6.23.15-grsec/arch/i386/mm/extable.c
12204 +--- linux-2.6.23.15/arch/i386/mm/extable.c 2007-10-09 21:31:38.000000000 +0100
12205 ++++ linux-2.6.23.15-grsec/arch/i386/mm/extable.c 2008-02-11 10:37:44.000000000 +0000
12206 +@@ -4,14 +4,63 @@
12207 +
12208 + #include <linux/module.h>
12209 + #include <linux/spinlock.h>
12210 ++#include <linux/sort.h>
12211 + #include <asm/uaccess.h>
12212 +
12213 ++/*
12214 ++ * The exception table needs to be sorted so that the binary
12215 ++ * search that we use to find entries in it works properly.
12216 ++ * This is used both for the kernel exception table and for
12217 ++ * the exception tables of modules that get loaded.
12218 ++ */
12219 ++static int cmp_ex(const void *a, const void *b)
12220 ++{
12221 ++ const struct exception_table_entry *x = a, *y = b;
12222 ++
12223 ++ /* avoid overflow */
12224 ++ if (x->insn > y->insn)
12225 ++ return 1;
12226 ++ if (x->insn < y->insn)
12227 ++ return -1;
12228 ++ return 0;
12229 ++}
12230 ++
12231 ++static void swap_ex(void *a, void *b, int size)
12232 ++{
12233 ++ struct exception_table_entry t, *x = a, *y = b;
12234 ++
12235 ++#ifdef CONFIG_PAX_KERNEXEC
12236 ++ unsigned long cr0;
12237 ++#endif
12238 ++
12239 ++ t = *x;
12240 ++
12241 ++#ifdef CONFIG_PAX_KERNEXEC
12242 ++ pax_open_kernel(cr0);
12243 ++#endif
12244 ++
12245 ++ *x = *y;
12246 ++ *y = t;
12247 ++
12248 ++#ifdef CONFIG_PAX_KERNEXEC
12249 ++ pax_close_kernel(cr0);
12250 ++#endif
12251 ++
12252 ++}
12253 ++
12254 ++void sort_extable(struct exception_table_entry *start,
12255 ++ struct exception_table_entry *finish)
12256 ++{
12257 ++ sort(start, finish - start, sizeof(struct exception_table_entry),
12258 ++ cmp_ex, swap_ex);
12259 ++}
12260 ++
12261 + int fixup_exception(struct pt_regs *regs)
12262 + {
12263 + const struct exception_table_entry *fixup;
12264 +
12265 + #ifdef CONFIG_PNPBIOS
12266 +- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
12267 ++ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
12268 + {
12269 + extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
12270 + extern u32 pnp_bios_is_utter_crap;
12271 +diff -Nurp linux-2.6.23.15/arch/i386/mm/fault.c linux-2.6.23.15-grsec/arch/i386/mm/fault.c
12272 +--- linux-2.6.23.15/arch/i386/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
12273 ++++ linux-2.6.23.15-grsec/arch/i386/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
12274 +@@ -25,10 +25,14 @@
12275 + #include <linux/kprobes.h>
12276 + #include <linux/uaccess.h>
12277 + #include <linux/kdebug.h>
12278 ++#include <linux/unistd.h>
12279 ++#include <linux/compiler.h>
12280 ++#include <linux/binfmts.h>
12281 +
12282 + #include <asm/system.h>
12283 + #include <asm/desc.h>
12284 + #include <asm/segment.h>
12285 ++#include <asm/tlbflush.h>
12286 +
12287 + extern void die(const char *,struct pt_regs *,long);
12288 +
12289 +@@ -79,7 +83,8 @@ static inline unsigned long get_segment_
12290 + {
12291 + unsigned long eip = regs->eip;
12292 + unsigned seg = regs->xcs & 0xffff;
12293 +- u32 seg_ar, seg_limit, base, *desc;
12294 ++ u32 seg_ar, seg_limit, base;
12295 ++ struct desc_struct *desc;
12296 +
12297 + /* Unlikely, but must come before segment checks. */
12298 + if (unlikely(regs->eflags & VM_MASK)) {
12299 +@@ -93,7 +98,7 @@ static inline unsigned long get_segment_
12300 +
12301 + /* By far the most common cases. */
12302 + if (likely(SEGMENT_IS_FLAT_CODE(seg)))
12303 +- return eip;
12304 ++ return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
12305 +
12306 + /* Check the segment exists, is within the current LDT/GDT size,
12307 + that kernel/user (ring 0..3) has the appropriate privilege,
12308 +@@ -111,16 +116,19 @@ static inline unsigned long get_segment_
12309 + if (seg & (1<<2)) {
12310 + /* Must lock the LDT while reading it. */
12311 + down(&current->mm->context.sem);
12312 +- desc = current->mm->context.ldt;
12313 +- desc = (void *)desc + (seg & ~7);
12314 ++ if ((seg >> 3) >= current->mm->context.size) {
12315 ++ up(&current->mm->context.sem);
12316 ++ *eip_limit = 0;
12317 ++ return 1; /* So that returned eip > *eip_limit. */
12318 ++ }
12319 ++ desc = &current->mm->context.ldt[seg >> 3];
12320 + } else {
12321 + /* Must disable preemption while reading the GDT. */
12322 +- desc = (u32 *)get_cpu_gdt_table(get_cpu());
12323 +- desc = (void *)desc + (seg & ~7);
12324 ++ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
12325 + }
12326 +
12327 + /* Decode the code segment base from the descriptor */
12328 +- base = get_desc_base((unsigned long *)desc);
12329 ++ base = get_desc_base(desc);
12330 +
12331 + if (seg & (1<<2)) {
12332 + up(&current->mm->context.sem);
12333 +@@ -221,6 +229,30 @@ static noinline void force_sig_info_faul
12334 +
12335 + fastcall void do_invalid_op(struct pt_regs *, unsigned long);
12336 +
12337 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12338 ++static int pax_handle_fetch_fault(struct pt_regs *regs);
12339 ++#endif
12340 ++
12341 ++#ifdef CONFIG_PAX_PAGEEXEC
12342 ++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
12343 ++{
12344 ++ pgd_t *pgd;
12345 ++ pud_t *pud;
12346 ++ pmd_t *pmd;
12347 ++
12348 ++ pgd = pgd_offset(mm, address);
12349 ++ if (!pgd_present(*pgd))
12350 ++ return NULL;
12351 ++ pud = pud_offset(pgd, address);
12352 ++ if (!pud_present(*pud))
12353 ++ return NULL;
12354 ++ pmd = pmd_offset(pud, address);
12355 ++ if (!pmd_present(*pmd))
12356 ++ return NULL;
12357 ++ return pmd;
12358 ++}
12359 ++#endif
12360 ++
12361 + static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
12362 + {
12363 + unsigned index = pgd_index(address);
12364 +@@ -304,14 +336,21 @@ fastcall void __kprobes do_page_fault(st
12365 + struct task_struct *tsk;
12366 + struct mm_struct *mm;
12367 + struct vm_area_struct * vma;
12368 +- unsigned long address;
12369 + int write, si_code;
12370 + int fault;
12371 ++ pte_t *pte;
12372 ++
12373 ++#ifdef CONFIG_PAX_PAGEEXEC
12374 ++ pmd_t *pmd;
12375 ++ spinlock_t *ptl;
12376 ++ unsigned char pte_mask;
12377 ++#endif
12378 +
12379 + /* get the address */
12380 +- address = read_cr2();
12381 ++ const unsigned long address = read_cr2();
12382 +
12383 + tsk = current;
12384 ++ mm = tsk->mm;
12385 +
12386 + si_code = SEGV_MAPERR;
12387 +
12388 +@@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st
12389 + if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
12390 + local_irq_enable();
12391 +
12392 +- mm = tsk->mm;
12393 +-
12394 + /*
12395 + * If we're in an interrupt, have no user context or are running in an
12396 + * atomic region then we must not take the fault..
12397 + */
12398 + if (in_atomic() || !mm)
12399 +- goto bad_area_nosemaphore;
12400 ++ goto bad_area_nopax;
12401 +
12402 + /* When running in the kernel we expect faults to occur only to
12403 + * addresses in user space. All other faults represent errors in the
12404 +@@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st
12405 + if (!down_read_trylock(&mm->mmap_sem)) {
12406 + if ((error_code & 4) == 0 &&
12407 + !search_exception_tables(regs->eip))
12408 +- goto bad_area_nosemaphore;
12409 ++ goto bad_area_nopax;
12410 + down_read(&mm->mmap_sem);
12411 + }
12412 +
12413 ++#ifdef CONFIG_PAX_PAGEEXEC
12414 ++ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
12415 ++ !(mm->pax_flags & MF_PAX_PAGEEXEC))
12416 ++ goto not_pax_fault;
12417 ++
12418 ++ /* PaX: it's our fault, let's handle it if we can */
12419 ++
12420 ++ /* PaX: take a look at read faults before acquiring any locks */
12421 ++ if (unlikely(!(error_code & 2) && (regs->eip == address))) {
12422 ++ /* instruction fetch attempt from a protected page in user mode */
12423 ++ up_read(&mm->mmap_sem);
12424 ++
12425 ++#ifdef CONFIG_PAX_EMUTRAMP
12426 ++ switch (pax_handle_fetch_fault(regs)) {
12427 ++ case 2:
12428 ++ return;
12429 ++ }
12430 ++#endif
12431 ++
12432 ++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
12433 ++ do_exit(SIGKILL);
12434 ++ }
12435 ++
12436 ++ pmd = pax_get_pmd(mm, address);
12437 ++ if (unlikely(!pmd))
12438 ++ goto not_pax_fault;
12439 ++
12440 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
12441 ++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
12442 ++ pte_unmap_unlock(pte, ptl);
12443 ++ goto not_pax_fault;
12444 ++ }
12445 ++
12446 ++ if (unlikely((error_code & 2) && !pte_write(*pte))) {
12447 ++ /* write attempt to a protected page in user mode */
12448 ++ pte_unmap_unlock(pte, ptl);
12449 ++ goto not_pax_fault;
12450 ++ }
12451 ++
12452 ++#ifdef CONFIG_SMP
12453 ++ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
12454 ++#else
12455 ++ if (likely(address > get_limit(regs->xcs)))
12456 ++#endif
12457 ++ {
12458 ++ set_pte(pte, pte_mkread(*pte));
12459 ++ __flush_tlb_one(address);
12460 ++ pte_unmap_unlock(pte, ptl);
12461 ++ up_read(&mm->mmap_sem);
12462 ++ return;
12463 ++ }
12464 ++
12465 ++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
12466 ++
12467 ++ /*
12468 ++ * PaX: fill DTLB with user rights and retry
12469 ++ */
12470 ++ __asm__ __volatile__ (
12471 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12472 ++ "movw %w4,%%es\n"
12473 ++#endif
12474 ++ "orb %2,(%1)\n"
12475 ++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
12476 ++/*
12477 ++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
12478 ++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
12479 ++ * page fault when examined during a TLB load attempt. this is true not only
12480 ++ * for PTEs holding a non-present entry but also present entries that will
12481 ++ * raise a page fault (such as those set up by PaX, or the copy-on-write
12482 ++ * mechanism). in effect it means that we do *not* need to flush the TLBs
12483 ++ * for our target pages since their PTEs are simply not in the TLBs at all.
12484 ++
12485 ++ * the best thing in omitting it is that we gain around 15-20% speed in the
12486 ++ * fast path of the page fault handler and can get rid of tracing since we
12487 ++ * can no longer flush unintended entries.
12488 ++ */
12489 ++ "invlpg (%0)\n"
12490 ++#endif
12491 ++ "testb $0,%%es:(%0)\n"
12492 ++ "xorb %3,(%1)\n"
12493 ++#ifdef CONFIG_PAX_MEMORY_UDEREF
12494 ++ "pushl %%ss\n"
12495 ++ "popl %%es\n"
12496 ++#endif
12497 ++ :
12498 ++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
12499 ++ : "memory", "cc");
12500 ++ pte_unmap_unlock(pte, ptl);
12501 ++ up_read(&mm->mmap_sem);
12502 ++ return;
12503 ++
12504 ++not_pax_fault:
12505 ++#endif
12506 ++
12507 + vma = find_vma(mm, address);
12508 + if (!vma)
12509 + goto bad_area;
12510 +@@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st
12511 + if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
12512 + goto bad_area;
12513 + }
12514 ++
12515 ++#ifdef CONFIG_PAX_SEGMEXEC
12516 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
12517 ++ goto bad_area;
12518 ++#endif
12519 ++
12520 + if (expand_stack(vma, address))
12521 + goto bad_area;
12522 + /*
12523 +@@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st
12524 + good_area:
12525 + si_code = SEGV_ACCERR;
12526 + write = 0;
12527 ++ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
12528 ++ goto bad_area;
12529 + switch (error_code & 3) {
12530 + default: /* 3: write, present */
12531 + /* fall through */
12532 +@@ -458,6 +597,41 @@ bad_area:
12533 + up_read(&mm->mmap_sem);
12534 +
12535 + bad_area_nosemaphore:
12536 ++
12537 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12538 ++ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
12539 ++ /*
12540 ++ * It's possible to have interrupts off here.
12541 ++ */
12542 ++ local_irq_enable();
12543 ++
12544 ++#ifdef CONFIG_PAX_PAGEEXEC
12545 ++ if ((nx_enabled && (error_code & 16)) ||
12546 ++ ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address))) {
12547 ++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
12548 ++ do_exit(SIGKILL);
12549 ++ }
12550 ++#endif
12551 ++
12552 ++#ifdef CONFIG_PAX_SEGMEXEC
12553 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
12554 ++
12555 ++#ifdef CONFIG_PAX_EMUTRAMP
12556 ++ switch (pax_handle_fetch_fault(regs)) {
12557 ++ case 2:
12558 ++ return;
12559 ++ }
12560 ++#endif
12561 ++
12562 ++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
12563 ++ do_exit(SIGKILL);
12564 ++ }
12565 ++#endif
12566 ++
12567 ++ }
12568 ++#endif
12569 ++
12570 ++bad_area_nopax:
12571 + /* User mode accesses just cause a SIGSEGV */
12572 + if (error_code & 4) {
12573 + /*
12574 +@@ -495,7 +669,7 @@ bad_area_nosemaphore:
12575 + if (boot_cpu_data.f00f_bug) {
12576 + unsigned long nr;
12577 +
12578 +- nr = (address - idt_descr.address) >> 3;
12579 ++ nr = (address - (unsigned long)idt_descr.address) >> 3;
12580 +
12581 + if (nr == 6) {
12582 + do_invalid_op(regs, 0);
12583 +@@ -528,18 +702,34 @@ no_context:
12584 + __typeof__(pte_val(__pte(0))) page;
12585 +
12586 + #ifdef CONFIG_X86_PAE
12587 +- if (error_code & 16) {
12588 +- pte_t *pte = lookup_address(address);
12589 ++ if (nx_enabled && (error_code & 16)) {
12590 ++ pte = lookup_address(address);
12591 +
12592 + if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
12593 + printk(KERN_CRIT "kernel tried to execute "
12594 + "NX-protected page - exploit attempt? "
12595 +- "(uid: %d)\n", current->uid);
12596 ++ "(uid: %d, task: %s, pid: %d)\n",
12597 ++ current->uid, current->comm, current->pid);
12598 + }
12599 + #endif
12600 + if (address < PAGE_SIZE)
12601 + printk(KERN_ALERT "BUG: unable to handle kernel NULL "
12602 + "pointer dereference");
12603 ++
12604 ++#ifdef CONFIG_PAX_KERNEXEC
12605 ++#ifdef CONFIG_MODULES
12606 ++ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
12607 ++#else
12608 ++ else if (init_mm.start_code <= address && address < init_mm.end_code)
12609 ++#endif
12610 ++ if (tsk->signal->curr_ip)
12611 ++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
12612 ++ NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
12613 ++ else
12614 ++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
12615 ++ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
12616 ++#endif
12617 ++
12618 + else
12619 + printk(KERN_ALERT "BUG: unable to handle kernel paging"
12620 + " request");
12621 +@@ -570,7 +760,7 @@ no_context:
12622 + * it's allocated already.
12623 + */
12624 + if ((page >> PAGE_SHIFT) < max_low_pfn
12625 +- && (page & _PAGE_PRESENT)) {
12626 ++ && (page & (_PAGE_PRESENT | _PAGE_PSE)) == _PAGE_PRESENT) {
12627 + page &= PAGE_MASK;
12628 + page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
12629 + & (PTRS_PER_PTE - 1)];
12630 +@@ -655,3 +845,92 @@ void vmalloc_sync_all(void)
12631 + start = address + PGDIR_SIZE;
12632 + }
12633 + }
12634 ++
12635 ++#ifdef CONFIG_PAX_EMUTRAMP
12636 ++/*
12637 ++ * PaX: decide what to do with offenders (regs->eip = fault address)
12638 ++ *
12639 ++ * returns 1 when task should be killed
12640 ++ * 2 when gcc trampoline was detected
12641 ++ */
12642 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
12643 ++{
12644 ++ int err;
12645 ++
12646 ++ if (regs->eflags & X86_EFLAGS_VM)
12647 ++ return 1;
12648 ++
12649 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
12650 ++ return 1;
12651 ++
12652 ++ do { /* PaX: gcc trampoline emulation #1 */
12653 ++ unsigned char mov1, mov2;
12654 ++ unsigned short jmp;
12655 ++ unsigned long addr1, addr2;
12656 ++
12657 ++ err = get_user(mov1, (unsigned char __user *)regs->eip);
12658 ++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
12659 ++ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
12660 ++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
12661 ++ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
12662 ++
12663 ++ if (err)
12664 ++ break;
12665 ++
12666 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
12667 ++ regs->ecx = addr1;
12668 ++ regs->eax = addr2;
12669 ++ regs->eip = addr2;
12670 ++ return 2;
12671 ++ }
12672 ++ } while (0);
12673 ++
12674 ++ do { /* PaX: gcc trampoline emulation #2 */
12675 ++ unsigned char mov, jmp;
12676 ++ unsigned long addr1, addr2;
12677 ++
12678 ++ err = get_user(mov, (unsigned char __user *)regs->eip);
12679 ++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
12680 ++ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
12681 ++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
12682 ++
12683 ++ if (err)
12684 ++ break;
12685 ++
12686 ++ if (mov == 0xB9 && jmp == 0xE9) {
12687 ++ regs->ecx = addr1;
12688 ++ regs->eip += addr2 + 10;
12689 ++ return 2;
12690 ++ }
12691 ++ } while (0);
12692 ++
12693 ++ return 1; /* PaX in action */
12694 ++}
12695 ++#endif
12696 ++
12697 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12698 ++void pax_report_insns(void *pc, void *sp)
12699 ++{
12700 ++ long i;
12701 ++
12702 ++ printk(KERN_ERR "PAX: bytes at PC: ");
12703 ++ for (i = 0; i < 20; i++) {
12704 ++ unsigned char c;
12705 ++ if (get_user(c, (unsigned char __user *)pc+i))
12706 ++ printk("?? ");
12707 ++ else
12708 ++ printk("%02x ", c);
12709 ++ }
12710 ++ printk("\n");
12711 ++
12712 ++ printk(KERN_ERR "PAX: bytes at SP-4: ");
12713 ++ for (i = -1; i < 20; i++) {
12714 ++ unsigned long c;
12715 ++ if (get_user(c, (unsigned long __user *)sp+i))
12716 ++ printk("???????? ");
12717 ++ else
12718 ++ printk("%08lx ", c);
12719 ++ }
12720 ++ printk("\n");
12721 ++}
12722 ++#endif
12723 +diff -Nurp linux-2.6.23.15/arch/i386/mm/hugetlbpage.c linux-2.6.23.15-grsec/arch/i386/mm/hugetlbpage.c
12724 +--- linux-2.6.23.15/arch/i386/mm/hugetlbpage.c 2007-10-09 21:31:38.000000000 +0100
12725 ++++ linux-2.6.23.15-grsec/arch/i386/mm/hugetlbpage.c 2008-02-11 10:37:44.000000000 +0000
12726 +@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
12727 + {
12728 + struct mm_struct *mm = current->mm;
12729 + struct vm_area_struct *vma;
12730 +- unsigned long start_addr;
12731 ++ unsigned long start_addr, task_size = TASK_SIZE;
12732 ++
12733 ++#ifdef CONFIG_PAX_SEGMEXEC
12734 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12735 ++ task_size = SEGMEXEC_TASK_SIZE;
12736 ++#endif
12737 +
12738 + if (len > mm->cached_hole_size) {
12739 +- start_addr = mm->free_area_cache;
12740 ++ start_addr = mm->free_area_cache;
12741 + } else {
12742 +- start_addr = TASK_UNMAPPED_BASE;
12743 +- mm->cached_hole_size = 0;
12744 ++ start_addr = mm->mmap_base;
12745 ++ mm->cached_hole_size = 0;
12746 + }
12747 +
12748 + full_search:
12749 +@@ -243,13 +248,13 @@ full_search:
12750 +
12751 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
12752 + /* At this point: (!vma || addr < vma->vm_end). */
12753 +- if (TASK_SIZE - len < addr) {
12754 ++ if (task_size - len < addr) {
12755 + /*
12756 + * Start a new search - just in case we missed
12757 + * some holes.
12758 + */
12759 +- if (start_addr != TASK_UNMAPPED_BASE) {
12760 +- start_addr = TASK_UNMAPPED_BASE;
12761 ++ if (start_addr != mm->mmap_base) {
12762 ++ start_addr = mm->mmap_base;
12763 + mm->cached_hole_size = 0;
12764 + goto full_search;
12765 + }
12766 +@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
12767 + {
12768 + struct mm_struct *mm = current->mm;
12769 + struct vm_area_struct *vma, *prev_vma;
12770 +- unsigned long base = mm->mmap_base, addr = addr0;
12771 ++ unsigned long base = mm->mmap_base, addr;
12772 + unsigned long largest_hole = mm->cached_hole_size;
12773 +- int first_time = 1;
12774 +
12775 + /* don't allow allocations above current base */
12776 + if (mm->free_area_cache > base)
12777 +@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
12778 + largest_hole = 0;
12779 + mm->free_area_cache = base;
12780 + }
12781 +-try_again:
12782 ++
12783 + /* make sure it can fit in the remaining address space */
12784 + if (mm->free_area_cache < len)
12785 + goto fail;
12786 +@@ -325,22 +329,26 @@ try_again:
12787 +
12788 + fail:
12789 + /*
12790 +- * if hint left us with no space for the requested
12791 +- * mapping then try again:
12792 +- */
12793 +- if (first_time) {
12794 +- mm->free_area_cache = base;
12795 +- largest_hole = 0;
12796 +- first_time = 0;
12797 +- goto try_again;
12798 +- }
12799 +- /*
12800 + * A failed mmap() very likely causes application failure,
12801 + * so fall back to the bottom-up function here. This scenario
12802 + * can happen with large stack limits and large mmap()
12803 + * allocations.
12804 + */
12805 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
12806 ++
12807 ++#ifdef CONFIG_PAX_SEGMEXEC
12808 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12809 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
12810 ++ else
12811 ++#endif
12812 ++
12813 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
12814 ++
12815 ++#ifdef CONFIG_PAX_RANDMMAP
12816 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
12817 ++ mm->mmap_base += mm->delta_mmap;
12818 ++#endif
12819 ++
12820 ++ mm->free_area_cache = mm->mmap_base;
12821 + mm->cached_hole_size = ~0UL;
12822 + addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
12823 + len, pgoff, flags);
12824 +@@ -348,6 +356,7 @@ fail:
12825 + /*
12826 + * Restore the topdown base:
12827 + */
12828 ++ mm->mmap_base = base;
12829 + mm->free_area_cache = base;
12830 + mm->cached_hole_size = ~0UL;
12831 +
12832 +@@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f
12833 + {
12834 + struct mm_struct *mm = current->mm;
12835 + struct vm_area_struct *vma;
12836 ++ unsigned long task_size = TASK_SIZE;
12837 +
12838 + if (len & ~HPAGE_MASK)
12839 + return -EINVAL;
12840 +- if (len > TASK_SIZE)
12841 ++
12842 ++#ifdef CONFIG_PAX_SEGMEXEC
12843 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
12844 ++ task_size = SEGMEXEC_TASK_SIZE;
12845 ++#endif
12846 ++
12847 ++ if (len > task_size)
12848 + return -ENOMEM;
12849 +
12850 + if (flags & MAP_FIXED) {
12851 +@@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f
12852 + if (addr) {
12853 + addr = ALIGN(addr, HPAGE_SIZE);
12854 + vma = find_vma(mm, addr);
12855 +- if (TASK_SIZE - len >= addr &&
12856 ++ if (task_size - len >= addr &&
12857 + (!vma || addr + len <= vma->vm_start))
12858 + return addr;
12859 + }
12860 +diff -Nurp linux-2.6.23.15/arch/i386/mm/init.c linux-2.6.23.15-grsec/arch/i386/mm/init.c
12861 +--- linux-2.6.23.15/arch/i386/mm/init.c 2007-10-09 21:31:38.000000000 +0100
12862 ++++ linux-2.6.23.15-grsec/arch/i386/mm/init.c 2008-02-11 10:37:44.000000000 +0000
12863 +@@ -44,6 +44,7 @@
12864 + #include <asm/tlbflush.h>
12865 + #include <asm/sections.h>
12866 + #include <asm/paravirt.h>
12867 ++#include <asm/desc.h>
12868 +
12869 + unsigned int __VMALLOC_RESERVE = 128 << 20;
12870 +
12871 +@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
12872 + static int noinline do_test_wp_bit(void);
12873 +
12874 + /*
12875 +- * Creates a middle page table and puts a pointer to it in the
12876 +- * given global directory entry. This only returns the gd entry
12877 +- * in non-PAE compilation mode, since the middle layer is folded.
12878 +- */
12879 +-static pmd_t * __init one_md_table_init(pgd_t *pgd)
12880 +-{
12881 +- pud_t *pud;
12882 +- pmd_t *pmd_table;
12883 +-
12884 +-#ifdef CONFIG_X86_PAE
12885 +- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
12886 +- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
12887 +-
12888 +- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
12889 +- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
12890 +- pud = pud_offset(pgd, 0);
12891 +- if (pmd_table != pmd_offset(pud, 0))
12892 +- BUG();
12893 +- }
12894 +-#endif
12895 +- pud = pud_offset(pgd, 0);
12896 +- pmd_table = pmd_offset(pud, 0);
12897 +- return pmd_table;
12898 +-}
12899 +-
12900 +-/*
12901 + * Create a page table and place a pointer to it in a middle page
12902 + * directory entry.
12903 + */
12904 +@@ -88,7 +63,11 @@ static pte_t * __init one_page_table_ini
12905 + pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
12906 +
12907 + paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT);
12908 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12909 ++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
12910 ++#else
12911 + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
12912 ++#endif
12913 + BUG_ON(page_table != pte_offset_kernel(pmd, 0));
12914 + }
12915 +
12916 +@@ -109,6 +88,7 @@ static pte_t * __init one_page_table_ini
12917 + static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
12918 + {
12919 + pgd_t *pgd;
12920 ++ pud_t *pud;
12921 + pmd_t *pmd;
12922 + int pgd_idx, pmd_idx;
12923 + unsigned long vaddr;
12924 +@@ -119,8 +99,13 @@ static void __init page_table_range_init
12925 + pgd = pgd_base + pgd_idx;
12926 +
12927 + for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
12928 +- pmd = one_md_table_init(pgd);
12929 +- pmd = pmd + pmd_index(vaddr);
12930 ++ pud = pud_offset(pgd, vaddr);
12931 ++ pmd = pmd_offset(pud, vaddr);
12932 ++
12933 ++#ifdef CONFIG_X86_PAE
12934 ++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
12935 ++#endif
12936 ++
12937 + for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
12938 + one_page_table_init(pmd);
12939 +
12940 +@@ -130,11 +115,23 @@ static void __init page_table_range_init
12941 + }
12942 + }
12943 +
12944 +-static inline int is_kernel_text(unsigned long addr)
12945 ++static inline int is_kernel_text(unsigned long start, unsigned long end)
12946 + {
12947 +- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
12948 +- return 1;
12949 +- return 0;
12950 ++ unsigned long etext;
12951 ++
12952 ++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
12953 ++ etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
12954 ++#else
12955 ++ etext = (unsigned long)&_etext;
12956 ++#endif
12957 ++
12958 ++ if ((start > etext + __KERNEL_TEXT_OFFSET ||
12959 ++ end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
12960 ++ (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
12961 ++ end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET) &&
12962 ++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
12963 ++ return 0;
12964 ++ return 1;
12965 + }
12966 +
12967 + /*
12968 +@@ -146,25 +143,29 @@ static void __init kernel_physical_mappi
12969 + {
12970 + unsigned long pfn;
12971 + pgd_t *pgd;
12972 ++ pud_t *pud;
12973 + pmd_t *pmd;
12974 + pte_t *pte;
12975 +- int pgd_idx, pmd_idx, pte_ofs;
12976 ++ unsigned int pgd_idx, pmd_idx, pte_ofs;
12977 +
12978 + pgd_idx = pgd_index(PAGE_OFFSET);
12979 + pgd = pgd_base + pgd_idx;
12980 + pfn = 0;
12981 +
12982 +- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
12983 +- pmd = one_md_table_init(pgd);
12984 +- if (pfn >= max_low_pfn)
12985 +- continue;
12986 ++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
12987 ++ pud = pud_offset(pgd, 0);
12988 ++ pmd = pmd_offset(pud, 0);
12989 ++
12990 ++#ifdef CONFIG_X86_PAE
12991 ++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
12992 ++#endif
12993 ++
12994 + for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
12995 +- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
12996 ++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
12997 +
12998 + /* Map with big pages if possible, otherwise create normal page tables. */
12999 +- if (cpu_has_pse) {
13000 +- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
13001 +- if (is_kernel_text(address) || is_kernel_text(address2))
13002 ++ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
13003 ++ if (is_kernel_text(address, address + PMD_SIZE))
13004 + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
13005 + else
13006 + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
13007 +@@ -176,7 +177,7 @@ static void __init kernel_physical_mappi
13008 + for (pte_ofs = 0;
13009 + pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
13010 + pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
13011 +- if (is_kernel_text(address))
13012 ++ if (is_kernel_text(address, address + PAGE_SIZE))
13013 + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
13014 + else
13015 + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
13016 +@@ -326,9 +327,9 @@ static void __init set_highmem_pages_ini
13017 + #define set_highmem_pages_init(bad_ppro) do { } while (0)
13018 + #endif /* CONFIG_HIGHMEM */
13019 +
13020 +-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
13021 ++unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL;
13022 + EXPORT_SYMBOL(__PAGE_KERNEL);
13023 +-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
13024 ++unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
13025 +
13026 + #ifdef CONFIG_NUMA
13027 + extern void __init remap_numa_kva(void);
13028 +@@ -339,26 +340,10 @@ extern void __init remap_numa_kva(void);
13029 + void __init native_pagetable_setup_start(pgd_t *base)
13030 + {
13031 + #ifdef CONFIG_X86_PAE
13032 +- int i;
13033 ++ unsigned int i;
13034 +
13035 +- /*
13036 +- * Init entries of the first-level page table to the
13037 +- * zero page, if they haven't already been set up.
13038 +- *
13039 +- * In a normal native boot, we'll be running on a
13040 +- * pagetable rooted in swapper_pg_dir, but not in PAE
13041 +- * mode, so this will end up clobbering the mappings
13042 +- * for the lower 24Mbytes of the address space,
13043 +- * without affecting the kernel address space.
13044 +- */
13045 +- for (i = 0; i < USER_PTRS_PER_PGD; i++)
13046 +- set_pgd(&base[i],
13047 +- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
13048 +-
13049 +- /* Make sure kernel address space is empty so that a pagetable
13050 +- will be allocated for it. */
13051 +- memset(&base[USER_PTRS_PER_PGD], 0,
13052 +- KERNEL_PGD_PTRS * sizeof(pgd_t));
13053 ++ for (i = 0; i < PTRS_PER_PGD; i++)
13054 ++ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
13055 + #else
13056 + paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
13057 + #endif
13058 +@@ -366,16 +351,6 @@ void __init native_pagetable_setup_start
13059 +
13060 + void __init native_pagetable_setup_done(pgd_t *base)
13061 + {
13062 +-#ifdef CONFIG_X86_PAE
13063 +- /*
13064 +- * Add low memory identity-mappings - SMP needs it when
13065 +- * starting up on an AP from real-mode. In the non-PAE
13066 +- * case we already have these mappings through head.S.
13067 +- * All user-space mappings are explicitly cleared after
13068 +- * SMP startup.
13069 +- */
13070 +- set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
13071 +-#endif
13072 + }
13073 +
13074 + /*
13075 +@@ -437,12 +412,12 @@ static void __init pagetable_init (void)
13076 + * Swap suspend & friends need this for resume because things like the intel-agp
13077 + * driver might have split up a kernel 4MB mapping.
13078 + */
13079 +-char __nosavedata swsusp_pg_dir[PAGE_SIZE]
13080 ++pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
13081 + __attribute__ ((aligned (PAGE_SIZE)));
13082 +
13083 + static inline void save_pg_dir(void)
13084 + {
13085 +- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
13086 ++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
13087 + }
13088 + #else
13089 + static inline void save_pg_dir(void)
13090 +@@ -471,12 +446,11 @@ void zap_low_mappings (void)
13091 + flush_tlb_all();
13092 + }
13093 +
13094 +-int nx_enabled = 0;
13095 ++int nx_enabled;
13096 +
13097 + #ifdef CONFIG_X86_PAE
13098 +
13099 +-static int disable_nx __initdata = 0;
13100 +-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
13101 ++u64 __supported_pte_mask __read_only = ~_PAGE_NX;
13102 + EXPORT_SYMBOL_GPL(__supported_pte_mask);
13103 +
13104 + /*
13105 +@@ -487,36 +461,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask);
13106 + * on Enable
13107 + * off Disable
13108 + */
13109 ++#if !defined(CONFIG_PAX_PAGEEXEC)
13110 + static int __init noexec_setup(char *str)
13111 + {
13112 + if (!str || !strcmp(str, "on")) {
13113 +- if (cpu_has_nx) {
13114 +- __supported_pte_mask |= _PAGE_NX;
13115 +- disable_nx = 0;
13116 +- }
13117 ++ if (cpu_has_nx)
13118 ++ nx_enabled = 1;
13119 + } else if (!strcmp(str,"off")) {
13120 +- disable_nx = 1;
13121 +- __supported_pte_mask &= ~_PAGE_NX;
13122 ++ nx_enabled = 0;
13123 + } else
13124 + return -EINVAL;
13125 +
13126 + return 0;
13127 + }
13128 + early_param("noexec", noexec_setup);
13129 ++#endif
13130 +
13131 + static void __init set_nx(void)
13132 + {
13133 +- unsigned int v[4], l, h;
13134 ++ if (!nx_enabled && cpu_has_nx) {
13135 ++ unsigned l, h;
13136 +
13137 +- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
13138 +- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
13139 +- if ((v[3] & (1 << 20)) && !disable_nx) {
13140 +- rdmsr(MSR_EFER, l, h);
13141 +- l |= EFER_NX;
13142 +- wrmsr(MSR_EFER, l, h);
13143 +- nx_enabled = 1;
13144 +- __supported_pte_mask |= _PAGE_NX;
13145 +- }
13146 ++ __supported_pte_mask &= ~_PAGE_NX;
13147 ++ rdmsr(MSR_EFER, l, h);
13148 ++ l &= ~EFER_NX;
13149 ++ wrmsr(MSR_EFER, l, h);
13150 + }
13151 + }
13152 +
13153 +@@ -569,14 +538,6 @@ void __init paging_init(void)
13154 +
13155 + load_cr3(swapper_pg_dir);
13156 +
13157 +-#ifdef CONFIG_X86_PAE
13158 +- /*
13159 +- * We will bail out later - printk doesn't work right now so
13160 +- * the user would just see a hanging kernel.
13161 +- */
13162 +- if (cpu_has_pae)
13163 +- set_in_cr4(X86_CR4_PAE);
13164 +-#endif
13165 + __flush_tlb_all();
13166 +
13167 + kmap_init();
13168 +@@ -647,7 +608,7 @@ void __init mem_init(void)
13169 + set_highmem_pages_init(bad_ppro);
13170 +
13171 + codesize = (unsigned long) &_etext - (unsigned long) &_text;
13172 +- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
13173 ++ datasize = (unsigned long) &_edata - (unsigned long) &_data;
13174 + initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
13175 +
13176 + kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
13177 +@@ -692,10 +653,10 @@ void __init mem_init(void)
13178 + (unsigned long)&__init_begin, (unsigned long)&__init_end,
13179 + ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
13180 +
13181 +- (unsigned long)&_etext, (unsigned long)&_edata,
13182 +- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
13183 ++ (unsigned long)&_data, (unsigned long)&_edata,
13184 ++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
13185 +
13186 +- (unsigned long)&_text, (unsigned long)&_etext,
13187 ++ (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
13188 + ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
13189 +
13190 + #ifdef CONFIG_HIGHMEM
13191 +@@ -706,10 +667,6 @@ void __init mem_init(void)
13192 + BUG_ON((unsigned long)high_memory > VMALLOC_START);
13193 + #endif /* double-sanity-check paranoia */
13194 +
13195 +-#ifdef CONFIG_X86_PAE
13196 +- if (!cpu_has_pae)
13197 +- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
13198 +-#endif
13199 + if (boot_cpu_data.wp_works_ok < 0)
13200 + test_wp_bit();
13201 +
13202 +@@ -844,6 +801,38 @@ void free_init_pages(char *what, unsigne
13203 +
13204 + void free_initmem(void)
13205 + {
13206 ++
13207 ++#ifdef CONFIG_PAX_KERNEXEC
13208 ++ /* PaX: limit KERNEL_CS to actual size */
13209 ++ unsigned long addr, limit;
13210 ++ __u32 a, b;
13211 ++ int cpu;
13212 ++ pgd_t *pgd;
13213 ++ pud_t *pud;
13214 ++ pmd_t *pmd;
13215 ++
13216 ++#ifdef CONFIG_MODULES
13217 ++ limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
13218 ++#else
13219 ++ limit = (unsigned long)&_etext;
13220 ++#endif
13221 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
13222 ++
13223 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13224 ++ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
13225 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
13226 ++ }
13227 ++
13228 ++ /* PaX: make KERNEL_CS read-only */
13229 ++ for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
13230 ++ pgd = pgd_offset_k(addr);
13231 ++ pud = pud_offset(pgd, addr);
13232 ++ pmd = pmd_offset(pud, addr);
13233 ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
13234 ++ }
13235 ++ flush_tlb_all();
13236 ++#endif
13237 ++
13238 + free_init_pages("unused kernel memory",
13239 + (unsigned long)(&__init_begin),
13240 + (unsigned long)(&__init_end));
13241 +diff -Nurp linux-2.6.23.15/arch/i386/mm/mmap.c linux-2.6.23.15-grsec/arch/i386/mm/mmap.c
13242 +--- linux-2.6.23.15/arch/i386/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
13243 ++++ linux-2.6.23.15-grsec/arch/i386/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
13244 +@@ -35,12 +35,18 @@
13245 + * Leave an at least ~128 MB hole.
13246 + */
13247 + #define MIN_GAP (128*1024*1024)
13248 +-#define MAX_GAP (TASK_SIZE/6*5)
13249 ++#define MAX_GAP (task_size/6*5)
13250 +
13251 + static inline unsigned long mmap_base(struct mm_struct *mm)
13252 + {
13253 + unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
13254 + unsigned long random_factor = 0;
13255 ++ unsigned long task_size = TASK_SIZE;
13256 ++
13257 ++#ifdef CONFIG_PAX_SEGMEXEC
13258 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13259 ++ task_size = SEGMEXEC_TASK_SIZE;
13260 ++#endif
13261 +
13262 + if (current->flags & PF_RANDOMIZE)
13263 + random_factor = get_random_int() % (1024*1024);
13264 +@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
13265 + else if (gap > MAX_GAP)
13266 + gap = MAX_GAP;
13267 +
13268 +- return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
13269 ++ return PAGE_ALIGN(task_size - gap - random_factor);
13270 + }
13271 +
13272 + /*
13273 +@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
13274 + if (sysctl_legacy_va_layout ||
13275 + (current->personality & ADDR_COMPAT_LAYOUT) ||
13276 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
13277 ++
13278 ++#ifdef CONFIG_PAX_SEGMEXEC
13279 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC)
13280 ++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
13281 ++ else
13282 ++#endif
13283 ++
13284 + mm->mmap_base = TASK_UNMAPPED_BASE;
13285 ++
13286 ++#ifdef CONFIG_PAX_RANDMMAP
13287 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13288 ++ mm->mmap_base += mm->delta_mmap;
13289 ++#endif
13290 ++
13291 + mm->get_unmapped_area = arch_get_unmapped_area;
13292 + mm->unmap_area = arch_unmap_area;
13293 + } else {
13294 + mm->mmap_base = mmap_base(mm);
13295 ++
13296 ++#ifdef CONFIG_PAX_RANDMMAP
13297 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
13298 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
13299 ++#endif
13300 ++
13301 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
13302 + mm->unmap_area = arch_unmap_area_topdown;
13303 + }
13304 +diff -Nurp linux-2.6.23.15/arch/i386/mm/pageattr.c linux-2.6.23.15-grsec/arch/i386/mm/pageattr.c
13305 +--- linux-2.6.23.15/arch/i386/mm/pageattr.c 2007-10-09 21:31:38.000000000 +0100
13306 ++++ linux-2.6.23.15-grsec/arch/i386/mm/pageattr.c 2008-02-11 10:37:44.000000000 +0000
13307 +@@ -13,6 +13,7 @@
13308 + #include <asm/tlbflush.h>
13309 + #include <asm/pgalloc.h>
13310 + #include <asm/sections.h>
13311 ++#include <asm/desc.h>
13312 +
13313 + static DEFINE_SPINLOCK(cpa_lock);
13314 + static struct list_head df_list = LIST_HEAD_INIT(df_list);
13315 +@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
13316 + }
13317 +
13318 + static struct page *split_large_page(unsigned long address, pgprot_t prot,
13319 +- pgprot_t ref_prot)
13320 ++ pgprot_t ref_prot, unsigned long flags)
13321 + {
13322 + int i;
13323 + unsigned long addr;
13324 + struct page *base;
13325 + pte_t *pbase;
13326 +
13327 +- spin_unlock_irq(&cpa_lock);
13328 ++ spin_unlock_irqrestore(&cpa_lock, flags);
13329 + base = alloc_pages(GFP_KERNEL, 0);
13330 +- spin_lock_irq(&cpa_lock);
13331 ++ spin_lock_irqsave(&cpa_lock, flags);
13332 + if (!base)
13333 + return NULL;
13334 +
13335 +@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
13336 + struct page *page;
13337 + unsigned long flags;
13338 +
13339 ++#ifdef CONFIG_PAX_KERNEXEC
13340 ++ unsigned long cr0;
13341 ++
13342 ++ pax_open_kernel(cr0);
13343 ++#endif
13344 ++
13345 + set_pte_atomic(kpte, pte); /* change init_mm */
13346 ++
13347 ++#ifdef CONFIG_PAX_KERNEXEC
13348 ++ pax_close_kernel(cr0);
13349 ++#endif
13350 ++
13351 + if (SHARED_KERNEL_PMD)
13352 + return;
13353 +
13354 +@@ -126,7 +138,7 @@ static inline void revert_page(struct pa
13355 + pte_t *linear;
13356 +
13357 + ref_prot =
13358 +- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
13359 ++ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
13360 + ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
13361 +
13362 + linear = (pte_t *)
13363 +@@ -143,7 +155,7 @@ static inline void save_page(struct page
13364 + }
13365 +
13366 + static int
13367 +-__change_page_attr(struct page *page, pgprot_t prot)
13368 ++__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
13369 + {
13370 + pte_t *kpte;
13371 + unsigned long address;
13372 +@@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg
13373 + struct page *split;
13374 +
13375 + ref_prot =
13376 +- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
13377 ++ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
13378 + ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
13379 +- split = split_large_page(address, prot, ref_prot);
13380 ++ split = split_large_page(address, prot, ref_prot, flags);
13381 + if (!split)
13382 + return -ENOMEM;
13383 +- set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
13384 +- kpte_page = split;
13385 ++ if (pte_huge(*kpte)) {
13386 ++ set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
13387 ++ kpte_page = split;
13388 ++ } else {
13389 ++ __free_pages(split, 0);
13390 ++ kpte = lookup_address(address);
13391 ++ kpte_page = virt_to_page(kpte);
13392 ++ set_pte_atomic(kpte, mk_pte(page, prot));
13393 ++ }
13394 + }
13395 + page_private(kpte_page)++;
13396 + } else if (!pte_huge(*kpte)) {
13397 +@@ -225,7 +244,7 @@ int change_page_attr(struct page *page,
13398 +
13399 + spin_lock_irqsave(&cpa_lock, flags);
13400 + for (i = 0; i < numpages; i++, page++) {
13401 +- err = __change_page_attr(page, prot);
13402 ++ err = __change_page_attr(page, prot, flags);
13403 + if (err)
13404 + break;
13405 + }
13406 +diff -Nurp linux-2.6.23.15/arch/i386/oprofile/backtrace.c linux-2.6.23.15-grsec/arch/i386/oprofile/backtrace.c
13407 +--- linux-2.6.23.15/arch/i386/oprofile/backtrace.c 2007-10-09 21:31:38.000000000 +0100
13408 ++++ linux-2.6.23.15-grsec/arch/i386/oprofile/backtrace.c 2008-02-11 10:37:44.000000000 +0000
13409 +@@ -22,7 +22,7 @@ struct frame_head {
13410 + static struct frame_head *
13411 + dump_kernel_backtrace(struct frame_head * head)
13412 + {
13413 +- oprofile_add_trace(head->ret);
13414 ++ oprofile_add_trace(head->ret + __KERNEL_TEXT_OFFSET);
13415 +
13416 + /* frame pointers should strictly progress back up the stack
13417 + * (towards higher addresses) */
13418 +@@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
13419 + head = (struct frame_head *)regs->ebp;
13420 + #endif
13421 +
13422 +- if (!user_mode_vm(regs)) {
13423 ++ if (!user_mode(regs)) {
13424 + while (depth-- && valid_kernel_stack(head, regs))
13425 + head = dump_kernel_backtrace(head);
13426 + return;
13427 +diff -Nurp linux-2.6.23.15/arch/i386/oprofile/op_model_p4.c linux-2.6.23.15-grsec/arch/i386/oprofile/op_model_p4.c
13428 +--- linux-2.6.23.15/arch/i386/oprofile/op_model_p4.c 2007-10-09 21:31:38.000000000 +0100
13429 ++++ linux-2.6.23.15-grsec/arch/i386/oprofile/op_model_p4.c 2008-02-11 10:37:44.000000000 +0000
13430 +@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
13431 + #endif
13432 + }
13433 +
13434 +-static int inline addr_increment(void)
13435 ++static inline int addr_increment(void)
13436 + {
13437 + #ifdef CONFIG_SMP
13438 + return smp_num_siblings == 2 ? 2 : 1;
13439 +diff -Nurp linux-2.6.23.15/arch/i386/pci/common.c linux-2.6.23.15-grsec/arch/i386/pci/common.c
13440 +--- linux-2.6.23.15/arch/i386/pci/common.c 2007-10-09 21:31:38.000000000 +0100
13441 ++++ linux-2.6.23.15-grsec/arch/i386/pci/common.c 2008-02-11 10:37:44.000000000 +0000
13442 +@@ -287,7 +287,7 @@ static struct dmi_system_id __devinitdat
13443 + DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
13444 + },
13445 + },
13446 +- {}
13447 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
13448 + };
13449 +
13450 + struct pci_bus * __devinit pcibios_scan_root(int busnum)
13451 +diff -Nurp linux-2.6.23.15/arch/i386/pci/early.c linux-2.6.23.15-grsec/arch/i386/pci/early.c
13452 +--- linux-2.6.23.15/arch/i386/pci/early.c 2007-10-09 21:31:38.000000000 +0100
13453 ++++ linux-2.6.23.15-grsec/arch/i386/pci/early.c 2008-02-11 10:37:44.000000000 +0000
13454 +@@ -7,7 +7,7 @@
13455 + /* Direct PCI access. This is used for PCI accesses in early boot before
13456 + the PCI subsystem works. */
13457 +
13458 +-#define PDprintk(x...)
13459 ++#define PDprintk(x...) do {} while (0)
13460 +
13461 + u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
13462 + {
13463 +diff -Nurp linux-2.6.23.15/arch/i386/pci/fixup.c linux-2.6.23.15-grsec/arch/i386/pci/fixup.c
13464 +--- linux-2.6.23.15/arch/i386/pci/fixup.c 2007-10-09 21:31:38.000000000 +0100
13465 ++++ linux-2.6.23.15-grsec/arch/i386/pci/fixup.c 2008-02-11 10:37:44.000000000 +0000
13466 +@@ -386,7 +386,7 @@ static struct dmi_system_id __devinitdat
13467 + DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
13468 + },
13469 + },
13470 +- { }
13471 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13472 + };
13473 +
13474 + static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
13475 +diff -Nurp linux-2.6.23.15/arch/i386/pci/irq.c linux-2.6.23.15-grsec/arch/i386/pci/irq.c
13476 +--- linux-2.6.23.15/arch/i386/pci/irq.c 2007-10-09 21:31:38.000000000 +0100
13477 ++++ linux-2.6.23.15-grsec/arch/i386/pci/irq.c 2008-02-11 10:37:44.000000000 +0000
13478 +@@ -508,7 +508,7 @@ static __init int intel_router_probe(str
13479 + static struct pci_device_id __initdata pirq_440gx[] = {
13480 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
13481 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
13482 +- { },
13483 ++ { PCI_DEVICE(0, 0) }
13484 + };
13485 +
13486 + /* 440GX has a proprietary PIRQ router -- don't use it */
13487 +@@ -1051,7 +1051,7 @@ static struct dmi_system_id __initdata p
13488 + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
13489 + },
13490 + },
13491 +- { }
13492 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
13493 + };
13494 +
13495 + static int __init pcibios_irq_init(void)
13496 +diff -Nurp linux-2.6.23.15/arch/i386/pci/pcbios.c linux-2.6.23.15-grsec/arch/i386/pci/pcbios.c
13497 +--- linux-2.6.23.15/arch/i386/pci/pcbios.c 2007-10-09 21:31:38.000000000 +0100
13498 ++++ linux-2.6.23.15-grsec/arch/i386/pci/pcbios.c 2008-02-11 10:37:44.000000000 +0000
13499 +@@ -57,50 +57,124 @@ union bios32 {
13500 + static struct {
13501 + unsigned long address;
13502 + unsigned short segment;
13503 +-} bios32_indirect = { 0, __KERNEL_CS };
13504 ++} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
13505 +
13506 + /*
13507 + * Returns the entry point for the given service, NULL on error
13508 + */
13509 +
13510 +-static unsigned long bios32_service(unsigned long service)
13511 ++static unsigned long __devinit bios32_service(unsigned long service)
13512 + {
13513 + unsigned char return_code; /* %al */
13514 + unsigned long address; /* %ebx */
13515 + unsigned long length; /* %ecx */
13516 + unsigned long entry; /* %edx */
13517 + unsigned long flags;
13518 ++ struct desc_struct *gdt;
13519 ++
13520 ++#ifdef CONFIG_PAX_KERNEXEC
13521 ++ unsigned long cr0;
13522 ++#endif
13523 +
13524 + local_irq_save(flags);
13525 +- __asm__("lcall *(%%edi); cld"
13526 ++
13527 ++ gdt = get_cpu_gdt_table(smp_processor_id());
13528 ++
13529 ++#ifdef CONFIG_PAX_KERNEXEC
13530 ++ pax_open_kernel(cr0);
13531 ++#endif
13532 ++
13533 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
13534 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
13535 ++ 0UL, 0xFFFFFUL, 0x9B, 0xC);
13536 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
13537 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
13538 ++ 0UL, 0xFFFFFUL, 0x93, 0xC);
13539 ++
13540 ++#ifdef CONFIG_PAX_KERNEXEC
13541 ++ pax_close_kernel(cr0);
13542 ++#endif
13543 ++
13544 ++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
13545 + : "=a" (return_code),
13546 + "=b" (address),
13547 + "=c" (length),
13548 + "=d" (entry)
13549 + : "0" (service),
13550 + "1" (0),
13551 +- "D" (&bios32_indirect));
13552 ++ "D" (&bios32_indirect),
13553 ++ "r"(__PCIBIOS_DS)
13554 ++ : "memory");
13555 ++
13556 ++#ifdef CONFIG_PAX_KERNEXEC
13557 ++ pax_open_kernel(cr0);
13558 ++#endif
13559 ++
13560 ++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
13561 ++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
13562 ++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
13563 ++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
13564 ++
13565 ++#ifdef CONFIG_PAX_KERNEXEC
13566 ++ pax_close_kernel(cr0);
13567 ++#endif
13568 ++
13569 + local_irq_restore(flags);
13570 +
13571 + switch (return_code) {
13572 +- case 0:
13573 +- return address + entry;
13574 +- case 0x80: /* Not present */
13575 +- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
13576 +- return 0;
13577 +- default: /* Shouldn't happen */
13578 +- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
13579 +- service, return_code);
13580 ++ case 0: {
13581 ++ int cpu;
13582 ++ unsigned char flags;
13583 ++
13584 ++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
13585 ++ if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) {
13586 ++ printk(KERN_WARNING "bios32_service: not valid\n");
13587 + return 0;
13588 ++ }
13589 ++ address = address + PAGE_OFFSET;
13590 ++ length += 16UL; /* some BIOSs underreport this... */
13591 ++ flags = 4;
13592 ++ if (length >= 64*1024*1024) {
13593 ++ length >>= PAGE_SHIFT;
13594 ++ flags |= 8;
13595 ++ }
13596 ++
13597 ++#ifdef CONFIG_PAX_KERNEXEC
13598 ++ pax_open_kernel(cr0);
13599 ++#endif
13600 ++
13601 ++ for (cpu = 0; cpu < NR_CPUS; cpu++) {
13602 ++ gdt = get_cpu_gdt_table(cpu);
13603 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
13604 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
13605 ++ address, length, 0x9b, flags);
13606 ++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
13607 ++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
13608 ++ address, length, 0x93, flags);
13609 ++ }
13610 ++
13611 ++#ifdef CONFIG_PAX_KERNEXEC
13612 ++ pax_close_kernel(cr0);
13613 ++#endif
13614 ++
13615 ++ return entry;
13616 ++ }
13617 ++ case 0x80: /* Not present */
13618 ++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
13619 ++ return 0;
13620 ++ default: /* Shouldn't happen */
13621 ++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
13622 ++ service, return_code);
13623 ++ return 0;
13624 + }
13625 + }
13626 +
13627 + static struct {
13628 + unsigned long address;
13629 + unsigned short segment;
13630 +-} pci_indirect = { 0, __KERNEL_CS };
13631 ++} pci_indirect __read_only = { 0, __PCIBIOS_CS };
13632 +
13633 +-static int pci_bios_present;
13634 ++static int pci_bios_present __read_only;
13635 +
13636 + static int __devinit check_pcibios(void)
13637 + {
13638 +@@ -109,11 +183,13 @@ static int __devinit check_pcibios(void)
13639 + unsigned long flags, pcibios_entry;
13640 +
13641 + if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
13642 +- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
13643 ++ pci_indirect.address = pcibios_entry;
13644 +
13645 + local_irq_save(flags);
13646 +- __asm__(
13647 +- "lcall *(%%edi); cld\n\t"
13648 ++ __asm__("movw %w6, %%ds\n\t"
13649 ++ "lcall *%%ss:(%%edi); cld\n\t"
13650 ++ "push %%ss\n\t"
13651 ++ "pop %%ds\n\t"
13652 + "jc 1f\n\t"
13653 + "xor %%ah, %%ah\n"
13654 + "1:"
13655 +@@ -122,7 +198,8 @@ static int __devinit check_pcibios(void)
13656 + "=b" (ebx),
13657 + "=c" (ecx)
13658 + : "1" (PCIBIOS_PCI_BIOS_PRESENT),
13659 +- "D" (&pci_indirect)
13660 ++ "D" (&pci_indirect),
13661 ++ "r" (__PCIBIOS_DS)
13662 + : "memory");
13663 + local_irq_restore(flags);
13664 +
13665 +@@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic
13666 + unsigned short bx;
13667 + unsigned short ret;
13668 +
13669 +- __asm__("lcall *(%%edi); cld\n\t"
13670 ++ __asm__("movw %w7, %%ds\n\t"
13671 ++ "lcall *%%ss:(%%edi); cld\n\t"
13672 ++ "push %%ss\n\t"
13673 ++ "pop %%ds\n\t"
13674 + "jc 1f\n\t"
13675 + "xor %%ah, %%ah\n"
13676 + "1:"
13677 +@@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic
13678 + "c" (device_id),
13679 + "d" (vendor),
13680 + "S" ((int) index),
13681 +- "D" (&pci_indirect));
13682 ++ "D" (&pci_indirect),
13683 ++ "r" (__PCIBIOS_DS));
13684 + *bus = (bx >> 8) & 0xff;
13685 + *device_fn = bx & 0xff;
13686 + return (int) (ret & 0xff00) >> 8;
13687 +@@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se
13688 +
13689 + switch (len) {
13690 + case 1:
13691 +- __asm__("lcall *(%%esi); cld\n\t"
13692 ++ __asm__("movw %w6, %%ds\n\t"
13693 ++ "lcall *%%ss:(%%esi); cld\n\t"
13694 ++ "push %%ss\n\t"
13695 ++ "pop %%ds\n\t"
13696 + "jc 1f\n\t"
13697 + "xor %%ah, %%ah\n"
13698 + "1:"
13699 +@@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se
13700 + : "1" (PCIBIOS_READ_CONFIG_BYTE),
13701 + "b" (bx),
13702 + "D" ((long)reg),
13703 +- "S" (&pci_indirect));
13704 ++ "S" (&pci_indirect),
13705 ++ "r" (__PCIBIOS_DS));
13706 + break;
13707 + case 2:
13708 +- __asm__("lcall *(%%esi); cld\n\t"
13709 ++ __asm__("movw %w6, %%ds\n\t"
13710 ++ "lcall *%%ss:(%%esi); cld\n\t"
13711 ++ "push %%ss\n\t"
13712 ++ "pop %%ds\n\t"
13713 + "jc 1f\n\t"
13714 + "xor %%ah, %%ah\n"
13715 + "1:"
13716 +@@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se
13717 + : "1" (PCIBIOS_READ_CONFIG_WORD),
13718 + "b" (bx),
13719 + "D" ((long)reg),
13720 +- "S" (&pci_indirect));
13721 ++ "S" (&pci_indirect),
13722 ++ "r" (__PCIBIOS_DS));
13723 + break;
13724 + case 4:
13725 +- __asm__("lcall *(%%esi); cld\n\t"
13726 ++ __asm__("movw %w6, %%ds\n\t"
13727 ++ "lcall *%%ss:(%%esi); cld\n\t"
13728 ++ "push %%ss\n\t"
13729 ++ "pop %%ds\n\t"
13730 + "jc 1f\n\t"
13731 + "xor %%ah, %%ah\n"
13732 + "1:"
13733 +@@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se
13734 + : "1" (PCIBIOS_READ_CONFIG_DWORD),
13735 + "b" (bx),
13736 + "D" ((long)reg),
13737 +- "S" (&pci_indirect));
13738 ++ "S" (&pci_indirect),
13739 ++ "r" (__PCIBIOS_DS));
13740 + break;
13741 + }
13742 +
13743 +@@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s
13744 +
13745 + switch (len) {
13746 + case 1:
13747 +- __asm__("lcall *(%%esi); cld\n\t"
13748 ++ __asm__("movw %w6, %%ds\n\t"
13749 ++ "lcall *%%ss:(%%esi); cld\n\t"
13750 ++ "push %%ss\n\t"
13751 ++ "pop %%ds\n\t"
13752 + "jc 1f\n\t"
13753 + "xor %%ah, %%ah\n"
13754 + "1:"
13755 +@@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s
13756 + "c" (value),
13757 + "b" (bx),
13758 + "D" ((long)reg),
13759 +- "S" (&pci_indirect));
13760 ++ "S" (&pci_indirect),
13761 ++ "r" (__PCIBIOS_DS));
13762 + break;
13763 + case 2:
13764 +- __asm__("lcall *(%%esi); cld\n\t"
13765 ++ __asm__("movw %w6, %%ds\n\t"
13766 ++ "lcall *%%ss:(%%esi); cld\n\t"
13767 ++ "push %%ss\n\t"
13768 ++ "pop %%ds\n\t"
13769 + "jc 1f\n\t"
13770 + "xor %%ah, %%ah\n"
13771 + "1:"
13772 +@@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s
13773 + "c" (value),
13774 + "b" (bx),
13775 + "D" ((long)reg),
13776 +- "S" (&pci_indirect));
13777 ++ "S" (&pci_indirect),
13778 ++ "r" (__PCIBIOS_DS));
13779 + break;
13780 + case 4:
13781 +- __asm__("lcall *(%%esi); cld\n\t"
13782 ++ __asm__("movw %w6, %%ds\n\t"
13783 ++ "lcall *%%ss:(%%esi); cld\n\t"
13784 ++ "push %%ss\n\t"
13785 ++ "pop %%ds\n\t"
13786 + "jc 1f\n\t"
13787 + "xor %%ah, %%ah\n"
13788 + "1:"
13789 +@@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s
13790 + "c" (value),
13791 + "b" (bx),
13792 + "D" ((long)reg),
13793 +- "S" (&pci_indirect));
13794 ++ "S" (&pci_indirect),
13795 ++ "r" (__PCIBIOS_DS));
13796 + break;
13797 + }
13798 +
13799 +@@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i
13800 +
13801 + DBG("PCI: Fetching IRQ routing table... ");
13802 + __asm__("push %%es\n\t"
13803 ++ "movw %w8, %%ds\n\t"
13804 + "push %%ds\n\t"
13805 + "pop %%es\n\t"
13806 +- "lcall *(%%esi); cld\n\t"
13807 ++ "lcall *%%ss:(%%esi); cld\n\t"
13808 + "pop %%es\n\t"
13809 ++ "push %%ss\n\t"
13810 ++ "pop %%ds\n"
13811 + "jc 1f\n\t"
13812 + "xor %%ah, %%ah\n"
13813 + "1:"
13814 +@@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i
13815 + "1" (0),
13816 + "D" ((long) &opt),
13817 + "S" (&pci_indirect),
13818 +- "m" (opt)
13819 ++ "m" (opt),
13820 ++ "r" (__PCIBIOS_DS)
13821 + : "memory");
13822 + DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
13823 + if (ret & 0xff00)
13824 +@@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d
13825 + {
13826 + int ret;
13827 +
13828 +- __asm__("lcall *(%%esi); cld\n\t"
13829 ++ __asm__("movw %w5, %%ds\n\t"
13830 ++ "lcall *%%ss:(%%esi); cld\n\t"
13831 ++ "push %%ss\n\t"
13832 ++ "pop %%ds\n"
13833 + "jc 1f\n\t"
13834 + "xor %%ah, %%ah\n"
13835 + "1:"
13836 +@@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d
13837 + : "0" (PCIBIOS_SET_PCI_HW_INT),
13838 + "b" ((dev->bus->number << 8) | dev->devfn),
13839 + "c" ((irq << 8) | (pin + 10)),
13840 +- "S" (&pci_indirect));
13841 ++ "S" (&pci_indirect),
13842 ++ "r" (__PCIBIOS_DS));
13843 + return !(ret & 0xff00);
13844 + }
13845 + EXPORT_SYMBOL(pcibios_set_irq_routing);
13846 +diff -Nurp linux-2.6.23.15/arch/i386/power/cpu.c linux-2.6.23.15-grsec/arch/i386/power/cpu.c
13847 +--- linux-2.6.23.15/arch/i386/power/cpu.c 2007-10-09 21:31:38.000000000 +0100
13848 ++++ linux-2.6.23.15-grsec/arch/i386/power/cpu.c 2008-02-11 10:37:44.000000000 +0000
13849 +@@ -64,7 +64,7 @@ static void do_fpu_end(void)
13850 + static void fix_processor_context(void)
13851 + {
13852 + int cpu = smp_processor_id();
13853 +- struct tss_struct * t = &per_cpu(init_tss, cpu);
13854 ++ struct tss_struct *t = init_tss + cpu;
13855 +
13856 + 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. */
13857 +
13858 +diff -Nurp linux-2.6.23.15/arch/i386/xen/enlighten.c linux-2.6.23.15-grsec/arch/i386/xen/enlighten.c
13859 +--- linux-2.6.23.15/arch/i386/xen/enlighten.c 2008-02-11 10:36:03.000000000 +0000
13860 ++++ linux-2.6.23.15-grsec/arch/i386/xen/enlighten.c 2008-02-11 10:37:44.000000000 +0000
13861 +@@ -320,7 +320,7 @@ static void xen_set_ldt(const void *addr
13862 + static void xen_load_gdt(const struct Xgt_desc_struct *dtr)
13863 + {
13864 + unsigned long *frames;
13865 +- unsigned long va = dtr->address;
13866 ++ unsigned long va = (unsigned long)dtr->address;
13867 + unsigned int size = dtr->size + 1;
13868 + unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
13869 + int f;
13870 +@@ -335,7 +335,7 @@ static void xen_load_gdt(const struct Xg
13871 + mcs = xen_mc_entry(sizeof(*frames) * pages);
13872 + frames = mcs.args;
13873 +
13874 +- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
13875 ++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
13876 + frames[f] = virt_to_mfn(va);
13877 + make_lowmem_page_readonly((void *)va);
13878 + }
13879 +@@ -429,7 +429,7 @@ static void xen_write_idt_entry(struct d
13880 +
13881 + preempt_disable();
13882 +
13883 +- start = __get_cpu_var(idt_desc).address;
13884 ++ start = (unsigned long)__get_cpu_var(idt_desc).address;
13885 + end = start + __get_cpu_var(idt_desc).size + 1;
13886 +
13887 + xen_mc_flush();
13888 +diff -Nurp linux-2.6.23.15/arch/i386/xen/smp.c linux-2.6.23.15-grsec/arch/i386/xen/smp.c
13889 +--- linux-2.6.23.15/arch/i386/xen/smp.c 2007-10-09 21:31:38.000000000 +0100
13890 ++++ linux-2.6.23.15-grsec/arch/i386/xen/smp.c 2008-02-11 10:37:44.000000000 +0000
13891 +@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi
13892 +
13893 + /* We've switched to the "real" per-cpu gdt, so make sure the
13894 + old memory can be recycled */
13895 +- make_lowmem_page_readwrite(&per_cpu__gdt_page);
13896 ++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id()));
13897 +
13898 + for (cpu = 0; cpu < NR_CPUS; cpu++) {
13899 + cpus_clear(cpu_sibling_map[cpu]);
13900 +@@ -198,7 +198,7 @@ static __cpuinit int
13901 + cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
13902 + {
13903 + struct vcpu_guest_context *ctxt;
13904 +- struct gdt_page *gdt = &per_cpu(gdt_page, cpu);
13905 ++ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
13906 +
13907 + if (cpu_test_and_set(cpu, cpu_initialized_map))
13908 + return 0;
13909 +@@ -222,11 +222,11 @@ cpu_initialize_context(unsigned int cpu,
13910 +
13911 + ctxt->ldt_ents = 0;
13912 +
13913 +- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK);
13914 +- make_lowmem_page_readonly(gdt->gdt);
13915 ++ BUG_ON((unsigned long)gdt & ~PAGE_MASK);
13916 ++ make_lowmem_page_readonly(gdt);
13917 +
13918 +- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt);
13919 +- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt);
13920 ++ ctxt->gdt_frames[0] = virt_to_mfn(gdt);
13921 ++ ctxt->gdt_ents = GDT_ENTRIES;
13922 +
13923 + ctxt->user_regs.cs = __KERNEL_CS;
13924 + ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs);
13925 +diff -Nurp linux-2.6.23.15/arch/ia64/ia32/binfmt_elf32.c linux-2.6.23.15-grsec/arch/ia64/ia32/binfmt_elf32.c
13926 +--- linux-2.6.23.15/arch/ia64/ia32/binfmt_elf32.c 2007-10-09 21:31:38.000000000 +0100
13927 ++++ linux-2.6.23.15-grsec/arch/ia64/ia32/binfmt_elf32.c 2008-02-11 10:37:44.000000000 +0000
13928 +@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
13929 +
13930 + #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
13931 +
13932 ++#ifdef CONFIG_PAX_ASLR
13933 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
13934 ++
13935 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
13936 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
13937 ++#endif
13938 ++
13939 + /* Ugly but avoids duplication */
13940 + #include "../../../fs/binfmt_elf.c"
13941 +
13942 +diff -Nurp linux-2.6.23.15/arch/ia64/ia32/ia32priv.h linux-2.6.23.15-grsec/arch/ia64/ia32/ia32priv.h
13943 +--- linux-2.6.23.15/arch/ia64/ia32/ia32priv.h 2007-10-09 21:31:38.000000000 +0100
13944 ++++ linux-2.6.23.15-grsec/arch/ia64/ia32/ia32priv.h 2008-02-11 10:37:44.000000000 +0000
13945 +@@ -304,7 +304,14 @@ struct old_linux32_dirent {
13946 + #define ELF_DATA ELFDATA2LSB
13947 + #define ELF_ARCH EM_386
13948 +
13949 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
13950 ++#ifdef CONFIG_PAX_RANDUSTACK
13951 ++#define __IA32_DELTA_STACK (current->mm->delta_stack)
13952 ++#else
13953 ++#define __IA32_DELTA_STACK 0UL
13954 ++#endif
13955 ++
13956 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
13957 ++
13958 + #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
13959 + #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
13960 +
13961 +diff -Nurp linux-2.6.23.15/arch/ia64/kernel/module.c linux-2.6.23.15-grsec/arch/ia64/kernel/module.c
13962 +--- linux-2.6.23.15/arch/ia64/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
13963 ++++ linux-2.6.23.15-grsec/arch/ia64/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
13964 +@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
13965 + void
13966 + module_free (struct module *mod, void *module_region)
13967 + {
13968 +- if (mod->arch.init_unw_table && module_region == mod->module_init) {
13969 ++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
13970 + unw_remove_unwind_table(mod->arch.init_unw_table);
13971 + mod->arch.init_unw_table = NULL;
13972 + }
13973 +@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
13974 + }
13975 +
13976 + static inline int
13977 ++in_init_rx (const struct module *mod, uint64_t addr)
13978 ++{
13979 ++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
13980 ++}
13981 ++
13982 ++static inline int
13983 ++in_init_rw (const struct module *mod, uint64_t addr)
13984 ++{
13985 ++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
13986 ++}
13987 ++
13988 ++static inline int
13989 + in_init (const struct module *mod, uint64_t addr)
13990 + {
13991 +- return addr - (uint64_t) mod->module_init < mod->init_size;
13992 ++ return in_init_rx(mod, value) || in_init_rw(mod, value);
13993 ++}
13994 ++
13995 ++static inline int
13996 ++in_core_rx (const struct module *mod, uint64_t addr)
13997 ++{
13998 ++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
13999 ++}
14000 ++
14001 ++static inline int
14002 ++in_core_rw (const struct module *mod, uint64_t addr)
14003 ++{
14004 ++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
14005 + }
14006 +
14007 + static inline int
14008 + in_core (const struct module *mod, uint64_t addr)
14009 + {
14010 +- return addr - (uint64_t) mod->module_core < mod->core_size;
14011 ++ return in_core_rx(mod, value) || in_core_rw(mod, value);
14012 + }
14013 +
14014 + static inline int
14015 +@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
14016 + break;
14017 +
14018 + case RV_BDREL:
14019 +- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
14020 ++ if (in_init_rx(mod, val))
14021 ++ val -= (uint64_t) mod->module_init_rx;
14022 ++ else if (in_init_rw(mod, val))
14023 ++ val -= (uint64_t) mod->module_init_rw;
14024 ++ else if (in_core_rx(mod, val))
14025 ++ val -= (uint64_t) mod->module_core_rx;
14026 ++ else if (in_core_rw(mod, val))
14027 ++ val -= (uint64_t) mod->module_core_rw;
14028 + break;
14029 +
14030 + case RV_LTV:
14031 +@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
14032 + * addresses have been selected...
14033 + */
14034 + uint64_t gp;
14035 +- if (mod->core_size > MAX_LTOFF)
14036 ++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
14037 + /*
14038 + * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
14039 + * at the end of the module.
14040 + */
14041 +- gp = mod->core_size - MAX_LTOFF / 2;
14042 ++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
14043 + else
14044 +- gp = mod->core_size / 2;
14045 +- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
14046 ++ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
14047 ++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
14048 + mod->arch.gp = gp;
14049 + DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
14050 + }
14051 +diff -Nurp linux-2.6.23.15/arch/ia64/kernel/ptrace.c linux-2.6.23.15-grsec/arch/ia64/kernel/ptrace.c
14052 +--- linux-2.6.23.15/arch/ia64/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
14053 ++++ linux-2.6.23.15-grsec/arch/ia64/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
14054 +@@ -17,6 +17,7 @@
14055 + #include <linux/security.h>
14056 + #include <linux/audit.h>
14057 + #include <linux/signal.h>
14058 ++#include <linux/grsecurity.h>
14059 +
14060 + #include <asm/pgtable.h>
14061 + #include <asm/processor.h>
14062 +@@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns
14063 + if (pid == 1) /* no messing around with init! */
14064 + goto out_tsk;
14065 +
14066 ++ if (gr_handle_ptrace(child, request))
14067 ++ goto out_tsk;
14068 ++
14069 + if (request == PTRACE_ATTACH) {
14070 + ret = ptrace_attach(child);
14071 + goto out_tsk;
14072 +diff -Nurp linux-2.6.23.15/arch/ia64/kernel/sys_ia64.c linux-2.6.23.15-grsec/arch/ia64/kernel/sys_ia64.c
14073 +--- linux-2.6.23.15/arch/ia64/kernel/sys_ia64.c 2007-10-09 21:31:38.000000000 +0100
14074 ++++ linux-2.6.23.15-grsec/arch/ia64/kernel/sys_ia64.c 2008-02-11 10:37:44.000000000 +0000
14075 +@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
14076 + if (REGION_NUMBER(addr) == RGN_HPAGE)
14077 + addr = 0;
14078 + #endif
14079 ++
14080 ++#ifdef CONFIG_PAX_RANDMMAP
14081 ++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
14082 ++ addr = mm->free_area_cache;
14083 ++ else
14084 ++#endif
14085 ++
14086 + if (!addr)
14087 + addr = mm->free_area_cache;
14088 +
14089 +@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
14090 + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
14091 + /* At this point: (!vma || addr < vma->vm_end). */
14092 + if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
14093 +- if (start_addr != TASK_UNMAPPED_BASE) {
14094 ++ if (start_addr != mm->mmap_base) {
14095 + /* Start a new search --- just in case we missed some holes. */
14096 +- addr = TASK_UNMAPPED_BASE;
14097 ++ addr = mm->mmap_base;
14098 + goto full_search;
14099 + }
14100 + return -ENOMEM;
14101 +diff -Nurp linux-2.6.23.15/arch/ia64/mm/fault.c linux-2.6.23.15-grsec/arch/ia64/mm/fault.c
14102 +--- linux-2.6.23.15/arch/ia64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
14103 ++++ linux-2.6.23.15-grsec/arch/ia64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
14104 +@@ -10,6 +10,7 @@
14105 + #include <linux/interrupt.h>
14106 + #include <linux/kprobes.h>
14107 + #include <linux/kdebug.h>
14108 ++#include <linux/binfmts.h>
14109 +
14110 + #include <asm/pgtable.h>
14111 + #include <asm/processor.h>
14112 +@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
14113 + return pte_present(pte);
14114 + }
14115 +
14116 ++#ifdef CONFIG_PAX_PAGEEXEC
14117 ++void pax_report_insns(void *pc, void *sp)
14118 ++{
14119 ++ unsigned long i;
14120 ++
14121 ++ printk(KERN_ERR "PAX: bytes at PC: ");
14122 ++ for (i = 0; i < 8; i++) {
14123 ++ unsigned int c;
14124 ++ if (get_user(c, (unsigned int *)pc+i))
14125 ++ printk("???????? ");
14126 ++ else
14127 ++ printk("%08x ", c);
14128 ++ }
14129 ++ printk("\n");
14130 ++}
14131 ++#endif
14132 ++
14133 + void __kprobes
14134 + ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
14135 + {
14136 +@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres
14137 + mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
14138 + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
14139 +
14140 +- if ((vma->vm_flags & mask) != mask)
14141 ++ if ((vma->vm_flags & mask) != mask) {
14142 ++
14143 ++#ifdef CONFIG_PAX_PAGEEXEC
14144 ++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
14145 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
14146 ++ goto bad_area;
14147 ++
14148 ++ up_read(&mm->mmap_sem);
14149 ++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
14150 ++ do_exit(SIGKILL);
14151 ++ }
14152 ++#endif
14153 ++
14154 + goto bad_area;
14155 +
14156 ++ }
14157 ++
14158 + survive:
14159 + /*
14160 + * If for any reason at all we couldn't handle the fault, make
14161 +diff -Nurp linux-2.6.23.15/arch/ia64/mm/init.c linux-2.6.23.15-grsec/arch/ia64/mm/init.c
14162 +--- linux-2.6.23.15/arch/ia64/mm/init.c 2007-10-09 21:31:38.000000000 +0100
14163 ++++ linux-2.6.23.15-grsec/arch/ia64/mm/init.c 2008-02-11 10:37:44.000000000 +0000
14164 +@@ -20,8 +20,8 @@
14165 + #include <linux/proc_fs.h>
14166 + #include <linux/bitops.h>
14167 + #include <linux/kexec.h>
14168 ++#include <linux/a.out.h>
14169 +
14170 +-#include <asm/a.out.h>
14171 + #include <asm/dma.h>
14172 + #include <asm/ia32.h>
14173 + #include <asm/io.h>
14174 +@@ -130,8 +130,21 @@ ia64_init_addr_space (void)
14175 + vma->vm_mm = current->mm;
14176 + vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
14177 + vma->vm_end = vma->vm_start + PAGE_SIZE;
14178 +- vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
14179 + vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
14180 ++
14181 ++#ifdef CONFIG_PAX_PAGEEXEC
14182 ++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
14183 ++ vm->vm_flags &= ~VM_EXEC;
14184 ++
14185 ++#ifdef CONFIG_PAX_MPROTECT
14186 ++ if (current->mm->pax_flags & MF_PAX_MPROTECT)
14187 ++ vma->vm_flags &= ~VM_MAYEXEC;
14188 ++#endif
14189 ++
14190 ++ }
14191 ++#endif
14192 ++
14193 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14194 + down_write(&current->mm->mmap_sem);
14195 + if (insert_vm_struct(current->mm, vma)) {
14196 + up_write(&current->mm->mmap_sem);
14197 +diff -Nurp linux-2.6.23.15/arch/mips/kernel/binfmt_elfn32.c linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfn32.c
14198 +--- linux-2.6.23.15/arch/mips/kernel/binfmt_elfn32.c 2007-10-09 21:31:38.000000000 +0100
14199 ++++ linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfn32.c 2008-02-11 10:37:44.000000000 +0000
14200 +@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
14201 + #undef ELF_ET_DYN_BASE
14202 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
14203 +
14204 ++#ifdef CONFIG_PAX_ASLR
14205 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
14206 ++
14207 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
14208 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
14209 ++#endif
14210 ++
14211 + #include <asm/processor.h>
14212 + #include <linux/module.h>
14213 + #include <linux/elfcore.h>
14214 +diff -Nurp linux-2.6.23.15/arch/mips/kernel/binfmt_elfo32.c linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfo32.c
14215 +--- linux-2.6.23.15/arch/mips/kernel/binfmt_elfo32.c 2007-10-09 21:31:38.000000000 +0100
14216 ++++ linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfo32.c 2008-02-11 10:37:44.000000000 +0000
14217 +@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
14218 + #undef ELF_ET_DYN_BASE
14219 + #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
14220 +
14221 ++#ifdef CONFIG_PAX_ASLR
14222 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
14223 ++
14224 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
14225 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
14226 ++#endif
14227 ++
14228 + #include <asm/processor.h>
14229 + #include <linux/module.h>
14230 + #include <linux/elfcore.h>
14231 +diff -Nurp linux-2.6.23.15/arch/mips/kernel/syscall.c linux-2.6.23.15-grsec/arch/mips/kernel/syscall.c
14232 +--- linux-2.6.23.15/arch/mips/kernel/syscall.c 2007-10-09 21:31:38.000000000 +0100
14233 ++++ linux-2.6.23.15-grsec/arch/mips/kernel/syscall.c 2008-02-11 10:37:44.000000000 +0000
14234 +@@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
14235 + do_color_align = 0;
14236 + if (filp || (flags & MAP_SHARED))
14237 + do_color_align = 1;
14238 ++
14239 ++#ifdef CONFIG_PAX_RANDMMAP
14240 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
14241 ++#endif
14242 ++
14243 + if (addr) {
14244 + if (do_color_align)
14245 + addr = COLOUR_ALIGN(addr, pgoff);
14246 +@@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
14247 + (!vmm || addr + len <= vmm->vm_start))
14248 + return addr;
14249 + }
14250 +- addr = TASK_UNMAPPED_BASE;
14251 ++ addr = current->mm->mmap_base;
14252 + if (do_color_align)
14253 + addr = COLOUR_ALIGN(addr, pgoff);
14254 + else
14255 +diff -Nurp linux-2.6.23.15/arch/mips/mm/fault.c linux-2.6.23.15-grsec/arch/mips/mm/fault.c
14256 +--- linux-2.6.23.15/arch/mips/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
14257 ++++ linux-2.6.23.15-grsec/arch/mips/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
14258 +@@ -26,6 +26,23 @@
14259 + #include <asm/ptrace.h>
14260 + #include <asm/highmem.h> /* For VMALLOC_END */
14261 +
14262 ++#ifdef CONFIG_PAX_PAGEEXEC
14263 ++void pax_report_insns(void *pc)
14264 ++{
14265 ++ unsigned long i;
14266 ++
14267 ++ printk(KERN_ERR "PAX: bytes at PC: ");
14268 ++ for (i = 0; i < 5; i++) {
14269 ++ unsigned int c;
14270 ++ if (get_user(c, (unsigned int *)pc+i))
14271 ++ printk("???????? ");
14272 ++ else
14273 ++ printk("%08x ", c);
14274 ++ }
14275 ++ printk("\n");
14276 ++}
14277 ++#endif
14278 ++
14279 + /*
14280 + * This routine handles page faults. It determines the address,
14281 + * and the problem, and then passes it off to one of the appropriate
14282 +diff -Nurp linux-2.6.23.15/arch/parisc/kernel/module.c linux-2.6.23.15-grsec/arch/parisc/kernel/module.c
14283 +--- linux-2.6.23.15/arch/parisc/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
14284 ++++ linux-2.6.23.15-grsec/arch/parisc/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
14285 +@@ -73,16 +73,38 @@
14286 +
14287 + /* three functions to determine where in the module core
14288 + * or init pieces the location is */
14289 ++static inline int in_init_rx(struct module *me, void *loc)
14290 ++{
14291 ++ return (loc >= me->module_init_rx &&
14292 ++ loc < (me->module_init_rx + me->init_size_rx));
14293 ++}
14294 ++
14295 ++static inline int in_init_rw(struct module *me, void *loc)
14296 ++{
14297 ++ return (loc >= me->module_init_rw &&
14298 ++ loc < (me->module_init_rw + me->init_size_rw));
14299 ++}
14300 ++
14301 + static inline int in_init(struct module *me, void *loc)
14302 + {
14303 +- return (loc >= me->module_init &&
14304 +- loc <= (me->module_init + me->init_size));
14305 ++ return in_init_rx(me, loc) || in_init_rw(me, loc);
14306 ++}
14307 ++
14308 ++static inline int in_core_rx(struct module *me, void *loc)
14309 ++{
14310 ++ return (loc >= me->module_core_rx &&
14311 ++ loc < (me->module_core_rx + me->core_size_rx));
14312 ++}
14313 ++
14314 ++static inline int in_core_rw(struct module *me, void *loc)
14315 ++{
14316 ++ return (loc >= me->module_core_rw &&
14317 ++ loc < (me->module_core_rw + me->core_size_rw));
14318 + }
14319 +
14320 + static inline int in_core(struct module *me, void *loc)
14321 + {
14322 +- return (loc >= me->module_core &&
14323 +- loc <= (me->module_core + me->core_size));
14324 ++ return in_core_rx(me, loc) || in_core_rw(me, loc);
14325 + }
14326 +
14327 + static inline int in_local(struct module *me, void *loc)
14328 +@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
14329 + }
14330 +
14331 + /* align things a bit */
14332 +- me->core_size = ALIGN(me->core_size, 16);
14333 +- me->arch.got_offset = me->core_size;
14334 +- me->core_size += gots * sizeof(struct got_entry);
14335 +-
14336 +- me->core_size = ALIGN(me->core_size, 16);
14337 +- me->arch.fdesc_offset = me->core_size;
14338 +- me->core_size += fdescs * sizeof(Elf_Fdesc);
14339 +-
14340 +- me->core_size = ALIGN(me->core_size, 16);
14341 +- me->arch.stub_offset = me->core_size;
14342 +- me->core_size += stubs * sizeof(struct stub_entry);
14343 +-
14344 +- me->init_size = ALIGN(me->init_size, 16);
14345 +- me->arch.init_stub_offset = me->init_size;
14346 +- me->init_size += init_stubs * sizeof(struct stub_entry);
14347 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
14348 ++ me->arch.got_offset = me->core_size_rw;
14349 ++ me->core_size_rw += gots * sizeof(struct got_entry);
14350 ++
14351 ++ me->core_size_rw = ALIGN(me->core_size_rw, 16);
14352 ++ me->arch.fdesc_offset = me->core_size_rw;
14353 ++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
14354 ++
14355 ++ me->core_size_rx = ALIGN(me->core_size_rx, 16);
14356 ++ me->arch.stub_offset = me->core_size_rx;
14357 ++ me->core_size_rx += stubs * sizeof(struct stub_entry);
14358 ++
14359 ++ me->init_size_rx = ALIGN(me->init_size_rx, 16);
14360 ++ me->arch.init_stub_offset = me->init_size_rx;
14361 ++ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
14362 +
14363 + me->arch.got_max = gots;
14364 + me->arch.fdesc_max = fdescs;
14365 +@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
14366 +
14367 + BUG_ON(value == 0);
14368 +
14369 +- got = me->module_core + me->arch.got_offset;
14370 ++ got = me->module_core_rw + me->arch.got_offset;
14371 + for (i = 0; got[i].addr; i++)
14372 + if (got[i].addr == value)
14373 + goto out;
14374 +@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
14375 + #ifdef CONFIG_64BIT
14376 + static Elf_Addr get_fdesc(struct module *me, unsigned long value)
14377 + {
14378 +- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
14379 ++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
14380 +
14381 + if (!value) {
14382 + printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
14383 +@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
14384 +
14385 + /* Create new one */
14386 + fdesc->addr = value;
14387 +- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
14388 ++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
14389 + return (Elf_Addr)fdesc;
14390 + }
14391 + #endif /* CONFIG_64BIT */
14392 +@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
14393 + if(init_section) {
14394 + i = me->arch.init_stub_count++;
14395 + BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
14396 +- stub = me->module_init + me->arch.init_stub_offset +
14397 ++ stub = me->module_init_rx + me->arch.init_stub_offset +
14398 + i * sizeof(struct stub_entry);
14399 + } else {
14400 + i = me->arch.stub_count++;
14401 + BUG_ON(me->arch.stub_count > me->arch.stub_max);
14402 +- stub = me->module_core + me->arch.stub_offset +
14403 ++ stub = me->module_core_rx + me->arch.stub_offset +
14404 + i * sizeof(struct stub_entry);
14405 + }
14406 +
14407 +@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
14408 +
14409 + table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
14410 + end = table + sechdrs[me->arch.unwind_section].sh_size;
14411 +- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
14412 ++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
14413 +
14414 + DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
14415 + me->arch.unwind_section, table, end, gp);
14416 +diff -Nurp linux-2.6.23.15/arch/parisc/kernel/sys_parisc.c linux-2.6.23.15-grsec/arch/parisc/kernel/sys_parisc.c
14417 +--- linux-2.6.23.15/arch/parisc/kernel/sys_parisc.c 2007-10-09 21:31:38.000000000 +0100
14418 ++++ linux-2.6.23.15-grsec/arch/parisc/kernel/sys_parisc.c 2008-02-11 10:37:44.000000000 +0000
14419 +@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
14420 + if (flags & MAP_FIXED)
14421 + return addr;
14422 + if (!addr)
14423 +- addr = TASK_UNMAPPED_BASE;
14424 ++ addr = current->mm->mmap_base;
14425 +
14426 + if (filp) {
14427 + addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
14428 +diff -Nurp linux-2.6.23.15/arch/parisc/kernel/traps.c linux-2.6.23.15-grsec/arch/parisc/kernel/traps.c
14429 +--- linux-2.6.23.15/arch/parisc/kernel/traps.c 2007-10-09 21:31:38.000000000 +0100
14430 ++++ linux-2.6.23.15-grsec/arch/parisc/kernel/traps.c 2008-02-11 10:37:44.000000000 +0000
14431 +@@ -713,9 +713,7 @@ void handle_interruption(int code, struc
14432 +
14433 + down_read(&current->mm->mmap_sem);
14434 + vma = find_vma(current->mm,regs->iaoq[0]);
14435 +- if (vma && (regs->iaoq[0] >= vma->vm_start)
14436 +- && (vma->vm_flags & VM_EXEC)) {
14437 +-
14438 ++ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
14439 + fault_address = regs->iaoq[0];
14440 + fault_space = regs->iasq[0];
14441 +
14442 +diff -Nurp linux-2.6.23.15/arch/parisc/mm/fault.c linux-2.6.23.15-grsec/arch/parisc/mm/fault.c
14443 +--- linux-2.6.23.15/arch/parisc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
14444 ++++ linux-2.6.23.15-grsec/arch/parisc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
14445 +@@ -16,6 +16,8 @@
14446 + #include <linux/sched.h>
14447 + #include <linux/interrupt.h>
14448 + #include <linux/module.h>
14449 ++#include <linux/unistd.h>
14450 ++#include <linux/binfmts.h>
14451 +
14452 + #include <asm/uaccess.h>
14453 + #include <asm/traps.h>
14454 +@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
14455 + static unsigned long
14456 + parisc_acctyp(unsigned long code, unsigned int inst)
14457 + {
14458 +- if (code == 6 || code == 16)
14459 ++ if (code == 6 || code == 7 || code == 16)
14460 + return VM_EXEC;
14461 +
14462 + switch (inst & 0xf0000000) {
14463 +@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
14464 + }
14465 + #endif
14466 +
14467 ++#ifdef CONFIG_PAX_PAGEEXEC
14468 ++/*
14469 ++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
14470 ++ *
14471 ++ * returns 1 when task should be killed
14472 ++ * 2 when rt_sigreturn trampoline was detected
14473 ++ * 3 when unpatched PLT trampoline was detected
14474 ++ */
14475 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
14476 ++{
14477 ++
14478 ++#ifdef CONFIG_PAX_EMUPLT
14479 ++ int err;
14480 ++
14481 ++ do { /* PaX: unpatched PLT emulation */
14482 ++ unsigned int bl, depwi;
14483 ++
14484 ++ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
14485 ++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
14486 ++
14487 ++ if (err)
14488 ++ break;
14489 ++
14490 ++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
14491 ++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
14492 ++
14493 ++ err = get_user(ldw, (unsigned int *)addr);
14494 ++ err |= get_user(bv, (unsigned int *)(addr+4));
14495 ++ err |= get_user(ldw2, (unsigned int *)(addr+8));
14496 ++
14497 ++ if (err)
14498 ++ break;
14499 ++
14500 ++ if (ldw == 0x0E801096U &&
14501 ++ bv == 0xEAC0C000U &&
14502 ++ ldw2 == 0x0E881095U)
14503 ++ {
14504 ++ unsigned int resolver, map;
14505 ++
14506 ++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
14507 ++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
14508 ++ if (err)
14509 ++ break;
14510 ++
14511 ++ regs->gr[20] = instruction_pointer(regs)+8;
14512 ++ regs->gr[21] = map;
14513 ++ regs->gr[22] = resolver;
14514 ++ regs->iaoq[0] = resolver | 3UL;
14515 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
14516 ++ return 3;
14517 ++ }
14518 ++ }
14519 ++ } while (0);
14520 ++#endif
14521 ++
14522 ++#ifdef CONFIG_PAX_EMUTRAMP
14523 ++
14524 ++#ifndef CONFIG_PAX_EMUSIGRT
14525 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
14526 ++ return 1;
14527 ++#endif
14528 ++
14529 ++ do { /* PaX: rt_sigreturn emulation */
14530 ++ unsigned int ldi1, ldi2, bel, nop;
14531 ++
14532 ++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
14533 ++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
14534 ++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
14535 ++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
14536 ++
14537 ++ if (err)
14538 ++ break;
14539 ++
14540 ++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
14541 ++ ldi2 == 0x3414015AU &&
14542 ++ bel == 0xE4008200U &&
14543 ++ nop == 0x08000240U)
14544 ++ {
14545 ++ regs->gr[25] = (ldi1 & 2) >> 1;
14546 ++ regs->gr[20] = __NR_rt_sigreturn;
14547 ++ regs->gr[31] = regs->iaoq[1] + 16;
14548 ++ regs->sr[0] = regs->iasq[1];
14549 ++ regs->iaoq[0] = 0x100UL;
14550 ++ regs->iaoq[1] = regs->iaoq[0] + 4;
14551 ++ regs->iasq[0] = regs->sr[2];
14552 ++ regs->iasq[1] = regs->sr[2];
14553 ++ return 2;
14554 ++ }
14555 ++ } while (0);
14556 ++#endif
14557 ++
14558 ++ return 1;
14559 ++}
14560 ++
14561 ++void pax_report_insns(void *pc, void *sp)
14562 ++{
14563 ++ unsigned long i;
14564 ++
14565 ++ printk(KERN_ERR "PAX: bytes at PC: ");
14566 ++ for (i = 0; i < 5; i++) {
14567 ++ unsigned int c;
14568 ++ if (get_user(c, (unsigned int *)pc+i))
14569 ++ printk("???????? ");
14570 ++ else
14571 ++ printk("%08x ", c);
14572 ++ }
14573 ++ printk("\n");
14574 ++}
14575 ++#endif
14576 ++
14577 + void do_page_fault(struct pt_regs *regs, unsigned long code,
14578 + unsigned long address)
14579 + {
14580 +@@ -165,8 +277,33 @@ good_area:
14581 +
14582 + acc_type = parisc_acctyp(code,regs->iir);
14583 +
14584 +- if ((vma->vm_flags & acc_type) != acc_type)
14585 ++ if ((vma->vm_flags & acc_type) != acc_type) {
14586 ++
14587 ++#ifdef CONFIG_PAX_PAGEEXEC
14588 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
14589 ++ (address & ~3UL) == instruction_pointer(regs))
14590 ++ {
14591 ++ up_read(&mm->mmap_sem);
14592 ++ switch (pax_handle_fetch_fault(regs)) {
14593 ++
14594 ++#ifdef CONFIG_PAX_EMUPLT
14595 ++ case 3:
14596 ++ return;
14597 ++#endif
14598 ++
14599 ++#ifdef CONFIG_PAX_EMUTRAMP
14600 ++ case 2:
14601 ++ return;
14602 ++#endif
14603 ++
14604 ++ }
14605 ++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
14606 ++ do_exit(SIGKILL);
14607 ++ }
14608 ++#endif
14609 ++
14610 + goto bad_area;
14611 ++ }
14612 +
14613 + /*
14614 + * If for any reason at all we couldn't handle the fault, make
14615 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/module_32.c linux-2.6.23.15-grsec/arch/powerpc/kernel/module_32.c
14616 +--- linux-2.6.23.15/arch/powerpc/kernel/module_32.c 2007-10-09 21:31:38.000000000 +0100
14617 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/module_32.c 2008-02-11 10:37:44.000000000 +0000
14618 +@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
14619 + me->arch.core_plt_section = i;
14620 + }
14621 + if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
14622 +- printk("Module doesn't contain .plt or .init.plt sections.\n");
14623 ++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
14624 + return -ENOEXEC;
14625 + }
14626 +
14627 +@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
14628 +
14629 + DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
14630 + /* Init, or core PLT? */
14631 +- if (location >= mod->module_core
14632 +- && location < mod->module_core + mod->core_size)
14633 ++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
14634 ++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
14635 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
14636 +- else
14637 ++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
14638 ++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
14639 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
14640 ++ else {
14641 ++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
14642 ++ return ~0UL;
14643 ++ }
14644 +
14645 + /* Find this entry, or if that fails, the next avail. entry */
14646 + while (entry->jump[0]) {
14647 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/signal_32.c linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_32.c
14648 +--- linux-2.6.23.15/arch/powerpc/kernel/signal_32.c 2007-10-09 21:31:38.000000000 +0100
14649 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_32.c 2008-02-11 10:37:44.000000000 +0000
14650 +@@ -728,7 +728,7 @@ int handle_rt_signal32(unsigned long sig
14651 +
14652 + /* Save user registers on the stack */
14653 + frame = &rt_sf->uc.uc_mcontext;
14654 +- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
14655 ++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
14656 + if (save_user_regs(regs, frame, 0))
14657 + goto badframe;
14658 + regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
14659 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/signal_64.c linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_64.c
14660 +--- linux-2.6.23.15/arch/powerpc/kernel/signal_64.c 2007-10-09 21:31:38.000000000 +0100
14661 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_64.c 2008-02-11 10:37:44.000000000 +0000
14662 +@@ -359,7 +359,7 @@ int handle_rt_signal64(int signr, struct
14663 + current->thread.fpscr.val = 0;
14664 +
14665 + /* Set up to return from userspace. */
14666 +- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
14667 ++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
14668 + regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
14669 + } else {
14670 + err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
14671 +diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/vdso.c linux-2.6.23.15-grsec/arch/powerpc/kernel/vdso.c
14672 +--- linux-2.6.23.15/arch/powerpc/kernel/vdso.c 2007-10-09 21:31:38.000000000 +0100
14673 ++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/vdso.c 2008-02-11 10:37:44.000000000 +0000
14674 +@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l
14675 + vdso_base = VDSO32_MBASE;
14676 + #endif
14677 +
14678 +- current->mm->context.vdso_base = 0;
14679 ++ current->mm->context.vdso_base = ~0UL;
14680 +
14681 + /* vDSO has a problem and was disabled, just don't "enable" it for the
14682 + * process
14683 +@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l
14684 + */
14685 + down_write(&mm->mmap_sem);
14686 + vdso_base = get_unmapped_area(NULL, vdso_base,
14687 +- vdso_pages << PAGE_SHIFT, 0, 0);
14688 ++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
14689 + if (IS_ERR_VALUE(vdso_base)) {
14690 + rc = vdso_base;
14691 + goto fail_mmapsem;
14692 +diff -Nurp linux-2.6.23.15/arch/powerpc/mm/fault.c linux-2.6.23.15-grsec/arch/powerpc/mm/fault.c
14693 +--- linux-2.6.23.15/arch/powerpc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
14694 ++++ linux-2.6.23.15-grsec/arch/powerpc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
14695 +@@ -29,6 +29,12 @@
14696 + #include <linux/module.h>
14697 + #include <linux/kprobes.h>
14698 + #include <linux/kdebug.h>
14699 ++#include <linux/binfmts.h>
14700 ++#include <linux/slab.h>
14701 ++#include <linux/pagemap.h>
14702 ++#include <linux/compiler.h>
14703 ++#include <linux/binfmts.h>
14704 ++#include <linux/unistd.h>
14705 +
14706 + #include <asm/page.h>
14707 + #include <asm/pgtable.h>
14708 +@@ -62,6 +68,364 @@ static inline int notify_page_fault(stru
14709 + }
14710 + #endif
14711 +
14712 ++#ifdef CONFIG_PAX_EMUSIGRT
14713 ++void pax_syscall_close(struct vm_area_struct *vma)
14714 ++{
14715 ++ vma->vm_mm->call_syscall = 0UL;
14716 ++}
14717 ++
14718 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
14719 ++{
14720 ++ struct page *page;
14721 ++ unsigned int *kaddr;
14722 ++
14723 ++ page = alloc_page(GFP_HIGHUSER);
14724 ++ if (!page)
14725 ++ return NOPAGE_OOM;
14726 ++
14727 ++ kaddr = kmap(page);
14728 ++ memset(kaddr, 0, PAGE_SIZE);
14729 ++ kaddr[0] = 0x44000002U; /* sc */
14730 ++ __flush_dcache_icache(kaddr);
14731 ++ kunmap(page);
14732 ++ if (type)
14733 ++ *type = VM_FAULT_MAJOR;
14734 ++ return page;
14735 ++}
14736 ++
14737 ++static struct vm_operations_struct pax_vm_ops = {
14738 ++ .close = pax_syscall_close,
14739 ++ .nopage = pax_syscall_nopage,
14740 ++};
14741 ++
14742 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
14743 ++{
14744 ++ int ret;
14745 ++
14746 ++ memset(vma, 0, sizeof(*vma));
14747 ++ vma->vm_mm = current->mm;
14748 ++ vma->vm_start = addr;
14749 ++ vma->vm_end = addr + PAGE_SIZE;
14750 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
14751 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14752 ++ vma->vm_ops = &pax_vm_ops;
14753 ++
14754 ++ ret = insert_vm_struct(current->mm, vma);
14755 ++ if (ret)
14756 ++ return ret;
14757 ++
14758 ++ ++current->mm->total_vm;
14759 ++ return 0;
14760 ++}
14761 ++#endif
14762 ++
14763 ++#ifdef CONFIG_PAX_PAGEEXEC
14764 ++/*
14765 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
14766 ++ *
14767 ++ * returns 1 when task should be killed
14768 ++ * 2 when patched GOT trampoline was detected
14769 ++ * 3 when patched PLT trampoline was detected
14770 ++ * 4 when unpatched PLT trampoline was detected
14771 ++ * 5 when sigreturn trampoline was detected
14772 ++ * 6 when rt_sigreturn trampoline was detected
14773 ++ */
14774 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
14775 ++{
14776 ++
14777 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
14778 ++ int err;
14779 ++#endif
14780 ++
14781 ++#ifdef CONFIG_PAX_EMUPLT
14782 ++ do { /* PaX: patched GOT emulation */
14783 ++ unsigned int blrl;
14784 ++
14785 ++ err = get_user(blrl, (unsigned int *)regs->nip);
14786 ++
14787 ++ if (!err && blrl == 0x4E800021U) {
14788 ++ unsigned long temp = regs->nip;
14789 ++
14790 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
14791 ++ regs->link = temp + 4UL;
14792 ++ return 2;
14793 ++ }
14794 ++ } while (0);
14795 ++
14796 ++ do { /* PaX: patched PLT emulation #1 */
14797 ++ unsigned int b;
14798 ++
14799 ++ err = get_user(b, (unsigned int *)regs->nip);
14800 ++
14801 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
14802 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
14803 ++ return 3;
14804 ++ }
14805 ++ } while (0);
14806 ++
14807 ++ do { /* PaX: unpatched PLT emulation #1 */
14808 ++ unsigned int li, b;
14809 ++
14810 ++ err = get_user(li, (unsigned int *)regs->nip);
14811 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
14812 ++
14813 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
14814 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
14815 ++ unsigned long addr = b | 0xFC000000UL;
14816 ++
14817 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
14818 ++ err = get_user(rlwinm, (unsigned int *)addr);
14819 ++ err |= get_user(add, (unsigned int *)(addr+4));
14820 ++ err |= get_user(li2, (unsigned int *)(addr+8));
14821 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
14822 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
14823 ++ err |= get_user(li3, (unsigned int *)(addr+20));
14824 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
14825 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
14826 ++
14827 ++ if (err)
14828 ++ break;
14829 ++
14830 ++ if (rlwinm == 0x556C083CU &&
14831 ++ add == 0x7D6C5A14U &&
14832 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
14833 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
14834 ++ mtctr == 0x7D8903A6U &&
14835 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
14836 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
14837 ++ bctr == 0x4E800420U)
14838 ++ {
14839 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14840 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14841 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
14842 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14843 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
14844 ++ regs->nip = regs->ctr;
14845 ++ return 4;
14846 ++ }
14847 ++ }
14848 ++ } while (0);
14849 ++
14850 ++#if 0
14851 ++ do { /* PaX: unpatched PLT emulation #2 */
14852 ++ unsigned int lis, lwzu, b, bctr;
14853 ++
14854 ++ err = get_user(lis, (unsigned int *)regs->nip);
14855 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
14856 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
14857 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
14858 ++
14859 ++ if (err)
14860 ++ break;
14861 ++
14862 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
14863 ++ (lwzu & 0xU) == 0xU &&
14864 ++ (b & 0xFC000003U) == 0x48000000U &&
14865 ++ bctr == 0x4E800420U)
14866 ++ {
14867 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
14868 ++ unsigned long addr = b | 0xFC000000UL;
14869 ++
14870 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
14871 ++ err = get_user(addis, (unsigned int*)addr);
14872 ++ err |= get_user(addi, (unsigned int*)(addr+4));
14873 ++ err |= get_user(rlwinm, (unsigned int*)(addr+8));
14874 ++ err |= get_user(add, (unsigned int*)(addr+12));
14875 ++ err |= get_user(li2, (unsigned int*)(addr+16));
14876 ++ err |= get_user(addis2, (unsigned int*)(addr+20));
14877 ++ err |= get_user(mtctr, (unsigned int*)(addr+24));
14878 ++ err |= get_user(li3, (unsigned int*)(addr+28));
14879 ++ err |= get_user(addis3, (unsigned int*)(addr+32));
14880 ++ err |= get_user(bctr, (unsigned int*)(addr+36));
14881 ++
14882 ++ if (err)
14883 ++ break;
14884 ++
14885 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
14886 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
14887 ++ rlwinm == 0x556C083CU &&
14888 ++ add == 0x7D6C5A14U &&
14889 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
14890 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
14891 ++ mtctr == 0x7D8903A6U &&
14892 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
14893 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
14894 ++ bctr == 0x4E800420U)
14895 ++ {
14896 ++ regs->gpr[PT_R11] =
14897 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14898 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14899 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
14900 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14901 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
14902 ++ regs->nip = regs->ctr;
14903 ++ return 4;
14904 ++ }
14905 ++ }
14906 ++ } while (0);
14907 ++#endif
14908 ++
14909 ++ do { /* PaX: unpatched PLT emulation #3 */
14910 ++ unsigned int li, b;
14911 ++
14912 ++ err = get_user(li, (unsigned int *)regs->nip);
14913 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
14914 ++
14915 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
14916 ++ unsigned int addis, lwz, mtctr, bctr;
14917 ++ unsigned long addr = b | 0xFC000000UL;
14918 ++
14919 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
14920 ++ err = get_user(addis, (unsigned int *)addr);
14921 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
14922 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
14923 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
14924 ++
14925 ++ if (err)
14926 ++ break;
14927 ++
14928 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
14929 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
14930 ++ mtctr == 0x7D6903A6U &&
14931 ++ bctr == 0x4E800420U)
14932 ++ {
14933 ++ unsigned int r11;
14934 ++
14935 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14936 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
14937 ++
14938 ++ err = get_user(r11, (unsigned int *)addr);
14939 ++ if (err)
14940 ++ break;
14941 ++
14942 ++ regs->gpr[PT_R11] = r11;
14943 ++ regs->ctr = r11;
14944 ++ regs->nip = r11;
14945 ++ return 4;
14946 ++ }
14947 ++ }
14948 ++ } while (0);
14949 ++#endif
14950 ++
14951 ++#ifdef CONFIG_PAX_EMUSIGRT
14952 ++ do { /* PaX: sigreturn emulation */
14953 ++ unsigned int li, sc;
14954 ++
14955 ++ err = get_user(li, (unsigned int *)regs->nip);
14956 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
14957 ++
14958 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
14959 ++ struct vm_area_struct *vma;
14960 ++ unsigned long call_syscall;
14961 ++
14962 ++ down_read(&current->mm->mmap_sem);
14963 ++ call_syscall = current->mm->call_syscall;
14964 ++ up_read(&current->mm->mmap_sem);
14965 ++ if (likely(call_syscall))
14966 ++ goto emulate;
14967 ++
14968 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
14969 ++
14970 ++ down_write(&current->mm->mmap_sem);
14971 ++ if (current->mm->call_syscall) {
14972 ++ call_syscall = current->mm->call_syscall;
14973 ++ up_write(&current->mm->mmap_sem);
14974 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
14975 ++ goto emulate;
14976 ++ }
14977 ++
14978 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
14979 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
14980 ++ up_write(&current->mm->mmap_sem);
14981 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
14982 ++ return 1;
14983 ++ }
14984 ++
14985 ++ if (pax_insert_vma(vma, call_syscall)) {
14986 ++ up_write(&current->mm->mmap_sem);
14987 ++ kmem_cache_free(vm_area_cachep, vma);
14988 ++ return 1;
14989 ++ }
14990 ++
14991 ++ current->mm->call_syscall = call_syscall;
14992 ++ up_write(&current->mm->mmap_sem);
14993 ++
14994 ++emulate:
14995 ++ regs->gpr[PT_R0] = __NR_sigreturn;
14996 ++ regs->nip = call_syscall;
14997 ++ return 5;
14998 ++ }
14999 ++ } while (0);
15000 ++
15001 ++ do { /* PaX: rt_sigreturn emulation */
15002 ++ unsigned int li, sc;
15003 ++
15004 ++ err = get_user(li, (unsigned int *)regs->nip);
15005 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
15006 ++
15007 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
15008 ++ struct vm_area_struct *vma;
15009 ++ unsigned int call_syscall;
15010 ++
15011 ++ down_read(&current->mm->mmap_sem);
15012 ++ call_syscall = current->mm->call_syscall;
15013 ++ up_read(&current->mm->mmap_sem);
15014 ++ if (likely(call_syscall))
15015 ++ goto rt_emulate;
15016 ++
15017 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
15018 ++
15019 ++ down_write(&current->mm->mmap_sem);
15020 ++ if (current->mm->call_syscall) {
15021 ++ call_syscall = current->mm->call_syscall;
15022 ++ up_write(&current->mm->mmap_sem);
15023 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15024 ++ goto rt_emulate;
15025 ++ }
15026 ++
15027 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
15028 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
15029 ++ up_write(&current->mm->mmap_sem);
15030 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15031 ++ return 1;
15032 ++ }
15033 ++
15034 ++ if (pax_insert_vma(vma, call_syscall)) {
15035 ++ up_write(&current->mm->mmap_sem);
15036 ++ kmem_cache_free(vm_area_cachep, vma);
15037 ++ return 1;
15038 ++ }
15039 ++
15040 ++ current->mm->call_syscall = call_syscall;
15041 ++ up_write(&current->mm->mmap_sem);
15042 ++
15043 ++rt_emulate:
15044 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
15045 ++ regs->nip = call_syscall;
15046 ++ return 6;
15047 ++ }
15048 ++ } while (0);
15049 ++#endif
15050 ++
15051 ++ return 1;
15052 ++}
15053 ++
15054 ++void pax_report_insns(void *pc, void *sp)
15055 ++{
15056 ++ unsigned long i;
15057 ++
15058 ++ printk(KERN_ERR "PAX: bytes at PC: ");
15059 ++ for (i = 0; i < 5; i++) {
15060 ++ unsigned int c;
15061 ++ if (get_user(c, (unsigned int *)pc+i))
15062 ++ printk("???????? ");
15063 ++ else
15064 ++ printk("%08x ", c);
15065 ++ }
15066 ++ printk("\n");
15067 ++}
15068 ++#endif
15069 ++
15070 + /*
15071 + * Check whether the instruction at regs->nip is a store using
15072 + * an update addressing form which will update r1.
15073 +@@ -157,7 +521,7 @@ int __kprobes do_page_fault(struct pt_re
15074 + * indicate errors in DSISR but can validly be set in SRR1.
15075 + */
15076 + if (trap == 0x400)
15077 +- error_code &= 0x48200000;
15078 ++ error_code &= 0x58200000;
15079 + else
15080 + is_write = error_code & DSISR_ISSTORE;
15081 + #else
15082 +@@ -357,6 +721,37 @@ bad_area:
15083 + bad_area_nosemaphore:
15084 + /* User mode accesses cause a SIGSEGV */
15085 + if (user_mode(regs)) {
15086 ++
15087 ++#ifdef CONFIG_PAX_PAGEEXEC
15088 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
15089 ++#ifdef CONFIG_PPC64
15090 ++ if (is_exec && (error_code & DSISR_PROTFAULT)) {
15091 ++#else
15092 ++ if (is_exec && regs->nip == address) {
15093 ++#endif
15094 ++ switch (pax_handle_fetch_fault(regs)) {
15095 ++
15096 ++#ifdef CONFIG_PAX_EMUPLT
15097 ++ case 2:
15098 ++ case 3:
15099 ++ case 4:
15100 ++ return 0;
15101 ++#endif
15102 ++
15103 ++#ifdef CONFIG_PAX_EMUSIGRT
15104 ++ case 5:
15105 ++ case 6:
15106 ++ return 0;
15107 ++#endif
15108 ++
15109 ++ }
15110 ++
15111 ++ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
15112 ++ do_exit(SIGKILL);
15113 ++ }
15114 ++ }
15115 ++#endif
15116 ++
15117 + _exception(SIGSEGV, regs, code, address);
15118 + return 0;
15119 + }
15120 +diff -Nurp linux-2.6.23.15/arch/powerpc/mm/mmap.c linux-2.6.23.15-grsec/arch/powerpc/mm/mmap.c
15121 +--- linux-2.6.23.15/arch/powerpc/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
15122 ++++ linux-2.6.23.15-grsec/arch/powerpc/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
15123 +@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
15124 + */
15125 + if (mmap_is_legacy()) {
15126 + mm->mmap_base = TASK_UNMAPPED_BASE;
15127 ++
15128 ++#ifdef CONFIG_PAX_RANDMMAP
15129 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
15130 ++ mm->mmap_base += mm->delta_mmap;
15131 ++#endif
15132 ++
15133 + mm->get_unmapped_area = arch_get_unmapped_area;
15134 + mm->unmap_area = arch_unmap_area;
15135 + } else {
15136 + mm->mmap_base = mmap_base();
15137 ++
15138 ++#ifdef CONFIG_PAX_RANDMMAP
15139 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
15140 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
15141 ++#endif
15142 ++
15143 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
15144 + mm->unmap_area = arch_unmap_area_topdown;
15145 + }
15146 +diff -Nurp linux-2.6.23.15/arch/ppc/mm/fault.c linux-2.6.23.15-grsec/arch/ppc/mm/fault.c
15147 +--- linux-2.6.23.15/arch/ppc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
15148 ++++ linux-2.6.23.15-grsec/arch/ppc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
15149 +@@ -25,6 +25,11 @@
15150 + #include <linux/interrupt.h>
15151 + #include <linux/highmem.h>
15152 + #include <linux/module.h>
15153 ++#include <linux/slab.h>
15154 ++#include <linux/pagemap.h>
15155 ++#include <linux/compiler.h>
15156 ++#include <linux/binfmts.h>
15157 ++#include <linux/unistd.h>
15158 +
15159 + #include <asm/page.h>
15160 + #include <asm/pgtable.h>
15161 +@@ -48,6 +53,364 @@ unsigned long pte_misses; /* updated by
15162 + unsigned long pte_errors; /* updated by do_page_fault() */
15163 + unsigned int probingmem;
15164 +
15165 ++#ifdef CONFIG_PAX_EMUSIGRT
15166 ++void pax_syscall_close(struct vm_area_struct *vma)
15167 ++{
15168 ++ vma->vm_mm->call_syscall = 0UL;
15169 ++}
15170 ++
15171 ++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
15172 ++{
15173 ++ struct page *page;
15174 ++ unsigned int *kaddr;
15175 ++
15176 ++ page = alloc_page(GFP_HIGHUSER);
15177 ++ if (!page)
15178 ++ return NOPAGE_OOM;
15179 ++
15180 ++ kaddr = kmap(page);
15181 ++ memset(kaddr, 0, PAGE_SIZE);
15182 ++ kaddr[0] = 0x44000002U; /* sc */
15183 ++ __flush_dcache_icache(kaddr);
15184 ++ kunmap(page);
15185 ++ if (type)
15186 ++ *type = VM_FAULT_MAJOR;
15187 ++ return page;
15188 ++}
15189 ++
15190 ++static struct vm_operations_struct pax_vm_ops = {
15191 ++ .close = pax_syscall_close,
15192 ++ .nopage = pax_syscall_nopage,
15193 ++};
15194 ++
15195 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
15196 ++{
15197 ++ int ret;
15198 ++
15199 ++ memset(vma, 0, sizeof(*vma));
15200 ++ vma->vm_mm = current->mm;
15201 ++ vma->vm_start = addr;
15202 ++ vma->vm_end = addr + PAGE_SIZE;
15203 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
15204 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
15205 ++ vma->vm_ops = &pax_vm_ops;
15206 ++
15207 ++ ret = insert_vm_struct(current->mm, vma);
15208 ++ if (ret)
15209 ++ return ret;
15210 ++
15211 ++ ++current->mm->total_vm;
15212 ++ return 0;
15213 ++}
15214 ++#endif
15215 ++
15216 ++#ifdef CONFIG_PAX_PAGEEXEC
15217 ++/*
15218 ++ * PaX: decide what to do with offenders (regs->nip = fault address)
15219 ++ *
15220 ++ * returns 1 when task should be killed
15221 ++ * 2 when patched GOT trampoline was detected
15222 ++ * 3 when patched PLT trampoline was detected
15223 ++ * 4 when unpatched PLT trampoline was detected
15224 ++ * 5 when sigreturn trampoline was detected
15225 ++ * 6 when rt_sigreturn trampoline was detected
15226 ++ */
15227 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
15228 ++{
15229 ++
15230 ++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
15231 ++ int err;
15232 ++#endif
15233 ++
15234 ++#ifdef CONFIG_PAX_EMUPLT
15235 ++ do { /* PaX: patched GOT emulation */
15236 ++ unsigned int blrl;
15237 ++
15238 ++ err = get_user(blrl, (unsigned int *)regs->nip);
15239 ++
15240 ++ if (!err && blrl == 0x4E800021U) {
15241 ++ unsigned long temp = regs->nip;
15242 ++
15243 ++ regs->nip = regs->link & 0xFFFFFFFCUL;
15244 ++ regs->link = temp + 4UL;
15245 ++ return 2;
15246 ++ }
15247 ++ } while (0);
15248 ++
15249 ++ do { /* PaX: patched PLT emulation #1 */
15250 ++ unsigned int b;
15251 ++
15252 ++ err = get_user(b, (unsigned int *)regs->nip);
15253 ++
15254 ++ if (!err && (b & 0xFC000003U) == 0x48000000U) {
15255 ++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
15256 ++ return 3;
15257 ++ }
15258 ++ } while (0);
15259 ++
15260 ++ do { /* PaX: unpatched PLT emulation #1 */
15261 ++ unsigned int li, b;
15262 ++
15263 ++ err = get_user(li, (unsigned int *)regs->nip);
15264 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
15265 ++
15266 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
15267 ++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
15268 ++ unsigned long addr = b | 0xFC000000UL;
15269 ++
15270 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
15271 ++ err = get_user(rlwinm, (unsigned int *)addr);
15272 ++ err |= get_user(add, (unsigned int *)(addr+4));
15273 ++ err |= get_user(li2, (unsigned int *)(addr+8));
15274 ++ err |= get_user(addis2, (unsigned int *)(addr+12));
15275 ++ err |= get_user(mtctr, (unsigned int *)(addr+16));
15276 ++ err |= get_user(li3, (unsigned int *)(addr+20));
15277 ++ err |= get_user(addis3, (unsigned int *)(addr+24));
15278 ++ err |= get_user(bctr, (unsigned int *)(addr+28));
15279 ++
15280 ++ if (err)
15281 ++ break;
15282 ++
15283 ++ if (rlwinm == 0x556C083CU &&
15284 ++ add == 0x7D6C5A14U &&
15285 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
15286 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
15287 ++ mtctr == 0x7D8903A6U &&
15288 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
15289 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
15290 ++ bctr == 0x4E800420U)
15291 ++ {
15292 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15293 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15294 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
15295 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15296 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
15297 ++ regs->nip = regs->ctr;
15298 ++ return 4;
15299 ++ }
15300 ++ }
15301 ++ } while (0);
15302 ++
15303 ++#if 0
15304 ++ do { /* PaX: unpatched PLT emulation #2 */
15305 ++ unsigned int lis, lwzu, b, bctr;
15306 ++
15307 ++ err = get_user(lis, (unsigned int *)regs->nip);
15308 ++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
15309 ++ err |= get_user(b, (unsigned int *)(regs->nip+8));
15310 ++ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
15311 ++
15312 ++ if (err)
15313 ++ break;
15314 ++
15315 ++ if ((lis & 0xFFFF0000U) == 0x39600000U &&
15316 ++ (lwzu & 0xU) == 0xU &&
15317 ++ (b & 0xFC000003U) == 0x48000000U &&
15318 ++ bctr == 0x4E800420U)
15319 ++ {
15320 ++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
15321 ++ unsigned long addr = b | 0xFC000000UL;
15322 ++
15323 ++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
15324 ++ err = get_user(addis, (unsigned int*)addr);
15325 ++ err |= get_user(addi, (unsigned int*)(addr+4));
15326 ++ err |= get_user(rlwinm, (unsigned int*)(addr+8));
15327 ++ err |= get_user(add, (unsigned int*)(addr+12));
15328 ++ err |= get_user(li2, (unsigned int*)(addr+16));
15329 ++ err |= get_user(addis2, (unsigned int*)(addr+20));
15330 ++ err |= get_user(mtctr, (unsigned int*)(addr+24));
15331 ++ err |= get_user(li3, (unsigned int*)(addr+28));
15332 ++ err |= get_user(addis3, (unsigned int*)(addr+32));
15333 ++ err |= get_user(bctr, (unsigned int*)(addr+36));
15334 ++
15335 ++ if (err)
15336 ++ break;
15337 ++
15338 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
15339 ++ (addi & 0xFFFF0000U) == 0x396B0000U &&
15340 ++ rlwinm == 0x556C083CU &&
15341 ++ add == 0x7D6C5A14U &&
15342 ++ (li2 & 0xFFFF0000U) == 0x39800000U &&
15343 ++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
15344 ++ mtctr == 0x7D8903A6U &&
15345 ++ (li3 & 0xFFFF0000U) == 0x39800000U &&
15346 ++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
15347 ++ bctr == 0x4E800420U)
15348 ++ {
15349 ++ regs->gpr[PT_R11] =
15350 ++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15351 ++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15352 ++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
15353 ++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15354 ++ regs->ctr += (addis2 & 0xFFFFU) << 16;
15355 ++ regs->nip = regs->ctr;
15356 ++ return 4;
15357 ++ }
15358 ++ }
15359 ++ } while (0);
15360 ++#endif
15361 ++
15362 ++ do { /* PaX: unpatched PLT emulation #3 */
15363 ++ unsigned int li, b;
15364 ++
15365 ++ err = get_user(li, (unsigned int *)regs->nip);
15366 ++ err |= get_user(b, (unsigned int *)(regs->nip+4));
15367 ++
15368 ++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
15369 ++ unsigned int addis, lwz, mtctr, bctr;
15370 ++ unsigned long addr = b | 0xFC000000UL;
15371 ++
15372 ++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
15373 ++ err = get_user(addis, (unsigned int *)addr);
15374 ++ err |= get_user(lwz, (unsigned int *)(addr+4));
15375 ++ err |= get_user(mtctr, (unsigned int *)(addr+8));
15376 ++ err |= get_user(bctr, (unsigned int *)(addr+12));
15377 ++
15378 ++ if (err)
15379 ++ break;
15380 ++
15381 ++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
15382 ++ (lwz & 0xFFFF0000U) == 0x816B0000U &&
15383 ++ mtctr == 0x7D6903A6U &&
15384 ++ bctr == 0x4E800420U)
15385 ++ {
15386 ++ unsigned int r11;
15387 ++
15388 ++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15389 ++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
15390 ++
15391 ++ err = get_user(r11, (unsigned int *)addr);
15392 ++ if (err)
15393 ++ break;
15394 ++
15395 ++ regs->gpr[PT_R11] = r11;
15396 ++ regs->ctr = r11;
15397 ++ regs->nip = r11;
15398 ++ return 4;
15399 ++ }
15400 ++ }
15401 ++ } while (0);
15402 ++#endif
15403 ++
15404 ++#ifdef CONFIG_PAX_EMUSIGRT
15405 ++ do { /* PaX: sigreturn emulation */
15406 ++ unsigned int li, sc;
15407 ++
15408 ++ err = get_user(li, (unsigned int *)regs->nip);
15409 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
15410 ++
15411 ++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
15412 ++ struct vm_area_struct *vma;
15413 ++ unsigned long call_syscall;
15414 ++
15415 ++ down_read(&current->mm->mmap_sem);
15416 ++ call_syscall = current->mm->call_syscall;
15417 ++ up_read(&current->mm->mmap_sem);
15418 ++ if (likely(call_syscall))
15419 ++ goto emulate;
15420 ++
15421 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
15422 ++
15423 ++ down_write(&current->mm->mmap_sem);
15424 ++ if (current->mm->call_syscall) {
15425 ++ call_syscall = current->mm->call_syscall;
15426 ++ up_write(&current->mm->mmap_sem);
15427 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15428 ++ goto emulate;
15429 ++ }
15430 ++
15431 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
15432 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
15433 ++ up_write(&current->mm->mmap_sem);
15434 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15435 ++ return 1;
15436 ++ }
15437 ++
15438 ++ if (pax_insert_vma(vma, call_syscall)) {
15439 ++ up_write(&current->mm->mmap_sem);
15440 ++ kmem_cache_free(vm_area_cachep, vma);
15441 ++ return 1;
15442 ++ }
15443 ++
15444 ++ current->mm->call_syscall = call_syscall;
15445 ++ up_write(&current->mm->mmap_sem);
15446 ++
15447 ++emulate:
15448 ++ regs->gpr[PT_R0] = __NR_sigreturn;
15449 ++ regs->nip = call_syscall;
15450 ++ return 5;
15451 ++ }
15452 ++ } while (0);
15453 ++
15454 ++ do { /* PaX: rt_sigreturn emulation */
15455 ++ unsigned int li, sc;
15456 ++
15457 ++ err = get_user(li, (unsigned int *)regs->nip);
15458 ++ err |= get_user(sc, (unsigned int *)(regs->nip+4));
15459 ++
15460 ++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
15461 ++ struct vm_area_struct *vma;
15462 ++ unsigned int call_syscall;
15463 ++
15464 ++ down_read(&current->mm->mmap_sem);
15465 ++ call_syscall = current->mm->call_syscall;
15466 ++ up_read(&current->mm->mmap_sem);
15467 ++ if (likely(call_syscall))
15468 ++ goto rt_emulate;
15469 ++
15470 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
15471 ++
15472 ++ down_write(&current->mm->mmap_sem);
15473 ++ if (current->mm->call_syscall) {
15474 ++ call_syscall = current->mm->call_syscall;
15475 ++ up_write(&current->mm->mmap_sem);
15476 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15477 ++ goto rt_emulate;
15478 ++ }
15479 ++
15480 ++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
15481 ++ if (!vma || (call_syscall & ~PAGE_MASK)) {
15482 ++ up_write(&current->mm->mmap_sem);
15483 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15484 ++ return 1;
15485 ++ }
15486 ++
15487 ++ if (pax_insert_vma(vma, call_syscall)) {
15488 ++ up_write(&current->mm->mmap_sem);
15489 ++ kmem_cache_free(vm_area_cachep, vma);
15490 ++ return 1;
15491 ++ }
15492 ++
15493 ++ current->mm->call_syscall = call_syscall;
15494 ++ up_write(&current->mm->mmap_sem);
15495 ++
15496 ++rt_emulate:
15497 ++ regs->gpr[PT_R0] = __NR_rt_sigreturn;
15498 ++ regs->nip = call_syscall;
15499 ++ return 6;
15500 ++ }
15501 ++ } while (0);
15502 ++#endif
15503 ++
15504 ++ return 1;
15505 ++}
15506 ++
15507 ++void pax_report_insns(void *pc, void *sp)
15508 ++{
15509 ++ unsigned long i;
15510 ++
15511 ++ printk(KERN_ERR "PAX: bytes at PC: ");
15512 ++ for (i = 0; i < 5; i++) {
15513 ++ unsigned int c;
15514 ++ if (get_user(c, (unsigned int *)pc+i))
15515 ++ printk("???????? ");
15516 ++ else
15517 ++ printk("%08x ", c);
15518 ++ }
15519 ++ printk("\n");
15520 ++}
15521 ++#endif
15522 ++
15523 + /*
15524 + * Check whether the instruction at regs->nip is a store using
15525 + * an update addressing form which will update r1.
15526 +@@ -109,7 +472,7 @@ int do_page_fault(struct pt_regs *regs,
15527 + * indicate errors in DSISR but can validly be set in SRR1.
15528 + */
15529 + if (TRAP(regs) == 0x400)
15530 +- error_code &= 0x48200000;
15531 ++ error_code &= 0x58200000;
15532 + else
15533 + is_write = error_code & 0x02000000;
15534 + #endif /* CONFIG_4xx || CONFIG_BOOKE */
15535 +@@ -204,15 +567,14 @@ good_area:
15536 + pte_t *ptep;
15537 + pmd_t *pmdp;
15538 +
15539 +-#if 0
15540 ++#if 1
15541 + /* It would be nice to actually enforce the VM execute
15542 + permission on CPUs which can do so, but far too
15543 + much stuff in userspace doesn't get the permissions
15544 + right, so we let any page be executed for now. */
15545 + if (! (vma->vm_flags & VM_EXEC))
15546 + goto bad_area;
15547 +-#endif
15548 +-
15549 ++#else
15550 + /* Since 4xx/Book-E supports per-page execute permission,
15551 + * we lazily flush dcache to icache. */
15552 + ptep = NULL;
15553 +@@ -235,6 +597,7 @@ good_area:
15554 + pte_unmap_unlock(ptep, ptl);
15555 + }
15556 + #endif
15557 ++#endif
15558 + /* a read */
15559 + } else {
15560 + /* protection fault */
15561 +@@ -278,6 +641,33 @@ bad_area:
15562 +
15563 + /* User mode accesses cause a SIGSEGV */
15564 + if (user_mode(regs)) {
15565 ++
15566 ++#ifdef CONFIG_PAX_PAGEEXEC
15567 ++ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
15568 ++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
15569 ++ switch (pax_handle_fetch_fault(regs)) {
15570 ++
15571 ++#ifdef CONFIG_PAX_EMUPLT
15572 ++ case 2:
15573 ++ case 3:
15574 ++ case 4:
15575 ++ return 0;
15576 ++#endif
15577 ++
15578 ++#ifdef CONFIG_PAX_EMUSIGRT
15579 ++ case 5:
15580 ++ case 6:
15581 ++ return 0;
15582 ++#endif
15583 ++
15584 ++ }
15585 ++
15586 ++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
15587 ++ do_exit(SIGKILL);
15588 ++ }
15589 ++ }
15590 ++#endif
15591 ++
15592 + _exception(SIGSEGV, regs, code, address);
15593 + return 0;
15594 + }
15595 +diff -Nurp linux-2.6.23.15/arch/s390/kernel/module.c linux-2.6.23.15-grsec/arch/s390/kernel/module.c
15596 +--- linux-2.6.23.15/arch/s390/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
15597 ++++ linux-2.6.23.15-grsec/arch/s390/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
15598 +@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
15599 +
15600 + /* Increase core size by size of got & plt and set start
15601 + offsets for got and plt. */
15602 +- me->core_size = ALIGN(me->core_size, 4);
15603 +- me->arch.got_offset = me->core_size;
15604 +- me->core_size += me->arch.got_size;
15605 +- me->arch.plt_offset = me->core_size;
15606 +- me->core_size += me->arch.plt_size;
15607 ++ me->core_size_rw = ALIGN(me->core_size_rw, 4);
15608 ++ me->arch.got_offset = me->core_size_rw;
15609 ++ me->core_size_rw += me->arch.got_size;
15610 ++ me->arch.plt_offset = me->core_size_rx;
15611 ++ me->core_size_rx += me->arch.plt_size;
15612 + return 0;
15613 + }
15614 +
15615 +@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
15616 + if (info->got_initialized == 0) {
15617 + Elf_Addr *gotent;
15618 +
15619 +- gotent = me->module_core + me->arch.got_offset +
15620 ++ gotent = me->module_core_rw + me->arch.got_offset +
15621 + info->got_offset;
15622 + *gotent = val;
15623 + info->got_initialized = 1;
15624 +@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
15625 + else if (r_type == R_390_GOTENT ||
15626 + r_type == R_390_GOTPLTENT)
15627 + *(unsigned int *) loc =
15628 +- (val + (Elf_Addr) me->module_core - loc) >> 1;
15629 ++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
15630 + else if (r_type == R_390_GOT64 ||
15631 + r_type == R_390_GOTPLT64)
15632 + *(unsigned long *) loc = val;
15633 +@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
15634 + case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
15635 + if (info->plt_initialized == 0) {
15636 + unsigned int *ip;
15637 +- ip = me->module_core + me->arch.plt_offset +
15638 ++ ip = me->module_core_rx + me->arch.plt_offset +
15639 + info->plt_offset;
15640 + #ifndef CONFIG_64BIT
15641 + ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
15642 +@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
15643 + val = me->arch.plt_offset - me->arch.got_offset +
15644 + info->plt_offset + rela->r_addend;
15645 + else
15646 +- val = (Elf_Addr) me->module_core +
15647 ++ val = (Elf_Addr) me->module_core_rx +
15648 + me->arch.plt_offset + info->plt_offset +
15649 + rela->r_addend - loc;
15650 + if (r_type == R_390_PLT16DBL)
15651 +@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
15652 + case R_390_GOTOFF32: /* 32 bit offset to GOT. */
15653 + case R_390_GOTOFF64: /* 64 bit offset to GOT. */
15654 + val = val + rela->r_addend -
15655 +- ((Elf_Addr) me->module_core + me->arch.got_offset);
15656 ++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
15657 + if (r_type == R_390_GOTOFF16)
15658 + *(unsigned short *) loc = val;
15659 + else if (r_type == R_390_GOTOFF32)
15660 +@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
15661 + break;
15662 + case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
15663 + case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
15664 +- val = (Elf_Addr) me->module_core + me->arch.got_offset +
15665 ++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
15666 + rela->r_addend - loc;
15667 + if (r_type == R_390_GOTPC)
15668 + *(unsigned int *) loc = val;
15669 +diff -Nurp linux-2.6.23.15/arch/sparc/Makefile linux-2.6.23.15-grsec/arch/sparc/Makefile
15670 +--- linux-2.6.23.15/arch/sparc/Makefile 2007-10-09 21:31:38.000000000 +0100
15671 ++++ linux-2.6.23.15-grsec/arch/sparc/Makefile 2008-02-11 10:37:44.000000000 +0000
15672 +@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
15673 + # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
15674 + INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
15675 + CORE_Y := $(core-y)
15676 +-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
15677 ++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
15678 + CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
15679 + DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
15680 + NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
15681 +diff -Nurp linux-2.6.23.15/arch/sparc/kernel/ptrace.c linux-2.6.23.15-grsec/arch/sparc/kernel/ptrace.c
15682 +--- linux-2.6.23.15/arch/sparc/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
15683 ++++ linux-2.6.23.15-grsec/arch/sparc/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
15684 +@@ -19,6 +19,7 @@
15685 + #include <linux/smp_lock.h>
15686 + #include <linux/security.h>
15687 + #include <linux/signal.h>
15688 ++#include <linux/grsecurity.h>
15689 +
15690 + #include <asm/pgtable.h>
15691 + #include <asm/system.h>
15692 +@@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs
15693 + goto out;
15694 + }
15695 +
15696 ++ if (gr_handle_ptrace(child, request)) {
15697 ++ pt_error_return(regs, EPERM);
15698 ++ goto out_tsk;
15699 ++ }
15700 ++
15701 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
15702 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
15703 + if (ptrace_attach(child)) {
15704 +diff -Nurp linux-2.6.23.15/arch/sparc/kernel/sys_sparc.c linux-2.6.23.15-grsec/arch/sparc/kernel/sys_sparc.c
15705 +--- linux-2.6.23.15/arch/sparc/kernel/sys_sparc.c 2007-10-09 21:31:38.000000000 +0100
15706 ++++ linux-2.6.23.15-grsec/arch/sparc/kernel/sys_sparc.c 2008-02-11 10:37:44.000000000 +0000
15707 +@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
15708 + if (ARCH_SUN4C_SUN4 && len > 0x20000000)
15709 + return -ENOMEM;
15710 + if (!addr)
15711 +- addr = TASK_UNMAPPED_BASE;
15712 ++ addr = current->mm->mmap_base;
15713 +
15714 + if (flags & MAP_SHARED)
15715 + addr = COLOUR_ALIGN(addr);
15716 +diff -Nurp linux-2.6.23.15/arch/sparc/mm/fault.c linux-2.6.23.15-grsec/arch/sparc/mm/fault.c
15717 +--- linux-2.6.23.15/arch/sparc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
15718 ++++ linux-2.6.23.15-grsec/arch/sparc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
15719 +@@ -21,6 +21,10 @@
15720 + #include <linux/interrupt.h>
15721 + #include <linux/module.h>
15722 + #include <linux/kdebug.h>
15723 ++#include <linux/slab.h>
15724 ++#include <linux/pagemap.h>
15725 ++#include <linux/compiler.h>
15726 ++#include <linux/binfmts.h>
15727 +
15728 + #include <asm/system.h>
15729 + #include <asm/page.h>
15730 +@@ -216,6 +220,252 @@ static unsigned long compute_si_addr(str
15731 + return safe_compute_effective_address(regs, insn);
15732 + }
15733 +
15734 ++#ifdef CONFIG_PAX_PAGEEXEC
15735 ++void pax_emuplt_close(struct vm_area_struct *vma)
15736 ++{
15737 ++ vma->vm_mm->call_dl_resolve = 0UL;
15738 ++}
15739 ++
15740 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
15741 ++{
15742 ++ struct page *page;
15743 ++ unsigned int *kaddr;
15744 ++
15745 ++ page = alloc_page(GFP_HIGHUSER);
15746 ++ if (!page)
15747 ++ return NOPAGE_OOM;
15748 ++
15749 ++ kaddr = kmap(page);
15750 ++ memset(kaddr, 0, PAGE_SIZE);
15751 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
15752 ++ flush_dcache_page(page);
15753 ++ kunmap(page);
15754 ++ if (type)
15755 ++ *type = VM_FAULT_MAJOR;
15756 ++
15757 ++ return page;
15758 ++}
15759 ++
15760 ++static struct vm_operations_struct pax_vm_ops = {
15761 ++ .close = pax_emuplt_close,
15762 ++ .nopage = pax_emuplt_nopage,
15763 ++};
15764 ++
15765 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
15766 ++{
15767 ++ int ret;
15768 ++
15769 ++ memset(vma, 0, sizeof(*vma));
15770 ++ vma->vm_mm = current->mm;
15771 ++ vma->vm_start = addr;
15772 ++ vma->vm_end = addr + PAGE_SIZE;
15773 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
15774 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
15775 ++ vma->vm_ops = &pax_vm_ops;
15776 ++
15777 ++ ret = insert_vm_struct(current->mm, vma);
15778 ++ if (ret)
15779 ++ return ret;
15780 ++
15781 ++ ++current->mm->total_vm;
15782 ++ return 0;
15783 ++}
15784 ++
15785 ++/*
15786 ++ * PaX: decide what to do with offenders (regs->pc = fault address)
15787 ++ *
15788 ++ * returns 1 when task should be killed
15789 ++ * 2 when patched PLT trampoline was detected
15790 ++ * 3 when unpatched PLT trampoline was detected
15791 ++ */
15792 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
15793 ++{
15794 ++
15795 ++#ifdef CONFIG_PAX_EMUPLT
15796 ++ int err;
15797 ++
15798 ++ do { /* PaX: patched PLT emulation #1 */
15799 ++ unsigned int sethi1, sethi2, jmpl;
15800 ++
15801 ++ err = get_user(sethi1, (unsigned int *)regs->pc);
15802 ++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
15803 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
15804 ++
15805 ++ if (err)
15806 ++ break;
15807 ++
15808 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
15809 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
15810 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
15811 ++ {
15812 ++ unsigned int addr;
15813 ++
15814 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
15815 ++ addr = regs->u_regs[UREG_G1];
15816 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
15817 ++ regs->pc = addr;
15818 ++ regs->npc = addr+4;
15819 ++ return 2;
15820 ++ }
15821 ++ } while (0);
15822 ++
15823 ++ { /* PaX: patched PLT emulation #2 */
15824 ++ unsigned int ba;
15825 ++
15826 ++ err = get_user(ba, (unsigned int *)regs->pc);
15827 ++
15828 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
15829 ++ unsigned int addr;
15830 ++
15831 ++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
15832 ++ regs->pc = addr;
15833 ++ regs->npc = addr+4;
15834 ++ return 2;
15835 ++ }
15836 ++ }
15837 ++
15838 ++ do { /* PaX: patched PLT emulation #3 */
15839 ++ unsigned int sethi, jmpl, nop;
15840 ++
15841 ++ err = get_user(sethi, (unsigned int *)regs->pc);
15842 ++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
15843 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
15844 ++
15845 ++ if (err)
15846 ++ break;
15847 ++
15848 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
15849 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
15850 ++ nop == 0x01000000U)
15851 ++ {
15852 ++ unsigned int addr;
15853 ++
15854 ++ addr = (sethi & 0x003FFFFFU) << 10;
15855 ++ regs->u_regs[UREG_G1] = addr;
15856 ++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
15857 ++ regs->pc = addr;
15858 ++ regs->npc = addr+4;
15859 ++ return 2;
15860 ++ }
15861 ++ } while (0);
15862 ++
15863 ++ do { /* PaX: unpatched PLT emulation step 1 */
15864 ++ unsigned int sethi, ba, nop;
15865 ++
15866 ++ err = get_user(sethi, (unsigned int *)regs->pc);
15867 ++ err |= get_user(ba, (unsigned int *)(regs->pc+4));
15868 ++ err |= get_user(nop, (unsigned int *)(regs->pc+8));
15869 ++
15870 ++ if (err)
15871 ++ break;
15872 ++
15873 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
15874 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
15875 ++ nop == 0x01000000U)
15876 ++ {
15877 ++ unsigned int addr, save, call;
15878 ++
15879 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
15880 ++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
15881 ++ else
15882 ++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
15883 ++
15884 ++ err = get_user(save, (unsigned int *)addr);
15885 ++ err |= get_user(call, (unsigned int *)(addr+4));
15886 ++ err |= get_user(nop, (unsigned int *)(addr+8));
15887 ++ if (err)
15888 ++ break;
15889 ++
15890 ++ if (save == 0x9DE3BFA8U &&
15891 ++ (call & 0xC0000000U) == 0x40000000U &&
15892 ++ nop == 0x01000000U)
15893 ++ {
15894 ++ struct vm_area_struct *vma;
15895 ++ unsigned long call_dl_resolve;
15896 ++
15897 ++ down_read(&current->mm->mmap_sem);
15898 ++ call_dl_resolve = current->mm->call_dl_resolve;
15899 ++ up_read(&current->mm->mmap_sem);
15900 ++ if (likely(call_dl_resolve))
15901 ++ goto emulate;
15902 ++
15903 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
15904 ++
15905 ++ down_write(&current->mm->mmap_sem);
15906 ++ if (current->mm->call_dl_resolve) {
15907 ++ call_dl_resolve = current->mm->call_dl_resolve;
15908 ++ up_write(&current->mm->mmap_sem);
15909 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15910 ++ goto emulate;
15911 ++ }
15912 ++
15913 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
15914 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
15915 ++ up_write(&current->mm->mmap_sem);
15916 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
15917 ++ return 1;
15918 ++ }
15919 ++
15920 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
15921 ++ up_write(&current->mm->mmap_sem);
15922 ++ kmem_cache_free(vm_area_cachep, vma);
15923 ++ return 1;
15924 ++ }
15925 ++
15926 ++ current->mm->call_dl_resolve = call_dl_resolve;
15927 ++ up_write(&current->mm->mmap_sem);
15928 ++
15929 ++emulate:
15930 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
15931 ++ regs->pc = call_dl_resolve;
15932 ++ regs->npc = addr+4;
15933 ++ return 3;
15934 ++ }
15935 ++ }
15936 ++ } while (0);
15937 ++
15938 ++ do { /* PaX: unpatched PLT emulation step 2 */
15939 ++ unsigned int save, call, nop;
15940 ++
15941 ++ err = get_user(save, (unsigned int *)(regs->pc-4));
15942 ++ err |= get_user(call, (unsigned int *)regs->pc);
15943 ++ err |= get_user(nop, (unsigned int *)(regs->pc+4));
15944 ++ if (err)
15945 ++ break;
15946 ++
15947 ++ if (save == 0x9DE3BFA8U &&
15948 ++ (call & 0xC0000000U) == 0x40000000U &&
15949 ++ nop == 0x01000000U)
15950 ++ {
15951 ++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
15952 ++
15953 ++ regs->u_regs[UREG_RETPC] = regs->pc;
15954 ++ regs->pc = dl_resolve;
15955 ++ regs->npc = dl_resolve+4;
15956 ++ return 3;
15957 ++ }
15958 ++ } while (0);
15959 ++#endif
15960 ++
15961 ++ return 1;
15962 ++}
15963 ++
15964 ++void pax_report_insns(void *pc, void *sp)
15965 ++{
15966 ++ unsigned long i;
15967 ++
15968 ++ printk(KERN_ERR "PAX: bytes at PC: ");
15969 ++ for (i = 0; i < 5; i++) {
15970 ++ unsigned int c;
15971 ++ if (get_user(c, (unsigned int *)pc+i))
15972 ++ printk("???????? ");
15973 ++ else
15974 ++ printk("%08x ", c);
15975 ++ }
15976 ++ printk("\n");
15977 ++}
15978 ++#endif
15979 ++
15980 + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
15981 + unsigned long address)
15982 + {
15983 +@@ -280,6 +530,24 @@ good_area:
15984 + if(!(vma->vm_flags & VM_WRITE))
15985 + goto bad_area;
15986 + } else {
15987 ++
15988 ++#ifdef CONFIG_PAX_PAGEEXEC
15989 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
15990 ++ up_read(&mm->mmap_sem);
15991 ++ switch (pax_handle_fetch_fault(regs)) {
15992 ++
15993 ++#ifdef CONFIG_PAX_EMUPLT
15994 ++ case 2:
15995 ++ case 3:
15996 ++ return;
15997 ++#endif
15998 ++
15999 ++ }
16000 ++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
16001 ++ do_exit(SIGKILL);
16002 ++ }
16003 ++#endif
16004 ++
16005 + /* Allow reads even for write-only mappings */
16006 + if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
16007 + goto bad_area;
16008 +diff -Nurp linux-2.6.23.15/arch/sparc/mm/init.c linux-2.6.23.15-grsec/arch/sparc/mm/init.c
16009 +--- linux-2.6.23.15/arch/sparc/mm/init.c 2007-10-09 21:31:38.000000000 +0100
16010 ++++ linux-2.6.23.15-grsec/arch/sparc/mm/init.c 2008-02-11 10:37:44.000000000 +0000
16011 +@@ -336,17 +336,17 @@ void __init paging_init(void)
16012 +
16013 + /* Initialize the protection map with non-constant, MMU dependent values. */
16014 + protection_map[0] = PAGE_NONE;
16015 +- protection_map[1] = PAGE_READONLY;
16016 +- protection_map[2] = PAGE_COPY;
16017 +- protection_map[3] = PAGE_COPY;
16018 ++ protection_map[1] = PAGE_READONLY_NOEXEC;
16019 ++ protection_map[2] = PAGE_COPY_NOEXEC;
16020 ++ protection_map[3] = PAGE_COPY_NOEXEC;
16021 + protection_map[4] = PAGE_READONLY;
16022 + protection_map[5] = PAGE_READONLY;
16023 + protection_map[6] = PAGE_COPY;
16024 + protection_map[7] = PAGE_COPY;
16025 + protection_map[8] = PAGE_NONE;
16026 +- protection_map[9] = PAGE_READONLY;
16027 +- protection_map[10] = PAGE_SHARED;
16028 +- protection_map[11] = PAGE_SHARED;
16029 ++ protection_map[9] = PAGE_READONLY_NOEXEC;
16030 ++ protection_map[10] = PAGE_SHARED_NOEXEC;
16031 ++ protection_map[11] = PAGE_SHARED_NOEXEC;
16032 + protection_map[12] = PAGE_READONLY;
16033 + protection_map[13] = PAGE_READONLY;
16034 + protection_map[14] = PAGE_SHARED;
16035 +diff -Nurp linux-2.6.23.15/arch/sparc/mm/srmmu.c linux-2.6.23.15-grsec/arch/sparc/mm/srmmu.c
16036 +--- linux-2.6.23.15/arch/sparc/mm/srmmu.c 2007-10-09 21:31:38.000000000 +0100
16037 ++++ linux-2.6.23.15-grsec/arch/sparc/mm/srmmu.c 2008-02-11 10:37:44.000000000 +0000
16038 +@@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void)
16039 + PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
16040 + BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
16041 + BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
16042 ++
16043 ++#ifdef CONFIG_PAX_PAGEEXEC
16044 ++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
16045 ++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
16046 ++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
16047 ++#endif
16048 ++
16049 + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
16050 + page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
16051 +
16052 +diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/Makefile linux-2.6.23.15-grsec/arch/sparc64/kernel/Makefile
16053 +--- linux-2.6.23.15/arch/sparc64/kernel/Makefile 2007-10-09 21:31:38.000000000 +0100
16054 ++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/Makefile 2008-02-11 10:37:44.000000000 +0000
16055 +@@ -3,7 +3,7 @@
16056 + #
16057 +
16058 + EXTRA_AFLAGS := -ansi
16059 +-EXTRA_CFLAGS := -Werror
16060 ++#EXTRA_CFLAGS := -Werror
16061 +
16062 + extra-y := head.o init_task.o vmlinux.lds
16063 +
16064 +diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/ptrace.c linux-2.6.23.15-grsec/arch/sparc64/kernel/ptrace.c
16065 +--- linux-2.6.23.15/arch/sparc64/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
16066 ++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000
16067 +@@ -22,6 +22,7 @@
16068 + #include <linux/seccomp.h>
16069 + #include <linux/audit.h>
16070 + #include <linux/signal.h>
16071 ++#include <linux/grsecurity.h>
16072 +
16073 + #include <asm/asi.h>
16074 + #include <asm/pgtable.h>
16075 +@@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs
16076 + goto out;
16077 + }
16078 +
16079 ++ if (gr_handle_ptrace(child, (long)request)) {
16080 ++ pt_error_return(regs, EPERM);
16081 ++ goto out_tsk;
16082 ++ }
16083 ++
16084 + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
16085 + || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
16086 + if (ptrace_attach(child)) {
16087 +diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/sys_sparc.c linux-2.6.23.15-grsec/arch/sparc64/kernel/sys_sparc.c
16088 +--- linux-2.6.23.15/arch/sparc64/kernel/sys_sparc.c 2008-02-11 10:36:03.000000000 +0000
16089 ++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/sys_sparc.c 2008-02-11 10:37:44.000000000 +0000
16090 +@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
16091 + /* We do not accept a shared mapping if it would violate
16092 + * cache aliasing constraints.
16093 + */
16094 +- if ((flags & MAP_SHARED) &&
16095 ++ if ((filp || (flags & MAP_SHARED)) &&
16096 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
16097 + return -EINVAL;
16098 + return addr;
16099 +@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
16100 + if (filp || (flags & MAP_SHARED))
16101 + do_color_align = 1;
16102 +
16103 ++#ifdef CONFIG_PAX_RANDMMAP
16104 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
16105 ++#endif
16106 ++
16107 + if (addr) {
16108 + if (do_color_align)
16109 + addr = COLOUR_ALIGN(addr, pgoff);
16110 +@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
16111 + }
16112 +
16113 + if (len > mm->cached_hole_size) {
16114 +- start_addr = addr = mm->free_area_cache;
16115 ++ start_addr = addr = mm->free_area_cache;
16116 + } else {
16117 +- start_addr = addr = TASK_UNMAPPED_BASE;
16118 ++ start_addr = addr = mm->mmap_base;
16119 + mm->cached_hole_size = 0;
16120 + }
16121 +
16122 +@@ -174,8 +178,8 @@ full_search:
16123 + vma = find_vma(mm, VA_EXCLUDE_END);
16124 + }
16125 + if (unlikely(task_size < addr)) {
16126 +- if (start_addr != TASK_UNMAPPED_BASE) {
16127 +- start_addr = addr = TASK_UNMAPPED_BASE;
16128 ++ if (start_addr != mm->mmap_base) {
16129 ++ start_addr = addr = mm->mmap_base;
16130 + mm->cached_hole_size = 0;
16131 + goto full_search;
16132 + }
16133 +@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
16134 + /* We do not accept a shared mapping if it would violate
16135 + * cache aliasing constraints.
16136 + */
16137 +- if ((flags & MAP_SHARED) &&
16138 ++ if ((filp || (flags & MAP_SHARED)) &&
16139 + ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
16140 + return -EINVAL;
16141 + return addr;
16142 +@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
16143 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
16144 + sysctl_legacy_va_layout) {
16145 + mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
16146 ++
16147 ++#ifdef CONFIG_PAX_RANDMMAP
16148 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16149 ++ mm->mmap_base += mm->delta_mmap;
16150 ++#endif
16151 ++
16152 + mm->get_unmapped_area = arch_get_unmapped_area;
16153 + mm->unmap_area = arch_unmap_area;
16154 + } else {
16155 +@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
16156 + gap = (task_size / 6 * 5);
16157 +
16158 + mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
16159 ++
16160 ++#ifdef CONFIG_PAX_RANDMMAP
16161 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16162 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
16163 ++#endif
16164 ++
16165 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
16166 + mm->unmap_area = arch_unmap_area_topdown;
16167 + }
16168 +diff -Nurp linux-2.6.23.15/arch/sparc64/mm/Makefile linux-2.6.23.15-grsec/arch/sparc64/mm/Makefile
16169 +--- linux-2.6.23.15/arch/sparc64/mm/Makefile 2007-10-09 21:31:38.000000000 +0100
16170 ++++ linux-2.6.23.15-grsec/arch/sparc64/mm/Makefile 2008-02-11 10:37:44.000000000 +0000
16171 +@@ -3,7 +3,7 @@
16172 + #
16173 +
16174 + EXTRA_AFLAGS := -ansi
16175 +-EXTRA_CFLAGS := -Werror
16176 ++#EXTRA_CFLAGS := -Werror
16177 +
16178 + obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
16179 +
16180 +diff -Nurp linux-2.6.23.15/arch/sparc64/mm/fault.c linux-2.6.23.15-grsec/arch/sparc64/mm/fault.c
16181 +--- linux-2.6.23.15/arch/sparc64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
16182 ++++ linux-2.6.23.15-grsec/arch/sparc64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
16183 +@@ -20,6 +20,10 @@
16184 + #include <linux/kprobes.h>
16185 + #include <linux/kallsyms.h>
16186 + #include <linux/kdebug.h>
16187 ++#include <linux/slab.h>
16188 ++#include <linux/pagemap.h>
16189 ++#include <linux/compiler.h>
16190 ++#include <linux/binfmts.h>
16191 +
16192 + #include <asm/page.h>
16193 + #include <asm/pgtable.h>
16194 +@@ -270,6 +274,369 @@ cannot_handle:
16195 + unhandled_fault (address, current, regs);
16196 + }
16197 +
16198 ++#ifdef CONFIG_PAX_PAGEEXEC
16199 ++#ifdef CONFIG_PAX_EMUPLT
16200 ++static void pax_emuplt_close(struct vm_area_struct *vma)
16201 ++{
16202 ++ vma->vm_mm->call_dl_resolve = 0UL;
16203 ++}
16204 ++
16205 ++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
16206 ++{
16207 ++ struct page *page;
16208 ++ unsigned int *kaddr;
16209 ++
16210 ++ page = alloc_page(GFP_HIGHUSER);
16211 ++ if (!page)
16212 ++ return NOPAGE_OOM;
16213 ++
16214 ++ kaddr = kmap(page);
16215 ++ memset(kaddr, 0, PAGE_SIZE);
16216 ++ kaddr[0] = 0x9DE3BFA8U; /* save */
16217 ++ flush_dcache_page(page);
16218 ++ kunmap(page);
16219 ++ if (type)
16220 ++ *type = VM_FAULT_MAJOR;
16221 ++ return page;
16222 ++}
16223 ++
16224 ++static struct vm_operations_struct pax_vm_ops = {
16225 ++ .close = pax_emuplt_close,
16226 ++ .nopage = pax_emuplt_nopage,
16227 ++};
16228 ++
16229 ++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
16230 ++{
16231 ++ int ret;
16232 ++
16233 ++ memset(vma, 0, sizeof(*vma));
16234 ++ vma->vm_mm = current->mm;
16235 ++ vma->vm_start = addr;
16236 ++ vma->vm_end = addr + PAGE_SIZE;
16237 ++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
16238 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
16239 ++ vma->vm_ops = &pax_vm_ops;
16240 ++
16241 ++ ret = insert_vm_struct(current->mm, vma);
16242 ++ if (ret)
16243 ++ return ret;
16244 ++
16245 ++ ++current->mm->total_vm;
16246 ++ return 0;
16247 ++}
16248 ++#endif
16249 ++
16250 ++/*
16251 ++ * PaX: decide what to do with offenders (regs->tpc = fault address)
16252 ++ *
16253 ++ * returns 1 when task should be killed
16254 ++ * 2 when patched PLT trampoline was detected
16255 ++ * 3 when unpatched PLT trampoline was detected
16256 ++ */
16257 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
16258 ++{
16259 ++
16260 ++#ifdef CONFIG_PAX_EMUPLT
16261 ++ int err;
16262 ++
16263 ++ do { /* PaX: patched PLT emulation #1 */
16264 ++ unsigned int sethi1, sethi2, jmpl;
16265 ++
16266 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
16267 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
16268 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
16269 ++
16270 ++ if (err)
16271 ++ break;
16272 ++
16273 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
16274 ++ (sethi2 & 0xFFC00000U) == 0x03000000U &&
16275 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U)
16276 ++ {
16277 ++ unsigned long addr;
16278 ++
16279 ++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
16280 ++ addr = regs->u_regs[UREG_G1];
16281 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
16282 ++ regs->tpc = addr;
16283 ++ regs->tnpc = addr+4;
16284 ++ return 2;
16285 ++ }
16286 ++ } while (0);
16287 ++
16288 ++ { /* PaX: patched PLT emulation #2 */
16289 ++ unsigned int ba;
16290 ++
16291 ++ err = get_user(ba, (unsigned int *)regs->tpc);
16292 ++
16293 ++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
16294 ++ unsigned long addr;
16295 ++
16296 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
16297 ++ regs->tpc = addr;
16298 ++ regs->tnpc = addr+4;
16299 ++ return 2;
16300 ++ }
16301 ++ }
16302 ++
16303 ++ do { /* PaX: patched PLT emulation #3 */
16304 ++ unsigned int sethi, jmpl, nop;
16305 ++
16306 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
16307 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
16308 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
16309 ++
16310 ++ if (err)
16311 ++ break;
16312 ++
16313 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
16314 ++ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
16315 ++ nop == 0x01000000U)
16316 ++ {
16317 ++ unsigned long addr;
16318 ++
16319 ++ addr = (sethi & 0x003FFFFFU) << 10;
16320 ++ regs->u_regs[UREG_G1] = addr;
16321 ++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
16322 ++ regs->tpc = addr;
16323 ++ regs->tnpc = addr+4;
16324 ++ return 2;
16325 ++ }
16326 ++ } while (0);
16327 ++
16328 ++ do { /* PaX: patched PLT emulation #4 */
16329 ++ unsigned int mov1, call, mov2;
16330 ++
16331 ++ err = get_user(mov1, (unsigned int *)regs->tpc);
16332 ++ err |= get_user(call, (unsigned int *)(regs->tpc+4));
16333 ++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
16334 ++
16335 ++ if (err)
16336 ++ break;
16337 ++
16338 ++ if (mov1 == 0x8210000FU &&
16339 ++ (call & 0xC0000000U) == 0x40000000U &&
16340 ++ mov2 == 0x9E100001U)
16341 ++ {
16342 ++ unsigned long addr;
16343 ++
16344 ++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
16345 ++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
16346 ++ regs->tpc = addr;
16347 ++ regs->tnpc = addr+4;
16348 ++ return 2;
16349 ++ }
16350 ++ } while (0);
16351 ++
16352 ++ do { /* PaX: patched PLT emulation #5 */
16353 ++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
16354 ++
16355 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
16356 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
16357 ++ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
16358 ++ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
16359 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
16360 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
16361 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
16362 ++
16363 ++ if (err)
16364 ++ break;
16365 ++
16366 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
16367 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
16368 ++ (or1 & 0xFFFFE000U) == 0x82106000U &&
16369 ++ (or2 & 0xFFFFE000U) == 0x8A116000U &&
16370 ++ sllx == 0x83287020 &&
16371 ++ jmpl == 0x81C04005U &&
16372 ++ nop == 0x01000000U)
16373 ++ {
16374 ++ unsigned long addr;
16375 ++
16376 ++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
16377 ++ regs->u_regs[UREG_G1] <<= 32;
16378 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
16379 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
16380 ++ regs->tpc = addr;
16381 ++ regs->tnpc = addr+4;
16382 ++ return 2;
16383 ++ }
16384 ++ } while (0);
16385 ++
16386 ++ do { /* PaX: patched PLT emulation #6 */
16387 ++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
16388 ++
16389 ++ err = get_user(sethi1, (unsigned int *)regs->tpc);
16390 ++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
16391 ++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
16392 ++ err |= get_user(or, (unsigned int *)(regs->tpc+12));
16393 ++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
16394 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
16395 ++
16396 ++ if (err)
16397 ++ break;
16398 ++
16399 ++ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
16400 ++ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
16401 ++ sllx == 0x83287020 &&
16402 ++ (or & 0xFFFFE000U) == 0x8A116000U &&
16403 ++ jmpl == 0x81C04005U &&
16404 ++ nop == 0x01000000U)
16405 ++ {
16406 ++ unsigned long addr;
16407 ++
16408 ++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
16409 ++ regs->u_regs[UREG_G1] <<= 32;
16410 ++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
16411 ++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
16412 ++ regs->tpc = addr;
16413 ++ regs->tnpc = addr+4;
16414 ++ return 2;
16415 ++ }
16416 ++ } while (0);
16417 ++
16418 ++ do { /* PaX: patched PLT emulation #7 */
16419 ++ unsigned int sethi, ba, nop;
16420 ++
16421 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
16422 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
16423 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
16424 ++
16425 ++ if (err)
16426 ++ break;
16427 ++
16428 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
16429 ++ (ba & 0xFFF00000U) == 0x30600000U &&
16430 ++ nop == 0x01000000U)
16431 ++ {
16432 ++ unsigned long addr;
16433 ++
16434 ++ addr = (sethi & 0x003FFFFFU) << 10;
16435 ++ regs->u_regs[UREG_G1] = addr;
16436 ++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
16437 ++ regs->tpc = addr;
16438 ++ regs->tnpc = addr+4;
16439 ++ return 2;
16440 ++ }
16441 ++ } while (0);
16442 ++
16443 ++ do { /* PaX: unpatched PLT emulation step 1 */
16444 ++ unsigned int sethi, ba, nop;
16445 ++
16446 ++ err = get_user(sethi, (unsigned int *)regs->tpc);
16447 ++ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
16448 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
16449 ++
16450 ++ if (err)
16451 ++ break;
16452 ++
16453 ++ if ((sethi & 0xFFC00000U) == 0x03000000U &&
16454 ++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
16455 ++ nop == 0x01000000U)
16456 ++ {
16457 ++ unsigned long addr;
16458 ++ unsigned int save, call;
16459 ++
16460 ++ if ((ba & 0xFFC00000U) == 0x30800000U)
16461 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
16462 ++ else
16463 ++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
16464 ++
16465 ++ err = get_user(save, (unsigned int *)addr);
16466 ++ err |= get_user(call, (unsigned int *)(addr+4));
16467 ++ err |= get_user(nop, (unsigned int *)(addr+8));
16468 ++ if (err)
16469 ++ break;
16470 ++
16471 ++ if (save == 0x9DE3BFA8U &&
16472 ++ (call & 0xC0000000U) == 0x40000000U &&
16473 ++ nop == 0x01000000U)
16474 ++ {
16475 ++ struct vm_area_struct *vma;
16476 ++ unsigned long call_dl_resolve;
16477 ++
16478 ++ down_read(&current->mm->mmap_sem);
16479 ++ call_dl_resolve = current->mm->call_dl_resolve;
16480 ++ up_read(&current->mm->mmap_sem);
16481 ++ if (likely(call_dl_resolve))
16482 ++ goto emulate;
16483 ++
16484 ++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
16485 ++
16486 ++ down_write(&current->mm->mmap_sem);
16487 ++ if (current->mm->call_dl_resolve) {
16488 ++ call_dl_resolve = current->mm->call_dl_resolve;
16489 ++ up_write(&current->mm->mmap_sem);
16490 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
16491 ++ goto emulate;
16492 ++ }
16493 ++
16494 ++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
16495 ++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
16496 ++ up_write(&current->mm->mmap_sem);
16497 ++ if (vma) kmem_cache_free(vm_area_cachep, vma);
16498 ++ return 1;
16499 ++ }
16500 ++
16501 ++ if (pax_insert_vma(vma, call_dl_resolve)) {
16502 ++ up_write(&current->mm->mmap_sem);
16503 ++ kmem_cache_free(vm_area_cachep, vma);
16504 ++ return 1;
16505 ++ }
16506 ++
16507 ++ current->mm->call_dl_resolve = call_dl_resolve;
16508 ++ up_write(&current->mm->mmap_sem);
16509 ++
16510 ++emulate:
16511 ++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
16512 ++ regs->tpc = call_dl_resolve;
16513 ++ regs->tnpc = addr+4;
16514 ++ return 3;
16515 ++ }
16516 ++ }
16517 ++ } while (0);
16518 ++
16519 ++ do { /* PaX: unpatched PLT emulation step 2 */
16520 ++ unsigned int save, call, nop;
16521 ++
16522 ++ err = get_user(save, (unsigned int *)(regs->tpc-4));
16523 ++ err |= get_user(call, (unsigned int *)regs->tpc);
16524 ++ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
16525 ++ if (err)
16526 ++ break;
16527 ++
16528 ++ if (save == 0x9DE3BFA8U &&
16529 ++ (call & 0xC0000000U) == 0x40000000U &&
16530 ++ nop == 0x01000000U)
16531 ++ {
16532 ++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
16533 ++
16534 ++ regs->u_regs[UREG_RETPC] = regs->tpc;
16535 ++ regs->tpc = dl_resolve;
16536 ++ regs->tnpc = dl_resolve+4;
16537 ++ return 3;
16538 ++ }
16539 ++ } while (0);
16540 ++#endif
16541 ++
16542 ++ return 1;
16543 ++}
16544 ++
16545 ++void pax_report_insns(void *pc, void *sp)
16546 ++{
16547 ++ unsigned long i;
16548 ++
16549 ++ printk(KERN_ERR "PAX: bytes at PC: ");
16550 ++ for (i = 0; i < 5; i++) {
16551 ++ unsigned int c;
16552 ++ if (get_user(c, (unsigned int *)pc+i))
16553 ++ printk("???????? ");
16554 ++ else
16555 ++ printk("%08x ", c);
16556 ++ }
16557 ++ printk("\n");
16558 ++}
16559 ++#endif
16560 ++
16561 + asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
16562 + {
16563 + struct mm_struct *mm = current->mm;
16564 +@@ -311,8 +678,10 @@ asmlinkage void __kprobes do_sparc64_fau
16565 + goto intr_or_no_mm;
16566 +
16567 + if (test_thread_flag(TIF_32BIT)) {
16568 +- if (!(regs->tstate & TSTATE_PRIV))
16569 ++ if (!(regs->tstate & TSTATE_PRIV)) {
16570 + regs->tpc &= 0xffffffff;
16571 ++ regs->tnpc &= 0xffffffff;
16572 ++ }
16573 + address &= 0xffffffff;
16574 + }
16575 +
16576 +@@ -329,6 +698,29 @@ asmlinkage void __kprobes do_sparc64_fau
16577 + if (!vma)
16578 + goto bad_area;
16579 +
16580 ++#ifdef CONFIG_PAX_PAGEEXEC
16581 ++ /* PaX: detect ITLB misses on non-exec pages */
16582 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
16583 ++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
16584 ++ {
16585 ++ if (address != regs->tpc)
16586 ++ goto good_area;
16587 ++
16588 ++ up_read(&mm->mmap_sem);
16589 ++ switch (pax_handle_fetch_fault(regs)) {
16590 ++
16591 ++#ifdef CONFIG_PAX_EMUPLT
16592 ++ case 2:
16593 ++ case 3:
16594 ++ return;
16595 ++#endif
16596 ++
16597 ++ }
16598 ++ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
16599 ++ do_exit(SIGKILL);
16600 ++ }
16601 ++#endif
16602 ++
16603 + /* Pure DTLB misses do not tell us whether the fault causing
16604 + * load/store/atomic was a write or not, it only says that there
16605 + * was no match. So in such a case we (carefully) read the
16606 +diff -Nurp linux-2.6.23.15/arch/v850/kernel/module.c linux-2.6.23.15-grsec/arch/v850/kernel/module.c
16607 +--- linux-2.6.23.15/arch/v850/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
16608 ++++ linux-2.6.23.15-grsec/arch/v850/kernel/module.c 2008-02-11 10:37:44.000000000 +0000
16609 +@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
16610 + tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
16611 +
16612 + /* Init, or core PLT? */
16613 +- if (location >= mod->module_core
16614 +- && location < mod->module_core + mod->core_size)
16615 ++ if (location >= mod->module_core_rx
16616 ++ && location < mod->module_core_rx + mod->core_size_rx)
16617 + entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
16618 + else
16619 + entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
16620 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_binfmt.c
16621 +--- linux-2.6.23.15/arch/x86_64/ia32/ia32_binfmt.c 2007-10-09 21:31:38.000000000 +0100
16622 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_binfmt.c 2008-02-11 10:37:44.000000000 +0000
16623 +@@ -36,12 +36,12 @@
16624 + #define AT_SYSINFO 32
16625 + #define AT_SYSINFO_EHDR 33
16626 +
16627 +-int sysctl_vsyscall32 = 1;
16628 ++int sysctl_vsyscall32;
16629 +
16630 + #undef ARCH_DLINFO
16631 + #define ARCH_DLINFO do { \
16632 + if (sysctl_vsyscall32) { \
16633 +- current->mm->context.vdso = (void *)VSYSCALL32_BASE; \
16634 ++ current->mm->context.vdso = VSYSCALL32_BASE; \
16635 + NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \
16636 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \
16637 + } \
16638 +@@ -145,6 +145,13 @@ struct elf_prpsinfo
16639 + //#include <asm/ia32.h>
16640 + #include <linux/elf.h>
16641 +
16642 ++#ifdef CONFIG_PAX_ASLR
16643 ++#define PAX_ELF_ET_DYN_BASE 0x08048000UL
16644 ++
16645 ++#define PAX_DELTA_MMAP_LEN 16
16646 ++#define PAX_DELTA_STACK_LEN 16
16647 ++#endif
16648 ++
16649 + typedef struct user_i387_ia32_struct elf_fpregset_t;
16650 + typedef struct user32_fxsr_struct elf_fpxregset_t;
16651 +
16652 +@@ -298,7 +305,7 @@ static ctl_table abi_table2[] = {
16653 + .mode = 0644,
16654 + .proc_handler = proc_dointvec
16655 + },
16656 +- {}
16657 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16658 + };
16659 +
16660 + static ctl_table abi_root_table2[] = {
16661 +@@ -308,7 +315,7 @@ static ctl_table abi_root_table2[] = {
16662 + .mode = 0555,
16663 + .child = abi_table2
16664 + },
16665 +- {}
16666 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16667 + };
16668 +
16669 + static __init int ia32_binfmt_init(void)
16670 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/ia32_signal.c linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_signal.c
16671 +--- linux-2.6.23.15/arch/x86_64/ia32/ia32_signal.c 2007-10-09 21:31:38.000000000 +0100
16672 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_signal.c 2008-02-11 10:37:44.000000000 +0000
16673 +@@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct
16674 + __NR_ia32_rt_sigreturn,
16675 + 0x80cd,
16676 + 0,
16677 ++ 0
16678 + };
16679 + err |= __copy_to_user(frame->retcode, &code, 8);
16680 + }
16681 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/mmap32.c linux-2.6.23.15-grsec/arch/x86_64/ia32/mmap32.c
16682 +--- linux-2.6.23.15/arch/x86_64/ia32/mmap32.c 2007-10-09 21:31:38.000000000 +0100
16683 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/mmap32.c 2008-02-11 10:37:44.000000000 +0000
16684 +@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str
16685 + (current->personality & ADDR_COMPAT_LAYOUT) ||
16686 + current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
16687 + mm->mmap_base = TASK_UNMAPPED_BASE;
16688 ++
16689 ++#ifdef CONFIG_PAX_RANDMMAP
16690 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16691 ++ mm->mmap_base += mm->delta_mmap;
16692 ++#endif
16693 ++
16694 + mm->get_unmapped_area = arch_get_unmapped_area;
16695 + mm->unmap_area = arch_unmap_area;
16696 + } else {
16697 + mm->mmap_base = mmap_base(mm);
16698 ++
16699 ++#ifdef CONFIG_PAX_RANDMMAP
16700 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
16701 ++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
16702 ++#endif
16703 ++
16704 + mm->get_unmapped_area = arch_get_unmapped_area_topdown;
16705 + mm->unmap_area = arch_unmap_area_topdown;
16706 + }
16707 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/ptrace32.c linux-2.6.23.15-grsec/arch/x86_64/ia32/ptrace32.c
16708 +--- linux-2.6.23.15/arch/x86_64/ia32/ptrace32.c 2007-10-09 21:31:38.000000000 +0100
16709 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ptrace32.c 2008-02-11 10:37:44.000000000 +0000
16710 +@@ -382,7 +382,7 @@ asmlinkage long sys32_ptrace(long reques
16711 + /* no checking to be bug-to-bug compatible with i386. */
16712 + /* but silence warning */
16713 + if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)))
16714 +- ;
16715 ++ {}
16716 + set_stopped_child_used_math(child);
16717 + child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask;
16718 + ret = 0;
16719 +diff -Nurp linux-2.6.23.15/arch/x86_64/ia32/syscall32.c linux-2.6.23.15-grsec/arch/x86_64/ia32/syscall32.c
16720 +--- linux-2.6.23.15/arch/x86_64/ia32/syscall32.c 2007-10-09 21:31:38.000000000 +0100
16721 ++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/syscall32.c 2008-02-11 10:37:44.000000000 +0000
16722 +@@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b
16723 + struct mm_struct *mm = current->mm;
16724 + int ret;
16725 +
16726 ++ if (!sysctl_vsyscall32)
16727 ++ return 0;
16728 ++
16729 + down_write(&mm->mmap_sem);
16730 + /*
16731 + * MAYWRITE to allow gdb to COW and set breakpoints
16732 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/hpet.c linux-2.6.23.15-grsec/arch/x86_64/kernel/hpet.c
16733 +--- linux-2.6.23.15/arch/x86_64/kernel/hpet.c 2007-10-09 21:31:38.000000000 +0100
16734 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/hpet.c 2008-02-11 10:37:44.000000000 +0000
16735 +@@ -65,7 +65,7 @@ static __init int late_hpet_init(void)
16736 + hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
16737 + timer = &hpet->hpet_timers[2];
16738 + for (i = 2; i < ntimer; timer++, i++)
16739 +- hd.hd_irq[i] = (timer->hpet_config &
16740 ++ hd.hd_irq[i] = (readl(&timer->hpet_config) &
16741 + Tn_INT_ROUTE_CNF_MASK) >>
16742 + Tn_INT_ROUTE_CNF_SHIFT;
16743 +
16744 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/i8259.c linux-2.6.23.15-grsec/arch/x86_64/kernel/i8259.c
16745 +--- linux-2.6.23.15/arch/x86_64/kernel/i8259.c 2007-10-09 21:31:38.000000000 +0100
16746 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/i8259.c 2008-02-11 10:37:44.000000000 +0000
16747 +@@ -395,7 +395,7 @@ device_initcall(i8259A_init_sysfs);
16748 + * IRQ2 is cascade interrupt to second interrupt controller
16749 + */
16750 +
16751 +-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
16752 ++static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
16753 + DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
16754 + [0 ... IRQ0_VECTOR - 1] = -1,
16755 + [IRQ0_VECTOR] = 0,
16756 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/ioport.c linux-2.6.23.15-grsec/arch/x86_64/kernel/ioport.c
16757 +--- linux-2.6.23.15/arch/x86_64/kernel/ioport.c 2007-10-09 21:31:38.000000000 +0100
16758 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/ioport.c 2008-02-11 10:37:44.000000000 +0000
16759 +@@ -16,6 +16,7 @@
16760 + #include <linux/slab.h>
16761 + #include <linux/thread_info.h>
16762 + #include <linux/syscalls.h>
16763 ++#include <linux/grsecurity.h>
16764 +
16765 + /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
16766 + static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
16767 +@@ -41,8 +42,16 @@ asmlinkage long sys_ioperm(unsigned long
16768 +
16769 + if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
16770 + return -EINVAL;
16771 ++
16772 ++#ifdef CONFIG_GRKERNSEC_IO
16773 ++ if (turn_on) {
16774 ++ gr_handle_ioperm();
16775 ++ return -EPERM;
16776 ++ }
16777 ++#else
16778 + if (turn_on && !capable(CAP_SYS_RAWIO))
16779 + return -EPERM;
16780 ++#endif
16781 +
16782 + /*
16783 + * If it's the first ioperm() call in this thread's lifetime, set the
16784 +@@ -111,8 +120,13 @@ asmlinkage long sys_iopl(unsigned int le
16785 + return -EINVAL;
16786 + /* Trying to gain more privileges? */
16787 + if (level > old) {
16788 ++#ifdef CONFIG_GRKERNSEC_IO
16789 ++ gr_handle_iopl();
16790 ++ return -EPERM;
16791 ++#else
16792 + if (!capable(CAP_SYS_RAWIO))
16793 + return -EPERM;
16794 ++#endif
16795 + }
16796 + regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12);
16797 + return 0;
16798 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/mce.c linux-2.6.23.15-grsec/arch/x86_64/kernel/mce.c
16799 +--- linux-2.6.23.15/arch/x86_64/kernel/mce.c 2007-10-09 21:31:38.000000000 +0100
16800 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/mce.c 2008-02-11 10:37:44.000000000 +0000
16801 +@@ -665,6 +665,7 @@ static struct miscdevice mce_log_device
16802 + MISC_MCELOG_MINOR,
16803 + "mcelog",
16804 + &mce_chrdev_ops,
16805 ++ {NULL, NULL}, NULL, NULL
16806 + };
16807 +
16808 + static unsigned long old_cr4 __initdata;
16809 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/process.c linux-2.6.23.15-grsec/arch/x86_64/kernel/process.c
16810 +--- linux-2.6.23.15/arch/x86_64/kernel/process.c 2007-10-09 21:31:38.000000000 +0100
16811 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/process.c 2008-02-11 10:37:44.000000000 +0000
16812 +@@ -894,10 +894,3 @@ int dump_task_regs(struct task_struct *t
16813 +
16814 + return 1;
16815 + }
16816 +-
16817 +-unsigned long arch_align_stack(unsigned long sp)
16818 +-{
16819 +- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
16820 +- sp -= get_random_int() % 8192;
16821 +- return sp & ~0xf;
16822 +-}
16823 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/setup64.c linux-2.6.23.15-grsec/arch/x86_64/kernel/setup64.c
16824 +--- linux-2.6.23.15/arch/x86_64/kernel/setup64.c 2007-10-09 21:31:38.000000000 +0100
16825 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/setup64.c 2008-02-11 10:37:44.000000000 +0000
16826 +@@ -37,7 +37,7 @@ struct desc_ptr idt_descr = { 256 * 16 -
16827 + char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
16828 +
16829 + unsigned long __supported_pte_mask __read_mostly = ~0UL;
16830 +-static int do_not_nx __cpuinitdata = 0;
16831 ++EXPORT_SYMBOL(__supported_pte_mask);
16832 +
16833 + /* noexec=on|off
16834 + Control non executable mappings for 64bit processes.
16835 +@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
16836 + return -EINVAL;
16837 + if (!strncmp(str, "on", 2)) {
16838 + __supported_pte_mask |= _PAGE_NX;
16839 +- do_not_nx = 0;
16840 + } else if (!strncmp(str, "off", 3)) {
16841 +- do_not_nx = 1;
16842 + __supported_pte_mask &= ~_PAGE_NX;
16843 + }
16844 + return 0;
16845 + }
16846 + early_param("noexec", nonx_setup);
16847 +
16848 +-int force_personality32 = 0;
16849 ++int force_personality32;
16850 +
16851 + /* noexec32=on|off
16852 + Control non executable heap for 32bit processes.
16853 +@@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
16854 + unsigned long efer;
16855 +
16856 + rdmsrl(MSR_EFER, efer);
16857 +- if (!(efer & EFER_NX) || do_not_nx) {
16858 ++ if (!(efer & EFER_NX)) {
16859 + __supported_pte_mask &= ~_PAGE_NX;
16860 + }
16861 + }
16862 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/signal.c linux-2.6.23.15-grsec/arch/x86_64/kernel/signal.c
16863 +--- linux-2.6.23.15/arch/x86_64/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100
16864 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/signal.c 2008-02-11 10:37:44.000000000 +0000
16865 +@@ -254,8 +254,8 @@ static int setup_rt_frame(int sig, struc
16866 + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
16867 + err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
16868 + if (sizeof(*set) == 16) {
16869 +- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
16870 +- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
16871 ++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
16872 ++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
16873 + } else
16874 + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
16875 +
16876 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/sys_x86_64.c linux-2.6.23.15-grsec/arch/x86_64/kernel/sys_x86_64.c
16877 +--- linux-2.6.23.15/arch/x86_64/kernel/sys_x86_64.c 2007-10-09 21:31:38.000000000 +0100
16878 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/sys_x86_64.c 2008-02-11 10:37:44.000000000 +0000
16879 +@@ -65,8 +65,8 @@ out:
16880 + return error;
16881 + }
16882 +
16883 +-static void find_start_end(unsigned long flags, unsigned long *begin,
16884 +- unsigned long *end)
16885 ++static void find_start_end(struct mm_struct *mm, unsigned long flags,
16886 ++ unsigned long *begin, unsigned long *end)
16887 + {
16888 + if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
16889 + /* This is usually used needed to map code in small
16890 +@@ -79,7 +79,7 @@ static void find_start_end(unsigned long
16891 + *begin = 0x40000000;
16892 + *end = 0x80000000;
16893 + } else {
16894 +- *begin = TASK_UNMAPPED_BASE;
16895 ++ *begin = mm->mmap_base;
16896 + *end = TASK_SIZE;
16897 + }
16898 + }
16899 +@@ -96,11 +96,15 @@ arch_get_unmapped_area(struct file *filp
16900 + if (flags & MAP_FIXED)
16901 + return addr;
16902 +
16903 +- find_start_end(flags, &begin, &end);
16904 ++ find_start_end(mm, flags, &begin, &end);
16905 +
16906 + if (len > end)
16907 + return -ENOMEM;
16908 +
16909 ++#ifdef CONFIG_PAX_RANDMMAP
16910 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
16911 ++#endif
16912 ++
16913 + if (addr) {
16914 + addr = PAGE_ALIGN(addr);
16915 + vma = find_vma(mm, addr);
16916 +diff -Nurp linux-2.6.23.15/arch/x86_64/kernel/vsyscall.c linux-2.6.23.15-grsec/arch/x86_64/kernel/vsyscall.c
16917 +--- linux-2.6.23.15/arch/x86_64/kernel/vsyscall.c 2007-10-09 21:31:38.000000000 +0100
16918 ++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/vsyscall.c 2008-02-11 10:37:44.000000000 +0000
16919 +@@ -273,13 +273,13 @@ static ctl_table kernel_table2[] = {
16920 + .mode = 0644,
16921 + .strategy = vsyscall_sysctl_nostrat,
16922 + .proc_handler = vsyscall_sysctl_change },
16923 +- {}
16924 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16925 + };
16926 +
16927 + static ctl_table kernel_root_table2[] = {
16928 + { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
16929 + .child = kernel_table2 },
16930 +- {}
16931 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
16932 + };
16933 +
16934 + #endif
16935 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/fault.c linux-2.6.23.15-grsec/arch/x86_64/mm/fault.c
16936 +--- linux-2.6.23.15/arch/x86_64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100
16937 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000
16938 +@@ -25,6 +25,7 @@
16939 + #include <linux/kprobes.h>
16940 + #include <linux/uaccess.h>
16941 + #include <linux/kdebug.h>
16942 ++#include <linux/binfmts.h>
16943 +
16944 + #include <asm/system.h>
16945 + #include <asm/pgalloc.h>
16946 +@@ -291,6 +292,163 @@ static int vmalloc_fault(unsigned long a
16947 + return 0;
16948 + }
16949 +
16950 ++#ifdef CONFIG_PAX_EMUTRAMP
16951 ++static int pax_handle_fetch_fault_32(struct pt_regs *regs)
16952 ++{
16953 ++ int err;
16954 ++
16955 ++ do { /* PaX: gcc trampoline emulation #1 */
16956 ++ unsigned char mov1, mov2;
16957 ++ unsigned short jmp;
16958 ++ unsigned int addr1, addr2;
16959 ++
16960 ++ if ((regs->rip + 11) >> 32)
16961 ++ break;
16962 ++
16963 ++ err = get_user(mov1, (unsigned char __user *)regs->rip);
16964 ++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
16965 ++ err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5));
16966 ++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
16967 ++ err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10));
16968 ++
16969 ++ if (err)
16970 ++ break;
16971 ++
16972 ++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
16973 ++ regs->rcx = addr1;
16974 ++ regs->rax = addr2;
16975 ++ regs->rip = addr2;
16976 ++ return 2;
16977 ++ }
16978 ++ } while (0);
16979 ++
16980 ++ do { /* PaX: gcc trampoline emulation #2 */
16981 ++ unsigned char mov, jmp;
16982 ++ unsigned int addr1, addr2;
16983 ++
16984 ++ if ((regs->rip + 9) >> 32)
16985 ++ break;
16986 ++
16987 ++ err = get_user(mov, (unsigned char __user *)regs->rip);
16988 ++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1));
16989 ++ err |= get_user(jmp, (unsigned char __user *)(regs->rip + 5));
16990 ++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6));
16991 ++
16992 ++ if (err)
16993 ++ break;
16994 ++
16995 ++ if (mov == 0xB9 && jmp == 0xE9) {
16996 ++ regs->rcx = addr1;
16997 ++ regs->rip = (unsigned int)(regs->rip + addr2 + 10);
16998 ++ return 2;
16999 ++ }
17000 ++ } while (0);
17001 ++
17002 ++ return 1; /* PaX in action */
17003 ++}
17004 ++
17005 ++static int pax_handle_fetch_fault_64(struct pt_regs *regs)
17006 ++{
17007 ++ int err;
17008 ++
17009 ++ do { /* PaX: gcc trampoline emulation #1 */
17010 ++ unsigned short mov1, mov2, jmp1;
17011 ++ unsigned char jmp2;
17012 ++ unsigned int addr1;
17013 ++ unsigned long addr2;
17014 ++
17015 ++ err = get_user(mov1, (unsigned short __user *)regs->rip);
17016 ++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2));
17017 ++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6));
17018 ++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8));
17019 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16));
17020 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18));
17021 ++
17022 ++ if (err)
17023 ++ break;
17024 ++
17025 ++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
17026 ++ regs->r11 = addr1;
17027 ++ regs->r10 = addr2;
17028 ++ regs->rip = addr1;
17029 ++ return 2;
17030 ++ }
17031 ++ } while (0);
17032 ++
17033 ++ do { /* PaX: gcc trampoline emulation #2 */
17034 ++ unsigned short mov1, mov2, jmp1;
17035 ++ unsigned char jmp2;
17036 ++ unsigned long addr1, addr2;
17037 ++
17038 ++ err = get_user(mov1, (unsigned short __user *)regs->rip);
17039 ++ err |= get_user(addr1, (unsigned long __user *)(regs->rip + 2));
17040 ++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 10));
17041 ++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 12));
17042 ++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 20));
17043 ++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 22));
17044 ++
17045 ++ if (err)
17046 ++ break;
17047 ++
17048 ++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
17049 ++ regs->r11 = addr1;
17050 ++ regs->r10 = addr2;
17051 ++ regs->rip = addr1;
17052 ++ return 2;
17053 ++ }
17054 ++ } while (0);
17055 ++
17056 ++ return 1; /* PaX in action */
17057 ++}
17058 ++
17059 ++/*
17060 ++ * PaX: decide what to do with offenders (regs->rip = fault address)
17061 ++ *
17062 ++ * returns 1 when task should be killed
17063 ++ * 2 when gcc trampoline was detected
17064 ++ */
17065 ++static int pax_handle_fetch_fault(struct pt_regs *regs)
17066 ++{
17067 ++ if (regs->eflags & X86_EFLAGS_VM)
17068 ++ return 1;
17069 ++
17070 ++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
17071 ++ return 1;
17072 ++
17073 ++ if (regs->cs == __USER32_CS || (regs->cs & (1<<2)))
17074 ++ return pax_handle_fetch_fault_32(regs);
17075 ++ else
17076 ++ return pax_handle_fetch_fault_64(regs);
17077 ++}
17078 ++#endif
17079 ++
17080 ++#ifdef CONFIG_PAX_PAGEEXEC
17081 ++void pax_report_insns(void *pc, void *sp)
17082 ++{
17083 ++ long i;
17084 ++
17085 ++ printk(KERN_ERR "PAX: bytes at PC: ");
17086 ++ for (i = 0; i < 20; i++) {
17087 ++ unsigned char c;
17088 ++ if (get_user(c, (unsigned char __user *)pc+i))
17089 ++ printk("?? ");
17090 ++ else
17091 ++ printk("%02x ", c);
17092 ++ }
17093 ++ printk("\n");
17094 ++
17095 ++ printk(KERN_ERR "PAX: bytes at SP-8: ");
17096 ++ for (i = -1; i < 10; i++) {
17097 ++ unsigned long c;
17098 ++ if (get_user(c, (unsigned long __user *)sp+i))
17099 ++ printk("???????????????? ");
17100 ++ else
17101 ++ printk("%016lx ", c);
17102 ++ }
17103 ++ printk("\n");
17104 ++}
17105 ++#endif
17106 ++
17107 + static int page_fault_trace;
17108 + int show_unhandled_signals = 1;
17109 +
17110 +@@ -427,6 +585,8 @@ asmlinkage void __kprobes do_page_fault(
17111 + good_area:
17112 + info.si_code = SEGV_ACCERR;
17113 + write = 0;
17114 ++ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
17115 ++ goto bad_area;
17116 + switch (error_code & (PF_PROT|PF_WRITE)) {
17117 + default: /* 3: write, present */
17118 + /* fall through */
17119 +@@ -478,6 +638,21 @@ bad_area_nosemaphore:
17120 + */
17121 + local_irq_enable();
17122 +
17123 ++#ifdef CONFIG_PAX_PAGEEXEC
17124 ++ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
17125 ++
17126 ++#ifdef CONFIG_PAX_EMUTRAMP
17127 ++ switch (pax_handle_fetch_fault(regs)) {
17128 ++ case 2:
17129 ++ return;
17130 ++ }
17131 ++#endif
17132 ++
17133 ++ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
17134 ++ do_exit(SIGKILL);
17135 ++ }
17136 ++#endif
17137 ++
17138 + if (is_prefetch(regs, address, error_code))
17139 + return;
17140 +
17141 +@@ -499,7 +674,7 @@ bad_area_nosemaphore:
17142 + tsk->comm, tsk->pid, address, regs->rip,
17143 + regs->rsp, error_code);
17144 + }
17145 +-
17146 ++
17147 + tsk->thread.cr2 = address;
17148 + /* Kernel addresses are always protection faults */
17149 + tsk->thread.error_code = error_code | (address >= TASK_SIZE);
17150 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/init.c linux-2.6.23.15-grsec/arch/x86_64/mm/init.c
17151 +--- linux-2.6.23.15/arch/x86_64/mm/init.c 2008-02-11 10:36:03.000000000 +0000
17152 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/init.c 2008-02-11 10:37:44.000000000 +0000
17153 +@@ -45,7 +45,7 @@
17154 + #include <asm/sections.h>
17155 +
17156 + #ifndef Dprintk
17157 +-#define Dprintk(x...)
17158 ++#define Dprintk(x...) do {} while (0)
17159 + #endif
17160 +
17161 + const struct dma_mapping_ops* dma_ops;
17162 +@@ -736,7 +736,7 @@ int in_gate_area_no_task(unsigned long a
17163 +
17164 + const char *arch_vma_name(struct vm_area_struct *vma)
17165 + {
17166 +- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
17167 ++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
17168 + return "[vdso]";
17169 + if (vma == &gate_vma)
17170 + return "[vsyscall]";
17171 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/mmap.c linux-2.6.23.15-grsec/arch/x86_64/mm/mmap.c
17172 +--- linux-2.6.23.15/arch/x86_64/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100
17173 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000
17174 +@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
17175 + unsigned rnd = get_random_int() & 0xfffffff;
17176 + mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
17177 + }
17178 ++
17179 ++#ifdef CONFIG_PAX_RANDMMAP
17180 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
17181 ++ mm->mmap_base += mm->delta_mmap;
17182 ++#endif
17183 ++
17184 + mm->get_unmapped_area = arch_get_unmapped_area;
17185 + mm->unmap_area = arch_unmap_area;
17186 + }
17187 +diff -Nurp linux-2.6.23.15/arch/x86_64/mm/numa.c linux-2.6.23.15-grsec/arch/x86_64/mm/numa.c
17188 +--- linux-2.6.23.15/arch/x86_64/mm/numa.c 2007-10-09 21:31:38.000000000 +0100
17189 ++++ linux-2.6.23.15-grsec/arch/x86_64/mm/numa.c 2008-02-11 10:37:44.000000000 +0000
17190 +@@ -19,7 +19,7 @@
17191 + #include <asm/acpi.h>
17192 +
17193 + #ifndef Dprintk
17194 +-#define Dprintk(x...)
17195 ++#define Dprintk(x...) do {} while (0)
17196 + #endif
17197 +
17198 + struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
17199 +diff -Nurp linux-2.6.23.15/arch/x86_64/vdso/vma.c linux-2.6.23.15-grsec/arch/x86_64/vdso/vma.c
17200 +--- linux-2.6.23.15/arch/x86_64/vdso/vma.c 2007-10-09 21:31:38.000000000 +0100
17201 ++++ linux-2.6.23.15-grsec/arch/x86_64/vdso/vma.c 2008-02-11 10:37:44.000000000 +0000
17202 +@@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l
17203 + if (ret)
17204 + goto up_fail;
17205 +
17206 +- current->mm->context.vdso = (void *)addr;
17207 ++ current->mm->context.vdso = addr;
17208 + up_fail:
17209 + up_write(&mm->mmap_sem);
17210 + return ret;
17211 +diff -Nurp linux-2.6.23.15/crypto/async_tx/async_tx.c linux-2.6.23.15-grsec/crypto/async_tx/async_tx.c
17212 +--- linux-2.6.23.15/crypto/async_tx/async_tx.c 2007-10-09 21:31:38.000000000 +0100
17213 ++++ linux-2.6.23.15-grsec/crypto/async_tx/async_tx.c 2008-02-11 10:37:44.000000000 +0000
17214 +@@ -342,8 +342,8 @@ async_tx_init(void)
17215 + err:
17216 + printk(KERN_ERR "async_tx: initialization failure\n");
17217 +
17218 +- while (--cap >= 0)
17219 +- free_percpu(channel_table[cap]);
17220 ++ while (cap)
17221 ++ free_percpu(channel_table[--cap]);
17222 +
17223 + return 1;
17224 + }
17225 +diff -Nurp linux-2.6.23.15/crypto/lrw.c linux-2.6.23.15-grsec/crypto/lrw.c
17226 +--- linux-2.6.23.15/crypto/lrw.c 2007-10-09 21:31:38.000000000 +0100
17227 ++++ linux-2.6.23.15-grsec/crypto/lrw.c 2008-02-11 10:37:44.000000000 +0000
17228 +@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
17229 + struct priv *ctx = crypto_tfm_ctx(parent);
17230 + struct crypto_cipher *child = ctx->child;
17231 + int err, i;
17232 +- be128 tmp = { 0 };
17233 ++ be128 tmp = { 0, 0 };
17234 + int bsize = crypto_cipher_blocksize(child);
17235 +
17236 + crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
17237 +diff -Nurp linux-2.6.23.15/drivers/acpi/blacklist.c linux-2.6.23.15-grsec/drivers/acpi/blacklist.c
17238 +--- linux-2.6.23.15/drivers/acpi/blacklist.c 2008-02-11 10:36:03.000000000 +0000
17239 ++++ linux-2.6.23.15-grsec/drivers/acpi/blacklist.c 2008-02-11 10:37:44.000000000 +0000
17240 +@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
17241 + {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
17242 + "Incorrect _ADR", 1},
17243 +
17244 +- {""}
17245 ++ {"", "", 0, 0, 0, all_versions, 0}
17246 + };
17247 +
17248 + #if CONFIG_ACPI_BLACKLIST_YEAR
17249 +diff -Nurp linux-2.6.23.15/drivers/acpi/processor_core.c linux-2.6.23.15-grsec/drivers/acpi/processor_core.c
17250 +--- linux-2.6.23.15/drivers/acpi/processor_core.c 2007-10-09 21:31:38.000000000 +0100
17251 ++++ linux-2.6.23.15-grsec/drivers/acpi/processor_core.c 2008-02-11 10:37:44.000000000 +0000
17252 +@@ -643,7 +643,7 @@ static int __cpuinit acpi_processor_star
17253 + return 0;
17254 + }
17255 +
17256 +- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
17257 ++ BUG_ON(pr->id >= NR_CPUS);
17258 +
17259 + /*
17260 + * Buggy BIOS check
17261 +diff -Nurp linux-2.6.23.15/drivers/acpi/processor_idle.c linux-2.6.23.15-grsec/drivers/acpi/processor_idle.c
17262 +--- linux-2.6.23.15/drivers/acpi/processor_idle.c 2007-10-09 21:31:38.000000000 +0100
17263 ++++ linux-2.6.23.15-grsec/drivers/acpi/processor_idle.c 2008-02-11 10:37:44.000000000 +0000
17264 +@@ -164,7 +164,7 @@ static struct dmi_system_id __cpuinitdat
17265 + DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
17266 + DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
17267 + (void *)2},
17268 +- {},
17269 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
17270 + };
17271 +
17272 + static inline u32 ticks_elapsed(u32 t1, u32 t2)
17273 +diff -Nurp linux-2.6.23.15/drivers/acpi/sleep/main.c linux-2.6.23.15-grsec/drivers/acpi/sleep/main.c
17274 +--- linux-2.6.23.15/drivers/acpi/sleep/main.c 2008-02-11 10:36:03.000000000 +0000
17275 ++++ linux-2.6.23.15-grsec/drivers/acpi/sleep/main.c 2008-02-11 10:37:44.000000000 +0000
17276 +@@ -228,7 +228,7 @@ static struct dmi_system_id __initdata a
17277 + .ident = "Toshiba Satellite 4030cdt",
17278 + .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
17279 + },
17280 +- {},
17281 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
17282 + };
17283 + #endif /* CONFIG_SUSPEND */
17284 +
17285 +diff -Nurp linux-2.6.23.15/drivers/acpi/tables/tbfadt.c linux-2.6.23.15-grsec/drivers/acpi/tables/tbfadt.c
17286 +--- linux-2.6.23.15/drivers/acpi/tables/tbfadt.c 2007-10-09 21:31:38.000000000 +0100
17287 ++++ linux-2.6.23.15-grsec/drivers/acpi/tables/tbfadt.c 2008-02-11 10:37:44.000000000 +0000
17288 +@@ -48,7 +48,7 @@
17289 + ACPI_MODULE_NAME("tbfadt")
17290 +
17291 + /* Local prototypes */
17292 +-static void inline
17293 ++static inline void
17294 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
17295 + u8 bit_width, u64 address);
17296 +
17297 +@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
17298 + *
17299 + ******************************************************************************/
17300 +
17301 +-static void inline
17302 ++static inline void
17303 + acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
17304 + u8 bit_width, u64 address)
17305 + {
17306 +diff -Nurp linux-2.6.23.15/drivers/ata/ahci.c linux-2.6.23.15-grsec/drivers/ata/ahci.c
17307 +--- linux-2.6.23.15/drivers/ata/ahci.c 2008-02-11 10:36:03.000000000 +0000
17308 ++++ linux-2.6.23.15-grsec/drivers/ata/ahci.c 2008-02-11 10:37:44.000000000 +0000
17309 +@@ -523,7 +523,7 @@ static const struct pci_device_id ahci_p
17310 + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
17311 + PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
17312 +
17313 +- { } /* terminate list */
17314 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17315 + };
17316 +
17317 +
17318 +diff -Nurp linux-2.6.23.15/drivers/ata/ata_piix.c linux-2.6.23.15-grsec/drivers/ata/ata_piix.c
17319 +--- linux-2.6.23.15/drivers/ata/ata_piix.c 2007-10-09 21:31:38.000000000 +0100
17320 ++++ linux-2.6.23.15-grsec/drivers/ata/ata_piix.c 2008-02-11 10:37:44.000000000 +0000
17321 +@@ -257,7 +257,7 @@ static const struct pci_device_id piix_p
17322 + /* SATA Controller IDE (Tolapai) */
17323 + { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci },
17324 +
17325 +- { } /* terminate list */
17326 ++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
17327 + };
17328 +
17329 + static struct pci_driver piix_pci_driver = {
17330 +@@ -617,7 +617,7 @@ static const struct ich_laptop ich_lapto
17331 + { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
17332 + { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
17333 + /* end marker */
17334 +- { 0, }
17335 ++ { 0, 0, 0 }
17336 + };
17337 +
17338 + /**
17339 +@@ -963,7 +963,7 @@ static int piix_broken_suspend(void)
17340 + },
17341 + },
17342 +
17343 +- { } /* terminate list */
17344 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */
17345 + };
17346 + static const char *oemstrs[] = {
17347 + "Tecra M3,",
17348 +diff -Nurp linux-2.6.23.15/drivers/ata/libata-core.c linux-2.6.23.15-grsec/drivers/ata/libata-core.c
17349 +--- linux-2.6.23.15/drivers/ata/libata-core.c 2008-02-11 10:36:03.000000000 +0000
17350 ++++ linux-2.6.23.15-grsec/drivers/ata/libata-core.c 2008-02-11 10:37:44.000000000 +0000
17351 +@@ -472,7 +472,7 @@ static const struct ata_xfer_ent {
17352 + { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
17353 + { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
17354 + { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
17355 +- { -1, },
17356 ++ { -1, 0, 0 },
17357 + };
17358 +
17359 + /**
17360 +@@ -2546,7 +2546,7 @@ static const struct ata_timing ata_timin
17361 +
17362 + /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
17363 +
17364 +- { 0xFF }
17365 ++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
17366 + };
17367 +
17368 + #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
17369 +@@ -3799,7 +3799,7 @@ static const struct ata_blacklist_entry
17370 + { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA },
17371 +
17372 + /* End Marker */
17373 +- { }
17374 ++ { NULL, NULL, 0 }
17375 + };
17376 +
17377 + static unsigned long ata_dev_blacklisted(const struct ata_device *dev)
17378 +diff -Nurp linux-2.6.23.15/drivers/char/agp/frontend.c linux-2.6.23.15-grsec/drivers/char/agp/frontend.c
17379 +--- linux-2.6.23.15/drivers/char/agp/frontend.c 2007-10-09 21:31:38.000000000 +0100
17380 ++++ linux-2.6.23.15-grsec/drivers/char/agp/frontend.c 2008-02-11 10:37:44.000000000 +0000
17381 +@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag
17382 + if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
17383 + return -EFAULT;
17384 +
17385 +- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
17386 ++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
17387 + return -EFAULT;
17388 +
17389 + client = agp_find_client_by_pid(reserve.pid);
17390 +diff -Nurp linux-2.6.23.15/drivers/char/agp/intel-agp.c linux-2.6.23.15-grsec/drivers/char/agp/intel-agp.c
17391 +--- linux-2.6.23.15/drivers/char/agp/intel-agp.c 2007-10-09 21:31:38.000000000 +0100
17392 ++++ linux-2.6.23.15-grsec/drivers/char/agp/intel-agp.c 2008-02-11 10:37:44.000000000 +0000
17393 +@@ -2071,7 +2071,7 @@ static struct pci_device_id agp_intel_pc
17394 + ID(PCI_DEVICE_ID_INTEL_G33_HB),
17395 + ID(PCI_DEVICE_ID_INTEL_Q35_HB),
17396 + ID(PCI_DEVICE_ID_INTEL_Q33_HB),
17397 +- { }
17398 ++ { 0, 0, 0, 0, 0, 0, 0 }
17399 + };
17400 +
17401 + MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
17402 +diff -Nurp linux-2.6.23.15/drivers/char/drm/drm_pciids.h linux-2.6.23.15-grsec/drivers/char/drm/drm_pciids.h
17403 +--- linux-2.6.23.15/drivers/char/drm/drm_pciids.h 2007-10-09 21:31:38.000000000 +0100
17404 ++++ linux-2.6.23.15-grsec/drivers/char/drm/drm_pciids.h 2008-02-11 10:37:44.000000000 +0000
17405 +@@ -251,7 +251,7 @@
17406 + {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17407 + {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17408 + {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17409 +- {0, 0, 0}
17410 ++ {0, 0, 0, 0, 0, 0, 0 }
17411 +
17412 + #define i830_PCI_IDS \
17413 + {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
17414 +diff -Nurp linux-2.6.23.15/drivers/char/hpet.c linux-2.6.23.15-grsec/drivers/char/hpet.c
17415 +--- linux-2.6.23.15/drivers/char/hpet.c 2007-10-09 21:31:38.000000000 +0100
17416 ++++ linux-2.6.23.15-grsec/drivers/char/hpet.c 2008-02-11 10:37:44.000000000 +0000
17417 +@@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv
17418 + },
17419 + };
17420 +
17421 +-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
17422 ++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
17423 +
17424 + static int __init hpet_init(void)
17425 + {
17426 +diff -Nurp linux-2.6.23.15/drivers/char/keyboard.c linux-2.6.23.15-grsec/drivers/char/keyboard.c
17427 +--- linux-2.6.23.15/drivers/char/keyboard.c 2007-10-09 21:31:38.000000000 +0100
17428 ++++ linux-2.6.23.15-grsec/drivers/char/keyboard.c 2008-02-11 10:37:44.000000000 +0000
17429 +@@ -605,6 +605,16 @@ static void k_spec(struct vc_data *vc, u
17430 + kbd->kbdmode == VC_MEDIUMRAW) &&
17431 + value != KVAL(K_SAK))
17432 + return; /* SAK is allowed even in raw mode */
17433 ++
17434 ++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
17435 ++ {
17436 ++ void *func = fn_handler[value];
17437 ++ if (func == fn_show_state || func == fn_show_ptregs ||
17438 ++ func == fn_show_mem)
17439 ++ return;
17440 ++ }
17441 ++#endif
17442 ++
17443 + fn_handler[value](vc);
17444 + }
17445 +
17446 +@@ -1340,7 +1350,7 @@ static const struct input_device_id kbd_
17447 + .evbit = { BIT(EV_SND) },
17448 + },
17449 +
17450 +- { }, /* Terminating entry */
17451 ++ { 0 }, /* Terminating entry */
17452 + };
17453 +
17454 + MODULE_DEVICE_TABLE(input, kbd_ids);
17455 +diff -Nurp linux-2.6.23.15/drivers/char/mem.c linux-2.6.23.15-grsec/drivers/char/mem.c
17456 +--- linux-2.6.23.15/drivers/char/mem.c 2007-10-09 21:31:38.000000000 +0100
17457 ++++ linux-2.6.23.15-grsec/drivers/char/mem.c 2008-02-11 10:37:44.000000000 +0000
17458 +@@ -26,6 +26,7 @@
17459 + #include <linux/bootmem.h>
17460 + #include <linux/splice.h>
17461 + #include <linux/pfn.h>
17462 ++#include <linux/grsecurity.h>
17463 +
17464 + #include <asm/uaccess.h>
17465 + #include <asm/io.h>
17466 +@@ -34,6 +35,10 @@
17467 + # include <linux/efi.h>
17468 + #endif
17469 +
17470 ++#ifdef CONFIG_GRKERNSEC
17471 ++extern struct file_operations grsec_fops;
17472 ++#endif
17473 ++
17474 + /*
17475 + * Architectures vary in how they handle caching for addresses
17476 + * outside of main memory.
17477 +@@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f
17478 + if (!valid_phys_addr_range(p, count))
17479 + return -EFAULT;
17480 +
17481 ++#ifdef CONFIG_GRKERNSEC_KMEM
17482 ++ gr_handle_mem_write();
17483 ++ return -EPERM;
17484 ++#endif
17485 ++
17486 + written = 0;
17487 +
17488 + #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
17489 +@@ -281,6 +291,11 @@ static int mmap_mem(struct file * file,
17490 + if (!private_mapping_ok(vma))
17491 + return -ENOSYS;
17492 +
17493 ++#ifdef CONFIG_GRKERNSEC_KMEM
17494 ++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
17495 ++ return -EPERM;
17496 ++#endif
17497 ++
17498 + vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
17499 + size,
17500 + vma->vm_page_prot);
17501 +@@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file *
17502 + ssize_t written;
17503 + char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
17504 +
17505 ++#ifdef CONFIG_GRKERNSEC_KMEM
17506 ++ gr_handle_kmem_write();
17507 ++ return -EPERM;
17508 ++#endif
17509 ++
17510 + if (p < (unsigned long) high_memory) {
17511 +
17512 + wrote = count;
17513 +@@ -635,6 +655,10 @@ static inline size_t read_zero_pagealign
17514 + struct vm_area_struct * vma;
17515 + unsigned long addr=(unsigned long)buf;
17516 +
17517 ++#ifdef CONFIG_PAX_SEGMEXEC
17518 ++ struct vm_area_struct *vma_m;
17519 ++#endif
17520 ++
17521 + mm = current->mm;
17522 + /* Oops, this was forgotten before. -ben */
17523 + down_read(&mm->mmap_sem);
17524 +@@ -651,8 +675,14 @@ static inline size_t read_zero_pagealign
17525 + if (count > size)
17526 + count = size;
17527 +
17528 ++#ifdef CONFIG_PAX_SEGMEXEC
17529 ++ vma_m = pax_find_mirror_vma(vma);
17530 ++ if (vma_m)
17531 ++ zap_page_range(vma_m, addr + SEGMEXEC_TASK_SIZE, count, NULL);
17532 ++#endif
17533 ++
17534 + zap_page_range(vma, addr, count, NULL);
17535 +- if (zeromap_page_range(vma, addr, count, PAGE_COPY))
17536 ++ if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
17537 + break;
17538 +
17539 + size -= count;
17540 +@@ -805,6 +835,16 @@ static loff_t memory_lseek(struct file *
17541 +
17542 + static int open_port(struct inode * inode, struct file * filp)
17543 + {
17544 ++#ifdef CONFIG_GRKERNSEC_KMEM
17545 ++ gr_handle_open_port();
17546 ++ return -EPERM;
17547 ++#endif
17548 ++
17549 ++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17550 ++}
17551 ++
17552 ++static int open_mem(struct inode * inode, struct file * filp)
17553 ++{
17554 + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
17555 + }
17556 +
17557 +@@ -812,7 +852,6 @@ static int open_port(struct inode * inod
17558 + #define full_lseek null_lseek
17559 + #define write_zero write_null
17560 + #define read_full read_zero
17561 +-#define open_mem open_port
17562 + #define open_kmem open_mem
17563 + #define open_oldmem open_mem
17564 +
17565 +@@ -945,6 +984,11 @@ static int memory_open(struct inode * in
17566 + filp->f_op = &oldmem_fops;
17567 + break;
17568 + #endif
17569 ++#ifdef CONFIG_GRKERNSEC
17570 ++ case 13:
17571 ++ filp->f_op = &grsec_fops;
17572 ++ break;
17573 ++#endif
17574 + default:
17575 + return -ENXIO;
17576 + }
17577 +@@ -977,6 +1021,9 @@ static const struct {
17578 + #ifdef CONFIG_CRASH_DUMP
17579 + {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
17580 + #endif
17581 ++#ifdef CONFIG_GRKERNSEC
17582 ++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
17583 ++#endif
17584 + };
17585 +
17586 + static struct class *mem_class;
17587 +diff -Nurp linux-2.6.23.15/drivers/char/nvram.c linux-2.6.23.15-grsec/drivers/char/nvram.c
17588 +--- linux-2.6.23.15/drivers/char/nvram.c 2007-10-09 21:31:38.000000000 +0100
17589 ++++ linux-2.6.23.15-grsec/drivers/char/nvram.c 2008-02-11 10:37:44.000000000 +0000
17590 +@@ -430,7 +430,10 @@ static const struct file_operations nvra
17591 + static struct miscdevice nvram_dev = {
17592 + NVRAM_MINOR,
17593 + "nvram",
17594 +- &nvram_fops
17595 ++ &nvram_fops,
17596 ++ {NULL, NULL},
17597 ++ NULL,
17598 ++ NULL
17599 + };
17600 +
17601 + static int __init
17602 +diff -Nurp linux-2.6.23.15/drivers/char/random.c linux-2.6.23.15-grsec/drivers/char/random.c
17603 +--- linux-2.6.23.15/drivers/char/random.c 2008-02-11 10:36:03.000000000 +0000
17604 ++++ linux-2.6.23.15-grsec/drivers/char/random.c 2008-02-11 10:37:44.000000000 +0000
17605 +@@ -248,8 +248,13 @@
17606 + /*
17607 + * Configuration information
17608 + */
17609 ++#ifdef CONFIG_GRKERNSEC_RANDNET
17610 ++#define INPUT_POOL_WORDS 512
17611 ++#define OUTPUT_POOL_WORDS 128
17612 ++#else
17613 + #define INPUT_POOL_WORDS 128
17614 + #define OUTPUT_POOL_WORDS 32
17615 ++#endif
17616 + #define SEC_XFER_SIZE 512
17617 +
17618 + /*
17619 +@@ -286,10 +291,17 @@ static struct poolinfo {
17620 + int poolwords;
17621 + int tap1, tap2, tap3, tap4, tap5;
17622 + } poolinfo_table[] = {
17623 ++#ifdef CONFIG_GRKERNSEC_RANDNET
17624 ++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
17625 ++ { 512, 411, 308, 208, 104, 1 },
17626 ++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
17627 ++ { 128, 103, 76, 51, 25, 1 },
17628 ++#else
17629 + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
17630 + { 128, 103, 76, 51, 25, 1 },
17631 + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
17632 + { 32, 26, 20, 14, 7, 1 },
17633 ++#endif
17634 + #if 0
17635 + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
17636 + { 2048, 1638, 1231, 819, 411, 1 },
17637 +@@ -1172,7 +1184,7 @@ EXPORT_SYMBOL(generate_random_uuid);
17638 + #include <linux/sysctl.h>
17639 +
17640 + static int min_read_thresh = 8, min_write_thresh;
17641 +-static int max_read_thresh = INPUT_POOL_WORDS * 32;
17642 ++static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
17643 + static int max_write_thresh = INPUT_POOL_WORDS * 32;
17644 + static char sysctl_bootid[16];
17645 +
17646 +diff -Nurp linux-2.6.23.15/drivers/char/vt_ioctl.c linux-2.6.23.15-grsec/drivers/char/vt_ioctl.c
17647 +--- linux-2.6.23.15/drivers/char/vt_ioctl.c 2007-10-09 21:31:38.000000000 +0100
17648 ++++ linux-2.6.23.15-grsec/drivers/char/vt_ioctl.c 2008-02-11 10:37:44.000000000 +0000
17649 +@@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
17650 + case KDSKBENT:
17651 + if (!perm)
17652 + return -EPERM;
17653 ++
17654 ++#ifdef CONFIG_GRKERNSEC
17655 ++ if (!capable(CAP_SYS_TTY_CONFIG))
17656 ++ return -EPERM;
17657 ++#endif
17658 ++
17659 + if (!i && v == K_NOSUCHMAP) {
17660 + /* deallocate map */
17661 + key_map = key_maps[s];
17662 +@@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
17663 + goto reterr;
17664 + }
17665 +
17666 ++#ifdef CONFIG_GRKERNSEC
17667 ++ if (!capable(CAP_SYS_TTY_CONFIG)) {
17668 ++ ret = -EPERM;
17669 ++ goto reterr;
17670 ++ }
17671 ++#endif
17672 ++
17673 + q = func_table[i];
17674 + first_free = funcbufptr + (funcbufsize - funcbufleft);
17675 + for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
17676 +diff -Nurp linux-2.6.23.15/drivers/dma/ioatdma.c linux-2.6.23.15-grsec/drivers/dma/ioatdma.c
17677 +--- linux-2.6.23.15/drivers/dma/ioatdma.c 2007-10-09 21:31:38.000000000 +0100
17678 ++++ linux-2.6.23.15-grsec/drivers/dma/ioatdma.c 2008-02-11 10:37:44.000000000 +0000
17679 +@@ -244,7 +244,6 @@ static void ioat_dma_free_chan_resources
17680 + struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
17681 + struct ioat_device *ioat_device = to_ioat_device(chan->device);
17682 + struct ioat_desc_sw *desc, *_desc;
17683 +- u16 chanctrl;
17684 + int in_use_descs = 0;
17685 +
17686 + ioat_dma_memcpy_cleanup(ioat_chan);
17687 +diff -Nurp linux-2.6.23.15/drivers/edac/edac_core.h linux-2.6.23.15-grsec/drivers/edac/edac_core.h
17688 +--- linux-2.6.23.15/drivers/edac/edac_core.h 2007-10-09 21:31:38.000000000 +0100
17689 ++++ linux-2.6.23.15-grsec/drivers/edac/edac_core.h 2008-02-11 10:37:44.000000000 +0000
17690 +@@ -86,11 +86,11 @@ extern int edac_debug_level;
17691 +
17692 + #else /* !CONFIG_EDAC_DEBUG */
17693 +
17694 +-#define debugf0( ... )
17695 +-#define debugf1( ... )
17696 +-#define debugf2( ... )
17697 +-#define debugf3( ... )
17698 +-#define debugf4( ... )
17699 ++#define debugf0( ... ) do {} while (0)
17700 ++#define debugf1( ... ) do {} while (0)
17701 ++#define debugf2( ... ) do {} while (0)
17702 ++#define debugf3( ... ) do {} while (0)
17703 ++#define debugf4( ... ) do {} while (0)
17704 +
17705 + #endif /* !CONFIG_EDAC_DEBUG */
17706 +
17707 +diff -Nurp linux-2.6.23.15/drivers/hwmon/fscpos.c linux-2.6.23.15-grsec/drivers/hwmon/fscpos.c
17708 +--- linux-2.6.23.15/drivers/hwmon/fscpos.c 2007-10-09 21:31:38.000000000 +0100
17709 ++++ linux-2.6.23.15-grsec/drivers/hwmon/fscpos.c 2008-02-11 10:37:44.000000000 +0000
17710 +@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
17711 + unsigned long v = simple_strtoul(buf, NULL, 10);
17712 +
17713 + /* Range: 0..255 */
17714 +- if (v < 0) v = 0;
17715 + if (v > 255) v = 255;
17716 +
17717 + mutex_lock(&data->update_lock);
17718 +diff -Nurp linux-2.6.23.15/drivers/hwmon/k8temp.c linux-2.6.23.15-grsec/drivers/hwmon/k8temp.c
17719 +--- linux-2.6.23.15/drivers/hwmon/k8temp.c 2007-10-09 21:31:38.000000000 +0100
17720 ++++ linux-2.6.23.15-grsec/drivers/hwmon/k8temp.c 2008-02-11 10:37:44.000000000 +0000
17721 +@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
17722 +
17723 + static struct pci_device_id k8temp_ids[] = {
17724 + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
17725 +- { 0 },
17726 ++ { 0, 0, 0, 0, 0, 0, 0 },
17727 + };
17728 +
17729 + MODULE_DEVICE_TABLE(pci, k8temp_ids);
17730 +diff -Nurp linux-2.6.23.15/drivers/hwmon/sis5595.c linux-2.6.23.15-grsec/drivers/hwmon/sis5595.c
17731 +--- linux-2.6.23.15/drivers/hwmon/sis5595.c 2007-10-09 21:31:38.000000000 +0100
17732 ++++ linux-2.6.23.15-grsec/drivers/hwmon/sis5595.c 2008-02-11 10:37:44.000000000 +0000
17733 +@@ -673,7 +673,7 @@ static struct sis5595_data *sis5595_upda
17734 +
17735 + static struct pci_device_id sis5595_pci_ids[] = {
17736 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
17737 +- { 0, }
17738 ++ { 0, 0, 0, 0, 0, 0, 0 }
17739 + };
17740 +
17741 + MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
17742 +diff -Nurp linux-2.6.23.15/drivers/hwmon/thmc50.c linux-2.6.23.15-grsec/drivers/hwmon/thmc50.c
17743 +--- linux-2.6.23.15/drivers/hwmon/thmc50.c 2007-10-09 21:31:38.000000000 +0100
17744 ++++ linux-2.6.23.15-grsec/drivers/hwmon/thmc50.c 2008-02-11 10:37:44.000000000 +0000
17745 +@@ -47,9 +47,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L
17746 + #define THMC50_REG_DIE_CODE 0x3F
17747 + #define THMC50_REG_ANALOG_OUT 0x19
17748 +
17749 +-const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
17750 +-const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
17751 +-const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
17752 ++static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 };
17753 ++static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C };
17754 ++static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B };
17755 +
17756 + #define THMC50_REG_CONF_nFANOFF 0x20
17757 +
17758 +diff -Nurp linux-2.6.23.15/drivers/hwmon/via686a.c linux-2.6.23.15-grsec/drivers/hwmon/via686a.c
17759 +--- linux-2.6.23.15/drivers/hwmon/via686a.c 2007-10-09 21:31:38.000000000 +0100
17760 ++++ linux-2.6.23.15-grsec/drivers/hwmon/via686a.c 2008-02-11 10:37:44.000000000 +0000
17761 +@@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda
17762 +
17763 + static struct pci_device_id via686a_pci_ids[] = {
17764 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
17765 +- { 0, }
17766 ++ { 0, 0, 0, 0, 0, 0, 0 }
17767 + };
17768 +
17769 + MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
17770 +diff -Nurp linux-2.6.23.15/drivers/hwmon/vt8231.c linux-2.6.23.15-grsec/drivers/hwmon/vt8231.c
17771 +--- linux-2.6.23.15/drivers/hwmon/vt8231.c 2007-10-09 21:31:38.000000000 +0100
17772 ++++ linux-2.6.23.15-grsec/drivers/hwmon/vt8231.c 2008-02-11 10:37:44.000000000 +0000
17773 +@@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri
17774 +
17775 + static struct pci_device_id vt8231_pci_ids[] = {
17776 + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
17777 +- { 0, }
17778 ++ { 0, 0, 0, 0, 0, 0, 0 }
17779 + };
17780 +
17781 + MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
17782 +diff -Nurp linux-2.6.23.15/drivers/hwmon/w83791d.c linux-2.6.23.15-grsec/drivers/hwmon/w83791d.c
17783 +--- linux-2.6.23.15/drivers/hwmon/w83791d.c 2007-10-09 21:31:38.000000000 +0100
17784 ++++ linux-2.6.23.15-grsec/drivers/hwmon/w83791d.c 2008-02-11 10:37:44.000000000 +0000
17785 +@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
17786 + static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
17787 + static int w83791d_detach_client(struct i2c_client *client);
17788 +
17789 +-static int w83791d_read(struct i2c_client *client, u8 register);
17790 +-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
17791 ++static int w83791d_read(struct i2c_client *client, u8 reg);
17792 ++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
17793 + static struct w83791d_data *w83791d_update_device(struct device *dev);
17794 +
17795 + #ifdef DEBUG
17796 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-i801.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i801.c
17797 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-i801.c 2007-10-09 21:31:38.000000000 +0100
17798 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i801.c 2008-02-11 10:37:44.000000000 +0000
17799 +@@ -543,7 +543,7 @@ static struct pci_device_id i801_ids[] =
17800 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
17801 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
17802 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
17803 +- { 0, }
17804 ++ { 0, 0, 0, 0, 0, 0, 0 }
17805 + };
17806 +
17807 + MODULE_DEVICE_TABLE (pci, i801_ids);
17808 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-i810.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i810.c
17809 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-i810.c 2007-10-09 21:31:38.000000000 +0100
17810 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i810.c 2008-02-11 10:37:44.000000000 +0000
17811 +@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
17812 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
17813 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
17814 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
17815 +- { 0, },
17816 ++ { 0, 0, 0, 0, 0, 0, 0 },
17817 + };
17818 +
17819 + MODULE_DEVICE_TABLE (pci, i810_ids);
17820 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-piix4.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-piix4.c
17821 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-piix4.c 2007-10-09 21:31:38.000000000 +0100
17822 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-piix4.c 2008-02-11 10:37:44.000000000 +0000
17823 +@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
17824 + .ident = "IBM",
17825 + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
17826 + },
17827 +- { },
17828 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
17829 + };
17830 +
17831 + static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
17832 +@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[]
17833 + .driver_data = 3 },
17834 + { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
17835 + .driver_data = 0 },
17836 +- { 0, }
17837 ++ { 0, 0, 0, 0, 0, 0, 0 }
17838 + };
17839 +
17840 + MODULE_DEVICE_TABLE (pci, piix4_ids);
17841 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-sis630.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis630.c
17842 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-sis630.c 2007-10-09 21:31:38.000000000 +0100
17843 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis630.c 2008-02-11 10:37:44.000000000 +0000
17844 +@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
17845 + static struct pci_device_id sis630_ids[] __devinitdata = {
17846 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
17847 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
17848 +- { 0, }
17849 ++ { PCI_DEVICE(0, 0) }
17850 + };
17851 +
17852 + MODULE_DEVICE_TABLE (pci, sis630_ids);
17853 +diff -Nurp linux-2.6.23.15/drivers/i2c/busses/i2c-sis96x.c linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis96x.c
17854 +--- linux-2.6.23.15/drivers/i2c/busses/i2c-sis96x.c 2007-10-09 21:31:38.000000000 +0100
17855 ++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis96x.c 2008-02-11 10:37:44.000000000 +0000
17856 +@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
17857 +
17858 + static struct pci_device_id sis96x_ids[] = {
17859 + { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
17860 +- { 0, }
17861 ++ { PCI_DEVICE(0, 0) }
17862 + };
17863 +
17864 + MODULE_DEVICE_TABLE (pci, sis96x_ids);
17865 +diff -Nurp linux-2.6.23.15/drivers/ide/ide-cd.c linux-2.6.23.15-grsec/drivers/ide/ide-cd.c
17866 +--- linux-2.6.23.15/drivers/ide/ide-cd.c 2007-10-09 21:31:38.000000000 +0100
17867 ++++ linux-2.6.23.15-grsec/drivers/ide/ide-cd.c 2008-02-11 10:37:44.000000000 +0000
17868 +@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
17869 + sector &= ~(bio_sectors -1);
17870 + valid = (sector - failed_command->sector) << 9;
17871 +
17872 +- if (valid < 0)
17873 +- valid = 0;
17874 + if (sector < get_capacity(info->disk) &&
17875 + drive->probed_capacity - sector < 4 * 75) {
17876 + set_capacity(info->disk, sector);
17877 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/dv1394.c linux-2.6.23.15-grsec/drivers/ieee1394/dv1394.c
17878 +--- linux-2.6.23.15/drivers/ieee1394/dv1394.c 2007-10-09 21:31:38.000000000 +0100
17879 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/dv1394.c 2008-02-11 10:37:44.000000000 +0000
17880 +@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
17881 + based upon DIF section and sequence
17882 + */
17883 +
17884 +-static void inline
17885 ++static inline void
17886 + frame_put_packet (struct frame *f, struct packet *p)
17887 + {
17888 + int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
17889 +@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
17890 + /* default SYT offset is 3 cycles */
17891 + init->syt_offset = 3;
17892 +
17893 +- if ( (init->channel > 63) || (init->channel < 0) )
17894 ++ if (init->channel > 63)
17895 + init->channel = 63;
17896 +
17897 + chan_mask = (u64)1 << init->channel;
17898 +@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
17899 + .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
17900 + .version = AVC_SW_VERSION_ENTRY & 0xffffff
17901 + },
17902 +- { }
17903 ++ { 0, 0, 0, 0, 0, 0 }
17904 + };
17905 +
17906 + MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
17907 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/eth1394.c linux-2.6.23.15-grsec/drivers/ieee1394/eth1394.c
17908 +--- linux-2.6.23.15/drivers/ieee1394/eth1394.c 2007-10-09 21:31:38.000000000 +0100
17909 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/eth1394.c 2008-02-11 10:37:44.000000000 +0000
17910 +@@ -449,7 +449,7 @@ static struct ieee1394_device_id eth1394
17911 + .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
17912 + .version = ETHER1394_GASP_VERSION,
17913 + },
17914 +- {}
17915 ++ { 0, 0, 0, 0, 0, 0 }
17916 + };
17917 +
17918 + MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
17919 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/hosts.c linux-2.6.23.15-grsec/drivers/ieee1394/hosts.c
17920 +--- linux-2.6.23.15/drivers/ieee1394/hosts.c 2007-10-09 21:31:38.000000000 +0100
17921 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/hosts.c 2008-02-11 10:37:44.000000000 +0000
17922 +@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
17923 + }
17924 +
17925 + static struct hpsb_host_driver dummy_driver = {
17926 ++ .name = "dummy",
17927 + .transmit_packet = dummy_transmit_packet,
17928 + .devctl = dummy_devctl,
17929 + .isoctl = dummy_isoctl
17930 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/ohci1394.c linux-2.6.23.15-grsec/drivers/ieee1394/ohci1394.c
17931 +--- linux-2.6.23.15/drivers/ieee1394/ohci1394.c 2007-10-09 21:31:38.000000000 +0100
17932 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/ohci1394.c 2008-02-11 10:37:44.000000000 +0000
17933 +@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
17934 + printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
17935 +
17936 + /* Module Parameters */
17937 +-static int phys_dma = 1;
17938 ++static int phys_dma;
17939 + module_param(phys_dma, int, 0444);
17940 +-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
17941 ++MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
17942 +
17943 + static void dma_trm_tasklet(unsigned long data);
17944 + static void dma_trm_reset(struct dma_trm_ctx *d);
17945 +@@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci
17946 + .subvendor = PCI_ANY_ID,
17947 + .subdevice = PCI_ANY_ID,
17948 + },
17949 +- { 0, },
17950 ++ { 0, 0, 0, 0, 0, 0, 0 },
17951 + };
17952 +
17953 + MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
17954 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/raw1394.c linux-2.6.23.15-grsec/drivers/ieee1394/raw1394.c
17955 +--- linux-2.6.23.15/drivers/ieee1394/raw1394.c 2007-10-09 21:31:38.000000000 +0100
17956 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/raw1394.c 2008-02-11 10:37:44.000000000 +0000
17957 +@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394
17958 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
17959 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
17960 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
17961 +- {}
17962 ++ { 0, 0, 0, 0, 0, 0 }
17963 + };
17964 +
17965 + MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
17966 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/sbp2.c linux-2.6.23.15-grsec/drivers/ieee1394/sbp2.c
17967 +--- linux-2.6.23.15/drivers/ieee1394/sbp2.c 2007-10-09 21:31:38.000000000 +0100
17968 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/sbp2.c 2008-02-11 10:37:44.000000000 +0000
17969 +@@ -272,7 +272,7 @@ static struct ieee1394_device_id sbp2_id
17970 + .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
17971 + .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
17972 + .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
17973 +- {}
17974 ++ { 0, 0, 0, 0, 0, 0 }
17975 + };
17976 + MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
17977 +
17978 +@@ -2063,7 +2063,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
17979 + MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
17980 + MODULE_LICENSE("GPL");
17981 +
17982 +-static int sbp2_module_init(void)
17983 ++static int __init sbp2_module_init(void)
17984 + {
17985 + int ret;
17986 +
17987 +diff -Nurp linux-2.6.23.15/drivers/ieee1394/video1394.c linux-2.6.23.15-grsec/drivers/ieee1394/video1394.c
17988 +--- linux-2.6.23.15/drivers/ieee1394/video1394.c 2007-10-09 21:31:38.000000000 +0100
17989 ++++ linux-2.6.23.15-grsec/drivers/ieee1394/video1394.c 2008-02-11 10:37:44.000000000 +0000
17990 +@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
17991 + if (unlikely(d == NULL))
17992 + return -EFAULT;
17993 +
17994 +- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
17995 ++ if (unlikely(v.buffer>=d->num_desc - 1)) {
17996 + PRINT(KERN_ERR, ohci->host->id,
17997 + "Buffer %d out of range",v.buffer);
17998 + return -EINVAL;
17999 +@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
18000 + if (unlikely(d == NULL))
18001 + return -EFAULT;
18002 +
18003 +- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
18004 ++ if (unlikely(v.buffer>d->num_desc - 1)) {
18005 + PRINT(KERN_ERR, ohci->host->id,
18006 + "Buffer %d out of range",v.buffer);
18007 + return -EINVAL;
18008 +@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
18009 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
18010 + if (d == NULL) return -EFAULT;
18011 +
18012 +- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
18013 ++ if (v.buffer>=d->num_desc - 1) {
18014 + PRINT(KERN_ERR, ohci->host->id,
18015 + "Buffer %d out of range",v.buffer);
18016 + return -EINVAL;
18017 +@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
18018 + d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
18019 + if (d == NULL) return -EFAULT;
18020 +
18021 +- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
18022 ++ if (v.buffer>=d->num_desc-1) {
18023 + PRINT(KERN_ERR, ohci->host->id,
18024 + "Buffer %d out of range",v.buffer);
18025 + return -EINVAL;
18026 +@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
18027 + .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
18028 + .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
18029 + },
18030 +- { }
18031 ++ { 0, 0, 0, 0, 0, 0 }
18032 + };
18033 +
18034 + MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
18035 +diff -Nurp linux-2.6.23.15/drivers/input/keyboard/atkbd.c linux-2.6.23.15-grsec/drivers/input/keyboard/atkbd.c
18036 +--- linux-2.6.23.15/drivers/input/keyboard/atkbd.c 2007-10-09 21:31:38.000000000 +0100
18037 ++++ linux-2.6.23.15-grsec/drivers/input/keyboard/atkbd.c 2008-02-11 10:37:44.000000000 +0000
18038 +@@ -1075,7 +1075,7 @@ static struct serio_device_id atkbd_seri
18039 + .id = SERIO_ANY,
18040 + .extra = SERIO_ANY,
18041 + },
18042 +- { 0 }
18043 ++ { 0, 0, 0, 0 }
18044 + };
18045 +
18046 + MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
18047 +diff -Nurp linux-2.6.23.15/drivers/input/mouse/lifebook.c linux-2.6.23.15-grsec/drivers/input/mouse/lifebook.c
18048 +--- linux-2.6.23.15/drivers/input/mouse/lifebook.c 2007-10-09 21:31:38.000000000 +0100
18049 ++++ linux-2.6.23.15-grsec/drivers/input/mouse/lifebook.c 2008-02-11 10:37:44.000000000 +0000
18050 +@@ -102,7 +102,7 @@ static struct dmi_system_id lifebook_dmi
18051 + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
18052 + },
18053 + },
18054 +- { }
18055 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
18056 + };
18057 +
18058 + static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
18059 +diff -Nurp linux-2.6.23.15/drivers/input/mouse/psmouse-base.c linux-2.6.23.15-grsec/drivers/input/mouse/psmouse-base.c
18060 +--- linux-2.6.23.15/drivers/input/mouse/psmouse-base.c 2007-10-09 21:31:38.000000000 +0100
18061 ++++ linux-2.6.23.15-grsec/drivers/input/mouse/psmouse-base.c 2008-02-11 10:37:44.000000000 +0000
18062 +@@ -1325,7 +1325,7 @@ static struct serio_device_id psmouse_se
18063 + .id = SERIO_ANY,
18064 + .extra = SERIO_ANY,
18065 + },
18066 +- { 0 }
18067 ++ { 0, 0, 0, 0 }
18068 + };
18069 +
18070 + MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
18071 +diff -Nurp linux-2.6.23.15/drivers/input/mouse/synaptics.c linux-2.6.23.15-grsec/drivers/input/mouse/synaptics.c
18072 +--- linux-2.6.23.15/drivers/input/mouse/synaptics.c 2007-10-09 21:31:38.000000000 +0100
18073 ++++ linux-2.6.23.15-grsec/drivers/input/mouse/synaptics.c 2008-02-11 10:37:44.000000000 +0000
18074 +@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
18075 + break;
18076 + case 2:
18077 + if (SYN_MODEL_PEN(priv->model_id))
18078 +- ; /* Nothing, treat a pen as a single finger */
18079 ++ break; /* Nothing, treat a pen as a single finger */
18080 + break;
18081 + case 4 ... 15:
18082 + if (SYN_CAP_PALMDETECT(priv->capabilities))
18083 +@@ -624,7 +624,7 @@ static struct dmi_system_id toshiba_dmi_
18084 + DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
18085 + },
18086 + },
18087 +- { }
18088 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18089 + };
18090 + #endif
18091 +
18092 +diff -Nurp linux-2.6.23.15/drivers/input/mousedev.c linux-2.6.23.15-grsec/drivers/input/mousedev.c
18093 +--- linux-2.6.23.15/drivers/input/mousedev.c 2008-02-11 10:36:03.000000000 +0000
18094 ++++ linux-2.6.23.15-grsec/drivers/input/mousedev.c 2008-02-11 10:37:44.000000000 +0000
18095 +@@ -1048,7 +1048,7 @@ static struct input_handler mousedev_han
18096 +
18097 + #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
18098 + static struct miscdevice psaux_mouse = {
18099 +- PSMOUSE_MINOR, "psaux", &mousedev_fops
18100 ++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
18101 + };
18102 + static int psaux_registered;
18103 + #endif
18104 +diff -Nurp linux-2.6.23.15/drivers/input/serio/i8042-x86ia64io.h linux-2.6.23.15-grsec/drivers/input/serio/i8042-x86ia64io.h
18105 +--- linux-2.6.23.15/drivers/input/serio/i8042-x86ia64io.h 2007-10-09 21:31:38.000000000 +0100
18106 ++++ linux-2.6.23.15-grsec/drivers/input/serio/i8042-x86ia64io.h 2008-02-11 10:37:44.000000000 +0000
18107 +@@ -110,7 +110,7 @@ static struct dmi_system_id __initdata i
18108 + DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
18109 + },
18110 + },
18111 +- { }
18112 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18113 + };
18114 +
18115 + /*
18116 +@@ -262,7 +262,7 @@ static struct dmi_system_id __initdata i
18117 + DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
18118 + },
18119 + },
18120 +- { }
18121 ++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
18122 + };
18123 +
18124 +
18125 +diff -Nurp linux-2.6.23.15/drivers/input/serio/serio_raw.c linux-2.6.23.15-grsec/drivers/input/serio/serio_raw.c
18126 +--- linux-2.6.23.15/drivers/input/serio/serio_raw.c 2007-10-09 21:31:38.000000000 +0100
18127 ++++ linux-2.6.23.15-grsec/drivers/input/serio/serio_raw.c 2008-02-11 10:37:44.000000000 +0000
18128 +@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
18129 + .id = SERIO_ANY,
18130 + .extra = SERIO_ANY,
18131 + },
18132 +- { 0 }
18133 ++ { 0, 0, 0, 0 }
18134 + };
18135 +
18136 + MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
18137 +diff -Nurp linux-2.6.23.15/drivers/kvm/kvm_main.c linux-2.6.23.15-grsec/drivers/kvm/kvm_main.c
18138 +--- linux-2.6.23.15/drivers/kvm/kvm_main.c 2008-02-11 10:36:03.000000000 +0000
18139 ++++ linux-2.6.23.15-grsec/drivers/kvm/kvm_main.c 2008-02-11 10:37:44.000000000 +0000
18140 +@@ -63,21 +63,21 @@ static struct kvm_stats_debugfs_item {
18141 + int offset;
18142 + struct dentry *dentry;
18143 + } debugfs_entries[] = {
18144 +- { "pf_fixed", STAT_OFFSET(pf_fixed) },
18145 +- { "pf_guest", STAT_OFFSET(pf_guest) },
18146 +- { "tlb_flush", STAT_OFFSET(tlb_flush) },
18147 +- { "invlpg", STAT_OFFSET(invlpg) },
18148 +- { "exits", STAT_OFFSET(exits) },
18149 +- { "io_exits", STAT_OFFSET(io_exits) },
18150 +- { "mmio_exits", STAT_OFFSET(mmio_exits) },
18151 +- { "signal_exits", STAT_OFFSET(signal_exits) },
18152 +- { "irq_window", STAT_OFFSET(irq_window_exits) },
18153 +- { "halt_exits", STAT_OFFSET(halt_exits) },
18154 +- { "request_irq", STAT_OFFSET(request_irq_exits) },
18155 +- { "irq_exits", STAT_OFFSET(irq_exits) },
18156 +- { "light_exits", STAT_OFFSET(light_exits) },
18157 +- { "efer_reload", STAT_OFFSET(efer_reload) },
18158 +- { NULL }
18159 ++ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
18160 ++ { "pf_guest", STAT_OFFSET(pf_guest), NULL },
18161 ++ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
18162 ++ { "invlpg", STAT_OFFSET(invlpg), NULL },
18163 ++ { "exits", STAT_OFFSET(exits), NULL },
18164 ++ { "io_exits", STAT_OFFSET(io_exits), NULL },
18165 ++ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
18166 ++ { "signal_exits", STAT_OFFSET(signal_exits), NULL },
18167 ++ { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
18168 ++ { "halt_exits", STAT_OFFSET(halt_exits), NULL },
18169 ++ { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
18170 ++ { "irq_exits", STAT_OFFSET(irq_exits), NULL },
18171 ++ { "light_exits", STAT_OFFSET(light_exits), NULL },
18172 ++ { "efer_reload", STAT_OFFSET(efer_reload), NULL },
18173 ++ { NULL, 0, NULL }
18174 + };
18175 +
18176 + static struct dentry *debugfs_dir;
18177 +@@ -2255,7 +2255,7 @@ static int kvm_vcpu_ioctl_translate(stru
18178 + static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
18179 + struct kvm_interrupt *irq)
18180 + {
18181 +- if (irq->irq < 0 || irq->irq >= 256)
18182 ++ if (irq->irq >= 256)
18183 + return -EINVAL;
18184 + vcpu_load(vcpu);
18185 +
18186 +@@ -2895,6 +2895,9 @@ static struct miscdevice kvm_dev = {
18187 + KVM_MINOR,
18188 + "kvm",
18189 + &kvm_chardev_ops,
18190 ++ {NULL, NULL},
18191 ++ NULL,
18192 ++ NULL
18193 + };
18194 +
18195 + static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
18196 +diff -Nurp linux-2.6.23.15/drivers/kvm/vmx.c linux-2.6.23.15-grsec/drivers/kvm/vmx.c
18197 +--- linux-2.6.23.15/drivers/kvm/vmx.c 2008-02-11 10:36:03.000000000 +0000
18198 ++++ linux-2.6.23.15-grsec/drivers/kvm/vmx.c 2008-02-11 10:37:44.000000000 +0000
18199 +@@ -2148,7 +2148,7 @@ again:
18200 +
18201 + vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
18202 +
18203 +- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
18204 ++ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
18205 +
18206 + if (unlikely(fail)) {
18207 + kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
18208 +diff -Nurp linux-2.6.23.15/drivers/kvm/x86_emulate.c linux-2.6.23.15-grsec/drivers/kvm/x86_emulate.c
18209 +--- linux-2.6.23.15/drivers/kvm/x86_emulate.c 2008-02-11 10:36:03.000000000 +0000
18210 ++++ linux-2.6.23.15-grsec/drivers/kvm/x86_emulate.c 2008-02-11 10:37:44.000000000 +0000
18211 +@@ -823,7 +823,7 @@ done_prefixes:
18212 + case DstReg:
18213 + dst.type = OP_REG;
18214 + if ((d & ByteOp)
18215 +- && !(twobyte_table && (b == 0xb6 || b == 0xb7))) {
18216 ++ && !(twobyte && (b == 0xb6 || b == 0xb7))) {
18217 + dst.ptr = decode_register(modrm_reg, _regs,
18218 + (rex_prefix == 0));
18219 + dst.val = *(u8 *) dst.ptr;
18220 +diff -Nurp linux-2.6.23.15/drivers/md/bitmap.c linux-2.6.23.15-grsec/drivers/md/bitmap.c
18221 +--- linux-2.6.23.15/drivers/md/bitmap.c 2008-02-11 10:36:03.000000000 +0000
18222 ++++ linux-2.6.23.15-grsec/drivers/md/bitmap.c 2008-02-11 10:37:44.000000000 +0000
18223 +@@ -57,7 +57,7 @@
18224 + # if DEBUG > 0
18225 + # define PRINTK(x...) printk(KERN_DEBUG x)
18226 + # else
18227 +-# define PRINTK(x...)
18228 ++# define PRINTK(x...) do {} while (0)
18229 + # endif
18230 + #endif
18231 +
18232 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2000.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2000.c
18233 +--- linux-2.6.23.15/drivers/mtd/devices/doc2000.c 2007-10-09 21:31:38.000000000 +0100
18234 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2000.c 2008-02-11 10:37:44.000000000 +0000
18235 +@@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd
18236 + len = ((from | 0x1ff) + 1) - from;
18237 +
18238 + /* The ECC will not be calculated correctly if less than 512 is read */
18239 +- if (len != 0x200 && eccbuf)
18240 ++ if (len != 0x200)
18241 + printk(KERN_WARNING
18242 + "ECC needs a full sector read (adr: %lx size %lx)\n",
18243 + (long) from, (long) len);
18244 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2001.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001.c
18245 +--- linux-2.6.23.15/drivers/mtd/devices/doc2001.c 2007-10-09 21:31:38.000000000 +0100
18246 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001.c 2008-02-11 10:37:44.000000000 +0000
18247 +@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
18248 + /* Don't allow read past end of device */
18249 + if (from >= this->totlen)
18250 + return -EINVAL;
18251 ++ if (!len)
18252 ++ return -EINVAL;
18253 +
18254 + /* Don't allow a single read to cross a 512-byte block boundary */
18255 + if (from + len > ((from | 0x1ff) + 1))
18256 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2001plus.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001plus.c
18257 +--- linux-2.6.23.15/drivers/mtd/devices/doc2001plus.c 2007-10-09 21:31:38.000000000 +0100
18258 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001plus.c 2008-02-11 10:37:44.000000000 +0000
18259 +@@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt
18260 + WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
18261 +
18262 + /* On interleaved devices the flags for 2nd half 512 are before data */
18263 +- if (eccbuf && before)
18264 ++ if (before)
18265 + fto -= 2;
18266 +
18267 + /* issue the Serial Data In command to initial the Page Program process */
18268 +diff -Nurp linux-2.6.23.15/drivers/mtd/devices/slram.c linux-2.6.23.15-grsec/drivers/mtd/devices/slram.c
18269 +--- linux-2.6.23.15/drivers/mtd/devices/slram.c 2007-10-09 21:31:38.000000000 +0100
18270 ++++ linux-2.6.23.15-grsec/drivers/mtd/devices/slram.c 2008-02-11 10:37:44.000000000 +0000
18271 +@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname,
18272 + }
18273 + T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
18274 + devname, devstart, devlength);
18275 +- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
18276 ++ if (devlength % SLRAM_BLK_SZ != 0) {
18277 + E("slram: Illegal start / length parameter.\n");
18278 + return(-EINVAL);
18279 + }
18280 +diff -Nurp linux-2.6.23.15/drivers/mtd/ubi/build.c linux-2.6.23.15-grsec/drivers/mtd/ubi/build.c
18281 +--- linux-2.6.23.15/drivers/mtd/ubi/build.c 2007-10-09 21:31:38.000000000 +0100
18282 ++++ linux-2.6.23.15-grsec/drivers/mtd/ubi/build.c 2008-02-11 10:37:44.000000000 +0000
18283 +@@ -727,7 +727,7 @@ static int __init bytes_str_to_int(const
18284 + unsigned long result;
18285 +
18286 + result = simple_strtoul(str, &endp, 0);
18287 +- if (str == endp || result < 0) {
18288 ++ if (str == endp) {
18289 + printk("UBI error: incorrect bytes count: \"%s\"\n", str);
18290 + return -EINVAL;
18291 + }
18292 +diff -Nurp linux-2.6.23.15/drivers/net/eepro100.c linux-2.6.23.15-grsec/drivers/net/eepro100.c
18293 +--- linux-2.6.23.15/drivers/net/eepro100.c 2007-10-09 21:31:38.000000000 +0100
18294 ++++ linux-2.6.23.15-grsec/drivers/net/eepro100.c 2008-02-11 10:37:44.000000000 +0000
18295 +@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
18296 + # define rx_align(skb) skb_reserve((skb), 2)
18297 + # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
18298 + #else
18299 +-# define rx_align(skb)
18300 ++# define rx_align(skb) do {} while (0)
18301 + # define RxFD_ALIGNMENT
18302 + #endif
18303 +
18304 +@@ -2344,33 +2344,33 @@ static void __devexit eepro100_remove_on
18305 + }
18306 +
18307 + static struct pci_device_id eepro100_pci_tbl[] = {
18308 +- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
18309 +- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
18310 +- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
18311 +- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
18312 +- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
18313 +- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
18314 +- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
18315 +- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
18316 +- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
18317 +- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
18318 +- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
18319 +- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
18320 +- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
18321 +- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
18322 +- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
18323 +- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
18324 +- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
18325 +- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
18326 +- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
18327 +- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
18328 +- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
18329 +- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
18330 +- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
18331 +- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
18332 +- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
18333 +- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
18334 +- { 0,}
18335 ++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18336 ++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18337 ++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18338 ++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18339 ++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18340 ++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18341 ++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18342 ++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18343 ++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18344 ++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18345 ++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18346 ++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18347 ++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18348 ++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18349 ++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18350 ++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18351 ++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18352 ++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18353 ++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18354 ++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18355 ++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18356 ++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18357 ++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18358 ++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18359 ++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18360 ++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
18361 ++ { 0, 0, 0, 0, 0, 0, 0 }
18362 + };
18363 + MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
18364 +
18365 +diff -Nurp linux-2.6.23.15/drivers/net/irda/vlsi_ir.c linux-2.6.23.15-grsec/drivers/net/irda/vlsi_ir.c
18366 +--- linux-2.6.23.15/drivers/net/irda/vlsi_ir.c 2007-10-09 21:31:38.000000000 +0100
18367 ++++ linux-2.6.23.15-grsec/drivers/net/irda/vlsi_ir.c 2008-02-11 10:37:44.000000000 +0000
18368 +@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
18369 + /* no race - tx-ring already empty */
18370 + vlsi_set_baud(idev, iobase);
18371 + netif_wake_queue(ndev);
18372 +- }
18373 +- else
18374 +- ;
18375 ++ } else {
18376 + /* keep the speed change pending like it would
18377 + * for any len>0 packet. tx completion interrupt
18378 + * will apply it when the tx ring becomes empty.
18379 + */
18380 ++ }
18381 + spin_unlock_irqrestore(&idev->lock, flags);
18382 + dev_kfree_skb_any(skb);
18383 + return 0;
18384 +diff -Nurp linux-2.6.23.15/drivers/net/pcnet32.c linux-2.6.23.15-grsec/drivers/net/pcnet32.c
18385 +--- linux-2.6.23.15/drivers/net/pcnet32.c 2007-10-09 21:31:38.000000000 +0100
18386 ++++ linux-2.6.23.15-grsec/drivers/net/pcnet32.c 2008-02-11 10:37:44.000000000 +0000
18387 +@@ -82,7 +82,7 @@ static int cards_found;
18388 + /*
18389 + * VLB I/O addresses
18390 + */
18391 +-static unsigned int pcnet32_portlist[] __initdata =
18392 ++static unsigned int pcnet32_portlist[] __devinitdata =
18393 + { 0x300, 0x320, 0x340, 0x360, 0 };
18394 +
18395 + static int pcnet32_debug = 0;
18396 +diff -Nurp linux-2.6.23.15/drivers/net/tg3.h linux-2.6.23.15-grsec/drivers/net/tg3.h
18397 +--- linux-2.6.23.15/drivers/net/tg3.h 2007-10-09 21:31:38.000000000 +0100
18398 ++++ linux-2.6.23.15-grsec/drivers/net/tg3.h 2008-02-11 10:37:44.000000000 +0000
18399 +@@ -127,6 +127,7 @@
18400 + #define CHIPREV_ID_5750_A0 0x4000
18401 + #define CHIPREV_ID_5750_A1 0x4001
18402 + #define CHIPREV_ID_5750_A3 0x4003
18403 ++#define CHIPREV_ID_5750_C1 0x4201
18404 + #define CHIPREV_ID_5750_C2 0x4202
18405 + #define CHIPREV_ID_5752_A0_HW 0x5000
18406 + #define CHIPREV_ID_5752_A0 0x6000
18407 +diff -Nurp linux-2.6.23.15/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.23.15-grsec/drivers/pci/hotplug/cpqphp_nvram.c
18408 +--- linux-2.6.23.15/drivers/pci/hotplug/cpqphp_nvram.c 2007-10-09 21:31:38.000000000 +0100
18409 ++++ linux-2.6.23.15-grsec/drivers/pci/hotplug/cpqphp_nvram.c 2008-02-11 10:37:44.000000000 +0000
18410 +@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
18411 +
18412 + void compaq_nvram_init (void __iomem *rom_start)
18413 + {
18414 ++
18415 ++#ifndef CONFIG_PAX_KERNEXEC
18416 + if (rom_start) {
18417 + compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
18418 + }
18419 ++#endif
18420 ++
18421 + dbg("int15 entry = %p\n", compaq_int15_entry_point);
18422 +
18423 + /* initialize our int15 lock */
18424 +diff -Nurp linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv.c linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv.c
18425 +--- linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv.c 2007-10-09 21:31:38.000000000 +0100
18426 ++++ linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv.c 2008-02-11 10:37:44.000000000 +0000
18427 +@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
18428 + .port_type = PCIE_RC_PORT,
18429 + .service_type = PCIE_PORT_SERVICE_AER,
18430 + },
18431 +- { /* end: all zeroes */ }
18432 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18433 + };
18434 +
18435 + static struct pci_error_handlers aer_error_handlers = {
18436 +diff -Nurp linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv_core.c
18437 +--- linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv_core.c 2007-10-09 21:31:38.000000000 +0100
18438 ++++ linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv_core.c 2008-02-11 10:37:44.000000000 +0000
18439 +@@ -660,7 +660,7 @@ static void aer_isr_one_error(struct pci
18440 + struct aer_err_source *e_src)
18441 + {
18442 + struct device *s_device;
18443 +- struct aer_err_info e_info = {0, 0, 0,};
18444 ++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
18445 + int i;
18446 + u16 id;
18447 +
18448 +diff -Nurp linux-2.6.23.15/drivers/pci/pcie/portdrv_pci.c linux-2.6.23.15-grsec/drivers/pci/pcie/portdrv_pci.c
18449 +--- linux-2.6.23.15/drivers/pci/pcie/portdrv_pci.c 2007-10-09 21:31:38.000000000 +0100
18450 ++++ linux-2.6.23.15-grsec/drivers/pci/pcie/portdrv_pci.c 2008-02-11 10:37:44.000000000 +0000
18451 +@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
18452 + static const struct pci_device_id port_pci_ids[] = { {
18453 + /* handle any PCI-Express port */
18454 + PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
18455 +- }, { /* end: all zeroes */ }
18456 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
18457 + };
18458 + MODULE_DEVICE_TABLE(pci, port_pci_ids);
18459 +
18460 +diff -Nurp linux-2.6.23.15/drivers/pci/proc.c linux-2.6.23.15-grsec/drivers/pci/proc.c
18461 +--- linux-2.6.23.15/drivers/pci/proc.c 2007-10-09 21:31:38.000000000 +0100
18462 ++++ linux-2.6.23.15-grsec/drivers/pci/proc.c 2008-02-11 10:37:44.000000000 +0000
18463 +@@ -466,7 +466,15 @@ static int __init pci_proc_init(void)
18464 + {
18465 + struct proc_dir_entry *entry;
18466 + struct pci_dev *dev = NULL;
18467 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
18468 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
18469 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
18470 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
18471 ++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
18472 ++#endif
18473 ++#else
18474 + proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
18475 ++#endif
18476 + entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
18477 + if (entry)
18478 + entry->proc_fops = &proc_bus_pci_dev_operations;
18479 +diff -Nurp linux-2.6.23.15/drivers/pcmcia/ti113x.h linux-2.6.23.15-grsec/drivers/pcmcia/ti113x.h
18480 +--- linux-2.6.23.15/drivers/pcmcia/ti113x.h 2007-10-09 21:31:38.000000000 +0100
18481 ++++ linux-2.6.23.15-grsec/drivers/pcmcia/ti113x.h 2008-02-11 10:37:44.000000000 +0000
18482 +@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
18483 + DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
18484 + ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
18485 +
18486 +- {}
18487 ++ { 0, 0, 0, 0, 0, 0, 0 }
18488 + };
18489 +
18490 + static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
18491 +diff -Nurp linux-2.6.23.15/drivers/pcmcia/yenta_socket.c linux-2.6.23.15-grsec/drivers/pcmcia/yenta_socket.c
18492 +--- linux-2.6.23.15/drivers/pcmcia/yenta_socket.c 2007-10-09 21:31:38.000000000 +0100
18493 ++++ linux-2.6.23.15-grsec/drivers/pcmcia/yenta_socket.c 2008-02-11 10:37:44.000000000 +0000
18494 +@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
18495 +
18496 + /* match any cardbus bridge */
18497 + CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
18498 +- { /* all zeroes */ }
18499 ++ { 0, 0, 0, 0, 0, 0, 0 }
18500 + };
18501 + MODULE_DEVICE_TABLE(pci, yenta_table);
18502 +
18503 +diff -Nurp linux-2.6.23.15/drivers/pnp/pnpbios/bioscalls.c linux-2.6.23.15-grsec/drivers/pnp/pnpbios/bioscalls.c
18504 +--- linux-2.6.23.15/drivers/pnp/pnpbios/bioscalls.c 2007-10-09 21:31:38.000000000 +0100
18505 ++++ linux-2.6.23.15-grsec/drivers/pnp/pnpbios/bioscalls.c 2008-02-11 10:37:44.000000000 +0000
18506 +@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
18507 + set_limit(gdt[(selname) >> 3], size); \
18508 + } while(0)
18509 +
18510 +-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
18511 ++static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 };
18512 +
18513 + /*
18514 + * At some point we want to use this stack frame pointer to unwind
18515 +@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func
18516 + struct desc_struct save_desc_40;
18517 + int cpu;
18518 +
18519 ++#ifdef CONFIG_PAX_KERNEXEC
18520 ++ unsigned long cr0;
18521 ++#endif
18522 ++
18523 + /*
18524 + * PnP BIOSes are generally not terribly re-entrant.
18525 + * Also, don't rely on them to save everything correctly.
18526 +@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func
18527 +
18528 + cpu = get_cpu();
18529 + save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
18530 ++
18531 ++#ifdef CONFIG_PAX_KERNEXEC
18532 ++ pax_open_kernel(cr0);
18533 ++#endif
18534 ++
18535 + get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
18536 +
18537 ++#ifdef CONFIG_PAX_KERNEXEC
18538 ++ pax_close_kernel(cr0);
18539 ++#endif
18540 ++
18541 + /* On some boxes IRQ's during PnP BIOS calls are deadly. */
18542 + spin_lock_irqsave(&pnp_bios_lock, flags);
18543 +
18544 +@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func
18545 + :"memory");
18546 + spin_unlock_irqrestore(&pnp_bios_lock, flags);
18547 +
18548 ++#ifdef CONFIG_PAX_KERNEXEC
18549 ++ pax_open_kernel(cr0);
18550 ++#endif
18551 ++
18552 + get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
18553 ++
18554 ++#ifdef CONFIG_PAX_KERNEXEC
18555 ++ pax_close_kernel(cr0);
18556 ++#endif
18557 ++
18558 + put_cpu();
18559 +
18560 + /* If we get here and this is set then the PnP BIOS faulted on us. */
18561 +@@ -469,16 +491,25 @@ int pnp_bios_read_escd(char *data, u32 n
18562 + return status;
18563 + }
18564 +
18565 +-void pnpbios_calls_init(union pnp_bios_install_struct *header)
18566 ++void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
18567 + {
18568 + int i;
18569 +
18570 ++#ifdef CONFIG_PAX_KERNEXEC
18571 ++ unsigned long cr0;
18572 ++#endif
18573 ++
18574 + spin_lock_init(&pnp_bios_lock);
18575 + pnp_bios_callpoint.offset = header->fields.pm16offset;
18576 + pnp_bios_callpoint.segment = PNP_CS16;
18577 +
18578 + set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
18579 + _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
18580 ++
18581 ++#ifdef CONFIG_PAX_KERNEXEC
18582 ++ pax_open_kernel(cr0);
18583 ++#endif
18584 ++
18585 + for (i = 0; i < NR_CPUS; i++) {
18586 + struct desc_struct *gdt = get_cpu_gdt_table(i);
18587 + if (!gdt)
18588 +@@ -489,4 +520,9 @@ void pnpbios_calls_init(union pnp_bios_i
18589 + set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
18590 + __va(header->fields.pm16dseg));
18591 + }
18592 ++
18593 ++#ifdef CONFIG_PAX_KERNEXEC
18594 ++ pax_close_kernel(cr0);
18595 ++#endif
18596 ++
18597 + }
18598 +diff -Nurp linux-2.6.23.15/drivers/pnp/quirks.c linux-2.6.23.15-grsec/drivers/pnp/quirks.c
18599 +--- linux-2.6.23.15/drivers/pnp/quirks.c 2007-10-09 21:31:38.000000000 +0100
18600 ++++ linux-2.6.23.15-grsec/drivers/pnp/quirks.c 2008-02-11 10:37:44.000000000 +0000
18601 +@@ -127,7 +127,7 @@ static struct pnp_fixup pnp_fixups[] = {
18602 + {"CTL0043", quirk_sb16audio_resources},
18603 + {"CTL0044", quirk_sb16audio_resources},
18604 + {"CTL0045", quirk_sb16audio_resources},
18605 +- {""}
18606 ++ {"", NULL}
18607 + };
18608 +
18609 + void pnp_fixup_device(struct pnp_dev *dev)
18610 +diff -Nurp linux-2.6.23.15/drivers/pnp/resource.c linux-2.6.23.15-grsec/drivers/pnp/resource.c
18611 +--- linux-2.6.23.15/drivers/pnp/resource.c 2007-10-09 21:31:38.000000000 +0100
18612 ++++ linux-2.6.23.15-grsec/drivers/pnp/resource.c 2008-02-11 10:37:44.000000000 +0000
18613 +@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i
18614 + return 1;
18615 +
18616 + /* check if the resource is valid */
18617 +- if (*irq < 0 || *irq > 15)
18618 ++ if (*irq > 15)
18619 + return 0;
18620 +
18621 + /* check if the resource is reserved */
18622 +@@ -412,7 +412,7 @@ int pnp_check_dma(struct pnp_dev *dev, i
18623 + return 1;
18624 +
18625 + /* check if the resource is valid */
18626 +- if (*dma < 0 || *dma == 4 || *dma > 7)
18627 ++ if (*dma == 4 || *dma > 7)
18628 + return 0;
18629 +
18630 + /* check if the resource is reserved */
18631 +diff -Nurp linux-2.6.23.15/drivers/scsi/scsi_lib.c linux-2.6.23.15-grsec/drivers/scsi/scsi_lib.c
18632 +--- linux-2.6.23.15/drivers/scsi/scsi_lib.c 2007-10-09 21:31:38.000000000 +0100
18633 ++++ linux-2.6.23.15-grsec/drivers/scsi/scsi_lib.c 2008-02-11 10:37:44.000000000 +0000
18634 +@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
18635 + #error SCSI_MAX_PHYS_SEGMENTS is too small
18636 + #endif
18637 +
18638 +-#define SP(x) { x, "sgpool-" #x }
18639 ++#define SP(x) { x, "sgpool-" #x, NULL, NULL }
18640 + static struct scsi_host_sg_pool scsi_sg_pools[] = {
18641 + SP(8),
18642 + SP(16),
18643 +diff -Nurp linux-2.6.23.15/drivers/scsi/scsi_logging.h linux-2.6.23.15-grsec/drivers/scsi/scsi_logging.h
18644 +--- linux-2.6.23.15/drivers/scsi/scsi_logging.h 2007-10-09 21:31:38.000000000 +0100
18645 ++++ linux-2.6.23.15-grsec/drivers/scsi/scsi_logging.h 2008-02-11 10:37:44.000000000 +0000
18646 +@@ -51,7 +51,7 @@ do { \
18647 + } while (0); \
18648 + } while (0)
18649 + #else
18650 +-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
18651 ++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
18652 + #endif /* CONFIG_SCSI_LOGGING */
18653 +
18654 + /*
18655 +diff -Nurp linux-2.6.23.15/drivers/serial/8250_pci.c linux-2.6.23.15-grsec/drivers/serial/8250_pci.c
18656 +--- linux-2.6.23.15/drivers/serial/8250_pci.c 2007-10-09 21:31:38.000000000 +0100
18657 ++++ linux-2.6.23.15-grsec/drivers/serial/8250_pci.c 2008-02-11 10:37:44.000000000 +0000
18658 +@@ -2589,7 +2589,7 @@ static struct pci_device_id serial_pci_t
18659 + PCI_ANY_ID, PCI_ANY_ID,
18660 + PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
18661 + 0xffff00, pbn_default },
18662 +- { 0, }
18663 ++ { 0, 0, 0, 0, 0, 0, 0 }
18664 + };
18665 +
18666 + static struct pci_driver serial_pci_driver = {
18667 +diff -Nurp linux-2.6.23.15/drivers/usb/class/cdc-acm.c linux-2.6.23.15-grsec/drivers/usb/class/cdc-acm.c
18668 +--- linux-2.6.23.15/drivers/usb/class/cdc-acm.c 2007-10-09 21:31:38.000000000 +0100
18669 ++++ linux-2.6.23.15-grsec/drivers/usb/class/cdc-acm.c 2008-02-11 10:37:44.000000000 +0000
18670 +@@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] =
18671 + USB_CDC_ACM_PROTO_AT_CDMA) },
18672 +
18673 + /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
18674 +- { }
18675 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18676 + };
18677 +
18678 + MODULE_DEVICE_TABLE (usb, acm_ids);
18679 +diff -Nurp linux-2.6.23.15/drivers/usb/class/usblp.c linux-2.6.23.15-grsec/drivers/usb/class/usblp.c
18680 +--- linux-2.6.23.15/drivers/usb/class/usblp.c 2007-10-09 21:31:38.000000000 +0100
18681 ++++ linux-2.6.23.15-grsec/drivers/usb/class/usblp.c 2008-02-11 10:37:44.000000000 +0000
18682 +@@ -225,7 +225,7 @@ static const struct quirk_printer_struct
18683 + { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
18684 + { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */
18685 + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
18686 +- { 0, 0 }
18687 ++ { 0, 0, 0 }
18688 + };
18689 +
18690 + static int usblp_wwait(struct usblp *usblp, int nonblock);
18691 +@@ -1376,7 +1376,7 @@ static struct usb_device_id usblp_ids []
18692 + { USB_INTERFACE_INFO(7, 1, 2) },
18693 + { USB_INTERFACE_INFO(7, 1, 3) },
18694 + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
18695 +- { } /* Terminating entry */
18696 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
18697 + };
18698 +
18699 + MODULE_DEVICE_TABLE (usb, usblp_ids);
18700 +diff -Nurp linux-2.6.23.15/drivers/usb/core/hub.c linux-2.6.23.15-grsec/drivers/usb/core/hub.c
18701 +--- linux-2.6.23.15/drivers/usb/core/hub.c 2008-02-11 10:36:03.000000000 +0000
18702 ++++ linux-2.6.23.15-grsec/drivers/usb/core/hub.c 2008-02-11 10:37:44.000000000 +0000
18703 +@@ -2762,7 +2762,7 @@ static struct usb_device_id hub_id_table
18704 + .bDeviceClass = USB_CLASS_HUB},
18705 + { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
18706 + .bInterfaceClass = USB_CLASS_HUB},
18707 +- { } /* Terminating entry */
18708 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
18709 + };
18710 +
18711 + MODULE_DEVICE_TABLE (usb, hub_id_table);
18712 +diff -Nurp linux-2.6.23.15/drivers/usb/host/ehci-pci.c linux-2.6.23.15-grsec/drivers/usb/host/ehci-pci.c
18713 +--- linux-2.6.23.15/drivers/usb/host/ehci-pci.c 2007-10-09 21:31:38.000000000 +0100
18714 ++++ linux-2.6.23.15-grsec/drivers/usb/host/ehci-pci.c 2008-02-11 10:37:44.000000000 +0000
18715 +@@ -377,7 +377,7 @@ static const struct pci_device_id pci_id
18716 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
18717 + .driver_data = (unsigned long) &ehci_pci_hc_driver,
18718 + },
18719 +- { /* end: all zeroes */ }
18720 ++ { 0, 0, 0, 0, 0, 0, 0 }
18721 + };
18722 + MODULE_DEVICE_TABLE(pci, pci_ids);
18723 +
18724 +diff -Nurp linux-2.6.23.15/drivers/usb/host/uhci-hcd.c linux-2.6.23.15-grsec/drivers/usb/host/uhci-hcd.c
18725 +--- linux-2.6.23.15/drivers/usb/host/uhci-hcd.c 2007-10-09 21:31:38.000000000 +0100
18726 ++++ linux-2.6.23.15-grsec/drivers/usb/host/uhci-hcd.c 2008-02-11 10:37:44.000000000 +0000
18727 +@@ -894,7 +894,7 @@ static const struct pci_device_id uhci_p
18728 + /* handle any USB UHCI controller */
18729 + PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
18730 + .driver_data = (unsigned long) &uhci_driver,
18731 +- }, { /* end: all zeroes */ }
18732 ++ }, { 0, 0, 0, 0, 0, 0, 0 }
18733 + };
18734 +
18735 + MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
18736 +diff -Nurp linux-2.6.23.15/drivers/usb/storage/debug.h linux-2.6.23.15-grsec/drivers/usb/storage/debug.h
18737 +--- linux-2.6.23.15/drivers/usb/storage/debug.h 2007-10-09 21:31:38.000000000 +0100
18738 ++++ linux-2.6.23.15-grsec/drivers/usb/storage/debug.h 2008-02-11 10:37:44.000000000 +0000
18739 +@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
18740 + #define US_DEBUGPX(x...) printk( x )
18741 + #define US_DEBUG(x) x
18742 + #else
18743 +-#define US_DEBUGP(x...)
18744 +-#define US_DEBUGPX(x...)
18745 +-#define US_DEBUG(x)
18746 ++#define US_DEBUGP(x...) do {} while (0)
18747 ++#define US_DEBUGPX(x...) do {} while (0)
18748 ++#define US_DEBUG(x) do {} while (0)
18749 + #endif
18750 +
18751 + #endif
18752 +diff -Nurp linux-2.6.23.15/drivers/usb/storage/usb.c linux-2.6.23.15-grsec/drivers/usb/storage/usb.c
18753 +--- linux-2.6.23.15/drivers/usb/storage/usb.c 2007-10-09 21:31:38.000000000 +0100
18754 ++++ linux-2.6.23.15-grsec/drivers/usb/storage/usb.c 2008-02-11 10:37:44.000000000 +0000
18755 +@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_
18756 + #undef UNUSUAL_DEV
18757 + #undef USUAL_DEV
18758 + /* Terminating entry */
18759 +- { }
18760 ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
18761 + };
18762 +
18763 + MODULE_DEVICE_TABLE (usb, storage_usb_ids);
18764 +@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_
18765 + # undef USUAL_DEV
18766 +
18767 + /* Terminating entry */
18768 +- { NULL }
18769 ++ { NULL, NULL, 0, 0, NULL }
18770 + };
18771 +
18772 +
18773 +diff -Nurp linux-2.6.23.15/drivers/video/fbcmap.c linux-2.6.23.15-grsec/drivers/video/fbcmap.c
18774 +--- linux-2.6.23.15/drivers/video/fbcmap.c 2007-10-09 21:31:38.000000000 +0100
18775 ++++ linux-2.6.23.15-grsec/drivers/video/fbcmap.c 2008-02-11 10:37:44.000000000 +0000
18776 +@@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user
18777 + int rc, size = cmap->len * sizeof(u16);
18778 + struct fb_cmap umap;
18779 +
18780 +- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
18781 +- !info->fbops->fb_setcmap))
18782 ++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
18783 + return -EINVAL;
18784 +
18785 + memset(&umap, 0, sizeof(struct fb_cmap));
18786 +diff -Nurp linux-2.6.23.15/drivers/video/fbmem.c linux-2.6.23.15-grsec/drivers/video/fbmem.c
18787 +--- linux-2.6.23.15/drivers/video/fbmem.c 2007-10-09 21:31:38.000000000 +0100
18788 ++++ linux-2.6.23.15-grsec/drivers/video/fbmem.c 2008-02-11 10:37:44.000000000 +0000
18789 +@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in
18790 + image->dx += image->width + 8;
18791 + }
18792 + } else if (rotate == FB_ROTATE_UD) {
18793 +- for (x = 0; x < num && image->dx >= 0; x++) {
18794 ++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
18795 + info->fbops->fb_imageblit(info, image);
18796 + image->dx -= image->width + 8;
18797 + }
18798 +@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in
18799 + image->dy += image->height + 8;
18800 + }
18801 + } else if (rotate == FB_ROTATE_CCW) {
18802 +- for (x = 0; x < num && image->dy >= 0; x++) {
18803 ++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
18804 + info->fbops->fb_imageblit(info, image);
18805 + image->dy -= image->height + 8;
18806 + }
18807 +@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil
18808 + case FBIOPUT_CON2FBMAP:
18809 + if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
18810 + return - EFAULT;
18811 +- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
18812 ++ if (con2fb.console > MAX_NR_CONSOLES)
18813 + return -EINVAL;
18814 +- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
18815 ++ if (con2fb.framebuffer >= FB_MAX)
18816 + return -EINVAL;
18817 + #ifdef CONFIG_KMOD
18818 + if (!registered_fb[con2fb.framebuffer])
18819 +diff -Nurp linux-2.6.23.15/drivers/video/fbmon.c linux-2.6.23.15-grsec/drivers/video/fbmon.c
18820 +--- linux-2.6.23.15/drivers/video/fbmon.c 2007-10-09 21:31:38.000000000 +0100
18821 ++++ linux-2.6.23.15-grsec/drivers/video/fbmon.c 2008-02-11 10:37:44.000000000 +0000
18822 +@@ -45,7 +45,7 @@
18823 + #ifdef DEBUG
18824 + #define DPRINTK(fmt, args...) printk(fmt,## args)
18825 + #else
18826 +-#define DPRINTK(fmt, args...)
18827 ++#define DPRINTK(fmt, args...) do {} while (0)
18828 + #endif
18829 +
18830 + #define FBMON_FIX_HEADER 1
18831 +diff -Nurp linux-2.6.23.15/drivers/video/i810/i810_accel.c linux-2.6.23.15-grsec/drivers/video/i810/i810_accel.c
18832 +--- linux-2.6.23.15/drivers/video/i810/i810_accel.c 2007-10-09 21:31:38.000000000 +0100
18833 ++++ linux-2.6.23.15-grsec/drivers/video/i810/i810_accel.c 2008-02-11 10:37:44.000000000 +0000
18834 +@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
18835 + }
18836 + }
18837 + printk("ringbuffer lockup!!!\n");
18838 ++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
18839 + i810_report_error(mmio);
18840 + par->dev_flags |= LOCKUP;
18841 + info->pixmap.scan_align = 1;
18842 +diff -Nurp linux-2.6.23.15/drivers/video/i810/i810_main.c linux-2.6.23.15-grsec/drivers/video/i810/i810_main.c
18843 +--- linux-2.6.23.15/drivers/video/i810/i810_main.c 2007-10-09 21:31:38.000000000 +0100
18844 ++++ linux-2.6.23.15-grsec/drivers/video/i810/i810_main.c 2008-02-11 10:37:44.000000000 +0000
18845 +@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
18846 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
18847 + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
18848 + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
18849 +- { 0 },
18850 ++ { 0, 0, 0, 0, 0, 0, 0 },
18851 + };
18852 +
18853 + static struct pci_driver i810fb_driver = {
18854 +@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
18855 + int size = ((cursor->image.width + 7) >> 3) *
18856 + cursor->image.height;
18857 + int i;
18858 +- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
18859 ++ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
18860 +
18861 + if (data == NULL)
18862 + return -ENOMEM;
18863 +diff -Nurp linux-2.6.23.15/drivers/video/modedb.c linux-2.6.23.15-grsec/drivers/video/modedb.c
18864 +--- linux-2.6.23.15/drivers/video/modedb.c 2007-10-09 21:31:38.000000000 +0100
18865 ++++ linux-2.6.23.15-grsec/drivers/video/modedb.c 2008-02-11 10:37:44.000000000 +0000
18866 +@@ -37,228 +37,228 @@ static const struct fb_videomode modedb[
18867 + {
18868 + /* 640x400 @ 70 Hz, 31.5 kHz hsync */
18869 + NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
18870 +- 0, FB_VMODE_NONINTERLACED
18871 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18872 + }, {
18873 + /* 640x480 @ 60 Hz, 31.5 kHz hsync */
18874 + NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
18875 +- 0, FB_VMODE_NONINTERLACED
18876 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18877 + }, {
18878 + /* 800x600 @ 56 Hz, 35.15 kHz hsync */
18879 + NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
18880 +- 0, FB_VMODE_NONINTERLACED
18881 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18882 + }, {
18883 + /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
18884 + NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
18885 +- 0, FB_VMODE_INTERLACED
18886 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18887 + }, {
18888 + /* 640x400 @ 85 Hz, 37.86 kHz hsync */
18889 + NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
18890 +- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18891 ++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18892 + }, {
18893 + /* 640x480 @ 72 Hz, 36.5 kHz hsync */
18894 + NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
18895 +- 0, FB_VMODE_NONINTERLACED
18896 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18897 + }, {
18898 + /* 640x480 @ 75 Hz, 37.50 kHz hsync */
18899 + NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
18900 +- 0, FB_VMODE_NONINTERLACED
18901 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18902 + }, {
18903 + /* 800x600 @ 60 Hz, 37.8 kHz hsync */
18904 + NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
18905 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18906 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18907 + }, {
18908 + /* 640x480 @ 85 Hz, 43.27 kHz hsync */
18909 + NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
18910 +- 0, FB_VMODE_NONINTERLACED
18911 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18912 + }, {
18913 + /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
18914 + NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
18915 +- 0, FB_VMODE_INTERLACED
18916 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18917 + }, {
18918 + /* 800x600 @ 72 Hz, 48.0 kHz hsync */
18919 + NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
18920 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18921 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18922 + }, {
18923 + /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
18924 + NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
18925 +- 0, FB_VMODE_NONINTERLACED
18926 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18927 + }, {
18928 + /* 640x480 @ 100 Hz, 53.01 kHz hsync */
18929 + NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
18930 +- 0, FB_VMODE_NONINTERLACED
18931 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18932 + }, {
18933 + /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
18934 + NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
18935 +- 0, FB_VMODE_NONINTERLACED
18936 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18937 + }, {
18938 + /* 800x600 @ 85 Hz, 55.84 kHz hsync */
18939 + NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
18940 +- 0, FB_VMODE_NONINTERLACED
18941 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18942 + }, {
18943 + /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
18944 + NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
18945 +- 0, FB_VMODE_NONINTERLACED
18946 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18947 + }, {
18948 + /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
18949 + NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
18950 +- 0, FB_VMODE_INTERLACED
18951 ++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
18952 + }, {
18953 + /* 800x600 @ 100 Hz, 64.02 kHz hsync */
18954 + NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
18955 +- 0, FB_VMODE_NONINTERLACED
18956 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18957 + }, {
18958 + /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
18959 + NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
18960 +- 0, FB_VMODE_NONINTERLACED
18961 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18962 + }, {
18963 + /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
18964 + NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
18965 +- 0, FB_VMODE_NONINTERLACED
18966 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18967 + }, {
18968 + /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
18969 + NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
18970 +- 0, FB_VMODE_NONINTERLACED
18971 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18972 + }, {
18973 + /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
18974 + NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
18975 +- 0, FB_VMODE_NONINTERLACED
18976 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18977 + }, {
18978 + /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
18979 + NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
18980 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18981 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18982 + }, {
18983 + /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
18984 + NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
18985 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
18986 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18987 + }, {
18988 + /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
18989 + NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
18990 +- 0, FB_VMODE_NONINTERLACED
18991 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18992 + }, {
18993 + /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
18994 + NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
18995 +- 0, FB_VMODE_NONINTERLACED
18996 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
18997 + }, {
18998 + /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
18999 + NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
19000 +- 0, FB_VMODE_NONINTERLACED
19001 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19002 + }, {
19003 + /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
19004 + NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
19005 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19006 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19007 + }, {
19008 + /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
19009 + NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
19010 +- 0, FB_VMODE_NONINTERLACED
19011 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19012 + }, {
19013 + /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
19014 + NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
19015 +- 0, FB_VMODE_NONINTERLACED
19016 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19017 + }, {
19018 + /* 1024x768 @ 100Hz, 80.21 kHz hsync */
19019 + NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
19020 +- 0, FB_VMODE_NONINTERLACED
19021 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19022 + }, {
19023 + /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
19024 + NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
19025 +- 0, FB_VMODE_NONINTERLACED
19026 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19027 + }, {
19028 + /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
19029 + NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
19030 +- 0, FB_VMODE_NONINTERLACED
19031 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19032 + }, {
19033 + /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
19034 + NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
19035 +- 0, FB_VMODE_NONINTERLACED
19036 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19037 + }, {
19038 + /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
19039 + NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
19040 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19041 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19042 + }, {
19043 + /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
19044 + NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
19045 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19046 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19047 + }, {
19048 + /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
19049 + NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
19050 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19051 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19052 + }, {
19053 + /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
19054 + NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
19055 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19056 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19057 + }, {
19058 + /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
19059 + NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
19060 +- 0, FB_VMODE_NONINTERLACED
19061 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19062 + }, {
19063 + /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
19064 + NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
19065 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19066 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19067 + }, {
19068 + /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
19069 + NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
19070 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19071 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19072 + }, {
19073 + /* 512x384 @ 78 Hz, 31.50 kHz hsync */
19074 + NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
19075 +- 0, FB_VMODE_NONINTERLACED
19076 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19077 + }, {
19078 + /* 512x384 @ 85 Hz, 34.38 kHz hsync */
19079 + NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
19080 +- 0, FB_VMODE_NONINTERLACED
19081 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19082 + }, {
19083 + /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
19084 + NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
19085 +- 0, FB_VMODE_DOUBLE
19086 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19087 + }, {
19088 + /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
19089 + NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
19090 +- 0, FB_VMODE_DOUBLE
19091 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19092 + }, {
19093 + /* 320x240 @ 72 Hz, 36.5 kHz hsync */
19094 + NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
19095 +- 0, FB_VMODE_DOUBLE
19096 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19097 + }, {
19098 + /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
19099 + NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
19100 +- 0, FB_VMODE_DOUBLE
19101 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19102 + }, {
19103 + /* 400x300 @ 60 Hz, 37.8 kHz hsync */
19104 + NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
19105 +- 0, FB_VMODE_DOUBLE
19106 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19107 + }, {
19108 + /* 400x300 @ 72 Hz, 48.0 kHz hsync */
19109 + NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
19110 +- 0, FB_VMODE_DOUBLE
19111 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19112 + }, {
19113 + /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
19114 + NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
19115 +- 0, FB_VMODE_DOUBLE
19116 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19117 + }, {
19118 + /* 480x300 @ 60 Hz, 37.8 kHz hsync */
19119 + NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
19120 +- 0, FB_VMODE_DOUBLE
19121 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19122 + }, {
19123 + /* 480x300 @ 63 Hz, 39.6 kHz hsync */
19124 + NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
19125 +- 0, FB_VMODE_DOUBLE
19126 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19127 + }, {
19128 + /* 480x300 @ 72 Hz, 48.0 kHz hsync */
19129 + NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
19130 +- 0, FB_VMODE_DOUBLE
19131 ++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
19132 + }, {
19133 + /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
19134 + NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
19135 + FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
19136 +- FB_VMODE_NONINTERLACED
19137 ++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19138 + }, {
19139 + /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
19140 + NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
19141 +- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
19142 ++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19143 + }, {
19144 + /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
19145 + NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
19146 +- 0, FB_VMODE_NONINTERLACED
19147 ++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
19148 + },
19149 + };
19150 +
19151 +diff -Nurp linux-2.6.23.15/drivers/video/vesafb.c linux-2.6.23.15-grsec/drivers/video/vesafb.c
19152 +--- linux-2.6.23.15/drivers/video/vesafb.c 2007-10-09 21:31:38.000000000 +0100
19153 ++++ linux-2.6.23.15-grsec/drivers/video/vesafb.c 2008-02-11 10:37:44.000000000 +0000
19154 +@@ -9,6 +9,7 @@
19155 + */
19156 +
19157 + #include <linux/module.h>
19158 ++#include <linux/moduleloader.h>
19159 + #include <linux/kernel.h>
19160 + #include <linux/errno.h>
19161 + #include <linux/string.h>
19162 +@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
19163 + unsigned int size_vmode;
19164 + unsigned int size_remap;
19165 + unsigned int size_total;
19166 ++ void *pmi_code = NULL;
19167 +
19168 + if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
19169 + return -ENODEV;
19170 +@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
19171 + size_remap = size_total;
19172 + vesafb_fix.smem_len = size_remap;
19173 +
19174 +-#ifndef __i386__
19175 +- screen_info.vesapm_seg = 0;
19176 +-#endif
19177 +-
19178 + if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
19179 + printk(KERN_WARNING
19180 + "vesafb: cannot reserve video memory at 0x%lx\n",
19181 +@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
19182 + printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
19183 + vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
19184 +
19185 ++#ifdef __i386__
19186 ++
19187 ++#ifdef CONFIG_PAX_KERNEXEC
19188 ++ pmi_code = module_alloc_exec(screen_info.vesapm_size);
19189 ++ if (!pmi_code)
19190 ++#else
19191 ++ if (0)
19192 ++#endif
19193 ++
19194 ++#endif
19195 ++ screen_info.vesapm_seg = 0;
19196 ++
19197 + if (screen_info.vesapm_seg) {
19198 +- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
19199 +- screen_info.vesapm_seg,screen_info.vesapm_off);
19200 ++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
19201 ++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
19202 + }
19203 +
19204 + if (screen_info.vesapm_seg < 0xc000)
19205 +@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
19206 +
19207 + if (ypan || pmi_setpal) {
19208 + unsigned short *pmi_base;
19209 +- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
19210 +- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
19211 +- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
19212 ++
19213 ++#ifdef CONFIG_PAX_KERNEXEC
19214 ++ unsigned long cr0;
19215 ++#endif
19216 ++
19217 ++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
19218 ++
19219 ++#ifdef CONFIG_PAX_KERNEXEC
19220 ++ pax_open_kernel(cr0);
19221 ++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
19222 ++ pax_close_kernel(cr0);
19223 ++#else
19224 ++ pmi_code = pmi_base;
19225 ++#endif
19226 ++
19227 ++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
19228 ++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
19229 ++
19230 ++#ifdef CONFIG_PAX_KERNEXEC
19231 ++ pmi_start -= __KERNEL_TEXT_OFFSET;
19232 ++ pmi_pal -= __KERNEL_TEXT_OFFSET;
19233 ++#endif
19234 ++
19235 + printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
19236 + if (pmi_base[3]) {
19237 + printk(KERN_INFO "vesafb: pmi: ports = ");
19238 +@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
19239 + info->node, info->fix.id);
19240 + return 0;
19241 + err:
19242 ++
19243 ++#ifdef CONFIG_PAX_KERNEXEC
19244 ++ module_free_exec(NULL, pmi_code);
19245 ++#endif
19246 ++
19247 + if (info->screen_base)
19248 + iounmap(info->screen_base);
19249 + framebuffer_release(info);
19250 +diff -Nurp linux-2.6.23.15/fs/Kconfig linux-2.6.23.15-grsec/fs/Kconfig
19251 +--- linux-2.6.23.15/fs/Kconfig 2007-10-09 21:31:38.000000000 +0100
19252 ++++ linux-2.6.23.15-grsec/fs/Kconfig 2008-02-11 10:37:44.000000000 +0000
19253 +@@ -909,7 +909,7 @@ config PROC_FS
19254 +
19255 + config PROC_KCORE
19256 + bool "/proc/kcore support" if !ARM
19257 +- depends on PROC_FS && MMU
19258 ++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
19259 +
19260 + config PROC_VMCORE
19261 + bool "/proc/vmcore support (EXPERIMENTAL)"
19262 +diff -Nurp linux-2.6.23.15/fs/binfmt_aout.c linux-2.6.23.15-grsec/fs/binfmt_aout.c
19263 +--- linux-2.6.23.15/fs/binfmt_aout.c 2007-10-09 21:31:38.000000000 +0100
19264 ++++ linux-2.6.23.15-grsec/fs/binfmt_aout.c 2008-02-11 10:37:44.000000000 +0000
19265 +@@ -24,6 +24,7 @@
19266 + #include <linux/binfmts.h>
19267 + #include <linux/personality.h>
19268 + #include <linux/init.h>
19269 ++#include <linux/grsecurity.h>
19270 +
19271 + #include <asm/system.h>
19272 + #include <asm/uaccess.h>
19273 +@@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
19274 + /* If the size of the dump file exceeds the rlimit, then see what would happen
19275 + if we wrote the stack, but not the data area. */
19276 + #ifdef __sparc__
19277 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
19278 + if ((dump.u_dsize+dump.u_ssize) >
19279 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
19280 + dump.u_dsize = 0;
19281 + #else
19282 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
19283 + if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
19284 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
19285 + dump.u_dsize = 0;
19286 +@@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
19287 +
19288 + /* Make sure we have enough room to write the stack and data areas. */
19289 + #ifdef __sparc__
19290 ++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
19291 + if ((dump.u_ssize) >
19292 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
19293 + dump.u_ssize = 0;
19294 + #else
19295 ++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
19296 + if ((dump.u_ssize+1) * PAGE_SIZE >
19297 + current->signal->rlim[RLIMIT_CORE].rlim_cur)
19298 + dump.u_ssize = 0;
19299 +@@ -294,6 +299,8 @@ static int load_aout_binary(struct linux
19300 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
19301 + if (rlim >= RLIM_INFINITY)
19302 + rlim = ~0;
19303 ++
19304 ++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
19305 + if (ex.a_data + ex.a_bss > rlim)
19306 + return -ENOMEM;
19307 +
19308 +@@ -326,6 +333,28 @@ static int load_aout_binary(struct linux
19309 + current->mm->mmap = NULL;
19310 + compute_creds(bprm);
19311 + current->flags &= ~PF_FORKNOEXEC;
19312 ++
19313 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19314 ++ current->mm->pax_flags = 0UL;
19315 ++#endif
19316 ++
19317 ++#ifdef CONFIG_PAX_PAGEEXEC
19318 ++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
19319 ++ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
19320 ++
19321 ++#ifdef CONFIG_PAX_EMUTRAMP
19322 ++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
19323 ++ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
19324 ++#endif
19325 ++
19326 ++#ifdef CONFIG_PAX_MPROTECT
19327 ++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
19328 ++ current->mm->pax_flags |= MF_PAX_MPROTECT;
19329 ++#endif
19330 ++
19331 ++ }
19332 ++#endif
19333 ++
19334 + #ifdef __sparc__
19335 + if (N_MAGIC(ex) == NMAGIC) {
19336 + loff_t pos = fd_offset;
19337 +@@ -421,7 +450,7 @@ static int load_aout_binary(struct linux
19338 +
19339 + down_write(&current->mm->mmap_sem);
19340 + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
19341 +- PROT_READ | PROT_WRITE | PROT_EXEC,
19342 ++ PROT_READ | PROT_WRITE,
19343 + MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
19344 + fd_offset + ex.a_text);
19345 + up_write(&current->mm->mmap_sem);
19346 +diff -Nurp linux-2.6.23.15/fs/binfmt_elf.c linux-2.6.23.15-grsec/fs/binfmt_elf.c
19347 +--- linux-2.6.23.15/fs/binfmt_elf.c 2007-10-09 21:31:38.000000000 +0100
19348 ++++ linux-2.6.23.15-grsec/fs/binfmt_elf.c 2008-02-11 10:37:44.000000000 +0000
19349 +@@ -39,10 +39,21 @@
19350 + #include <linux/random.h>
19351 + #include <linux/elf.h>
19352 + #include <linux/utsname.h>
19353 ++#include <linux/grsecurity.h>
19354 ++
19355 + #include <asm/uaccess.h>
19356 + #include <asm/param.h>
19357 + #include <asm/page.h>
19358 +
19359 ++#ifdef CONFIG_PAX_SEGMEXEC
19360 ++#include <asm/desc.h>
19361 ++#endif
19362 ++
19363 ++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
19364 ++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
19365 ++EXPORT_SYMBOL(pax_set_initial_flags_func);
19366 ++#endif
19367 ++
19368 + static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
19369 + static int load_elf_library(struct file *);
19370 + static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
19371 +@@ -84,6 +95,8 @@ static struct linux_binfmt elf_format =
19372 +
19373 + static int set_brk(unsigned long start, unsigned long end)
19374 + {
19375 ++ unsigned long e = end;
19376 ++
19377 + start = ELF_PAGEALIGN(start);
19378 + end = ELF_PAGEALIGN(end);
19379 + if (end > start) {
19380 +@@ -94,7 +107,7 @@ static int set_brk(unsigned long start,
19381 + if (BAD_ADDR(addr))
19382 + return addr;
19383 + }
19384 +- current->mm->start_brk = current->mm->brk = end;
19385 ++ current->mm->start_brk = current->mm->brk = e;
19386 + return 0;
19387 + }
19388 +
19389 +@@ -325,10 +338,9 @@ static unsigned long load_elf_interp(str
19390 + {
19391 + struct elf_phdr *elf_phdata;
19392 + struct elf_phdr *eppnt;
19393 +- unsigned long load_addr = 0;
19394 +- int load_addr_set = 0;
19395 ++ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
19396 + unsigned long last_bss = 0, elf_bss = 0;
19397 +- unsigned long error = ~0UL;
19398 ++ unsigned long error = -EINVAL;
19399 + int retval, i, size;
19400 +
19401 + /* First of all, some simple consistency checks */
19402 +@@ -367,66 +379,86 @@ static unsigned long load_elf_interp(str
19403 + goto out_close;
19404 + }
19405 +
19406 ++#ifdef CONFIG_PAX_SEGMEXEC
19407 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
19408 ++ task_size = SEGMEXEC_TASK_SIZE;
19409 ++#endif
19410 ++
19411 + eppnt = elf_phdata;
19412 ++ min_addr = task_size;
19413 ++ max_addr = 0;
19414 ++ error = -ENOMEM;
19415 ++
19416 + for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
19417 +- if (eppnt->p_type == PT_LOAD) {
19418 +- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
19419 +- int elf_prot = 0;
19420 +- unsigned long vaddr = 0;
19421 +- unsigned long k, map_addr;
19422 +-
19423 +- if (eppnt->p_flags & PF_R)
19424 +- elf_prot = PROT_READ;
19425 +- if (eppnt->p_flags & PF_W)
19426 +- elf_prot |= PROT_WRITE;
19427 +- if (eppnt->p_flags & PF_X)
19428 +- elf_prot |= PROT_EXEC;
19429 +- vaddr = eppnt->p_vaddr;
19430 +- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
19431 +- elf_type |= MAP_FIXED;
19432 +-
19433 +- map_addr = elf_map(interpreter, load_addr + vaddr,
19434 +- eppnt, elf_prot, elf_type);
19435 +- error = map_addr;
19436 +- if (BAD_ADDR(map_addr))
19437 +- goto out_close;
19438 +-
19439 +- if (!load_addr_set &&
19440 +- interp_elf_ex->e_type == ET_DYN) {
19441 +- load_addr = map_addr - ELF_PAGESTART(vaddr);
19442 +- load_addr_set = 1;
19443 +- }
19444 ++ if (eppnt->p_type != PT_LOAD)
19445 ++ continue;
19446 +
19447 +- /*
19448 +- * Check to see if the section's size will overflow the
19449 +- * allowed task size. Note that p_filesz must always be
19450 +- * <= p_memsize so it's only necessary to check p_memsz.
19451 +- */
19452 +- k = load_addr + eppnt->p_vaddr;
19453 +- if (BAD_ADDR(k) ||
19454 +- eppnt->p_filesz > eppnt->p_memsz ||
19455 +- eppnt->p_memsz > TASK_SIZE ||
19456 +- TASK_SIZE - eppnt->p_memsz < k) {
19457 +- error = -ENOMEM;
19458 +- goto out_close;
19459 +- }
19460 ++ /*
19461 ++ * Check to see if the section's size will overflow the
19462 ++ * allowed task size. Note that p_filesz must always be
19463 ++ * <= p_memsize so it is only necessary to check p_memsz.
19464 ++ */
19465 ++ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
19466 ++ goto out_close;
19467 +
19468 +- /*
19469 +- * Find the end of the file mapping for this phdr, and
19470 +- * keep track of the largest address we see for this.
19471 +- */
19472 +- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
19473 +- if (k > elf_bss)
19474 +- elf_bss = k;
19475 ++ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
19476 ++ min_addr = ELF_PAGESTART(eppnt->p_vaddr);
19477 ++ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
19478 ++ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
19479 ++ }
19480 ++ if (min_addr >= max_addr || max_addr > task_size)
19481 ++ goto out_close;
19482 +
19483 +- /*
19484 +- * Do the same thing for the memory mapping - between
19485 +- * elf_bss and last_bss is the bss section.
19486 +- */
19487 +- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
19488 +- if (k > last_bss)
19489 +- last_bss = k;
19490 +- }
19491 ++ if (interp_elf_ex->e_type == ET_DYN) {
19492 ++ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
19493 ++
19494 ++ if (load_addr >= task_size)
19495 ++ goto out_close;
19496 ++
19497 ++ load_addr -= min_addr;
19498 ++ }
19499 ++
19500 ++ eppnt = elf_phdata;
19501 ++ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
19502 ++ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
19503 ++ int elf_prot = 0;
19504 ++ unsigned long vaddr = 0;
19505 ++ unsigned long k, map_addr;
19506 ++
19507 ++ if (eppnt->p_type != PT_LOAD)
19508 ++ continue;
19509 ++
19510 ++ if (eppnt->p_flags & PF_R)
19511 ++ elf_prot = PROT_READ;
19512 ++ if (eppnt->p_flags & PF_W)
19513 ++ elf_prot |= PROT_WRITE;
19514 ++ if (eppnt->p_flags & PF_X)
19515 ++ elf_prot |= PROT_EXEC;
19516 ++ vaddr = eppnt->p_vaddr;
19517 ++
19518 ++ map_addr = elf_map(interpreter, load_addr + vaddr,
19519 ++ eppnt, elf_prot, elf_type);
19520 ++ error = map_addr;
19521 ++ if (BAD_ADDR(map_addr))
19522 ++ goto out_close;
19523 ++
19524 ++ k = load_addr + eppnt->p_vaddr;
19525 ++
19526 ++ /*
19527 ++ * Find the end of the file mapping for this phdr, and
19528 ++ * keep track of the largest address we see for this.
19529 ++ */
19530 ++ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
19531 ++ if (k > elf_bss)
19532 ++ elf_bss = k;
19533 ++
19534 ++ /*
19535 ++ * Do the same thing for the memory mapping - between
19536 ++ * elf_bss and last_bss is the bss section.
19537 ++ */
19538 ++ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
19539 ++ if (k > last_bss)
19540 ++ last_bss = k;
19541 + }
19542 +
19543 + /*
19544 +@@ -454,6 +486,8 @@ static unsigned long load_elf_interp(str
19545 +
19546 + *interp_load_addr = load_addr;
19547 + error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
19548 ++ if (BAD_ADDR(error))
19549 ++ error = -EFAULT;
19550 +
19551 + out_close:
19552 + kfree(elf_phdata);
19553 +@@ -464,7 +498,7 @@ out:
19554 + static unsigned long load_aout_interp(struct exec *interp_ex,
19555 + struct file *interpreter)
19556 + {
19557 +- unsigned long text_data, elf_entry = ~0UL;
19558 ++ unsigned long text_data, elf_entry = -EINVAL;
19559 + char __user * addr;
19560 + loff_t offset;
19561 +
19562 +@@ -507,6 +541,177 @@ out:
19563 + return elf_entry;
19564 + }
19565 +
19566 ++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
19567 ++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
19568 ++{
19569 ++ unsigned long pax_flags = 0UL;
19570 ++
19571 ++#ifdef CONFIG_PAX_PAGEEXEC
19572 ++ if (elf_phdata->p_flags & PF_PAGEEXEC)
19573 ++ pax_flags |= MF_PAX_PAGEEXEC;
19574 ++#endif
19575 ++
19576 ++#ifdef CONFIG_PAX_SEGMEXEC
19577 ++ if (elf_phdata->p_flags & PF_SEGMEXEC)
19578 ++ pax_flags |= MF_PAX_SEGMEXEC;
19579 ++#endif
19580 ++
19581 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19582 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19583 ++ if (nx_enabled)
19584 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19585 ++ else
19586 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19587 ++ }
19588 ++#endif
19589 ++
19590 ++#ifdef CONFIG_PAX_EMUTRAMP
19591 ++ if (elf_phdata->p_flags & PF_EMUTRAMP)
19592 ++ pax_flags |= MF_PAX_EMUTRAMP;
19593 ++#endif
19594 ++
19595 ++#ifdef CONFIG_PAX_MPROTECT
19596 ++ if (elf_phdata->p_flags & PF_MPROTECT)
19597 ++ pax_flags |= MF_PAX_MPROTECT;
19598 ++#endif
19599 ++
19600 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
19601 ++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
19602 ++ pax_flags |= MF_PAX_RANDMMAP;
19603 ++#endif
19604 ++
19605 ++ return pax_flags;
19606 ++}
19607 ++#endif
19608 ++
19609 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19610 ++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
19611 ++{
19612 ++ unsigned long pax_flags = 0UL;
19613 ++
19614 ++#ifdef CONFIG_PAX_PAGEEXEC
19615 ++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
19616 ++ pax_flags |= MF_PAX_PAGEEXEC;
19617 ++#endif
19618 ++
19619 ++#ifdef CONFIG_PAX_SEGMEXEC
19620 ++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
19621 ++ pax_flags |= MF_PAX_SEGMEXEC;
19622 ++#endif
19623 ++
19624 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19625 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19626 ++ if (nx_enabled)
19627 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19628 ++ else
19629 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19630 ++ }
19631 ++#endif
19632 ++
19633 ++#ifdef CONFIG_PAX_EMUTRAMP
19634 ++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
19635 ++ pax_flags |= MF_PAX_EMUTRAMP;
19636 ++#endif
19637 ++
19638 ++#ifdef CONFIG_PAX_MPROTECT
19639 ++ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
19640 ++ pax_flags |= MF_PAX_MPROTECT;
19641 ++#endif
19642 ++
19643 ++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
19644 ++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
19645 ++ pax_flags |= MF_PAX_RANDMMAP;
19646 ++#endif
19647 ++
19648 ++ return pax_flags;
19649 ++}
19650 ++#endif
19651 ++
19652 ++#ifdef CONFIG_PAX_EI_PAX
19653 ++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
19654 ++{
19655 ++ unsigned long pax_flags = 0UL;
19656 ++
19657 ++#ifdef CONFIG_PAX_PAGEEXEC
19658 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
19659 ++ pax_flags |= MF_PAX_PAGEEXEC;
19660 ++#endif
19661 ++
19662 ++#ifdef CONFIG_PAX_SEGMEXEC
19663 ++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
19664 ++ pax_flags |= MF_PAX_SEGMEXEC;
19665 ++#endif
19666 ++
19667 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
19668 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19669 ++ if (nx_enabled)
19670 ++ pax_flags &= ~MF_PAX_SEGMEXEC;
19671 ++ else
19672 ++ pax_flags &= ~MF_PAX_PAGEEXEC;
19673 ++ }
19674 ++#endif
19675 ++
19676 ++#ifdef CONFIG_PAX_EMUTRAMP
19677 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
19678 ++ pax_flags |= MF_PAX_EMUTRAMP;
19679 ++#endif
19680 ++
19681 ++#ifdef CONFIG_PAX_MPROTECT
19682 ++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
19683 ++ pax_flags |= MF_PAX_MPROTECT;
19684 ++#endif
19685 ++
19686 ++#ifdef CONFIG_PAX_ASLR
19687 ++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
19688 ++ pax_flags |= MF_PAX_RANDMMAP;
19689 ++#endif
19690 ++
19691 ++ return pax_flags;
19692 ++}
19693 ++#endif
19694 ++
19695 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
19696 ++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
19697 ++{
19698 ++ unsigned long pax_flags = 0UL;
19699 ++
19700 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19701 ++ unsigned long i;
19702 ++#endif
19703 ++
19704 ++#ifdef CONFIG_PAX_EI_PAX
19705 ++ pax_flags = pax_parse_ei_pax(elf_ex);
19706 ++#endif
19707 ++
19708 ++#ifdef CONFIG_PAX_PT_PAX_FLAGS
19709 ++ for (i = 0UL; i < elf_ex->e_phnum; i++)
19710 ++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
19711 ++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
19712 ++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
19713 ++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
19714 ++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
19715 ++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
19716 ++ return -EINVAL;
19717 ++
19718 ++#ifdef CONFIG_PAX_SOFTMODE
19719 ++ if (pax_softmode)
19720 ++ pax_flags = pax_parse_softmode(&elf_phdata[i]);
19721 ++ else
19722 ++#endif
19723 ++
19724 ++ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
19725 ++ break;
19726 ++ }
19727 ++#endif
19728 ++
19729 ++ if (0 > pax_check_flags(&pax_flags))
19730 ++ return -EINVAL;
19731 ++
19732 ++ current->mm->pax_flags = pax_flags;
19733 ++ return 0;
19734 ++}
19735 ++#endif
19736 ++
19737 + /*
19738 + * These are the functions used to load ELF style executables and shared
19739 + * libraries. There is no binary dependent code anywhere else.
19740 +@@ -544,7 +749,7 @@ static int load_elf_binary(struct linux_
19741 + char * elf_interpreter = NULL;
19742 + unsigned int interpreter_type = INTERPRETER_NONE;
19743 + unsigned char ibcs2_interpreter = 0;
19744 +- unsigned long error;
19745 ++ unsigned long error = 0;
19746 + struct elf_phdr *elf_ppnt, *elf_phdata;
19747 + unsigned long elf_bss, elf_brk;
19748 + int elf_exec_fileno;
19749 +@@ -556,12 +761,12 @@ static int load_elf_binary(struct linux_
19750 + char passed_fileno[6];
19751 + struct files_struct *files;
19752 + int executable_stack = EXSTACK_DEFAULT;
19753 +- unsigned long def_flags = 0;
19754 + struct {
19755 + struct elfhdr elf_ex;
19756 + struct elfhdr interp_elf_ex;
19757 + struct exec interp_ex;
19758 + } *loc;
19759 ++ unsigned long task_size = TASK_SIZE;
19760 +
19761 + loc = kmalloc(sizeof(*loc), GFP_KERNEL);
19762 + if (!loc) {
19763 +@@ -788,14 +993,89 @@ static int load_elf_binary(struct linux_
19764 +
19765 + /* OK, This is the point of no return */
19766 + current->flags &= ~PF_FORKNOEXEC;
19767 +- current->mm->def_flags = def_flags;
19768 ++
19769 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
19770 ++ current->mm->pax_flags = 0UL;
19771 ++#endif
19772 ++
19773 ++#ifdef CONFIG_PAX_DLRESOLVE
19774 ++ current->mm->call_dl_resolve = 0UL;
19775 ++#endif
19776 ++
19777 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
19778 ++ current->mm->call_syscall = 0UL;
19779 ++#endif
19780 ++
19781 ++#ifdef CONFIG_PAX_ASLR
19782 ++ current->mm->delta_mmap = 0UL;
19783 ++ current->mm->delta_stack = 0UL;
19784 ++#endif
19785 ++
19786 ++ current->mm->def_flags = 0;
19787 ++
19788 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
19789 ++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
19790 ++ send_sig(SIGKILL, current, 0);
19791 ++ goto out_free_dentry;
19792 ++ }
19793 ++#endif
19794 ++
19795 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19796 ++ pax_set_initial_flags(bprm);
19797 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
19798 ++ if (pax_set_initial_flags_func)
19799 ++ (pax_set_initial_flags_func)(bprm);
19800 ++#endif
19801 ++
19802 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
19803 ++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
19804 ++ current->mm->context.user_cs_limit = PAGE_SIZE;
19805 ++ current->mm->def_flags |= VM_PAGEEXEC;
19806 ++ }
19807 ++#endif
19808 ++
19809 ++#ifdef CONFIG_PAX_SEGMEXEC
19810 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
19811 ++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
19812 ++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
19813 ++ task_size = SEGMEXEC_TASK_SIZE;
19814 ++ }
19815 ++#endif
19816 ++
19817 ++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
19818 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
19819 ++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
19820 ++ put_cpu_no_resched();
19821 ++ }
19822 ++#endif
19823 ++
19824 ++#ifdef CONFIG_PAX_ASLR
19825 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
19826 ++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
19827 ++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
19828 ++ }
19829 ++#endif
19830 ++
19831 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19832 ++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
19833 ++ executable_stack = EXSTACK_DEFAULT;
19834 ++#endif
19835 +
19836 + /* Do this immediately, since STACK_TOP as used in setup_arg_pages
19837 + may depend on the personality. */
19838 + SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
19839 ++
19840 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
19841 ++ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
19842 ++#endif
19843 ++
19844 + if (elf_read_implies_exec(loc->elf_ex, executable_stack))
19845 + current->personality |= READ_IMPLIES_EXEC;
19846 +
19847 ++#ifdef CONFIG_PAX_ASLR
19848 ++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
19849 ++#endif
19850 ++
19851 + if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
19852 + current->flags |= PF_RANDOMIZE;
19853 + arch_pick_mmap_layout(current->mm);
19854 +@@ -871,6 +1151,20 @@ static int load_elf_binary(struct linux_
19855 + * might try to exec. This is because the brk will
19856 + * follow the loader, and is not movable. */
19857 + load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
19858 ++
19859 ++#ifdef CONFIG_PAX_RANDMMAP
19860 ++ /* PaX: randomize base address at the default exe base if requested */
19861 ++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
19862 ++#ifdef CONFIG_SPARC64
19863 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
19864 ++#else
19865 ++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
19866 ++#endif
19867 ++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
19868 ++ elf_flags |= MAP_FIXED;
19869 ++ }
19870 ++#endif
19871 ++
19872 + }
19873 +
19874 + error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
19875 +@@ -903,9 +1197,9 @@ static int load_elf_binary(struct linux_
19876 + * allowed task size. Note that p_filesz must always be
19877 + * <= p_memsz so it is only necessary to check p_memsz.
19878 + */
19879 +- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
19880 +- elf_ppnt->p_memsz > TASK_SIZE ||
19881 +- TASK_SIZE - elf_ppnt->p_memsz < k) {
19882 ++ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
19883 ++ elf_ppnt->p_memsz > task_size ||
19884 ++ task_size - elf_ppnt->p_memsz < k) {
19885 + /* set_brk can never work. Avoid overflows. */
19886 + send_sig(SIGKILL, current, 0);
19887 + retval = -EINVAL;
19888 +@@ -933,6 +1227,11 @@ static int load_elf_binary(struct linux_
19889 + start_data += load_bias;
19890 + end_data += load_bias;
19891 +
19892 ++#ifdef CONFIG_PAX_RANDMMAP
19893 ++ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
19894 ++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
19895 ++#endif
19896 ++
19897 + /* Calling set_brk effectively mmaps the pages that we need
19898 + * for the bss and break sections. We must do this before
19899 + * mapping in the interpreter, to make sure it doesn't wind
19900 +@@ -944,9 +1243,11 @@ static int load_elf_binary(struct linux_
19901 + goto out_free_dentry;
19902 + }
19903 + if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
19904 +- send_sig(SIGSEGV, current, 0);
19905 +- retval = -EFAULT; /* Nobody gets to see this, but.. */
19906 +- goto out_free_dentry;
19907 ++ /*
19908 ++ * This bss-zeroing can fail if the ELF
19909 ++ * file specifies odd protections. So
19910 ++ * we don't check the return value
19911 ++ */
19912 + }
19913 +
19914 + if (elf_interpreter) {
19915 +@@ -1183,8 +1484,10 @@ static int dump_seek(struct file *file,
19916 + unsigned long n = off;
19917 + if (n > PAGE_SIZE)
19918 + n = PAGE_SIZE;
19919 +- if (!dump_write(file, buf, n))
19920 ++ if (!dump_write(file, buf, n)) {
19921 ++ free_page((unsigned long)buf);
19922 + return 0;
19923 ++ }
19924 + off -= n;
19925 + }
19926 + free_page((unsigned long)buf);
19927 +@@ -1199,7 +1502,7 @@ static int dump_seek(struct file *file,
19928 + *
19929 + * I think we should skip something. But I am not sure how. H.J.
19930 + */
19931 +-static int maydump(struct vm_area_struct *vma, unsigned long mm_flags)
19932 ++static int maydump(struct vm_area_struct *vma, unsigned long mm_flags, long signr)
19933 + {
19934 + /* The vma can be set up to tell us the answer directly. */
19935 + if (vma->vm_flags & VM_ALWAYSDUMP)
19936 +@@ -1218,7 +1521,7 @@ static int maydump(struct vm_area_struct
19937 + }
19938 +
19939 + /* By default, if it hasn't been written to, don't write it out. */
19940 +- if (!vma->anon_vma)
19941 ++ if (signr != SIGKILL && !vma->anon_vma)
19942 + return test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags);
19943 +
19944 + return test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags);
19945 +@@ -1275,8 +1578,11 @@ static int writenote(struct memelfnote *
19946 + #undef DUMP_WRITE
19947 +
19948 + #define DUMP_WRITE(addr, nr) \
19949 ++ do { \
19950 ++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
19951 + if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
19952 +- goto end_coredump;
19953 ++ goto end_coredump; \
19954 ++ } while (0);
19955 + #define DUMP_SEEK(off) \
19956 + if (!dump_seek(file, (off))) \
19957 + goto end_coredump;
19958 +@@ -1676,7 +1982,7 @@ static int elf_core_dump(long signr, str
19959 + phdr.p_offset = offset;
19960 + phdr.p_vaddr = vma->vm_start;
19961 + phdr.p_paddr = 0;
19962 +- phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
19963 ++ phdr.p_filesz = maydump(vma, mm_flags, signr) ? sz : 0;
19964 + phdr.p_memsz = sz;
19965 + offset += phdr.p_filesz;
19966 + phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
19967 +@@ -1720,7 +2026,7 @@ static int elf_core_dump(long signr, str
19968 + vma = next_vma(vma, gate_vma)) {
19969 + unsigned long addr;
19970 +
19971 +- if (!maydump(vma, mm_flags))
19972 ++ if (!maydump(vma, mm_flags, signr))
19973 + continue;
19974 +
19975 + for (addr = vma->vm_start;
19976 +@@ -1743,6 +2049,7 @@ static int elf_core_dump(long signr, str
19977 + flush_cache_page(vma, addr,
19978 + page_to_pfn(page));
19979 + kaddr = kmap(page);
19980 ++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
19981 + if ((size += PAGE_SIZE) > limit ||
19982 + !dump_write(file, kaddr,
19983 + PAGE_SIZE)) {
19984 +diff -Nurp linux-2.6.23.15/fs/binfmt_flat.c linux-2.6.23.15-grsec/fs/binfmt_flat.c
19985 +--- linux-2.6.23.15/fs/binfmt_flat.c 2007-10-09 21:31:38.000000000 +0100
19986 ++++ linux-2.6.23.15-grsec/fs/binfmt_flat.c 2008-02-11 10:37:44.000000000 +0000
19987 +@@ -559,7 +559,9 @@ static int load_flat_file(struct linux_b
19988 + realdatastart = (unsigned long) -ENOMEM;
19989 + printk("Unable to allocate RAM for process data, errno %d\n",
19990 + (int)-realdatastart);
19991 ++ down_write(&current->mm->mmap_sem);
19992 + do_munmap(current->mm, textpos, text_len);
19993 ++ up_write(&current->mm->mmap_sem);
19994 + ret = realdatastart;
19995 + goto err;
19996 + }
19997 +@@ -581,8 +583,10 @@ static int load_flat_file(struct linux_b
19998 + }
19999 + if (result >= (unsigned long)-4096) {
20000 + printk("Unable to read data+bss, errno %d\n", (int)-result);
20001 ++ down_write(&current->mm->mmap_sem);
20002 + do_munmap(current->mm, textpos, text_len);
20003 + do_munmap(current->mm, realdatastart, data_len + extra);
20004 ++ up_write(&current->mm->mmap_sem);
20005 + ret = result;
20006 + goto err;
20007 + }
20008 +@@ -655,8 +659,10 @@ static int load_flat_file(struct linux_b
20009 + }
20010 + if (result >= (unsigned long)-4096) {
20011 + printk("Unable to read code+data+bss, errno %d\n",(int)-result);
20012 ++ down_write(&current->mm->mmap_sem);
20013 + do_munmap(current->mm, textpos, text_len + data_len + extra +
20014 + MAX_SHARED_LIBS * sizeof(unsigned long));
20015 ++ up_write(&current->mm->mmap_sem);
20016 + ret = result;
20017 + goto err;
20018 + }
20019 +diff -Nurp linux-2.6.23.15/fs/binfmt_misc.c linux-2.6.23.15-grsec/fs/binfmt_misc.c
20020 +--- linux-2.6.23.15/fs/binfmt_misc.c 2007-10-09 21:31:38.000000000 +0100
20021 ++++ linux-2.6.23.15-grsec/fs/binfmt_misc.c 2008-02-11 10:37:44.000000000 +0000
20022 +@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
20023 + struct files_struct *files = NULL;
20024 +
20025 + retval = -ENOEXEC;
20026 +- if (!enabled)
20027 ++ if (!enabled || bprm->misc)
20028 + goto _ret;
20029 +
20030 ++ bprm->misc++;
20031 ++
20032 + /* to keep locking time low, we copy the interpreter string */
20033 + read_lock(&entries_lock);
20034 + fmt = check_file(bprm);
20035 +@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl
20036 + static struct tree_descr bm_files[] = {
20037 + [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
20038 + [3] = {"register", &bm_register_operations, S_IWUSR},
20039 +- /* last one */ {""}
20040 ++ /* last one */ {"", NULL, 0}
20041 + };
20042 + int err = simple_fill_super(sb, 0x42494e4d, bm_files);
20043 + if (!err)
20044 +diff -Nurp linux-2.6.23.15/fs/buffer.c linux-2.6.23.15-grsec/fs/buffer.c
20045 +--- linux-2.6.23.15/fs/buffer.c 2007-10-09 21:31:38.000000000 +0100
20046 ++++ linux-2.6.23.15-grsec/fs/buffer.c 2008-02-11 10:37:44.000000000 +0000
20047 +@@ -41,6 +41,7 @@
20048 + #include <linux/bitops.h>
20049 + #include <linux/mpage.h>
20050 + #include <linux/bit_spinlock.h>
20051 ++#include <linux/grsecurity.h>
20052 +
20053 + static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
20054 +
20055 +@@ -2017,6 +2018,7 @@ static int __generic_cont_expand(struct
20056 +
20057 + err = -EFBIG;
20058 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
20059 ++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
20060 + if (limit != RLIM_INFINITY && size > (loff_t)limit) {
20061 + send_sig(SIGXFSZ, current, 0);
20062 + goto out;
20063 +diff -Nurp linux-2.6.23.15/fs/cifs/cifs_uniupr.h linux-2.6.23.15-grsec/fs/cifs/cifs_uniupr.h
20064 +--- linux-2.6.23.15/fs/cifs/cifs_uniupr.h 2007-10-09 21:31:38.000000000 +0100
20065 ++++ linux-2.6.23.15-grsec/fs/cifs/cifs_uniupr.h 2008-02-11 10:37:44.000000000 +0000
20066 +@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
20067 + {0x0490, 0x04cc, UniCaseRangeU0490},
20068 + {0x1e00, 0x1ffc, UniCaseRangeU1e00},
20069 + {0xff40, 0xff5a, UniCaseRangeUff40},
20070 +- {0}
20071 ++ {0, 0, NULL}
20072 + };
20073 + #endif
20074 +
20075 +diff -Nurp linux-2.6.23.15/fs/cifs/dir.c linux-2.6.23.15-grsec/fs/cifs/dir.c
20076 +--- linux-2.6.23.15/fs/cifs/dir.c 2007-10-09 21:31:38.000000000 +0100
20077 ++++ linux-2.6.23.15-grsec/fs/cifs/dir.c 2008-02-11 10:37:44.000000000 +0000
20078 +@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, stru
20079 + /* BB Do not bother to decode buf since no
20080 + local inode yet to put timestamps in,
20081 + but we can reuse it safely */
20082 +- int bytes_written;
20083 ++ unsigned int bytes_written;
20084 + struct win_dev *pdev;
20085 + pdev = (struct win_dev *)buf;
20086 + if (S_ISCHR(mode)) {
20087 +diff -Nurp linux-2.6.23.15/fs/cifs/inode.c linux-2.6.23.15-grsec/fs/cifs/inode.c
20088 +--- linux-2.6.23.15/fs/cifs/inode.c 2008-02-11 10:36:03.000000000 +0000
20089 ++++ linux-2.6.23.15-grsec/fs/cifs/inode.c 2008-02-11 10:37:44.000000000 +0000
20090 +@@ -1470,7 +1470,7 @@ int cifs_setattr(struct dentry *direntry
20091 + atomic_dec(&open_file->wrtPending);
20092 + cFYI(1, ("SetFSize for attrs rc = %d", rc));
20093 + if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
20094 +- int bytes_written;
20095 ++ unsigned int bytes_written;
20096 + rc = CIFSSMBWrite(xid, pTcon,
20097 + nfid, 0, attrs->ia_size,
20098 + &bytes_written, NULL, NULL,
20099 +@@ -1503,7 +1503,7 @@ int cifs_setattr(struct dentry *direntry
20100 + cifs_sb->mnt_cifs_flags &
20101 + CIFS_MOUNT_MAP_SPECIAL_CHR);
20102 + if (rc == 0) {
20103 +- int bytes_written;
20104 ++ unsigned int bytes_written;
20105 + rc = CIFSSMBWrite(xid, pTcon,
20106 + netfid, 0,
20107 + attrs->ia_size,
20108 +diff -Nurp linux-2.6.23.15/fs/compat.c linux-2.6.23.15-grsec/fs/compat.c
20109 +--- linux-2.6.23.15/fs/compat.c 2007-10-09 21:31:38.000000000 +0100
20110 ++++ linux-2.6.23.15-grsec/fs/compat.c 2008-02-11 10:37:44.000000000 +0000
20111 +@@ -50,6 +50,7 @@
20112 + #include <linux/poll.h>
20113 + #include <linux/mm.h>
20114 + #include <linux/eventpoll.h>
20115 ++#include <linux/grsecurity.h>
20116 +
20117 + #include <asm/uaccess.h>
20118 + #include <asm/mmu_context.h>
20119 +@@ -1300,14 +1301,12 @@ static int compat_copy_strings(int argc,
20120 + if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
20121 + struct page *page;
20122 +
20123 +-#ifdef CONFIG_STACK_GROWSUP
20124 + ret = expand_stack_downwards(bprm->vma, pos);
20125 + if (ret < 0) {
20126 + /* We've exceed the stack rlimit. */
20127 + ret = -E2BIG;
20128 + goto out;
20129 + }
20130 +-#endif
20131 + ret = get_user_pages(current, bprm->mm, pos,
20132 + 1, 1, 1, &page, NULL);
20133 + if (ret <= 0) {
20134 +@@ -1353,6 +1352,11 @@ int compat_do_execve(char * filename,
20135 + compat_uptr_t __user *envp,
20136 + struct pt_regs * regs)
20137 + {
20138 ++#ifdef CONFIG_GRKERNSEC
20139 ++ struct file *old_exec_file;
20140 ++ struct acl_subject_label *old_acl;
20141 ++ struct rlimit old_rlim[RLIM_NLIMITS];
20142 ++#endif
20143 + struct linux_binprm *bprm;
20144 + struct file *file;
20145 + int retval;
20146 +@@ -1373,6 +1377,14 @@ int compat_do_execve(char * filename,
20147 + bprm->filename = filename;
20148 + bprm->interp = filename;
20149 +
20150 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
20151 ++ retval = -EAGAIN;
20152 ++ if (gr_handle_nproc())
20153 ++ goto out_file;
20154 ++ retval = -EACCES;
20155 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
20156 ++ goto out_file;
20157 ++
20158 + retval = bprm_mm_init(bprm);
20159 + if (retval)
20160 + goto out_file;
20161 +@@ -1406,8 +1418,36 @@ int compat_do_execve(char * filename,
20162 + if (retval < 0)
20163 + goto out;
20164 +
20165 ++ if (!gr_tpe_allow(file)) {
20166 ++ retval = -EACCES;
20167 ++ goto out;
20168 ++ }
20169 ++
20170 ++ if (gr_check_crash_exec(file)) {
20171 ++ retval = -EACCES;
20172 ++ goto out;
20173 ++ }
20174 ++
20175 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
20176 ++
20177 ++ gr_handle_exec_args(bprm, (char __user * __user *)argv);
20178 ++
20179 ++#ifdef CONFIG_GRKERNSEC
20180 ++ old_acl = current->acl;
20181 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
20182 ++ old_exec_file = current->exec_file;
20183 ++ get_file(file);
20184 ++ current->exec_file = file;
20185 ++#endif
20186 ++
20187 ++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
20188 ++
20189 + retval = search_binary_handler(bprm, regs);
20190 + if (retval >= 0) {
20191 ++#ifdef CONFIG_GRKERNSEC
20192 ++ if (old_exec_file)
20193 ++ fput(old_exec_file);
20194 ++#endif
20195 + /* execve success */
20196 + security_bprm_free(bprm);
20197 + acct_update_integrals(current);
20198 +@@ -1415,6 +1455,13 @@ int compat_do_execve(char * filename,
20199 + return retval;
20200 + }
20201 +
20202 ++#ifdef CONFIG_GRKERNSEC
20203 ++ current->acl = old_acl;
20204 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
20205 ++ fput(current->exec_file);
20206 ++ current->exec_file = old_exec_file;
20207 ++#endif
20208 ++
20209 + out:
20210 + if (bprm->security)
20211 + security_bprm_free(bprm);
20212 +diff -Nurp linux-2.6.23.15/fs/compat_ioctl.c linux-2.6.23.15-grsec/fs/compat_ioctl.c
20213 +--- linux-2.6.23.15/fs/compat_ioctl.c 2007-10-09 21:31:38.000000000 +0100
20214 ++++ linux-2.6.23.15-grsec/fs/compat_ioctl.c 2008-02-11 10:37:44.000000000 +0000
20215 +@@ -2431,15 +2431,15 @@ struct ioctl_trans {
20216 + };
20217 +
20218 + #define HANDLE_IOCTL(cmd,handler) \
20219 +- { (cmd), (ioctl_trans_handler_t)(handler) },
20220 ++ { (cmd), (ioctl_trans_handler_t)(handler), NULL },
20221 +
20222 + /* pointer to compatible structure or no argument */
20223 + #define COMPATIBLE_IOCTL(cmd) \
20224 +- { (cmd), do_ioctl32_pointer },
20225 ++ { (cmd), do_ioctl32_pointer, NULL },
20226 +
20227 + /* argument is an unsigned long integer, not a pointer */
20228 + #define ULONG_IOCTL(cmd) \
20229 +- { (cmd), (ioctl_trans_handler_t)sys_ioctl },
20230 ++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
20231 +
20232 + /* ioctl should not be warned about even if it's not implemented.
20233 + Valid reasons to use this:
20234 +diff -Nurp linux-2.6.23.15/fs/debugfs/inode.c linux-2.6.23.15-grsec/fs/debugfs/inode.c
20235 +--- linux-2.6.23.15/fs/debugfs/inode.c 2007-10-09 21:31:38.000000000 +0100
20236 ++++ linux-2.6.23.15-grsec/fs/debugfs/inode.c 2008-02-11 10:37:44.000000000 +0000
20237 +@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
20238 +
20239 + static int debug_fill_super(struct super_block *sb, void *data, int silent)
20240 + {
20241 +- static struct tree_descr debug_files[] = {{""}};
20242 ++ static struct tree_descr debug_files[] = {{"", NULL, 0}};
20243 +
20244 + return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
20245 + }
20246 +diff -Nurp linux-2.6.23.15/fs/exec.c linux-2.6.23.15-grsec/fs/exec.c
20247 +--- linux-2.6.23.15/fs/exec.c 2008-02-11 10:36:03.000000000 +0000
20248 ++++ linux-2.6.23.15-grsec/fs/exec.c 2008-02-11 10:37:44.000000000 +0000
20249 +@@ -50,6 +50,8 @@
20250 + #include <linux/tsacct_kern.h>
20251 + #include <linux/cn_proc.h>
20252 + #include <linux/audit.h>
20253 ++#include <linux/random.h>
20254 ++#include <linux/grsecurity.h>
20255 +
20256 + #include <asm/uaccess.h>
20257 + #include <asm/mmu_context.h>
20258 +@@ -184,18 +186,10 @@ static struct page *get_arg_page(struct
20259 + int write)
20260 + {
20261 + struct page *page;
20262 +- int ret;
20263 +
20264 +-#ifdef CONFIG_STACK_GROWSUP
20265 +- if (write) {
20266 +- ret = expand_stack_downwards(bprm->vma, pos);
20267 +- if (ret < 0)
20268 +- return NULL;
20269 +- }
20270 +-#endif
20271 +- ret = get_user_pages(current, bprm->mm, pos,
20272 +- 1, write, 1, &page, NULL);
20273 +- if (ret <= 0)
20274 ++ if (0 > expand_stack_downwards(bprm->vma, pos))
20275 ++ return NULL;
20276 ++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
20277 + return NULL;
20278 +
20279 + if (write) {
20280 +@@ -260,7 +254,12 @@ static int __bprm_mm_init(struct linux_b
20281 + vma->vm_start = vma->vm_end - PAGE_SIZE;
20282 +
20283 + vma->vm_flags = VM_STACK_FLAGS;
20284 +- vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
20285 ++
20286 ++#ifdef CONFIG_PAX_SEGMEXEC
20287 ++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
20288 ++#endif
20289 ++
20290 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
20291 + err = insert_vm_struct(mm, vma);
20292 + if (err) {
20293 + up_write(&mm->mmap_sem);
20294 +@@ -272,6 +271,11 @@ static int __bprm_mm_init(struct linux_b
20295 +
20296 + bprm->p = vma->vm_end - sizeof(void *);
20297 +
20298 ++#ifdef CONFIG_PAX_RANDUSTACK
20299 ++ if (randomize_va_space)
20300 ++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
20301 ++#endif
20302 ++
20303 + return 0;
20304 +
20305 + err:
20306 +@@ -395,7 +399,7 @@ static int count(char __user * __user *
20307 + if (!p)
20308 + break;
20309 + argv++;
20310 +- if(++i > max)
20311 ++ if (++i > max)
20312 + return -E2BIG;
20313 + cond_resched();
20314 + }
20315 +@@ -535,6 +539,10 @@ static int shift_arg_pages(struct vm_are
20316 + if (vma != find_vma(mm, new_start))
20317 + return -EFAULT;
20318 +
20319 ++#ifdef CONFIG_PAX_SEGMEXEC
20320 ++ BUG_ON(pax_find_mirror_vma(vma));
20321 ++#endif
20322 ++
20323 + /*
20324 + * cover the whole range: [new_start, old_end)
20325 + */
20326 +@@ -623,6 +631,14 @@ int setup_arg_pages(struct linux_binprm
20327 + bprm->exec -= stack_shift;
20328 +
20329 + down_write(&mm->mmap_sem);
20330 ++
20331 ++ /* Move stack pages down in memory. */
20332 ++ if (stack_shift) {
20333 ++ ret = shift_arg_pages(vma, stack_shift);
20334 ++ if (ret)
20335 ++ goto out_unlock;
20336 ++ }
20337 ++
20338 + vm_flags = vma->vm_flags;
20339 +
20340 + /*
20341 +@@ -634,23 +650,28 @@ int setup_arg_pages(struct linux_binprm
20342 + vm_flags |= VM_EXEC;
20343 + else if (executable_stack == EXSTACK_DISABLE_X)
20344 + vm_flags &= ~VM_EXEC;
20345 ++ else
20346 ++ vm_flags = VM_STACK_FLAGS;
20347 + vm_flags |= mm->def_flags;
20348 +
20349 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20350 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
20351 ++ vm_flags &= ~VM_EXEC;
20352 ++
20353 ++#ifdef CONFIG_PAX_MPROTECT
20354 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
20355 ++ vm_flags &= ~VM_MAYEXEC;
20356 ++#endif
20357 ++
20358 ++ }
20359 ++#endif
20360 ++
20361 + ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
20362 + vm_flags);
20363 + if (ret)
20364 + goto out_unlock;
20365 + BUG_ON(prev != vma);
20366 +
20367 +- /* Move stack pages down in memory. */
20368 +- if (stack_shift) {
20369 +- ret = shift_arg_pages(vma, stack_shift);
20370 +- if (ret) {
20371 +- up_write(&mm->mmap_sem);
20372 +- return ret;
20373 +- }
20374 +- }
20375 +-
20376 + #ifdef CONFIG_STACK_GROWSUP
20377 + stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
20378 + #else
20379 +@@ -662,7 +683,7 @@ int setup_arg_pages(struct linux_binprm
20380 +
20381 + out_unlock:
20382 + up_write(&mm->mmap_sem);
20383 +- return 0;
20384 ++ return ret;
20385 + }
20386 + EXPORT_SYMBOL(setup_arg_pages);
20387 +
20388 +@@ -682,7 +703,7 @@ struct file *open_exec(const char *name)
20389 + file = ERR_PTR(-EACCES);
20390 + if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
20391 + S_ISREG(inode->i_mode)) {
20392 +- int err = vfs_permission(&nd, MAY_EXEC);
20393 ++ err = vfs_permission(&nd, MAY_EXEC);
20394 + file = ERR_PTR(err);
20395 + if (!err) {
20396 + file = nameidata_to_filp(&nd, O_RDONLY);
20397 +@@ -1339,6 +1360,11 @@ int do_execve(char * filename,
20398 + char __user *__user *envp,
20399 + struct pt_regs * regs)
20400 + {
20401 ++#ifdef CONFIG_GRKERNSEC
20402 ++ struct file *old_exec_file;
20403 ++ struct acl_subject_label *old_acl;
20404 ++ struct rlimit old_rlim[RLIM_NLIMITS];
20405 ++#endif
20406 + struct linux_binprm *bprm;
20407 + struct file *file;
20408 + unsigned long env_p;
20409 +@@ -1354,6 +1380,20 @@ int do_execve(char * filename,
20410 + if (IS_ERR(file))
20411 + goto out_kfree;
20412 +
20413 ++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
20414 ++
20415 ++ if (gr_handle_nproc()) {
20416 ++ allow_write_access(file);
20417 ++ fput(file);
20418 ++ return -EAGAIN;
20419 ++ }
20420 ++
20421 ++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
20422 ++ allow_write_access(file);
20423 ++ fput(file);
20424 ++ return -EACCES;
20425 ++ }
20426 ++
20427 + sched_exec();
20428 +
20429 + bprm->file = file;
20430 +@@ -1395,8 +1435,38 @@ int do_execve(char * filename,
20431 + goto out;
20432 + bprm->argv_len = env_p - bprm->p;
20433 +
20434 ++ if (!gr_tpe_allow(file)) {
20435 ++ retval = -EACCES;
20436 ++ goto out;
20437 ++ }
20438 ++
20439 ++ if (gr_check_crash_exec(file)) {
20440 ++ retval = -EACCES;
20441 ++ goto out;
20442 ++ }
20443 ++
20444 ++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
20445 ++
20446 ++ gr_handle_exec_args(bprm, argv);
20447 ++
20448 ++#ifdef CONFIG_GRKERNSEC
20449 ++ old_acl = current->acl;
20450 ++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
20451 ++ old_exec_file = current->exec_file;
20452 ++ get_file(file);
20453 ++ current->exec_file = file;
20454 ++#endif
20455 ++
20456 ++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
20457 ++ if (retval < 0)
20458 ++ goto out_fail;
20459 ++
20460 + retval = search_binary_handler(bprm,regs);
20461 + if (retval >= 0) {
20462 ++#ifdef CONFIG_GRKERNSEC
20463 ++ if (old_exec_file)
20464 ++ fput(old_exec_file);
20465 ++#endif
20466 + /* execve success */
20467 + free_arg_pages(bprm);
20468 + security_bprm_free(bprm);
20469 +@@ -1405,6 +1475,14 @@ int do_execve(char * filename,
20470 + return retval;
20471 + }
20472 +
20473 ++out_fail:
20474 ++#ifdef CONFIG_GRKERNSEC
20475 ++ current->acl = old_acl;
20476 ++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
20477 ++ fput(current->exec_file);
20478 ++ current->exec_file = old_exec_file;
20479 ++#endif
20480 ++
20481 + out:
20482 + free_arg_pages(bprm);
20483 + if (bprm->security)
20484 +@@ -1561,6 +1639,114 @@ out:
20485 + return ispipe;
20486 + }
20487 +
20488 ++int pax_check_flags(unsigned long *flags)
20489 ++{
20490 ++ int retval = 0;
20491 ++
20492 ++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
20493 ++ if (*flags & MF_PAX_SEGMEXEC)
20494 ++ {
20495 ++ *flags &= ~MF_PAX_SEGMEXEC;
20496 ++ retval = -EINVAL;
20497 ++ }
20498 ++#endif
20499 ++
20500 ++ if ((*flags & MF_PAX_PAGEEXEC)
20501 ++
20502 ++#ifdef CONFIG_PAX_PAGEEXEC
20503 ++ && (*flags & MF_PAX_SEGMEXEC)
20504 ++#endif
20505 ++
20506 ++ )
20507 ++ {
20508 ++ *flags &= ~MF_PAX_PAGEEXEC;
20509 ++ retval = -EINVAL;
20510 ++ }
20511 ++
20512 ++ if ((*flags & MF_PAX_MPROTECT)
20513 ++
20514 ++#ifdef CONFIG_PAX_MPROTECT
20515 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
20516 ++#endif
20517 ++
20518 ++ )
20519 ++ {
20520 ++ *flags &= ~MF_PAX_MPROTECT;
20521 ++ retval = -EINVAL;
20522 ++ }
20523 ++
20524 ++ if ((*flags & MF_PAX_EMUTRAMP)
20525 ++
20526 ++#ifdef CONFIG_PAX_EMUTRAMP
20527 ++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
20528 ++#endif
20529 ++
20530 ++ )
20531 ++ {
20532 ++ *flags &= ~MF_PAX_EMUTRAMP;
20533 ++ retval = -EINVAL;
20534 ++ }
20535 ++
20536 ++ return retval;
20537 ++}
20538 ++
20539 ++EXPORT_SYMBOL(pax_check_flags);
20540 ++
20541 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
20542 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
20543 ++{
20544 ++ struct task_struct *tsk = current;
20545 ++ struct mm_struct *mm = current->mm;
20546 ++ char *buffer_exec = (char *)__get_free_page(GFP_ATOMIC);
20547 ++ char *buffer_fault = (char *)__get_free_page(GFP_ATOMIC);
20548 ++ char *path_exec = NULL;
20549 ++ char *path_fault = NULL;
20550 ++ unsigned long start = 0UL, end = 0UL, offset = 0UL;
20551 ++
20552 ++ if (buffer_exec && buffer_fault) {
20553 ++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
20554 ++
20555 ++ down_read(&mm->mmap_sem);
20556 ++ vma = mm->mmap;
20557 ++ while (vma && (!vma_exec || !vma_fault)) {
20558 ++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
20559 ++ vma_exec = vma;
20560 ++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
20561 ++ vma_fault = vma;
20562 ++ vma = vma->vm_next;
20563 ++ }
20564 ++ if (vma_exec) {
20565 ++ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
20566 ++ if (IS_ERR(path_exec))
20567 ++ path_exec = "<path too long>";
20568 ++ }
20569 ++ if (vma_fault) {
20570 ++ start = vma_fault->vm_start;
20571 ++ end = vma_fault->vm_end;
20572 ++ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
20573 ++ if (vma_fault->vm_file) {
20574 ++ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
20575 ++ if (IS_ERR(path_fault))
20576 ++ path_fault = "<path too long>";
20577 ++ } else
20578 ++ path_fault = "<anonymous mapping>";
20579 ++ }
20580 ++ up_read(&mm->mmap_sem);
20581 ++ }
20582 ++ if (tsk->signal->curr_ip)
20583 ++ 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);
20584 ++ else
20585 ++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
20586 ++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
20587 ++ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
20588 ++ tsk->uid, tsk->euid, pc, sp);
20589 ++ free_page((unsigned long)buffer_exec);
20590 ++ free_page((unsigned long)buffer_fault);
20591 ++ pax_report_insns(pc, sp);
20592 ++ do_coredump(SIGKILL, SIGKILL, regs);
20593 ++}
20594 ++#endif
20595 ++
20596 + static void zap_process(struct task_struct *start)
20597 + {
20598 + struct task_struct *t;
20599 +@@ -1753,6 +1939,10 @@ int do_coredump(long signr, int exit_cod
20600 + */
20601 + clear_thread_flag(TIF_SIGPENDING);
20602 +
20603 ++ if (signr == SIGKILL || signr == SIGILL)
20604 ++ gr_handle_brute_attach(current);
20605 ++
20606 ++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
20607 + if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
20608 + goto fail_unlock;
20609 +
20610 +diff -Nurp linux-2.6.23.15/fs/ext2/balloc.c linux-2.6.23.15-grsec/fs/ext2/balloc.c
20611 +--- linux-2.6.23.15/fs/ext2/balloc.c 2007-10-09 21:31:38.000000000 +0100
20612 ++++ linux-2.6.23.15-grsec/fs/ext2/balloc.c 2008-02-11 10:37:44.000000000 +0000
20613 +@@ -111,7 +111,7 @@ static int reserve_blocks(struct super_b
20614 + if (free_blocks < count)
20615 + count = free_blocks;
20616 +
20617 +- if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
20618 ++ if (free_blocks < root_blocks + count && !capable_nolog(CAP_SYS_RESOURCE) &&
20619 + sbi->s_resuid != current->fsuid &&
20620 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20621 + /*
20622 +diff -Nurp linux-2.6.23.15/fs/ext3/balloc.c linux-2.6.23.15-grsec/fs/ext3/balloc.c
20623 +--- linux-2.6.23.15/fs/ext3/balloc.c 2007-10-09 21:31:38.000000000 +0100
20624 ++++ linux-2.6.23.15-grsec/fs/ext3/balloc.c 2008-02-11 10:37:44.000000000 +0000
20625 +@@ -1359,7 +1359,7 @@ static int ext3_has_free_blocks(struct e
20626 +
20627 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20628 + root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
20629 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20630 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20631 + sbi->s_resuid != current->fsuid &&
20632 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20633 + return 0;
20634 +diff -Nurp linux-2.6.23.15/fs/ext3/namei.c linux-2.6.23.15-grsec/fs/ext3/namei.c
20635 +--- linux-2.6.23.15/fs/ext3/namei.c 2007-10-09 21:31:38.000000000 +0100
20636 ++++ linux-2.6.23.15-grsec/fs/ext3/namei.c 2008-02-11 10:37:44.000000000 +0000
20637 +@@ -1188,9 +1188,9 @@ static struct ext3_dir_entry_2 *do_split
20638 + u32 hash2;
20639 + struct dx_map_entry *map;
20640 + char *data1 = (*bh)->b_data, *data2;
20641 +- unsigned split, move, size, i;
20642 ++ unsigned split, move, size;
20643 + struct ext3_dir_entry_2 *de = NULL, *de2;
20644 +- int err = 0;
20645 ++ int i, err = 0;
20646 +
20647 + bh2 = ext3_append (handle, dir, &newblock, &err);
20648 + if (!(bh2)) {
20649 +diff -Nurp linux-2.6.23.15/fs/ext3/xattr.c linux-2.6.23.15-grsec/fs/ext3/xattr.c
20650 +--- linux-2.6.23.15/fs/ext3/xattr.c 2007-10-09 21:31:38.000000000 +0100
20651 ++++ linux-2.6.23.15-grsec/fs/ext3/xattr.c 2008-02-11 10:37:44.000000000 +0000
20652 +@@ -89,8 +89,8 @@
20653 + printk("\n"); \
20654 + } while (0)
20655 + #else
20656 +-# define ea_idebug(f...)
20657 +-# define ea_bdebug(f...)
20658 ++# define ea_idebug(f...) do {} while (0)
20659 ++# define ea_bdebug(f...) do {} while (0)
20660 + #endif
20661 +
20662 + static void ext3_xattr_cache_insert(struct buffer_head *);
20663 +diff -Nurp linux-2.6.23.15/fs/ext4/balloc.c linux-2.6.23.15-grsec/fs/ext4/balloc.c
20664 +--- linux-2.6.23.15/fs/ext4/balloc.c 2007-10-09 21:31:38.000000000 +0100
20665 ++++ linux-2.6.23.15-grsec/fs/ext4/balloc.c 2008-02-11 10:37:44.000000000 +0000
20666 +@@ -1376,7 +1376,7 @@ static int ext4_has_free_blocks(struct e
20667 +
20668 + free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
20669 + root_blocks = ext4_r_blocks_count(sbi->s_es);
20670 +- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
20671 ++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
20672 + sbi->s_resuid != current->fsuid &&
20673 + (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
20674 + return 0;
20675 +diff -Nurp linux-2.6.23.15/fs/ext4/namei.c linux-2.6.23.15-grsec/fs/ext4/namei.c
20676 +--- linux-2.6.23.15/fs/ext4/namei.c 2007-10-09 21:31:38.000000000 +0100
20677 ++++ linux-2.6.23.15-grsec/fs/ext4/namei.c 2008-02-11 10:37:44.000000000 +0000
20678 +@@ -1186,9 +1186,9 @@ static struct ext4_dir_entry_2 *do_split
20679 + u32 hash2;
20680 + struct dx_map_entry *map;
20681 + char *data1 = (*bh)->b_data, *data2;
20682 +- unsigned split, move, size, i;
20683 ++ unsigned split, move, size;
20684 + struct ext4_dir_entry_2 *de = NULL, *de2;
20685 +- int err = 0;
20686 ++ int i, err = 0;
20687 +
20688 + bh2 = ext4_append (handle, dir, &newblock, &err);
20689 + if (!(bh2)) {
20690 +diff -Nurp linux-2.6.23.15/fs/fcntl.c linux-2.6.23.15-grsec/fs/fcntl.c
20691 +--- linux-2.6.23.15/fs/fcntl.c 2007-10-09 21:31:38.000000000 +0100
20692 ++++ linux-2.6.23.15-grsec/fs/fcntl.c 2008-02-11 10:37:44.000000000 +0000
20693 +@@ -18,6 +18,7 @@
20694 + #include <linux/ptrace.h>
20695 + #include <linux/signal.h>
20696 + #include <linux/rcupdate.h>
20697 ++#include <linux/grsecurity.h>
20698 +
20699 + #include <asm/poll.h>
20700 + #include <asm/siginfo.h>
20701 +@@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
20702 + struct fdtable *fdt;
20703 +
20704 + error = -EINVAL;
20705 ++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
20706 + if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20707 + goto out;
20708 +
20709 +@@ -82,6 +84,7 @@ repeat:
20710 + fdt->max_fds, start);
20711 +
20712 + error = -EMFILE;
20713 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
20714 + if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
20715 + goto out;
20716 +
20717 +@@ -140,6 +143,8 @@ asmlinkage long sys_dup2(unsigned int ol
20718 + struct files_struct * files = current->files;
20719 + struct fdtable *fdt;
20720 +
20721 ++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
20722 ++
20723 + spin_lock(&files->file_lock);
20724 + if (!(file = fcheck(oldfd)))
20725 + goto out_unlock;
20726 +@@ -458,7 +463,8 @@ static inline int sigio_perm(struct task
20727 + return (((fown->euid == 0) ||
20728 + (fown->euid == p->suid) || (fown->euid == p->uid) ||
20729 + (fown->uid == p->suid) || (fown->uid == p->uid)) &&
20730 +- !security_file_send_sigiotask(p, fown, sig));
20731 ++ !security_file_send_sigiotask(p, fown, sig) &&
20732 ++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
20733 + }
20734 +
20735 + static void send_sigio_to_task(struct task_struct *p,
20736 +diff -Nurp linux-2.6.23.15/fs/fuse/control.c linux-2.6.23.15-grsec/fs/fuse/control.c
20737 +--- linux-2.6.23.15/fs/fuse/control.c 2007-10-09 21:31:38.000000000 +0100
20738 ++++ linux-2.6.23.15-grsec/fs/fuse/control.c 2008-02-11 10:37:44.000000000 +0000
20739 +@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
20740 +
20741 + static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
20742 + {
20743 +- struct tree_descr empty_descr = {""};
20744 ++ struct tree_descr empty_descr = {"", NULL, 0};
20745 + struct fuse_conn *fc;
20746 + int err;
20747 +
20748 +diff -Nurp linux-2.6.23.15/fs/hfs/inode.c linux-2.6.23.15-grsec/fs/hfs/inode.c
20749 +--- linux-2.6.23.15/fs/hfs/inode.c 2007-10-09 21:31:38.000000000 +0100
20750 ++++ linux-2.6.23.15-grsec/fs/hfs/inode.c 2008-02-11 10:37:44.000000000 +0000
20751 +@@ -415,7 +415,7 @@ int hfs_write_inode(struct inode *inode,
20752 +
20753 + if (S_ISDIR(main_inode->i_mode)) {
20754 + if (fd.entrylength < sizeof(struct hfs_cat_dir))
20755 +- /* panic? */;
20756 ++ {/* panic? */}
20757 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
20758 + sizeof(struct hfs_cat_dir));
20759 + if (rec.type != HFS_CDR_DIR ||
20760 +@@ -436,7 +436,7 @@ int hfs_write_inode(struct inode *inode,
20761 + sizeof(struct hfs_cat_file));
20762 + } else {
20763 + if (fd.entrylength < sizeof(struct hfs_cat_file))
20764 +- /* panic? */;
20765 ++ {/* panic? */}
20766 + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
20767 + sizeof(struct hfs_cat_file));
20768 + if (rec.type != HFS_CDR_FIL ||
20769 +diff -Nurp linux-2.6.23.15/fs/hfsplus/inode.c linux-2.6.23.15-grsec/fs/hfsplus/inode.c
20770 +--- linux-2.6.23.15/fs/hfsplus/inode.c 2007-10-09 21:31:38.000000000 +0100
20771 ++++ linux-2.6.23.15-grsec/fs/hfsplus/inode.c 2008-02-11 10:37:44.000000000 +0000
20772 +@@ -418,7 +418,7 @@ int hfsplus_cat_read_inode(struct inode
20773 + struct hfsplus_cat_folder *folder = &entry.folder;
20774 +
20775 + if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
20776 +- /* panic? */;
20777 ++ {/* panic? */}
20778 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
20779 + sizeof(struct hfsplus_cat_folder));
20780 + hfsplus_get_perms(inode, &folder->permissions, 1);
20781 +@@ -435,7 +435,7 @@ int hfsplus_cat_read_inode(struct inode
20782 + struct hfsplus_cat_file *file = &entry.file;
20783 +
20784 + if (fd->entrylength < sizeof(struct hfsplus_cat_file))
20785 +- /* panic? */;
20786 ++ {/* panic? */}
20787 + hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
20788 + sizeof(struct hfsplus_cat_file));
20789 +
20790 +@@ -491,7 +491,7 @@ int hfsplus_cat_write_inode(struct inode
20791 + struct hfsplus_cat_folder *folder = &entry.folder;
20792 +
20793 + if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
20794 +- /* panic? */;
20795 ++ {/* panic? */}
20796 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
20797 + sizeof(struct hfsplus_cat_folder));
20798 + /* simple node checks? */
20799 +@@ -513,7 +513,7 @@ int hfsplus_cat_write_inode(struct inode
20800 + struct hfsplus_cat_file *file = &entry.file;
20801 +
20802 + if (fd.entrylength < sizeof(struct hfsplus_cat_file))
20803 +- /* panic? */;
20804 ++ {/* panic? */}
20805 + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
20806 + sizeof(struct hfsplus_cat_file));
20807 + hfsplus_inode_write_fork(inode, &file->data_fork);
20808 +diff -Nurp linux-2.6.23.15/fs/jffs2/debug.h linux-2.6.23.15-grsec/fs/jffs2/debug.h
20809 +--- linux-2.6.23.15/fs/jffs2/debug.h 2007-10-09 21:31:38.000000000 +0100
20810 ++++ linux-2.6.23.15-grsec/fs/jffs2/debug.h 2008-02-11 10:37:44.000000000 +0000
20811 +@@ -51,13 +51,13 @@
20812 + #if CONFIG_JFFS2_FS_DEBUG > 0
20813 + #define D1(x) x
20814 + #else
20815 +-#define D1(x)
20816 ++#define D1(x) do {} while (0);
20817 + #endif
20818 +
20819 + #if CONFIG_JFFS2_FS_DEBUG > 1
20820 + #define D2(x) x
20821 + #else
20822 +-#define D2(x)
20823 ++#define D2(x) do {} while (0);
20824 + #endif
20825 +
20826 + /* The prefixes of JFFS2 messages */
20827 +@@ -113,68 +113,68 @@
20828 + #ifdef JFFS2_DBG_READINODE_MESSAGES
20829 + #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20830 + #else
20831 +-#define dbg_readinode(fmt, ...)
20832 ++#define dbg_readinode(fmt, ...) do {} while (0)
20833 + #endif
20834 +
20835 + /* Fragtree build debugging messages */
20836 + #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
20837 + #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20838 + #else
20839 +-#define dbg_fragtree(fmt, ...)
20840 ++#define dbg_fragtree(fmt, ...) do {} while (0)
20841 + #endif
20842 + #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
20843 + #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20844 + #else
20845 +-#define dbg_fragtree2(fmt, ...)
20846 ++#define dbg_fragtree2(fmt, ...) do {} while (0)
20847 + #endif
20848 +
20849 + /* Directory entry list manilulation debugging messages */
20850 + #ifdef JFFS2_DBG_DENTLIST_MESSAGES
20851 + #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20852 + #else
20853 +-#define dbg_dentlist(fmt, ...)
20854 ++#define dbg_dentlist(fmt, ...) do {} while (0)
20855 + #endif
20856 +
20857 + /* Print the messages about manipulating node_refs */
20858 + #ifdef JFFS2_DBG_NODEREF_MESSAGES
20859 + #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20860 + #else
20861 +-#define dbg_noderef(fmt, ...)
20862 ++#define dbg_noderef(fmt, ...) do {} while (0)
20863 + #endif
20864 +
20865 + /* Manipulations with the list of inodes (JFFS2 inocache) */
20866 + #ifdef JFFS2_DBG_INOCACHE_MESSAGES
20867 + #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20868 + #else
20869 +-#define dbg_inocache(fmt, ...)
20870 ++#define dbg_inocache(fmt, ...) do {} while (0)
20871 + #endif
20872 +
20873 + /* Summary debugging messages */
20874 + #ifdef JFFS2_DBG_SUMMARY_MESSAGES
20875 + #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20876 + #else
20877 +-#define dbg_summary(fmt, ...)
20878 ++#define dbg_summary(fmt, ...) do {} while (0)
20879 + #endif
20880 +
20881 + /* File system build messages */
20882 + #ifdef JFFS2_DBG_FSBUILD_MESSAGES
20883 + #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20884 + #else
20885 +-#define dbg_fsbuild(fmt, ...)
20886 ++#define dbg_fsbuild(fmt, ...) do {} while (0)
20887 + #endif
20888 +
20889 + /* Watch the object allocations */
20890 + #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
20891 + #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20892 + #else
20893 +-#define dbg_memalloc(fmt, ...)
20894 ++#define dbg_memalloc(fmt, ...) do {} while (0)
20895 + #endif
20896 +
20897 + /* Watch the XATTR subsystem */
20898 + #ifdef JFFS2_DBG_XATTR_MESSAGES
20899 + #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
20900 + #else
20901 +-#define dbg_xattr(fmt, ...)
20902 ++#define dbg_xattr(fmt, ...) do {} while (0)
20903 + #endif
20904 +
20905 + /* "Sanity" checks */
20906 +diff -Nurp linux-2.6.23.15/fs/jffs2/erase.c linux-2.6.23.15-grsec/fs/jffs2/erase.c
20907 +--- linux-2.6.23.15/fs/jffs2/erase.c 2007-10-09 21:31:38.000000000 +0100
20908 ++++ linux-2.6.23.15-grsec/fs/jffs2/erase.c 2008-02-11 10:37:44.000000000 +0000
20909 +@@ -389,7 +389,8 @@ static void jffs2_mark_erased_block(stru
20910 + struct jffs2_unknown_node marker = {
20911 + .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
20912 + .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
20913 +- .totlen = cpu_to_je32(c->cleanmarker_size)
20914 ++ .totlen = cpu_to_je32(c->cleanmarker_size),
20915 ++ .hdr_crc = cpu_to_je32(0)
20916 + };
20917 +
20918 + jffs2_prealloc_raw_node_refs(c, jeb, 1);
20919 +diff -Nurp linux-2.6.23.15/fs/jffs2/summary.h linux-2.6.23.15-grsec/fs/jffs2/summary.h
20920 +--- linux-2.6.23.15/fs/jffs2/summary.h 2007-10-09 21:31:38.000000000 +0100
20921 ++++ linux-2.6.23.15-grsec/fs/jffs2/summary.h 2008-02-11 10:37:44.000000000 +0000
20922 +@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
20923 +
20924 + #define jffs2_sum_active() (0)
20925 + #define jffs2_sum_init(a) (0)
20926 +-#define jffs2_sum_exit(a)
20927 +-#define jffs2_sum_disable_collecting(a)
20928 ++#define jffs2_sum_exit(a) do {} while (0)
20929 ++#define jffs2_sum_disable_collecting(a) do {} while (0)
20930 + #define jffs2_sum_is_disabled(a) (0)
20931 +-#define jffs2_sum_reset_collected(a)
20932 ++#define jffs2_sum_reset_collected(a) do {} while (0)
20933 + #define jffs2_sum_add_kvec(a,b,c,d) (0)
20934 +-#define jffs2_sum_move_collected(a,b)
20935 ++#define jffs2_sum_move_collected(a,b) do {} while (0)
20936 + #define jffs2_sum_write_sumnode(a) (0)
20937 +-#define jffs2_sum_add_padding_mem(a,b)
20938 +-#define jffs2_sum_add_inode_mem(a,b,c)
20939 +-#define jffs2_sum_add_dirent_mem(a,b,c)
20940 +-#define jffs2_sum_add_xattr_mem(a,b,c)
20941 +-#define jffs2_sum_add_xref_mem(a,b,c)
20942 ++#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
20943 ++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
20944 ++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
20945 ++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
20946 ++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
20947 + #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
20948 +
20949 + #endif /* CONFIG_JFFS2_SUMMARY */
20950 +diff -Nurp linux-2.6.23.15/fs/jffs2/wbuf.c linux-2.6.23.15-grsec/fs/jffs2/wbuf.c
20951 +--- linux-2.6.23.15/fs/jffs2/wbuf.c 2007-10-09 21:31:38.000000000 +0100
20952 ++++ linux-2.6.23.15-grsec/fs/jffs2/wbuf.c 2008-02-11 10:37:44.000000000 +0000
20953 +@@ -973,7 +973,8 @@ static const struct jffs2_unknown_node o
20954 + {
20955 + .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
20956 + .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
20957 +- .totlen = constant_cpu_to_je32(8)
20958 ++ .totlen = constant_cpu_to_je32(8),
20959 ++ .hdr_crc = constant_cpu_to_je32(0)
20960 + };
20961 +
20962 + /*
20963 +diff -Nurp linux-2.6.23.15/fs/namei.c linux-2.6.23.15-grsec/fs/namei.c
20964 +--- linux-2.6.23.15/fs/namei.c 2008-02-11 10:36:03.000000000 +0000
20965 ++++ linux-2.6.23.15-grsec/fs/namei.c 2008-02-11 10:37:44.000000000 +0000
20966 +@@ -31,6 +31,7 @@
20967 + #include <linux/file.h>
20968 + #include <linux/fcntl.h>
20969 + #include <linux/namei.h>
20970 ++#include <linux/grsecurity.h>
20971 + #include <asm/namei.h>
20972 + #include <asm/uaccess.h>
20973 +
20974 +@@ -638,6 +639,13 @@ static inline int do_follow_link(struct
20975 + err = security_inode_follow_link(path->dentry, nd);
20976 + if (err)
20977 + goto loop;
20978 ++
20979 ++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
20980 ++ path->dentry->d_inode, path->dentry, nd->mnt)) {
20981 ++ err = -EACCES;
20982 ++ goto loop;
20983 ++ }
20984 ++
20985 + current->link_count++;
20986 + current->total_link_count++;
20987 + nd->depth++;
20988 +@@ -983,11 +991,18 @@ return_reval:
20989 + break;
20990 + }
20991 + return_base:
20992 ++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
20993 ++ path_release(nd);
20994 ++ return -ENOENT;
20995 ++ }
20996 + return 0;
20997 + out_dput:
20998 + dput_path(&next, nd);
20999 + break;
21000 + }
21001 ++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
21002 ++ err = -ENOENT;
21003 ++
21004 + path_release(nd);
21005 + return_err:
21006 + return err;
21007 +@@ -1649,9 +1664,17 @@ static int open_namei_create(struct name
21008 + int error;
21009 + struct dentry *dir = nd->dentry;
21010 +
21011 ++ if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
21012 ++ error = -EACCES;
21013 ++ goto out_unlock_dput;
21014 ++ }
21015 ++
21016 + if (!IS_POSIXACL(dir->d_inode))
21017 + mode &= ~current->fs->umask;
21018 + error = vfs_create(dir->d_inode, path->dentry, mode, nd);
21019 ++ if (!error)
21020 ++ gr_handle_create(path->dentry, nd->mnt);
21021 ++out_unlock_dput:
21022 + mutex_unlock(&dir->d_inode->i_mutex);
21023 + dput(nd->dentry);
21024 + nd->dentry = path->dentry;
21025 +@@ -1702,6 +1725,17 @@ int open_namei(int dfd, const char *path
21026 + nd, flag);
21027 + if (error)
21028 + return error;
21029 ++
21030 ++ if (gr_handle_rawio(nd->dentry->d_inode)) {
21031 ++ error = -EPERM;
21032 ++ goto exit;
21033 ++ }
21034 ++
21035 ++ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
21036 ++ error = -EACCES;
21037 ++ goto exit;
21038 ++ }
21039 ++
21040 + goto ok;
21041 + }
21042 +
21043 +@@ -1751,6 +1785,23 @@ do_last:
21044 + /*
21045 + * It already exists.
21046 + */
21047 ++
21048 ++ if (gr_handle_rawio(path.dentry->d_inode)) {
21049 ++ mutex_unlock(&dir->d_inode->i_mutex);
21050 ++ error = -EPERM;
21051 ++ goto exit_dput;
21052 ++ }
21053 ++ if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
21054 ++ mutex_unlock(&dir->d_inode->i_mutex);
21055 ++ error = -EACCES;
21056 ++ goto exit_dput;
21057 ++ }
21058 ++ if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
21059 ++ mutex_unlock(&dir->d_inode->i_mutex);
21060 ++ error = -EACCES;
21061 ++ goto exit_dput;
21062 ++ }
21063 ++
21064 + mutex_unlock(&dir->d_inode->i_mutex);
21065 + audit_inode(pathname, path.dentry->d_inode);
21066 +
21067 +@@ -1806,6 +1857,13 @@ do_link:
21068 + error = security_inode_follow_link(path.dentry, nd);
21069 + if (error)
21070 + goto exit_dput;
21071 ++
21072 ++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
21073 ++ path.dentry, nd->mnt)) {
21074 ++ error = -EACCES;
21075 ++ goto exit_dput;
21076 ++ }
21077 ++
21078 + error = __do_follow_link(&path, nd);
21079 + if (error) {
21080 + /* Does someone understand code flow here? Or it is only
21081 +@@ -1934,6 +1992,22 @@ asmlinkage long sys_mknodat(int dfd, con
21082 + if (!IS_POSIXACL(nd.dentry->d_inode))
21083 + mode &= ~current->fs->umask;
21084 + if (!IS_ERR(dentry)) {
21085 ++ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
21086 ++ error = -EPERM;
21087 ++ dput(dentry);
21088 ++ mutex_unlock(&nd.dentry->d_inode->i_mutex);
21089 ++ path_release(&nd);
21090 ++ goto out;
21091 ++ }
21092 ++
21093 ++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
21094 ++ error = -EACCES;
21095 ++ dput(dentry);
21096 ++ mutex_unlock(&nd.dentry->d_inode->i_mutex);
21097 ++ path_release(&nd);
21098 ++ goto out;
21099 ++ }
21100 ++
21101 + switch (mode & S_IFMT) {
21102 + case 0: case S_IFREG:
21103 + error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
21104 +@@ -1951,6 +2025,10 @@ asmlinkage long sys_mknodat(int dfd, con
21105 + default:
21106 + error = -EINVAL;
21107 + }
21108 ++
21109 ++ if (!error)
21110 ++ gr_handle_create(dentry, nd.mnt);
21111 ++
21112 + dput(dentry);
21113 + }
21114 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
21115 +@@ -2008,9 +2086,18 @@ asmlinkage long sys_mkdirat(int dfd, con
21116 + if (IS_ERR(dentry))
21117 + goto out_unlock;
21118 +
21119 ++ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
21120 ++ error = -EACCES;
21121 ++ goto out_unlock_dput;
21122 ++ }
21123 ++
21124 + if (!IS_POSIXACL(nd.dentry->d_inode))
21125 + mode &= ~current->fs->umask;
21126 + error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
21127 ++
21128 ++ if (!error)
21129 ++ gr_handle_create(dentry, nd.mnt);
21130 ++out_unlock_dput:
21131 + dput(dentry);
21132 + out_unlock:
21133 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
21134 +@@ -2092,6 +2179,8 @@ static long do_rmdir(int dfd, const char
21135 + char * name;
21136 + struct dentry *dentry;
21137 + struct nameidata nd;
21138 ++ ino_t saved_ino = 0;
21139 ++ dev_t saved_dev = 0;
21140 +
21141 + name = getname(pathname);
21142 + if(IS_ERR(name))
21143 +@@ -2117,7 +2206,22 @@ static long do_rmdir(int dfd, const char
21144 + error = PTR_ERR(dentry);
21145 + if (IS_ERR(dentry))
21146 + goto exit2;
21147 ++
21148 ++ if (dentry->d_inode != NULL) {
21149 ++ if (dentry->d_inode->i_nlink <= 1) {
21150 ++ saved_ino = dentry->d_inode->i_ino;
21151 ++ saved_dev = dentry->d_inode->i_sb->s_dev;
21152 ++ }
21153 ++
21154 ++ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
21155 ++ error = -EACCES;
21156 ++ goto dput_exit2;
21157 ++ }
21158 ++ }
21159 + error = vfs_rmdir(nd.dentry->d_inode, dentry);
21160 ++ if (!error && (saved_dev || saved_ino))
21161 ++ gr_handle_delete(saved_ino, saved_dev);
21162 ++dput_exit2:
21163 + dput(dentry);
21164 + exit2:
21165 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
21166 +@@ -2176,6 +2280,8 @@ static long do_unlinkat(int dfd, const c
21167 + struct dentry *dentry;
21168 + struct nameidata nd;
21169 + struct inode *inode = NULL;
21170 ++ ino_t saved_ino = 0;
21171 ++ dev_t saved_dev = 0;
21172 +
21173 + name = getname(pathname);
21174 + if(IS_ERR(name))
21175 +@@ -2191,13 +2297,26 @@ static long do_unlinkat(int dfd, const c
21176 + dentry = lookup_hash(&nd);
21177 + error = PTR_ERR(dentry);
21178 + if (!IS_ERR(dentry)) {
21179 ++ error = 0;
21180 + /* Why not before? Because we want correct error value */
21181 + if (nd.last.name[nd.last.len])
21182 + goto slashes;
21183 + inode = dentry->d_inode;
21184 +- if (inode)
21185 ++ if (inode) {
21186 ++ if (inode->i_nlink <= 1) {
21187 ++ saved_ino = inode->i_ino;
21188 ++ saved_dev = inode->i_sb->s_dev;
21189 ++ }
21190 ++
21191 ++ if (!gr_acl_handle_unlink(dentry, nd.mnt))
21192 ++ error = -EACCES;
21193 ++
21194 + atomic_inc(&inode->i_count);
21195 +- error = vfs_unlink(nd.dentry->d_inode, dentry);
21196 ++ }
21197 ++ if (!error)
21198 ++ error = vfs_unlink(nd.dentry->d_inode, dentry);
21199 ++ if (!error && (saved_ino || saved_dev))
21200 ++ gr_handle_delete(saved_ino, saved_dev);
21201 + exit2:
21202 + dput(dentry);
21203 + }
21204 +@@ -2278,7 +2397,16 @@ asmlinkage long sys_symlinkat(const char
21205 + if (IS_ERR(dentry))
21206 + goto out_unlock;
21207 +
21208 ++ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
21209 ++ error = -EACCES;
21210 ++ goto out_dput_unlock;
21211 ++ }
21212 ++
21213 + error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
21214 ++
21215 ++ if (!error)
21216 ++ gr_handle_create(dentry, nd.mnt);
21217 ++out_dput_unlock:
21218 + dput(dentry);
21219 + out_unlock:
21220 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
21221 +@@ -2373,7 +2501,25 @@ asmlinkage long sys_linkat(int olddfd, c
21222 + error = PTR_ERR(new_dentry);
21223 + if (IS_ERR(new_dentry))
21224 + goto out_unlock;
21225 ++
21226 ++ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
21227 ++ old_nd.dentry->d_inode,
21228 ++ old_nd.dentry->d_inode->i_mode, to)) {
21229 ++ error = -EACCES;
21230 ++ goto out_unlock_dput;
21231 ++ }
21232 ++
21233 ++ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
21234 ++ old_nd.dentry, old_nd.mnt, to)) {
21235 ++ error = -EACCES;
21236 ++ goto out_unlock_dput;
21237 ++ }
21238 ++
21239 + error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
21240 ++
21241 ++ if (!error)
21242 ++ gr_handle_create(new_dentry, nd.mnt);
21243 ++out_unlock_dput:
21244 + dput(new_dentry);
21245 + out_unlock:
21246 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
21247 +@@ -2599,8 +2745,16 @@ static int do_rename(int olddfd, const c
21248 + if (new_dentry == trap)
21249 + goto exit5;
21250 +
21251 +- error = vfs_rename(old_dir->d_inode, old_dentry,
21252 ++ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
21253 ++ old_dentry, old_dir->d_inode, oldnd.mnt,
21254 ++ newname);
21255 ++
21256 ++ if (!error)
21257 ++ error = vfs_rename(old_dir->d_inode, old_dentry,
21258 + new_dir->d_inode, new_dentry);
21259 ++ if (!error)
21260 ++ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
21261 ++ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
21262 + exit5:
21263 + dput(new_dentry);
21264 + exit4:
21265 +diff -Nurp linux-2.6.23.15/fs/namespace.c linux-2.6.23.15-grsec/fs/namespace.c
21266 +--- linux-2.6.23.15/fs/namespace.c 2007-10-09 21:31:38.000000000 +0100
21267 ++++ linux-2.6.23.15-grsec/fs/namespace.c 2008-02-11 10:37:44.000000000 +0000
21268 +@@ -25,6 +25,7 @@
21269 + #include <linux/security.h>
21270 + #include <linux/mount.h>
21271 + #include <linux/ramfs.h>
21272 ++#include <linux/grsecurity.h>
21273 + #include <asm/uaccess.h>
21274 + #include <asm/unistd.h>
21275 + #include "pnode.h"
21276 +@@ -597,6 +598,8 @@ static int do_umount(struct vfsmount *mn
21277 + DQUOT_OFF(sb);
21278 + retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
21279 + unlock_kernel();
21280 ++
21281 ++ gr_log_remount(mnt->mnt_devname, retval);
21282 + }
21283 + up_write(&sb->s_umount);
21284 + return retval;
21285 +@@ -617,6 +620,9 @@ static int do_umount(struct vfsmount *mn
21286 + security_sb_umount_busy(mnt);
21287 + up_write(&namespace_sem);
21288 + release_mounts(&umount_list);
21289 ++
21290 ++ gr_log_unmount(mnt->mnt_devname, retval);
21291 ++
21292 + return retval;
21293 + }
21294 +
21295 +@@ -1422,6 +1428,11 @@ long do_mount(char *dev_name, char *dir_
21296 + if (retval)
21297 + goto dput_out;
21298 +
21299 ++ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
21300 ++ retval = -EPERM;
21301 ++ goto dput_out;
21302 ++ }
21303 ++
21304 + if (flags & MS_REMOUNT)
21305 + retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
21306 + data_page);
21307 +@@ -1436,6 +1447,9 @@ long do_mount(char *dev_name, char *dir_
21308 + dev_name, data_page);
21309 + dput_out:
21310 + path_release(&nd);
21311 ++
21312 ++ gr_log_mount(dev_name, dir_name, retval);
21313 ++
21314 + return retval;
21315 + }
21316 +
21317 +@@ -1673,6 +1687,9 @@ asmlinkage long sys_pivot_root(const cha
21318 + if (!capable(CAP_SYS_ADMIN))
21319 + return -EPERM;
21320 +
21321 ++ if (gr_handle_chroot_pivot())
21322 ++ return -EPERM;
21323 ++
21324 + lock_kernel();
21325 +
21326 + error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
21327 +diff -Nurp linux-2.6.23.15/fs/nfs/callback_xdr.c linux-2.6.23.15-grsec/fs/nfs/callback_xdr.c
21328 +--- linux-2.6.23.15/fs/nfs/callback_xdr.c 2007-10-09 21:31:38.000000000 +0100
21329 ++++ linux-2.6.23.15-grsec/fs/nfs/callback_xdr.c 2008-02-11 10:37:44.000000000 +0000
21330 +@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
21331 + if (unlikely(status != 0))
21332 + return status;
21333 + /* We do not like overly long tags! */
21334 +- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
21335 ++ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
21336 + printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
21337 + __FUNCTION__, hdr->taglen);
21338 + return htonl(NFS4ERR_RESOURCE);
21339 +diff -Nurp linux-2.6.23.15/fs/nfs/nfs4proc.c linux-2.6.23.15-grsec/fs/nfs/nfs4proc.c
21340 +--- linux-2.6.23.15/fs/nfs/nfs4proc.c 2007-10-09 21:31:38.000000000 +0100
21341 ++++ linux-2.6.23.15-grsec/fs/nfs/nfs4proc.c 2008-02-11 10:37:44.000000000 +0000
21342 +@@ -657,7 +657,7 @@ static int _nfs4_do_open_reclaim(struct
21343 + static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
21344 + {
21345 + struct nfs_server *server = NFS_SERVER(state->inode);
21346 +- struct nfs4_exception exception = { };
21347 ++ struct nfs4_exception exception = {0, 0};
21348 + int err;
21349 + do {
21350 + err = _nfs4_do_open_reclaim(ctx, state);
21351 +@@ -699,7 +699,7 @@ static int _nfs4_open_delegation_recall(
21352 +
21353 + int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
21354 + {
21355 +- struct nfs4_exception exception = { };
21356 ++ struct nfs4_exception exception = {0, 0};
21357 + struct nfs_server *server = NFS_SERVER(state->inode);
21358 + int err;
21359 + do {
21360 +@@ -1020,7 +1020,7 @@ static int _nfs4_open_expired(struct nfs
21361 + static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
21362 + {
21363 + struct nfs_server *server = NFS_SERVER(state->inode);
21364 +- struct nfs4_exception exception = { };
21365 ++ struct nfs4_exception exception = {0, 0};
21366 + int err;
21367 +
21368 + do {
21369 +@@ -1122,7 +1122,7 @@ out_err:
21370 +
21371 + static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
21372 + {
21373 +- struct nfs4_exception exception = { };
21374 ++ struct nfs4_exception exception = {0, 0};
21375 + struct nfs4_state *res;
21376 + int status;
21377 +
21378 +@@ -1211,7 +1211,7 @@ static int nfs4_do_setattr(struct inode
21379 + struct iattr *sattr, struct nfs4_state *state)
21380 + {
21381 + struct nfs_server *server = NFS_SERVER(inode);
21382 +- struct nfs4_exception exception = { };
21383 ++ struct nfs4_exception exception = {0, 0};
21384 + int err;
21385 + do {
21386 + err = nfs4_handle_exception(server,
21387 +@@ -1504,7 +1504,7 @@ static int _nfs4_server_capabilities(str
21388 +
21389 + int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
21390 + {
21391 +- struct nfs4_exception exception = { };
21392 ++ struct nfs4_exception exception = {0, 0};
21393 + int err;
21394 + do {
21395 + err = nfs4_handle_exception(server,
21396 +@@ -1537,7 +1537,7 @@ static int _nfs4_lookup_root(struct nfs_
21397 + static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
21398 + struct nfs_fsinfo *info)
21399 + {
21400 +- struct nfs4_exception exception = { };
21401 ++ struct nfs4_exception exception = {0, 0};
21402 + int err;
21403 + do {
21404 + err = nfs4_handle_exception(server,
21405 +@@ -1626,7 +1626,7 @@ static int _nfs4_proc_getattr(struct nfs
21406 +
21407 + static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
21408 + {
21409 +- struct nfs4_exception exception = { };
21410 ++ struct nfs4_exception exception = {0, 0};
21411 + int err;
21412 + do {
21413 + err = nfs4_handle_exception(server,
21414 +@@ -1716,7 +1716,7 @@ static int nfs4_proc_lookupfh(struct nfs
21415 + struct qstr *name, struct nfs_fh *fhandle,
21416 + struct nfs_fattr *fattr)
21417 + {
21418 +- struct nfs4_exception exception = { };
21419 ++ struct nfs4_exception exception = {0, 0};
21420 + int err;
21421 + do {
21422 + err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
21423 +@@ -1745,7 +1745,7 @@ static int _nfs4_proc_lookup(struct inod
21424 +
21425 + static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
21426 + {
21427 +- struct nfs4_exception exception = { };
21428 ++ struct nfs4_exception exception = {0, 0};
21429 + int err;
21430 + do {
21431 + err = nfs4_handle_exception(NFS_SERVER(dir),
21432 +@@ -1801,7 +1801,7 @@ static int _nfs4_proc_access(struct inod
21433 +
21434 + static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
21435 + {
21436 +- struct nfs4_exception exception = { };
21437 ++ struct nfs4_exception exception = {0, 0};
21438 + int err;
21439 + do {
21440 + err = nfs4_handle_exception(NFS_SERVER(inode),
21441 +@@ -1856,7 +1856,7 @@ static int _nfs4_proc_readlink(struct in
21442 + static int nfs4_proc_readlink(struct inode *inode, struct page *page,
21443 + unsigned int pgbase, unsigned int pglen)
21444 + {
21445 +- struct nfs4_exception exception = { };
21446 ++ struct nfs4_exception exception = {0, 0};
21447 + int err;
21448 + do {
21449 + err = nfs4_handle_exception(NFS_SERVER(inode),
21450 +@@ -1950,7 +1950,7 @@ static int _nfs4_proc_remove(struct inod
21451 +
21452 + static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
21453 + {
21454 +- struct nfs4_exception exception = { };
21455 ++ struct nfs4_exception exception = {0, 0};
21456 + int err;
21457 + do {
21458 + err = nfs4_handle_exception(NFS_SERVER(dir),
21459 +@@ -2022,7 +2022,7 @@ static int _nfs4_proc_rename(struct inod
21460 + static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
21461 + struct inode *new_dir, struct qstr *new_name)
21462 + {
21463 +- struct nfs4_exception exception = { };
21464 ++ struct nfs4_exception exception = {0, 0};
21465 + int err;
21466 + do {
21467 + err = nfs4_handle_exception(NFS_SERVER(old_dir),
21468 +@@ -2069,7 +2069,7 @@ static int _nfs4_proc_link(struct inode
21469 +
21470 + static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
21471 + {
21472 +- struct nfs4_exception exception = { };
21473 ++ struct nfs4_exception exception = {0, 0};
21474 + int err;
21475 + do {
21476 + err = nfs4_handle_exception(NFS_SERVER(inode),
21477 +@@ -2126,7 +2126,7 @@ static int _nfs4_proc_symlink(struct ino
21478 + static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
21479 + struct page *page, unsigned int len, struct iattr *sattr)
21480 + {
21481 +- struct nfs4_exception exception = { };
21482 ++ struct nfs4_exception exception = {0, 0};
21483 + int err;
21484 + do {
21485 + err = nfs4_handle_exception(NFS_SERVER(dir),
21486 +@@ -2179,7 +2179,7 @@ static int _nfs4_proc_mkdir(struct inode
21487 + static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
21488 + struct iattr *sattr)
21489 + {
21490 +- struct nfs4_exception exception = { };
21491 ++ struct nfs4_exception exception = {0, 0};
21492 + int err;
21493 + do {
21494 + err = nfs4_handle_exception(NFS_SERVER(dir),
21495 +@@ -2225,7 +2225,7 @@ static int _nfs4_proc_readdir(struct den
21496 + static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
21497 + u64 cookie, struct page *page, unsigned int count, int plus)
21498 + {
21499 +- struct nfs4_exception exception = { };
21500 ++ struct nfs4_exception exception = {0, 0};
21501 + int err;
21502 + do {
21503 + err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
21504 +@@ -2295,7 +2295,7 @@ static int _nfs4_proc_mknod(struct inode
21505 + static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
21506 + struct iattr *sattr, dev_t rdev)
21507 + {
21508 +- struct nfs4_exception exception = { };
21509 ++ struct nfs4_exception exception = {0, 0};
21510 + int err;
21511 + do {
21512 + err = nfs4_handle_exception(NFS_SERVER(dir),
21513 +@@ -2324,7 +2324,7 @@ static int _nfs4_proc_statfs(struct nfs_
21514 +
21515 + static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
21516 + {
21517 +- struct nfs4_exception exception = { };
21518 ++ struct nfs4_exception exception = {0, 0};
21519 + int err;
21520 + do {
21521 + err = nfs4_handle_exception(server,
21522 +@@ -2352,7 +2352,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
21523 +
21524 + static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
21525 + {
21526 +- struct nfs4_exception exception = { };
21527 ++ struct nfs4_exception exception = {0, 0};
21528 + int err;
21529 +
21530 + do {
21531 +@@ -2395,7 +2395,7 @@ static int _nfs4_proc_pathconf(struct nf
21532 + static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
21533 + struct nfs_pathconf *pathconf)
21534 + {
21535 +- struct nfs4_exception exception = { };
21536 ++ struct nfs4_exception exception = {0, 0};
21537 + int err;
21538 +
21539 + do {
21540 +@@ -2714,7 +2714,7 @@ out_free:
21541 +
21542 + static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
21543 + {
21544 +- struct nfs4_exception exception = { };
21545 ++ struct nfs4_exception exception = {0, 0};
21546 + ssize_t ret;
21547 + do {
21548 + ret = __nfs4_get_acl_uncached(inode, buf, buflen);
21549 +@@ -2768,7 +2768,7 @@ static int __nfs4_proc_set_acl(struct in
21550 +
21551 + static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
21552 + {
21553 +- struct nfs4_exception exception = { };
21554 ++ struct nfs4_exception exception = {0, 0};
21555 + int err;
21556 + do {
21557 + err = nfs4_handle_exception(NFS_SERVER(inode),
21558 +@@ -3065,7 +3065,7 @@ static int _nfs4_proc_delegreturn(struct
21559 + int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
21560 + {
21561 + struct nfs_server *server = NFS_SERVER(inode);
21562 +- struct nfs4_exception exception = { };
21563 ++ struct nfs4_exception exception = {0, 0};
21564 + int err;
21565 + do {
21566 + err = _nfs4_proc_delegreturn(inode, cred, stateid);
21567 +@@ -3140,7 +3140,7 @@ out:
21568 +
21569 + static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
21570 + {
21571 +- struct nfs4_exception exception = { };
21572 ++ struct nfs4_exception exception = {0, 0};
21573 + int err;
21574 +
21575 + do {
21576 +@@ -3474,7 +3474,7 @@ static int _nfs4_do_setlk(struct nfs4_st
21577 + static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
21578 + {
21579 + struct nfs_server *server = NFS_SERVER(state->inode);
21580 +- struct nfs4_exception exception = { };
21581 ++ struct nfs4_exception exception = {0, 0};
21582 + int err;
21583 +
21584 + do {
21585 +@@ -3492,7 +3492,7 @@ static int nfs4_lock_reclaim(struct nfs4
21586 + static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
21587 + {
21588 + struct nfs_server *server = NFS_SERVER(state->inode);
21589 +- struct nfs4_exception exception = { };
21590 ++ struct nfs4_exception exception = {0, 0};
21591 + int err;
21592 +
21593 + err = nfs4_set_lock_state(state, request);
21594 +@@ -3553,7 +3553,7 @@ out:
21595 +
21596 + static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
21597 + {
21598 +- struct nfs4_exception exception = { };
21599 ++ struct nfs4_exception exception = {0, 0};
21600 + int err;
21601 +
21602 + do {
21603 +@@ -3603,7 +3603,7 @@ nfs4_proc_lock(struct file *filp, int cm
21604 + int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
21605 + {
21606 + struct nfs_server *server = NFS_SERVER(state->inode);
21607 +- struct nfs4_exception exception = { };
21608 ++ struct nfs4_exception exception = {0, 0};
21609 + int err;
21610 +
21611 + err = nfs4_set_lock_state(state, fl);
21612 +diff -Nurp linux-2.6.23.15/fs/nfsd/export.c linux-2.6.23.15-grsec/fs/nfsd/export.c
21613 +--- linux-2.6.23.15/fs/nfsd/export.c 2007-10-09 21:31:38.000000000 +0100
21614 ++++ linux-2.6.23.15-grsec/fs/nfsd/export.c 2008-02-11 10:37:44.000000000 +0000
21615 +@@ -478,7 +478,7 @@ static int secinfo_parse(char **mesg, ch
21616 + * probably discover the problem when someone fails to
21617 + * authenticate.
21618 + */
21619 +- if (f->pseudoflavor < 0)
21620 ++ if ((s32)f->pseudoflavor < 0)
21621 + return -EINVAL;
21622 + err = get_int(mesg, &f->flags);
21623 + if (err)
21624 +diff -Nurp linux-2.6.23.15/fs/nfsd/nfs4state.c linux-2.6.23.15-grsec/fs/nfsd/nfs4state.c
21625 +--- linux-2.6.23.15/fs/nfsd/nfs4state.c 2007-10-09 21:31:38.000000000 +0100
21626 ++++ linux-2.6.23.15-grsec/fs/nfsd/nfs4state.c 2008-02-11 10:37:44.000000000 +0000
21627 +@@ -1248,7 +1248,7 @@ static int access_valid(u32 x)
21628 +
21629 + static int deny_valid(u32 x)
21630 + {
21631 +- return (x >= 0 && x < 5);
21632 ++ return (x < 5);
21633 + }
21634 +
21635 + static void
21636 +diff -Nurp linux-2.6.23.15/fs/nls/nls_base.c linux-2.6.23.15-grsec/fs/nls/nls_base.c
21637 +--- linux-2.6.23.15/fs/nls/nls_base.c 2007-10-09 21:31:38.000000000 +0100
21638 ++++ linux-2.6.23.15-grsec/fs/nls/nls_base.c 2008-02-11 10:37:44.000000000 +0000
21639 +@@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] =
21640 + {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
21641 + {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
21642 + {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
21643 +- {0, /* end of table */}
21644 ++ {0, 0, 0, 0, 0, /* end of table */}
21645 + };
21646 +
21647 + int
21648 +diff -Nurp linux-2.6.23.15/fs/ntfs/file.c linux-2.6.23.15-grsec/fs/ntfs/file.c
21649 +--- linux-2.6.23.15/fs/ntfs/file.c 2007-10-09 21:31:38.000000000 +0100
21650 ++++ linux-2.6.23.15-grsec/fs/ntfs/file.c 2008-02-11 10:37:44.000000000 +0000
21651 +@@ -2295,6 +2295,6 @@ const struct inode_operations ntfs_file_
21652 + #endif /* NTFS_RW */
21653 + };
21654 +
21655 +-const struct file_operations ntfs_empty_file_ops = {};
21656 ++const struct file_operations ntfs_empty_file_ops;
21657 +
21658 +-const struct inode_operations ntfs_empty_inode_ops = {};
21659 ++const struct inode_operations ntfs_empty_inode_ops;
21660 +diff -Nurp linux-2.6.23.15/fs/open.c linux-2.6.23.15-grsec/fs/open.c
21661 +--- linux-2.6.23.15/fs/open.c 2007-10-09 21:31:38.000000000 +0100
21662 ++++ linux-2.6.23.15-grsec/fs/open.c 2008-02-11 10:37:44.000000000 +0000
21663 +@@ -27,6 +27,7 @@
21664 + #include <linux/rcupdate.h>
21665 + #include <linux/audit.h>
21666 + #include <linux/falloc.h>
21667 ++#include <linux/grsecurity.h>
21668 +
21669 + int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
21670 + {
21671 +@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
21672 + if (length < 0)
21673 + return -EINVAL;
21674 +
21675 ++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
21676 ++ return -EACCES;
21677 ++
21678 + newattrs.ia_size = length;
21679 + newattrs.ia_valid = ATTR_SIZE | time_attrs;
21680 + if (filp) {
21681 +@@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c
21682 + if(IS_RDONLY(nd.dentry->d_inode))
21683 + res = -EROFS;
21684 +
21685 ++ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
21686 ++ res = -EACCES;
21687 ++
21688 + out_path_release:
21689 + path_release(&nd);
21690 + out:
21691 +@@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u
21692 + if (error)
21693 + goto dput_and_out;
21694 +
21695 ++ gr_log_chdir(nd.dentry, nd.mnt);
21696 ++
21697 + set_fs_pwd(current->fs, nd.mnt, nd.dentry);
21698 +
21699 + dput_and_out:
21700 +@@ -520,6 +529,13 @@ asmlinkage long sys_fchdir(unsigned int
21701 + goto out_putf;
21702 +
21703 + error = file_permission(file, MAY_EXEC);
21704 ++
21705 ++ if (!error && !gr_chroot_fchdir(dentry, mnt))
21706 ++ error = -EPERM;
21707 ++
21708 ++ if (!error)
21709 ++ gr_log_chdir(dentry, mnt);
21710 ++
21711 + if (!error)
21712 + set_fs_pwd(current->fs, mnt, dentry);
21713 + out_putf:
21714 +@@ -545,8 +561,16 @@ asmlinkage long sys_chroot(const char __
21715 + if (!capable(CAP_SYS_CHROOT))
21716 + goto dput_and_out;
21717 +
21718 ++ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
21719 ++ goto dput_and_out;
21720 ++
21721 + set_fs_root(current->fs, nd.mnt, nd.dentry);
21722 + set_fs_altroot();
21723 ++
21724 ++ gr_handle_chroot_caps(current);
21725 ++
21726 ++ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
21727 ++
21728 + error = 0;
21729 + dput_and_out:
21730 + path_release(&nd);
21731 +@@ -577,9 +601,22 @@ asmlinkage long sys_fchmod(unsigned int
21732 + err = -EPERM;
21733 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21734 + goto out_putf;
21735 ++
21736 ++ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
21737 ++ err = -EACCES;
21738 ++ goto out_putf;
21739 ++ }
21740 ++
21741 + mutex_lock(&inode->i_mutex);
21742 + if (mode == (mode_t) -1)
21743 + mode = inode->i_mode;
21744 ++
21745 ++ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
21746 ++ err = -EPERM;
21747 ++ mutex_unlock(&inode->i_mutex);
21748 ++ goto out_putf;
21749 ++ }
21750 ++
21751 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
21752 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
21753 + err = notify_change(dentry, &newattrs);
21754 +@@ -612,9 +649,21 @@ asmlinkage long sys_fchmodat(int dfd, co
21755 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21756 + goto dput_and_out;
21757 +
21758 ++ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
21759 ++ error = -EACCES;
21760 ++ goto dput_and_out;
21761 ++ };
21762 ++
21763 + mutex_lock(&inode->i_mutex);
21764 + if (mode == (mode_t) -1)
21765 + mode = inode->i_mode;
21766 ++
21767 ++ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
21768 ++ error = -EACCES;
21769 ++ mutex_unlock(&inode->i_mutex);
21770 ++ goto dput_and_out;
21771 ++ }
21772 ++
21773 + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
21774 + newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
21775 + error = notify_change(nd.dentry, &newattrs);
21776 +@@ -631,7 +680,7 @@ asmlinkage long sys_chmod(const char __u
21777 + return sys_fchmodat(AT_FDCWD, filename, mode);
21778 + }
21779 +
21780 +-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
21781 ++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
21782 + {
21783 + struct inode * inode;
21784 + int error;
21785 +@@ -648,6 +697,12 @@ static int chown_common(struct dentry *
21786 + error = -EPERM;
21787 + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
21788 + goto out;
21789 ++
21790 ++ if (!gr_acl_handle_chown(dentry, mnt)) {
21791 ++ error = -EACCES;
21792 ++ goto out;
21793 ++ }
21794 ++
21795 + newattrs.ia_valid = ATTR_CTIME;
21796 + if (user != (uid_t) -1) {
21797 + newattrs.ia_valid |= ATTR_UID;
21798 +@@ -674,7 +729,7 @@ asmlinkage long sys_chown(const char __u
21799 + error = user_path_walk(filename, &nd);
21800 + if (error)
21801 + goto out;
21802 +- error = chown_common(nd.dentry, user, group);
21803 ++ error = chown_common(nd.dentry, user, group, nd.mnt);
21804 + path_release(&nd);
21805 + out:
21806 + return error;
21807 +@@ -694,7 +749,7 @@ asmlinkage long sys_fchownat(int dfd, co
21808 + error = __user_walk_fd(dfd, filename, follow, &nd);
21809 + if (error)
21810 + goto out;
21811 +- error = chown_common(nd.dentry, user, group);
21812 ++ error = chown_common(nd.dentry, user, group, nd.mnt);
21813 + path_release(&nd);
21814 + out:
21815 + return error;
21816 +@@ -708,7 +763,7 @@ asmlinkage long sys_lchown(const char __
21817 + error = user_path_walk_link(filename, &nd);
21818 + if (error)
21819 + goto out;
21820 +- error = chown_common(nd.dentry, user, group);
21821 ++ error = chown_common(nd.dentry, user, group, nd.mnt);
21822 + path_release(&nd);
21823 + out:
21824 + return error;
21825 +@@ -727,7 +782,7 @@ asmlinkage long sys_fchown(unsigned int
21826 +
21827 + dentry = file->f_path.dentry;
21828 + audit_inode(NULL, dentry->d_inode);
21829 +- error = chown_common(dentry, user, group);
21830 ++ error = chown_common(dentry, user, group, file->f_vfsmnt);
21831 + fput(file);
21832 + out:
21833 + return error;
21834 +@@ -934,6 +989,7 @@ repeat:
21835 + * N.B. For clone tasks sharing a files structure, this test
21836 + * will limit the total number of files that can be opened.
21837 + */
21838 ++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
21839 + if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
21840 + goto out;
21841 +
21842 +diff -Nurp linux-2.6.23.15/fs/partitions/efi.c linux-2.6.23.15-grsec/fs/partitions/efi.c
21843 +--- linux-2.6.23.15/fs/partitions/efi.c 2007-10-09 21:31:38.000000000 +0100
21844 ++++ linux-2.6.23.15-grsec/fs/partitions/efi.c 2008-02-11 10:37:44.000000000 +0000
21845 +@@ -99,7 +99,7 @@
21846 + #ifdef EFI_DEBUG
21847 + #define Dprintk(x...) printk(KERN_DEBUG x)
21848 + #else
21849 +-#define Dprintk(x...)
21850 ++#define Dprintk(x...) do {} while (0)
21851 + #endif
21852 +
21853 + /* This allows a kernel command line option 'gpt' to override
21854 +diff -Nurp linux-2.6.23.15/fs/pipe.c linux-2.6.23.15-grsec/fs/pipe.c
21855 +--- linux-2.6.23.15/fs/pipe.c 2007-10-09 21:31:38.000000000 +0100
21856 ++++ linux-2.6.23.15-grsec/fs/pipe.c 2008-02-11 10:37:44.000000000 +0000
21857 +@@ -888,7 +888,7 @@ void free_pipe_info(struct inode *inode)
21858 + inode->i_pipe = NULL;
21859 + }
21860 +
21861 +-static struct vfsmount *pipe_mnt __read_mostly;
21862 ++struct vfsmount *pipe_mnt __read_mostly;
21863 + static int pipefs_delete_dentry(struct dentry *dentry)
21864 + {
21865 + /*
21866 +diff -Nurp linux-2.6.23.15/fs/proc/array.c linux-2.6.23.15-grsec/fs/proc/array.c
21867 +--- linux-2.6.23.15/fs/proc/array.c 2008-02-11 10:36:03.000000000 +0000
21868 ++++ linux-2.6.23.15-grsec/fs/proc/array.c 2008-02-11 10:37:44.000000000 +0000
21869 +@@ -298,6 +298,21 @@ static inline char *task_context_switch_
21870 + p->nivcsw);
21871 + }
21872 +
21873 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21874 ++static inline char *task_pax(struct task_struct *p, char *buffer)
21875 ++{
21876 ++ if (p->mm)
21877 ++ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
21878 ++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
21879 ++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
21880 ++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
21881 ++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
21882 ++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
21883 ++ else
21884 ++ return buffer + sprintf(buffer, "PaX:\t-----\n");
21885 ++}
21886 ++#endif
21887 ++
21888 + int proc_pid_status(struct task_struct *task, char *buffer)
21889 + {
21890 + char *orig = buffer;
21891 +@@ -317,6 +332,11 @@ int proc_pid_status(struct task_struct *
21892 + buffer = task_show_regs(task, buffer);
21893 + #endif
21894 + buffer = task_context_switch_counts(task, buffer);
21895 ++
21896 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
21897 ++ buffer = task_pax(task, buffer);
21898 ++#endif
21899 ++
21900 + return buffer - orig;
21901 + }
21902 +
21903 +@@ -372,6 +392,12 @@ static cputime_t task_stime(struct task_
21904 + }
21905 + #endif
21906 +
21907 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21908 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
21909 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
21910 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
21911 ++#endif
21912 ++
21913 + static int do_task_stat(struct task_struct *task, char *buffer, int whole)
21914 + {
21915 + unsigned long vsize, eip, esp, wchan = ~0UL;
21916 +@@ -458,6 +484,19 @@ static int do_task_stat(struct task_stru
21917 + stime = task_stime(task);
21918 + }
21919 +
21920 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21921 ++ if (PAX_RAND_FLAGS(mm)) {
21922 ++ eip = 0;
21923 ++ esp = 0;
21924 ++ wchan = 0;
21925 ++ }
21926 ++#endif
21927 ++#ifdef CONFIG_GRKERNSEC_HIDESYM
21928 ++ wchan = 0;
21929 ++ eip =0;
21930 ++ esp =0;
21931 ++#endif
21932 ++
21933 + /* scale priority and nice values from timeslices to -20..20 */
21934 + /* to make it look like a "normal" Unix priority/nice value */
21935 + priority = task_prio(task);
21936 +@@ -498,9 +537,15 @@ static int do_task_stat(struct task_stru
21937 + vsize,
21938 + mm ? get_mm_rss(mm) : 0,
21939 + rsslim,
21940 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
21941 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
21942 ++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
21943 ++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
21944 ++#else
21945 + mm ? mm->start_code : 0,
21946 + mm ? mm->end_code : 0,
21947 + mm ? mm->start_stack : 0,
21948 ++#endif
21949 + esp,
21950 + eip,
21951 + /* The signal information here is obsolete.
21952 +@@ -547,3 +592,14 @@ int proc_pid_statm(struct task_struct *t
21953 + return sprintf(buffer, "%d %d %d %d %d %d %d\n",
21954 + size, resident, shared, text, lib, data, 0);
21955 + }
21956 ++
21957 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
21958 ++int proc_pid_ipaddr(struct task_struct *task, char * buffer)
21959 ++{
21960 ++ int len;
21961 ++
21962 ++ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
21963 ++ return len;
21964 ++}
21965 ++#endif
21966 ++
21967 +diff -Nurp linux-2.6.23.15/fs/proc/base.c linux-2.6.23.15-grsec/fs/proc/base.c
21968 +--- linux-2.6.23.15/fs/proc/base.c 2007-10-09 21:31:38.000000000 +0100
21969 ++++ linux-2.6.23.15-grsec/fs/proc/base.c 2008-02-11 10:37:44.000000000 +0000
21970 +@@ -73,6 +73,7 @@
21971 + #include <linux/nsproxy.h>
21972 + #include <linux/oom.h>
21973 + #include <linux/elf.h>
21974 ++#include <linux/grsecurity.h>
21975 + #include "internal.h"
21976 +
21977 + /* NOTE:
21978 +@@ -123,7 +124,7 @@ struct pid_entry {
21979 + NULL, &proc_info_file_operations, \
21980 + { .proc_read = &proc_##OTYPE } )
21981 +
21982 +-int maps_protect;
21983 ++int maps_protect = 1;
21984 + EXPORT_SYMBOL(maps_protect);
21985 +
21986 + static struct fs_struct *get_fs_struct(struct task_struct *task)
21987 +@@ -197,7 +198,7 @@ static int proc_root_link(struct inode *
21988 + (task->parent == current && \
21989 + (task->ptrace & PT_PTRACED) && \
21990 + (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
21991 +- security_ptrace(current,task) == 0))
21992 ++ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
21993 +
21994 + static int proc_pid_environ(struct task_struct *task, char * buffer)
21995 + {
21996 +@@ -263,9 +264,9 @@ static int proc_pid_auxv(struct task_str
21997 + struct mm_struct *mm = get_task_mm(task);
21998 + if (mm) {
21999 + unsigned int nwords = 0;
22000 +- do
22001 ++ do {
22002 + nwords += 2;
22003 +- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
22004 ++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
22005 + res = nwords * sizeof(mm->saved_auxv[0]);
22006 + if (res > PAGE_SIZE)
22007 + res = PAGE_SIZE;
22008 +@@ -338,6 +339,8 @@ static int proc_fd_access_allowed(struct
22009 + task = get_proc_task(inode);
22010 + if (task) {
22011 + allowed = ptrace_may_attach(task);
22012 ++ if (allowed != 0)
22013 ++ allowed = !gr_acl_handle_procpidmem(task);
22014 + put_task_struct(task);
22015 + }
22016 + return allowed;
22017 +@@ -528,7 +531,7 @@ static ssize_t mem_read(struct file * fi
22018 + if (!task)
22019 + goto out_no_task;
22020 +
22021 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
22022 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
22023 + goto out;
22024 +
22025 + ret = -ENOMEM;
22026 +@@ -598,7 +601,7 @@ static ssize_t mem_write(struct file * f
22027 + if (!task)
22028 + goto out_no_task;
22029 +
22030 +- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
22031 ++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
22032 + goto out;
22033 +
22034 + copied = -ENOMEM;
22035 +@@ -1050,7 +1053,11 @@ static struct inode *proc_pid_make_inode
22036 + inode->i_gid = 0;
22037 + if (task_dumpable(task)) {
22038 + inode->i_uid = task->euid;
22039 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22040 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22041 ++#else
22042 + inode->i_gid = task->egid;
22043 ++#endif
22044 + }
22045 + security_task_to_inode(task, inode);
22046 +
22047 +@@ -1066,17 +1073,45 @@ static int pid_getattr(struct vfsmount *
22048 + {
22049 + struct inode *inode = dentry->d_inode;
22050 + struct task_struct *task;
22051 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22052 ++ struct task_struct *tmp = current;
22053 ++#endif
22054 ++
22055 + generic_fillattr(inode, stat);
22056 +
22057 + rcu_read_lock();
22058 + stat->uid = 0;
22059 + stat->gid = 0;
22060 + task = pid_task(proc_pid(inode), PIDTYPE_PID);
22061 +- if (task) {
22062 ++
22063 ++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
22064 ++ rcu_read_unlock();
22065 ++ return -ENOENT;
22066 ++ }
22067 ++
22068 ++
22069 ++ if (task
22070 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22071 ++ && (!tmp->uid || (tmp->uid == task->uid)
22072 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22073 ++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
22074 ++#endif
22075 ++ )
22076 ++#endif
22077 ++ ) {
22078 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
22079 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22080 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
22081 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22082 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
22083 ++#endif
22084 + task_dumpable(task)) {
22085 + stat->uid = task->euid;
22086 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22087 ++ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
22088 ++#else
22089 + stat->gid = task->egid;
22090 ++#endif
22091 + }
22092 + }
22093 + rcu_read_unlock();
22094 +@@ -1104,11 +1139,21 @@ static int pid_revalidate(struct dentry
22095 + {
22096 + struct inode *inode = dentry->d_inode;
22097 + struct task_struct *task = get_proc_task(inode);
22098 ++
22099 + if (task) {
22100 + if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
22101 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22102 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
22103 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22104 ++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
22105 ++#endif
22106 + task_dumpable(task)) {
22107 + inode->i_uid = task->euid;
22108 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22109 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22110 ++#else
22111 + inode->i_gid = task->egid;
22112 ++#endif
22113 + } else {
22114 + inode->i_uid = 0;
22115 + inode->i_gid = 0;
22116 +@@ -1118,6 +1163,7 @@ static int pid_revalidate(struct dentry
22117 + put_task_struct(task);
22118 + return 1;
22119 + }
22120 ++out:
22121 + d_drop(dentry);
22122 + return 0;
22123 + }
22124 +@@ -1374,6 +1420,9 @@ static struct dentry *proc_lookupfd_comm
22125 + if (fd == ~0U)
22126 + goto out;
22127 +
22128 ++ if (gr_acl_handle_procpidmem(task))
22129 ++ goto out;
22130 ++
22131 + result = instantiate(dir, dentry, task, &fd);
22132 + out:
22133 + put_task_struct(task);
22134 +@@ -1410,6 +1459,8 @@ static int proc_readfd_common(struct fil
22135 + goto out;
22136 + filp->f_pos++;
22137 + default:
22138 ++ if (gr_acl_handle_procpidmem(p))
22139 ++ goto out;
22140 + files = get_files_struct(p);
22141 + if (!files)
22142 + goto out;
22143 +@@ -1598,6 +1649,9 @@ static struct dentry *proc_pident_lookup
22144 + if (!task)
22145 + goto out_no_task;
22146 +
22147 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22148 ++ goto out;
22149 ++
22150 + /*
22151 + * Yes, it does not scale. And it should not. Don't add
22152 + * new entries into /proc/<tgid>/ without very good reasons.
22153 +@@ -1643,6 +1697,9 @@ static int proc_pident_readdir(struct fi
22154 + if (!task)
22155 + goto out_no_task;
22156 +
22157 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22158 ++ goto out;
22159 ++
22160 + ret = 0;
22161 + pid = task->pid;
22162 + i = filp->f_pos;
22163 +@@ -1998,6 +2055,9 @@ static struct dentry *proc_base_lookup(s
22164 + if (p > last)
22165 + goto out;
22166 +
22167 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
22168 ++ goto out;
22169 ++
22170 + error = proc_base_instantiate(dir, dentry, task, p);
22171 +
22172 + out:
22173 +@@ -2097,6 +2157,9 @@ static const struct pid_entry tgid_base_
22174 + #ifdef CONFIG_TASK_IO_ACCOUNTING
22175 + INF("io", S_IRUGO, pid_io_accounting),
22176 + #endif
22177 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
22178 ++ INF("ipaddr", S_IRUSR, pid_ipaddr),
22179 ++#endif
22180 + };
22181 +
22182 + static int proc_tgid_base_readdir(struct file * filp,
22183 +@@ -2200,7 +2263,14 @@ static struct dentry *proc_pid_instantia
22184 + if (!inode)
22185 + goto out;
22186 +
22187 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22188 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
22189 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
22190 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22191 ++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
22192 ++#else
22193 + inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
22194 ++#endif
22195 + inode->i_op = &proc_tgid_base_inode_operations;
22196 + inode->i_fop = &proc_tgid_base_operations;
22197 + inode->i_flags|=S_IMMUTABLE;
22198 +@@ -2241,7 +2311,11 @@ struct dentry *proc_pid_lookup(struct in
22199 + if (!task)
22200 + goto out;
22201 +
22202 ++ if (gr_check_hidden_task(task))
22203 ++ goto out_put_task;
22204 ++
22205 + result = proc_pid_instantiate(dir, dentry, task, NULL);
22206 ++out_put_task:
22207 + put_task_struct(task);
22208 + out:
22209 + return result;
22210 +@@ -2299,6 +2373,9 @@ int proc_pid_readdir(struct file * filp,
22211 + {
22212 + unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
22213 + struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
22214 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22215 ++ struct task_struct *tmp = current;
22216 ++#endif
22217 + struct task_struct *task;
22218 + int tgid;
22219 +
22220 +@@ -2316,6 +2393,18 @@ int proc_pid_readdir(struct file * filp,
22221 + task;
22222 + put_task_struct(task), task = next_tgid(tgid + 1)) {
22223 + tgid = task->pid;
22224 ++
22225 ++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
22226 ++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22227 ++ || (tmp->uid && (task->uid != tmp->uid)
22228 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22229 ++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
22230 ++#endif
22231 ++ )
22232 ++#endif
22233 ++ )
22234 ++ continue;
22235 ++
22236 + filp->f_pos = tgid + TGID_OFFSET;
22237 + if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
22238 + put_task_struct(task);
22239 +diff -Nurp linux-2.6.23.15/fs/proc/inode.c linux-2.6.23.15-grsec/fs/proc/inode.c
22240 +--- linux-2.6.23.15/fs/proc/inode.c 2007-10-09 21:31:38.000000000 +0100
22241 ++++ linux-2.6.23.15-grsec/fs/proc/inode.c 2008-02-11 10:37:44.000000000 +0000
22242 +@@ -418,7 +418,11 @@ struct inode *proc_get_inode(struct supe
22243 + if (de->mode) {
22244 + inode->i_mode = de->mode;
22245 + inode->i_uid = de->uid;
22246 ++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
22247 ++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
22248 ++#else
22249 + inode->i_gid = de->gid;
22250 ++#endif
22251 + }
22252 + if (de->size)
22253 + inode->i_size = de->size;
22254 +diff -Nurp linux-2.6.23.15/fs/proc/internal.h linux-2.6.23.15-grsec/fs/proc/internal.h
22255 +--- linux-2.6.23.15/fs/proc/internal.h 2007-10-09 21:31:38.000000000 +0100
22256 ++++ linux-2.6.23.15-grsec/fs/proc/internal.h 2008-02-11 10:37:44.000000000 +0000
22257 +@@ -45,6 +45,9 @@ extern int proc_tid_stat(struct task_str
22258 + extern int proc_tgid_stat(struct task_struct *, char *);
22259 + extern int proc_pid_status(struct task_struct *, char *);
22260 + extern int proc_pid_statm(struct task_struct *, char *);
22261 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
22262 ++extern int proc_pid_ipaddr(struct task_struct*,char*);
22263 ++#endif
22264 +
22265 + extern const struct file_operations proc_maps_operations;
22266 + extern const struct file_operations proc_numa_maps_operations;
22267 +diff -Nurp linux-2.6.23.15/fs/proc/proc_misc.c linux-2.6.23.15-grsec/fs/proc/proc_misc.c
22268 +--- linux-2.6.23.15/fs/proc/proc_misc.c 2007-10-09 21:31:38.000000000 +0100
22269 ++++ linux-2.6.23.15-grsec/fs/proc/proc_misc.c 2008-02-11 10:37:44.000000000 +0000
22270 +@@ -668,6 +668,8 @@ void create_seq_entry(char *name, mode_t
22271 +
22272 + void __init proc_misc_init(void)
22273 + {
22274 ++ int gr_mode = 0;
22275 ++
22276 + static struct {
22277 + char *name;
22278 + int (*read_proc)(char*,char**,off_t,int,int*,void*);
22279 +@@ -683,7 +685,9 @@ void __init proc_misc_init(void)
22280 + {"stram", stram_read_proc},
22281 + #endif
22282 + {"filesystems", filesystems_read_proc},
22283 ++#ifndef CONFIG_GRKERNSEC_PROC_ADD
22284 + {"cmdline", cmdline_read_proc},
22285 ++#endif
22286 + {"locks", locks_read_proc},
22287 + {"execdomains", execdomains_read_proc},
22288 + {NULL,}
22289 +@@ -691,6 +695,15 @@ void __init proc_misc_init(void)
22290 + for (p = simple_ones; p->name; p++)
22291 + create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
22292 +
22293 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22294 ++ gr_mode = S_IRUSR;
22295 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22296 ++ gr_mode = S_IRUSR | S_IRGRP;
22297 ++#endif
22298 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22299 ++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
22300 ++#endif
22301 ++
22302 + proc_symlink("mounts", NULL, "self/mounts");
22303 +
22304 + /* And now for trickier ones */
22305 +@@ -702,7 +715,11 @@ void __init proc_misc_init(void)
22306 + entry->proc_fops = &proc_kmsg_operations;
22307 + }
22308 + #endif
22309 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22310 ++ create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
22311 ++#else
22312 + create_seq_entry("devices", 0, &proc_devinfo_operations);
22313 ++#endif
22314 + create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
22315 + #ifdef CONFIG_BLOCK
22316 + create_seq_entry("partitions", 0, &proc_partitions_operations);
22317 +@@ -710,7 +727,11 @@ void __init proc_misc_init(void)
22318 + create_seq_entry("stat", 0, &proc_stat_operations);
22319 + create_seq_entry("interrupts", 0, &proc_interrupts_operations);
22320 + #ifdef CONFIG_SLAB
22321 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22322 ++ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
22323 ++#else
22324 + create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
22325 ++#endif
22326 + #ifdef CONFIG_DEBUG_SLAB_LEAK
22327 + create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
22328 + #endif
22329 +@@ -727,7 +748,7 @@ void __init proc_misc_init(void)
22330 + #ifdef CONFIG_SCHEDSTATS
22331 + create_seq_entry("schedstat", 0, &proc_schedstat_operations);
22332 + #endif
22333 +-#ifdef CONFIG_PROC_KCORE
22334 ++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
22335 + proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
22336 + if (proc_root_kcore) {
22337 + proc_root_kcore->proc_fops = &proc_kcore_operations;
22338 +diff -Nurp linux-2.6.23.15/fs/proc/proc_sysctl.c linux-2.6.23.15-grsec/fs/proc/proc_sysctl.c
22339 +--- linux-2.6.23.15/fs/proc/proc_sysctl.c 2007-10-09 21:31:38.000000000 +0100
22340 ++++ linux-2.6.23.15-grsec/fs/proc/proc_sysctl.c 2008-02-11 10:37:44.000000000 +0000
22341 +@@ -7,6 +7,8 @@
22342 + #include <linux/security.h>
22343 + #include "internal.h"
22344 +
22345 ++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
22346 ++
22347 + static struct dentry_operations proc_sys_dentry_operations;
22348 + static const struct file_operations proc_sys_file_operations;
22349 + static struct inode_operations proc_sys_inode_operations;
22350 +@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
22351 + if (!table)
22352 + goto out;
22353 +
22354 ++ if (gr_handle_sysctl(table, 001))
22355 ++ goto out;
22356 ++
22357 + err = ERR_PTR(-ENOMEM);
22358 + inode = proc_sys_make_inode(dir, table);
22359 + if (!inode)
22360 +@@ -358,6 +363,9 @@ static int proc_sys_readdir(struct file
22361 + if (pos < filp->f_pos)
22362 + continue;
22363 +
22364 ++ if (gr_handle_sysctl(table, 0))
22365 ++ continue;
22366 ++
22367 + if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
22368 + goto out;
22369 + filp->f_pos = pos + 1;
22370 +@@ -420,6 +428,30 @@ out:
22371 + return error;
22372 + }
22373 +
22374 ++/* Eric Biederman is to blame */
22375 ++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
22376 ++{
22377 ++ int error = 0;
22378 ++ struct ctl_table_header *head;
22379 ++ struct ctl_table *table;
22380 ++
22381 ++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
22382 ++ /* Has the sysctl entry disappeared on us? */
22383 ++ if (!table)
22384 ++ goto out;
22385 ++
22386 ++ if (gr_handle_sysctl(table, 001)) {
22387 ++ error = -ENOENT;
22388 ++ goto out;
22389 ++ }
22390 ++
22391 ++out:
22392 ++ sysctl_head_finish(head);
22393 ++
22394 ++ generic_fillattr(dentry->d_inode, stat);
22395 ++
22396 ++ return error;
22397 ++}
22398 + static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
22399 + {
22400 + struct inode *inode = dentry->d_inode;
22401 +@@ -448,6 +480,7 @@ static struct inode_operations proc_sys_
22402 + .lookup = proc_sys_lookup,
22403 + .permission = proc_sys_permission,
22404 + .setattr = proc_sys_setattr,
22405 ++ .getattr = proc_sys_getattr,
22406 + };
22407 +
22408 + static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
22409 +diff -Nurp linux-2.6.23.15/fs/proc/root.c linux-2.6.23.15-grsec/fs/proc/root.c
22410 +--- linux-2.6.23.15/fs/proc/root.c 2007-10-09 21:31:38.000000000 +0100
22411 ++++ linux-2.6.23.15-grsec/fs/proc/root.c 2008-02-11 10:37:44.000000000 +0000
22412 +@@ -61,7 +61,13 @@ void __init proc_root_init(void)
22413 + return;
22414 + }
22415 + proc_misc_init();
22416 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22417 ++ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
22418 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22419 ++ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
22420 ++#else
22421 + proc_net = proc_mkdir("net", NULL);
22422 ++#endif
22423 + proc_net_stat = proc_mkdir("net/stat", NULL);
22424 +
22425 + #ifdef CONFIG_SYSVIPC
22426 +@@ -78,7 +84,15 @@ void __init proc_root_init(void)
22427 + #ifdef CONFIG_PROC_DEVICETREE
22428 + proc_device_tree_init();
22429 + #endif
22430 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
22431 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
22432 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
22433 ++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
22434 ++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
22435 ++#endif
22436 ++#else
22437 + proc_bus = proc_mkdir("bus", NULL);
22438 ++#endif
22439 + proc_sys_init();
22440 + }
22441 +
22442 +diff -Nurp linux-2.6.23.15/fs/proc/task_mmu.c linux-2.6.23.15-grsec/fs/proc/task_mmu.c
22443 +--- linux-2.6.23.15/fs/proc/task_mmu.c 2007-10-09 21:31:38.000000000 +0100
22444 ++++ linux-2.6.23.15-grsec/fs/proc/task_mmu.c 2008-02-11 10:37:44.000000000 +0000
22445 +@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha
22446 + "VmStk:\t%8lu kB\n"
22447 + "VmExe:\t%8lu kB\n"
22448 + "VmLib:\t%8lu kB\n"
22449 +- "VmPTE:\t%8lu kB\n",
22450 +- hiwater_vm << (PAGE_SHIFT-10),
22451 ++ "VmPTE:\t%8lu kB\n"
22452 ++
22453 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22454 ++ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
22455 ++#endif
22456 ++
22457 ++ ,hiwater_vm << (PAGE_SHIFT-10),
22458 + (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
22459 + mm->locked_vm << (PAGE_SHIFT-10),
22460 + hiwater_rss << (PAGE_SHIFT-10),
22461 + total_rss << (PAGE_SHIFT-10),
22462 + data << (PAGE_SHIFT-10),
22463 + mm->stack_vm << (PAGE_SHIFT-10), text, lib,
22464 +- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
22465 ++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
22466 ++
22467 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
22468 ++ , mm->context.user_cs_base, mm->context.user_cs_limit
22469 ++#endif
22470 ++
22471 ++ );
22472 ++
22473 + return buffer;
22474 + }
22475 +
22476 +@@ -131,6 +143,12 @@ struct pmd_walker {
22477 + unsigned long, void *);
22478 + };
22479 +
22480 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22481 ++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
22482 ++ (_mm->pax_flags & MF_PAX_RANDMMAP || \
22483 ++ _mm->pax_flags & MF_PAX_SEGMEXEC))
22484 ++#endif
22485 ++
22486 + static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
22487 + {
22488 + struct proc_maps_private *priv = m->private;
22489 +@@ -153,13 +171,22 @@ static int show_map_internal(struct seq_
22490 + }
22491 +
22492 + seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
22493 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22494 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
22495 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
22496 ++#else
22497 + vma->vm_start,
22498 + vma->vm_end,
22499 ++#endif
22500 + flags & VM_READ ? 'r' : '-',
22501 + flags & VM_WRITE ? 'w' : '-',
22502 + flags & VM_EXEC ? 'x' : '-',
22503 + flags & VM_MAYSHARE ? 's' : 'p',
22504 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22505 ++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
22506 ++#else
22507 + vma->vm_pgoff << PAGE_SHIFT,
22508 ++#endif
22509 + MAJOR(dev), MINOR(dev), ino, &len);
22510 +
22511 + /*
22512 +@@ -173,11 +200,11 @@ static int show_map_internal(struct seq_
22513 + const char *name = arch_vma_name(vma);
22514 + if (!name) {
22515 + if (mm) {
22516 +- if (vma->vm_start <= mm->start_brk &&
22517 +- vma->vm_end >= mm->brk) {
22518 ++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
22519 + name = "[heap]";
22520 +- } else if (vma->vm_start <= mm->start_stack &&
22521 +- vma->vm_end >= mm->start_stack) {
22522 ++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
22523 ++ (vma->vm_start <= mm->start_stack &&
22524 ++ vma->vm_end >= mm->start_stack)) {
22525 + name = "[stack]";
22526 + }
22527 + } else {
22528 +@@ -191,7 +218,27 @@ static int show_map_internal(struct seq_
22529 + }
22530 + seq_putc(m, '\n');
22531 +
22532 +- if (mss)
22533 ++
22534 ++ if (mss) {
22535 ++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
22536 ++ if (PAX_RAND_FLAGS(mm))
22537 ++ seq_printf(m,
22538 ++ "Size: %8lu kB\n"
22539 ++ "Rss: %8lu kB\n"
22540 ++ "Shared_Clean: %8lu kB\n"
22541 ++ "Shared_Dirty: %8lu kB\n"
22542 ++ "Private_Clean: %8lu kB\n"
22543 ++ "Private_Dirty: %8lu kB\n",
22544 ++ "Referenced: %8lu kB\n",
22545 ++ 0UL,
22546 ++ 0UL,
22547 ++ 0UL,
22548 ++ 0UL,
22549 ++ 0UL,
22550 ++ 0UL,
22551 ++ 0UL);
22552 ++ else
22553 ++#endif
22554 + seq_printf(m,
22555 + "Size: %8lu kB\n"
22556 + "Rss: %8lu kB\n"
22557 +@@ -207,6 +254,7 @@ static int show_map_internal(struct seq_
22558 + mss->private_clean >> 10,
22559 + mss->private_dirty >> 10,
22560 + mss->referenced >> 10);
22561 ++ }
22562 +
22563 + if (m->count < m->size) /* vma is copied successfully */
22564 + m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
22565 +diff -Nurp linux-2.6.23.15/fs/readdir.c linux-2.6.23.15-grsec/fs/readdir.c
22566 +--- linux-2.6.23.15/fs/readdir.c 2007-10-09 21:31:38.000000000 +0100
22567 ++++ linux-2.6.23.15-grsec/fs/readdir.c 2008-02-11 10:37:44.000000000 +0000
22568 +@@ -16,6 +16,8 @@
22569 + #include <linux/security.h>
22570 + #include <linux/syscalls.h>
22571 + #include <linux/unistd.h>
22572 ++#include <linux/namei.h>
22573 ++#include <linux/grsecurity.h>
22574 +
22575 + #include <asm/uaccess.h>
22576 +
22577 +@@ -64,6 +66,7 @@ struct old_linux_dirent {
22578 +
22579 + struct readdir_callback {
22580 + struct old_linux_dirent __user * dirent;
22581 ++ struct file * file;
22582 + int result;
22583 + };
22584 +
22585 +@@ -79,6 +82,10 @@ static int fillonedir(void * __buf, cons
22586 + d_ino = ino;
22587 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
22588 + return -EOVERFLOW;
22589 ++
22590 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22591 ++ return 0;
22592 ++
22593 + buf->result++;
22594 + dirent = buf->dirent;
22595 + if (!access_ok(VERIFY_WRITE, dirent,
22596 +@@ -110,6 +117,7 @@ asmlinkage long old_readdir(unsigned int
22597 +
22598 + buf.result = 0;
22599 + buf.dirent = dirent;
22600 ++ buf.file = file;
22601 +
22602 + error = vfs_readdir(file, fillonedir, &buf);
22603 + if (error >= 0)
22604 +@@ -136,6 +144,7 @@ struct linux_dirent {
22605 + struct getdents_callback {
22606 + struct linux_dirent __user * current_dir;
22607 + struct linux_dirent __user * previous;
22608 ++ struct file * file;
22609 + int count;
22610 + int error;
22611 + };
22612 +@@ -154,6 +163,10 @@ static int filldir(void * __buf, const c
22613 + d_ino = ino;
22614 + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
22615 + return -EOVERFLOW;
22616 ++
22617 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22618 ++ return 0;
22619 ++
22620 + dirent = buf->previous;
22621 + if (dirent) {
22622 + if (__put_user(offset, &dirent->d_off))
22623 +@@ -200,6 +213,7 @@ asmlinkage long sys_getdents(unsigned in
22624 + buf.previous = NULL;
22625 + buf.count = count;
22626 + buf.error = 0;
22627 ++ buf.file = file;
22628 +
22629 + error = vfs_readdir(file, filldir, &buf);
22630 + if (error < 0)
22631 +@@ -222,6 +236,7 @@ out:
22632 + struct getdents_callback64 {
22633 + struct linux_dirent64 __user * current_dir;
22634 + struct linux_dirent64 __user * previous;
22635 ++ struct file *file;
22636 + int count;
22637 + int error;
22638 + };
22639 +@@ -236,6 +251,10 @@ static int filldir64(void * __buf, const
22640 + buf->error = -EINVAL; /* only used if we fail.. */
22641 + if (reclen > buf->count)
22642 + return -EINVAL;
22643 ++
22644 ++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
22645 ++ return 0;
22646 ++
22647 + dirent = buf->previous;
22648 + if (dirent) {
22649 + if (__put_user(offset, &dirent->d_off))
22650 +@@ -282,6 +301,7 @@ asmlinkage long sys_getdents64(unsigned
22651 +
22652 + buf.current_dir = dirent;
22653 + buf.previous = NULL;
22654 ++ buf.file = file;
22655 + buf.count = count;
22656 + buf.error = 0;
22657 +
22658 +diff -Nurp linux-2.6.23.15/fs/udf/balloc.c linux-2.6.23.15-grsec/fs/udf/balloc.c
22659 +--- linux-2.6.23.15/fs/udf/balloc.c 2007-10-09 21:31:38.000000000 +0100
22660 ++++ linux-2.6.23.15-grsec/fs/udf/balloc.c 2008-02-11 10:37:44.000000000 +0000
22661 +@@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc
22662 + unsigned long overflow;
22663 +
22664 + mutex_lock(&sbi->s_alloc_mutex);
22665 +- if (bloc.logicalBlockNum < 0 ||
22666 +- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
22667 ++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
22668 + udf_debug("%d < %d || %d + %d > %d\n",
22669 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
22670 + UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
22671 +@@ -221,7 +220,7 @@ static int udf_bitmap_prealloc_blocks(st
22672 + struct buffer_head *bh;
22673 +
22674 + mutex_lock(&sbi->s_alloc_mutex);
22675 +- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
22676 ++ if (first_block >= UDF_SB_PARTLEN(sb, partition))
22677 + goto out;
22678 +
22679 + if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
22680 +@@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s
22681 + mutex_lock(&sbi->s_alloc_mutex);
22682 +
22683 + repeat:
22684 +- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
22685 ++ if (goal >= UDF_SB_PARTLEN(sb, partition))
22686 + goal = 0;
22687 +
22688 + nr_groups = bitmap->s_nr_groups;
22689 +@@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct
22690 + int i;
22691 +
22692 + mutex_lock(&sbi->s_alloc_mutex);
22693 +- if (bloc.logicalBlockNum < 0 ||
22694 +- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
22695 ++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) {
22696 + udf_debug("%d < %d || %d + %d > %d\n",
22697 + bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
22698 + UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum));
22699 +@@ -627,7 +625,7 @@ static int udf_table_prealloc_blocks(str
22700 + struct extent_position epos;
22701 + int8_t etype = -1;
22702 +
22703 +- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
22704 ++ if (first_block >= UDF_SB_PARTLEN(sb, partition))
22705 + return 0;
22706 +
22707 + if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
22708 +@@ -703,7 +701,7 @@ static int udf_table_new_block(struct su
22709 + return newblock;
22710 +
22711 + mutex_lock(&sbi->s_alloc_mutex);
22712 +- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
22713 ++ if (goal >= UDF_SB_PARTLEN(sb, partition))
22714 + goal = 0;
22715 +
22716 + /* We search for the closest matching block to goal. If we find a exact hit,
22717 +diff -Nurp linux-2.6.23.15/fs/udf/inode.c linux-2.6.23.15-grsec/fs/udf/inode.c
22718 +--- linux-2.6.23.15/fs/udf/inode.c 2007-10-09 21:31:38.000000000 +0100
22719 ++++ linux-2.6.23.15-grsec/fs/udf/inode.c 2008-02-11 10:37:44.000000000 +0000
22720 +@@ -308,9 +308,6 @@ static int udf_get_block(struct inode *i
22721 +
22722 + lock_kernel();
22723 +
22724 +- if (block < 0)
22725 +- goto abort_negative;
22726 +-
22727 + if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) {
22728 + UDF_I_NEXT_ALLOC_BLOCK(inode)++;
22729 + UDF_I_NEXT_ALLOC_GOAL(inode)++;
22730 +@@ -331,10 +328,6 @@ static int udf_get_block(struct inode *i
22731 + abort:
22732 + unlock_kernel();
22733 + return err;
22734 +-
22735 +-abort_negative:
22736 +- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
22737 +- goto abort;
22738 + }
22739 +
22740 + static struct buffer_head *udf_getblk(struct inode *inode, long block,
22741 +diff -Nurp linux-2.6.23.15/fs/ufs/inode.c linux-2.6.23.15-grsec/fs/ufs/inode.c
22742 +--- linux-2.6.23.15/fs/ufs/inode.c 2007-10-09 21:31:38.000000000 +0100
22743 ++++ linux-2.6.23.15-grsec/fs/ufs/inode.c 2008-02-11 10:37:44.000000000 +0000
22744 +@@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
22745 +
22746 +
22747 + UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
22748 +- if (i_block < 0) {
22749 +- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
22750 +- } else if (i_block < direct_blocks) {
22751 ++ if (i_block < direct_blocks) {
22752 + offsets[n++] = i_block;
22753 + } else if ((i_block -= direct_blocks) < indirect_blocks) {
22754 + offsets[n++] = UFS_IND_BLOCK;
22755 +@@ -439,8 +437,6 @@ int ufs_getfrag_block(struct inode *inod
22756 + lock_kernel();
22757 +
22758 + UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
22759 +- if (fragment < 0)
22760 +- goto abort_negative;
22761 + if (fragment >
22762 + ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
22763 + << uspi->s_fpbshift))
22764 +@@ -503,10 +499,6 @@ abort:
22765 + unlock_kernel();
22766 + return err;
22767 +
22768 +-abort_negative:
22769 +- ufs_warning(sb, "ufs_get_block", "block < 0");
22770 +- goto abort;
22771 +-
22772 + abort_too_big:
22773 + ufs_warning(sb, "ufs_get_block", "block > big");
22774 + goto abort;
22775 +diff -Nurp linux-2.6.23.15/fs/utimes.c linux-2.6.23.15-grsec/fs/utimes.c
22776 +--- linux-2.6.23.15/fs/utimes.c 2007-10-09 21:31:38.000000000 +0100
22777 ++++ linux-2.6.23.15-grsec/fs/utimes.c 2008-02-11 10:37:44.000000000 +0000
22778 +@@ -6,6 +6,7 @@
22779 + #include <linux/sched.h>
22780 + #include <linux/stat.h>
22781 + #include <linux/utime.h>
22782 ++#include <linux/grsecurity.h>
22783 + #include <asm/uaccess.h>
22784 + #include <asm/unistd.h>
22785 +
22786 +@@ -47,6 +48,7 @@ long do_utimes(int dfd, char __user *fil
22787 + int error;
22788 + struct nameidata nd;
22789 + struct dentry *dentry;
22790 ++ struct vfsmount *mnt;
22791 + struct inode *inode;
22792 + struct iattr newattrs;
22793 + struct file *f = NULL;
22794 +@@ -65,12 +67,14 @@ long do_utimes(int dfd, char __user *fil
22795 + if (!f)
22796 + goto out;
22797 + dentry = f->f_path.dentry;
22798 ++ mnt = f->f_path.mnt;
22799 + } else {
22800 + error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
22801 + if (error)
22802 + goto out;
22803 +
22804 + dentry = nd.dentry;
22805 ++ mnt = nd.mnt;
22806 + }
22807 +
22808 + inode = dentry->d_inode;
22809 +@@ -117,6 +121,12 @@ long do_utimes(int dfd, char __user *fil
22810 + }
22811 + }
22812 + }
22813 ++
22814 ++ if (!gr_acl_handle_utime(dentry, mnt)) {
22815 ++ error = -EACCES;
22816 ++ goto dput_and_out;
22817 ++ }
22818 ++
22819 + mutex_lock(&inode->i_mutex);
22820 + error = notify_change(dentry, &newattrs);
22821 + mutex_unlock(&inode->i_mutex);
22822 +diff -Nurp linux-2.6.23.15/fs/xfs/xfs_bmap.c linux-2.6.23.15-grsec/fs/xfs/xfs_bmap.c
22823 +--- linux-2.6.23.15/fs/xfs/xfs_bmap.c 2007-10-09 21:31:38.000000000 +0100
22824 ++++ linux-2.6.23.15-grsec/fs/xfs/xfs_bmap.c 2008-02-11 10:37:44.000000000 +0000
22825 +@@ -374,7 +374,7 @@ xfs_bmap_validate_ret(
22826 + int nmap,
22827 + int ret_nmap);
22828 + #else
22829 +-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
22830 ++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
22831 + #endif /* DEBUG */
22832 +
22833 + #if defined(XFS_RW_TRACE)
22834 +diff -Nurp linux-2.6.23.15/grsecurity/Kconfig linux-2.6.23.15-grsec/grsecurity/Kconfig
22835 +--- linux-2.6.23.15/grsecurity/Kconfig 1970-01-01 01:00:00.000000000 +0100
22836 ++++ linux-2.6.23.15-grsec/grsecurity/Kconfig 2008-02-11 10:37:44.000000000 +0000
22837 +@@ -0,0 +1,873 @@
22838 ++#
22839 ++# grecurity configuration
22840 ++#
22841 ++
22842 ++menu "Grsecurity"
22843 ++
22844 ++config GRKERNSEC
22845 ++ bool "Grsecurity"
22846 ++ select CRYPTO
22847 ++ select CRYPTO_SHA256
22848 ++ help
22849 ++ If you say Y here, you will be able to configure many features
22850 ++ that will enhance the security of your system. It is highly
22851 ++ recommended that you say Y here and read through the help
22852 ++ for each option so that you fully understand the features and
22853 ++ can evaluate their usefulness for your machine.
22854 ++
22855 ++choice
22856 ++ prompt "Security Level"
22857 ++ depends GRKERNSEC
22858 ++ default GRKERNSEC_CUSTOM
22859 ++
22860 ++config GRKERNSEC_LOW
22861 ++ bool "Low"
22862 ++ select GRKERNSEC_LINK
22863 ++ select GRKERNSEC_FIFO
22864 ++ select GRKERNSEC_EXECVE
22865 ++ select GRKERNSEC_RANDNET
22866 ++ select GRKERNSEC_DMESG
22867 ++ select GRKERNSEC_CHROOT_CHDIR
22868 ++ select GRKERNSEC_MODSTOP if (MODULES)
22869 ++
22870 ++ help
22871 ++ If you choose this option, several of the grsecurity options will
22872 ++ be enabled that will give you greater protection against a number
22873 ++ of attacks, while assuring that none of your software will have any
22874 ++ conflicts with the additional security measures. If you run a lot
22875 ++ of unusual software, or you are having problems with the higher
22876 ++ security levels, you should say Y here. With this option, the
22877 ++ following features are enabled:
22878 ++
22879 ++ - Linking restrictions
22880 ++ - FIFO restrictions
22881 ++ - Enforcing RLIMIT_NPROC on execve
22882 ++ - Restricted dmesg
22883 ++ - Enforced chdir("/") on chroot
22884 ++ - Runtime module disabling
22885 ++
22886 ++config GRKERNSEC_MEDIUM
22887 ++ bool "Medium"
22888 ++ select PAX
22889 ++ select PAX_EI_PAX
22890 ++ select PAX_PT_PAX_FLAGS
22891 ++ select PAX_HAVE_ACL_FLAGS
22892 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22893 ++ select GRKERNSEC_CHROOT_SYSCTL
22894 ++ select GRKERNSEC_LINK
22895 ++ select GRKERNSEC_FIFO
22896 ++ select GRKERNSEC_EXECVE
22897 ++ select GRKERNSEC_DMESG
22898 ++ select GRKERNSEC_RANDNET
22899 ++ select GRKERNSEC_FORKFAIL
22900 ++ select GRKERNSEC_TIME
22901 ++ select GRKERNSEC_SIGNAL
22902 ++ select GRKERNSEC_CHROOT
22903 ++ select GRKERNSEC_CHROOT_UNIX
22904 ++ select GRKERNSEC_CHROOT_MOUNT
22905 ++ select GRKERNSEC_CHROOT_PIVOT
22906 ++ select GRKERNSEC_CHROOT_DOUBLE
22907 ++ select GRKERNSEC_CHROOT_CHDIR
22908 ++ select GRKERNSEC_CHROOT_MKNOD
22909 ++ select GRKERNSEC_PROC
22910 ++ select GRKERNSEC_PROC_USERGROUP
22911 ++ select GRKERNSEC_MODSTOP if (MODULES)
22912 ++ select PAX_RANDUSTACK
22913 ++ select PAX_ASLR
22914 ++ select PAX_RANDMMAP
22915 ++
22916 ++ help
22917 ++ If you say Y here, several features in addition to those included
22918 ++ in the low additional security level will be enabled. These
22919 ++ features provide even more security to your system, though in rare
22920 ++ cases they may be incompatible with very old or poorly written
22921 ++ software. If you enable this option, make sure that your auth
22922 ++ service (identd) is running as gid 1001. With this option,
22923 ++ the following features (in addition to those provided in the
22924 ++ low additional security level) will be enabled:
22925 ++
22926 ++ - Randomized TCP source ports
22927 ++ - Failed fork logging
22928 ++ - Time change logging
22929 ++ - Signal logging
22930 ++ - Deny mounts in chroot
22931 ++ - Deny double chrooting
22932 ++ - Deny sysctl writes in chroot
22933 ++ - Deny mknod in chroot
22934 ++ - Deny access to abstract AF_UNIX sockets out of chroot
22935 ++ - Deny pivot_root in chroot
22936 ++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
22937 ++ - /proc restrictions with special GID set to 10 (usually wheel)
22938 ++ - Address Space Layout Randomization (ASLR)
22939 ++
22940 ++config GRKERNSEC_HIGH
22941 ++ bool "High"
22942 ++ select GRKERNSEC_LINK
22943 ++ select GRKERNSEC_FIFO
22944 ++ select GRKERNSEC_EXECVE
22945 ++ select GRKERNSEC_DMESG
22946 ++ select GRKERNSEC_FORKFAIL
22947 ++ select GRKERNSEC_TIME
22948 ++ select GRKERNSEC_SIGNAL
22949 ++ select GRKERNSEC_CHROOT_SHMAT
22950 ++ select GRKERNSEC_CHROOT_UNIX
22951 ++ select GRKERNSEC_CHROOT_MOUNT
22952 ++ select GRKERNSEC_CHROOT_FCHDIR
22953 ++ select GRKERNSEC_CHROOT_PIVOT
22954 ++ select GRKERNSEC_CHROOT_DOUBLE
22955 ++ select GRKERNSEC_CHROOT_CHDIR
22956 ++ select GRKERNSEC_CHROOT_MKNOD
22957 ++ select GRKERNSEC_CHROOT_CAPS
22958 ++ select GRKERNSEC_CHROOT_SYSCTL
22959 ++ select GRKERNSEC_CHROOT_FINDTASK
22960 ++ select GRKERNSEC_PROC
22961 ++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22962 ++ select GRKERNSEC_HIDESYM
22963 ++ select GRKERNSEC_BRUTE
22964 ++ select GRKERNSEC_SHM if (SYSVIPC)
22965 ++ select GRKERNSEC_PROC_USERGROUP
22966 ++ select GRKERNSEC_KMEM
22967 ++ select GRKERNSEC_RESLOG
22968 ++ select GRKERNSEC_RANDNET
22969 ++ select GRKERNSEC_PROC_ADD
22970 ++ select GRKERNSEC_CHROOT_CHMOD
22971 ++ select GRKERNSEC_CHROOT_NICE
22972 ++ select GRKERNSEC_AUDIT_MOUNT
22973 ++ select GRKERNSEC_MODSTOP if (MODULES)
22974 ++ select PAX
22975 ++ select PAX_RANDUSTACK
22976 ++ select PAX_ASLR
22977 ++ select PAX_RANDMMAP
22978 ++ select PAX_NOEXEC
22979 ++ select PAX_MPROTECT
22980 ++ select PAX_EI_PAX
22981 ++ select PAX_PT_PAX_FLAGS
22982 ++ select PAX_HAVE_ACL_FLAGS
22983 ++ select PAX_KERNEXEC if (!X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK)
22984 ++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
22985 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
22986 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
22987 ++ select PAX_PAGEEXEC if (!X86)
22988 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
22989 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
22990 ++ select PAX_SYSCALL if (PPC32)
22991 ++ select PAX_EMUTRAMP if (PARISC)
22992 ++ select PAX_EMUSIGRT if (PARISC)
22993 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
22994 ++ help
22995 ++ If you say Y here, many of the features of grsecurity will be
22996 ++ enabled, which will protect you against many kinds of attacks
22997 ++ against your system. The heightened security comes at a cost
22998 ++ of an increased chance of incompatibilities with rare software
22999 ++ on your machine. Since this security level enables PaX, you should
23000 ++ view <http://pax.grsecurity.net> and read about the PaX
23001 ++ project. While you are there, download chpax and run it on
23002 ++ binaries that cause problems with PaX. Also remember that
23003 ++ since the /proc restrictions are enabled, you must run your
23004 ++ identd as gid 1001. This security level enables the following
23005 ++ features in addition to those listed in the low and medium
23006 ++ security levels:
23007 ++
23008 ++ - Additional /proc restrictions
23009 ++ - Chmod restrictions in chroot
23010 ++ - No signals, ptrace, or viewing of processes outside of chroot
23011 ++ - Capability restrictions in chroot
23012 ++ - Deny fchdir out of chroot
23013 ++ - Priority restrictions in chroot
23014 ++ - Segmentation-based implementation of PaX
23015 ++ - Mprotect restrictions
23016 ++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
23017 ++ - Kernel stack randomization
23018 ++ - Mount/unmount/remount logging
23019 ++ - Kernel symbol hiding
23020 ++ - Destroy unused shared memory
23021 ++ - Prevention of memory exhaustion-based exploits
23022 ++config GRKERNSEC_CUSTOM
23023 ++ bool "Custom"
23024 ++ help
23025 ++ If you say Y here, you will be able to configure every grsecurity
23026 ++ option, which allows you to enable many more features that aren't
23027 ++ covered in the basic security levels. These additional features
23028 ++ include TPE, socket restrictions, and the sysctl system for
23029 ++ grsecurity. It is advised that you read through the help for
23030 ++ each option to determine its usefulness in your situation.
23031 ++
23032 ++endchoice
23033 ++
23034 ++menu "Address Space Protection"
23035 ++depends on GRKERNSEC
23036 ++
23037 ++config GRKERNSEC_KMEM
23038 ++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
23039 ++ help
23040 ++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
23041 ++ be written to via mmap or otherwise to modify the running kernel.
23042 ++ /dev/port will also not be allowed to be opened. If you have module
23043 ++ support disabled, enabling this will close up four ways that are
23044 ++ currently used to insert malicious code into the running kernel.
23045 ++ Even with all these features enabled, we still highly recommend that
23046 ++ you use the RBAC system, as it is still possible for an attacker to
23047 ++ modify the running kernel through privileged I/O granted by ioperm/iopl.
23048 ++ If you are not using XFree86, you may be able to stop this additional
23049 ++ case by enabling the 'Disable privileged I/O' option. Though nothing
23050 ++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
23051 ++ but only to video memory, which is the only writing we allow in this
23052 ++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
23053 ++ not be allowed to mprotect it with PROT_WRITE later.
23054 ++ It is highly recommended that you say Y here if you meet all the
23055 ++ conditions above.
23056 ++
23057 ++config GRKERNSEC_IO
23058 ++ bool "Disable privileged I/O"
23059 ++ depends on X86
23060 ++ select RTC
23061 ++ help
23062 ++ If you say Y here, all ioperm and iopl calls will return an error.
23063 ++ Ioperm and iopl can be used to modify the running kernel.
23064 ++ Unfortunately, some programs need this access to operate properly,
23065 ++ the most notable of which are XFree86 and hwclock. hwclock can be
23066 ++ remedied by having RTC support in the kernel, so CONFIG_RTC is
23067 ++ enabled if this option is enabled, to ensure that hwclock operates
23068 ++ correctly. XFree86 still will not operate correctly with this option
23069 ++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
23070 ++ and you still want to protect your kernel against modification,
23071 ++ use the RBAC system.
23072 ++
23073 ++config GRKERNSEC_PROC_MEMMAP
23074 ++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
23075 ++ depends on PAX_NOEXEC || PAX_ASLR
23076 ++ help
23077 ++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
23078 ++ give no information about the addresses of its mappings if
23079 ++ PaX features that rely on random addresses are enabled on the task.
23080 ++ If you use PaX it is greatly recommended that you say Y here as it
23081 ++ closes up a hole that makes the full ASLR useless for suid
23082 ++ binaries.
23083 ++
23084 ++config GRKERNSEC_BRUTE
23085 ++ bool "Deter exploit bruteforcing"
23086 ++ help
23087 ++ If you say Y here, attempts to bruteforce exploits against forking
23088 ++ daemons such as apache or sshd will be deterred. When a child of a
23089 ++ forking daemon is killed by PaX or crashes due to an illegal
23090 ++ instruction, the parent process will be delayed 30 seconds upon every
23091 ++ subsequent fork until the administrator is able to assess the
23092 ++ situation and restart the daemon. It is recommended that you also
23093 ++ enable signal logging in the auditing section so that logs are
23094 ++ generated when a process performs an illegal instruction.
23095 ++
23096 ++config GRKERNSEC_MODSTOP
23097 ++ bool "Runtime module disabling"
23098 ++ depends on MODULES
23099 ++ help
23100 ++ If you say Y here, you will be able to disable the ability to (un)load
23101 ++ modules at runtime. This feature is useful if you need the ability
23102 ++ to load kernel modules at boot time, but do not want to allow an
23103 ++ attacker to load a rootkit kernel module into the system, or to remove
23104 ++ a loaded kernel module important to system functioning. You should
23105 ++ enable the /dev/mem protection feature as well, since rootkits can be
23106 ++ inserted into the kernel via other methods than kernel modules. Since
23107 ++ an untrusted module could still be loaded by modifying init scripts and
23108 ++ rebooting the system, it is also recommended that you enable the RBAC
23109 ++ system. If you enable this option, a sysctl option with name
23110 ++ "disable_modules" will be created. Setting this option to "1" disables
23111 ++ module loading. After this option is set, no further writes to it are
23112 ++ allowed until the system is rebooted.
23113 ++
23114 ++config GRKERNSEC_HIDESYM
23115 ++ bool "Hide kernel symbols"
23116 ++ help
23117 ++ If you say Y here, getting information on loaded modules, and
23118 ++ displaying all kernel symbols through a syscall will be restricted
23119 ++ to users with CAP_SYS_MODULE. This option is only effective
23120 ++ provided the following conditions are met:
23121 ++ 1) The kernel using grsecurity is not precompiled by some distribution
23122 ++ 2) You are using the RBAC system and hiding other files such as your
23123 ++ kernel image and System.map
23124 ++ 3) You have the additional /proc restrictions enabled, which removes
23125 ++ /proc/kcore
23126 ++ If the above conditions are met, this option will aid to provide a
23127 ++ useful protection against local and remote kernel exploitation of
23128 ++ overflows and arbitrary read/write vulnerabilities.
23129 ++
23130 ++endmenu
23131 ++menu "Role Based Access Control Options"
23132 ++depends on GRKERNSEC
23133 ++
23134 ++config GRKERNSEC_ACL_HIDEKERN
23135 ++ bool "Hide kernel processes"
23136 ++ help
23137 ++ If you say Y here, all kernel threads will be hidden to all
23138 ++ processes but those whose subject has the "view hidden processes"
23139 ++ flag.
23140 ++
23141 ++config GRKERNSEC_ACL_MAXTRIES
23142 ++ int "Maximum tries before password lockout"
23143 ++ default 3
23144 ++ help
23145 ++ This option enforces the maximum number of times a user can attempt
23146 ++ to authorize themselves with the grsecurity RBAC system before being
23147 ++ denied the ability to attempt authorization again for a specified time.
23148 ++ The lower the number, the harder it will be to brute-force a password.
23149 ++
23150 ++config GRKERNSEC_ACL_TIMEOUT
23151 ++ int "Time to wait after max password tries, in seconds"
23152 ++ default 30
23153 ++ help
23154 ++ This option specifies the time the user must wait after attempting to
23155 ++ authorize to the RBAC system with the maximum number of invalid
23156 ++ passwords. The higher the number, the harder it will be to brute-force
23157 ++ a password.
23158 ++
23159 ++endmenu
23160 ++menu "Filesystem Protections"
23161 ++depends on GRKERNSEC
23162 ++
23163 ++config GRKERNSEC_PROC
23164 ++ bool "Proc restrictions"
23165 ++ help
23166 ++ If you say Y here, the permissions of the /proc filesystem
23167 ++ will be altered to enhance system security and privacy. You MUST
23168 ++ choose either a user only restriction or a user and group restriction.
23169 ++ Depending upon the option you choose, you can either restrict users to
23170 ++ see only the processes they themselves run, or choose a group that can
23171 ++ view all processes and files normally restricted to root if you choose
23172 ++ the "restrict to user only" option. NOTE: If you're running identd as
23173 ++ a non-root user, you will have to run it as the group you specify here.
23174 ++
23175 ++config GRKERNSEC_PROC_USER
23176 ++ bool "Restrict /proc to user only"
23177 ++ depends on GRKERNSEC_PROC
23178 ++ help
23179 ++ If you say Y here, non-root users will only be able to view their own
23180 ++ processes, and restricts them from viewing network-related information,
23181 ++ and viewing kernel symbol and module information.
23182 ++
23183 ++config GRKERNSEC_PROC_USERGROUP
23184 ++ bool "Allow special group"
23185 ++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
23186 ++ help
23187 ++ If you say Y here, you will be able to select a group that will be
23188 ++ able to view all processes, network-related information, and
23189 ++ kernel and symbol information. This option is useful if you want
23190 ++ to run identd as a non-root user.
23191 ++
23192 ++config GRKERNSEC_PROC_GID
23193 ++ int "GID for special group"
23194 ++ depends on GRKERNSEC_PROC_USERGROUP
23195 ++ default 1001
23196 ++
23197 ++config GRKERNSEC_PROC_ADD
23198 ++ bool "Additional restrictions"
23199 ++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
23200 ++ help
23201 ++ If you say Y here, additional restrictions will be placed on
23202 ++ /proc that keep normal users from viewing device information and
23203 ++ slabinfo information that could be useful for exploits.
23204 ++
23205 ++config GRKERNSEC_LINK
23206 ++ bool "Linking restrictions"
23207 ++ help
23208 ++ If you say Y here, /tmp race exploits will be prevented, since users
23209 ++ will no longer be able to follow symlinks owned by other users in
23210 ++ world-writable +t directories (i.e. /tmp), unless the owner of the
23211 ++ symlink is the owner of the directory. users will also not be
23212 ++ able to hardlink to files they do not own. If the sysctl option is
23213 ++ enabled, a sysctl option with name "linking_restrictions" is created.
23214 ++
23215 ++config GRKERNSEC_FIFO
23216 ++ bool "FIFO restrictions"
23217 ++ help
23218 ++ If you say Y here, users will not be able to write to FIFOs they don't
23219 ++ own in world-writable +t directories (i.e. /tmp), unless the owner of
23220 ++ the FIFO is the same owner of the directory it's held in. If the sysctl
23221 ++ option is enabled, a sysctl option with name "fifo_restrictions" is
23222 ++ created.
23223 ++
23224 ++config GRKERNSEC_CHROOT
23225 ++ bool "Chroot jail restrictions"
23226 ++ help
23227 ++ If you say Y here, you will be able to choose several options that will
23228 ++ make breaking out of a chrooted jail much more difficult. If you
23229 ++ encounter no software incompatibilities with the following options, it
23230 ++ is recommended that you enable each one.
23231 ++
23232 ++config GRKERNSEC_CHROOT_MOUNT
23233 ++ bool "Deny mounts"
23234 ++ depends on GRKERNSEC_CHROOT
23235 ++ help
23236 ++ If you say Y here, processes inside a chroot will not be able to
23237 ++ mount or remount filesystems. If the sysctl option is enabled, a
23238 ++ sysctl option with name "chroot_deny_mount" is created.
23239 ++
23240 ++config GRKERNSEC_CHROOT_DOUBLE
23241 ++ bool "Deny double-chroots"
23242 ++ depends on GRKERNSEC_CHROOT
23243 ++ help
23244 ++ If you say Y here, processes inside a chroot will not be able to chroot
23245 ++ again outside the chroot. This is a widely used method of breaking
23246 ++ out of a chroot jail and should not be allowed. If the sysctl
23247 ++ option is enabled, a sysctl option with name
23248 ++ "chroot_deny_chroot" is created.
23249 ++
23250 ++config GRKERNSEC_CHROOT_PIVOT
23251 ++ bool "Deny pivot_root in chroot"
23252 ++ depends on GRKERNSEC_CHROOT
23253 ++ help
23254 ++ If you say Y here, processes inside a chroot will not be able to use
23255 ++ a function called pivot_root() that was introduced in Linux 2.3.41. It
23256 ++ works similar to chroot in that it changes the root filesystem. This
23257 ++ function could be misused in a chrooted process to attempt to break out
23258 ++ of the chroot, and therefore should not be allowed. If the sysctl
23259 ++ option is enabled, a sysctl option with name "chroot_deny_pivot" is
23260 ++ created.
23261 ++
23262 ++config GRKERNSEC_CHROOT_CHDIR
23263 ++ bool "Enforce chdir(\"/\") on all chroots"
23264 ++ depends on GRKERNSEC_CHROOT
23265 ++ help
23266 ++ If you say Y here, the current working directory of all newly-chrooted
23267 ++ applications will be set to the the root directory of the chroot.
23268 ++ The man page on chroot(2) states:
23269 ++ Note that this call does not change the current working
23270 ++ directory, so that `.' can be outside the tree rooted at
23271 ++ `/'. In particular, the super-user can escape from a
23272 ++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
23273 ++
23274 ++ It is recommended that you say Y here, since it's not known to break
23275 ++ any software. If the sysctl option is enabled, a sysctl option with
23276 ++ name "chroot_enforce_chdir" is created.
23277 ++
23278 ++config GRKERNSEC_CHROOT_CHMOD
23279 ++ bool "Deny (f)chmod +s"
23280 ++ depends on GRKERNSEC_CHROOT
23281 ++ help
23282 ++ If you say Y here, processes inside a chroot will not be able to chmod
23283 ++ or fchmod files to make them have suid or sgid bits. This protects
23284 ++ against another published method of breaking a chroot. If the sysctl
23285 ++ option is enabled, a sysctl option with name "chroot_deny_chmod" is
23286 ++ created.
23287 ++
23288 ++config GRKERNSEC_CHROOT_FCHDIR
23289 ++ bool "Deny fchdir out of chroot"
23290 ++ depends on GRKERNSEC_CHROOT
23291 ++ help
23292 ++ If you say Y here, a well-known method of breaking chroots by fchdir'ing
23293 ++ to a file descriptor of the chrooting process that points to a directory
23294 ++ outside the filesystem will be stopped. If the sysctl option
23295 ++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
23296 ++
23297 ++config GRKERNSEC_CHROOT_MKNOD
23298 ++ bool "Deny mknod"
23299 ++ depends on GRKERNSEC_CHROOT
23300 ++ help
23301 ++ If you say Y here, processes inside a chroot will not be allowed to
23302 ++ mknod. The problem with using mknod inside a chroot is that it
23303 ++ would allow an attacker to create a device entry that is the same
23304 ++ as one on the physical root of your system, which could range from
23305 ++ anything from the console device to a device for your harddrive (which
23306 ++ they could then use to wipe the drive or steal data). It is recommended
23307 ++ that you say Y here, unless you run into software incompatibilities.
23308 ++ If the sysctl option is enabled, a sysctl option with name
23309 ++ "chroot_deny_mknod" is created.
23310 ++
23311 ++config GRKERNSEC_CHROOT_SHMAT
23312 ++ bool "Deny shmat() out of chroot"
23313 ++ depends on GRKERNSEC_CHROOT
23314 ++ help
23315 ++ If you say Y here, processes inside a chroot will not be able to attach
23316 ++ to shared memory segments that were created outside of the chroot jail.
23317 ++ It is recommended that you say Y here. If the sysctl option is enabled,
23318 ++ a sysctl option with name "chroot_deny_shmat" is created.
23319 ++
23320 ++config GRKERNSEC_CHROOT_UNIX
23321 ++ bool "Deny access to abstract AF_UNIX sockets out of chroot"
23322 ++ depends on GRKERNSEC_CHROOT
23323 ++ help
23324 ++ If you say Y here, processes inside a chroot will not be able to
23325 ++ connect to abstract (meaning not belonging to a filesystem) Unix
23326 ++ domain sockets that were bound outside of a chroot. It is recommended
23327 ++ that you say Y here. If the sysctl option is enabled, a sysctl option
23328 ++ with name "chroot_deny_unix" is created.
23329 ++
23330 ++config GRKERNSEC_CHROOT_FINDTASK
23331 ++ bool "Protect outside processes"
23332 ++ depends on GRKERNSEC_CHROOT
23333 ++ help
23334 ++ If you say Y here, processes inside a chroot will not be able to
23335 ++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
23336 ++ or view any process outside of the chroot. If the sysctl
23337 ++ option is enabled, a sysctl option with name "chroot_findtask" is
23338 ++ created.
23339 ++
23340 ++config GRKERNSEC_CHROOT_NICE
23341 ++ bool "Restrict priority changes"
23342 ++ depends on GRKERNSEC_CHROOT
23343 ++ help
23344 ++ If you say Y here, processes inside a chroot will not be able to raise
23345 ++ the priority of processes in the chroot, or alter the priority of
23346 ++ processes outside the chroot. This provides more security than simply
23347 ++ removing CAP_SYS_NICE from the process' capability set. If the
23348 ++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
23349 ++ is created.
23350 ++
23351 ++config GRKERNSEC_CHROOT_SYSCTL
23352 ++ bool "Deny sysctl writes"
23353 ++ depends on GRKERNSEC_CHROOT
23354 ++ help
23355 ++ If you say Y here, an attacker in a chroot will not be able to
23356 ++ write to sysctl entries, either by sysctl(2) or through a /proc
23357 ++ interface. It is strongly recommended that you say Y here. If the
23358 ++ sysctl option is enabled, a sysctl option with name
23359 ++ "chroot_deny_sysctl" is created.
23360 ++
23361 ++config GRKERNSEC_CHROOT_CAPS
23362 ++ bool "Capability restrictions"
23363 ++ depends on GRKERNSEC_CHROOT
23364 ++ help
23365 ++ If you say Y here, the capabilities on all root processes within a
23366 ++ chroot jail will be lowered to stop module insertion, raw i/o,
23367 ++ system and net admin tasks, rebooting the system, modifying immutable
23368 ++ files, modifying IPC owned by another, and changing the system time.
23369 ++ This is left an option because it can break some apps. Disable this
23370 ++ if your chrooted apps are having problems performing those kinds of
23371 ++ tasks. If the sysctl option is enabled, a sysctl option with
23372 ++ name "chroot_caps" is created.
23373 ++
23374 ++endmenu
23375 ++menu "Kernel Auditing"
23376 ++depends on GRKERNSEC
23377 ++
23378 ++config GRKERNSEC_AUDIT_GROUP
23379 ++ bool "Single group for auditing"
23380 ++ help
23381 ++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
23382 ++ will only operate on a group you specify. This option is recommended
23383 ++ if you only want to watch certain users instead of having a large
23384 ++ amount of logs from the entire system. If the sysctl option is enabled,
23385 ++ a sysctl option with name "audit_group" is created.
23386 ++
23387 ++config GRKERNSEC_AUDIT_GID
23388 ++ int "GID for auditing"
23389 ++ depends on GRKERNSEC_AUDIT_GROUP
23390 ++ default 1007
23391 ++
23392 ++config GRKERNSEC_EXECLOG
23393 ++ bool "Exec logging"
23394 ++ help
23395 ++ If you say Y here, all execve() calls will be logged (since the
23396 ++ other exec*() calls are frontends to execve(), all execution
23397 ++ will be logged). Useful for shell-servers that like to keep track
23398 ++ of their users. If the sysctl option is enabled, a sysctl option with
23399 ++ name "exec_logging" is created.
23400 ++ WARNING: This option when enabled will produce a LOT of logs, especially
23401 ++ on an active system.
23402 ++
23403 ++config GRKERNSEC_RESLOG
23404 ++ bool "Resource logging"
23405 ++ help
23406 ++ If you say Y here, all attempts to overstep resource limits will
23407 ++ be logged with the resource name, the requested size, and the current
23408 ++ limit. It is highly recommended that you say Y here. If the sysctl
23409 ++ option is enabled, a sysctl option with name "resource_logging" is
23410 ++ created. If the RBAC system is enabled, the sysctl value is ignored.
23411 ++
23412 ++config GRKERNSEC_CHROOT_EXECLOG
23413 ++ bool "Log execs within chroot"
23414 ++ help
23415 ++ If you say Y here, all executions inside a chroot jail will be logged
23416 ++ to syslog. This can cause a large amount of logs if certain
23417 ++ applications (eg. djb's daemontools) are installed on the system, and
23418 ++ is therefore left as an option. If the sysctl option is enabled, a
23419 ++ sysctl option with name "chroot_execlog" is created.
23420 ++
23421 ++config GRKERNSEC_AUDIT_CHDIR
23422 ++ bool "Chdir logging"
23423 ++ help
23424 ++ If you say Y here, all chdir() calls will be logged. If the sysctl
23425 ++ option is enabled, a sysctl option with name "audit_chdir" is created.
23426 ++
23427 ++config GRKERNSEC_AUDIT_MOUNT
23428 ++ bool "(Un)Mount logging"
23429 ++ help
23430 ++ If you say Y here, all mounts and unmounts will be logged. If the
23431 ++ sysctl option is enabled, a sysctl option with name "audit_mount" is
23432 ++ created.
23433 ++
23434 ++config GRKERNSEC_AUDIT_IPC
23435 ++ bool "IPC logging"
23436 ++ help
23437 ++ If you say Y here, creation and removal of message queues, semaphores,
23438 ++ and shared memory will be logged. If the sysctl option is enabled, a
23439 ++ sysctl option with name "audit_ipc" is created.
23440 ++
23441 ++config GRKERNSEC_SIGNAL
23442 ++ bool "Signal logging"
23443 ++ help
23444 ++ If you say Y here, certain important signals will be logged, such as
23445 ++ SIGSEGV, which will as a result inform you of when a error in a program
23446 ++ occurred, which in some cases could mean a possible exploit attempt.
23447 ++ If the sysctl option is enabled, a sysctl option with name
23448 ++ "signal_logging" is created.
23449 ++
23450 ++config GRKERNSEC_FORKFAIL
23451 ++ bool "Fork failure logging"
23452 ++ help
23453 ++ If you say Y here, all failed fork() attempts will be logged.
23454 ++ This could suggest a fork bomb, or someone attempting to overstep
23455 ++ their process limit. If the sysctl option is enabled, a sysctl option
23456 ++ with name "forkfail_logging" is created.
23457 ++
23458 ++config GRKERNSEC_TIME
23459 ++ bool "Time change logging"
23460 ++ help
23461 ++ If you say Y here, any changes of the system clock will be logged.
23462 ++ If the sysctl option is enabled, a sysctl option with name
23463 ++ "timechange_logging" is created.
23464 ++
23465 ++config GRKERNSEC_PROC_IPADDR
23466 ++ bool "/proc/<pid>/ipaddr support"
23467 ++ help
23468 ++ If you say Y here, a new entry will be added to each /proc/<pid>
23469 ++ directory that contains the IP address of the person using the task.
23470 ++ The IP is carried across local TCP and AF_UNIX stream sockets.
23471 ++ This information can be useful for IDS/IPSes to perform remote response
23472 ++ to a local attack. The entry is readable by only the owner of the
23473 ++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
23474 ++ the RBAC system), and thus does not create privacy concerns.
23475 ++
23476 ++config GRKERNSEC_AUDIT_TEXTREL
23477 ++ bool 'ELF text relocations logging (READ HELP)'
23478 ++ depends on PAX_MPROTECT
23479 ++ help
23480 ++ If you say Y here, text relocations will be logged with the filename
23481 ++ of the offending library or binary. The purpose of the feature is
23482 ++ to help Linux distribution developers get rid of libraries and
23483 ++ binaries that need text relocations which hinder the future progress
23484 ++ of PaX. Only Linux distribution developers should say Y here, and
23485 ++ never on a production machine, as this option creates an information
23486 ++ leak that could aid an attacker in defeating the randomization of
23487 ++ a single memory region. If the sysctl option is enabled, a sysctl
23488 ++ option with name "audit_textrel" is created.
23489 ++
23490 ++endmenu
23491 ++
23492 ++menu "Executable Protections"
23493 ++depends on GRKERNSEC
23494 ++
23495 ++config GRKERNSEC_EXECVE
23496 ++ bool "Enforce RLIMIT_NPROC on execs"
23497 ++ help
23498 ++ If you say Y here, users with a resource limit on processes will
23499 ++ have the value checked during execve() calls. The current system
23500 ++ only checks the system limit during fork() calls. If the sysctl option
23501 ++ is enabled, a sysctl option with name "execve_limiting" is created.
23502 ++
23503 ++config GRKERNSEC_SHM
23504 ++ bool "Destroy unused shared memory"
23505 ++ depends on SYSVIPC
23506 ++ help
23507 ++ If you say Y here, shared memory will be destroyed when no one is
23508 ++ attached to it. Otherwise, resources involved with the shared
23509 ++ memory can be used up and not be associated with any process (as the
23510 ++ shared memory still exists, and the creating process has exited). If
23511 ++ the sysctl option is enabled, a sysctl option with name
23512 ++ "destroy_unused_shm" is created.
23513 ++
23514 ++config GRKERNSEC_DMESG
23515 ++ bool "Dmesg(8) restriction"
23516 ++ help
23517 ++ If you say Y here, non-root users will not be able to use dmesg(8)
23518 ++ to view up to the last 4kb of messages in the kernel's log buffer.
23519 ++ If the sysctl option is enabled, a sysctl option with name "dmesg" is
23520 ++ created.
23521 ++
23522 ++config GRKERNSEC_TPE
23523 ++ bool "Trusted Path Execution (TPE)"
23524 ++ help
23525 ++ If you say Y here, you will be able to choose a gid to add to the
23526 ++ supplementary groups of users you want to mark as "untrusted."
23527 ++ These users will not be able to execute any files that are not in
23528 ++ root-owned directories writable only by root. If the sysctl option
23529 ++ is enabled, a sysctl option with name "tpe" is created.
23530 ++
23531 ++config GRKERNSEC_TPE_ALL
23532 ++ bool "Partially restrict non-root users"
23533 ++ depends on GRKERNSEC_TPE
23534 ++ help
23535 ++ If you say Y here, All non-root users other than the ones in the
23536 ++ group specified in the main TPE option will only be allowed to
23537 ++ execute files in directories they own that are not group or
23538 ++ world-writable, or in directories owned by root and writable only by
23539 ++ root. If the sysctl option is enabled, a sysctl option with name
23540 ++ "tpe_restrict_all" is created.
23541 ++
23542 ++config GRKERNSEC_TPE_INVERT
23543 ++ bool "Invert GID option"
23544 ++ depends on GRKERNSEC_TPE
23545 ++ help
23546 ++ If you say Y here, the group you specify in the TPE configuration will
23547 ++ decide what group TPE restrictions will be *disabled* for. This
23548 ++ option is useful if you want TPE restrictions to be applied to most
23549 ++ users on the system.
23550 ++
23551 ++config GRKERNSEC_TPE_GID
23552 ++ int "GID for untrusted users"
23553 ++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
23554 ++ default 1005
23555 ++ help
23556 ++ If you have selected the "Invert GID option" above, setting this
23557 ++ GID determines what group TPE restrictions will be *disabled* for.
23558 ++ If you have not selected the "Invert GID option" above, setting this
23559 ++ GID determines what group TPE restrictions will be *enabled* for.
23560 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23561 ++ is created.
23562 ++
23563 ++config GRKERNSEC_TPE_GID
23564 ++ int "GID for trusted users"
23565 ++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
23566 ++ default 1005
23567 ++ help
23568 ++ If you have selected the "Invert GID option" above, setting this
23569 ++ GID determines what group TPE restrictions will be *disabled* for.
23570 ++ If you have not selected the "Invert GID option" above, setting this
23571 ++ GID determines what group TPE restrictions will be *enabled* for.
23572 ++ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23573 ++ is created.
23574 ++
23575 ++endmenu
23576 ++menu "Network Protections"
23577 ++depends on GRKERNSEC
23578 ++
23579 ++config GRKERNSEC_RANDNET
23580 ++ bool "Larger entropy pools"
23581 ++ help
23582 ++ If you say Y here, the entropy pools used for many features of Linux
23583 ++ and grsecurity will be doubled in size. Since several grsecurity
23584 ++ features use additional randomness, it is recommended that you say Y
23585 ++ here. Saying Y here has a similar effect as modifying
23586 ++ /proc/sys/kernel/random/poolsize.
23587 ++
23588 ++config GRKERNSEC_SOCKET
23589 ++ bool "Socket restrictions"
23590 ++ help
23591 ++ If you say Y here, you will be able to choose from several options.
23592 ++ If you assign a GID on your system and add it to the supplementary
23593 ++ groups of users you want to restrict socket access to, this patch
23594 ++ will perform up to three things, based on the option(s) you choose.
23595 ++
23596 ++config GRKERNSEC_SOCKET_ALL
23597 ++ bool "Deny any sockets to group"
23598 ++ depends on GRKERNSEC_SOCKET
23599 ++ help
23600 ++ If you say Y here, you will be able to choose a GID of whose users will
23601 ++ be unable to connect to other hosts from your machine or run server
23602 ++ applications from your machine. If the sysctl option is enabled, a
23603 ++ sysctl option with name "socket_all" is created.
23604 ++
23605 ++config GRKERNSEC_SOCKET_ALL_GID
23606 ++ int "GID to deny all sockets for"
23607 ++ depends on GRKERNSEC_SOCKET_ALL
23608 ++ default 1004
23609 ++ help
23610 ++ Here you can choose the GID to disable socket access for. Remember to
23611 ++ add the users you want socket access disabled for to the GID
23612 ++ specified here. If the sysctl option is enabled, a sysctl option
23613 ++ with name "socket_all_gid" is created.
23614 ++
23615 ++config GRKERNSEC_SOCKET_CLIENT
23616 ++ bool "Deny client sockets to group"
23617 ++ depends on GRKERNSEC_SOCKET
23618 ++ help
23619 ++ If you say Y here, you will be able to choose a GID of whose users will
23620 ++ be unable to connect to other hosts from your machine, but will be
23621 ++ able to run servers. If this option is enabled, all users in the group
23622 ++ you specify will have to use passive mode when initiating ftp transfers
23623 ++ from the shell on your machine. If the sysctl option is enabled, a
23624 ++ sysctl option with name "socket_client" is created.
23625 ++
23626 ++config GRKERNSEC_SOCKET_CLIENT_GID
23627 ++ int "GID to deny client sockets for"
23628 ++ depends on GRKERNSEC_SOCKET_CLIENT
23629 ++ default 1003
23630 ++ help
23631 ++ Here you can choose the GID to disable client socket access for.
23632 ++ Remember to add the users you want client socket access disabled for to
23633 ++ the GID specified here. If the sysctl option is enabled, a sysctl
23634 ++ option with name "socket_client_gid" is created.
23635 ++
23636 ++config GRKERNSEC_SOCKET_SERVER
23637 ++ bool "Deny server sockets to group"
23638 ++ depends on GRKERNSEC_SOCKET
23639 ++ help
23640 ++ If you say Y here, you will be able to choose a GID of whose users will
23641 ++ be unable to run server applications from your machine. If the sysctl
23642 ++ option is enabled, a sysctl option with name "socket_server" is created.
23643 ++
23644 ++config GRKERNSEC_SOCKET_SERVER_GID
23645 ++ int "GID to deny server sockets for"
23646 ++ depends on GRKERNSEC_SOCKET_SERVER
23647 ++ default 1002
23648 ++ help
23649 ++ Here you can choose the GID to disable server socket access for.
23650 ++ Remember to add the users you want server socket access disabled for to
23651 ++ the GID specified here. If the sysctl option is enabled, a sysctl
23652 ++ option with name "socket_server_gid" is created.
23653 ++
23654 ++endmenu
23655 ++menu "Sysctl support"
23656 ++depends on GRKERNSEC && SYSCTL
23657 ++
23658 ++config GRKERNSEC_SYSCTL
23659 ++ bool "Sysctl support"
23660 ++ help
23661 ++ If you say Y here, you will be able to change the options that
23662 ++ grsecurity runs with at bootup, without having to recompile your
23663 ++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
23664 ++ to enable (1) or disable (0) various features. All the sysctl entries
23665 ++ are mutable until the "grsec_lock" entry is set to a non-zero value.
23666 ++ All features enabled in the kernel configuration are disabled at boot
23667 ++ if you do not say Y to the "Turn on features by default" option.
23668 ++ All options should be set at startup, and the grsec_lock entry should
23669 ++ be set to a non-zero value after all the options are set.
23670 ++ *THIS IS EXTREMELY IMPORTANT*
23671 ++
23672 ++config GRKERNSEC_SYSCTL_ON
23673 ++ bool "Turn on features by default"
23674 ++ depends on GRKERNSEC_SYSCTL
23675 ++ help
23676 ++ If you say Y here, instead of having all features enabled in the
23677 ++ kernel configuration disabled at boot time, the features will be
23678 ++ enabled at boot time. It is recommended you say Y here unless
23679 ++ there is some reason you would want all sysctl-tunable features to
23680 ++ be disabled by default. As mentioned elsewhere, it is important
23681 ++ to enable the grsec_lock entry once you have finished modifying
23682 ++ the sysctl entries.
23683 ++
23684 ++endmenu
23685 ++menu "Logging Options"
23686 ++depends on GRKERNSEC
23687 ++
23688 ++config GRKERNSEC_FLOODTIME
23689 ++ int "Seconds in between log messages (minimum)"
23690 ++ default 10
23691 ++ help
23692 ++ This option allows you to enforce the number of seconds between
23693 ++ grsecurity log messages. The default should be suitable for most
23694 ++ people, however, if you choose to change it, choose a value small enough
23695 ++ to allow informative logs to be produced, but large enough to
23696 ++ prevent flooding.
23697 ++
23698 ++config GRKERNSEC_FLOODBURST
23699 ++ int "Number of messages in a burst (maximum)"
23700 ++ default 4
23701 ++ help
23702 ++ This option allows you to choose the maximum number of messages allowed
23703 ++ within the flood time interval you chose in a separate option. The
23704 ++ default should be suitable for most people, however if you find that
23705 ++ many of your logs are being interpreted as flooding, you may want to
23706 ++ raise this value.
23707 ++
23708 ++endmenu
23709 ++
23710 ++endmenu
23711 +diff -Nurp linux-2.6.23.15/grsecurity/Makefile linux-2.6.23.15-grsec/grsecurity/Makefile
23712 +--- linux-2.6.23.15/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100
23713 ++++ linux-2.6.23.15-grsec/grsecurity/Makefile 2008-02-11 10:37:44.000000000 +0000
23714 +@@ -0,0 +1,20 @@
23715 ++# grsecurity's ACL system was originally written in 2001 by Michael Dalton
23716 ++# during 2001-2005 it has been completely redesigned by Brad Spengler
23717 ++# into an RBAC system
23718 ++#
23719 ++# All code in this directory and various hooks inserted throughout the kernel
23720 ++# are copyright Brad Spengler, and released under the GPL v2 or higher
23721 ++
23722 ++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
23723 ++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
23724 ++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
23725 ++
23726 ++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
23727 ++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
23728 ++ gracl_learn.o grsec_log.o
23729 ++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
23730 ++
23731 ++ifndef CONFIG_GRKERNSEC
23732 ++obj-y += grsec_disabled.o
23733 ++endif
23734 ++
23735 +diff -Nurp linux-2.6.23.15/grsecurity/gracl.c linux-2.6.23.15-grsec/grsecurity/gracl.c
23736 +--- linux-2.6.23.15/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100
23737 ++++ linux-2.6.23.15-grsec/grsecurity/gracl.c 2008-02-11 10:37:44.000000000 +0000
23738 +@@ -0,0 +1,3722 @@
23739 ++#include <linux/kernel.h>
23740 ++#include <linux/module.h>
23741 ++#include <linux/sched.h>
23742 ++#include <linux/mm.h>
23743 ++#include <linux/file.h>
23744 ++#include <linux/fs.h>
23745 ++#include <linux/namei.h>
23746 ++#include <linux/mount.h>
23747 ++#include <linux/tty.h>
23748 ++#include <linux/proc_fs.h>
23749 ++#include <linux/smp_lock.h>
23750 ++#include <linux/slab.h>
23751 ++#include <linux/vmalloc.h>
23752 ++#include <linux/types.h>
23753 ++#include <linux/capability.h>
23754 ++#include <linux/sysctl.h>
23755 ++#include <linux/netdevice.h>
23756 ++#include <linux/ptrace.h>
23757 ++#include <linux/gracl.h>
23758 ++#include <linux/gralloc.h>
23759 ++#include <linux/grsecurity.h>
23760 ++#include <linux/grinternal.h>
23761 ++#include <linux/pid_namespace.h>
23762 ++#include <linux/percpu.h>
23763 ++
23764 ++#include <asm/uaccess.h>
23765 ++#include <asm/errno.h>
23766 ++#include <asm/mman.h>
23767 ++
23768 ++static struct acl_role_db acl_role_set;
23769 ++static struct name_db name_set;
23770 ++static struct inodev_db inodev_set;
23771 ++
23772 ++/* for keeping track of userspace pointers used for subjects, so we
23773 ++ can share references in the kernel as well
23774 ++*/
23775 ++
23776 ++static struct dentry *real_root;
23777 ++static struct vfsmount *real_root_mnt;
23778 ++
23779 ++static struct acl_subj_map_db subj_map_set;
23780 ++
23781 ++static struct acl_role_label *default_role;
23782 ++
23783 ++static u16 acl_sp_role_value;
23784 ++
23785 ++extern char *gr_shared_page[4];
23786 ++static DECLARE_MUTEX(gr_dev_sem);
23787 ++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
23788 ++
23789 ++struct gr_arg *gr_usermode;
23790 ++
23791 ++static unsigned int gr_status = GR_STATUS_INIT;
23792 ++
23793 ++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
23794 ++extern void gr_clear_learn_entries(void);
23795 ++
23796 ++#ifdef CONFIG_GRKERNSEC_RESLOG
23797 ++extern void gr_log_resource(const struct task_struct *task,
23798 ++ const int res, const unsigned long wanted, const int gt);
23799 ++#endif
23800 ++
23801 ++unsigned char *gr_system_salt;
23802 ++unsigned char *gr_system_sum;
23803 ++
23804 ++static struct sprole_pw **acl_special_roles = NULL;
23805 ++static __u16 num_sprole_pws = 0;
23806 ++
23807 ++static struct acl_role_label *kernel_role = NULL;
23808 ++
23809 ++static unsigned int gr_auth_attempts = 0;
23810 ++static unsigned long gr_auth_expires = 0UL;
23811 ++
23812 ++extern struct vfsmount *sock_mnt;
23813 ++extern struct vfsmount *pipe_mnt;
23814 ++extern struct vfsmount *shm_mnt;
23815 ++static struct acl_object_label *fakefs_obj;
23816 ++
23817 ++extern int gr_init_uidset(void);
23818 ++extern void gr_free_uidset(void);
23819 ++extern void gr_remove_uid(uid_t uid);
23820 ++extern int gr_find_uid(uid_t uid);
23821 ++
23822 ++__inline__ int
23823 ++gr_acl_is_enabled(void)
23824 ++{
23825 ++ return (gr_status & GR_READY);
23826 ++}
23827 ++
23828 ++char gr_roletype_to_char(void)
23829 ++{
23830 ++ switch (current->role->roletype &
23831 ++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
23832 ++ GR_ROLE_SPECIAL)) {
23833 ++ case GR_ROLE_DEFAULT:
23834 ++ return 'D';
23835 ++ case GR_ROLE_USER:
23836 ++ return 'U';
23837 ++ case GR_ROLE_GROUP:
23838 ++ return 'G';
23839 ++ case GR_ROLE_SPECIAL:
23840 ++ return 'S';
23841 ++ }
23842 ++
23843 ++ return 'X';
23844 ++}
23845 ++
23846 ++__inline__ int
23847 ++gr_acl_tpe_check(void)
23848 ++{
23849 ++ if (unlikely(!(gr_status & GR_READY)))
23850 ++ return 0;
23851 ++ if (current->role->roletype & GR_ROLE_TPE)
23852 ++ return 1;
23853 ++ else
23854 ++ return 0;
23855 ++}
23856 ++
23857 ++int
23858 ++gr_handle_rawio(const struct inode *inode)
23859 ++{
23860 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23861 ++ if (inode && S_ISBLK(inode->i_mode) &&
23862 ++ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
23863 ++ !capable(CAP_SYS_RAWIO))
23864 ++ return 1;
23865 ++#endif
23866 ++ return 0;
23867 ++}
23868 ++
23869 ++static int
23870 ++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
23871 ++{
23872 ++ int i;
23873 ++ unsigned long *l1;
23874 ++ unsigned long *l2;
23875 ++ unsigned char *c1;
23876 ++ unsigned char *c2;
23877 ++ int num_longs;
23878 ++
23879 ++ if (likely(lena != lenb))
23880 ++ return 0;
23881 ++
23882 ++ l1 = (unsigned long *)a;
23883 ++ l2 = (unsigned long *)b;
23884 ++
23885 ++ num_longs = lena / sizeof(unsigned long);
23886 ++
23887 ++ for (i = num_longs; i--; l1++, l2++) {
23888 ++ if (unlikely(*l1 != *l2))
23889 ++ return 0;
23890 ++ }
23891 ++
23892 ++ c1 = (unsigned char *) l1;
23893 ++ c2 = (unsigned char *) l2;
23894 ++
23895 ++ i = lena - (num_longs * sizeof(unsigned long));
23896 ++
23897 ++ for (; i--; c1++, c2++) {
23898 ++ if (unlikely(*c1 != *c2))
23899 ++ return 0;
23900 ++ }
23901 ++
23902 ++ return 1;
23903 ++}
23904 ++
23905 ++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
23906 ++ struct dentry *root, struct vfsmount *rootmnt,
23907 ++ char *buffer, int buflen)
23908 ++{
23909 ++ char * end = buffer+buflen;
23910 ++ char * retval;
23911 ++ int namelen;
23912 ++
23913 ++ *--end = '\0';
23914 ++ buflen--;
23915 ++
23916 ++ if (buflen < 1)
23917 ++ goto Elong;
23918 ++ /* Get '/' right */
23919 ++ retval = end-1;
23920 ++ *retval = '/';
23921 ++
23922 ++ for (;;) {
23923 ++ struct dentry * parent;
23924 ++
23925 ++ if (dentry == root && vfsmnt == rootmnt)
23926 ++ break;
23927 ++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
23928 ++ /* Global root? */
23929 ++ spin_lock(&vfsmount_lock);
23930 ++ if (vfsmnt->mnt_parent == vfsmnt) {
23931 ++ spin_unlock(&vfsmount_lock);
23932 ++ goto global_root;
23933 ++ }
23934 ++ dentry = vfsmnt->mnt_mountpoint;
23935 ++ vfsmnt = vfsmnt->mnt_parent;
23936 ++ spin_unlock(&vfsmount_lock);
23937 ++ continue;
23938 ++ }
23939 ++ parent = dentry->d_parent;
23940 ++ prefetch(parent);
23941 ++ namelen = dentry->d_name.len;
23942 ++ buflen -= namelen + 1;
23943 ++ if (buflen < 0)
23944 ++ goto Elong;
23945 ++ end -= namelen;
23946 ++ memcpy(end, dentry->d_name.name, namelen);
23947 ++ *--end = '/';
23948 ++ retval = end;
23949 ++ dentry = parent;
23950 ++ }
23951 ++
23952 ++ return retval;
23953 ++
23954 ++global_root:
23955 ++ namelen = dentry->d_name.len;
23956 ++ buflen -= namelen;
23957 ++ if (buflen < 0)
23958 ++ goto Elong;
23959 ++ retval -= namelen-1; /* hit the slash */
23960 ++ memcpy(retval, dentry->d_name.name, namelen);
23961 ++ return retval;
23962 ++Elong:
23963 ++ return ERR_PTR(-ENAMETOOLONG);
23964 ++}
23965 ++
23966 ++static char *
23967 ++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
23968 ++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
23969 ++{
23970 ++ char *retval;
23971 ++
23972 ++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
23973 ++ if (unlikely(IS_ERR(retval)))
23974 ++ retval = strcpy(buf, "<path too long>");
23975 ++ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
23976 ++ retval[1] = '\0';
23977 ++
23978 ++ return retval;
23979 ++}
23980 ++
23981 ++static char *
23982 ++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
23983 ++ char *buf, int buflen)
23984 ++{
23985 ++ char *res;
23986 ++
23987 ++ /* we can use real_root, real_root_mnt, because this is only called
23988 ++ by the RBAC system */
23989 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
23990 ++
23991 ++ return res;
23992 ++}
23993 ++
23994 ++static char *
23995 ++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
23996 ++ char *buf, int buflen)
23997 ++{
23998 ++ char *res;
23999 ++ struct dentry *root;
24000 ++ struct vfsmount *rootmnt;
24001 ++ struct task_struct *reaper = child_reaper(current);
24002 ++
24003 ++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
24004 ++ read_lock(&reaper->fs->lock);
24005 ++ root = dget(reaper->fs->root);
24006 ++ rootmnt = mntget(reaper->fs->rootmnt);
24007 ++ read_unlock(&reaper->fs->lock);
24008 ++
24009 ++ spin_lock(&dcache_lock);
24010 ++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
24011 ++ spin_unlock(&dcache_lock);
24012 ++
24013 ++ dput(root);
24014 ++ mntput(rootmnt);
24015 ++ return res;
24016 ++}
24017 ++
24018 ++static char *
24019 ++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
24020 ++{
24021 ++ char *ret;
24022 ++ spin_lock(&dcache_lock);
24023 ++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
24024 ++ PAGE_SIZE);
24025 ++ spin_unlock(&dcache_lock);
24026 ++ return ret;
24027 ++}
24028 ++
24029 ++char *
24030 ++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
24031 ++{
24032 ++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
24033 ++ PAGE_SIZE);
24034 ++}
24035 ++
24036 ++char *
24037 ++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
24038 ++{
24039 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
24040 ++ PAGE_SIZE);
24041 ++}
24042 ++
24043 ++char *
24044 ++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
24045 ++{
24046 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
24047 ++ PAGE_SIZE);
24048 ++}
24049 ++
24050 ++char *
24051 ++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
24052 ++{
24053 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
24054 ++ PAGE_SIZE);
24055 ++}
24056 ++
24057 ++char *
24058 ++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
24059 ++{
24060 ++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
24061 ++ PAGE_SIZE);
24062 ++}
24063 ++
24064 ++__inline__ __u32
24065 ++to_gr_audit(const __u32 reqmode)
24066 ++{
24067 ++ /* masks off auditable permission flags, then shifts them to create
24068 ++ auditing flags, and adds the special case of append auditing if
24069 ++ we're requesting write */
24070 ++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
24071 ++}
24072 ++
24073 ++struct acl_subject_label *
24074 ++lookup_subject_map(const struct acl_subject_label *userp)
24075 ++{
24076 ++ unsigned int index = shash(userp, subj_map_set.s_size);
24077 ++ struct subject_map *match;
24078 ++
24079 ++ match = subj_map_set.s_hash[index];
24080 ++
24081 ++ while (match && match->user != userp)
24082 ++ match = match->next;
24083 ++
24084 ++ if (match != NULL)
24085 ++ return match->kernel;
24086 ++ else
24087 ++ return NULL;
24088 ++}
24089 ++
24090 ++static void
24091 ++insert_subj_map_entry(struct subject_map *subjmap)
24092 ++{
24093 ++ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
24094 ++ struct subject_map **curr;
24095 ++
24096 ++ subjmap->prev = NULL;
24097 ++
24098 ++ curr = &subj_map_set.s_hash[index];
24099 ++ if (*curr != NULL)
24100 ++ (*curr)->prev = subjmap;
24101 ++
24102 ++ subjmap->next = *curr;
24103 ++ *curr = subjmap;
24104 ++
24105 ++ return;
24106 ++}
24107 ++
24108 ++static struct acl_role_label *
24109 ++lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
24110 ++ const gid_t gid)
24111 ++{
24112 ++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
24113 ++ struct acl_role_label *match;
24114 ++ struct role_allowed_ip *ipp;
24115 ++ unsigned int x;
24116 ++
24117 ++ match = acl_role_set.r_hash[index];
24118 ++
24119 ++ while (match) {
24120 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
24121 ++ for (x = 0; x < match->domain_child_num; x++) {
24122 ++ if (match->domain_children[x] == uid)
24123 ++ goto found;
24124 ++ }
24125 ++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
24126 ++ break;
24127 ++ match = match->next;
24128 ++ }
24129 ++found:
24130 ++ if (match == NULL) {
24131 ++ try_group:
24132 ++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
24133 ++ match = acl_role_set.r_hash[index];
24134 ++
24135 ++ while (match) {
24136 ++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
24137 ++ for (x = 0; x < match->domain_child_num; x++) {
24138 ++ if (match->domain_children[x] == gid)
24139 ++ goto found2;
24140 ++ }
24141 ++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
24142 ++ break;
24143 ++ match = match->next;
24144 ++ }
24145 ++found2:
24146 ++ if (match == NULL)
24147 ++ match = default_role;
24148 ++ if (match->allowed_ips == NULL)
24149 ++ return match;
24150 ++ else {
24151 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
24152 ++ if (likely
24153 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
24154 ++ (ntohl(ipp->addr) & ipp->netmask)))
24155 ++ return match;
24156 ++ }
24157 ++ match = default_role;
24158 ++ }
24159 ++ } else if (match->allowed_ips == NULL) {
24160 ++ return match;
24161 ++ } else {
24162 ++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
24163 ++ if (likely
24164 ++ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
24165 ++ (ntohl(ipp->addr) & ipp->netmask)))
24166 ++ return match;
24167 ++ }
24168 ++ goto try_group;
24169 ++ }
24170 ++
24171 ++ return match;
24172 ++}
24173 ++
24174 ++struct acl_subject_label *
24175 ++lookup_acl_subj_label(const ino_t ino, const dev_t dev,
24176 ++ const struct acl_role_label *role)
24177 ++{
24178 ++ unsigned int index = fhash(ino, dev, role->subj_hash_size);
24179 ++ struct acl_subject_label *match;
24180 ++
24181 ++ match = role->subj_hash[index];
24182 ++
24183 ++ while (match && (match->inode != ino || match->device != dev ||
24184 ++ (match->mode & GR_DELETED))) {
24185 ++ match = match->next;
24186 ++ }
24187 ++
24188 ++ if (match && !(match->mode & GR_DELETED))
24189 ++ return match;
24190 ++ else
24191 ++ return NULL;
24192 ++}
24193 ++
24194 ++static struct acl_object_label *
24195 ++lookup_acl_obj_label(const ino_t ino, const dev_t dev,
24196 ++ const struct acl_subject_label *subj)
24197 ++{
24198 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
24199 ++ struct acl_object_label *match;
24200 ++
24201 ++ match = subj->obj_hash[index];
24202 ++
24203 ++ while (match && (match->inode != ino || match->device != dev ||
24204 ++ (match->mode & GR_DELETED))) {
24205 ++ match = match->next;
24206 ++ }
24207 ++
24208 ++ if (match && !(match->mode & GR_DELETED))
24209 ++ return match;
24210 ++ else
24211 ++ return NULL;
24212 ++}
24213 ++
24214 ++static struct acl_object_label *
24215 ++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
24216 ++ const struct acl_subject_label *subj)
24217 ++{
24218 ++ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
24219 ++ struct acl_object_label *match;
24220 ++
24221 ++ match = subj->obj_hash[index];
24222 ++
24223 ++ while (match && (match->inode != ino || match->device != dev ||
24224 ++ !(match->mode & GR_DELETED))) {
24225 ++ match = match->next;
24226 ++ }
24227 ++
24228 ++ if (match && (match->mode & GR_DELETED))
24229 ++ return match;
24230 ++
24231 ++ match = subj->obj_hash[index];
24232 ++
24233 ++ while (match && (match->inode != ino || match->device != dev ||
24234 ++ (match->mode & GR_DELETED))) {
24235 ++ match = match->next;
24236 ++ }
24237 ++
24238 ++ if (match && !(match->mode & GR_DELETED))
24239 ++ return match;
24240 ++ else
24241 ++ return NULL;
24242 ++}
24243 ++
24244 ++static struct name_entry *
24245 ++lookup_name_entry(const char *name)
24246 ++{
24247 ++ unsigned int len = strlen(name);
24248 ++ unsigned int key = full_name_hash(name, len);
24249 ++ unsigned int index = key % name_set.n_size;
24250 ++ struct name_entry *match;
24251 ++
24252 ++ match = name_set.n_hash[index];
24253 ++
24254 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
24255 ++ match = match->next;
24256 ++
24257 ++ return match;
24258 ++}
24259 ++
24260 ++static struct name_entry *
24261 ++lookup_name_entry_create(const char *name)
24262 ++{
24263 ++ unsigned int len = strlen(name);
24264 ++ unsigned int key = full_name_hash(name, len);
24265 ++ unsigned int index = key % name_set.n_size;
24266 ++ struct name_entry *match;
24267 ++
24268 ++ match = name_set.n_hash[index];
24269 ++
24270 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
24271 ++ !match->deleted))
24272 ++ match = match->next;
24273 ++
24274 ++ if (match && match->deleted)
24275 ++ return match;
24276 ++
24277 ++ match = name_set.n_hash[index];
24278 ++
24279 ++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
24280 ++ match->deleted))
24281 ++ match = match->next;
24282 ++
24283 ++ if (match && !match->deleted)
24284 ++ return match;
24285 ++ else
24286 ++ return NULL;
24287 ++}
24288 ++
24289 ++static struct inodev_entry *
24290 ++lookup_inodev_entry(const ino_t ino, const dev_t dev)
24291 ++{
24292 ++ unsigned int index = fhash(ino, dev, inodev_set.i_size);
24293 ++ struct inodev_entry *match;
24294 ++
24295 ++ match = inodev_set.i_hash[index];
24296 ++
24297 ++ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
24298 ++ match = match->next;
24299 ++
24300 ++ return match;
24301 ++}
24302 ++
24303 ++static void
24304 ++insert_inodev_entry(struct inodev_entry *entry)
24305 ++{
24306 ++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
24307 ++ inodev_set.i_size);
24308 ++ struct inodev_entry **curr;
24309 ++
24310 ++ entry->prev = NULL;
24311 ++
24312 ++ curr = &inodev_set.i_hash[index];
24313 ++ if (*curr != NULL)
24314 ++ (*curr)->prev = entry;
24315 ++
24316 ++ entry->next = *curr;
24317 ++ *curr = entry;
24318 ++
24319 ++ return;
24320 ++}
24321 ++
24322 ++static void
24323 ++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
24324 ++{
24325 ++ unsigned int index =
24326 ++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
24327 ++ struct acl_role_label **curr;
24328 ++
24329 ++ role->prev = NULL;
24330 ++
24331 ++ curr = &acl_role_set.r_hash[index];
24332 ++ if (*curr != NULL)
24333 ++ (*curr)->prev = role;
24334 ++
24335 ++ role->next = *curr;
24336 ++ *curr = role;
24337 ++
24338 ++ return;
24339 ++}
24340 ++
24341 ++static void
24342 ++insert_acl_role_label(struct acl_role_label *role)
24343 ++{
24344 ++ int i;
24345 ++
24346 ++ if (role->roletype & GR_ROLE_DOMAIN) {
24347 ++ for (i = 0; i < role->domain_child_num; i++)
24348 ++ __insert_acl_role_label(role, role->domain_children[i]);
24349 ++ } else
24350 ++ __insert_acl_role_label(role, role->uidgid);
24351 ++}
24352 ++
24353 ++static int
24354 ++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
24355 ++{
24356 ++ struct name_entry **curr, *nentry;
24357 ++ struct inodev_entry *ientry;
24358 ++ unsigned int len = strlen(name);
24359 ++ unsigned int key = full_name_hash(name, len);
24360 ++ unsigned int index = key % name_set.n_size;
24361 ++
24362 ++ curr = &name_set.n_hash[index];
24363 ++
24364 ++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
24365 ++ curr = &((*curr)->next);
24366 ++
24367 ++ if (*curr != NULL)
24368 ++ return 1;
24369 ++
24370 ++ nentry = acl_alloc(sizeof (struct name_entry));
24371 ++ if (nentry == NULL)
24372 ++ return 0;
24373 ++ ientry = acl_alloc(sizeof (struct inodev_entry));
24374 ++ if (ientry == NULL)
24375 ++ return 0;
24376 ++ ientry->nentry = nentry;
24377 ++
24378 ++ nentry->key = key;
24379 ++ nentry->name = name;
24380 ++ nentry->inode = inode;
24381 ++ nentry->device = device;
24382 ++ nentry->len = len;
24383 ++ nentry->deleted = deleted;
24384 ++
24385 ++ nentry->prev = NULL;
24386 ++ curr = &name_set.n_hash[index];
24387 ++ if (*curr != NULL)
24388 ++ (*curr)->prev = nentry;
24389 ++ nentry->next = *curr;
24390 ++ *curr = nentry;
24391 ++
24392 ++ /* insert us into the table searchable by inode/dev */
24393 ++ insert_inodev_entry(ientry);
24394 ++
24395 ++ return 1;
24396 ++}
24397 ++
24398 ++static void
24399 ++insert_acl_obj_label(struct acl_object_label *obj,
24400 ++ struct acl_subject_label *subj)
24401 ++{
24402 ++ unsigned int index =
24403 ++ fhash(obj->inode, obj->device, subj->obj_hash_size);
24404 ++ struct acl_object_label **curr;
24405 ++
24406 ++
24407 ++ obj->prev = NULL;
24408 ++
24409 ++ curr = &subj->obj_hash[index];
24410 ++ if (*curr != NULL)
24411 ++ (*curr)->prev = obj;
24412 ++
24413 ++ obj->next = *curr;
24414 ++ *curr = obj;
24415 ++
24416 ++ return;
24417 ++}
24418 ++
24419 ++static void
24420 ++insert_acl_subj_label(struct acl_subject_label *obj,
24421 ++ struct acl_role_label *role)
24422 ++{
24423 ++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
24424 ++ struct acl_subject_label **curr;
24425 ++
24426 ++ obj->prev = NULL;
24427 ++
24428 ++ curr = &role->subj_hash[index];
24429 ++ if (*curr != NULL)
24430 ++ (*curr)->prev = obj;
24431 ++
24432 ++ obj->next = *curr;
24433 ++ *curr = obj;
24434 ++
24435 ++ return;
24436 ++}
24437 ++
24438 ++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
24439 ++
24440 ++static void *
24441 ++create_table(__u32 * len, int elementsize)
24442 ++{
24443 ++ unsigned int table_sizes[] = {
24444 ++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
24445 ++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
24446 ++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
24447 ++ 268435399, 536870909, 1073741789, 2147483647
24448 ++ };
24449 ++ void *newtable = NULL;
24450 ++ unsigned int pwr = 0;
24451 ++
24452 ++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
24453 ++ table_sizes[pwr] <= *len)
24454 ++ pwr++;
24455 ++
24456 ++ if (table_sizes[pwr] <= *len)
24457 ++ return newtable;
24458 ++
24459 ++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
24460 ++ newtable =
24461 ++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
24462 ++ else
24463 ++ newtable = vmalloc(table_sizes[pwr] * elementsize);
24464 ++
24465 ++ *len = table_sizes[pwr];
24466 ++
24467 ++ return newtable;
24468 ++}
24469 ++
24470 ++static int
24471 ++init_variables(const struct gr_arg *arg)
24472 ++{
24473 ++ struct task_struct *reaper = child_reaper(current);
24474 ++ unsigned int stacksize;
24475 ++
24476 ++ subj_map_set.s_size = arg->role_db.num_subjects;
24477 ++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
24478 ++ name_set.n_size = arg->role_db.num_objects;
24479 ++ inodev_set.i_size = arg->role_db.num_objects;
24480 ++
24481 ++ if (!subj_map_set.s_size || !acl_role_set.r_size ||
24482 ++ !name_set.n_size || !inodev_set.i_size)
24483 ++ return 1;
24484 ++
24485 ++ if (!gr_init_uidset())
24486 ++ return 1;
24487 ++
24488 ++ /* set up the stack that holds allocation info */
24489 ++
24490 ++ stacksize = arg->role_db.num_pointers + 5;
24491 ++
24492 ++ if (!acl_alloc_stack_init(stacksize))
24493 ++ return 1;
24494 ++
24495 ++ /* grab reference for the real root dentry and vfsmount */
24496 ++ read_lock(&reaper->fs->lock);
24497 ++ real_root_mnt = mntget(reaper->fs->rootmnt);
24498 ++ real_root = dget(reaper->fs->root);
24499 ++ read_unlock(&reaper->fs->lock);
24500 ++
24501 ++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
24502 ++ if (fakefs_obj == NULL)
24503 ++ return 1;
24504 ++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
24505 ++
24506 ++ subj_map_set.s_hash =
24507 ++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
24508 ++ acl_role_set.r_hash =
24509 ++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
24510 ++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
24511 ++ inodev_set.i_hash =
24512 ++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
24513 ++
24514 ++ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
24515 ++ !name_set.n_hash || !inodev_set.i_hash)
24516 ++ return 1;
24517 ++
24518 ++ memset(subj_map_set.s_hash, 0,
24519 ++ sizeof(struct subject_map *) * subj_map_set.s_size);
24520 ++ memset(acl_role_set.r_hash, 0,
24521 ++ sizeof (struct acl_role_label *) * acl_role_set.r_size);
24522 ++ memset(name_set.n_hash, 0,
24523 ++ sizeof (struct name_entry *) * name_set.n_size);
24524 ++ memset(inodev_set.i_hash, 0,
24525 ++ sizeof (struct inodev_entry *) * inodev_set.i_size);
24526 ++
24527 ++ return 0;
24528 ++}
24529 ++
24530 ++/* free information not needed after startup
24531 ++ currently contains user->kernel pointer mappings for subjects
24532 ++*/
24533 ++
24534 ++static void
24535 ++free_init_variables(void)
24536 ++{
24537 ++ __u32 i;
24538 ++
24539 ++ if (subj_map_set.s_hash) {
24540 ++ for (i = 0; i < subj_map_set.s_size; i++) {
24541 ++ if (subj_map_set.s_hash[i]) {
24542 ++ kfree(subj_map_set.s_hash[i]);
24543 ++ subj_map_set.s_hash[i] = NULL;
24544 ++ }
24545 ++ }
24546 ++
24547 ++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
24548 ++ PAGE_SIZE)
24549 ++ kfree(subj_map_set.s_hash);
24550 ++ else
24551 ++ vfree(subj_map_set.s_hash);
24552 ++ }
24553 ++
24554 ++ return;
24555 ++}
24556 ++
24557 ++static void
24558 ++free_variables(void)
24559 ++{
24560 ++ struct acl_subject_label *s;
24561 ++ struct acl_role_label *r;
24562 ++ struct task_struct *task, *task2;
24563 ++ unsigned int i, x;
24564 ++
24565 ++ gr_clear_learn_entries();
24566 ++
24567 ++ read_lock(&tasklist_lock);
24568 ++ do_each_thread(task2, task) {
24569 ++ task->acl_sp_role = 0;
24570 ++ task->acl_role_id = 0;
24571 ++ task->acl = NULL;
24572 ++ task->role = NULL;
24573 ++ } while_each_thread(task2, task);
24574 ++ read_unlock(&tasklist_lock);
24575 ++
24576 ++ /* release the reference to the real root dentry and vfsmount */
24577 ++ if (real_root)
24578 ++ dput(real_root);
24579 ++ real_root = NULL;
24580 ++ if (real_root_mnt)
24581 ++ mntput(real_root_mnt);
24582 ++ real_root_mnt = NULL;
24583 ++
24584 ++ /* free all object hash tables */
24585 ++
24586 ++ FOR_EACH_ROLE_START(r, i)
24587 ++ if (r->subj_hash == NULL)
24588 ++ break;
24589 ++ FOR_EACH_SUBJECT_START(r, s, x)
24590 ++ if (s->obj_hash == NULL)
24591 ++ break;
24592 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
24593 ++ kfree(s->obj_hash);
24594 ++ else
24595 ++ vfree(s->obj_hash);
24596 ++ FOR_EACH_SUBJECT_END(s, x)
24597 ++ FOR_EACH_NESTED_SUBJECT_START(r, s)
24598 ++ if (s->obj_hash == NULL)
24599 ++ break;
24600 ++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
24601 ++ kfree(s->obj_hash);
24602 ++ else
24603 ++ vfree(s->obj_hash);
24604 ++ FOR_EACH_NESTED_SUBJECT_END(s)
24605 ++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
24606 ++ kfree(r->subj_hash);
24607 ++ else
24608 ++ vfree(r->subj_hash);
24609 ++ r->subj_hash = NULL;
24610 ++ FOR_EACH_ROLE_END(r,i)
24611 ++
24612 ++ acl_free_all();
24613 ++
24614 ++ if (acl_role_set.r_hash) {
24615 ++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
24616 ++ PAGE_SIZE)
24617 ++ kfree(acl_role_set.r_hash);
24618 ++ else
24619 ++ vfree(acl_role_set.r_hash);
24620 ++ }
24621 ++ if (name_set.n_hash) {
24622 ++ if ((name_set.n_size * sizeof (struct name_entry *)) <=
24623 ++ PAGE_SIZE)
24624 ++ kfree(name_set.n_hash);
24625 ++ else
24626 ++ vfree(name_set.n_hash);
24627 ++ }
24628 ++
24629 ++ if (inodev_set.i_hash) {
24630 ++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
24631 ++ PAGE_SIZE)
24632 ++ kfree(inodev_set.i_hash);
24633 ++ else
24634 ++ vfree(inodev_set.i_hash);
24635 ++ }
24636 ++
24637 ++ gr_free_uidset();
24638 ++
24639 ++ memset(&name_set, 0, sizeof (struct name_db));
24640 ++ memset(&inodev_set, 0, sizeof (struct inodev_db));
24641 ++ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
24642 ++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
24643 ++
24644 ++ default_role = NULL;
24645 ++
24646 ++ return;
24647 ++}
24648 ++
24649 ++static __u32
24650 ++count_user_objs(struct acl_object_label *userp)
24651 ++{
24652 ++ struct acl_object_label o_tmp;
24653 ++ __u32 num = 0;
24654 ++
24655 ++ while (userp) {
24656 ++ if (copy_from_user(&o_tmp, userp,
24657 ++ sizeof (struct acl_object_label)))
24658 ++ break;
24659 ++
24660 ++ userp = o_tmp.prev;
24661 ++ num++;
24662 ++ }
24663 ++
24664 ++ return num;
24665 ++}
24666 ++
24667 ++static struct acl_subject_label *
24668 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
24669 ++
24670 ++static int
24671 ++copy_user_glob(struct acl_object_label *obj)
24672 ++{
24673 ++ struct acl_object_label *g_tmp, **guser;
24674 ++ unsigned int len;
24675 ++ char *tmp;
24676 ++
24677 ++ if (obj->globbed == NULL)
24678 ++ return 0;
24679 ++
24680 ++ guser = &obj->globbed;
24681 ++ while (*guser) {
24682 ++ g_tmp = (struct acl_object_label *)
24683 ++ acl_alloc(sizeof (struct acl_object_label));
24684 ++ if (g_tmp == NULL)
24685 ++ return -ENOMEM;
24686 ++
24687 ++ if (copy_from_user(g_tmp, *guser,
24688 ++ sizeof (struct acl_object_label)))
24689 ++ return -EFAULT;
24690 ++
24691 ++ len = strnlen_user(g_tmp->filename, PATH_MAX);
24692 ++
24693 ++ if (!len || len >= PATH_MAX)
24694 ++ return -EINVAL;
24695 ++
24696 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24697 ++ return -ENOMEM;
24698 ++
24699 ++ if (copy_from_user(tmp, g_tmp->filename, len))
24700 ++ return -EFAULT;
24701 ++
24702 ++ g_tmp->filename = tmp;
24703 ++
24704 ++ *guser = g_tmp;
24705 ++ guser = &(g_tmp->next);
24706 ++ }
24707 ++
24708 ++ return 0;
24709 ++}
24710 ++
24711 ++static int
24712 ++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
24713 ++ struct acl_role_label *role)
24714 ++{
24715 ++ struct acl_object_label *o_tmp;
24716 ++ unsigned int len;
24717 ++ int ret;
24718 ++ char *tmp;
24719 ++
24720 ++ while (userp) {
24721 ++ if ((o_tmp = (struct acl_object_label *)
24722 ++ acl_alloc(sizeof (struct acl_object_label))) == NULL)
24723 ++ return -ENOMEM;
24724 ++
24725 ++ if (copy_from_user(o_tmp, userp,
24726 ++ sizeof (struct acl_object_label)))
24727 ++ return -EFAULT;
24728 ++
24729 ++ userp = o_tmp->prev;
24730 ++
24731 ++ len = strnlen_user(o_tmp->filename, PATH_MAX);
24732 ++
24733 ++ if (!len || len >= PATH_MAX)
24734 ++ return -EINVAL;
24735 ++
24736 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24737 ++ return -ENOMEM;
24738 ++
24739 ++ if (copy_from_user(tmp, o_tmp->filename, len))
24740 ++ return -EFAULT;
24741 ++
24742 ++ o_tmp->filename = tmp;
24743 ++
24744 ++ insert_acl_obj_label(o_tmp, subj);
24745 ++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
24746 ++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
24747 ++ return -ENOMEM;
24748 ++
24749 ++ ret = copy_user_glob(o_tmp);
24750 ++ if (ret)
24751 ++ return ret;
24752 ++
24753 ++ if (o_tmp->nested) {
24754 ++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
24755 ++ if (IS_ERR(o_tmp->nested))
24756 ++ return PTR_ERR(o_tmp->nested);
24757 ++
24758 ++ /* insert into nested subject list */
24759 ++ o_tmp->nested->next = role->hash->first;
24760 ++ role->hash->first = o_tmp->nested;
24761 ++ }
24762 ++ }
24763 ++
24764 ++ return 0;
24765 ++}
24766 ++
24767 ++static __u32
24768 ++count_user_subjs(struct acl_subject_label *userp)
24769 ++{
24770 ++ struct acl_subject_label s_tmp;
24771 ++ __u32 num = 0;
24772 ++
24773 ++ while (userp) {
24774 ++ if (copy_from_user(&s_tmp, userp,
24775 ++ sizeof (struct acl_subject_label)))
24776 ++ break;
24777 ++
24778 ++ userp = s_tmp.prev;
24779 ++ /* do not count nested subjects against this count, since
24780 ++ they are not included in the hash table, but are
24781 ++ attached to objects. We have already counted
24782 ++ the subjects in userspace for the allocation
24783 ++ stack
24784 ++ */
24785 ++ if (!(s_tmp.mode & GR_NESTED))
24786 ++ num++;
24787 ++ }
24788 ++
24789 ++ return num;
24790 ++}
24791 ++
24792 ++static int
24793 ++copy_user_allowedips(struct acl_role_label *rolep)
24794 ++{
24795 ++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
24796 ++
24797 ++ ruserip = rolep->allowed_ips;
24798 ++
24799 ++ while (ruserip) {
24800 ++ rlast = rtmp;
24801 ++
24802 ++ if ((rtmp = (struct role_allowed_ip *)
24803 ++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
24804 ++ return -ENOMEM;
24805 ++
24806 ++ if (copy_from_user(rtmp, ruserip,
24807 ++ sizeof (struct role_allowed_ip)))
24808 ++ return -EFAULT;
24809 ++
24810 ++ ruserip = rtmp->prev;
24811 ++
24812 ++ if (!rlast) {
24813 ++ rtmp->prev = NULL;
24814 ++ rolep->allowed_ips = rtmp;
24815 ++ } else {
24816 ++ rlast->next = rtmp;
24817 ++ rtmp->prev = rlast;
24818 ++ }
24819 ++
24820 ++ if (!ruserip)
24821 ++ rtmp->next = NULL;
24822 ++ }
24823 ++
24824 ++ return 0;
24825 ++}
24826 ++
24827 ++static int
24828 ++copy_user_transitions(struct acl_role_label *rolep)
24829 ++{
24830 ++ struct role_transition *rusertp, *rtmp = NULL, *rlast;
24831 ++
24832 ++ unsigned int len;
24833 ++ char *tmp;
24834 ++
24835 ++ rusertp = rolep->transitions;
24836 ++
24837 ++ while (rusertp) {
24838 ++ rlast = rtmp;
24839 ++
24840 ++ if ((rtmp = (struct role_transition *)
24841 ++ acl_alloc(sizeof (struct role_transition))) == NULL)
24842 ++ return -ENOMEM;
24843 ++
24844 ++ if (copy_from_user(rtmp, rusertp,
24845 ++ sizeof (struct role_transition)))
24846 ++ return -EFAULT;
24847 ++
24848 ++ rusertp = rtmp->prev;
24849 ++
24850 ++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
24851 ++
24852 ++ if (!len || len >= GR_SPROLE_LEN)
24853 ++ return -EINVAL;
24854 ++
24855 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24856 ++ return -ENOMEM;
24857 ++
24858 ++ if (copy_from_user(tmp, rtmp->rolename, len))
24859 ++ return -EFAULT;
24860 ++
24861 ++ rtmp->rolename = tmp;
24862 ++
24863 ++ if (!rlast) {
24864 ++ rtmp->prev = NULL;
24865 ++ rolep->transitions = rtmp;
24866 ++ } else {
24867 ++ rlast->next = rtmp;
24868 ++ rtmp->prev = rlast;
24869 ++ }
24870 ++
24871 ++ if (!rusertp)
24872 ++ rtmp->next = NULL;
24873 ++ }
24874 ++
24875 ++ return 0;
24876 ++}
24877 ++
24878 ++static struct acl_subject_label *
24879 ++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
24880 ++{
24881 ++ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
24882 ++ unsigned int len;
24883 ++ char *tmp;
24884 ++ __u32 num_objs;
24885 ++ struct acl_ip_label **i_tmp, *i_utmp2;
24886 ++ struct gr_hash_struct ghash;
24887 ++ struct subject_map *subjmap;
24888 ++ unsigned int i_num;
24889 ++ int err;
24890 ++
24891 ++ s_tmp = lookup_subject_map(userp);
24892 ++
24893 ++ /* we've already copied this subject into the kernel, just return
24894 ++ the reference to it, and don't copy it over again
24895 ++ */
24896 ++ if (s_tmp)
24897 ++ return(s_tmp);
24898 ++
24899 ++ if ((s_tmp = (struct acl_subject_label *)
24900 ++ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
24901 ++ return ERR_PTR(-ENOMEM);
24902 ++
24903 ++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
24904 ++ if (subjmap == NULL)
24905 ++ return ERR_PTR(-ENOMEM);
24906 ++
24907 ++ subjmap->user = userp;
24908 ++ subjmap->kernel = s_tmp;
24909 ++ insert_subj_map_entry(subjmap);
24910 ++
24911 ++ if (copy_from_user(s_tmp, userp,
24912 ++ sizeof (struct acl_subject_label)))
24913 ++ return ERR_PTR(-EFAULT);
24914 ++
24915 ++ len = strnlen_user(s_tmp->filename, PATH_MAX);
24916 ++
24917 ++ if (!len || len >= PATH_MAX)
24918 ++ return ERR_PTR(-EINVAL);
24919 ++
24920 ++ if ((tmp = (char *) acl_alloc(len)) == NULL)
24921 ++ return ERR_PTR(-ENOMEM);
24922 ++
24923 ++ if (copy_from_user(tmp, s_tmp->filename, len))
24924 ++ return ERR_PTR(-EFAULT);
24925 ++
24926 ++ s_tmp->filename = tmp;
24927 ++
24928 ++ if (!strcmp(s_tmp->filename, "/"))
24929 ++ role->root_label = s_tmp;
24930 ++
24931 ++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
24932 ++ return ERR_PTR(-EFAULT);
24933 ++
24934 ++ /* copy user and group transition tables */
24935 ++
24936 ++ if (s_tmp->user_trans_num) {
24937 ++ uid_t *uidlist;
24938 ++
24939 ++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
24940 ++ if (uidlist == NULL)
24941 ++ return ERR_PTR(-ENOMEM);
24942 ++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
24943 ++ return ERR_PTR(-EFAULT);
24944 ++
24945 ++ s_tmp->user_transitions = uidlist;
24946 ++ }
24947 ++
24948 ++ if (s_tmp->group_trans_num) {
24949 ++ gid_t *gidlist;
24950 ++
24951 ++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
24952 ++ if (gidlist == NULL)
24953 ++ return ERR_PTR(-ENOMEM);
24954 ++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
24955 ++ return ERR_PTR(-EFAULT);
24956 ++
24957 ++ s_tmp->group_transitions = gidlist;
24958 ++ }
24959 ++
24960 ++ /* set up object hash table */
24961 ++ num_objs = count_user_objs(ghash.first);
24962 ++
24963 ++ s_tmp->obj_hash_size = num_objs;
24964 ++ s_tmp->obj_hash =
24965 ++ (struct acl_object_label **)
24966 ++ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
24967 ++
24968 ++ if (!s_tmp->obj_hash)
24969 ++ return ERR_PTR(-ENOMEM);
24970 ++
24971 ++ memset(s_tmp->obj_hash, 0,
24972 ++ s_tmp->obj_hash_size *
24973 ++ sizeof (struct acl_object_label *));
24974 ++
24975 ++ /* add in objects */
24976 ++ err = copy_user_objs(ghash.first, s_tmp, role);
24977 ++
24978 ++ if (err)
24979 ++ return ERR_PTR(err);
24980 ++
24981 ++ /* set pointer for parent subject */
24982 ++ if (s_tmp->parent_subject) {
24983 ++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
24984 ++
24985 ++ if (IS_ERR(s_tmp2))
24986 ++ return s_tmp2;
24987 ++
24988 ++ s_tmp->parent_subject = s_tmp2;
24989 ++ }
24990 ++
24991 ++ /* add in ip acls */
24992 ++
24993 ++ if (!s_tmp->ip_num) {
24994 ++ s_tmp->ips = NULL;
24995 ++ goto insert;
24996 ++ }
24997 ++
24998 ++ i_tmp =
24999 ++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
25000 ++ sizeof (struct
25001 ++ acl_ip_label *));
25002 ++
25003 ++ if (!i_tmp)
25004 ++ return ERR_PTR(-ENOMEM);
25005 ++
25006 ++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
25007 ++ *(i_tmp + i_num) =
25008 ++ (struct acl_ip_label *)
25009 ++ acl_alloc(sizeof (struct acl_ip_label));
25010 ++ if (!*(i_tmp + i_num))
25011 ++ return ERR_PTR(-ENOMEM);
25012 ++
25013 ++ if (copy_from_user
25014 ++ (&i_utmp2, s_tmp->ips + i_num,
25015 ++ sizeof (struct acl_ip_label *)))
25016 ++ return ERR_PTR(-EFAULT);
25017 ++
25018 ++ if (copy_from_user
25019 ++ (*(i_tmp + i_num), i_utmp2,
25020 ++ sizeof (struct acl_ip_label)))
25021 ++ return ERR_PTR(-EFAULT);
25022 ++
25023 ++ if ((*(i_tmp + i_num))->iface == NULL)
25024 ++ continue;
25025 ++
25026 ++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
25027 ++ if (!len || len >= IFNAMSIZ)
25028 ++ return ERR_PTR(-EINVAL);
25029 ++ tmp = acl_alloc(len);
25030 ++ if (tmp == NULL)
25031 ++ return ERR_PTR(-ENOMEM);
25032 ++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
25033 ++ return ERR_PTR(-EFAULT);
25034 ++ (*(i_tmp + i_num))->iface = tmp;
25035 ++ }
25036 ++
25037 ++ s_tmp->ips = i_tmp;
25038 ++
25039 ++insert:
25040 ++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
25041 ++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
25042 ++ return ERR_PTR(-ENOMEM);
25043 ++
25044 ++ return s_tmp;
25045 ++}
25046 ++
25047 ++static int
25048 ++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
25049 ++{
25050 ++ struct acl_subject_label s_pre;
25051 ++ struct acl_subject_label * ret;
25052 ++ int err;
25053 ++
25054 ++ while (userp) {
25055 ++ if (copy_from_user(&s_pre, userp,
25056 ++ sizeof (struct acl_subject_label)))
25057 ++ return -EFAULT;
25058 ++
25059 ++ /* do not add nested subjects here, add
25060 ++ while parsing objects
25061 ++ */
25062 ++
25063 ++ if (s_pre.mode & GR_NESTED) {
25064 ++ userp = s_pre.prev;
25065 ++ continue;
25066 ++ }
25067 ++
25068 ++ ret = do_copy_user_subj(userp, role);
25069 ++
25070 ++ err = PTR_ERR(ret);
25071 ++ if (IS_ERR(ret))
25072 ++ return err;
25073 ++
25074 ++ insert_acl_subj_label(ret, role);
25075 ++
25076 ++ userp = s_pre.prev;
25077 ++ }
25078 ++
25079 ++ return 0;
25080 ++}
25081 ++
25082 ++static int
25083 ++copy_user_acl(struct gr_arg *arg)
25084 ++{
25085 ++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
25086 ++ struct sprole_pw *sptmp;
25087 ++ struct gr_hash_struct *ghash;
25088 ++ uid_t *domainlist;
25089 ++ unsigned int r_num;
25090 ++ unsigned int len;
25091 ++ char *tmp;
25092 ++ int err = 0;
25093 ++ __u16 i;
25094 ++ __u32 num_subjs;
25095 ++
25096 ++ /* we need a default and kernel role */
25097 ++ if (arg->role_db.num_roles < 2)
25098 ++ return -EINVAL;
25099 ++
25100 ++ /* copy special role authentication info from userspace */
25101 ++
25102 ++ num_sprole_pws = arg->num_sprole_pws;
25103 ++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
25104 ++
25105 ++ if (!acl_special_roles) {
25106 ++ err = -ENOMEM;
25107 ++ goto cleanup;
25108 ++ }
25109 ++
25110 ++ for (i = 0; i < num_sprole_pws; i++) {
25111 ++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
25112 ++ if (!sptmp) {
25113 ++ err = -ENOMEM;
25114 ++ goto cleanup;
25115 ++ }
25116 ++ if (copy_from_user(sptmp, arg->sprole_pws + i,
25117 ++ sizeof (struct sprole_pw))) {
25118 ++ err = -EFAULT;
25119 ++ goto cleanup;
25120 ++ }
25121 ++
25122 ++ len =
25123 ++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
25124 ++
25125 ++ if (!len || len >= GR_SPROLE_LEN) {
25126 ++ err = -EINVAL;
25127 ++ goto cleanup;
25128 ++ }
25129 ++
25130 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
25131 ++ err = -ENOMEM;
25132 ++ goto cleanup;
25133 ++ }
25134 ++
25135 ++ if (copy_from_user(tmp, sptmp->rolename, len)) {
25136 ++ err = -EFAULT;
25137 ++ goto cleanup;
25138 ++ }
25139 ++
25140 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
25141 ++ printk(KERN_ALERT "Copying special role %s\n", tmp);
25142 ++#endif
25143 ++ sptmp->rolename = tmp;
25144 ++ acl_special_roles[i] = sptmp;
25145 ++ }
25146 ++
25147 ++ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
25148 ++
25149 ++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
25150 ++ r_tmp = acl_alloc(sizeof (struct acl_role_label));
25151 ++
25152 ++ if (!r_tmp) {
25153 ++ err = -ENOMEM;
25154 ++ goto cleanup;
25155 ++ }
25156 ++
25157 ++ if (copy_from_user(&r_utmp2, r_utmp + r_num,
25158 ++ sizeof (struct acl_role_label *))) {
25159 ++ err = -EFAULT;
25160 ++ goto cleanup;
25161 ++ }
25162 ++
25163 ++ if (copy_from_user(r_tmp, r_utmp2,
25164 ++ sizeof (struct acl_role_label))) {
25165 ++ err = -EFAULT;
25166 ++ goto cleanup;
25167 ++ }
25168 ++
25169 ++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
25170 ++
25171 ++ if (!len || len >= PATH_MAX) {
25172 ++ err = -EINVAL;
25173 ++ goto cleanup;
25174 ++ }
25175 ++
25176 ++ if ((tmp = (char *) acl_alloc(len)) == NULL) {
25177 ++ err = -ENOMEM;
25178 ++ goto cleanup;
25179 ++ }
25180 ++ if (copy_from_user(tmp, r_tmp->rolename, len)) {
25181 ++ err = -EFAULT;
25182 ++ goto cleanup;
25183 ++ }
25184 ++ r_tmp->rolename = tmp;
25185 ++
25186 ++ if (!strcmp(r_tmp->rolename, "default")
25187 ++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
25188 ++ default_role = r_tmp;
25189 ++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
25190 ++ kernel_role = r_tmp;
25191 ++ }
25192 ++
25193 ++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
25194 ++ err = -ENOMEM;
25195 ++ goto cleanup;
25196 ++ }
25197 ++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
25198 ++ err = -EFAULT;
25199 ++ goto cleanup;
25200 ++ }
25201 ++
25202 ++ r_tmp->hash = ghash;
25203 ++
25204 ++ num_subjs = count_user_subjs(r_tmp->hash->first);
25205 ++
25206 ++ r_tmp->subj_hash_size = num_subjs;
25207 ++ r_tmp->subj_hash =
25208 ++ (struct acl_subject_label **)
25209 ++ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
25210 ++
25211 ++ if (!r_tmp->subj_hash) {
25212 ++ err = -ENOMEM;
25213 ++ goto cleanup;
25214 ++ }
25215 ++
25216 ++ err = copy_user_allowedips(r_tmp);
25217 ++ if (err)
25218 ++ goto cleanup;
25219 ++
25220 ++ /* copy domain info */
25221 ++ if (r_tmp->domain_children != NULL) {
25222 ++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
25223 ++ if (domainlist == NULL) {
25224 ++ err = -ENOMEM;
25225 ++ goto cleanup;
25226 ++ }
25227 ++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
25228 ++ err = -EFAULT;
25229 ++ goto cleanup;
25230 ++ }
25231 ++ r_tmp->domain_children = domainlist;
25232 ++ }
25233 ++
25234 ++ err = copy_user_transitions(r_tmp);
25235 ++ if (err)
25236 ++ goto cleanup;
25237 ++
25238 ++ memset(r_tmp->subj_hash, 0,
25239 ++ r_tmp->subj_hash_size *
25240 ++ sizeof (struct acl_subject_label *));
25241 ++
25242 ++ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
25243 ++
25244 ++ if (err)
25245 ++ goto cleanup;
25246 ++
25247 ++ /* set nested subject list to null */
25248 ++ r_tmp->hash->first = NULL;
25249 ++
25250 ++ insert_acl_role_label(r_tmp);
25251 ++ }
25252 ++
25253 ++ goto return_err;
25254 ++ cleanup:
25255 ++ free_variables();
25256 ++ return_err:
25257 ++ return err;
25258 ++
25259 ++}
25260 ++
25261 ++static int
25262 ++gracl_init(struct gr_arg *args)
25263 ++{
25264 ++ int error = 0;
25265 ++
25266 ++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
25267 ++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
25268 ++
25269 ++ if (init_variables(args)) {
25270 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
25271 ++ error = -ENOMEM;
25272 ++ free_variables();
25273 ++ goto out;
25274 ++ }
25275 ++
25276 ++ error = copy_user_acl(args);
25277 ++ free_init_variables();
25278 ++ if (error) {
25279 ++ free_variables();
25280 ++ goto out;
25281 ++ }
25282 ++
25283 ++ if ((error = gr_set_acls(0))) {
25284 ++ free_variables();
25285 ++ goto out;
25286 ++ }
25287 ++
25288 ++ gr_status |= GR_READY;
25289 ++ out:
25290 ++ return error;
25291 ++}
25292 ++
25293 ++/* derived from glibc fnmatch() 0: match, 1: no match*/
25294 ++
25295 ++static int
25296 ++glob_match(const char *p, const char *n)
25297 ++{
25298 ++ char c;
25299 ++
25300 ++ while ((c = *p++) != '\0') {
25301 ++ switch (c) {
25302 ++ case '?':
25303 ++ if (*n == '\0')
25304 ++ return 1;
25305 ++ else if (*n == '/')
25306 ++ return 1;
25307 ++ break;
25308 ++ case '\\':
25309 ++ if (*n != c)
25310 ++ return 1;
25311 ++ break;
25312 ++ case '*':
25313 ++ for (c = *p++; c == '?' || c == '*'; c = *p++) {
25314 ++ if (*n == '/')
25315 ++ return 1;
25316 ++ else if (c == '?') {
25317 ++ if (*n == '\0')
25318 ++ return 1;
25319 ++ else
25320 ++ ++n;
25321 ++ }
25322 ++ }
25323 ++ if (c == '\0') {
25324 ++ return 0;
25325 ++ } else {
25326 ++ const char *endp;
25327 ++
25328 ++ if ((endp = strchr(n, '/')) == NULL)
25329 ++ endp = n + strlen(n);
25330 ++
25331 ++ if (c == '[') {
25332 ++ for (--p; n < endp; ++n)
25333 ++ if (!glob_match(p, n))
25334 ++ return 0;
25335 ++ } else if (c == '/') {
25336 ++ while (*n != '\0' && *n != '/')
25337 ++ ++n;
25338 ++ if (*n == '/' && !glob_match(p, n + 1))
25339 ++ return 0;
25340 ++ } else {
25341 ++ for (--p; n < endp; ++n)
25342 ++ if (*n == c && !glob_match(p, n))
25343 ++ return 0;
25344 ++ }
25345 ++
25346 ++ return 1;
25347 ++ }
25348 ++ case '[':
25349 ++ {
25350 ++ int not;
25351 ++ char cold;
25352 ++
25353 ++ if (*n == '\0' || *n == '/')
25354 ++ return 1;
25355 ++
25356 ++ not = (*p == '!' || *p == '^');
25357 ++ if (not)
25358 ++ ++p;
25359 ++
25360 ++ c = *p++;
25361 ++ for (;;) {
25362 ++ unsigned char fn = (unsigned char)*n;
25363 ++
25364 ++ if (c == '\0')
25365 ++ return 1;
25366 ++ else {
25367 ++ if (c == fn)
25368 ++ goto matched;
25369 ++ cold = c;
25370 ++ c = *p++;
25371 ++
25372 ++ if (c == '-' && *p != ']') {
25373 ++ unsigned char cend = *p++;
25374 ++
25375 ++ if (cend == '\0')
25376 ++ return 1;
25377 ++
25378 ++ if (cold <= fn && fn <= cend)
25379 ++ goto matched;
25380 ++
25381 ++ c = *p++;
25382 ++ }
25383 ++ }
25384 ++
25385 ++ if (c == ']')
25386 ++ break;
25387 ++ }
25388 ++ if (!not)
25389 ++ return 1;
25390 ++ break;
25391 ++ matched:
25392 ++ while (c != ']') {
25393 ++ if (c == '\0')
25394 ++ return 1;
25395 ++
25396 ++ c = *p++;
25397 ++ }
25398 ++ if (not)
25399 ++ return 1;
25400 ++ }
25401 ++ break;
25402 ++ default:
25403 ++ if (c != *n)
25404 ++ return 1;
25405 ++ }
25406 ++
25407 ++ ++n;
25408 ++ }
25409 ++
25410 ++ if (*n == '\0')
25411 ++ return 0;
25412 ++
25413 ++ if (*n == '/')
25414 ++ return 0;
25415 ++
25416 ++ return 1;
25417 ++}
25418 ++
25419 ++static struct acl_object_label *
25420 ++chk_glob_label(struct acl_object_label *globbed,
25421 ++ struct dentry *dentry, struct vfsmount *mnt, char **path)
25422 ++{
25423 ++ struct acl_object_label *tmp;
25424 ++
25425 ++ if (*path == NULL)
25426 ++ *path = gr_to_filename_nolock(dentry, mnt);
25427 ++
25428 ++ tmp = globbed;
25429 ++
25430 ++ while (tmp) {
25431 ++ if (!glob_match(tmp->filename, *path))
25432 ++ return tmp;
25433 ++ tmp = tmp->next;
25434 ++ }
25435 ++
25436 ++ return NULL;
25437 ++}
25438 ++
25439 ++static struct acl_object_label *
25440 ++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
25441 ++ const ino_t curr_ino, const dev_t curr_dev,
25442 ++ const struct acl_subject_label *subj, char **path)
25443 ++{
25444 ++ struct acl_subject_label *tmpsubj;
25445 ++ struct acl_object_label *retval;
25446 ++ struct acl_object_label *retval2;
25447 ++
25448 ++ tmpsubj = (struct acl_subject_label *) subj;
25449 ++ read_lock(&gr_inode_lock);
25450 ++ do {
25451 ++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
25452 ++ if (retval) {
25453 ++ if (retval->globbed) {
25454 ++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
25455 ++ (struct vfsmount *)orig_mnt, path);
25456 ++ if (retval2)
25457 ++ retval = retval2;
25458 ++ }
25459 ++ break;
25460 ++ }
25461 ++ } while ((tmpsubj = tmpsubj->parent_subject));
25462 ++ read_unlock(&gr_inode_lock);
25463 ++
25464 ++ return retval;
25465 ++}
25466 ++
25467 ++static __inline__ struct acl_object_label *
25468 ++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
25469 ++ const struct dentry *curr_dentry,
25470 ++ const struct acl_subject_label *subj, char **path)
25471 ++{
25472 ++ return __full_lookup(orig_dentry, orig_mnt,
25473 ++ curr_dentry->d_inode->i_ino,
25474 ++ curr_dentry->d_inode->i_sb->s_dev, subj, path);
25475 ++}
25476 ++
25477 ++static struct acl_object_label *
25478 ++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25479 ++ const struct acl_subject_label *subj, char *path)
25480 ++{
25481 ++ struct dentry *dentry = (struct dentry *) l_dentry;
25482 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
25483 ++ struct acl_object_label *retval;
25484 ++
25485 ++ spin_lock(&dcache_lock);
25486 ++
25487 ++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
25488 ++ /* ignore Eric Biederman */
25489 ++ IS_PRIVATE(l_dentry->d_inode))) {
25490 ++ retval = fakefs_obj;
25491 ++ goto out;
25492 ++ }
25493 ++
25494 ++ for (;;) {
25495 ++ if (dentry == real_root && mnt == real_root_mnt)
25496 ++ break;
25497 ++
25498 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
25499 ++ if (mnt->mnt_parent == mnt)
25500 ++ break;
25501 ++
25502 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25503 ++ if (retval != NULL)
25504 ++ goto out;
25505 ++
25506 ++ dentry = mnt->mnt_mountpoint;
25507 ++ mnt = mnt->mnt_parent;
25508 ++ continue;
25509 ++ }
25510 ++
25511 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25512 ++ if (retval != NULL)
25513 ++ goto out;
25514 ++
25515 ++ dentry = dentry->d_parent;
25516 ++ }
25517 ++
25518 ++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
25519 ++
25520 ++ if (retval == NULL)
25521 ++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
25522 ++out:
25523 ++ spin_unlock(&dcache_lock);
25524 ++ return retval;
25525 ++}
25526 ++
25527 ++static __inline__ struct acl_object_label *
25528 ++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25529 ++ const struct acl_subject_label *subj)
25530 ++{
25531 ++ char *path = NULL;
25532 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
25533 ++}
25534 ++
25535 ++static __inline__ struct acl_object_label *
25536 ++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25537 ++ const struct acl_subject_label *subj, char *path)
25538 ++{
25539 ++ return __chk_obj_label(l_dentry, l_mnt, subj, path);
25540 ++}
25541 ++
25542 ++static struct acl_subject_label *
25543 ++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
25544 ++ const struct acl_role_label *role)
25545 ++{
25546 ++ struct dentry *dentry = (struct dentry *) l_dentry;
25547 ++ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
25548 ++ struct acl_subject_label *retval;
25549 ++
25550 ++ spin_lock(&dcache_lock);
25551 ++
25552 ++ for (;;) {
25553 ++ if (dentry == real_root && mnt == real_root_mnt)
25554 ++ break;
25555 ++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
25556 ++ if (mnt->mnt_parent == mnt)
25557 ++ break;
25558 ++
25559 ++ read_lock(&gr_inode_lock);
25560 ++ retval =
25561 ++ lookup_acl_subj_label(dentry->d_inode->i_ino,
25562 ++ dentry->d_inode->i_sb->s_dev, role);
25563 ++ read_unlock(&gr_inode_lock);
25564 ++ if (retval != NULL)
25565 ++ goto out;
25566 ++
25567 ++ dentry = mnt->mnt_mountpoint;
25568 ++ mnt = mnt->mnt_parent;
25569 ++ continue;
25570 ++ }
25571 ++
25572 ++ read_lock(&gr_inode_lock);
25573 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
25574 ++ dentry->d_inode->i_sb->s_dev, role);
25575 ++ read_unlock(&gr_inode_lock);
25576 ++ if (retval != NULL)
25577 ++ goto out;
25578 ++
25579 ++ dentry = dentry->d_parent;
25580 ++ }
25581 ++
25582 ++ read_lock(&gr_inode_lock);
25583 ++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
25584 ++ dentry->d_inode->i_sb->s_dev, role);
25585 ++ read_unlock(&gr_inode_lock);
25586 ++
25587 ++ if (unlikely(retval == NULL)) {
25588 ++ read_lock(&gr_inode_lock);
25589 ++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
25590 ++ real_root->d_inode->i_sb->s_dev, role);
25591 ++ read_unlock(&gr_inode_lock);
25592 ++ }
25593 ++out:
25594 ++ spin_unlock(&dcache_lock);
25595 ++
25596 ++ return retval;
25597 ++}
25598 ++
25599 ++static void
25600 ++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
25601 ++{
25602 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
25603 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
25604 ++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
25605 ++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
25606 ++
25607 ++ return;
25608 ++}
25609 ++
25610 ++static void
25611 ++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
25612 ++{
25613 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
25614 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
25615 ++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
25616 ++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
25617 ++
25618 ++ return;
25619 ++}
25620 ++
25621 ++static void
25622 ++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
25623 ++ const unsigned int effective, const unsigned int fs)
25624 ++{
25625 ++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
25626 ++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
25627 ++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
25628 ++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
25629 ++
25630 ++ return;
25631 ++}
25632 ++
25633 ++__u32
25634 ++gr_check_link(const struct dentry * new_dentry,
25635 ++ const struct dentry * parent_dentry,
25636 ++ const struct vfsmount * parent_mnt,
25637 ++ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
25638 ++{
25639 ++ struct acl_object_label *obj;
25640 ++ __u32 oldmode, newmode;
25641 ++ __u32 needmode;
25642 ++
25643 ++ if (unlikely(!(gr_status & GR_READY)))
25644 ++ return (GR_CREATE | GR_LINK);
25645 ++
25646 ++ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
25647 ++ oldmode = obj->mode;
25648 ++
25649 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25650 ++ oldmode |= (GR_CREATE | GR_LINK);
25651 ++
25652 ++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
25653 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
25654 ++ needmode |= GR_SETID | GR_AUDIT_SETID;
25655 ++
25656 ++ newmode =
25657 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
25658 ++ oldmode | needmode);
25659 ++
25660 ++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
25661 ++ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
25662 ++ GR_INHERIT | GR_AUDIT_INHERIT);
25663 ++
25664 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
25665 ++ goto bad;
25666 ++
25667 ++ if ((oldmode & needmode) != needmode)
25668 ++ goto bad;
25669 ++
25670 ++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
25671 ++ if ((newmode & needmode) != needmode)
25672 ++ goto bad;
25673 ++
25674 ++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
25675 ++ return newmode;
25676 ++bad:
25677 ++ needmode = oldmode;
25678 ++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
25679 ++ needmode |= GR_SETID;
25680 ++
25681 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
25682 ++ gr_log_learn(current, old_dentry, old_mnt, needmode);
25683 ++ return (GR_CREATE | GR_LINK);
25684 ++ } else if (newmode & GR_SUPPRESS)
25685 ++ return GR_SUPPRESS;
25686 ++ else
25687 ++ return 0;
25688 ++}
25689 ++
25690 ++__u32
25691 ++gr_search_file(const struct dentry * dentry, const __u32 mode,
25692 ++ const struct vfsmount * mnt)
25693 ++{
25694 ++ __u32 retval = mode;
25695 ++ struct acl_subject_label *curracl;
25696 ++ struct acl_object_label *currobj;
25697 ++
25698 ++ if (unlikely(!(gr_status & GR_READY)))
25699 ++ return (mode & ~GR_AUDITS);
25700 ++
25701 ++ curracl = current->acl;
25702 ++
25703 ++ currobj = chk_obj_label(dentry, mnt, curracl);
25704 ++ retval = currobj->mode & mode;
25705 ++
25706 ++ if (unlikely
25707 ++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
25708 ++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
25709 ++ __u32 new_mode = mode;
25710 ++
25711 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25712 ++
25713 ++ retval = new_mode;
25714 ++
25715 ++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
25716 ++ new_mode |= GR_INHERIT;
25717 ++
25718 ++ if (!(mode & GR_NOLEARN))
25719 ++ gr_log_learn(current, dentry, mnt, new_mode);
25720 ++ }
25721 ++
25722 ++ return retval;
25723 ++}
25724 ++
25725 ++__u32
25726 ++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
25727 ++ const struct vfsmount * mnt, const __u32 mode)
25728 ++{
25729 ++ struct name_entry *match;
25730 ++ struct acl_object_label *matchpo;
25731 ++ struct acl_subject_label *curracl;
25732 ++ char *path;
25733 ++ __u32 retval;
25734 ++
25735 ++ if (unlikely(!(gr_status & GR_READY)))
25736 ++ return (mode & ~GR_AUDITS);
25737 ++
25738 ++ preempt_disable();
25739 ++ path = gr_to_filename_rbac(new_dentry, mnt);
25740 ++ match = lookup_name_entry_create(path);
25741 ++
25742 ++ if (!match)
25743 ++ goto check_parent;
25744 ++
25745 ++ curracl = current->acl;
25746 ++
25747 ++ read_lock(&gr_inode_lock);
25748 ++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
25749 ++ read_unlock(&gr_inode_lock);
25750 ++
25751 ++ if (matchpo) {
25752 ++ if ((matchpo->mode & mode) !=
25753 ++ (mode & ~(GR_AUDITS | GR_SUPPRESS))
25754 ++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
25755 ++ __u32 new_mode = mode;
25756 ++
25757 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25758 ++
25759 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
25760 ++
25761 ++ preempt_enable();
25762 ++ return new_mode;
25763 ++ }
25764 ++ preempt_enable();
25765 ++ return (matchpo->mode & mode);
25766 ++ }
25767 ++
25768 ++ check_parent:
25769 ++ curracl = current->acl;
25770 ++
25771 ++ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
25772 ++ retval = matchpo->mode & mode;
25773 ++
25774 ++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
25775 ++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
25776 ++ __u32 new_mode = mode;
25777 ++
25778 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
25779 ++
25780 ++ gr_log_learn(current, new_dentry, mnt, new_mode);
25781 ++ preempt_enable();
25782 ++ return new_mode;
25783 ++ }
25784 ++
25785 ++ preempt_enable();
25786 ++ return retval;
25787 ++}
25788 ++
25789 ++int
25790 ++gr_check_hidden_task(const struct task_struct *task)
25791 ++{
25792 ++ if (unlikely(!(gr_status & GR_READY)))
25793 ++ return 0;
25794 ++
25795 ++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
25796 ++ return 1;
25797 ++
25798 ++ return 0;
25799 ++}
25800 ++
25801 ++int
25802 ++gr_check_protected_task(const struct task_struct *task)
25803 ++{
25804 ++ if (unlikely(!(gr_status & GR_READY) || !task))
25805 ++ return 0;
25806 ++
25807 ++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
25808 ++ task->acl != current->acl)
25809 ++ return 1;
25810 ++
25811 ++ return 0;
25812 ++}
25813 ++
25814 ++void
25815 ++gr_copy_label(struct task_struct *tsk)
25816 ++{
25817 ++ tsk->signal->used_accept = 0;
25818 ++ tsk->acl_sp_role = 0;
25819 ++ tsk->acl_role_id = current->acl_role_id;
25820 ++ tsk->acl = current->acl;
25821 ++ tsk->role = current->role;
25822 ++ tsk->signal->curr_ip = current->signal->curr_ip;
25823 ++ if (current->exec_file)
25824 ++ get_file(current->exec_file);
25825 ++ tsk->exec_file = current->exec_file;
25826 ++ tsk->is_writable = current->is_writable;
25827 ++ if (unlikely(current->signal->used_accept))
25828 ++ current->signal->curr_ip = 0;
25829 ++
25830 ++ return;
25831 ++}
25832 ++
25833 ++static void
25834 ++gr_set_proc_res(struct task_struct *task)
25835 ++{
25836 ++ struct acl_subject_label *proc;
25837 ++ unsigned short i;
25838 ++
25839 ++ proc = task->acl;
25840 ++
25841 ++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
25842 ++ return;
25843 ++
25844 ++ for (i = 0; i < (GR_NLIMITS - 1); i++) {
25845 ++ if (!(proc->resmask & (1 << i)))
25846 ++ continue;
25847 ++
25848 ++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
25849 ++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
25850 ++ }
25851 ++
25852 ++ return;
25853 ++}
25854 ++
25855 ++int
25856 ++gr_check_user_change(int real, int effective, int fs)
25857 ++{
25858 ++ unsigned int i;
25859 ++ __u16 num;
25860 ++ uid_t *uidlist;
25861 ++ int curuid;
25862 ++ int realok = 0;
25863 ++ int effectiveok = 0;
25864 ++ int fsok = 0;
25865 ++
25866 ++ if (unlikely(!(gr_status & GR_READY)))
25867 ++ return 0;
25868 ++
25869 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25870 ++ gr_log_learn_id_change(current, 'u', real, effective, fs);
25871 ++
25872 ++ num = current->acl->user_trans_num;
25873 ++ uidlist = current->acl->user_transitions;
25874 ++
25875 ++ if (uidlist == NULL)
25876 ++ return 0;
25877 ++
25878 ++ if (real == -1)
25879 ++ realok = 1;
25880 ++ if (effective == -1)
25881 ++ effectiveok = 1;
25882 ++ if (fs == -1)
25883 ++ fsok = 1;
25884 ++
25885 ++ if (current->acl->user_trans_type & GR_ID_ALLOW) {
25886 ++ for (i = 0; i < num; i++) {
25887 ++ curuid = (int)uidlist[i];
25888 ++ if (real == curuid)
25889 ++ realok = 1;
25890 ++ if (effective == curuid)
25891 ++ effectiveok = 1;
25892 ++ if (fs == curuid)
25893 ++ fsok = 1;
25894 ++ }
25895 ++ } else if (current->acl->user_trans_type & GR_ID_DENY) {
25896 ++ for (i = 0; i < num; i++) {
25897 ++ curuid = (int)uidlist[i];
25898 ++ if (real == curuid)
25899 ++ break;
25900 ++ if (effective == curuid)
25901 ++ break;
25902 ++ if (fs == curuid)
25903 ++ break;
25904 ++ }
25905 ++ /* not in deny list */
25906 ++ if (i == num) {
25907 ++ realok = 1;
25908 ++ effectiveok = 1;
25909 ++ fsok = 1;
25910 ++ }
25911 ++ }
25912 ++
25913 ++ if (realok && effectiveok && fsok)
25914 ++ return 0;
25915 ++ else {
25916 ++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
25917 ++ return 1;
25918 ++ }
25919 ++}
25920 ++
25921 ++int
25922 ++gr_check_group_change(int real, int effective, int fs)
25923 ++{
25924 ++ unsigned int i;
25925 ++ __u16 num;
25926 ++ gid_t *gidlist;
25927 ++ int curgid;
25928 ++ int realok = 0;
25929 ++ int effectiveok = 0;
25930 ++ int fsok = 0;
25931 ++
25932 ++ if (unlikely(!(gr_status & GR_READY)))
25933 ++ return 0;
25934 ++
25935 ++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
25936 ++ gr_log_learn_id_change(current, 'g', real, effective, fs);
25937 ++
25938 ++ num = current->acl->group_trans_num;
25939 ++ gidlist = current->acl->group_transitions;
25940 ++
25941 ++ if (gidlist == NULL)
25942 ++ return 0;
25943 ++
25944 ++ if (real == -1)
25945 ++ realok = 1;
25946 ++ if (effective == -1)
25947 ++ effectiveok = 1;
25948 ++ if (fs == -1)
25949 ++ fsok = 1;
25950 ++
25951 ++ if (current->acl->group_trans_type & GR_ID_ALLOW) {
25952 ++ for (i = 0; i < num; i++) {
25953 ++ curgid = (int)gidlist[i];
25954 ++ if (real == curgid)
25955 ++ realok = 1;
25956 ++ if (effective == curgid)
25957 ++ effectiveok = 1;
25958 ++ if (fs == curgid)
25959 ++ fsok = 1;
25960 ++ }
25961 ++ } else if (current->acl->group_trans_type & GR_ID_DENY) {
25962 ++ for (i = 0; i < num; i++) {
25963 ++ curgid = (int)gidlist[i];
25964 ++ if (real == curgid)
25965 ++ break;
25966 ++ if (effective == curgid)
25967 ++ break;
25968 ++ if (fs == curgid)
25969 ++ break;
25970 ++ }
25971 ++ /* not in deny list */
25972 ++ if (i == num) {
25973 ++ realok = 1;
25974 ++ effectiveok = 1;
25975 ++ fsok = 1;
25976 ++ }
25977 ++ }
25978 ++
25979 ++ if (realok && effectiveok && fsok)
25980 ++ return 0;
25981 ++ else {
25982 ++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
25983 ++ return 1;
25984 ++ }
25985 ++}
25986 ++
25987 ++void
25988 ++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
25989 ++{
25990 ++ struct acl_role_label *role = task->role;
25991 ++ struct acl_subject_label *subj = NULL;
25992 ++ struct acl_object_label *obj;
25993 ++ struct file *filp;
25994 ++
25995 ++ if (unlikely(!(gr_status & GR_READY)))
25996 ++ return;
25997 ++
25998 ++ filp = task->exec_file;
25999 ++
26000 ++ /* kernel process, we'll give them the kernel role */
26001 ++ if (unlikely(!filp)) {
26002 ++ task->role = kernel_role;
26003 ++ task->acl = kernel_role->root_label;
26004 ++ return;
26005 ++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
26006 ++ role = lookup_acl_role_label(task, uid, gid);
26007 ++
26008 ++ /* perform subject lookup in possibly new role
26009 ++ we can use this result below in the case where role == task->role
26010 ++ */
26011 ++ subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
26012 ++
26013 ++ /* if we changed uid/gid, but result in the same role
26014 ++ and are using inheritance, don't lose the inherited subject
26015 ++ if current subject is other than what normal lookup
26016 ++ would result in, we arrived via inheritance, don't
26017 ++ lose subject
26018 ++ */
26019 ++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
26020 ++ (subj == task->acl)))
26021 ++ task->acl = subj;
26022 ++
26023 ++ task->role = role;
26024 ++
26025 ++ task->is_writable = 0;
26026 ++
26027 ++ /* ignore additional mmap checks for processes that are writable
26028 ++ by the default ACL */
26029 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
26030 ++ if (unlikely(obj->mode & GR_WRITE))
26031 ++ task->is_writable = 1;
26032 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
26033 ++ if (unlikely(obj->mode & GR_WRITE))
26034 ++ task->is_writable = 1;
26035 ++
26036 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26037 ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
26038 ++#endif
26039 ++
26040 ++ gr_set_proc_res(task);
26041 ++
26042 ++ return;
26043 ++}
26044 ++
26045 ++int
26046 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
26047 ++{
26048 ++ struct task_struct *task = current;
26049 ++ struct acl_subject_label *newacl;
26050 ++ struct acl_object_label *obj;
26051 ++ __u32 retmode;
26052 ++
26053 ++ if (unlikely(!(gr_status & GR_READY)))
26054 ++ return 0;
26055 ++
26056 ++ newacl = chk_subj_label(dentry, mnt, task->role);
26057 ++
26058 ++ task_lock(task);
26059 ++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
26060 ++ GR_POVERRIDE) && (task->acl != newacl) &&
26061 ++ !(task->role->roletype & GR_ROLE_GOD) &&
26062 ++ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
26063 ++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
26064 ++ (atomic_read(&task->fs->count) > 1 ||
26065 ++ atomic_read(&task->files->count) > 1 ||
26066 ++ atomic_read(&task->sighand->count) > 1)) {
26067 ++ task_unlock(task);
26068 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
26069 ++ return -EACCES;
26070 ++ }
26071 ++ task_unlock(task);
26072 ++
26073 ++ obj = chk_obj_label(dentry, mnt, task->acl);
26074 ++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
26075 ++
26076 ++ if (!(task->acl->mode & GR_INHERITLEARN) &&
26077 ++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
26078 ++ if (obj->nested)
26079 ++ task->acl = obj->nested;
26080 ++ else
26081 ++ task->acl = newacl;
26082 ++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
26083 ++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
26084 ++
26085 ++ task->is_writable = 0;
26086 ++
26087 ++ /* ignore additional mmap checks for processes that are writable
26088 ++ by the default ACL */
26089 ++ obj = chk_obj_label(dentry, mnt, default_role->root_label);
26090 ++ if (unlikely(obj->mode & GR_WRITE))
26091 ++ task->is_writable = 1;
26092 ++ obj = chk_obj_label(dentry, mnt, task->role->root_label);
26093 ++ if (unlikely(obj->mode & GR_WRITE))
26094 ++ task->is_writable = 1;
26095 ++
26096 ++ gr_set_proc_res(task);
26097 ++
26098 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26099 ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
26100 ++#endif
26101 ++ return 0;
26102 ++}
26103 ++
26104 ++/* always called with valid inodev ptr */
26105 ++static void
26106 ++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
26107 ++{
26108 ++ struct acl_object_label *matchpo;
26109 ++ struct acl_subject_label *matchps;
26110 ++ struct acl_subject_label *subj;
26111 ++ struct acl_role_label *role;
26112 ++ unsigned int i, x;
26113 ++
26114 ++ FOR_EACH_ROLE_START(role, i)
26115 ++ FOR_EACH_SUBJECT_START(role, subj, x)
26116 ++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
26117 ++ matchpo->mode |= GR_DELETED;
26118 ++ FOR_EACH_SUBJECT_END(subj,x)
26119 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
26120 ++ if (subj->inode == ino && subj->device == dev)
26121 ++ subj->mode |= GR_DELETED;
26122 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
26123 ++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
26124 ++ matchps->mode |= GR_DELETED;
26125 ++ FOR_EACH_ROLE_END(role,i)
26126 ++
26127 ++ inodev->nentry->deleted = 1;
26128 ++
26129 ++ return;
26130 ++}
26131 ++
26132 ++void
26133 ++gr_handle_delete(const ino_t ino, const dev_t dev)
26134 ++{
26135 ++ struct inodev_entry *inodev;
26136 ++
26137 ++ if (unlikely(!(gr_status & GR_READY)))
26138 ++ return;
26139 ++
26140 ++ write_lock(&gr_inode_lock);
26141 ++ inodev = lookup_inodev_entry(ino, dev);
26142 ++ if (inodev != NULL)
26143 ++ do_handle_delete(inodev, ino, dev);
26144 ++ write_unlock(&gr_inode_lock);
26145 ++
26146 ++ return;
26147 ++}
26148 ++
26149 ++static void
26150 ++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
26151 ++ const ino_t newinode, const dev_t newdevice,
26152 ++ struct acl_subject_label *subj)
26153 ++{
26154 ++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
26155 ++ struct acl_object_label *match;
26156 ++
26157 ++ match = subj->obj_hash[index];
26158 ++
26159 ++ while (match && (match->inode != oldinode ||
26160 ++ match->device != olddevice ||
26161 ++ !(match->mode & GR_DELETED)))
26162 ++ match = match->next;
26163 ++
26164 ++ if (match && (match->inode == oldinode)
26165 ++ && (match->device == olddevice)
26166 ++ && (match->mode & GR_DELETED)) {
26167 ++ if (match->prev == NULL) {
26168 ++ subj->obj_hash[index] = match->next;
26169 ++ if (match->next != NULL)
26170 ++ match->next->prev = NULL;
26171 ++ } else {
26172 ++ match->prev->next = match->next;
26173 ++ if (match->next != NULL)
26174 ++ match->next->prev = match->prev;
26175 ++ }
26176 ++ match->prev = NULL;
26177 ++ match->next = NULL;
26178 ++ match->inode = newinode;
26179 ++ match->device = newdevice;
26180 ++ match->mode &= ~GR_DELETED;
26181 ++
26182 ++ insert_acl_obj_label(match, subj);
26183 ++ }
26184 ++
26185 ++ return;
26186 ++}
26187 ++
26188 ++static void
26189 ++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
26190 ++ const ino_t newinode, const dev_t newdevice,
26191 ++ struct acl_role_label *role)
26192 ++{
26193 ++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
26194 ++ struct acl_subject_label *match;
26195 ++
26196 ++ match = role->subj_hash[index];
26197 ++
26198 ++ while (match && (match->inode != oldinode ||
26199 ++ match->device != olddevice ||
26200 ++ !(match->mode & GR_DELETED)))
26201 ++ match = match->next;
26202 ++
26203 ++ if (match && (match->inode == oldinode)
26204 ++ && (match->device == olddevice)
26205 ++ && (match->mode & GR_DELETED)) {
26206 ++ if (match->prev == NULL) {
26207 ++ role->subj_hash[index] = match->next;
26208 ++ if (match->next != NULL)
26209 ++ match->next->prev = NULL;
26210 ++ } else {
26211 ++ match->prev->next = match->next;
26212 ++ if (match->next != NULL)
26213 ++ match->next->prev = match->prev;
26214 ++ }
26215 ++ match->prev = NULL;
26216 ++ match->next = NULL;
26217 ++ match->inode = newinode;
26218 ++ match->device = newdevice;
26219 ++ match->mode &= ~GR_DELETED;
26220 ++
26221 ++ insert_acl_subj_label(match, role);
26222 ++ }
26223 ++
26224 ++ return;
26225 ++}
26226 ++
26227 ++static void
26228 ++update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
26229 ++ const ino_t newinode, const dev_t newdevice)
26230 ++{
26231 ++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
26232 ++ struct inodev_entry *match;
26233 ++
26234 ++ match = inodev_set.i_hash[index];
26235 ++
26236 ++ while (match && (match->nentry->inode != oldinode ||
26237 ++ match->nentry->device != olddevice || !match->nentry->deleted))
26238 ++ match = match->next;
26239 ++
26240 ++ if (match && (match->nentry->inode == oldinode)
26241 ++ && (match->nentry->device == olddevice) &&
26242 ++ match->nentry->deleted) {
26243 ++ if (match->prev == NULL) {
26244 ++ inodev_set.i_hash[index] = match->next;
26245 ++ if (match->next != NULL)
26246 ++ match->next->prev = NULL;
26247 ++ } else {
26248 ++ match->prev->next = match->next;
26249 ++ if (match->next != NULL)
26250 ++ match->next->prev = match->prev;
26251 ++ }
26252 ++ match->prev = NULL;
26253 ++ match->next = NULL;
26254 ++ match->nentry->inode = newinode;
26255 ++ match->nentry->device = newdevice;
26256 ++ match->nentry->deleted = 0;
26257 ++
26258 ++ insert_inodev_entry(match);
26259 ++ }
26260 ++
26261 ++ return;
26262 ++}
26263 ++
26264 ++static void
26265 ++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
26266 ++ const struct vfsmount *mnt)
26267 ++{
26268 ++ struct acl_subject_label *subj;
26269 ++ struct acl_role_label *role;
26270 ++ unsigned int i, x;
26271 ++
26272 ++ FOR_EACH_ROLE_START(role, i)
26273 ++ update_acl_subj_label(matchn->inode, matchn->device,
26274 ++ dentry->d_inode->i_ino,
26275 ++ dentry->d_inode->i_sb->s_dev, role);
26276 ++
26277 ++ FOR_EACH_NESTED_SUBJECT_START(role, subj)
26278 ++ if ((subj->inode == dentry->d_inode->i_ino) &&
26279 ++ (subj->device == dentry->d_inode->i_sb->s_dev)) {
26280 ++ subj->inode = dentry->d_inode->i_ino;
26281 ++ subj->device = dentry->d_inode->i_sb->s_dev;
26282 ++ }
26283 ++ FOR_EACH_NESTED_SUBJECT_END(subj)
26284 ++ FOR_EACH_SUBJECT_START(role, subj, x)
26285 ++ update_acl_obj_label(matchn->inode, matchn->device,
26286 ++ dentry->d_inode->i_ino,
26287 ++ dentry->d_inode->i_sb->s_dev, subj);
26288 ++ FOR_EACH_SUBJECT_END(subj,x)
26289 ++ FOR_EACH_ROLE_END(role,i)
26290 ++
26291 ++ update_inodev_entry(matchn->inode, matchn->device,
26292 ++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
26293 ++
26294 ++ return;
26295 ++}
26296 ++
26297 ++void
26298 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
26299 ++{
26300 ++ struct name_entry *matchn;
26301 ++
26302 ++ if (unlikely(!(gr_status & GR_READY)))
26303 ++ return;
26304 ++
26305 ++ preempt_disable();
26306 ++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
26307 ++
26308 ++ if (unlikely((unsigned long)matchn)) {
26309 ++ write_lock(&gr_inode_lock);
26310 ++ do_handle_create(matchn, dentry, mnt);
26311 ++ write_unlock(&gr_inode_lock);
26312 ++ }
26313 ++ preempt_enable();
26314 ++
26315 ++ return;
26316 ++}
26317 ++
26318 ++void
26319 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26320 ++ struct dentry *old_dentry,
26321 ++ struct dentry *new_dentry,
26322 ++ struct vfsmount *mnt, const __u8 replace)
26323 ++{
26324 ++ struct name_entry *matchn;
26325 ++ struct inodev_entry *inodev;
26326 ++
26327 ++ /* vfs_rename swaps the name and parent link for old_dentry and
26328 ++ new_dentry
26329 ++ at this point, old_dentry has the new name, parent link, and inode
26330 ++ for the renamed file
26331 ++ if a file is being replaced by a rename, new_dentry has the inode
26332 ++ and name for the replaced file
26333 ++ */
26334 ++
26335 ++ if (unlikely(!(gr_status & GR_READY)))
26336 ++ return;
26337 ++
26338 ++ preempt_disable();
26339 ++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
26340 ++
26341 ++ /* we wouldn't have to check d_inode if it weren't for
26342 ++ NFS silly-renaming
26343 ++ */
26344 ++
26345 ++ write_lock(&gr_inode_lock);
26346 ++ if (unlikely(replace && new_dentry->d_inode)) {
26347 ++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
26348 ++ new_dentry->d_inode->i_sb->s_dev);
26349 ++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
26350 ++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
26351 ++ new_dentry->d_inode->i_sb->s_dev);
26352 ++ }
26353 ++
26354 ++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
26355 ++ old_dentry->d_inode->i_sb->s_dev);
26356 ++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
26357 ++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
26358 ++ old_dentry->d_inode->i_sb->s_dev);
26359 ++
26360 ++ if (unlikely((unsigned long)matchn))
26361 ++ do_handle_create(matchn, old_dentry, mnt);
26362 ++
26363 ++ write_unlock(&gr_inode_lock);
26364 ++ preempt_enable();
26365 ++
26366 ++ return;
26367 ++}
26368 ++
26369 ++static int
26370 ++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
26371 ++ unsigned char **sum)
26372 ++{
26373 ++ struct acl_role_label *r;
26374 ++ struct role_allowed_ip *ipp;
26375 ++ struct role_transition *trans;
26376 ++ unsigned int i;
26377 ++ int found = 0;
26378 ++
26379 ++ /* check transition table */
26380 ++
26381 ++ for (trans = current->role->transitions; trans; trans = trans->next) {
26382 ++ if (!strcmp(rolename, trans->rolename)) {
26383 ++ found = 1;
26384 ++ break;
26385 ++ }
26386 ++ }
26387 ++
26388 ++ if (!found)
26389 ++ return 0;
26390 ++
26391 ++ /* handle special roles that do not require authentication
26392 ++ and check ip */
26393 ++
26394 ++ FOR_EACH_ROLE_START(r, i)
26395 ++ if (!strcmp(rolename, r->rolename) &&
26396 ++ (r->roletype & GR_ROLE_SPECIAL)) {
26397 ++ found = 0;
26398 ++ if (r->allowed_ips != NULL) {
26399 ++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
26400 ++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
26401 ++ (ntohl(ipp->addr) & ipp->netmask))
26402 ++ found = 1;
26403 ++ }
26404 ++ } else
26405 ++ found = 2;
26406 ++ if (!found)
26407 ++ return 0;
26408 ++
26409 ++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
26410 ++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
26411 ++ *salt = NULL;
26412 ++ *sum = NULL;
26413 ++ return 1;
26414 ++ }
26415 ++ }
26416 ++ FOR_EACH_ROLE_END(r,i)
26417 ++
26418 ++ for (i = 0; i < num_sprole_pws; i++) {
26419 ++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
26420 ++ *salt = acl_special_roles[i]->salt;
26421 ++ *sum = acl_special_roles[i]->sum;
26422 ++ return 1;
26423 ++ }
26424 ++ }
26425 ++
26426 ++ return 0;
26427 ++}
26428 ++
26429 ++static void
26430 ++assign_special_role(char *rolename)
26431 ++{
26432 ++ struct acl_object_label *obj;
26433 ++ struct acl_role_label *r;
26434 ++ struct acl_role_label *assigned = NULL;
26435 ++ struct task_struct *tsk;
26436 ++ struct file *filp;
26437 ++ unsigned int i;
26438 ++
26439 ++ FOR_EACH_ROLE_START(r, i)
26440 ++ if (!strcmp(rolename, r->rolename) &&
26441 ++ (r->roletype & GR_ROLE_SPECIAL))
26442 ++ assigned = r;
26443 ++ FOR_EACH_ROLE_END(r,i)
26444 ++
26445 ++ if (!assigned)
26446 ++ return;
26447 ++
26448 ++ read_lock(&tasklist_lock);
26449 ++ read_lock(&grsec_exec_file_lock);
26450 ++
26451 ++ tsk = current->parent;
26452 ++ if (tsk == NULL)
26453 ++ goto out_unlock;
26454 ++
26455 ++ filp = tsk->exec_file;
26456 ++ if (filp == NULL)
26457 ++ goto out_unlock;
26458 ++
26459 ++ tsk->is_writable = 0;
26460 ++
26461 ++ tsk->acl_sp_role = 1;
26462 ++ tsk->acl_role_id = ++acl_sp_role_value;
26463 ++ tsk->role = assigned;
26464 ++ tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
26465 ++
26466 ++ /* ignore additional mmap checks for processes that are writable
26467 ++ by the default ACL */
26468 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
26469 ++ if (unlikely(obj->mode & GR_WRITE))
26470 ++ tsk->is_writable = 1;
26471 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
26472 ++ if (unlikely(obj->mode & GR_WRITE))
26473 ++ tsk->is_writable = 1;
26474 ++
26475 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26476 ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
26477 ++#endif
26478 ++
26479 ++out_unlock:
26480 ++ read_unlock(&grsec_exec_file_lock);
26481 ++ read_unlock(&tasklist_lock);
26482 ++ return;
26483 ++}
26484 ++
26485 ++int gr_check_secure_terminal(struct task_struct *task)
26486 ++{
26487 ++ struct task_struct *p, *p2, *p3;
26488 ++ struct files_struct *files;
26489 ++ struct fdtable *fdt;
26490 ++ struct file *our_file = NULL, *file;
26491 ++ int i;
26492 ++
26493 ++ if (task->signal->tty == NULL)
26494 ++ return 1;
26495 ++
26496 ++ files = get_files_struct(task);
26497 ++ if (files != NULL) {
26498 ++ rcu_read_lock();
26499 ++ fdt = files_fdtable(files);
26500 ++ for (i=0; i < fdt->max_fds; i++) {
26501 ++ file = fcheck_files(files, i);
26502 ++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
26503 ++ get_file(file);
26504 ++ our_file = file;
26505 ++ }
26506 ++ }
26507 ++ rcu_read_unlock();
26508 ++ put_files_struct(files);
26509 ++ }
26510 ++
26511 ++ if (our_file == NULL)
26512 ++ return 1;
26513 ++
26514 ++ read_lock(&tasklist_lock);
26515 ++ do_each_thread(p2, p) {
26516 ++ files = get_files_struct(p);
26517 ++ if (files == NULL ||
26518 ++ (p->signal && p->signal->tty == task->signal->tty)) {
26519 ++ if (files != NULL)
26520 ++ put_files_struct(files);
26521 ++ continue;
26522 ++ }
26523 ++ rcu_read_lock();
26524 ++ fdt = files_fdtable(files);
26525 ++ for (i=0; i < fdt->max_fds; i++) {
26526 ++ file = fcheck_files(files, i);
26527 ++ if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
26528 ++ file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
26529 ++ p3 = task;
26530 ++ while (p3->pid > 0) {
26531 ++ if (p3 == p)
26532 ++ break;
26533 ++ p3 = p3->parent;
26534 ++ }
26535 ++ if (p3 == p)
26536 ++ break;
26537 ++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
26538 ++ gr_handle_alertkill(p);
26539 ++ rcu_read_unlock();
26540 ++ put_files_struct(files);
26541 ++ read_unlock(&tasklist_lock);
26542 ++ fput(our_file);
26543 ++ return 0;
26544 ++ }
26545 ++ }
26546 ++ rcu_read_unlock();
26547 ++ put_files_struct(files);
26548 ++ } while_each_thread(p2, p);
26549 ++ read_unlock(&tasklist_lock);
26550 ++
26551 ++ fput(our_file);
26552 ++ return 1;
26553 ++}
26554 ++
26555 ++ssize_t
26556 ++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
26557 ++{
26558 ++ struct gr_arg_wrapper uwrap;
26559 ++ unsigned char *sprole_salt;
26560 ++ unsigned char *sprole_sum;
26561 ++ int error = sizeof (struct gr_arg_wrapper);
26562 ++ int error2 = 0;
26563 ++
26564 ++ down(&gr_dev_sem);
26565 ++
26566 ++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
26567 ++ error = -EPERM;
26568 ++ goto out;
26569 ++ }
26570 ++
26571 ++ if (count != sizeof (struct gr_arg_wrapper)) {
26572 ++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
26573 ++ error = -EINVAL;
26574 ++ goto out;
26575 ++ }
26576 ++
26577 ++
26578 ++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
26579 ++ gr_auth_expires = 0;
26580 ++ gr_auth_attempts = 0;
26581 ++ }
26582 ++
26583 ++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
26584 ++ error = -EFAULT;
26585 ++ goto out;
26586 ++ }
26587 ++
26588 ++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
26589 ++ error = -EINVAL;
26590 ++ goto out;
26591 ++ }
26592 ++
26593 ++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
26594 ++ error = -EFAULT;
26595 ++ goto out;
26596 ++ }
26597 ++
26598 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
26599 ++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
26600 ++ time_after(gr_auth_expires, get_seconds())) {
26601 ++ error = -EBUSY;
26602 ++ goto out;
26603 ++ }
26604 ++
26605 ++ /* if non-root trying to do anything other than use a special role,
26606 ++ do not attempt authentication, do not count towards authentication
26607 ++ locking
26608 ++ */
26609 ++
26610 ++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
26611 ++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
26612 ++ current->uid) {
26613 ++ error = -EPERM;
26614 ++ goto out;
26615 ++ }
26616 ++
26617 ++ /* ensure pw and special role name are null terminated */
26618 ++
26619 ++ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
26620 ++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
26621 ++
26622 ++ /* Okay.
26623 ++ * We have our enough of the argument structure..(we have yet
26624 ++ * to copy_from_user the tables themselves) . Copy the tables
26625 ++ * only if we need them, i.e. for loading operations. */
26626 ++
26627 ++ switch (gr_usermode->mode) {
26628 ++ case STATUS:
26629 ++ if (gr_status & GR_READY) {
26630 ++ error = 1;
26631 ++ if (!gr_check_secure_terminal(current))
26632 ++ error = 3;
26633 ++ } else
26634 ++ error = 2;
26635 ++ goto out;
26636 ++ case SHUTDOWN:
26637 ++ if ((gr_status & GR_READY)
26638 ++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26639 ++ gr_status &= ~GR_READY;
26640 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
26641 ++ free_variables();
26642 ++ memset(gr_usermode, 0, sizeof (struct gr_arg));
26643 ++ memset(gr_system_salt, 0, GR_SALT_LEN);
26644 ++ memset(gr_system_sum, 0, GR_SHA_LEN);
26645 ++ } else if (gr_status & GR_READY) {
26646 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
26647 ++ error = -EPERM;
26648 ++ } else {
26649 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
26650 ++ error = -EAGAIN;
26651 ++ }
26652 ++ break;
26653 ++ case ENABLE:
26654 ++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
26655 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
26656 ++ else {
26657 ++ if (gr_status & GR_READY)
26658 ++ error = -EAGAIN;
26659 ++ else
26660 ++ error = error2;
26661 ++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
26662 ++ }
26663 ++ break;
26664 ++ case RELOAD:
26665 ++ if (!(gr_status & GR_READY)) {
26666 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
26667 ++ error = -EAGAIN;
26668 ++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26669 ++ lock_kernel();
26670 ++ gr_status &= ~GR_READY;
26671 ++ free_variables();
26672 ++ if (!(error2 = gracl_init(gr_usermode))) {
26673 ++ unlock_kernel();
26674 ++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
26675 ++ } else {
26676 ++ unlock_kernel();
26677 ++ error = error2;
26678 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
26679 ++ }
26680 ++ } else {
26681 ++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
26682 ++ error = -EPERM;
26683 ++ }
26684 ++ break;
26685 ++ case SEGVMOD:
26686 ++ if (unlikely(!(gr_status & GR_READY))) {
26687 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
26688 ++ error = -EAGAIN;
26689 ++ break;
26690 ++ }
26691 ++
26692 ++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
26693 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
26694 ++ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
26695 ++ struct acl_subject_label *segvacl;
26696 ++ segvacl =
26697 ++ lookup_acl_subj_label(gr_usermode->segv_inode,
26698 ++ gr_usermode->segv_device,
26699 ++ current->role);
26700 ++ if (segvacl) {
26701 ++ segvacl->crashes = 0;
26702 ++ segvacl->expires = 0;
26703 ++ }
26704 ++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
26705 ++ gr_remove_uid(gr_usermode->segv_uid);
26706 ++ }
26707 ++ } else {
26708 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
26709 ++ error = -EPERM;
26710 ++ }
26711 ++ break;
26712 ++ case SPROLE:
26713 ++ case SPROLEPAM:
26714 ++ if (unlikely(!(gr_status & GR_READY))) {
26715 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
26716 ++ error = -EAGAIN;
26717 ++ break;
26718 ++ }
26719 ++
26720 ++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
26721 ++ current->role->expires = 0;
26722 ++ current->role->auth_attempts = 0;
26723 ++ }
26724 ++
26725 ++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
26726 ++ time_after(current->role->expires, get_seconds())) {
26727 ++ error = -EBUSY;
26728 ++ goto out;
26729 ++ }
26730 ++
26731 ++ if (lookup_special_role_auth
26732 ++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
26733 ++ && ((!sprole_salt && !sprole_sum)
26734 ++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
26735 ++ char *p = "";
26736 ++ assign_special_role(gr_usermode->sp_role);
26737 ++ read_lock(&tasklist_lock);
26738 ++ if (current->parent)
26739 ++ p = current->parent->role->rolename;
26740 ++ read_unlock(&tasklist_lock);
26741 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
26742 ++ p, acl_sp_role_value);
26743 ++ } else {
26744 ++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
26745 ++ error = -EPERM;
26746 ++ if(!(current->role->auth_attempts++))
26747 ++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
26748 ++
26749 ++ goto out;
26750 ++ }
26751 ++ break;
26752 ++ case UNSPROLE:
26753 ++ if (unlikely(!(gr_status & GR_READY))) {
26754 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
26755 ++ error = -EAGAIN;
26756 ++ break;
26757 ++ }
26758 ++
26759 ++ if (current->role->roletype & GR_ROLE_SPECIAL) {
26760 ++ char *p = "";
26761 ++ int i = 0;
26762 ++
26763 ++ read_lock(&tasklist_lock);
26764 ++ if (current->parent) {
26765 ++ p = current->parent->role->rolename;
26766 ++ i = current->parent->acl_role_id;
26767 ++ }
26768 ++ read_unlock(&tasklist_lock);
26769 ++
26770 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
26771 ++ gr_set_acls(1);
26772 ++ } else {
26773 ++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
26774 ++ error = -EPERM;
26775 ++ goto out;
26776 ++ }
26777 ++ break;
26778 ++ default:
26779 ++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
26780 ++ error = -EINVAL;
26781 ++ break;
26782 ++ }
26783 ++
26784 ++ if (error != -EPERM)
26785 ++ goto out;
26786 ++
26787 ++ if(!(gr_auth_attempts++))
26788 ++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
26789 ++
26790 ++ out:
26791 ++ up(&gr_dev_sem);
26792 ++ return error;
26793 ++}
26794 ++
26795 ++int
26796 ++gr_set_acls(const int type)
26797 ++{
26798 ++ struct acl_object_label *obj;
26799 ++ struct task_struct *task, *task2;
26800 ++ struct file *filp;
26801 ++ struct acl_role_label *role = current->role;
26802 ++ __u16 acl_role_id = current->acl_role_id;
26803 ++
26804 ++ read_lock(&tasklist_lock);
26805 ++ read_lock(&grsec_exec_file_lock);
26806 ++ do_each_thread(task2, task) {
26807 ++ /* check to see if we're called from the exit handler,
26808 ++ if so, only replace ACLs that have inherited the admin
26809 ++ ACL */
26810 ++
26811 ++ if (type && (task->role != role ||
26812 ++ task->acl_role_id != acl_role_id))
26813 ++ continue;
26814 ++
26815 ++ task->acl_role_id = 0;
26816 ++ task->acl_sp_role = 0;
26817 ++
26818 ++ if ((filp = task->exec_file)) {
26819 ++ task->role = lookup_acl_role_label(task, task->uid, task->gid);
26820 ++
26821 ++ task->acl =
26822 ++ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
26823 ++ task->role);
26824 ++ if (task->acl) {
26825 ++ struct acl_subject_label *curr;
26826 ++ curr = task->acl;
26827 ++
26828 ++ task->is_writable = 0;
26829 ++ /* ignore additional mmap checks for processes that are writable
26830 ++ by the default ACL */
26831 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
26832 ++ if (unlikely(obj->mode & GR_WRITE))
26833 ++ task->is_writable = 1;
26834 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
26835 ++ if (unlikely(obj->mode & GR_WRITE))
26836 ++ task->is_writable = 1;
26837 ++
26838 ++ gr_set_proc_res(task);
26839 ++
26840 ++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
26841 ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
26842 ++#endif
26843 ++ } else {
26844 ++ read_unlock(&grsec_exec_file_lock);
26845 ++ read_unlock(&tasklist_lock);
26846 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
26847 ++ return 1;
26848 ++ }
26849 ++ } else {
26850 ++ // it's a kernel process
26851 ++ task->role = kernel_role;
26852 ++ task->acl = kernel_role->root_label;
26853 ++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
26854 ++ task->acl->mode &= ~GR_PROCFIND;
26855 ++#endif
26856 ++ }
26857 ++ } while_each_thread(task2, task);
26858 ++ read_unlock(&grsec_exec_file_lock);
26859 ++ read_unlock(&tasklist_lock);
26860 ++ return 0;
26861 ++}
26862 ++
26863 ++void
26864 ++gr_learn_resource(const struct task_struct *task,
26865 ++ const int res, const unsigned long wanted, const int gt)
26866 ++{
26867 ++ struct acl_subject_label *acl;
26868 ++
26869 ++ if (unlikely((gr_status & GR_READY) &&
26870 ++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
26871 ++ goto skip_reslog;
26872 ++
26873 ++#ifdef CONFIG_GRKERNSEC_RESLOG
26874 ++ gr_log_resource(task, res, wanted, gt);
26875 ++#endif
26876 ++ skip_reslog:
26877 ++
26878 ++ if (unlikely(!(gr_status & GR_READY) || !wanted))
26879 ++ return;
26880 ++
26881 ++ acl = task->acl;
26882 ++
26883 ++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
26884 ++ !(acl->resmask & (1 << (unsigned short) res))))
26885 ++ return;
26886 ++
26887 ++ if (wanted >= acl->res[res].rlim_cur) {
26888 ++ unsigned long res_add;
26889 ++
26890 ++ res_add = wanted;
26891 ++ switch (res) {
26892 ++ case RLIMIT_CPU:
26893 ++ res_add += GR_RLIM_CPU_BUMP;
26894 ++ break;
26895 ++ case RLIMIT_FSIZE:
26896 ++ res_add += GR_RLIM_FSIZE_BUMP;
26897 ++ break;
26898 ++ case RLIMIT_DATA:
26899 ++ res_add += GR_RLIM_DATA_BUMP;
26900 ++ break;
26901 ++ case RLIMIT_STACK:
26902 ++ res_add += GR_RLIM_STACK_BUMP;
26903 ++ break;
26904 ++ case RLIMIT_CORE:
26905 ++ res_add += GR_RLIM_CORE_BUMP;
26906 ++ break;
26907 ++ case RLIMIT_RSS:
26908 ++ res_add += GR_RLIM_RSS_BUMP;
26909 ++ break;
26910 ++ case RLIMIT_NPROC:
26911 ++ res_add += GR_RLIM_NPROC_BUMP;
26912 ++ break;
26913 ++ case RLIMIT_NOFILE:
26914 ++ res_add += GR_RLIM_NOFILE_BUMP;
26915 ++ break;
26916 ++ case RLIMIT_MEMLOCK:
26917 ++ res_add += GR_RLIM_MEMLOCK_BUMP;
26918 ++ break;
26919 ++ case RLIMIT_AS:
26920 ++ res_add += GR_RLIM_AS_BUMP;
26921 ++ break;
26922 ++ case RLIMIT_LOCKS:
26923 ++ res_add += GR_RLIM_LOCKS_BUMP;
26924 ++ break;
26925 ++ }
26926 ++
26927 ++ acl->res[res].rlim_cur = res_add;
26928 ++
26929 ++ if (wanted > acl->res[res].rlim_max)
26930 ++ acl->res[res].rlim_max = res_add;
26931 ++
26932 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
26933 ++ task->role->roletype, acl->filename,
26934 ++ acl->res[res].rlim_cur, acl->res[res].rlim_max,
26935 ++ "", (unsigned long) res);
26936 ++ }
26937 ++
26938 ++ return;
26939 ++}
26940 ++
26941 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26942 ++void
26943 ++pax_set_initial_flags(struct linux_binprm *bprm)
26944 ++{
26945 ++ struct task_struct *task = current;
26946 ++ struct acl_subject_label *proc;
26947 ++ unsigned long flags;
26948 ++
26949 ++ if (unlikely(!(gr_status & GR_READY)))
26950 ++ return;
26951 ++
26952 ++ flags = pax_get_flags(task);
26953 ++
26954 ++ proc = task->acl;
26955 ++
26956 ++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
26957 ++ flags &= ~MF_PAX_PAGEEXEC;
26958 ++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
26959 ++ flags &= ~MF_PAX_SEGMEXEC;
26960 ++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
26961 ++ flags &= ~MF_PAX_RANDMMAP;
26962 ++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
26963 ++ flags &= ~MF_PAX_EMUTRAMP;
26964 ++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
26965 ++ flags &= ~MF_PAX_MPROTECT;
26966 ++
26967 ++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
26968 ++ flags |= MF_PAX_PAGEEXEC;
26969 ++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
26970 ++ flags |= MF_PAX_SEGMEXEC;
26971 ++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
26972 ++ flags |= MF_PAX_RANDMMAP;
26973 ++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
26974 ++ flags |= MF_PAX_EMUTRAMP;
26975 ++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
26976 ++ flags |= MF_PAX_MPROTECT;
26977 ++
26978 ++ pax_set_flags(task, flags);
26979 ++
26980 ++ return;
26981 ++}
26982 ++#endif
26983 ++
26984 ++#ifdef CONFIG_SYSCTL
26985 ++/* Eric Biederman likes breaking userland ABI and every inode-based security
26986 ++ system to save 35kb of memory */
26987 ++
26988 ++/* we modify the passed in filename, but adjust it back before returning */
26989 ++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
26990 ++{
26991 ++ struct name_entry *nmatch;
26992 ++ char *p, *lastp = NULL;
26993 ++ struct acl_object_label *obj = NULL, *tmp;
26994 ++ struct acl_subject_label *tmpsubj;
26995 ++ int done = 0;
26996 ++ char c = '\0';
26997 ++
26998 ++ read_lock(&gr_inode_lock);
26999 ++
27000 ++ p = name + len - 1;
27001 ++ do {
27002 ++ nmatch = lookup_name_entry(name);
27003 ++ if (lastp != NULL)
27004 ++ *lastp = c;
27005 ++
27006 ++ if (nmatch == NULL)
27007 ++ goto next_component;
27008 ++ tmpsubj = current->acl;
27009 ++ do {
27010 ++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
27011 ++ if (obj != NULL) {
27012 ++ tmp = obj->globbed;
27013 ++ while (tmp) {
27014 ++ if (!glob_match(tmp->filename, name)) {
27015 ++ obj = tmp;
27016 ++ goto found_obj;
27017 ++ }
27018 ++ tmp = tmp->next;
27019 ++ }
27020 ++ goto found_obj;
27021 ++ }
27022 ++ } while ((tmpsubj = tmpsubj->parent_subject));
27023 ++next_component:
27024 ++ /* end case */
27025 ++ if (p == name)
27026 ++ break;
27027 ++
27028 ++ while (*p != '/')
27029 ++ p--;
27030 ++ if (p == name)
27031 ++ lastp = p + 1;
27032 ++ else {
27033 ++ lastp = p;
27034 ++ p--;
27035 ++ }
27036 ++ c = *lastp;
27037 ++ *lastp = '\0';
27038 ++ } while (1);
27039 ++found_obj:
27040 ++ read_unlock(&gr_inode_lock);
27041 ++ /* obj returned will always be non-null */
27042 ++ return obj;
27043 ++}
27044 ++
27045 ++/* returns 0 when allowing, non-zero on error
27046 ++ op of 0 is used for readdir, so we don't log the names of hidden files
27047 ++*/
27048 ++__u32
27049 ++gr_handle_sysctl(const struct ctl_table *table, const int op)
27050 ++{
27051 ++ ctl_table *tmp;
27052 ++ struct nameidata nd;
27053 ++ const char *proc_sys = "/proc/sys";
27054 ++ char *path;
27055 ++ struct acl_object_label *obj;
27056 ++ unsigned short len = 0, pos = 0, depth = 0, i;
27057 ++ __u32 err = 0;
27058 ++ __u32 mode = 0;
27059 ++
27060 ++ if (unlikely(!(gr_status & GR_READY)))
27061 ++ return 0;
27062 ++
27063 ++ /* for now, ignore operations on non-sysctl entries if it's not a
27064 ++ readdir*/
27065 ++ if (table->child != NULL && op != 0)
27066 ++ return 0;
27067 ++
27068 ++ mode |= GR_FIND;
27069 ++ /* it's only a read if it's an entry, read on dirs is for readdir */
27070 ++ if (op & 004)
27071 ++ mode |= GR_READ;
27072 ++ if (op & 002)
27073 ++ mode |= GR_WRITE;
27074 ++
27075 ++ preempt_disable();
27076 ++
27077 ++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
27078 ++
27079 ++ /* it's only a read/write if it's an actual entry, not a dir
27080 ++ (which are opened for readdir)
27081 ++ */
27082 ++
27083 ++ /* convert the requested sysctl entry into a pathname */
27084 ++
27085 ++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
27086 ++ len += strlen(tmp->procname);
27087 ++ len++;
27088 ++ depth++;
27089 ++ }
27090 ++
27091 ++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
27092 ++ /* deny */
27093 ++ goto out;
27094 ++ }
27095 ++
27096 ++ memset(path, 0, PAGE_SIZE);
27097 ++
27098 ++ memcpy(path, proc_sys, strlen(proc_sys));
27099 ++
27100 ++ pos += strlen(proc_sys);
27101 ++
27102 ++ for (; depth > 0; depth--) {
27103 ++ path[pos] = '/';
27104 ++ pos++;
27105 ++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
27106 ++ if (depth == i) {
27107 ++ memcpy(path + pos, tmp->procname,
27108 ++ strlen(tmp->procname));
27109 ++ pos += strlen(tmp->procname);
27110 ++ }
27111 ++ i++;
27112 ++ }
27113 ++ }
27114 ++
27115 ++ obj = gr_lookup_by_name(path, pos);
27116 ++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
27117 ++
27118 ++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
27119 ++ ((err & mode) != mode))) {
27120 ++ __u32 new_mode = mode;
27121 ++
27122 ++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
27123 ++
27124 ++ err = 0;
27125 ++ gr_log_learn_sysctl(current, path, new_mode);
27126 ++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
27127 ++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
27128 ++ err = -ENOENT;
27129 ++ } else if (!(err & GR_FIND)) {
27130 ++ err = -ENOENT;
27131 ++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
27132 ++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
27133 ++ path, (mode & GR_READ) ? " reading" : "",
27134 ++ (mode & GR_WRITE) ? " writing" : "");
27135 ++ err = -EACCES;
27136 ++ } else if ((err & mode) != mode) {
27137 ++ err = -EACCES;
27138 ++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
27139 ++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
27140 ++ path, (mode & GR_READ) ? " reading" : "",
27141 ++ (mode & GR_WRITE) ? " writing" : "");
27142 ++ err = 0;
27143 ++ } else
27144 ++ err = 0;
27145 ++
27146 ++ out:
27147 ++ preempt_enable();
27148 ++
27149 ++ return err;
27150 ++}
27151 ++#endif
27152 ++
27153 ++int
27154 ++gr_handle_proc_ptrace(struct task_struct *task)
27155 ++{
27156 ++ struct file *filp;
27157 ++ struct task_struct *tmp = task;
27158 ++ struct task_struct *curtemp = current;
27159 ++ __u32 retmode;
27160 ++
27161 ++ if (unlikely(!(gr_status & GR_READY)))
27162 ++ return 0;
27163 ++
27164 ++ read_lock(&tasklist_lock);
27165 ++ read_lock(&grsec_exec_file_lock);
27166 ++ filp = task->exec_file;
27167 ++
27168 ++ while (tmp->pid > 0) {
27169 ++ if (tmp == curtemp)
27170 ++ break;
27171 ++ tmp = tmp->parent;
27172 ++ }
27173 ++
27174 ++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
27175 ++ read_unlock(&grsec_exec_file_lock);
27176 ++ read_unlock(&tasklist_lock);
27177 ++ return 1;
27178 ++ }
27179 ++
27180 ++ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
27181 ++ read_unlock(&grsec_exec_file_lock);
27182 ++ read_unlock(&tasklist_lock);
27183 ++
27184 ++ if (retmode & GR_NOPTRACE)
27185 ++ return 1;
27186 ++
27187 ++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
27188 ++ && (current->acl != task->acl || (current->acl != current->role->root_label
27189 ++ && current->pid != task->pid)))
27190 ++ return 1;
27191 ++
27192 ++ return 0;
27193 ++}
27194 ++
27195 ++int
27196 ++gr_handle_ptrace(struct task_struct *task, const long request)
27197 ++{
27198 ++ struct task_struct *tmp = task;
27199 ++ struct task_struct *curtemp = current;
27200 ++ __u32 retmode;
27201 ++
27202 ++ if (unlikely(!(gr_status & GR_READY)))
27203 ++ return 0;
27204 ++
27205 ++ read_lock(&tasklist_lock);
27206 ++ while (tmp->pid > 0) {
27207 ++ if (tmp == curtemp)
27208 ++ break;
27209 ++ tmp = tmp->parent;
27210 ++ }
27211 ++
27212 ++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
27213 ++ read_unlock(&tasklist_lock);
27214 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27215 ++ return 1;
27216 ++ }
27217 ++ read_unlock(&tasklist_lock);
27218 ++
27219 ++ read_lock(&grsec_exec_file_lock);
27220 ++ if (unlikely(!task->exec_file)) {
27221 ++ read_unlock(&grsec_exec_file_lock);
27222 ++ return 0;
27223 ++ }
27224 ++
27225 ++ retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
27226 ++ read_unlock(&grsec_exec_file_lock);
27227 ++
27228 ++ if (retmode & GR_NOPTRACE) {
27229 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27230 ++ return 1;
27231 ++ }
27232 ++
27233 ++ if (retmode & GR_PTRACERD) {
27234 ++ switch (request) {
27235 ++ case PTRACE_POKETEXT:
27236 ++ case PTRACE_POKEDATA:
27237 ++ case PTRACE_POKEUSR:
27238 ++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
27239 ++ case PTRACE_SETREGS:
27240 ++ case PTRACE_SETFPREGS:
27241 ++#endif
27242 ++#ifdef CONFIG_X86
27243 ++ case PTRACE_SETFPXREGS:
27244 ++#endif
27245 ++#ifdef CONFIG_ALTIVEC
27246 ++ case PTRACE_SETVRREGS:
27247 ++#endif
27248 ++ return 1;
27249 ++ default:
27250 ++ return 0;
27251 ++ }
27252 ++ } else if (!(current->acl->mode & GR_POVERRIDE) &&
27253 ++ !(current->role->roletype & GR_ROLE_GOD) &&
27254 ++ (current->acl != task->acl)) {
27255 ++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
27256 ++ return 1;
27257 ++ }
27258 ++
27259 ++ return 0;
27260 ++}
27261 ++
27262 ++static int is_writable_mmap(const struct file *filp)
27263 ++{
27264 ++ struct task_struct *task = current;
27265 ++ struct acl_object_label *obj, *obj2;
27266 ++
27267 ++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
27268 ++ !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
27269 ++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
27270 ++ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
27271 ++ task->role->root_label);
27272 ++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
27273 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
27274 ++ return 1;
27275 ++ }
27276 ++ }
27277 ++ return 0;
27278 ++}
27279 ++
27280 ++int
27281 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
27282 ++{
27283 ++ __u32 mode;
27284 ++
27285 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
27286 ++ return 1;
27287 ++
27288 ++ if (is_writable_mmap(file))
27289 ++ return 0;
27290 ++
27291 ++ mode =
27292 ++ gr_search_file(file->f_dentry,
27293 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
27294 ++ file->f_vfsmnt);
27295 ++
27296 ++ if (!gr_tpe_allow(file))
27297 ++ return 0;
27298 ++
27299 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
27300 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
27301 ++ return 0;
27302 ++ } else if (unlikely(!(mode & GR_EXEC))) {
27303 ++ return 0;
27304 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
27305 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
27306 ++ return 1;
27307 ++ }
27308 ++
27309 ++ return 1;
27310 ++}
27311 ++
27312 ++int
27313 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
27314 ++{
27315 ++ __u32 mode;
27316 ++
27317 ++ if (unlikely(!file || !(prot & PROT_EXEC)))
27318 ++ return 1;
27319 ++
27320 ++ if (is_writable_mmap(file))
27321 ++ return 0;
27322 ++
27323 ++ mode =
27324 ++ gr_search_file(file->f_dentry,
27325 ++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
27326 ++ file->f_vfsmnt);
27327 ++
27328 ++ if (!gr_tpe_allow(file))
27329 ++ return 0;
27330 ++
27331 ++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
27332 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
27333 ++ return 0;
27334 ++ } else if (unlikely(!(mode & GR_EXEC))) {
27335 ++ return 0;
27336 ++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
27337 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
27338 ++ return 1;
27339 ++ }
27340 ++
27341 ++ return 1;
27342 ++}
27343 ++
27344 ++void
27345 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
27346 ++{
27347 ++ unsigned long runtime;
27348 ++ unsigned long cputime;
27349 ++ unsigned int wday, cday;
27350 ++ __u8 whr, chr;
27351 ++ __u8 wmin, cmin;
27352 ++ __u8 wsec, csec;
27353 ++
27354 ++ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
27355 ++ !(task->acl->mode & GR_PROCACCT)))
27356 ++ return;
27357 ++
27358 ++ runtime = xtime.tv_sec - task->start_time.tv_sec;
27359 ++ wday = runtime / (3600 * 24);
27360 ++ runtime -= wday * (3600 * 24);
27361 ++ whr = runtime / 3600;
27362 ++ runtime -= whr * 3600;
27363 ++ wmin = runtime / 60;
27364 ++ runtime -= wmin * 60;
27365 ++ wsec = runtime;
27366 ++
27367 ++ cputime = (task->utime + task->stime) / HZ;
27368 ++ cday = cputime / (3600 * 24);
27369 ++ cputime -= cday * (3600 * 24);
27370 ++ chr = cputime / 3600;
27371 ++ cputime -= chr * 3600;
27372 ++ cmin = cputime / 60;
27373 ++ cputime -= cmin * 60;
27374 ++ csec = cputime;
27375 ++
27376 ++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
27377 ++
27378 ++ return;
27379 ++}
27380 ++
27381 ++void gr_set_kernel_label(struct task_struct *task)
27382 ++{
27383 ++ if (gr_status & GR_READY) {
27384 ++ task->role = kernel_role;
27385 ++ task->acl = kernel_role->root_label;
27386 ++ }
27387 ++ return;
27388 ++}
27389 ++
27390 ++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
27391 ++{
27392 ++ struct task_struct *task = current;
27393 ++ struct dentry *dentry = file->f_dentry;
27394 ++ struct vfsmount *mnt = file->f_vfsmnt;
27395 ++ struct acl_object_label *obj, *tmp;
27396 ++ struct acl_subject_label *subj;
27397 ++ unsigned int bufsize;
27398 ++ int is_not_root;
27399 ++ char *path;
27400 ++
27401 ++ if (unlikely(!(gr_status & GR_READY)))
27402 ++ return 1;
27403 ++
27404 ++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
27405 ++ return 1;
27406 ++
27407 ++ /* ignore Eric Biederman */
27408 ++ if (IS_PRIVATE(dentry->d_inode))
27409 ++ return 1;
27410 ++
27411 ++ subj = task->acl;
27412 ++ do {
27413 ++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
27414 ++ if (obj != NULL)
27415 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27416 ++ } while ((subj = subj->parent_subject));
27417 ++
27418 ++ obj = chk_obj_label(dentry, mnt, task->acl);
27419 ++ if (obj->globbed == NULL)
27420 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27421 ++
27422 ++ is_not_root = ((obj->filename[0] == '/') &&
27423 ++ (obj->filename[1] == '\0')) ? 0 : 1;
27424 ++ bufsize = PAGE_SIZE - namelen - is_not_root;
27425 ++
27426 ++ /* check bufsize > PAGE_SIZE || bufsize == 0 */
27427 ++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
27428 ++ return 1;
27429 ++
27430 ++ preempt_disable();
27431 ++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
27432 ++ bufsize);
27433 ++
27434 ++ bufsize = strlen(path);
27435 ++
27436 ++ /* if base is "/", don't append an additional slash */
27437 ++ if (is_not_root)
27438 ++ *(path + bufsize) = '/';
27439 ++ memcpy(path + bufsize + is_not_root, name, namelen);
27440 ++ *(path + bufsize + namelen + is_not_root) = '\0';
27441 ++
27442 ++ tmp = obj->globbed;
27443 ++ while (tmp) {
27444 ++ if (!glob_match(tmp->filename, path)) {
27445 ++ preempt_enable();
27446 ++ return (tmp->mode & GR_FIND) ? 1 : 0;
27447 ++ }
27448 ++ tmp = tmp->next;
27449 ++ }
27450 ++ preempt_enable();
27451 ++ return (obj->mode & GR_FIND) ? 1 : 0;
27452 ++}
27453 ++
27454 ++EXPORT_SYMBOL(gr_learn_resource);
27455 ++EXPORT_SYMBOL(gr_set_kernel_label);
27456 ++#ifdef CONFIG_SECURITY
27457 ++EXPORT_SYMBOL(gr_check_user_change);
27458 ++EXPORT_SYMBOL(gr_check_group_change);
27459 ++#endif
27460 ++
27461 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_alloc.c linux-2.6.23.15-grsec/grsecurity/gracl_alloc.c
27462 +--- linux-2.6.23.15/grsecurity/gracl_alloc.c 1970-01-01 01:00:00.000000000 +0100
27463 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_alloc.c 2008-02-11 10:37:44.000000000 +0000
27464 +@@ -0,0 +1,91 @@
27465 ++#include <linux/kernel.h>
27466 ++#include <linux/mm.h>
27467 ++#include <linux/slab.h>
27468 ++#include <linux/vmalloc.h>
27469 ++#include <linux/gracl.h>
27470 ++#include <linux/grsecurity.h>
27471 ++
27472 ++static unsigned long alloc_stack_next = 1;
27473 ++static unsigned long alloc_stack_size = 1;
27474 ++static void **alloc_stack;
27475 ++
27476 ++static __inline__ int
27477 ++alloc_pop(void)
27478 ++{
27479 ++ if (alloc_stack_next == 1)
27480 ++ return 0;
27481 ++
27482 ++ kfree(alloc_stack[alloc_stack_next - 2]);
27483 ++
27484 ++ alloc_stack_next--;
27485 ++
27486 ++ return 1;
27487 ++}
27488 ++
27489 ++static __inline__ void
27490 ++alloc_push(void *buf)
27491 ++{
27492 ++ if (alloc_stack_next >= alloc_stack_size)
27493 ++ BUG();
27494 ++
27495 ++ alloc_stack[alloc_stack_next - 1] = buf;
27496 ++
27497 ++ alloc_stack_next++;
27498 ++
27499 ++ return;
27500 ++}
27501 ++
27502 ++void *
27503 ++acl_alloc(unsigned long len)
27504 ++{
27505 ++ void *ret;
27506 ++
27507 ++ if (len > PAGE_SIZE)
27508 ++ BUG();
27509 ++
27510 ++ ret = kmalloc(len, GFP_KERNEL);
27511 ++
27512 ++ if (ret)
27513 ++ alloc_push(ret);
27514 ++
27515 ++ return ret;
27516 ++}
27517 ++
27518 ++void
27519 ++acl_free_all(void)
27520 ++{
27521 ++ if (gr_acl_is_enabled() || !alloc_stack)
27522 ++ return;
27523 ++
27524 ++ while (alloc_pop()) ;
27525 ++
27526 ++ if (alloc_stack) {
27527 ++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
27528 ++ kfree(alloc_stack);
27529 ++ else
27530 ++ vfree(alloc_stack);
27531 ++ }
27532 ++
27533 ++ alloc_stack = NULL;
27534 ++ alloc_stack_size = 1;
27535 ++ alloc_stack_next = 1;
27536 ++
27537 ++ return;
27538 ++}
27539 ++
27540 ++int
27541 ++acl_alloc_stack_init(unsigned long size)
27542 ++{
27543 ++ if ((size * sizeof (void *)) <= PAGE_SIZE)
27544 ++ alloc_stack =
27545 ++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
27546 ++ else
27547 ++ alloc_stack = (void **) vmalloc(size * sizeof (void *));
27548 ++
27549 ++ alloc_stack_size = size;
27550 ++
27551 ++ if (!alloc_stack)
27552 ++ return 0;
27553 ++ else
27554 ++ return 1;
27555 ++}
27556 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_cap.c linux-2.6.23.15-grsec/grsecurity/gracl_cap.c
27557 +--- linux-2.6.23.15/grsecurity/gracl_cap.c 1970-01-01 01:00:00.000000000 +0100
27558 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_cap.c 2008-02-11 10:37:44.000000000 +0000
27559 +@@ -0,0 +1,112 @@
27560 ++#include <linux/kernel.h>
27561 ++#include <linux/module.h>
27562 ++#include <linux/sched.h>
27563 ++#include <linux/capability.h>
27564 ++#include <linux/gracl.h>
27565 ++#include <linux/grsecurity.h>
27566 ++#include <linux/grinternal.h>
27567 ++
27568 ++static const char *captab_log[] = {
27569 ++ "CAP_CHOWN",
27570 ++ "CAP_DAC_OVERRIDE",
27571 ++ "CAP_DAC_READ_SEARCH",
27572 ++ "CAP_FOWNER",
27573 ++ "CAP_FSETID",
27574 ++ "CAP_KILL",
27575 ++ "CAP_SETGID",
27576 ++ "CAP_SETUID",
27577 ++ "CAP_SETPCAP",
27578 ++ "CAP_LINUX_IMMUTABLE",
27579 ++ "CAP_NET_BIND_SERVICE",
27580 ++ "CAP_NET_BROADCAST",
27581 ++ "CAP_NET_ADMIN",
27582 ++ "CAP_NET_RAW",
27583 ++ "CAP_IPC_LOCK",
27584 ++ "CAP_IPC_OWNER",
27585 ++ "CAP_SYS_MODULE",
27586 ++ "CAP_SYS_RAWIO",
27587 ++ "CAP_SYS_CHROOT",
27588 ++ "CAP_SYS_PTRACE",
27589 ++ "CAP_SYS_PACCT",
27590 ++ "CAP_SYS_ADMIN",
27591 ++ "CAP_SYS_BOOT",
27592 ++ "CAP_SYS_NICE",
27593 ++ "CAP_SYS_RESOURCE",
27594 ++ "CAP_SYS_TIME",
27595 ++ "CAP_SYS_TTY_CONFIG",
27596 ++ "CAP_MKNOD",
27597 ++ "CAP_LEASE",
27598 ++ "CAP_AUDIT_WRITE",
27599 ++ "CAP_AUDIT_CONTROL"
27600 ++};
27601 ++
27602 ++EXPORT_SYMBOL(gr_task_is_capable);
27603 ++EXPORT_SYMBOL(gr_is_capable_nolog);
27604 ++
27605 ++int
27606 ++gr_task_is_capable(struct task_struct *task, const int cap)
27607 ++{
27608 ++ struct acl_subject_label *curracl;
27609 ++ __u32 cap_drop = 0, cap_mask = 0;
27610 ++
27611 ++ if (!gr_acl_is_enabled())
27612 ++ return 1;
27613 ++
27614 ++ curracl = task->acl;
27615 ++
27616 ++ cap_drop = curracl->cap_lower;
27617 ++ cap_mask = curracl->cap_mask;
27618 ++
27619 ++ while ((curracl = curracl->parent_subject)) {
27620 ++ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
27621 ++ cap_drop |= curracl->cap_lower & (1 << cap);
27622 ++ cap_mask |= curracl->cap_mask;
27623 ++ }
27624 ++
27625 ++ if (!cap_raised(cap_drop, cap))
27626 ++ return 1;
27627 ++
27628 ++ curracl = task->acl;
27629 ++
27630 ++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
27631 ++ && cap_raised(task->cap_effective, cap)) {
27632 ++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
27633 ++ task->role->roletype, task->uid,
27634 ++ task->gid, task->exec_file ?
27635 ++ gr_to_filename(task->exec_file->f_dentry,
27636 ++ task->exec_file->f_vfsmnt) : curracl->filename,
27637 ++ curracl->filename, 0UL,
27638 ++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
27639 ++ return 1;
27640 ++ }
27641 ++
27642 ++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
27643 ++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
27644 ++ return 0;
27645 ++}
27646 ++
27647 ++int
27648 ++gr_is_capable_nolog(const int cap)
27649 ++{
27650 ++ struct acl_subject_label *curracl;
27651 ++ __u32 cap_drop = 0, cap_mask = 0;
27652 ++
27653 ++ if (!gr_acl_is_enabled())
27654 ++ return 1;
27655 ++
27656 ++ curracl = current->acl;
27657 ++
27658 ++ cap_drop = curracl->cap_lower;
27659 ++ cap_mask = curracl->cap_mask;
27660 ++
27661 ++ while ((curracl = curracl->parent_subject)) {
27662 ++ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
27663 ++ cap_mask |= curracl->cap_mask;
27664 ++ }
27665 ++
27666 ++ if (!cap_raised(cap_drop, cap))
27667 ++ return 1;
27668 ++
27669 ++ return 0;
27670 ++}
27671 ++
27672 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_fs.c linux-2.6.23.15-grsec/grsecurity/gracl_fs.c
27673 +--- linux-2.6.23.15/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100
27674 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_fs.c 2008-02-11 10:37:44.000000000 +0000
27675 +@@ -0,0 +1,423 @@
27676 ++#include <linux/kernel.h>
27677 ++#include <linux/sched.h>
27678 ++#include <linux/types.h>
27679 ++#include <linux/fs.h>
27680 ++#include <linux/file.h>
27681 ++#include <linux/stat.h>
27682 ++#include <linux/grsecurity.h>
27683 ++#include <linux/grinternal.h>
27684 ++#include <linux/gracl.h>
27685 ++
27686 ++__u32
27687 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
27688 ++ const struct vfsmount * mnt)
27689 ++{
27690 ++ __u32 mode;
27691 ++
27692 ++ if (unlikely(!dentry->d_inode))
27693 ++ return GR_FIND;
27694 ++
27695 ++ mode =
27696 ++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
27697 ++
27698 ++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
27699 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
27700 ++ return mode;
27701 ++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
27702 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
27703 ++ return 0;
27704 ++ } else if (unlikely(!(mode & GR_FIND)))
27705 ++ return 0;
27706 ++
27707 ++ return GR_FIND;
27708 ++}
27709 ++
27710 ++__u32
27711 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
27712 ++ const int fmode)
27713 ++{
27714 ++ __u32 reqmode = GR_FIND;
27715 ++ __u32 mode;
27716 ++
27717 ++ if (unlikely(!dentry->d_inode))
27718 ++ return reqmode;
27719 ++
27720 ++ if (unlikely(fmode & O_APPEND))
27721 ++ reqmode |= GR_APPEND;
27722 ++ else if (unlikely(fmode & FMODE_WRITE))
27723 ++ reqmode |= GR_WRITE;
27724 ++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
27725 ++ reqmode |= GR_READ;
27726 ++
27727 ++ mode =
27728 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
27729 ++ mnt);
27730 ++
27731 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27732 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
27733 ++ reqmode & GR_READ ? " reading" : "",
27734 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27735 ++ GR_APPEND ? " appending" : "");
27736 ++ return reqmode;
27737 ++ } else
27738 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27739 ++ {
27740 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
27741 ++ reqmode & GR_READ ? " reading" : "",
27742 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27743 ++ GR_APPEND ? " appending" : "");
27744 ++ return 0;
27745 ++ } else if (unlikely((mode & reqmode) != reqmode))
27746 ++ return 0;
27747 ++
27748 ++ return reqmode;
27749 ++}
27750 ++
27751 ++__u32
27752 ++gr_acl_handle_creat(const struct dentry * dentry,
27753 ++ const struct dentry * p_dentry,
27754 ++ const struct vfsmount * p_mnt, const int fmode,
27755 ++ const int imode)
27756 ++{
27757 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
27758 ++ __u32 mode;
27759 ++
27760 ++ if (unlikely(fmode & O_APPEND))
27761 ++ reqmode |= GR_APPEND;
27762 ++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
27763 ++ reqmode |= GR_READ;
27764 ++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
27765 ++ reqmode |= GR_SETID;
27766 ++
27767 ++ mode =
27768 ++ gr_check_create(dentry, p_dentry, p_mnt,
27769 ++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
27770 ++
27771 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27772 ++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
27773 ++ reqmode & GR_READ ? " reading" : "",
27774 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27775 ++ GR_APPEND ? " appending" : "");
27776 ++ return reqmode;
27777 ++ } else
27778 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27779 ++ {
27780 ++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
27781 ++ reqmode & GR_READ ? " reading" : "",
27782 ++ reqmode & GR_WRITE ? " writing" : reqmode &
27783 ++ GR_APPEND ? " appending" : "");
27784 ++ return 0;
27785 ++ } else if (unlikely((mode & reqmode) != reqmode))
27786 ++ return 0;
27787 ++
27788 ++ return reqmode;
27789 ++}
27790 ++
27791 ++__u32
27792 ++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
27793 ++ const int fmode)
27794 ++{
27795 ++ __u32 mode, reqmode = GR_FIND;
27796 ++
27797 ++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
27798 ++ reqmode |= GR_EXEC;
27799 ++ if (fmode & S_IWOTH)
27800 ++ reqmode |= GR_WRITE;
27801 ++ if (fmode & S_IROTH)
27802 ++ reqmode |= GR_READ;
27803 ++
27804 ++ mode =
27805 ++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
27806 ++ mnt);
27807 ++
27808 ++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
27809 ++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
27810 ++ reqmode & GR_READ ? " reading" : "",
27811 ++ reqmode & GR_WRITE ? " writing" : "",
27812 ++ reqmode & GR_EXEC ? " executing" : "");
27813 ++ return reqmode;
27814 ++ } else
27815 ++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
27816 ++ {
27817 ++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
27818 ++ reqmode & GR_READ ? " reading" : "",
27819 ++ reqmode & GR_WRITE ? " writing" : "",
27820 ++ reqmode & GR_EXEC ? " executing" : "");
27821 ++ return 0;
27822 ++ } else if (unlikely((mode & reqmode) != reqmode))
27823 ++ return 0;
27824 ++
27825 ++ return reqmode;
27826 ++}
27827 ++
27828 ++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
27829 ++{
27830 ++ __u32 mode;
27831 ++
27832 ++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
27833 ++
27834 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
27835 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
27836 ++ return mode;
27837 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
27838 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
27839 ++ return 0;
27840 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
27841 ++ return 0;
27842 ++
27843 ++ return (reqmode);
27844 ++}
27845 ++
27846 ++__u32
27847 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
27848 ++{
27849 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
27850 ++}
27851 ++
27852 ++__u32
27853 ++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
27854 ++{
27855 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
27856 ++}
27857 ++
27858 ++__u32
27859 ++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
27860 ++{
27861 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
27862 ++}
27863 ++
27864 ++__u32
27865 ++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
27866 ++{
27867 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
27868 ++}
27869 ++
27870 ++__u32
27871 ++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
27872 ++ mode_t mode)
27873 ++{
27874 ++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
27875 ++ return 1;
27876 ++
27877 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
27878 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
27879 ++ GR_FCHMOD_ACL_MSG);
27880 ++ } else {
27881 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
27882 ++ }
27883 ++}
27884 ++
27885 ++__u32
27886 ++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
27887 ++ mode_t mode)
27888 ++{
27889 ++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
27890 ++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
27891 ++ GR_CHMOD_ACL_MSG);
27892 ++ } else {
27893 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
27894 ++ }
27895 ++}
27896 ++
27897 ++__u32
27898 ++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
27899 ++{
27900 ++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
27901 ++}
27902 ++
27903 ++__u32
27904 ++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
27905 ++{
27906 ++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
27907 ++}
27908 ++
27909 ++__u32
27910 ++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
27911 ++{
27912 ++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
27913 ++ GR_UNIXCONNECT_ACL_MSG);
27914 ++}
27915 ++
27916 ++/* hardlinks require at minimum create permission,
27917 ++ any additional privilege required is based on the
27918 ++ privilege of the file being linked to
27919 ++*/
27920 ++__u32
27921 ++gr_acl_handle_link(const struct dentry * new_dentry,
27922 ++ const struct dentry * parent_dentry,
27923 ++ const struct vfsmount * parent_mnt,
27924 ++ const struct dentry * old_dentry,
27925 ++ const struct vfsmount * old_mnt, const char *to)
27926 ++{
27927 ++ __u32 mode;
27928 ++ __u32 needmode = GR_CREATE | GR_LINK;
27929 ++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
27930 ++
27931 ++ mode =
27932 ++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
27933 ++ old_mnt);
27934 ++
27935 ++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
27936 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
27937 ++ return mode;
27938 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
27939 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
27940 ++ return 0;
27941 ++ } else if (unlikely((mode & needmode) != needmode))
27942 ++ return 0;
27943 ++
27944 ++ return 1;
27945 ++}
27946 ++
27947 ++__u32
27948 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
27949 ++ const struct dentry * parent_dentry,
27950 ++ const struct vfsmount * parent_mnt, const char *from)
27951 ++{
27952 ++ __u32 needmode = GR_WRITE | GR_CREATE;
27953 ++ __u32 mode;
27954 ++
27955 ++ mode =
27956 ++ gr_check_create(new_dentry, parent_dentry, parent_mnt,
27957 ++ GR_CREATE | GR_AUDIT_CREATE |
27958 ++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
27959 ++
27960 ++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
27961 ++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
27962 ++ return mode;
27963 ++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
27964 ++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
27965 ++ return 0;
27966 ++ } else if (unlikely((mode & needmode) != needmode))
27967 ++ return 0;
27968 ++
27969 ++ return (GR_WRITE | GR_CREATE);
27970 ++}
27971 ++
27972 ++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)
27973 ++{
27974 ++ __u32 mode;
27975 ++
27976 ++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
27977 ++
27978 ++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
27979 ++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
27980 ++ return mode;
27981 ++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
27982 ++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
27983 ++ return 0;
27984 ++ } else if (unlikely((mode & (reqmode)) != (reqmode)))
27985 ++ return 0;
27986 ++
27987 ++ return (reqmode);
27988 ++}
27989 ++
27990 ++__u32
27991 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
27992 ++ const struct dentry * parent_dentry,
27993 ++ const struct vfsmount * parent_mnt,
27994 ++ const int mode)
27995 ++{
27996 ++ __u32 reqmode = GR_WRITE | GR_CREATE;
27997 ++ if (unlikely(mode & (S_ISUID | S_ISGID)))
27998 ++ reqmode |= GR_SETID;
27999 ++
28000 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
28001 ++ reqmode, GR_MKNOD_ACL_MSG);
28002 ++}
28003 ++
28004 ++__u32
28005 ++gr_acl_handle_mkdir(const struct dentry *new_dentry,
28006 ++ const struct dentry *parent_dentry,
28007 ++ const struct vfsmount *parent_mnt)
28008 ++{
28009 ++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
28010 ++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
28011 ++}
28012 ++
28013 ++#define RENAME_CHECK_SUCCESS(old, new) \
28014 ++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
28015 ++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
28016 ++
28017 ++int
28018 ++gr_acl_handle_rename(struct dentry *new_dentry,
28019 ++ struct dentry *parent_dentry,
28020 ++ const struct vfsmount *parent_mnt,
28021 ++ struct dentry *old_dentry,
28022 ++ struct inode *old_parent_inode,
28023 ++ struct vfsmount *old_mnt, const char *newname)
28024 ++{
28025 ++ __u32 comp1, comp2;
28026 ++ int error = 0;
28027 ++
28028 ++ if (unlikely(!gr_acl_is_enabled()))
28029 ++ return 0;
28030 ++
28031 ++ if (!new_dentry->d_inode) {
28032 ++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
28033 ++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
28034 ++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
28035 ++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
28036 ++ GR_DELETE | GR_AUDIT_DELETE |
28037 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
28038 ++ GR_SUPPRESS, old_mnt);
28039 ++ } else {
28040 ++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
28041 ++ GR_CREATE | GR_DELETE |
28042 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
28043 ++ GR_AUDIT_READ | GR_AUDIT_WRITE |
28044 ++ GR_SUPPRESS, parent_mnt);
28045 ++ comp2 =
28046 ++ gr_search_file(old_dentry,
28047 ++ GR_READ | GR_WRITE | GR_AUDIT_READ |
28048 ++ GR_DELETE | GR_AUDIT_DELETE |
28049 ++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
28050 ++ }
28051 ++
28052 ++ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
28053 ++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
28054 ++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
28055 ++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
28056 ++ && !(comp2 & GR_SUPPRESS)) {
28057 ++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
28058 ++ error = -EACCES;
28059 ++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
28060 ++ error = -EACCES;
28061 ++
28062 ++ return error;
28063 ++}
28064 ++
28065 ++void
28066 ++gr_acl_handle_exit(void)
28067 ++{
28068 ++ u16 id;
28069 ++ char *rolename;
28070 ++ struct file *exec_file;
28071 ++
28072 ++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
28073 ++ id = current->acl_role_id;
28074 ++ rolename = current->role->rolename;
28075 ++ gr_set_acls(1);
28076 ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
28077 ++ }
28078 ++
28079 ++ write_lock(&grsec_exec_file_lock);
28080 ++ exec_file = current->exec_file;
28081 ++ current->exec_file = NULL;
28082 ++ write_unlock(&grsec_exec_file_lock);
28083 ++
28084 ++ if (exec_file)
28085 ++ fput(exec_file);
28086 ++}
28087 ++
28088 ++int
28089 ++gr_acl_handle_procpidmem(const struct task_struct *task)
28090 ++{
28091 ++ if (unlikely(!gr_acl_is_enabled()))
28092 ++ return 0;
28093 ++
28094 ++ if (task->acl->mode & GR_PROTPROCFD)
28095 ++ return -EACCES;
28096 ++
28097 ++ return 0;
28098 ++}
28099 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_ip.c linux-2.6.23.15-grsec/grsecurity/gracl_ip.c
28100 +--- linux-2.6.23.15/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100
28101 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_ip.c 2008-02-11 10:37:44.000000000 +0000
28102 +@@ -0,0 +1,313 @@
28103 ++#include <linux/kernel.h>
28104 ++#include <asm/uaccess.h>
28105 ++#include <asm/errno.h>
28106 ++#include <net/sock.h>
28107 ++#include <linux/file.h>
28108 ++#include <linux/fs.h>
28109 ++#include <linux/net.h>
28110 ++#include <linux/in.h>
28111 ++#include <linux/skbuff.h>
28112 ++#include <linux/ip.h>
28113 ++#include <linux/udp.h>
28114 ++#include <linux/smp_lock.h>
28115 ++#include <linux/types.h>
28116 ++#include <linux/sched.h>
28117 ++#include <linux/netdevice.h>
28118 ++#include <linux/inetdevice.h>
28119 ++#include <linux/gracl.h>
28120 ++#include <linux/grsecurity.h>
28121 ++#include <linux/grinternal.h>
28122 ++
28123 ++#define GR_BIND 0x01
28124 ++#define GR_CONNECT 0x02
28125 ++#define GR_INVERT 0x04
28126 ++
28127 ++static const char * gr_protocols[256] = {
28128 ++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
28129 ++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
28130 ++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
28131 ++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
28132 ++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
28133 ++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
28134 ++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
28135 ++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
28136 ++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
28137 ++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
28138 ++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
28139 ++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
28140 ++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
28141 ++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
28142 ++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
28143 ++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
28144 ++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
28145 ++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
28146 ++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
28147 ++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
28148 ++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
28149 ++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
28150 ++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
28151 ++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
28152 ++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
28153 ++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
28154 ++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
28155 ++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
28156 ++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
28157 ++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
28158 ++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
28159 ++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
28160 ++ };
28161 ++
28162 ++static const char * gr_socktypes[11] = {
28163 ++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
28164 ++ "unknown:7", "unknown:8", "unknown:9", "packet"
28165 ++ };
28166 ++
28167 ++const char *
28168 ++gr_proto_to_name(unsigned char proto)
28169 ++{
28170 ++ return gr_protocols[proto];
28171 ++}
28172 ++
28173 ++const char *
28174 ++gr_socktype_to_name(unsigned char type)
28175 ++{
28176 ++ return gr_socktypes[type];
28177 ++}
28178 ++
28179 ++int
28180 ++gr_search_socket(const int domain, const int type, const int protocol)
28181 ++{
28182 ++ struct acl_subject_label *curr;
28183 ++
28184 ++ if (unlikely(!gr_acl_is_enabled()))
28185 ++ goto exit;
28186 ++
28187 ++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
28188 ++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
28189 ++ goto exit; // let the kernel handle it
28190 ++
28191 ++ curr = current->acl;
28192 ++
28193 ++ if (!curr->ips)
28194 ++ goto exit;
28195 ++
28196 ++ if ((curr->ip_type & (1 << type)) &&
28197 ++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
28198 ++ goto exit;
28199 ++
28200 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
28201 ++ /* we don't place acls on raw sockets , and sometimes
28202 ++ dgram/ip sockets are opened for ioctl and not
28203 ++ bind/connect, so we'll fake a bind learn log */
28204 ++ if (type == SOCK_RAW || type == SOCK_PACKET) {
28205 ++ __u32 fakeip = 0;
28206 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28207 ++ current->role->roletype, current->uid,
28208 ++ current->gid, current->exec_file ?
28209 ++ gr_to_filename(current->exec_file->f_dentry,
28210 ++ current->exec_file->f_vfsmnt) :
28211 ++ curr->filename, curr->filename,
28212 ++ NIPQUAD(fakeip), 0, type,
28213 ++ protocol, GR_CONNECT,
28214 ++NIPQUAD(current->signal->curr_ip));
28215 ++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
28216 ++ __u32 fakeip = 0;
28217 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28218 ++ current->role->roletype, current->uid,
28219 ++ current->gid, current->exec_file ?
28220 ++ gr_to_filename(current->exec_file->f_dentry,
28221 ++ current->exec_file->f_vfsmnt) :
28222 ++ curr->filename, curr->filename,
28223 ++ NIPQUAD(fakeip), 0, type,
28224 ++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
28225 ++ }
28226 ++ /* we'll log when they use connect or bind */
28227 ++ goto exit;
28228 ++ }
28229 ++
28230 ++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
28231 ++ gr_socktype_to_name(type), gr_proto_to_name(protocol));
28232 ++
28233 ++ return 0;
28234 ++ exit:
28235 ++ return 1;
28236 ++}
28237 ++
28238 ++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)
28239 ++{
28240 ++ if ((ip->mode & mode) &&
28241 ++ (ip_port >= ip->low) &&
28242 ++ (ip_port <= ip->high) &&
28243 ++ ((ntohl(ip_addr) & our_netmask) ==
28244 ++ (ntohl(our_addr) & our_netmask))
28245 ++ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
28246 ++ && (ip->type & (1 << type))) {
28247 ++ if (ip->mode & GR_INVERT)
28248 ++ return 2; // specifically denied
28249 ++ else
28250 ++ return 1; // allowed
28251 ++ }
28252 ++
28253 ++ return 0; // not specifically allowed, may continue parsing
28254 ++}
28255 ++
28256 ++static int
28257 ++gr_search_connectbind(const int mode, const struct sock *sk,
28258 ++ const struct sockaddr_in *addr, const int type)
28259 ++{
28260 ++ char iface[IFNAMSIZ] = {0};
28261 ++ struct acl_subject_label *curr;
28262 ++ struct acl_ip_label *ip;
28263 ++ struct net_device *dev;
28264 ++ struct in_device *idev;
28265 ++ unsigned long i;
28266 ++ int ret;
28267 ++ __u32 ip_addr = 0;
28268 ++ __u32 our_addr;
28269 ++ __u32 our_netmask;
28270 ++ char *p;
28271 ++ __u16 ip_port = 0;
28272 ++
28273 ++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
28274 ++ return 1;
28275 ++
28276 ++ curr = current->acl;
28277 ++
28278 ++ if (!curr->ips)
28279 ++ return 1;
28280 ++
28281 ++ ip_addr = addr->sin_addr.s_addr;
28282 ++ ip_port = ntohs(addr->sin_port);
28283 ++
28284 ++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
28285 ++ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
28286 ++ current->role->roletype, current->uid,
28287 ++ current->gid, current->exec_file ?
28288 ++ gr_to_filename(current->exec_file->f_dentry,
28289 ++ current->exec_file->f_vfsmnt) :
28290 ++ curr->filename, curr->filename,
28291 ++ NIPQUAD(ip_addr), ip_port, type,
28292 ++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
28293 ++ return 1;
28294 ++ }
28295 ++
28296 ++ for (i = 0; i < curr->ip_num; i++) {
28297 ++ ip = *(curr->ips + i);
28298 ++ if (ip->iface != NULL) {
28299 ++ strncpy(iface, ip->iface, IFNAMSIZ - 1);
28300 ++ p = strchr(iface, ':');
28301 ++ if (p != NULL)
28302 ++ *p = '\0';
28303 ++ dev = dev_get_by_name(iface);
28304 ++ if (dev == NULL)
28305 ++ continue;
28306 ++ idev = in_dev_get(dev);
28307 ++ if (idev == NULL) {
28308 ++ dev_put(dev);
28309 ++ continue;
28310 ++ }
28311 ++ rcu_read_lock();
28312 ++ for_ifa(idev) {
28313 ++ if (!strcmp(ip->iface, ifa->ifa_label)) {
28314 ++ our_addr = ifa->ifa_address;
28315 ++ our_netmask = 0xffffffff;
28316 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
28317 ++ if (ret == 1) {
28318 ++ rcu_read_unlock();
28319 ++ in_dev_put(idev);
28320 ++ dev_put(dev);
28321 ++ return 1;
28322 ++ } else if (ret == 2) {
28323 ++ rcu_read_unlock();
28324 ++ in_dev_put(idev);
28325 ++ dev_put(dev);
28326 ++ goto denied;
28327 ++ }
28328 ++ }
28329 ++ } endfor_ifa(idev);
28330 ++ rcu_read_unlock();
28331 ++ in_dev_put(idev);
28332 ++ dev_put(dev);
28333 ++ } else {
28334 ++ our_addr = ip->addr;
28335 ++ our_netmask = ip->netmask;
28336 ++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
28337 ++ if (ret == 1)
28338 ++ return 1;
28339 ++ else if (ret == 2)
28340 ++ goto denied;
28341 ++ }
28342 ++ }
28343 ++
28344 ++denied:
28345 ++ if (mode == GR_BIND)
28346 ++ 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));
28347 ++ else if (mode == GR_CONNECT)
28348 ++ 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));
28349 ++
28350 ++ return 0;
28351 ++}
28352 ++
28353 ++int
28354 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
28355 ++{
28356 ++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
28357 ++}
28358 ++
28359 ++int
28360 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
28361 ++{
28362 ++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
28363 ++}
28364 ++
28365 ++int gr_search_listen(const struct socket *sock)
28366 ++{
28367 ++ struct sock *sk = sock->sk;
28368 ++ struct sockaddr_in addr;
28369 ++
28370 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
28371 ++ addr.sin_port = inet_sk(sk)->sport;
28372 ++
28373 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
28374 ++}
28375 ++
28376 ++int gr_search_accept(const struct socket *sock)
28377 ++{
28378 ++ struct sock *sk = sock->sk;
28379 ++ struct sockaddr_in addr;
28380 ++
28381 ++ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
28382 ++ addr.sin_port = inet_sk(sk)->sport;
28383 ++
28384 ++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
28385 ++}
28386 ++
28387 ++int
28388 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
28389 ++{
28390 ++ if (addr)
28391 ++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
28392 ++ else {
28393 ++ struct sockaddr_in sin;
28394 ++ const struct inet_sock *inet = inet_sk(sk);
28395 ++
28396 ++ sin.sin_addr.s_addr = inet->daddr;
28397 ++ sin.sin_port = inet->dport;
28398 ++
28399 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
28400 ++ }
28401 ++}
28402 ++
28403 ++int
28404 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
28405 ++{
28406 ++ struct sockaddr_in sin;
28407 ++
28408 ++ if (unlikely(skb->len < sizeof (struct udphdr)))
28409 ++ return 1; // skip this packet
28410 ++
28411 ++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
28412 ++ sin.sin_port = udp_hdr(skb)->source;
28413 ++
28414 ++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
28415 ++}
28416 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_learn.c linux-2.6.23.15-grsec/grsecurity/gracl_learn.c
28417 +--- linux-2.6.23.15/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100
28418 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_learn.c 2008-02-11 10:37:44.000000000 +0000
28419 +@@ -0,0 +1,211 @@
28420 ++#include <linux/kernel.h>
28421 ++#include <linux/mm.h>
28422 ++#include <linux/sched.h>
28423 ++#include <linux/poll.h>
28424 ++#include <linux/smp_lock.h>
28425 ++#include <linux/string.h>
28426 ++#include <linux/file.h>
28427 ++#include <linux/types.h>
28428 ++#include <linux/vmalloc.h>
28429 ++#include <linux/grinternal.h>
28430 ++
28431 ++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
28432 ++ size_t count, loff_t *ppos);
28433 ++extern int gr_acl_is_enabled(void);
28434 ++
28435 ++static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
28436 ++static int gr_learn_attached;
28437 ++
28438 ++/* use a 512k buffer */
28439 ++#define LEARN_BUFFER_SIZE (512 * 1024)
28440 ++
28441 ++static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
28442 ++static DECLARE_MUTEX(gr_learn_user_sem);
28443 ++
28444 ++/* we need to maintain two buffers, so that the kernel context of grlearn
28445 ++ uses a semaphore around the userspace copying, and the other kernel contexts
28446 ++ use a spinlock when copying into the buffer, since they cannot sleep
28447 ++*/
28448 ++static char *learn_buffer;
28449 ++static char *learn_buffer_user;
28450 ++static int learn_buffer_len;
28451 ++static int learn_buffer_user_len;
28452 ++
28453 ++static ssize_t
28454 ++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
28455 ++{
28456 ++ DECLARE_WAITQUEUE(wait, current);
28457 ++ ssize_t retval = 0;
28458 ++
28459 ++ add_wait_queue(&learn_wait, &wait);
28460 ++ set_current_state(TASK_INTERRUPTIBLE);
28461 ++ do {
28462 ++ down(&gr_learn_user_sem);
28463 ++ spin_lock(&gr_learn_lock);
28464 ++ if (learn_buffer_len)
28465 ++ break;
28466 ++ spin_unlock(&gr_learn_lock);
28467 ++ up(&gr_learn_user_sem);
28468 ++ if (file->f_flags & O_NONBLOCK) {
28469 ++ retval = -EAGAIN;
28470 ++ goto out;
28471 ++ }
28472 ++ if (signal_pending(current)) {
28473 ++ retval = -ERESTARTSYS;
28474 ++ goto out;
28475 ++ }
28476 ++
28477 ++ schedule();
28478 ++ } while (1);
28479 ++
28480 ++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
28481 ++ learn_buffer_user_len = learn_buffer_len;
28482 ++ retval = learn_buffer_len;
28483 ++ learn_buffer_len = 0;
28484 ++
28485 ++ spin_unlock(&gr_learn_lock);
28486 ++
28487 ++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
28488 ++ retval = -EFAULT;
28489 ++
28490 ++ up(&gr_learn_user_sem);
28491 ++out:
28492 ++ set_current_state(TASK_RUNNING);
28493 ++ remove_wait_queue(&learn_wait, &wait);
28494 ++ return retval;
28495 ++}
28496 ++
28497 ++static unsigned int
28498 ++poll_learn(struct file * file, poll_table * wait)
28499 ++{
28500 ++ poll_wait(file, &learn_wait, wait);
28501 ++
28502 ++ if (learn_buffer_len)
28503 ++ return (POLLIN | POLLRDNORM);
28504 ++
28505 ++ return 0;
28506 ++}
28507 ++
28508 ++void
28509 ++gr_clear_learn_entries(void)
28510 ++{
28511 ++ char *tmp;
28512 ++
28513 ++ down(&gr_learn_user_sem);
28514 ++ if (learn_buffer != NULL) {
28515 ++ spin_lock(&gr_learn_lock);
28516 ++ tmp = learn_buffer;
28517 ++ learn_buffer = NULL;
28518 ++ spin_unlock(&gr_learn_lock);
28519 ++ vfree(learn_buffer);
28520 ++ }
28521 ++ if (learn_buffer_user != NULL) {
28522 ++ vfree(learn_buffer_user);
28523 ++ learn_buffer_user = NULL;
28524 ++ }
28525 ++ learn_buffer_len = 0;
28526 ++ up(&gr_learn_user_sem);
28527 ++
28528 ++ return;
28529 ++}
28530 ++
28531 ++void
28532 ++gr_add_learn_entry(const char *fmt, ...)
28533 ++{
28534 ++ va_list args;
28535 ++ unsigned int len;
28536 ++
28537 ++ if (!gr_learn_attached)
28538 ++ return;
28539 ++
28540 ++ spin_lock(&gr_learn_lock);
28541 ++
28542 ++ /* leave a gap at the end so we know when it's "full" but don't have to
28543 ++ compute the exact length of the string we're trying to append
28544 ++ */
28545 ++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
28546 ++ spin_unlock(&gr_learn_lock);
28547 ++ wake_up_interruptible(&learn_wait);
28548 ++ return;
28549 ++ }
28550 ++ if (learn_buffer == NULL) {
28551 ++ spin_unlock(&gr_learn_lock);
28552 ++ return;
28553 ++ }
28554 ++
28555 ++ va_start(args, fmt);
28556 ++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
28557 ++ va_end(args);
28558 ++
28559 ++ learn_buffer_len += len + 1;
28560 ++
28561 ++ spin_unlock(&gr_learn_lock);
28562 ++ wake_up_interruptible(&learn_wait);
28563 ++
28564 ++ return;
28565 ++}
28566 ++
28567 ++static int
28568 ++open_learn(struct inode *inode, struct file *file)
28569 ++{
28570 ++ if (file->f_mode & FMODE_READ && gr_learn_attached)
28571 ++ return -EBUSY;
28572 ++ if (file->f_mode & FMODE_READ) {
28573 ++ int retval = 0;
28574 ++ down(&gr_learn_user_sem);
28575 ++ if (learn_buffer == NULL)
28576 ++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
28577 ++ if (learn_buffer_user == NULL)
28578 ++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
28579 ++ if (learn_buffer == NULL) {
28580 ++ retval = -ENOMEM;
28581 ++ goto out_error;
28582 ++ }
28583 ++ if (learn_buffer_user == NULL) {
28584 ++ retval = -ENOMEM;
28585 ++ goto out_error;
28586 ++ }
28587 ++ learn_buffer_len = 0;
28588 ++ learn_buffer_user_len = 0;
28589 ++ gr_learn_attached = 1;
28590 ++out_error:
28591 ++ up(&gr_learn_user_sem);
28592 ++ return retval;
28593 ++ }
28594 ++ return 0;
28595 ++}
28596 ++
28597 ++static int
28598 ++close_learn(struct inode *inode, struct file *file)
28599 ++{
28600 ++ char *tmp;
28601 ++
28602 ++ if (file->f_mode & FMODE_READ) {
28603 ++ down(&gr_learn_user_sem);
28604 ++ if (learn_buffer != NULL) {
28605 ++ spin_lock(&gr_learn_lock);
28606 ++ tmp = learn_buffer;
28607 ++ learn_buffer = NULL;
28608 ++ spin_unlock(&gr_learn_lock);
28609 ++ vfree(tmp);
28610 ++ }
28611 ++ if (learn_buffer_user != NULL) {
28612 ++ vfree(learn_buffer_user);
28613 ++ learn_buffer_user = NULL;
28614 ++ }
28615 ++ learn_buffer_len = 0;
28616 ++ learn_buffer_user_len = 0;
28617 ++ gr_learn_attached = 0;
28618 ++ up(&gr_learn_user_sem);
28619 ++ }
28620 ++
28621 ++ return 0;
28622 ++}
28623 ++
28624 ++struct file_operations grsec_fops = {
28625 ++ .read = read_learn,
28626 ++ .write = write_grsec_handler,
28627 ++ .open = open_learn,
28628 ++ .release = close_learn,
28629 ++ .poll = poll_learn,
28630 ++};
28631 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_res.c linux-2.6.23.15-grsec/grsecurity/gracl_res.c
28632 +--- linux-2.6.23.15/grsecurity/gracl_res.c 1970-01-01 01:00:00.000000000 +0100
28633 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_res.c 2008-02-11 10:37:44.000000000 +0000
28634 +@@ -0,0 +1,45 @@
28635 ++#include <linux/kernel.h>
28636 ++#include <linux/sched.h>
28637 ++#include <linux/gracl.h>
28638 ++#include <linux/grinternal.h>
28639 ++
28640 ++static const char *restab_log[] = {
28641 ++ [RLIMIT_CPU] = "RLIMIT_CPU",
28642 ++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
28643 ++ [RLIMIT_DATA] = "RLIMIT_DATA",
28644 ++ [RLIMIT_STACK] = "RLIMIT_STACK",
28645 ++ [RLIMIT_CORE] = "RLIMIT_CORE",
28646 ++ [RLIMIT_RSS] = "RLIMIT_RSS",
28647 ++ [RLIMIT_NPROC] = "RLIMIT_NPROC",
28648 ++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
28649 ++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
28650 ++ [RLIMIT_AS] = "RLIMIT_AS",
28651 ++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
28652 ++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
28653 ++};
28654 ++
28655 ++void
28656 ++gr_log_resource(const struct task_struct *task,
28657 ++ const int res, const unsigned long wanted, const int gt)
28658 ++{
28659 ++ if (res == RLIMIT_NPROC &&
28660 ++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
28661 ++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
28662 ++ return;
28663 ++ else if (res == RLIMIT_MEMLOCK &&
28664 ++ cap_raised(task->cap_effective, CAP_IPC_LOCK))
28665 ++ return;
28666 ++
28667 ++ if (!gr_acl_is_enabled() && !grsec_resource_logging)
28668 ++ return;
28669 ++
28670 ++ preempt_disable();
28671 ++
28672 ++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
28673 ++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
28674 ++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
28675 ++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
28676 ++ preempt_enable_no_resched();
28677 ++
28678 ++ return;
28679 ++}
28680 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_segv.c linux-2.6.23.15-grsec/grsecurity/gracl_segv.c
28681 +--- linux-2.6.23.15/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100
28682 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_segv.c 2008-02-11 10:37:44.000000000 +0000
28683 +@@ -0,0 +1,301 @@
28684 ++#include <linux/kernel.h>
28685 ++#include <linux/mm.h>
28686 ++#include <asm/uaccess.h>
28687 ++#include <asm/errno.h>
28688 ++#include <asm/mman.h>
28689 ++#include <net/sock.h>
28690 ++#include <linux/file.h>
28691 ++#include <linux/fs.h>
28692 ++#include <linux/net.h>
28693 ++#include <linux/in.h>
28694 ++#include <linux/smp_lock.h>
28695 ++#include <linux/slab.h>
28696 ++#include <linux/types.h>
28697 ++#include <linux/sched.h>
28698 ++#include <linux/timer.h>
28699 ++#include <linux/gracl.h>
28700 ++#include <linux/grsecurity.h>
28701 ++#include <linux/grinternal.h>
28702 ++
28703 ++static struct crash_uid *uid_set;
28704 ++static unsigned short uid_used;
28705 ++static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
28706 ++extern rwlock_t gr_inode_lock;
28707 ++extern struct acl_subject_label *
28708 ++ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
28709 ++ struct acl_role_label *role);
28710 ++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
28711 ++
28712 ++int
28713 ++gr_init_uidset(void)
28714 ++{
28715 ++ uid_set =
28716 ++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
28717 ++ uid_used = 0;
28718 ++
28719 ++ return uid_set ? 1 : 0;
28720 ++}
28721 ++
28722 ++void
28723 ++gr_free_uidset(void)
28724 ++{
28725 ++ if (uid_set)
28726 ++ kfree(uid_set);
28727 ++
28728 ++ return;
28729 ++}
28730 ++
28731 ++int
28732 ++gr_find_uid(const uid_t uid)
28733 ++{
28734 ++ struct crash_uid *tmp = uid_set;
28735 ++ uid_t buid;
28736 ++ int low = 0, high = uid_used - 1, mid;
28737 ++
28738 ++ while (high >= low) {
28739 ++ mid = (low + high) >> 1;
28740 ++ buid = tmp[mid].uid;
28741 ++ if (buid == uid)
28742 ++ return mid;
28743 ++ if (buid > uid)
28744 ++ high = mid - 1;
28745 ++ if (buid < uid)
28746 ++ low = mid + 1;
28747 ++ }
28748 ++
28749 ++ return -1;
28750 ++}
28751 ++
28752 ++static __inline__ void
28753 ++gr_insertsort(void)
28754 ++{
28755 ++ unsigned short i, j;
28756 ++ struct crash_uid index;
28757 ++
28758 ++ for (i = 1; i < uid_used; i++) {
28759 ++ index = uid_set[i];
28760 ++ j = i;
28761 ++ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
28762 ++ uid_set[j] = uid_set[j - 1];
28763 ++ j--;
28764 ++ }
28765 ++ uid_set[j] = index;
28766 ++ }
28767 ++
28768 ++ return;
28769 ++}
28770 ++
28771 ++static __inline__ void
28772 ++gr_insert_uid(const uid_t uid, const unsigned long expires)
28773 ++{
28774 ++ int loc;
28775 ++
28776 ++ if (uid_used == GR_UIDTABLE_MAX)
28777 ++ return;
28778 ++
28779 ++ loc = gr_find_uid(uid);
28780 ++
28781 ++ if (loc >= 0) {
28782 ++ uid_set[loc].expires = expires;
28783 ++ return;
28784 ++ }
28785 ++
28786 ++ uid_set[uid_used].uid = uid;
28787 ++ uid_set[uid_used].expires = expires;
28788 ++ uid_used++;
28789 ++
28790 ++ gr_insertsort();
28791 ++
28792 ++ return;
28793 ++}
28794 ++
28795 ++void
28796 ++gr_remove_uid(const unsigned short loc)
28797 ++{
28798 ++ unsigned short i;
28799 ++
28800 ++ for (i = loc + 1; i < uid_used; i++)
28801 ++ uid_set[i - 1] = uid_set[i];
28802 ++
28803 ++ uid_used--;
28804 ++
28805 ++ return;
28806 ++}
28807 ++
28808 ++int
28809 ++gr_check_crash_uid(const uid_t uid)
28810 ++{
28811 ++ int loc;
28812 ++ int ret = 0;
28813 ++
28814 ++ if (unlikely(!gr_acl_is_enabled()))
28815 ++ return 0;
28816 ++
28817 ++ spin_lock(&gr_uid_lock);
28818 ++ loc = gr_find_uid(uid);
28819 ++
28820 ++ if (loc < 0)
28821 ++ goto out_unlock;
28822 ++
28823 ++ if (time_before_eq(uid_set[loc].expires, get_seconds()))
28824 ++ gr_remove_uid(loc);
28825 ++ else
28826 ++ ret = 1;
28827 ++
28828 ++out_unlock:
28829 ++ spin_unlock(&gr_uid_lock);
28830 ++ return ret;
28831 ++}
28832 ++
28833 ++static __inline__ int
28834 ++proc_is_setxid(const struct task_struct *task)
28835 ++{
28836 ++ if (task->uid != task->euid || task->uid != task->suid ||
28837 ++ task->uid != task->fsuid)
28838 ++ return 1;
28839 ++ if (task->gid != task->egid || task->gid != task->sgid ||
28840 ++ task->gid != task->fsgid)
28841 ++ return 1;
28842 ++
28843 ++ return 0;
28844 ++}
28845 ++static __inline__ int
28846 ++gr_fake_force_sig(int sig, struct task_struct *t)
28847 ++{
28848 ++ unsigned long int flags;
28849 ++ int ret, blocked, ignored;
28850 ++ struct k_sigaction *action;
28851 ++
28852 ++ spin_lock_irqsave(&t->sighand->siglock, flags);
28853 ++ action = &t->sighand->action[sig-1];
28854 ++ ignored = action->sa.sa_handler == SIG_IGN;
28855 ++ blocked = sigismember(&t->blocked, sig);
28856 ++ if (blocked || ignored) {
28857 ++ action->sa.sa_handler = SIG_DFL;
28858 ++ if (blocked) {
28859 ++ sigdelset(&t->blocked, sig);
28860 ++ recalc_sigpending_and_wake(t);
28861 ++ }
28862 ++ }
28863 ++ ret = specific_send_sig_info(sig, (void*)1L, t);
28864 ++ spin_unlock_irqrestore(&t->sighand->siglock, flags);
28865 ++
28866 ++ return ret;
28867 ++}
28868 ++
28869 ++void
28870 ++gr_handle_crash(struct task_struct *task, const int sig)
28871 ++{
28872 ++ struct acl_subject_label *curr;
28873 ++ struct acl_subject_label *curr2;
28874 ++ struct task_struct *tsk, *tsk2;
28875 ++
28876 ++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
28877 ++ return;
28878 ++
28879 ++ if (unlikely(!gr_acl_is_enabled()))
28880 ++ return;
28881 ++
28882 ++ curr = task->acl;
28883 ++
28884 ++ if (!(curr->resmask & (1 << GR_CRASH_RES)))
28885 ++ return;
28886 ++
28887 ++ if (time_before_eq(curr->expires, get_seconds())) {
28888 ++ curr->expires = 0;
28889 ++ curr->crashes = 0;
28890 ++ }
28891 ++
28892 ++ curr->crashes++;
28893 ++
28894 ++ if (!curr->expires)
28895 ++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
28896 ++
28897 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
28898 ++ time_after(curr->expires, get_seconds())) {
28899 ++ if (task->uid && proc_is_setxid(task)) {
28900 ++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
28901 ++ spin_lock(&gr_uid_lock);
28902 ++ gr_insert_uid(task->uid, curr->expires);
28903 ++ spin_unlock(&gr_uid_lock);
28904 ++ curr->expires = 0;
28905 ++ curr->crashes = 0;
28906 ++ read_lock(&tasklist_lock);
28907 ++ do_each_thread(tsk2, tsk) {
28908 ++ if (tsk != task && tsk->uid == task->uid)
28909 ++ gr_fake_force_sig(SIGKILL, tsk);
28910 ++ } while_each_thread(tsk2, tsk);
28911 ++ read_unlock(&tasklist_lock);
28912 ++ } else {
28913 ++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
28914 ++ read_lock(&tasklist_lock);
28915 ++ do_each_thread(tsk2, tsk) {
28916 ++ if (likely(tsk != task)) {
28917 ++ curr2 = tsk->acl;
28918 ++
28919 ++ if (curr2->device == curr->device &&
28920 ++ curr2->inode == curr->inode)
28921 ++ gr_fake_force_sig(SIGKILL, tsk);
28922 ++ }
28923 ++ } while_each_thread(tsk2, tsk);
28924 ++ read_unlock(&tasklist_lock);
28925 ++ }
28926 ++ }
28927 ++
28928 ++ return;
28929 ++}
28930 ++
28931 ++int
28932 ++gr_check_crash_exec(const struct file *filp)
28933 ++{
28934 ++ struct acl_subject_label *curr;
28935 ++
28936 ++ if (unlikely(!gr_acl_is_enabled()))
28937 ++ return 0;
28938 ++
28939 ++ read_lock(&gr_inode_lock);
28940 ++ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
28941 ++ filp->f_dentry->d_inode->i_sb->s_dev,
28942 ++ current->role);
28943 ++ read_unlock(&gr_inode_lock);
28944 ++
28945 ++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
28946 ++ (!curr->crashes && !curr->expires))
28947 ++ return 0;
28948 ++
28949 ++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
28950 ++ time_after(curr->expires, get_seconds()))
28951 ++ return 1;
28952 ++ else if (time_before_eq(curr->expires, get_seconds())) {
28953 ++ curr->crashes = 0;
28954 ++ curr->expires = 0;
28955 ++ }
28956 ++
28957 ++ return 0;
28958 ++}
28959 ++
28960 ++void
28961 ++gr_handle_alertkill(struct task_struct *task)
28962 ++{
28963 ++ struct acl_subject_label *curracl;
28964 ++ __u32 curr_ip;
28965 ++ struct task_struct *p, *p2;
28966 ++
28967 ++ if (unlikely(!gr_acl_is_enabled()))
28968 ++ return;
28969 ++
28970 ++ curracl = task->acl;
28971 ++ curr_ip = task->signal->curr_ip;
28972 ++
28973 ++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
28974 ++ read_lock(&tasklist_lock);
28975 ++ do_each_thread(p2, p) {
28976 ++ if (p->signal->curr_ip == curr_ip)
28977 ++ gr_fake_force_sig(SIGKILL, p);
28978 ++ } while_each_thread(p2, p);
28979 ++ read_unlock(&tasklist_lock);
28980 ++ } else if (curracl->mode & GR_KILLPROC)
28981 ++ gr_fake_force_sig(SIGKILL, task);
28982 ++
28983 ++ return;
28984 ++}
28985 +diff -Nurp linux-2.6.23.15/grsecurity/gracl_shm.c linux-2.6.23.15-grsec/grsecurity/gracl_shm.c
28986 +--- linux-2.6.23.15/grsecurity/gracl_shm.c 1970-01-01 01:00:00.000000000 +0100
28987 ++++ linux-2.6.23.15-grsec/grsecurity/gracl_shm.c 2008-02-11 10:37:44.000000000 +0000
28988 +@@ -0,0 +1,33 @@
28989 ++#include <linux/kernel.h>
28990 ++#include <linux/mm.h>
28991 ++#include <linux/sched.h>
28992 ++#include <linux/file.h>
28993 ++#include <linux/ipc.h>
28994 ++#include <linux/gracl.h>
28995 ++#include <linux/grsecurity.h>
28996 ++#include <linux/grinternal.h>
28997 ++
28998 ++int
28999 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29000 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
29001 ++{
29002 ++ struct task_struct *task;
29003 ++
29004 ++ if (!gr_acl_is_enabled())
29005 ++ return 1;
29006 ++
29007 ++ task = find_task_by_pid(shm_cprid);
29008 ++
29009 ++ if (unlikely(!task))
29010 ++ task = find_task_by_pid(shm_lapid);
29011 ++
29012 ++ if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
29013 ++ (task->pid == shm_lapid)) &&
29014 ++ (task->acl->mode & GR_PROTSHM) &&
29015 ++ (task->acl != current->acl))) {
29016 ++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
29017 ++ return 0;
29018 ++ }
29019 ++
29020 ++ return 1;
29021 ++}
29022 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_chdir.c linux-2.6.23.15-grsec/grsecurity/grsec_chdir.c
29023 +--- linux-2.6.23.15/grsecurity/grsec_chdir.c 1970-01-01 01:00:00.000000000 +0100
29024 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_chdir.c 2008-02-11 10:37:44.000000000 +0000
29025 +@@ -0,0 +1,19 @@
29026 ++#include <linux/kernel.h>
29027 ++#include <linux/sched.h>
29028 ++#include <linux/fs.h>
29029 ++#include <linux/file.h>
29030 ++#include <linux/grsecurity.h>
29031 ++#include <linux/grinternal.h>
29032 ++
29033 ++void
29034 ++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
29035 ++{
29036 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
29037 ++ if ((grsec_enable_chdir && grsec_enable_group &&
29038 ++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
29039 ++ !grsec_enable_group)) {
29040 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
29041 ++ }
29042 ++#endif
29043 ++ return;
29044 ++}
29045 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_chroot.c linux-2.6.23.15-grsec/grsecurity/grsec_chroot.c
29046 +--- linux-2.6.23.15/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100
29047 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_chroot.c 2008-02-11 10:37:44.000000000 +0000
29048 +@@ -0,0 +1,335 @@
29049 ++#include <linux/kernel.h>
29050 ++#include <linux/module.h>
29051 ++#include <linux/sched.h>
29052 ++#include <linux/file.h>
29053 ++#include <linux/fs.h>
29054 ++#include <linux/mount.h>
29055 ++#include <linux/types.h>
29056 ++#include <linux/pid_namespace.h>
29057 ++#include <linux/grsecurity.h>
29058 ++#include <linux/grinternal.h>
29059 ++
29060 ++int
29061 ++gr_handle_chroot_unix(const pid_t pid)
29062 ++{
29063 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
29064 ++ struct pid *spid = NULL;
29065 ++
29066 ++ if (unlikely(!grsec_enable_chroot_unix))
29067 ++ return 1;
29068 ++
29069 ++ if (likely(!proc_is_chrooted(current)))
29070 ++ return 1;
29071 ++
29072 ++ read_lock(&tasklist_lock);
29073 ++
29074 ++ spid = find_pid(pid);
29075 ++ if (spid) {
29076 ++ struct task_struct *p;
29077 ++ p = pid_task(spid, PIDTYPE_PID);
29078 ++ task_lock(p);
29079 ++ if (unlikely(!have_same_root(current, p))) {
29080 ++ task_unlock(p);
29081 ++ read_unlock(&tasklist_lock);
29082 ++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
29083 ++ return 0;
29084 ++ }
29085 ++ task_unlock(p);
29086 ++ }
29087 ++ read_unlock(&tasklist_lock);
29088 ++#endif
29089 ++ return 1;
29090 ++}
29091 ++
29092 ++int
29093 ++gr_handle_chroot_nice(void)
29094 ++{
29095 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
29096 ++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
29097 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
29098 ++ return -EPERM;
29099 ++ }
29100 ++#endif
29101 ++ return 0;
29102 ++}
29103 ++
29104 ++int
29105 ++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
29106 ++{
29107 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
29108 ++ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
29109 ++ && proc_is_chrooted(current)) {
29110 ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
29111 ++ return -EACCES;
29112 ++ }
29113 ++#endif
29114 ++ return 0;
29115 ++}
29116 ++
29117 ++int
29118 ++gr_handle_chroot_rawio(const struct inode *inode)
29119 ++{
29120 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
29121 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
29122 ++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
29123 ++ return 1;
29124 ++#endif
29125 ++ return 0;
29126 ++}
29127 ++
29128 ++int
29129 ++gr_pid_is_chrooted(struct task_struct *p)
29130 ++{
29131 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
29132 ++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
29133 ++ return 0;
29134 ++
29135 ++ task_lock(p);
29136 ++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
29137 ++ !have_same_root(current, p)) {
29138 ++ task_unlock(p);
29139 ++ return 1;
29140 ++ }
29141 ++ task_unlock(p);
29142 ++#endif
29143 ++ return 0;
29144 ++}
29145 ++
29146 ++EXPORT_SYMBOL(gr_pid_is_chrooted);
29147 ++
29148 ++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
29149 ++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
29150 ++{
29151 ++ struct dentry *dentry = (struct dentry *)u_dentry;
29152 ++ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
29153 ++ struct dentry *realroot;
29154 ++ struct vfsmount *realrootmnt;
29155 ++ struct dentry *currentroot;
29156 ++ struct vfsmount *currentmnt;
29157 ++ struct task_struct *reaper = child_reaper(current);
29158 ++ int ret = 1;
29159 ++
29160 ++ read_lock(&reaper->fs->lock);
29161 ++ realrootmnt = mntget(reaper->fs->rootmnt);
29162 ++ realroot = dget(reaper->fs->root);
29163 ++ read_unlock(&reaper->fs->lock);
29164 ++
29165 ++ read_lock(&current->fs->lock);
29166 ++ currentmnt = mntget(current->fs->rootmnt);
29167 ++ currentroot = dget(current->fs->root);
29168 ++ read_unlock(&current->fs->lock);
29169 ++
29170 ++ spin_lock(&dcache_lock);
29171 ++ for (;;) {
29172 ++ if (unlikely((dentry == realroot && mnt == realrootmnt)
29173 ++ || (dentry == currentroot && mnt == currentmnt)))
29174 ++ break;
29175 ++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
29176 ++ if (mnt->mnt_parent == mnt)
29177 ++ break;
29178 ++ dentry = mnt->mnt_mountpoint;
29179 ++ mnt = mnt->mnt_parent;
29180 ++ continue;
29181 ++ }
29182 ++ dentry = dentry->d_parent;
29183 ++ }
29184 ++ spin_unlock(&dcache_lock);
29185 ++
29186 ++ dput(currentroot);
29187 ++ mntput(currentmnt);
29188 ++
29189 ++ /* access is outside of chroot */
29190 ++ if (dentry == realroot && mnt == realrootmnt)
29191 ++ ret = 0;
29192 ++
29193 ++ dput(realroot);
29194 ++ mntput(realrootmnt);
29195 ++ return ret;
29196 ++}
29197 ++#endif
29198 ++
29199 ++int
29200 ++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
29201 ++{
29202 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
29203 ++ if (!grsec_enable_chroot_fchdir)
29204 ++ return 1;
29205 ++
29206 ++ if (!proc_is_chrooted(current))
29207 ++ return 1;
29208 ++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
29209 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
29210 ++ return 0;
29211 ++ }
29212 ++#endif
29213 ++ return 1;
29214 ++}
29215 ++
29216 ++int
29217 ++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29218 ++ const time_t shm_createtime)
29219 ++{
29220 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
29221 ++ struct pid *pid = NULL;
29222 ++ time_t starttime;
29223 ++
29224 ++ if (unlikely(!grsec_enable_chroot_shmat))
29225 ++ return 1;
29226 ++
29227 ++ if (likely(!proc_is_chrooted(current)))
29228 ++ return 1;
29229 ++
29230 ++ read_lock(&tasklist_lock);
29231 ++
29232 ++ pid = find_pid(shm_cprid);
29233 ++ if (pid) {
29234 ++ struct task_struct *p;
29235 ++ p = pid_task(pid, PIDTYPE_PID);
29236 ++ task_lock(p);
29237 ++ starttime = p->start_time.tv_sec;
29238 ++ if (unlikely(!have_same_root(current, p) &&
29239 ++ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
29240 ++ task_unlock(p);
29241 ++ read_unlock(&tasklist_lock);
29242 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
29243 ++ return 0;
29244 ++ }
29245 ++ task_unlock(p);
29246 ++ } else {
29247 ++ pid = find_pid(shm_lapid);
29248 ++ if (pid) {
29249 ++ struct task_struct *p;
29250 ++ p = pid_task(pid, PIDTYPE_PID);
29251 ++ task_lock(p);
29252 ++ if (unlikely(!have_same_root(current, p))) {
29253 ++ task_unlock(p);
29254 ++ read_unlock(&tasklist_lock);
29255 ++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
29256 ++ return 0;
29257 ++ }
29258 ++ task_unlock(p);
29259 ++ }
29260 ++ }
29261 ++
29262 ++ read_unlock(&tasklist_lock);
29263 ++#endif
29264 ++ return 1;
29265 ++}
29266 ++
29267 ++void
29268 ++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
29269 ++{
29270 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
29271 ++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
29272 ++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
29273 ++#endif
29274 ++ return;
29275 ++}
29276 ++
29277 ++int
29278 ++gr_handle_chroot_mknod(const struct dentry *dentry,
29279 ++ const struct vfsmount *mnt, const int mode)
29280 ++{
29281 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
29282 ++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
29283 ++ proc_is_chrooted(current)) {
29284 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
29285 ++ return -EPERM;
29286 ++ }
29287 ++#endif
29288 ++ return 0;
29289 ++}
29290 ++
29291 ++int
29292 ++gr_handle_chroot_mount(const struct dentry *dentry,
29293 ++ const struct vfsmount *mnt, const char *dev_name)
29294 ++{
29295 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
29296 ++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
29297 ++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
29298 ++ return -EPERM;
29299 ++ }
29300 ++#endif
29301 ++ return 0;
29302 ++}
29303 ++
29304 ++int
29305 ++gr_handle_chroot_pivot(void)
29306 ++{
29307 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
29308 ++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
29309 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
29310 ++ return -EPERM;
29311 ++ }
29312 ++#endif
29313 ++ return 0;
29314 ++}
29315 ++
29316 ++int
29317 ++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
29318 ++{
29319 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
29320 ++ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
29321 ++ !gr_is_outside_chroot(dentry, mnt)) {
29322 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
29323 ++ return -EPERM;
29324 ++ }
29325 ++#endif
29326 ++ return 0;
29327 ++}
29328 ++
29329 ++void
29330 ++gr_handle_chroot_caps(struct task_struct *task)
29331 ++{
29332 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
29333 ++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
29334 ++ task->cap_permitted =
29335 ++ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
29336 ++ task->cap_inheritable =
29337 ++ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
29338 ++ task->cap_effective =
29339 ++ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
29340 ++ }
29341 ++#endif
29342 ++ return;
29343 ++}
29344 ++
29345 ++int
29346 ++gr_handle_chroot_sysctl(const int op)
29347 ++{
29348 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
29349 ++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
29350 ++ && (op & 002))
29351 ++ return -EACCES;
29352 ++#endif
29353 ++ return 0;
29354 ++}
29355 ++
29356 ++void
29357 ++gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
29358 ++{
29359 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
29360 ++ if (grsec_enable_chroot_chdir)
29361 ++ set_fs_pwd(current->fs, mnt, dentry);
29362 ++#endif
29363 ++ return;
29364 ++}
29365 ++
29366 ++int
29367 ++gr_handle_chroot_chmod(const struct dentry *dentry,
29368 ++ const struct vfsmount *mnt, const int mode)
29369 ++{
29370 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
29371 ++ if (grsec_enable_chroot_chmod &&
29372 ++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
29373 ++ proc_is_chrooted(current)) {
29374 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
29375 ++ return -EPERM;
29376 ++ }
29377 ++#endif
29378 ++ return 0;
29379 ++}
29380 ++
29381 ++#ifdef CONFIG_SECURITY
29382 ++EXPORT_SYMBOL(gr_handle_chroot_caps);
29383 ++#endif
29384 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_disabled.c linux-2.6.23.15-grsec/grsecurity/grsec_disabled.c
29385 +--- linux-2.6.23.15/grsecurity/grsec_disabled.c 1970-01-01 01:00:00.000000000 +0100
29386 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_disabled.c 2008-02-11 10:37:44.000000000 +0000
29387 +@@ -0,0 +1,418 @@
29388 ++#include <linux/kernel.h>
29389 ++#include <linux/module.h>
29390 ++#include <linux/sched.h>
29391 ++#include <linux/file.h>
29392 ++#include <linux/fs.h>
29393 ++#include <linux/kdev_t.h>
29394 ++#include <linux/net.h>
29395 ++#include <linux/in.h>
29396 ++#include <linux/ip.h>
29397 ++#include <linux/skbuff.h>
29398 ++#include <linux/sysctl.h>
29399 ++
29400 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
29401 ++void
29402 ++pax_set_initial_flags(struct linux_binprm *bprm)
29403 ++{
29404 ++ return;
29405 ++}
29406 ++#endif
29407 ++
29408 ++#ifdef CONFIG_SYSCTL
29409 ++__u32
29410 ++gr_handle_sysctl(const struct ctl_table * table, const int op)
29411 ++{
29412 ++ return 0;
29413 ++}
29414 ++#endif
29415 ++
29416 ++int
29417 ++gr_acl_is_enabled(void)
29418 ++{
29419 ++ return 0;
29420 ++}
29421 ++
29422 ++int
29423 ++gr_handle_rawio(const struct inode *inode)
29424 ++{
29425 ++ return 0;
29426 ++}
29427 ++
29428 ++void
29429 ++gr_acl_handle_psacct(struct task_struct *task, const long code)
29430 ++{
29431 ++ return;
29432 ++}
29433 ++
29434 ++int
29435 ++gr_handle_ptrace(struct task_struct *task, const long request)
29436 ++{
29437 ++ return 0;
29438 ++}
29439 ++
29440 ++int
29441 ++gr_handle_proc_ptrace(struct task_struct *task)
29442 ++{
29443 ++ return 0;
29444 ++}
29445 ++
29446 ++void
29447 ++gr_learn_resource(const struct task_struct *task,
29448 ++ const int res, const unsigned long wanted, const int gt)
29449 ++{
29450 ++ return;
29451 ++}
29452 ++
29453 ++int
29454 ++gr_set_acls(const int type)
29455 ++{
29456 ++ return 0;
29457 ++}
29458 ++
29459 ++int
29460 ++gr_check_hidden_task(const struct task_struct *tsk)
29461 ++{
29462 ++ return 0;
29463 ++}
29464 ++
29465 ++int
29466 ++gr_check_protected_task(const struct task_struct *task)
29467 ++{
29468 ++ return 0;
29469 ++}
29470 ++
29471 ++void
29472 ++gr_copy_label(struct task_struct *tsk)
29473 ++{
29474 ++ return;
29475 ++}
29476 ++
29477 ++void
29478 ++gr_set_pax_flags(struct task_struct *task)
29479 ++{
29480 ++ return;
29481 ++}
29482 ++
29483 ++int
29484 ++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
29485 ++{
29486 ++ return 0;
29487 ++}
29488 ++
29489 ++void
29490 ++gr_handle_delete(const ino_t ino, const dev_t dev)
29491 ++{
29492 ++ return;
29493 ++}
29494 ++
29495 ++void
29496 ++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
29497 ++{
29498 ++ return;
29499 ++}
29500 ++
29501 ++void
29502 ++gr_handle_crash(struct task_struct *task, const int sig)
29503 ++{
29504 ++ return;
29505 ++}
29506 ++
29507 ++int
29508 ++gr_check_crash_exec(const struct file *filp)
29509 ++{
29510 ++ return 0;
29511 ++}
29512 ++
29513 ++int
29514 ++gr_check_crash_uid(const uid_t uid)
29515 ++{
29516 ++ return 0;
29517 ++}
29518 ++
29519 ++void
29520 ++gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
29521 ++ struct dentry *old_dentry,
29522 ++ struct dentry *new_dentry,
29523 ++ struct vfsmount *mnt, const __u8 replace)
29524 ++{
29525 ++ return;
29526 ++}
29527 ++
29528 ++int
29529 ++gr_search_socket(const int family, const int type, const int protocol)
29530 ++{
29531 ++ return 1;
29532 ++}
29533 ++
29534 ++int
29535 ++gr_search_connectbind(const int mode, const struct socket *sock,
29536 ++ const struct sockaddr_in *addr)
29537 ++{
29538 ++ return 1;
29539 ++}
29540 ++
29541 ++int
29542 ++gr_task_is_capable(struct task_struct *task, const int cap)
29543 ++{
29544 ++ return 1;
29545 ++}
29546 ++
29547 ++int
29548 ++gr_is_capable_nolog(const int cap)
29549 ++{
29550 ++ return 1;
29551 ++}
29552 ++
29553 ++void
29554 ++gr_handle_alertkill(struct task_struct *task)
29555 ++{
29556 ++ return;
29557 ++}
29558 ++
29559 ++__u32
29560 ++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
29561 ++{
29562 ++ return 1;
29563 ++}
29564 ++
29565 ++__u32
29566 ++gr_acl_handle_hidden_file(const struct dentry * dentry,
29567 ++ const struct vfsmount * mnt)
29568 ++{
29569 ++ return 1;
29570 ++}
29571 ++
29572 ++__u32
29573 ++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
29574 ++ const int fmode)
29575 ++{
29576 ++ return 1;
29577 ++}
29578 ++
29579 ++__u32
29580 ++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
29581 ++{
29582 ++ return 1;
29583 ++}
29584 ++
29585 ++__u32
29586 ++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
29587 ++{
29588 ++ return 1;
29589 ++}
29590 ++
29591 ++int
29592 ++gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
29593 ++ unsigned int *vm_flags)
29594 ++{
29595 ++ return 1;
29596 ++}
29597 ++
29598 ++__u32
29599 ++gr_acl_handle_truncate(const struct dentry * dentry,
29600 ++ const struct vfsmount * mnt)
29601 ++{
29602 ++ return 1;
29603 ++}
29604 ++
29605 ++__u32
29606 ++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
29607 ++{
29608 ++ return 1;
29609 ++}
29610 ++
29611 ++__u32
29612 ++gr_acl_handle_access(const struct dentry * dentry,
29613 ++ const struct vfsmount * mnt, const int fmode)
29614 ++{
29615 ++ return 1;
29616 ++}
29617 ++
29618 ++__u32
29619 ++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
29620 ++ mode_t mode)
29621 ++{
29622 ++ return 1;
29623 ++}
29624 ++
29625 ++__u32
29626 ++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
29627 ++ mode_t mode)
29628 ++{
29629 ++ return 1;
29630 ++}
29631 ++
29632 ++__u32
29633 ++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
29634 ++{
29635 ++ return 1;
29636 ++}
29637 ++
29638 ++void
29639 ++grsecurity_init(void)
29640 ++{
29641 ++ return;
29642 ++}
29643 ++
29644 ++__u32
29645 ++gr_acl_handle_mknod(const struct dentry * new_dentry,
29646 ++ const struct dentry * parent_dentry,
29647 ++ const struct vfsmount * parent_mnt,
29648 ++ const int mode)
29649 ++{
29650 ++ return 1;
29651 ++}
29652 ++
29653 ++__u32
29654 ++gr_acl_handle_mkdir(const struct dentry * new_dentry,
29655 ++ const struct dentry * parent_dentry,
29656 ++ const struct vfsmount * parent_mnt)
29657 ++{
29658 ++ return 1;
29659 ++}
29660 ++
29661 ++__u32
29662 ++gr_acl_handle_symlink(const struct dentry * new_dentry,
29663 ++ const struct dentry * parent_dentry,
29664 ++ const struct vfsmount * parent_mnt, const char *from)
29665 ++{
29666 ++ return 1;
29667 ++}
29668 ++
29669 ++__u32
29670 ++gr_acl_handle_link(const struct dentry * new_dentry,
29671 ++ const struct dentry * parent_dentry,
29672 ++ const struct vfsmount * parent_mnt,
29673 ++ const struct dentry * old_dentry,
29674 ++ const struct vfsmount * old_mnt, const char *to)
29675 ++{
29676 ++ return 1;
29677 ++}
29678 ++
29679 ++int
29680 ++gr_acl_handle_rename(const struct dentry *new_dentry,
29681 ++ const struct dentry *parent_dentry,
29682 ++ const struct vfsmount *parent_mnt,
29683 ++ const struct dentry *old_dentry,
29684 ++ const struct inode *old_parent_inode,
29685 ++ const struct vfsmount *old_mnt, const char *newname)
29686 ++{
29687 ++ return 0;
29688 ++}
29689 ++
29690 ++int
29691 ++gr_acl_handle_filldir(const struct file *file, const char *name,
29692 ++ const int namelen, const ino_t ino)
29693 ++{
29694 ++ return 1;
29695 ++}
29696 ++
29697 ++int
29698 ++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
29699 ++ const time_t shm_createtime, const uid_t cuid, const int shmid)
29700 ++{
29701 ++ return 1;
29702 ++}
29703 ++
29704 ++int
29705 ++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
29706 ++{
29707 ++ return 1;
29708 ++}
29709 ++
29710 ++int
29711 ++gr_search_accept(const struct socket *sock)
29712 ++{
29713 ++ return 1;
29714 ++}
29715 ++
29716 ++int
29717 ++gr_search_listen(const struct socket *sock)
29718 ++{
29719 ++ return 1;
29720 ++}
29721 ++
29722 ++int
29723 ++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
29724 ++{
29725 ++ return 1;
29726 ++}
29727 ++
29728 ++__u32
29729 ++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
29730 ++{
29731 ++ return 1;
29732 ++}
29733 ++
29734 ++__u32
29735 ++gr_acl_handle_creat(const struct dentry * dentry,
29736 ++ const struct dentry * p_dentry,
29737 ++ const struct vfsmount * p_mnt, const int fmode,
29738 ++ const int imode)
29739 ++{
29740 ++ return 1;
29741 ++}
29742 ++
29743 ++void
29744 ++gr_acl_handle_exit(void)
29745 ++{
29746 ++ return;
29747 ++}
29748 ++
29749 ++int
29750 ++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
29751 ++{
29752 ++ return 1;
29753 ++}
29754 ++
29755 ++void
29756 ++gr_set_role_label(const uid_t uid, const gid_t gid)
29757 ++{
29758 ++ return;
29759 ++}
29760 ++
29761 ++int
29762 ++gr_acl_handle_procpidmem(const struct task_struct *task)
29763 ++{
29764 ++ return 0;
29765 ++}
29766 ++
29767 ++int
29768 ++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
29769 ++{
29770 ++ return 1;
29771 ++}
29772 ++
29773 ++int
29774 ++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
29775 ++{
29776 ++ return 1;
29777 ++}
29778 ++
29779 ++void
29780 ++gr_set_kernel_label(struct task_struct *task)
29781 ++{
29782 ++ return;
29783 ++}
29784 ++
29785 ++int
29786 ++gr_check_user_change(int real, int effective, int fs)
29787 ++{
29788 ++ return 0;
29789 ++}
29790 ++
29791 ++int
29792 ++gr_check_group_change(int real, int effective, int fs)
29793 ++{
29794 ++ return 0;
29795 ++}
29796 ++
29797 ++
29798 ++EXPORT_SYMBOL(gr_task_is_capable);
29799 ++EXPORT_SYMBOL(gr_is_capable_nolog);
29800 ++EXPORT_SYMBOL(gr_learn_resource);
29801 ++EXPORT_SYMBOL(gr_set_kernel_label);
29802 ++#ifdef CONFIG_SECURITY
29803 ++EXPORT_SYMBOL(gr_check_user_change);
29804 ++EXPORT_SYMBOL(gr_check_group_change);
29805 ++#endif
29806 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_exec.c linux-2.6.23.15-grsec/grsecurity/grsec_exec.c
29807 +--- linux-2.6.23.15/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100
29808 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_exec.c 2008-02-11 10:37:44.000000000 +0000
29809 +@@ -0,0 +1,88 @@
29810 ++#include <linux/kernel.h>
29811 ++#include <linux/sched.h>
29812 ++#include <linux/file.h>
29813 ++#include <linux/binfmts.h>
29814 ++#include <linux/smp_lock.h>
29815 ++#include <linux/fs.h>
29816 ++#include <linux/types.h>
29817 ++#include <linux/grdefs.h>
29818 ++#include <linux/grinternal.h>
29819 ++#include <linux/capability.h>
29820 ++
29821 ++#include <asm/uaccess.h>
29822 ++
29823 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
29824 ++static char gr_exec_arg_buf[132];
29825 ++static DECLARE_MUTEX(gr_exec_arg_sem);
29826 ++#endif
29827 ++
29828 ++int
29829 ++gr_handle_nproc(void)
29830 ++{
29831 ++#ifdef CONFIG_GRKERNSEC_EXECVE
29832 ++ if (grsec_enable_execve && current->user &&
29833 ++ (atomic_read(&current->user->processes) >
29834 ++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
29835 ++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
29836 ++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
29837 ++ return -EAGAIN;
29838 ++ }
29839 ++#endif
29840 ++ return 0;
29841 ++}
29842 ++
29843 ++void
29844 ++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
29845 ++{
29846 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
29847 ++ char *grarg = gr_exec_arg_buf;
29848 ++ unsigned int i, x, execlen = 0;
29849 ++ char c;
29850 ++
29851 ++ if (!((grsec_enable_execlog && grsec_enable_group &&
29852 ++ in_group_p(grsec_audit_gid))
29853 ++ || (grsec_enable_execlog && !grsec_enable_group)))
29854 ++ return;
29855 ++
29856 ++ down(&gr_exec_arg_sem);
29857 ++ memset(grarg, 0, sizeof(gr_exec_arg_buf));
29858 ++
29859 ++ if (unlikely(argv == NULL))
29860 ++ goto log;
29861 ++
29862 ++ for (i = 0; i < bprm->argc && execlen < 128; i++) {
29863 ++ const char __user *p;
29864 ++ unsigned int len;
29865 ++
29866 ++ if (copy_from_user(&p, argv + i, sizeof(p)))
29867 ++ goto log;
29868 ++ if (!p)
29869 ++ goto log;
29870 ++ len = strnlen_user(p, 128 - execlen);
29871 ++ if (len > 128 - execlen)
29872 ++ len = 128 - execlen;
29873 ++ else if (len > 0)
29874 ++ len--;
29875 ++ if (copy_from_user(grarg + execlen, p, len))
29876 ++ goto log;
29877 ++
29878 ++ /* rewrite unprintable characters */
29879 ++ for (x = 0; x < len; x++) {
29880 ++ c = *(grarg + execlen + x);
29881 ++ if (c < 32 || c > 126)
29882 ++ *(grarg + execlen + x) = ' ';
29883 ++ }
29884 ++
29885 ++ execlen += len;
29886 ++ *(grarg + execlen) = ' ';
29887 ++ *(grarg + execlen + 1) = '\0';
29888 ++ execlen++;
29889 ++ }
29890 ++
29891 ++ log:
29892 ++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
29893 ++ bprm->file->f_vfsmnt, grarg);
29894 ++ up(&gr_exec_arg_sem);
29895 ++#endif
29896 ++ return;
29897 ++}
29898 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_fifo.c linux-2.6.23.15-grsec/grsecurity/grsec_fifo.c
29899 +--- linux-2.6.23.15/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100
29900 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_fifo.c 2008-02-11 10:37:44.000000000 +0000
29901 +@@ -0,0 +1,22 @@
29902 ++#include <linux/kernel.h>
29903 ++#include <linux/sched.h>
29904 ++#include <linux/fs.h>
29905 ++#include <linux/file.h>
29906 ++#include <linux/grinternal.h>
29907 ++
29908 ++int
29909 ++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
29910 ++ const struct dentry *dir, const int flag, const int acc_mode)
29911 ++{
29912 ++#ifdef CONFIG_GRKERNSEC_FIFO
29913 ++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
29914 ++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
29915 ++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
29916 ++ (current->fsuid != dentry->d_inode->i_uid)) {
29917 ++ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
29918 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
29919 ++ return -EACCES;
29920 ++ }
29921 ++#endif
29922 ++ return 0;
29923 ++}
29924 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_fork.c linux-2.6.23.15-grsec/grsecurity/grsec_fork.c
29925 +--- linux-2.6.23.15/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100
29926 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_fork.c 2008-02-11 10:37:44.000000000 +0000
29927 +@@ -0,0 +1,15 @@
29928 ++#include <linux/kernel.h>
29929 ++#include <linux/sched.h>
29930 ++#include <linux/grsecurity.h>
29931 ++#include <linux/grinternal.h>
29932 ++#include <linux/errno.h>
29933 ++
29934 ++void
29935 ++gr_log_forkfail(const int retval)
29936 ++{
29937 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
29938 ++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
29939 ++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
29940 ++#endif
29941 ++ return;
29942 ++}
29943 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_init.c linux-2.6.23.15-grsec/grsecurity/grsec_init.c
29944 +--- linux-2.6.23.15/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100
29945 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_init.c 2008-02-11 10:37:44.000000000 +0000
29946 +@@ -0,0 +1,230 @@
29947 ++#include <linux/kernel.h>
29948 ++#include <linux/sched.h>
29949 ++#include <linux/mm.h>
29950 ++#include <linux/smp_lock.h>
29951 ++#include <linux/gracl.h>
29952 ++#include <linux/slab.h>
29953 ++#include <linux/vmalloc.h>
29954 ++#include <linux/percpu.h>
29955 ++
29956 ++int grsec_enable_shm;
29957 ++int grsec_enable_link;
29958 ++int grsec_enable_dmesg;
29959 ++int grsec_enable_fifo;
29960 ++int grsec_enable_execve;
29961 ++int grsec_enable_execlog;
29962 ++int grsec_enable_signal;
29963 ++int grsec_enable_forkfail;
29964 ++int grsec_enable_time;
29965 ++int grsec_enable_audit_textrel;
29966 ++int grsec_enable_group;
29967 ++int grsec_audit_gid;
29968 ++int grsec_enable_chdir;
29969 ++int grsec_enable_audit_ipc;
29970 ++int grsec_enable_mount;
29971 ++int grsec_enable_chroot_findtask;
29972 ++int grsec_enable_chroot_mount;
29973 ++int grsec_enable_chroot_shmat;
29974 ++int grsec_enable_chroot_fchdir;
29975 ++int grsec_enable_chroot_double;
29976 ++int grsec_enable_chroot_pivot;
29977 ++int grsec_enable_chroot_chdir;
29978 ++int grsec_enable_chroot_chmod;
29979 ++int grsec_enable_chroot_mknod;
29980 ++int grsec_enable_chroot_nice;
29981 ++int grsec_enable_chroot_execlog;
29982 ++int grsec_enable_chroot_caps;
29983 ++int grsec_enable_chroot_sysctl;
29984 ++int grsec_enable_chroot_unix;
29985 ++int grsec_enable_tpe;
29986 ++int grsec_tpe_gid;
29987 ++int grsec_enable_tpe_all;
29988 ++int grsec_enable_socket_all;
29989 ++int grsec_socket_all_gid;
29990 ++int grsec_enable_socket_client;
29991 ++int grsec_socket_client_gid;
29992 ++int grsec_enable_socket_server;
29993 ++int grsec_socket_server_gid;
29994 ++int grsec_resource_logging;
29995 ++int grsec_lock;
29996 ++
29997 ++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
29998 ++unsigned long grsec_alert_wtime = 0;
29999 ++unsigned long grsec_alert_fyet = 0;
30000 ++
30001 ++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
30002 ++
30003 ++rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
30004 ++
30005 ++char *gr_shared_page[4];
30006 ++
30007 ++char *gr_alert_log_fmt;
30008 ++char *gr_audit_log_fmt;
30009 ++char *gr_alert_log_buf;
30010 ++char *gr_audit_log_buf;
30011 ++
30012 ++extern struct gr_arg *gr_usermode;
30013 ++extern unsigned char *gr_system_salt;
30014 ++extern unsigned char *gr_system_sum;
30015 ++
30016 ++void
30017 ++grsecurity_init(void)
30018 ++{
30019 ++ int j;
30020 ++ /* create the per-cpu shared pages */
30021 ++
30022 ++ for (j = 0; j < 4; j++) {
30023 ++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
30024 ++ if (gr_shared_page[j] == NULL) {
30025 ++ panic("Unable to allocate grsecurity shared page");
30026 ++ return;
30027 ++ }
30028 ++ }
30029 ++
30030 ++ /* allocate log buffers */
30031 ++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
30032 ++ if (!gr_alert_log_fmt) {
30033 ++ panic("Unable to allocate grsecurity alert log format buffer");
30034 ++ return;
30035 ++ }
30036 ++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
30037 ++ if (!gr_audit_log_fmt) {
30038 ++ panic("Unable to allocate grsecurity audit log format buffer");
30039 ++ return;
30040 ++ }
30041 ++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
30042 ++ if (!gr_alert_log_buf) {
30043 ++ panic("Unable to allocate grsecurity alert log buffer");
30044 ++ return;
30045 ++ }
30046 ++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
30047 ++ if (!gr_audit_log_buf) {
30048 ++ panic("Unable to allocate grsecurity audit log buffer");
30049 ++ return;
30050 ++ }
30051 ++
30052 ++ /* allocate memory for authentication structure */
30053 ++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
30054 ++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
30055 ++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
30056 ++
30057 ++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
30058 ++ panic("Unable to allocate grsecurity authentication structure");
30059 ++ return;
30060 ++ }
30061 ++
30062 ++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
30063 ++#ifndef CONFIG_GRKERNSEC_SYSCTL
30064 ++ grsec_lock = 1;
30065 ++#endif
30066 ++#ifdef CONFIG_GRKERNSEC_SHM
30067 ++ grsec_enable_shm = 1;
30068 ++#endif
30069 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
30070 ++ grsec_enable_audit_textrel = 1;
30071 ++#endif
30072 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
30073 ++ grsec_enable_group = 1;
30074 ++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
30075 ++#endif
30076 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
30077 ++ grsec_enable_chdir = 1;
30078 ++#endif
30079 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30080 ++ grsec_enable_audit_ipc = 1;
30081 ++#endif
30082 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30083 ++ grsec_enable_mount = 1;
30084 ++#endif
30085 ++#ifdef CONFIG_GRKERNSEC_LINK
30086 ++ grsec_enable_link = 1;
30087 ++#endif
30088 ++#ifdef CONFIG_GRKERNSEC_DMESG
30089 ++ grsec_enable_dmesg = 1;
30090 ++#endif
30091 ++#ifdef CONFIG_GRKERNSEC_FIFO
30092 ++ grsec_enable_fifo = 1;
30093 ++#endif
30094 ++#ifdef CONFIG_GRKERNSEC_EXECVE
30095 ++ grsec_enable_execve = 1;
30096 ++#endif
30097 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
30098 ++ grsec_enable_execlog = 1;
30099 ++#endif
30100 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
30101 ++ grsec_enable_signal = 1;
30102 ++#endif
30103 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
30104 ++ grsec_enable_forkfail = 1;
30105 ++#endif
30106 ++#ifdef CONFIG_GRKERNSEC_TIME
30107 ++ grsec_enable_time = 1;
30108 ++#endif
30109 ++#ifdef CONFIG_GRKERNSEC_RESLOG
30110 ++ grsec_resource_logging = 1;
30111 ++#endif
30112 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
30113 ++ grsec_enable_chroot_findtask = 1;
30114 ++#endif
30115 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
30116 ++ grsec_enable_chroot_unix = 1;
30117 ++#endif
30118 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
30119 ++ grsec_enable_chroot_mount = 1;
30120 ++#endif
30121 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
30122 ++ grsec_enable_chroot_fchdir = 1;
30123 ++#endif
30124 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
30125 ++ grsec_enable_chroot_shmat = 1;
30126 ++#endif
30127 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
30128 ++ grsec_enable_chroot_double = 1;
30129 ++#endif
30130 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
30131 ++ grsec_enable_chroot_pivot = 1;
30132 ++#endif
30133 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
30134 ++ grsec_enable_chroot_chdir = 1;
30135 ++#endif
30136 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
30137 ++ grsec_enable_chroot_chmod = 1;
30138 ++#endif
30139 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
30140 ++ grsec_enable_chroot_mknod = 1;
30141 ++#endif
30142 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
30143 ++ grsec_enable_chroot_nice = 1;
30144 ++#endif
30145 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
30146 ++ grsec_enable_chroot_execlog = 1;
30147 ++#endif
30148 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
30149 ++ grsec_enable_chroot_caps = 1;
30150 ++#endif
30151 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
30152 ++ grsec_enable_chroot_sysctl = 1;
30153 ++#endif
30154 ++#ifdef CONFIG_GRKERNSEC_TPE
30155 ++ grsec_enable_tpe = 1;
30156 ++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
30157 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
30158 ++ grsec_enable_tpe_all = 1;
30159 ++#endif
30160 ++#endif
30161 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
30162 ++ grsec_enable_socket_all = 1;
30163 ++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
30164 ++#endif
30165 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
30166 ++ grsec_enable_socket_client = 1;
30167 ++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
30168 ++#endif
30169 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30170 ++ grsec_enable_socket_server = 1;
30171 ++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
30172 ++#endif
30173 ++#endif
30174 ++
30175 ++ return;
30176 ++}
30177 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_ipc.c linux-2.6.23.15-grsec/grsecurity/grsec_ipc.c
30178 +--- linux-2.6.23.15/grsecurity/grsec_ipc.c 1970-01-01 01:00:00.000000000 +0100
30179 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_ipc.c 2008-02-11 10:37:44.000000000 +0000
30180 +@@ -0,0 +1,81 @@
30181 ++#include <linux/kernel.h>
30182 ++#include <linux/sched.h>
30183 ++#include <linux/types.h>
30184 ++#include <linux/ipc.h>
30185 ++#include <linux/grsecurity.h>
30186 ++#include <linux/grinternal.h>
30187 ++
30188 ++void
30189 ++gr_log_msgget(const int ret, const int msgflg)
30190 ++{
30191 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30192 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30193 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30194 ++ !grsec_enable_group)) && (ret >= 0)
30195 ++ && (msgflg & IPC_CREAT))
30196 ++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
30197 ++#endif
30198 ++ return;
30199 ++}
30200 ++
30201 ++void
30202 ++gr_log_msgrm(const uid_t uid, const uid_t cuid)
30203 ++{
30204 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30205 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30206 ++ grsec_enable_audit_ipc) ||
30207 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30208 ++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
30209 ++#endif
30210 ++ return;
30211 ++}
30212 ++
30213 ++void
30214 ++gr_log_semget(const int err, const int semflg)
30215 ++{
30216 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30217 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30218 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30219 ++ !grsec_enable_group)) && (err >= 0)
30220 ++ && (semflg & IPC_CREAT))
30221 ++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
30222 ++#endif
30223 ++ return;
30224 ++}
30225 ++
30226 ++void
30227 ++gr_log_semrm(const uid_t uid, const uid_t cuid)
30228 ++{
30229 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30230 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30231 ++ grsec_enable_audit_ipc) ||
30232 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30233 ++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
30234 ++#endif
30235 ++ return;
30236 ++}
30237 ++
30238 ++void
30239 ++gr_log_shmget(const int err, const int shmflg, const size_t size)
30240 ++{
30241 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30242 ++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30243 ++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
30244 ++ !grsec_enable_group)) && (err >= 0)
30245 ++ && (shmflg & IPC_CREAT))
30246 ++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
30247 ++#endif
30248 ++ return;
30249 ++}
30250 ++
30251 ++void
30252 ++gr_log_shmrm(const uid_t uid, const uid_t cuid)
30253 ++{
30254 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
30255 ++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
30256 ++ grsec_enable_audit_ipc) ||
30257 ++ (grsec_enable_audit_ipc && !grsec_enable_group))
30258 ++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
30259 ++#endif
30260 ++ return;
30261 ++}
30262 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_link.c linux-2.6.23.15-grsec/grsecurity/grsec_link.c
30263 +--- linux-2.6.23.15/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100
30264 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_link.c 2008-02-11 10:37:44.000000000 +0000
30265 +@@ -0,0 +1,39 @@
30266 ++#include <linux/kernel.h>
30267 ++#include <linux/sched.h>
30268 ++#include <linux/fs.h>
30269 ++#include <linux/file.h>
30270 ++#include <linux/grinternal.h>
30271 ++
30272 ++int
30273 ++gr_handle_follow_link(const struct inode *parent,
30274 ++ const struct inode *inode,
30275 ++ const struct dentry *dentry, const struct vfsmount *mnt)
30276 ++{
30277 ++#ifdef CONFIG_GRKERNSEC_LINK
30278 ++ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
30279 ++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
30280 ++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
30281 ++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
30282 ++ return -EACCES;
30283 ++ }
30284 ++#endif
30285 ++ return 0;
30286 ++}
30287 ++
30288 ++int
30289 ++gr_handle_hardlink(const struct dentry *dentry,
30290 ++ const struct vfsmount *mnt,
30291 ++ struct inode *inode, const int mode, const char *to)
30292 ++{
30293 ++#ifdef CONFIG_GRKERNSEC_LINK
30294 ++ if (grsec_enable_link && current->fsuid != inode->i_uid &&
30295 ++ (!S_ISREG(mode) || (mode & S_ISUID) ||
30296 ++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
30297 ++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
30298 ++ !capable(CAP_FOWNER) && current->uid) {
30299 ++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
30300 ++ return -EPERM;
30301 ++ }
30302 ++#endif
30303 ++ return 0;
30304 ++}
30305 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_log.c linux-2.6.23.15-grsec/grsecurity/grsec_log.c
30306 +--- linux-2.6.23.15/grsecurity/grsec_log.c 1970-01-01 01:00:00.000000000 +0100
30307 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_log.c 2008-02-11 10:37:44.000000000 +0000
30308 +@@ -0,0 +1,269 @@
30309 ++#include <linux/kernel.h>
30310 ++#include <linux/sched.h>
30311 ++#include <linux/file.h>
30312 ++#include <linux/tty.h>
30313 ++#include <linux/fs.h>
30314 ++#include <linux/grinternal.h>
30315 ++
30316 ++#define BEGIN_LOCKS(x) \
30317 ++ read_lock(&tasklist_lock); \
30318 ++ read_lock(&grsec_exec_file_lock); \
30319 ++ if (x != GR_DO_AUDIT) \
30320 ++ spin_lock(&grsec_alert_lock); \
30321 ++ else \
30322 ++ spin_lock(&grsec_audit_lock)
30323 ++
30324 ++#define END_LOCKS(x) \
30325 ++ if (x != GR_DO_AUDIT) \
30326 ++ spin_unlock(&grsec_alert_lock); \
30327 ++ else \
30328 ++ spin_unlock(&grsec_audit_lock); \
30329 ++ read_unlock(&grsec_exec_file_lock); \
30330 ++ read_unlock(&tasklist_lock); \
30331 ++ if (x == GR_DONT_AUDIT) \
30332 ++ gr_handle_alertkill(current)
30333 ++
30334 ++enum {
30335 ++ FLOODING,
30336 ++ NO_FLOODING
30337 ++};
30338 ++
30339 ++extern char *gr_alert_log_fmt;
30340 ++extern char *gr_audit_log_fmt;
30341 ++extern char *gr_alert_log_buf;
30342 ++extern char *gr_audit_log_buf;
30343 ++
30344 ++static int gr_log_start(int audit)
30345 ++{
30346 ++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
30347 ++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
30348 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30349 ++
30350 ++ if (audit == GR_DO_AUDIT)
30351 ++ goto set_fmt;
30352 ++
30353 ++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
30354 ++ grsec_alert_wtime = jiffies;
30355 ++ grsec_alert_fyet = 0;
30356 ++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
30357 ++ grsec_alert_fyet++;
30358 ++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
30359 ++ grsec_alert_wtime = jiffies;
30360 ++ grsec_alert_fyet++;
30361 ++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
30362 ++ return FLOODING;
30363 ++ } else return FLOODING;
30364 ++
30365 ++set_fmt:
30366 ++ memset(buf, 0, PAGE_SIZE);
30367 ++ if (current->signal->curr_ip && gr_acl_is_enabled()) {
30368 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
30369 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
30370 ++ } else if (current->signal->curr_ip) {
30371 ++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
30372 ++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
30373 ++ } else if (gr_acl_is_enabled()) {
30374 ++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
30375 ++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
30376 ++ } else {
30377 ++ sprintf(fmt, "%s%s", loglevel, "grsec: ");
30378 ++ strcpy(buf, fmt);
30379 ++ }
30380 ++
30381 ++ return NO_FLOODING;
30382 ++}
30383 ++
30384 ++static void gr_log_middle(int audit, const char *msg, va_list ap)
30385 ++{
30386 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30387 ++ unsigned int len = strlen(buf);
30388 ++
30389 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
30390 ++
30391 ++ return;
30392 ++}
30393 ++
30394 ++static void gr_log_middle_varargs(int audit, const char *msg, ...)
30395 ++{
30396 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30397 ++ unsigned int len = strlen(buf);
30398 ++ va_list ap;
30399 ++
30400 ++ va_start(ap, msg);
30401 ++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
30402 ++ va_end(ap);
30403 ++
30404 ++ return;
30405 ++}
30406 ++
30407 ++static void gr_log_end(int audit)
30408 ++{
30409 ++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
30410 ++ unsigned int len = strlen(buf);
30411 ++
30412 ++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
30413 ++ printk("%s\n", buf);
30414 ++
30415 ++ return;
30416 ++}
30417 ++
30418 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
30419 ++{
30420 ++ int logtype;
30421 ++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
30422 ++ char *str1, *str2, *str3;
30423 ++ int num1, num2;
30424 ++ unsigned long ulong1, ulong2;
30425 ++ struct dentry *dentry;
30426 ++ struct vfsmount *mnt;
30427 ++ struct file *file;
30428 ++ struct task_struct *task;
30429 ++ va_list ap;
30430 ++
30431 ++ BEGIN_LOCKS(audit);
30432 ++ logtype = gr_log_start(audit);
30433 ++ if (logtype == FLOODING) {
30434 ++ END_LOCKS(audit);
30435 ++ return;
30436 ++ }
30437 ++ va_start(ap, argtypes);
30438 ++ switch (argtypes) {
30439 ++ case GR_TTYSNIFF:
30440 ++ task = va_arg(ap, struct task_struct *);
30441 ++ 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);
30442 ++ break;
30443 ++ case GR_SYSCTL_HIDDEN:
30444 ++ str1 = va_arg(ap, char *);
30445 ++ gr_log_middle_varargs(audit, msg, result, str1);
30446 ++ break;
30447 ++ case GR_RBAC:
30448 ++ dentry = va_arg(ap, struct dentry *);
30449 ++ mnt = va_arg(ap, struct vfsmount *);
30450 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
30451 ++ break;
30452 ++ case GR_RBAC_STR:
30453 ++ dentry = va_arg(ap, struct dentry *);
30454 ++ mnt = va_arg(ap, struct vfsmount *);
30455 ++ str1 = va_arg(ap, char *);
30456 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
30457 ++ break;
30458 ++ case GR_STR_RBAC:
30459 ++ str1 = va_arg(ap, char *);
30460 ++ dentry = va_arg(ap, struct dentry *);
30461 ++ mnt = va_arg(ap, struct vfsmount *);
30462 ++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
30463 ++ break;
30464 ++ case GR_RBAC_MODE2:
30465 ++ dentry = va_arg(ap, struct dentry *);
30466 ++ mnt = va_arg(ap, struct vfsmount *);
30467 ++ str1 = va_arg(ap, char *);
30468 ++ str2 = va_arg(ap, char *);
30469 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
30470 ++ break;
30471 ++ case GR_RBAC_MODE3:
30472 ++ dentry = va_arg(ap, struct dentry *);
30473 ++ mnt = va_arg(ap, struct vfsmount *);
30474 ++ str1 = va_arg(ap, char *);
30475 ++ str2 = va_arg(ap, char *);
30476 ++ str3 = va_arg(ap, char *);
30477 ++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
30478 ++ break;
30479 ++ case GR_FILENAME:
30480 ++ dentry = va_arg(ap, struct dentry *);
30481 ++ mnt = va_arg(ap, struct vfsmount *);
30482 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
30483 ++ break;
30484 ++ case GR_STR_FILENAME:
30485 ++ str1 = va_arg(ap, char *);
30486 ++ dentry = va_arg(ap, struct dentry *);
30487 ++ mnt = va_arg(ap, struct vfsmount *);
30488 ++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
30489 ++ break;
30490 ++ case GR_FILENAME_STR:
30491 ++ dentry = va_arg(ap, struct dentry *);
30492 ++ mnt = va_arg(ap, struct vfsmount *);
30493 ++ str1 = va_arg(ap, char *);
30494 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
30495 ++ break;
30496 ++ case GR_FILENAME_TWO_INT:
30497 ++ dentry = va_arg(ap, struct dentry *);
30498 ++ mnt = va_arg(ap, struct vfsmount *);
30499 ++ num1 = va_arg(ap, int);
30500 ++ num2 = va_arg(ap, int);
30501 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
30502 ++ break;
30503 ++ case GR_FILENAME_TWO_INT_STR:
30504 ++ dentry = va_arg(ap, struct dentry *);
30505 ++ mnt = va_arg(ap, struct vfsmount *);
30506 ++ num1 = va_arg(ap, int);
30507 ++ num2 = va_arg(ap, int);
30508 ++ str1 = va_arg(ap, char *);
30509 ++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
30510 ++ break;
30511 ++ case GR_TEXTREL:
30512 ++ file = va_arg(ap, struct file *);
30513 ++ ulong1 = va_arg(ap, unsigned long);
30514 ++ ulong2 = va_arg(ap, unsigned long);
30515 ++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
30516 ++ break;
30517 ++ case GR_PTRACE:
30518 ++ task = va_arg(ap, struct task_struct *);
30519 ++ gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
30520 ++ break;
30521 ++ case GR_RESOURCE:
30522 ++ task = va_arg(ap, struct task_struct *);
30523 ++ ulong1 = va_arg(ap, unsigned long);
30524 ++ str1 = va_arg(ap, char *);
30525 ++ ulong2 = va_arg(ap, unsigned long);
30526 ++ 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);
30527 ++ break;
30528 ++ case GR_CAP:
30529 ++ task = va_arg(ap, struct task_struct *);
30530 ++ str1 = va_arg(ap, char *);
30531 ++ 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);
30532 ++ break;
30533 ++ case GR_SIG:
30534 ++ task = va_arg(ap, struct task_struct *);
30535 ++ num1 = va_arg(ap, int);
30536 ++ 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);
30537 ++ break;
30538 ++ case GR_CRASH1:
30539 ++ task = va_arg(ap, struct task_struct *);
30540 ++ ulong1 = va_arg(ap, unsigned long);
30541 ++ 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);
30542 ++ break;
30543 ++ case GR_CRASH2:
30544 ++ task = va_arg(ap, struct task_struct *);
30545 ++ ulong1 = va_arg(ap, unsigned long);
30546 ++ 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);
30547 ++ break;
30548 ++ case GR_PSACCT:
30549 ++ {
30550 ++ unsigned int wday, cday;
30551 ++ __u8 whr, chr;
30552 ++ __u8 wmin, cmin;
30553 ++ __u8 wsec, csec;
30554 ++ char cur_tty[64] = { 0 };
30555 ++ char parent_tty[64] = { 0 };
30556 ++
30557 ++ task = va_arg(ap, struct task_struct *);
30558 ++ wday = va_arg(ap, unsigned int);
30559 ++ cday = va_arg(ap, unsigned int);
30560 ++ whr = va_arg(ap, int);
30561 ++ chr = va_arg(ap, int);
30562 ++ wmin = va_arg(ap, int);
30563 ++ cmin = va_arg(ap, int);
30564 ++ wsec = va_arg(ap, int);
30565 ++ csec = va_arg(ap, int);
30566 ++ ulong1 = va_arg(ap, unsigned long);
30567 ++
30568 ++ 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);
30569 ++ }
30570 ++ break;
30571 ++ default:
30572 ++ gr_log_middle(audit, msg, ap);
30573 ++ }
30574 ++ va_end(ap);
30575 ++ gr_log_end(audit);
30576 ++ END_LOCKS(audit);
30577 ++}
30578 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_mem.c linux-2.6.23.15-grsec/grsecurity/grsec_mem.c
30579 +--- linux-2.6.23.15/grsecurity/grsec_mem.c 1970-01-01 01:00:00.000000000 +0100
30580 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_mem.c 2008-02-11 10:37:44.000000000 +0000
30581 +@@ -0,0 +1,71 @@
30582 ++#include <linux/kernel.h>
30583 ++#include <linux/sched.h>
30584 ++#include <linux/mm.h>
30585 ++#include <linux/mman.h>
30586 ++#include <linux/grinternal.h>
30587 ++
30588 ++void
30589 ++gr_handle_ioperm(void)
30590 ++{
30591 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
30592 ++ return;
30593 ++}
30594 ++
30595 ++void
30596 ++gr_handle_iopl(void)
30597 ++{
30598 ++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
30599 ++ return;
30600 ++}
30601 ++
30602 ++void
30603 ++gr_handle_mem_write(void)
30604 ++{
30605 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
30606 ++ return;
30607 ++}
30608 ++
30609 ++void
30610 ++gr_handle_kmem_write(void)
30611 ++{
30612 ++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
30613 ++ return;
30614 ++}
30615 ++
30616 ++void
30617 ++gr_handle_open_port(void)
30618 ++{
30619 ++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
30620 ++ return;
30621 ++}
30622 ++
30623 ++int
30624 ++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
30625 ++{
30626 ++ unsigned long start, end;
30627 ++
30628 ++ start = offset;
30629 ++ end = start + vma->vm_end - vma->vm_start;
30630 ++
30631 ++ if (start > end) {
30632 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
30633 ++ return -EPERM;
30634 ++ }
30635 ++
30636 ++ /* allowed ranges : ISA I/O BIOS */
30637 ++ if ((start >= __pa(high_memory))
30638 ++#ifdef CONFIG_X86
30639 ++ || (start >= 0x000a0000 && end <= 0x00100000)
30640 ++ || (start >= 0x00000000 && end <= 0x00001000)
30641 ++#endif
30642 ++ )
30643 ++ return 0;
30644 ++
30645 ++ if (vma->vm_flags & VM_WRITE) {
30646 ++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
30647 ++ return -EPERM;
30648 ++ } else
30649 ++ vma->vm_flags &= ~VM_MAYWRITE;
30650 ++
30651 ++ return 0;
30652 ++}
30653 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_mount.c linux-2.6.23.15-grsec/grsecurity/grsec_mount.c
30654 +--- linux-2.6.23.15/grsecurity/grsec_mount.c 1970-01-01 01:00:00.000000000 +0100
30655 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_mount.c 2008-02-11 10:37:44.000000000 +0000
30656 +@@ -0,0 +1,34 @@
30657 ++#include <linux/kernel.h>
30658 ++#include <linux/sched.h>
30659 ++#include <linux/grsecurity.h>
30660 ++#include <linux/grinternal.h>
30661 ++
30662 ++void
30663 ++gr_log_remount(const char *devname, const int retval)
30664 ++{
30665 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30666 ++ if (grsec_enable_mount && (retval >= 0))
30667 ++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
30668 ++#endif
30669 ++ return;
30670 ++}
30671 ++
30672 ++void
30673 ++gr_log_unmount(const char *devname, const int retval)
30674 ++{
30675 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30676 ++ if (grsec_enable_mount && (retval >= 0))
30677 ++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
30678 ++#endif
30679 ++ return;
30680 ++}
30681 ++
30682 ++void
30683 ++gr_log_mount(const char *from, const char *to, const int retval)
30684 ++{
30685 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
30686 ++ if (grsec_enable_mount && (retval >= 0))
30687 ++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
30688 ++#endif
30689 ++ return;
30690 ++}
30691 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_sig.c linux-2.6.23.15-grsec/grsecurity/grsec_sig.c
30692 +--- linux-2.6.23.15/grsecurity/grsec_sig.c 1970-01-01 01:00:00.000000000 +0100
30693 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_sig.c 2008-02-11 10:37:44.000000000 +0000
30694 +@@ -0,0 +1,59 @@
30695 ++#include <linux/kernel.h>
30696 ++#include <linux/sched.h>
30697 ++#include <linux/grsecurity.h>
30698 ++#include <linux/grinternal.h>
30699 ++
30700 ++void
30701 ++gr_log_signal(const int sig, const struct task_struct *t)
30702 ++{
30703 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
30704 ++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
30705 ++ (sig == SIGABRT) || (sig == SIGBUS))) {
30706 ++ if (t->pid == current->pid) {
30707 ++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
30708 ++ } else {
30709 ++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
30710 ++ }
30711 ++ }
30712 ++#endif
30713 ++ return;
30714 ++}
30715 ++
30716 ++int
30717 ++gr_handle_signal(const struct task_struct *p, const int sig)
30718 ++{
30719 ++#ifdef CONFIG_GRKERNSEC
30720 ++ if (current->pid > 1 && gr_check_protected_task(p)) {
30721 ++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
30722 ++ return -EPERM;
30723 ++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
30724 ++ return -EPERM;
30725 ++ }
30726 ++#endif
30727 ++ return 0;
30728 ++}
30729 ++
30730 ++void gr_handle_brute_attach(struct task_struct *p)
30731 ++{
30732 ++#ifdef CONFIG_GRKERNSEC_BRUTE
30733 ++ read_lock(&tasklist_lock);
30734 ++ read_lock(&grsec_exec_file_lock);
30735 ++ if (p->parent && p->parent->exec_file == p->exec_file)
30736 ++ p->parent->brute = 1;
30737 ++ read_unlock(&grsec_exec_file_lock);
30738 ++ read_unlock(&tasklist_lock);
30739 ++#endif
30740 ++ return;
30741 ++}
30742 ++
30743 ++void gr_handle_brute_check(void)
30744 ++{
30745 ++#ifdef CONFIG_GRKERNSEC_BRUTE
30746 ++ if (current->brute) {
30747 ++ set_current_state(TASK_UNINTERRUPTIBLE);
30748 ++ schedule_timeout(30 * HZ);
30749 ++ }
30750 ++#endif
30751 ++ return;
30752 ++}
30753 ++
30754 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_sock.c linux-2.6.23.15-grsec/grsecurity/grsec_sock.c
30755 +--- linux-2.6.23.15/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100
30756 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_sock.c 2008-02-11 10:37:44.000000000 +0000
30757 +@@ -0,0 +1,263 @@
30758 ++#include <linux/kernel.h>
30759 ++#include <linux/module.h>
30760 ++#include <linux/sched.h>
30761 ++#include <linux/file.h>
30762 ++#include <linux/net.h>
30763 ++#include <linux/in.h>
30764 ++#include <linux/ip.h>
30765 ++#include <net/sock.h>
30766 ++#include <net/inet_sock.h>
30767 ++#include <linux/grsecurity.h>
30768 ++#include <linux/grinternal.h>
30769 ++#include <linux/gracl.h>
30770 ++
30771 ++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
30772 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
30773 ++EXPORT_SYMBOL(udp_v4_lookup);
30774 ++#endif
30775 ++
30776 ++EXPORT_SYMBOL(gr_cap_rtnetlink);
30777 ++
30778 ++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
30779 ++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
30780 ++
30781 ++EXPORT_SYMBOL(gr_search_udp_recvmsg);
30782 ++EXPORT_SYMBOL(gr_search_udp_sendmsg);
30783 ++
30784 ++#ifdef CONFIG_UNIX_MODULE
30785 ++EXPORT_SYMBOL(gr_acl_handle_unix);
30786 ++EXPORT_SYMBOL(gr_acl_handle_mknod);
30787 ++EXPORT_SYMBOL(gr_handle_chroot_unix);
30788 ++EXPORT_SYMBOL(gr_handle_create);
30789 ++#endif
30790 ++
30791 ++#ifdef CONFIG_GRKERNSEC
30792 ++#define gr_conn_table_size 32749
30793 ++struct conn_table_entry {
30794 ++ struct conn_table_entry *next;
30795 ++ struct signal_struct *sig;
30796 ++};
30797 ++
30798 ++struct conn_table_entry *gr_conn_table[gr_conn_table_size];
30799 ++spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
30800 ++
30801 ++extern const char * gr_socktype_to_name(unsigned char type);
30802 ++extern const char * gr_proto_to_name(unsigned char proto);
30803 ++
30804 ++static __inline__ int
30805 ++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
30806 ++{
30807 ++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
30808 ++}
30809 ++
30810 ++static __inline__ int
30811 ++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
30812 ++ __u16 sport, __u16 dport)
30813 ++{
30814 ++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
30815 ++ sig->gr_sport == sport && sig->gr_dport == dport))
30816 ++ return 1;
30817 ++ else
30818 ++ return 0;
30819 ++}
30820 ++
30821 ++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
30822 ++{
30823 ++ struct conn_table_entry **match;
30824 ++ unsigned int index;
30825 ++
30826 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
30827 ++ sig->gr_sport, sig->gr_dport,
30828 ++ gr_conn_table_size);
30829 ++
30830 ++ newent->sig = sig;
30831 ++
30832 ++ match = &gr_conn_table[index];
30833 ++ newent->next = *match;
30834 ++ *match = newent;
30835 ++
30836 ++ return;
30837 ++}
30838 ++
30839 ++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
30840 ++{
30841 ++ struct conn_table_entry *match, *last = NULL;
30842 ++ unsigned int index;
30843 ++
30844 ++ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
30845 ++ sig->gr_sport, sig->gr_dport,
30846 ++ gr_conn_table_size);
30847 ++
30848 ++ match = gr_conn_table[index];
30849 ++ while (match && !conn_match(match->sig,
30850 ++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
30851 ++ sig->gr_dport)) {
30852 ++ last = match;
30853 ++ match = match->next;
30854 ++ }
30855 ++
30856 ++ if (match) {
30857 ++ if (last)
30858 ++ last->next = match->next;
30859 ++ else
30860 ++ gr_conn_table[index] = NULL;
30861 ++ kfree(match);
30862 ++ }
30863 ++
30864 ++ return;
30865 ++}
30866 ++
30867 ++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
30868 ++ __u16 sport, __u16 dport)
30869 ++{
30870 ++ struct conn_table_entry *match;
30871 ++ unsigned int index;
30872 ++
30873 ++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
30874 ++
30875 ++ match = gr_conn_table[index];
30876 ++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
30877 ++ match = match->next;
30878 ++
30879 ++ if (match)
30880 ++ return match->sig;
30881 ++ else
30882 ++ return NULL;
30883 ++}
30884 ++
30885 ++#endif
30886 ++
30887 ++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
30888 ++{
30889 ++#ifdef CONFIG_GRKERNSEC
30890 ++ struct signal_struct *sig = task->signal;
30891 ++ struct conn_table_entry *newent;
30892 ++
30893 ++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
30894 ++ if (newent == NULL)
30895 ++ return;
30896 ++ /* no bh lock needed since we are called with bh disabled */
30897 ++ spin_lock(&gr_conn_table_lock);
30898 ++ gr_del_task_from_ip_table_nolock(sig);
30899 ++ sig->gr_saddr = inet->rcv_saddr;
30900 ++ sig->gr_daddr = inet->daddr;
30901 ++ sig->gr_sport = inet->sport;
30902 ++ sig->gr_dport = inet->dport;
30903 ++ gr_add_to_task_ip_table_nolock(sig, newent);
30904 ++ spin_unlock(&gr_conn_table_lock);
30905 ++#endif
30906 ++ return;
30907 ++}
30908 ++
30909 ++void gr_del_task_from_ip_table(struct task_struct *task)
30910 ++{
30911 ++#ifdef CONFIG_GRKERNSEC
30912 ++ spin_lock(&gr_conn_table_lock);
30913 ++ gr_del_task_from_ip_table_nolock(task->signal);
30914 ++ spin_unlock(&gr_conn_table_lock);
30915 ++#endif
30916 ++ return;
30917 ++}
30918 ++
30919 ++void
30920 ++gr_attach_curr_ip(const struct sock *sk)
30921 ++{
30922 ++#ifdef CONFIG_GRKERNSEC
30923 ++ struct signal_struct *p, *set;
30924 ++ const struct inet_sock *inet = inet_sk(sk);
30925 ++
30926 ++ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
30927 ++ return;
30928 ++
30929 ++ set = current->signal;
30930 ++
30931 ++ spin_lock_bh(&gr_conn_table_lock);
30932 ++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
30933 ++ inet->dport, inet->sport);
30934 ++ if (unlikely(p != NULL)) {
30935 ++ set->curr_ip = p->curr_ip;
30936 ++ set->used_accept = 1;
30937 ++ gr_del_task_from_ip_table_nolock(p);
30938 ++ spin_unlock_bh(&gr_conn_table_lock);
30939 ++ return;
30940 ++ }
30941 ++ spin_unlock_bh(&gr_conn_table_lock);
30942 ++
30943 ++ set->curr_ip = inet->daddr;
30944 ++ set->used_accept = 1;
30945 ++#endif
30946 ++ return;
30947 ++}
30948 ++
30949 ++int
30950 ++gr_handle_sock_all(const int family, const int type, const int protocol)
30951 ++{
30952 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
30953 ++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
30954 ++ (family != AF_UNIX) && (family != AF_LOCAL)) {
30955 ++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
30956 ++ return -EACCES;
30957 ++ }
30958 ++#endif
30959 ++ return 0;
30960 ++}
30961 ++
30962 ++int
30963 ++gr_handle_sock_server(const struct sockaddr *sck)
30964 ++{
30965 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30966 ++ if (grsec_enable_socket_server &&
30967 ++ in_group_p(grsec_socket_server_gid) &&
30968 ++ sck && (sck->sa_family != AF_UNIX) &&
30969 ++ (sck->sa_family != AF_LOCAL)) {
30970 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
30971 ++ return -EACCES;
30972 ++ }
30973 ++#endif
30974 ++ return 0;
30975 ++}
30976 ++
30977 ++int
30978 ++gr_handle_sock_server_other(const struct sock *sck)
30979 ++{
30980 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
30981 ++ if (grsec_enable_socket_server &&
30982 ++ in_group_p(grsec_socket_server_gid) &&
30983 ++ sck && (sck->sk_family != AF_UNIX) &&
30984 ++ (sck->sk_family != AF_LOCAL)) {
30985 ++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
30986 ++ return -EACCES;
30987 ++ }
30988 ++#endif
30989 ++ return 0;
30990 ++}
30991 ++
30992 ++int
30993 ++gr_handle_sock_client(const struct sockaddr *sck)
30994 ++{
30995 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
30996 ++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
30997 ++ sck && (sck->sa_family != AF_UNIX) &&
30998 ++ (sck->sa_family != AF_LOCAL)) {
30999 ++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
31000 ++ return -EACCES;
31001 ++ }
31002 ++#endif
31003 ++ return 0;
31004 ++}
31005 ++
31006 ++__u32
31007 ++gr_cap_rtnetlink(void)
31008 ++{
31009 ++#ifdef CONFIG_GRKERNSEC
31010 ++ if (!gr_acl_is_enabled())
31011 ++ return current->cap_effective;
31012 ++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
31013 ++ gr_task_is_capable(current, CAP_NET_ADMIN))
31014 ++ return current->cap_effective;
31015 ++ else
31016 ++ return 0;
31017 ++#else
31018 ++ return current->cap_effective;
31019 ++#endif
31020 ++}
31021 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_sysctl.c linux-2.6.23.15-grsec/grsecurity/grsec_sysctl.c
31022 +--- linux-2.6.23.15/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100
31023 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_sysctl.c 2008-02-11 10:37:44.000000000 +0000
31024 +@@ -0,0 +1,456 @@
31025 ++#include <linux/kernel.h>
31026 ++#include <linux/sched.h>
31027 ++#include <linux/sysctl.h>
31028 ++#include <linux/grsecurity.h>
31029 ++#include <linux/grinternal.h>
31030 ++
31031 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31032 ++int grsec_modstop;
31033 ++#endif
31034 ++
31035 ++int
31036 ++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
31037 ++{
31038 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
31039 ++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
31040 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
31041 ++ return -EACCES;
31042 ++ }
31043 ++#endif
31044 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31045 ++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
31046 ++ grsec_modstop && (op & 002)) {
31047 ++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
31048 ++ return -EACCES;
31049 ++ }
31050 ++#endif
31051 ++ return 0;
31052 ++}
31053 ++
31054 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
31055 ++enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
31056 ++GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
31057 ++GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
31058 ++GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
31059 ++GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
31060 ++GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
31061 ++GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
31062 ++GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
31063 ++GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
31064 ++
31065 ++
31066 ++ctl_table grsecurity_table[] = {
31067 ++#ifdef CONFIG_GRKERNSEC_SYSCTL
31068 ++#ifdef CONFIG_GRKERNSEC_LINK
31069 ++ {
31070 ++ .ctl_name = GS_LINK,
31071 ++ .procname = "linking_restrictions",
31072 ++ .data = &grsec_enable_link,
31073 ++ .maxlen = sizeof(int),
31074 ++ .mode = 0600,
31075 ++ .proc_handler = &proc_dointvec,
31076 ++ },
31077 ++#endif
31078 ++#ifdef CONFIG_GRKERNSEC_FIFO
31079 ++ {
31080 ++ .ctl_name = GS_FIFO,
31081 ++ .procname = "fifo_restrictions",
31082 ++ .data = &grsec_enable_fifo,
31083 ++ .maxlen = sizeof(int),
31084 ++ .mode = 0600,
31085 ++ .proc_handler = &proc_dointvec,
31086 ++ },
31087 ++#endif
31088 ++#ifdef CONFIG_GRKERNSEC_EXECVE
31089 ++ {
31090 ++ .ctl_name = GS_EXECVE,
31091 ++ .procname = "execve_limiting",
31092 ++ .data = &grsec_enable_execve,
31093 ++ .maxlen = sizeof(int),
31094 ++ .mode = 0600,
31095 ++ .proc_handler = &proc_dointvec,
31096 ++ },
31097 ++#endif
31098 ++#ifdef CONFIG_GRKERNSEC_EXECLOG
31099 ++ {
31100 ++ .ctl_name = GS_EXECLOG,
31101 ++ .procname = "exec_logging",
31102 ++ .data = &grsec_enable_execlog,
31103 ++ .maxlen = sizeof(int),
31104 ++ .mode = 0600,
31105 ++ .proc_handler = &proc_dointvec,
31106 ++ },
31107 ++#endif
31108 ++#ifdef CONFIG_GRKERNSEC_SIGNAL
31109 ++ {
31110 ++ .ctl_name = GS_SIGNAL,
31111 ++ .procname = "signal_logging",
31112 ++ .data = &grsec_enable_signal,
31113 ++ .maxlen = sizeof(int),
31114 ++ .mode = 0600,
31115 ++ .proc_handler = &proc_dointvec,
31116 ++ },
31117 ++#endif
31118 ++#ifdef CONFIG_GRKERNSEC_FORKFAIL
31119 ++ {
31120 ++ .ctl_name = GS_FORKFAIL,
31121 ++ .procname = "forkfail_logging",
31122 ++ .data = &grsec_enable_forkfail,
31123 ++ .maxlen = sizeof(int),
31124 ++ .mode = 0600,
31125 ++ .proc_handler = &proc_dointvec,
31126 ++ },
31127 ++#endif
31128 ++#ifdef CONFIG_GRKERNSEC_TIME
31129 ++ {
31130 ++ .ctl_name = GS_TIME,
31131 ++ .procname = "timechange_logging",
31132 ++ .data = &grsec_enable_time,
31133 ++ .maxlen = sizeof(int),
31134 ++ .mode = 0600,
31135 ++ .proc_handler = &proc_dointvec,
31136 ++ },
31137 ++#endif
31138 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
31139 ++ {
31140 ++ .ctl_name = GS_CHROOT_SHMAT,
31141 ++ .procname = "chroot_deny_shmat",
31142 ++ .data = &grsec_enable_chroot_shmat,
31143 ++ .maxlen = sizeof(int),
31144 ++ .mode = 0600,
31145 ++ .proc_handler = &proc_dointvec,
31146 ++ },
31147 ++#endif
31148 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
31149 ++ {
31150 ++ .ctl_name = GS_CHROOT_UNIX,
31151 ++ .procname = "chroot_deny_unix",
31152 ++ .data = &grsec_enable_chroot_unix,
31153 ++ .maxlen = sizeof(int),
31154 ++ .mode = 0600,
31155 ++ .proc_handler = &proc_dointvec,
31156 ++ },
31157 ++#endif
31158 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
31159 ++ {
31160 ++ .ctl_name = GS_CHROOT_MNT,
31161 ++ .procname = "chroot_deny_mount",
31162 ++ .data = &grsec_enable_chroot_mount,
31163 ++ .maxlen = sizeof(int),
31164 ++ .mode = 0600,
31165 ++ .proc_handler = &proc_dointvec,
31166 ++ },
31167 ++#endif
31168 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
31169 ++ {
31170 ++ .ctl_name = GS_CHROOT_FCHDIR,
31171 ++ .procname = "chroot_deny_fchdir",
31172 ++ .data = &grsec_enable_chroot_fchdir,
31173 ++ .maxlen = sizeof(int),
31174 ++ .mode = 0600,
31175 ++ .proc_handler = &proc_dointvec,
31176 ++ },
31177 ++#endif
31178 ++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
31179 ++ {
31180 ++ .ctl_name = GS_CHROOT_DBL,
31181 ++ .procname = "chroot_deny_chroot",
31182 ++ .data = &grsec_enable_chroot_double,
31183 ++ .maxlen = sizeof(int),
31184 ++ .mode = 0600,
31185 ++ .proc_handler = &proc_dointvec,
31186 ++ },
31187 ++#endif
31188 ++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
31189 ++ {
31190 ++ .ctl_name = GS_CHROOT_PVT,
31191 ++ .procname = "chroot_deny_pivot",
31192 ++ .data = &grsec_enable_chroot_pivot,
31193 ++ .maxlen = sizeof(int),
31194 ++ .mode = 0600,
31195 ++ .proc_handler = &proc_dointvec,
31196 ++ },
31197 ++#endif
31198 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
31199 ++ {
31200 ++ .ctl_name = GS_CHROOT_CD,
31201 ++ .procname = "chroot_enforce_chdir",
31202 ++ .data = &grsec_enable_chroot_chdir,
31203 ++ .maxlen = sizeof(int),
31204 ++ .mode = 0600,
31205 ++ .proc_handler = &proc_dointvec,
31206 ++ },
31207 ++#endif
31208 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
31209 ++ {
31210 ++ .ctl_name = GS_CHROOT_CM,
31211 ++ .procname = "chroot_deny_chmod",
31212 ++ .data = &grsec_enable_chroot_chmod,
31213 ++ .maxlen = sizeof(int),
31214 ++ .mode = 0600,
31215 ++ .proc_handler = &proc_dointvec,
31216 ++ },
31217 ++#endif
31218 ++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
31219 ++ {
31220 ++ .ctl_name = GS_CHROOT_MK,
31221 ++ .procname = "chroot_deny_mknod",
31222 ++ .data = &grsec_enable_chroot_mknod,
31223 ++ .maxlen = sizeof(int),
31224 ++ .mode = 0600,
31225 ++ .proc_handler = &proc_dointvec,
31226 ++ },
31227 ++#endif
31228 ++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
31229 ++ {
31230 ++ .ctl_name = GS_CHROOT_NI,
31231 ++ .procname = "chroot_restrict_nice",
31232 ++ .data = &grsec_enable_chroot_nice,
31233 ++ .maxlen = sizeof(int),
31234 ++ .mode = 0600,
31235 ++ .proc_handler = &proc_dointvec,
31236 ++ },
31237 ++#endif
31238 ++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
31239 ++ {
31240 ++ .ctl_name = GS_CHROOT_EXECLOG,
31241 ++ .procname = "chroot_execlog",
31242 ++ .data = &grsec_enable_chroot_execlog,
31243 ++ .maxlen = sizeof(int),
31244 ++ .mode = 0600,
31245 ++ .proc_handler = &proc_dointvec,
31246 ++ },
31247 ++#endif
31248 ++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
31249 ++ {
31250 ++ .ctl_name = GS_CHROOT_CAPS,
31251 ++ .procname = "chroot_caps",
31252 ++ .data = &grsec_enable_chroot_caps,
31253 ++ .maxlen = sizeof(int),
31254 ++ .mode = 0600,
31255 ++ .proc_handler = &proc_dointvec,
31256 ++ },
31257 ++#endif
31258 ++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
31259 ++ {
31260 ++ .ctl_name = GS_CHROOT_SYSCTL,
31261 ++ .procname = "chroot_deny_sysctl",
31262 ++ .data = &grsec_enable_chroot_sysctl,
31263 ++ .maxlen = sizeof(int),
31264 ++ .mode = 0600,
31265 ++ .proc_handler = &proc_dointvec,
31266 ++ },
31267 ++#endif
31268 ++#ifdef CONFIG_GRKERNSEC_TPE
31269 ++ {
31270 ++ .ctl_name = GS_TPE,
31271 ++ .procname = "tpe",
31272 ++ .data = &grsec_enable_tpe,
31273 ++ .maxlen = sizeof(int),
31274 ++ .mode = 0600,
31275 ++ .proc_handler = &proc_dointvec,
31276 ++ },
31277 ++ {
31278 ++ .ctl_name = GS_TPE_GID,
31279 ++ .procname = "tpe_gid",
31280 ++ .data = &grsec_tpe_gid,
31281 ++ .maxlen = sizeof(int),
31282 ++ .mode = 0600,
31283 ++ .proc_handler = &proc_dointvec,
31284 ++ },
31285 ++#endif
31286 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
31287 ++ {
31288 ++ .ctl_name = GS_TPE_ALL,
31289 ++ .procname = "tpe_restrict_all",
31290 ++ .data = &grsec_enable_tpe_all,
31291 ++ .maxlen = sizeof(int),
31292 ++ .mode = 0600,
31293 ++ .proc_handler = &proc_dointvec,
31294 ++ },
31295 ++#endif
31296 ++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
31297 ++ {
31298 ++ .ctl_name = GS_SOCKET_ALL,
31299 ++ .procname = "socket_all",
31300 ++ .data = &grsec_enable_socket_all,
31301 ++ .maxlen = sizeof(int),
31302 ++ .mode = 0600,
31303 ++ .proc_handler = &proc_dointvec,
31304 ++ },
31305 ++ {
31306 ++ .ctl_name = GS_SOCKET_ALL_GID,
31307 ++ .procname = "socket_all_gid",
31308 ++ .data = &grsec_socket_all_gid,
31309 ++ .maxlen = sizeof(int),
31310 ++ .mode = 0600,
31311 ++ .proc_handler = &proc_dointvec,
31312 ++ },
31313 ++#endif
31314 ++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
31315 ++ {
31316 ++ .ctl_name = GS_SOCKET_CLIENT,
31317 ++ .procname = "socket_client",
31318 ++ .data = &grsec_enable_socket_client,
31319 ++ .maxlen = sizeof(int),
31320 ++ .mode = 0600,
31321 ++ .proc_handler = &proc_dointvec,
31322 ++ },
31323 ++ {
31324 ++ .ctl_name = GS_SOCKET_CLIENT_GID,
31325 ++ .procname = "socket_client_gid",
31326 ++ .data = &grsec_socket_client_gid,
31327 ++ .maxlen = sizeof(int),
31328 ++ .mode = 0600,
31329 ++ .proc_handler = &proc_dointvec,
31330 ++ },
31331 ++#endif
31332 ++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
31333 ++ {
31334 ++ .ctl_name = GS_SOCKET_SERVER,
31335 ++ .procname = "socket_server",
31336 ++ .data = &grsec_enable_socket_server,
31337 ++ .maxlen = sizeof(int),
31338 ++ .mode = 0600,
31339 ++ .proc_handler = &proc_dointvec,
31340 ++ },
31341 ++ {
31342 ++ .ctl_name = GS_SOCKET_SERVER_GID,
31343 ++ .procname = "socket_server_gid",
31344 ++ .data = &grsec_socket_server_gid,
31345 ++ .maxlen = sizeof(int),
31346 ++ .mode = 0600,
31347 ++ .proc_handler = &proc_dointvec,
31348 ++ },
31349 ++#endif
31350 ++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
31351 ++ {
31352 ++ .ctl_name = GS_GROUP,
31353 ++ .procname = "audit_group",
31354 ++ .data = &grsec_enable_group,
31355 ++ .maxlen = sizeof(int),
31356 ++ .mode = 0600,
31357 ++ .proc_handler = &proc_dointvec,
31358 ++ },
31359 ++ {
31360 ++ .ctl_name = GS_GID,
31361 ++ .procname = "audit_gid",
31362 ++ .data = &grsec_audit_gid,
31363 ++ .maxlen = sizeof(int),
31364 ++ .mode = 0600,
31365 ++ .proc_handler = &proc_dointvec,
31366 ++ },
31367 ++#endif
31368 ++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
31369 ++ {
31370 ++ .ctl_name = GS_ACHDIR,
31371 ++ .procname = "audit_chdir",
31372 ++ .data = &grsec_enable_chdir,
31373 ++ .maxlen = sizeof(int),
31374 ++ .mode = 0600,
31375 ++ .proc_handler = &proc_dointvec,
31376 ++ },
31377 ++#endif
31378 ++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
31379 ++ {
31380 ++ .ctl_name = GS_AMOUNT,
31381 ++ .procname = "audit_mount",
31382 ++ .data = &grsec_enable_mount,
31383 ++ .maxlen = sizeof(int),
31384 ++ .mode = 0600,
31385 ++ .proc_handler = &proc_dointvec,
31386 ++ },
31387 ++#endif
31388 ++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
31389 ++ {
31390 ++ .ctl_name = GS_AIPC,
31391 ++ .procname = "audit_ipc",
31392 ++ .data = &grsec_enable_audit_ipc,
31393 ++ .maxlen = sizeof(int),
31394 ++ .mode = 0600,
31395 ++ .proc_handler = &proc_dointvec,
31396 ++ },
31397 ++#endif
31398 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31399 ++ {
31400 ++ .ctl_name = GS_TEXTREL,
31401 ++ .procname = "audit_textrel",
31402 ++ .data = &grsec_enable_audit_textrel,
31403 ++ .maxlen = sizeof(int),
31404 ++ .mode = 0600,
31405 ++ .proc_handler = &proc_dointvec,
31406 ++ },
31407 ++#endif
31408 ++#ifdef CONFIG_GRKERNSEC_DMESG
31409 ++ {
31410 ++ .ctl_name = GS_DMSG,
31411 ++ .procname = "dmesg",
31412 ++ .data = &grsec_enable_dmesg,
31413 ++ .maxlen = sizeof(int),
31414 ++ .mode = 0600,
31415 ++ .proc_handler = &proc_dointvec,
31416 ++ },
31417 ++#endif
31418 ++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
31419 ++ {
31420 ++ .ctl_name = GS_FINDTASK,
31421 ++ .procname = "chroot_findtask",
31422 ++ .data = &grsec_enable_chroot_findtask,
31423 ++ .maxlen = sizeof(int),
31424 ++ .mode = 0600,
31425 ++ .proc_handler = &proc_dointvec,
31426 ++ },
31427 ++#endif
31428 ++#ifdef CONFIG_GRKERNSEC_SHM
31429 ++ {
31430 ++ .ctl_name = GS_SHM,
31431 ++ .procname = "destroy_unused_shm",
31432 ++ .data = &grsec_enable_shm,
31433 ++ .maxlen = sizeof(int),
31434 ++ .mode = 0600,
31435 ++ .proc_handler = &proc_dointvec,
31436 ++ },
31437 ++#endif
31438 ++#ifdef CONFIG_GRKERNSEC_RESLOG
31439 ++ {
31440 ++ .ctl_name = GS_RESLOG,
31441 ++ .procname = "resource_logging",
31442 ++ .data = &grsec_resource_logging,
31443 ++ .maxlen = sizeof(int),
31444 ++ .mode = 0600,
31445 ++ .proc_handler = &proc_dointvec,
31446 ++ },
31447 ++#endif
31448 ++ {
31449 ++ .ctl_name = GS_LOCK,
31450 ++ .procname = "grsec_lock",
31451 ++ .data = &grsec_lock,
31452 ++ .maxlen = sizeof(int),
31453 ++ .mode = 0600,
31454 ++ .proc_handler = &proc_dointvec,
31455 ++ },
31456 ++#endif
31457 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31458 ++ {
31459 ++ .ctl_name = GS_MODSTOP,
31460 ++ .procname = "disable_modules",
31461 ++ .data = &grsec_modstop,
31462 ++ .maxlen = sizeof(int),
31463 ++ .mode = 0600,
31464 ++ .proc_handler = &proc_dointvec,
31465 ++ },
31466 ++#endif
31467 ++ { .ctl_name = 0 }
31468 ++};
31469 ++#endif
31470 ++
31471 ++int gr_check_modstop(void)
31472 ++{
31473 ++#ifdef CONFIG_GRKERNSEC_MODSTOP
31474 ++ if (grsec_modstop == 1) {
31475 ++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
31476 ++ return 1;
31477 ++ }
31478 ++#endif
31479 ++ return 0;
31480 ++}
31481 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_textrel.c linux-2.6.23.15-grsec/grsecurity/grsec_textrel.c
31482 +--- linux-2.6.23.15/grsecurity/grsec_textrel.c 1970-01-01 01:00:00.000000000 +0100
31483 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_textrel.c 2008-02-11 10:37:44.000000000 +0000
31484 +@@ -0,0 +1,16 @@
31485 ++#include <linux/kernel.h>
31486 ++#include <linux/sched.h>
31487 ++#include <linux/mm.h>
31488 ++#include <linux/file.h>
31489 ++#include <linux/grinternal.h>
31490 ++#include <linux/grsecurity.h>
31491 ++
31492 ++void
31493 ++gr_log_textrel(struct vm_area_struct * vma)
31494 ++{
31495 ++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
31496 ++ if (grsec_enable_audit_textrel)
31497 ++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
31498 ++#endif
31499 ++ return;
31500 ++}
31501 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_time.c linux-2.6.23.15-grsec/grsecurity/grsec_time.c
31502 +--- linux-2.6.23.15/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100
31503 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_time.c 2008-02-11 10:37:44.000000000 +0000
31504 +@@ -0,0 +1,13 @@
31505 ++#include <linux/kernel.h>
31506 ++#include <linux/sched.h>
31507 ++#include <linux/grinternal.h>
31508 ++
31509 ++void
31510 ++gr_log_timechange(void)
31511 ++{
31512 ++#ifdef CONFIG_GRKERNSEC_TIME
31513 ++ if (grsec_enable_time)
31514 ++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
31515 ++#endif
31516 ++ return;
31517 ++}
31518 +diff -Nurp linux-2.6.23.15/grsecurity/grsec_tpe.c linux-2.6.23.15-grsec/grsecurity/grsec_tpe.c
31519 +--- linux-2.6.23.15/grsecurity/grsec_tpe.c 1970-01-01 01:00:00.000000000 +0100
31520 ++++ linux-2.6.23.15-grsec/grsecurity/grsec_tpe.c 2008-02-11 10:37:44.000000000 +0000
31521 +@@ -0,0 +1,37 @@
31522 ++#include <linux/kernel.h>
31523 ++#include <linux/sched.h>
31524 ++#include <linux/file.h>
31525 ++#include <linux/fs.h>
31526 ++#include <linux/grinternal.h>
31527 ++
31528 ++extern int gr_acl_tpe_check(void);
31529 ++
31530 ++int
31531 ++gr_tpe_allow(const struct file *file)
31532 ++{
31533 ++#ifdef CONFIG_GRKERNSEC
31534 ++ struct inode *inode = file->f_dentry->d_parent->d_inode;
31535 ++
31536 ++ if (current->uid && ((grsec_enable_tpe &&
31537 ++#ifdef CONFIG_GRKERNSEC_TPE_INVERT
31538 ++ !in_group_p(grsec_tpe_gid)
31539 ++#else
31540 ++ in_group_p(grsec_tpe_gid)
31541 ++#endif
31542 ++ ) || gr_acl_tpe_check()) &&
31543 ++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
31544 ++ (inode->i_mode & S_IWOTH))))) {
31545 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
31546 ++ return 0;
31547 ++ }
31548 ++#ifdef CONFIG_GRKERNSEC_TPE_ALL
31549 ++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
31550 ++ ((inode->i_uid && (inode->i_uid != current->uid)) ||
31551 ++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
31552 ++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
31553 ++ return 0;
31554 ++ }
31555 ++#endif
31556 ++#endif
31557 ++ return 1;
31558 ++}
31559 +diff -Nurp linux-2.6.23.15/grsecurity/grsum.c linux-2.6.23.15-grsec/grsecurity/grsum.c
31560 +--- linux-2.6.23.15/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100
31561 ++++ linux-2.6.23.15-grsec/grsecurity/grsum.c 2008-02-11 10:37:44.000000000 +0000
31562 +@@ -0,0 +1,59 @@
31563 ++#include <linux/err.h>
31564 ++#include <linux/kernel.h>
31565 ++#include <linux/sched.h>
31566 ++#include <linux/mm.h>
31567 ++#include <linux/scatterlist.h>
31568 ++#include <linux/crypto.h>
31569 ++#include <linux/gracl.h>
31570 ++
31571 ++
31572 ++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
31573 ++#error "crypto and sha256 must be built into the kernel"
31574 ++#endif
31575 ++
31576 ++int
31577 ++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
31578 ++{
31579 ++ char *p;
31580 ++ struct crypto_hash *tfm;
31581 ++ struct hash_desc desc;
31582 ++ struct scatterlist sg;
31583 ++ unsigned char temp_sum[GR_SHA_LEN];
31584 ++ volatile int retval = 0;
31585 ++ volatile int dummy = 0;
31586 ++ unsigned int i;
31587 ++
31588 ++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
31589 ++ if (IS_ERR(tfm)) {
31590 ++ /* should never happen, since sha256 should be built in */
31591 ++ return 1;
31592 ++ }
31593 ++
31594 ++ desc.tfm = tfm;
31595 ++ desc.flags = 0;
31596 ++
31597 ++ crypto_hash_init(&desc);
31598 ++
31599 ++ p = salt;
31600 ++ sg_set_buf(&sg, p, GR_SALT_LEN);
31601 ++ crypto_hash_update(&desc, &sg, sg.length);
31602 ++
31603 ++ p = entry->pw;
31604 ++ sg_set_buf(&sg, p, strlen(p));
31605 ++
31606 ++ crypto_hash_update(&desc, &sg, sg.length);
31607 ++
31608 ++ crypto_hash_final(&desc, temp_sum);
31609 ++
31610 ++ memset(entry->pw, 0, GR_PW_LEN);
31611 ++
31612 ++ for (i = 0; i < GR_SHA_LEN; i++)
31613 ++ if (sum[i] != temp_sum[i])
31614 ++ retval = 1;
31615 ++ else
31616 ++ dummy = 1; // waste a cycle
31617 ++
31618 ++ crypto_free_hash(tfm);
31619 ++
31620 ++ return retval;
31621 ++}
31622 +diff -Nurp linux-2.6.23.15/include/asm-alpha/a.out.h linux-2.6.23.15-grsec/include/asm-alpha/a.out.h
31623 +--- linux-2.6.23.15/include/asm-alpha/a.out.h 2007-10-09 21:31:38.000000000 +0100
31624 ++++ linux-2.6.23.15-grsec/include/asm-alpha/a.out.h 2008-02-11 10:37:44.000000000 +0000
31625 +@@ -98,7 +98,7 @@ struct exec
31626 + set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
31627 + ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
31628 +
31629 +-#define STACK_TOP \
31630 ++#define __STACK_TOP \
31631 + (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
31632 +
31633 + #define STACK_TOP_MAX 0x00120000000UL
31634 +diff -Nurp linux-2.6.23.15/include/asm-alpha/elf.h linux-2.6.23.15-grsec/include/asm-alpha/elf.h
31635 +--- linux-2.6.23.15/include/asm-alpha/elf.h 2007-10-09 21:31:38.000000000 +0100
31636 ++++ linux-2.6.23.15-grsec/include/asm-alpha/elf.h 2008-02-11 10:37:44.000000000 +0000
31637 +@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
31638 +
31639 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
31640 +
31641 ++#ifdef CONFIG_PAX_ASLR
31642 ++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
31643 ++
31644 ++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
31645 ++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
31646 ++#endif
31647 ++
31648 + /* $0 is set by ld.so to a pointer to a function which might be
31649 + registered using atexit. This provides a mean for the dynamic
31650 + linker to call DT_FINI functions for shared libraries that have
31651 +diff -Nurp linux-2.6.23.15/include/asm-alpha/kmap_types.h linux-2.6.23.15-grsec/include/asm-alpha/kmap_types.h
31652 +--- linux-2.6.23.15/include/asm-alpha/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31653 ++++ linux-2.6.23.15-grsec/include/asm-alpha/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31654 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
31655 + D(10) KM_IRQ1,
31656 + D(11) KM_SOFTIRQ0,
31657 + D(12) KM_SOFTIRQ1,
31658 +-D(13) KM_TYPE_NR
31659 ++D(13) KM_CLEARPAGE,
31660 ++D(14) KM_TYPE_NR
31661 + };
31662 +
31663 + #undef D
31664 +diff -Nurp linux-2.6.23.15/include/asm-alpha/pgtable.h linux-2.6.23.15-grsec/include/asm-alpha/pgtable.h
31665 +--- linux-2.6.23.15/include/asm-alpha/pgtable.h 2007-10-09 21:31:38.000000000 +0100
31666 ++++ linux-2.6.23.15-grsec/include/asm-alpha/pgtable.h 2008-02-11 10:37:44.000000000 +0000
31667 +@@ -101,6 +101,17 @@ struct vm_area_struct;
31668 + #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
31669 + #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
31670 + #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
31671 ++
31672 ++#ifdef CONFIG_PAX_PAGEEXEC
31673 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
31674 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
31675 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
31676 ++#else
31677 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
31678 ++# define PAGE_COPY_NOEXEC PAGE_COPY
31679 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
31680 ++#endif
31681 ++
31682 + #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
31683 +
31684 + #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
31685 +diff -Nurp linux-2.6.23.15/include/asm-arm/a.out.h linux-2.6.23.15-grsec/include/asm-arm/a.out.h
31686 +--- linux-2.6.23.15/include/asm-arm/a.out.h 2007-10-09 21:31:38.000000000 +0100
31687 ++++ linux-2.6.23.15-grsec/include/asm-arm/a.out.h 2008-02-11 10:37:44.000000000 +0000
31688 +@@ -28,7 +28,7 @@ struct exec
31689 + #define M_ARM 103
31690 +
31691 + #ifdef __KERNEL__
31692 +-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
31693 ++#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
31694 + TASK_SIZE : TASK_SIZE_26)
31695 + #define STACK_TOP_MAX TASK_SIZE
31696 + #endif
31697 +diff -Nurp linux-2.6.23.15/include/asm-arm/elf.h linux-2.6.23.15-grsec/include/asm-arm/elf.h
31698 +--- linux-2.6.23.15/include/asm-arm/elf.h 2007-10-09 21:31:38.000000000 +0100
31699 ++++ linux-2.6.23.15-grsec/include/asm-arm/elf.h 2008-02-11 10:37:44.000000000 +0000
31700 +@@ -90,6 +90,13 @@ extern char elf_platform[];
31701 +
31702 + #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
31703 +
31704 ++#ifdef CONFIG_PAX_ASLR
31705 ++#define PAX_ELF_ET_DYN_BASE 0x00008000UL
31706 ++
31707 ++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
31708 ++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
31709 ++#endif
31710 ++
31711 + /* When the program starts, a1 contains a pointer to a function to be
31712 + registered with atexit, as per the SVR4 ABI. A value of 0 means we
31713 + have no such handler. */
31714 +diff -Nurp linux-2.6.23.15/include/asm-arm/kmap_types.h linux-2.6.23.15-grsec/include/asm-arm/kmap_types.h
31715 +--- linux-2.6.23.15/include/asm-arm/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31716 ++++ linux-2.6.23.15-grsec/include/asm-arm/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31717 +@@ -18,6 +18,7 @@ enum km_type {
31718 + KM_IRQ1,
31719 + KM_SOFTIRQ0,
31720 + KM_SOFTIRQ1,
31721 ++ KM_CLEARPAGE,
31722 + KM_TYPE_NR
31723 + };
31724 +
31725 +diff -Nurp linux-2.6.23.15/include/asm-avr32/a.out.h linux-2.6.23.15-grsec/include/asm-avr32/a.out.h
31726 +--- linux-2.6.23.15/include/asm-avr32/a.out.h 2007-10-09 21:31:38.000000000 +0100
31727 ++++ linux-2.6.23.15-grsec/include/asm-avr32/a.out.h 2008-02-11 10:37:44.000000000 +0000
31728 +@@ -19,8 +19,8 @@ struct exec
31729 +
31730 + #ifdef __KERNEL__
31731 +
31732 +-#define STACK_TOP TASK_SIZE
31733 +-#define STACK_TOP_MAX STACK_TOP
31734 ++#define __STACK_TOP TASK_SIZE
31735 ++#define STACK_TOP_MAX __STACK_TOP
31736 +
31737 + #endif
31738 +
31739 +diff -Nurp linux-2.6.23.15/include/asm-avr32/elf.h linux-2.6.23.15-grsec/include/asm-avr32/elf.h
31740 +--- linux-2.6.23.15/include/asm-avr32/elf.h 2007-10-09 21:31:38.000000000 +0100
31741 ++++ linux-2.6.23.15-grsec/include/asm-avr32/elf.h 2008-02-11 10:37:44.000000000 +0000
31742 +@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
31743 + the loader. We need to make sure that it is out of the way of the program
31744 + that it will "exec", and that there is sufficient room for the brk. */
31745 +
31746 +-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
31747 ++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
31748 +
31749 ++#ifdef CONFIG_PAX_ASLR
31750 ++#define PAX_ELF_ET_DYN_BASE 0x00001000UL
31751 ++
31752 ++#define PAX_DELTA_MMAP_LEN 15
31753 ++#define PAX_DELTA_STACK_LEN 15
31754 ++#endif
31755 +
31756 + /* This yields a mask that user programs can use to figure out what
31757 + instruction set this CPU supports. This could be done in user space,
31758 +diff -Nurp linux-2.6.23.15/include/asm-avr32/kmap_types.h linux-2.6.23.15-grsec/include/asm-avr32/kmap_types.h
31759 +--- linux-2.6.23.15/include/asm-avr32/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31760 ++++ linux-2.6.23.15-grsec/include/asm-avr32/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31761 +@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
31762 + D(11) KM_IRQ1,
31763 + D(12) KM_SOFTIRQ0,
31764 + D(13) KM_SOFTIRQ1,
31765 +-D(14) KM_TYPE_NR
31766 ++D(14) KM_CLEARPAGE,
31767 ++D(15) KM_TYPE_NR
31768 + };
31769 +
31770 + #undef D
31771 +diff -Nurp linux-2.6.23.15/include/asm-blackfin/kmap_types.h linux-2.6.23.15-grsec/include/asm-blackfin/kmap_types.h
31772 +--- linux-2.6.23.15/include/asm-blackfin/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31773 ++++ linux-2.6.23.15-grsec/include/asm-blackfin/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31774 +@@ -15,6 +15,7 @@ enum km_type {
31775 + KM_IRQ1,
31776 + KM_SOFTIRQ0,
31777 + KM_SOFTIRQ1,
31778 ++ KM_CLEARPAGE,
31779 + KM_TYPE_NR
31780 + };
31781 +
31782 +diff -Nurp linux-2.6.23.15/include/asm-cris/kmap_types.h linux-2.6.23.15-grsec/include/asm-cris/kmap_types.h
31783 +--- linux-2.6.23.15/include/asm-cris/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31784 ++++ linux-2.6.23.15-grsec/include/asm-cris/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31785 +@@ -19,6 +19,7 @@ enum km_type {
31786 + KM_IRQ1,
31787 + KM_SOFTIRQ0,
31788 + KM_SOFTIRQ1,
31789 ++ KM_CLEARPAGE,
31790 + KM_TYPE_NR
31791 + };
31792 +
31793 +diff -Nurp linux-2.6.23.15/include/asm-frv/kmap_types.h linux-2.6.23.15-grsec/include/asm-frv/kmap_types.h
31794 +--- linux-2.6.23.15/include/asm-frv/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31795 ++++ linux-2.6.23.15-grsec/include/asm-frv/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31796 +@@ -23,6 +23,7 @@ enum km_type {
31797 + KM_IRQ1,
31798 + KM_SOFTIRQ0,
31799 + KM_SOFTIRQ1,
31800 ++ KM_CLEARPAGE,
31801 + KM_TYPE_NR
31802 + };
31803 +
31804 +diff -Nurp linux-2.6.23.15/include/asm-generic/futex.h linux-2.6.23.15-grsec/include/asm-generic/futex.h
31805 +--- linux-2.6.23.15/include/asm-generic/futex.h 2007-10-09 21:31:38.000000000 +0100
31806 ++++ linux-2.6.23.15-grsec/include/asm-generic/futex.h 2008-02-11 10:37:44.000000000 +0000
31807 +@@ -8,7 +8,7 @@
31808 + #include <asm/uaccess.h>
31809 +
31810 + static inline int
31811 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
31812 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
31813 + {
31814 + int op = (encoded_op >> 28) & 7;
31815 + int cmp = (encoded_op >> 24) & 15;
31816 +@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
31817 + }
31818 +
31819 + static inline int
31820 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
31821 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
31822 + {
31823 + return -ENOSYS;
31824 + }
31825 +diff -Nurp linux-2.6.23.15/include/asm-generic/vmlinux.lds.h linux-2.6.23.15-grsec/include/asm-generic/vmlinux.lds.h
31826 +--- linux-2.6.23.15/include/asm-generic/vmlinux.lds.h 2007-10-09 21:31:38.000000000 +0100
31827 ++++ linux-2.6.23.15-grsec/include/asm-generic/vmlinux.lds.h 2008-02-11 10:37:44.000000000 +0000
31828 +@@ -19,6 +19,7 @@
31829 + .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
31830 + VMLINUX_SYMBOL(__start_rodata) = .; \
31831 + *(.rodata) *(.rodata.*) \
31832 ++ *(.data.read_only) \
31833 + *(__vermagic) /* Kernel version magic */ \
31834 + } \
31835 + \
31836 +diff -Nurp linux-2.6.23.15/include/asm-h8300/kmap_types.h linux-2.6.23.15-grsec/include/asm-h8300/kmap_types.h
31837 +--- linux-2.6.23.15/include/asm-h8300/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
31838 ++++ linux-2.6.23.15-grsec/include/asm-h8300/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
31839 +@@ -15,6 +15,7 @@ enum km_type {
31840 + KM_IRQ1,
31841 + KM_SOFTIRQ0,
31842 + KM_SOFTIRQ1,
31843 ++ KM_CLEARPAGE,
31844 + KM_TYPE_NR
31845 + };
31846 +
31847 +diff -Nurp linux-2.6.23.15/include/asm-i386/a.out.h linux-2.6.23.15-grsec/include/asm-i386/a.out.h
31848 +--- linux-2.6.23.15/include/asm-i386/a.out.h 2007-10-09 21:31:38.000000000 +0100
31849 ++++ linux-2.6.23.15-grsec/include/asm-i386/a.out.h 2008-02-11 10:37:44.000000000 +0000
31850 +@@ -19,8 +19,13 @@ struct exec
31851 +
31852 + #ifdef __KERNEL__
31853 +
31854 +-#define STACK_TOP TASK_SIZE
31855 +-#define STACK_TOP_MAX STACK_TOP
31856 ++#ifdef CONFIG_PAX_SEGMEXEC
31857 ++#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
31858 ++#else
31859 ++#define __STACK_TOP TASK_SIZE
31860 ++#endif
31861 ++
31862 ++#define STACK_TOP_MAX TASK_SIZE
31863 +
31864 + #endif
31865 +
31866 +diff -Nurp linux-2.6.23.15/include/asm-i386/alternative.h linux-2.6.23.15-grsec/include/asm-i386/alternative.h
31867 +--- linux-2.6.23.15/include/asm-i386/alternative.h 2007-10-09 21:31:38.000000000 +0100
31868 ++++ linux-2.6.23.15-grsec/include/asm-i386/alternative.h 2008-02-11 10:37:44.000000000 +0000
31869 +@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
31870 + " .byte 662b-661b\n" /* sourcelen */ \
31871 + " .byte 664f-663f\n" /* replacementlen */ \
31872 + ".previous\n" \
31873 +- ".section .altinstr_replacement,\"ax\"\n" \
31874 ++ ".section .altinstr_replacement,\"a\"\n" \
31875 + "663:\n\t" newinstr "\n664:\n" /* replacement */\
31876 + ".previous" :: "i" (feature) : "memory")
31877 +
31878 +@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
31879 + " .byte 662b-661b\n" /* sourcelen */ \
31880 + " .byte 664f-663f\n" /* replacementlen */ \
31881 + ".previous\n" \
31882 +- ".section .altinstr_replacement,\"ax\"\n" \
31883 ++ ".section .altinstr_replacement,\"a\"\n" \
31884 + "663:\n\t" newinstr "\n664:\n" /* replacement */\
31885 + ".previous" :: "i" (feature), ##input)
31886 +
31887 +@@ -93,7 +93,7 @@ static inline void alternatives_smp_swit
31888 + " .byte 662b-661b\n" /* sourcelen */ \
31889 + " .byte 664f-663f\n" /* replacementlen */ \
31890 + ".previous\n" \
31891 +- ".section .altinstr_replacement,\"ax\"\n" \
31892 ++ ".section .altinstr_replacement,\"a\"\n" \
31893 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
31894 + ".previous" : output : [feat] "i" (feature), ##input)
31895 +
31896 +diff -Nurp linux-2.6.23.15/include/asm-i386/apic.h linux-2.6.23.15-grsec/include/asm-i386/apic.h
31897 +--- linux-2.6.23.15/include/asm-i386/apic.h 2007-10-09 21:31:38.000000000 +0100
31898 ++++ linux-2.6.23.15-grsec/include/asm-i386/apic.h 2008-02-11 10:37:44.000000000 +0000
31899 +@@ -8,7 +8,7 @@
31900 + #include <asm/processor.h>
31901 + #include <asm/system.h>
31902 +
31903 +-#define Dprintk(x...)
31904 ++#define Dprintk(x...) do {} while (0)
31905 +
31906 + /*
31907 + * Debugging macros
31908 +diff -Nurp linux-2.6.23.15/include/asm-i386/cache.h linux-2.6.23.15-grsec/include/asm-i386/cache.h
31909 +--- linux-2.6.23.15/include/asm-i386/cache.h 2007-10-09 21:31:38.000000000 +0100
31910 ++++ linux-2.6.23.15-grsec/include/asm-i386/cache.h 2008-02-11 10:37:44.000000000 +0000
31911 +@@ -10,5 +10,6 @@
31912 + #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
31913 +
31914 + #define __read_mostly __attribute__((__section__(".data.read_mostly")))
31915 ++#define __read_only __attribute__((__section__(".data.read_only")))
31916 +
31917 + #endif
31918 +diff -Nurp linux-2.6.23.15/include/asm-i386/checksum.h linux-2.6.23.15-grsec/include/asm-i386/checksum.h
31919 +--- linux-2.6.23.15/include/asm-i386/checksum.h 2007-10-09 21:31:38.000000000 +0100
31920 ++++ linux-2.6.23.15-grsec/include/asm-i386/checksum.h 2008-02-11 10:37:44.000000000 +0000
31921 +@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
31922 + asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
31923 + int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
31924 +
31925 ++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
31926 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
31927 ++
31928 ++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
31929 ++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
31930 ++
31931 + /*
31932 + * Note: when you get a NULL pointer exception here this means someone
31933 + * passed in an incorrect kernel address to one of these functions.
31934 +@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
31935 + int len, __wsum sum, int *err_ptr)
31936 + {
31937 + might_sleep();
31938 +- return csum_partial_copy_generic((__force void *)src, dst,
31939 ++ return csum_partial_copy_generic_from_user((__force void *)src, dst,
31940 + len, sum, err_ptr, NULL);
31941 + }
31942 +
31943 +@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
31944 + {
31945 + might_sleep();
31946 + if (access_ok(VERIFY_WRITE, dst, len))
31947 +- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
31948 ++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
31949 +
31950 + if (len)
31951 + *err_ptr = -EFAULT;
31952 +diff -Nurp linux-2.6.23.15/include/asm-i386/desc.h linux-2.6.23.15-grsec/include/asm-i386/desc.h
31953 +--- linux-2.6.23.15/include/asm-i386/desc.h 2007-10-09 21:31:38.000000000 +0100
31954 ++++ linux-2.6.23.15-grsec/include/asm-i386/desc.h 2008-02-11 10:37:44.000000000 +0000
31955 +@@ -7,26 +7,22 @@
31956 + #ifndef __ASSEMBLY__
31957 +
31958 + #include <linux/preempt.h>
31959 +-#include <linux/smp.h>
31960 + #include <linux/percpu.h>
31961 ++#include <linux/smp.h>
31962 +
31963 + #include <asm/mmu.h>
31964 +
31965 ++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
31966 ++
31967 + struct Xgt_desc_struct {
31968 + unsigned short size;
31969 +- unsigned long address __attribute__((packed));
31970 ++ struct desc_struct *address __attribute__((packed));
31971 + unsigned short pad;
31972 + } __attribute__ ((packed));
31973 +
31974 +-struct gdt_page
31975 +-{
31976 +- struct desc_struct gdt[GDT_ENTRIES];
31977 +-} __attribute__((aligned(PAGE_SIZE)));
31978 +-DECLARE_PER_CPU(struct gdt_page, gdt_page);
31979 +-
31980 + static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
31981 + {
31982 +- return per_cpu(gdt_page, cpu).gdt;
31983 ++ return cpu_gdt_table[cpu];
31984 + }
31985 +
31986 + extern struct Xgt_desc_struct idt_descr;
31987 +@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
31988 + static inline void write_dt_entry(struct desc_struct *dt,
31989 + int entry, u32 entry_low, u32 entry_high)
31990 + {
31991 ++
31992 ++#ifdef CONFIG_PAX_KERNEXEC
31993 ++ unsigned long cr0;
31994 ++
31995 ++ pax_open_kernel(cr0);
31996 ++#endif
31997 ++
31998 + dt[entry].a = entry_low;
31999 + dt[entry].b = entry_high;
32000 ++
32001 ++#ifdef CONFIG_PAX_KERNEXEC
32002 ++ pax_close_kernel(cr0);
32003 ++#endif
32004 ++
32005 + }
32006 +
32007 + static inline void native_set_ldt(const void *addr, unsigned int entries)
32008 +@@ -139,8 +147,19 @@ static inline void native_load_tls(struc
32009 + unsigned int i;
32010 + struct desc_struct *gdt = get_cpu_gdt_table(cpu);
32011 +
32012 ++#ifdef CONFIG_PAX_KERNEXEC
32013 ++ unsigned long cr0;
32014 ++
32015 ++ pax_open_kernel(cr0);
32016 ++#endif
32017 ++
32018 + for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
32019 + gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
32020 ++
32021 ++#ifdef CONFIG_PAX_KERNEXEC
32022 ++ pax_close_kernel(cr0);
32023 ++#endif
32024 ++
32025 + }
32026 +
32027 + static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
32028 +@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
32029 + ((info)->seg_32bit << 22) | \
32030 + ((info)->limit_in_pages << 23) | \
32031 + ((info)->useable << 20) | \
32032 +- 0x7000)
32033 ++ 0x7100)
32034 +
32035 + #define LDT_empty(info) (\
32036 + (info)->base_addr == 0 && \
32037 +@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
32038 + preempt_enable();
32039 + }
32040 +
32041 +-static inline unsigned long get_desc_base(unsigned long *desc)
32042 ++static inline unsigned long get_desc_base(struct desc_struct *desc)
32043 + {
32044 + unsigned long base;
32045 +- base = ((desc[0] >> 16) & 0x0000ffff) |
32046 +- ((desc[1] << 16) & 0x00ff0000) |
32047 +- (desc[1] & 0xff000000);
32048 ++ base = ((desc->a >> 16) & 0x0000ffff) |
32049 ++ ((desc->b << 16) & 0x00ff0000) |
32050 ++ (desc->b & 0xff000000);
32051 + return base;
32052 + }
32053 +
32054 ++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
32055 ++{
32056 ++ __u32 a, b;
32057 ++
32058 ++ if (likely(limit))
32059 ++ limit = (limit - 1UL) >> PAGE_SHIFT;
32060 ++ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
32061 ++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
32062 ++}
32063 ++
32064 + #else /* __ASSEMBLY__ */
32065 +
32066 + /*
32067 +diff -Nurp linux-2.6.23.15/include/asm-i386/elf.h linux-2.6.23.15-grsec/include/asm-i386/elf.h
32068 +--- linux-2.6.23.15/include/asm-i386/elf.h 2007-10-09 21:31:38.000000000 +0100
32069 ++++ linux-2.6.23.15-grsec/include/asm-i386/elf.h 2008-02-11 10:37:44.000000000 +0000
32070 +@@ -73,7 +73,18 @@ typedef struct user_fxsr_struct elf_fpxr
32071 + the loader. We need to make sure that it is out of the way of the program
32072 + that it will "exec", and that there is sufficient room for the brk. */
32073 +
32074 ++#ifdef CONFIG_PAX_SEGMEXEC
32075 ++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
32076 ++#else
32077 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
32078 ++#endif
32079 ++
32080 ++#ifdef CONFIG_PAX_ASLR
32081 ++#define PAX_ELF_ET_DYN_BASE 0x10000000UL
32082 ++
32083 ++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
32084 ++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
32085 ++#endif
32086 +
32087 + /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
32088 + now struct_user_regs, they are different) */
32089 +@@ -131,7 +142,7 @@ extern int dump_task_extended_fpu (struc
32090 + #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
32091 +
32092 + #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
32093 +-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
32094 ++#define VDSO_CURRENT_BASE (current->mm->context.vdso)
32095 + #define VDSO_PRELINK 0
32096 +
32097 + #define VDSO_SYM(x) \
32098 +diff -Nurp linux-2.6.23.15/include/asm-i386/futex.h linux-2.6.23.15-grsec/include/asm-i386/futex.h
32099 +--- linux-2.6.23.15/include/asm-i386/futex.h 2007-10-09 21:31:38.000000000 +0100
32100 ++++ linux-2.6.23.15-grsec/include/asm-i386/futex.h 2008-02-11 10:37:44.000000000 +0000
32101 +@@ -11,8 +11,11 @@
32102 +
32103 + #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
32104 + __asm__ __volatile ( \
32105 ++ "movw %w6, %%ds\n"\
32106 + "1: " insn "\n" \
32107 +-"2: .section .fixup,\"ax\"\n\
32108 ++"2: pushl %%ss\n\
32109 ++ popl %%ds\n\
32110 ++ .section .fixup,\"ax\"\n\
32111 + 3: mov %3, %1\n\
32112 + jmp 2b\n\
32113 + .previous\n\
32114 +@@ -21,16 +24,19 @@
32115 + .long 1b,3b\n\
32116 + .previous" \
32117 + : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
32118 +- : "i" (-EFAULT), "0" (oparg), "1" (0))
32119 ++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
32120 +
32121 + #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
32122 + __asm__ __volatile ( \
32123 +-"1: movl %2, %0\n\
32124 ++" movw %w7, %%es\n\
32125 ++1: movl %%es:%2, %0\n\
32126 + movl %0, %3\n" \
32127 + insn "\n" \
32128 +-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
32129 ++"2: " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\
32130 + jnz 1b\n\
32131 +-3: .section .fixup,\"ax\"\n\
32132 ++3: pushl %%ss\n\
32133 ++ popl %%es\n\
32134 ++ .section .fixup,\"ax\"\n\
32135 + 4: mov %5, %1\n\
32136 + jmp 3b\n\
32137 + .previous\n\
32138 +@@ -40,10 +46,10 @@
32139 + .previous" \
32140 + : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
32141 + "=&r" (tem) \
32142 +- : "r" (oparg), "i" (-EFAULT), "1" (0))
32143 ++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
32144 +
32145 + static inline int
32146 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
32147 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
32148 + {
32149 + int op = (encoded_op >> 28) & 7;
32150 + int cmp = (encoded_op >> 24) & 15;
32151 +@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
32152 + pagefault_disable();
32153 +
32154 + if (op == FUTEX_OP_SET)
32155 +- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
32156 ++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
32157 + else {
32158 + #ifndef CONFIG_X86_BSWAP
32159 + if (boot_cpu_data.x86 == 3)
32160 +@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
32161 + #endif
32162 + switch (op) {
32163 + case FUTEX_OP_ADD:
32164 +- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
32165 ++ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret,
32166 + oldval, uaddr, oparg);
32167 + break;
32168 + case FUTEX_OP_OR:
32169 +@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
32170 + }
32171 +
32172 + static inline int
32173 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
32174 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
32175 + {
32176 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
32177 + return -EFAULT;
32178 +
32179 + __asm__ __volatile__(
32180 +- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
32181 +-
32182 +- "2: .section .fixup, \"ax\" \n"
32183 ++ " movw %w5, %%ds \n"
32184 ++ "1: " LOCK_PREFIX "cmpxchgl %3, %%ds:%1 \n"
32185 ++ "2: pushl %%ss \n"
32186 ++ " popl %%ds \n"
32187 ++ " .section .fixup, \"ax\" \n"
32188 + "3: mov %2, %0 \n"
32189 + " jmp 2b \n"
32190 + " .previous \n"
32191 +@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
32192 + " .previous \n"
32193 +
32194 + : "=a" (oldval), "+m" (*uaddr)
32195 +- : "i" (-EFAULT), "r" (newval), "0" (oldval)
32196 ++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
32197 + : "memory"
32198 + );
32199 +
32200 +diff -Nurp linux-2.6.23.15/include/asm-i386/i387.h linux-2.6.23.15-grsec/include/asm-i386/i387.h
32201 +--- linux-2.6.23.15/include/asm-i386/i387.h 2007-10-09 21:31:38.000000000 +0100
32202 ++++ linux-2.6.23.15-grsec/include/asm-i386/i387.h 2008-02-11 10:37:44.000000000 +0000
32203 +@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
32204 + #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
32205 +
32206 + /* We need a safe address that is cheap to find and that is already
32207 +- in L1 during context switch. The best choices are unfortunately
32208 +- different for UP and SMP */
32209 +-#ifdef CONFIG_SMP
32210 +-#define safe_address (__per_cpu_offset[0])
32211 +-#else
32212 +-#define safe_address (kstat_cpu(0).cpustat.user)
32213 +-#endif
32214 ++ in L1 during context switch. */
32215 ++#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
32216 +
32217 + /*
32218 + * These must be called with preempt disabled
32219 +diff -Nurp linux-2.6.23.15/include/asm-i386/irqflags.h linux-2.6.23.15-grsec/include/asm-i386/irqflags.h
32220 +--- linux-2.6.23.15/include/asm-i386/irqflags.h 2007-10-09 21:31:38.000000000 +0100
32221 ++++ linux-2.6.23.15-grsec/include/asm-i386/irqflags.h 2008-02-11 10:37:44.000000000 +0000
32222 +@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_
32223 + #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
32224 + #define INTERRUPT_RETURN iret
32225 + #define GET_CR0_INTO_EAX movl %cr0, %eax
32226 ++#define GET_CR0_INTO_EDX movl %cr0, %edx
32227 ++#define SET_CR0_FROM_EDX movl %edx, %cr0
32228 + #endif /* __ASSEMBLY__ */
32229 + #endif /* CONFIG_PARAVIRT */
32230 +
32231 +diff -Nurp linux-2.6.23.15/include/asm-i386/kmap_types.h linux-2.6.23.15-grsec/include/asm-i386/kmap_types.h
32232 +--- linux-2.6.23.15/include/asm-i386/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
32233 ++++ linux-2.6.23.15-grsec/include/asm-i386/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
32234 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
32235 + D(10) KM_IRQ1,
32236 + D(11) KM_SOFTIRQ0,
32237 + D(12) KM_SOFTIRQ1,
32238 +-D(13) KM_TYPE_NR
32239 ++D(13) KM_CLEARPAGE,
32240 ++D(14) KM_TYPE_NR
32241 + };
32242 +
32243 + #undef D
32244 +diff -Nurp linux-2.6.23.15/include/asm-i386/mach-default/apm.h linux-2.6.23.15-grsec/include/asm-i386/mach-default/apm.h
32245 +--- linux-2.6.23.15/include/asm-i386/mach-default/apm.h 2007-10-09 21:31:38.000000000 +0100
32246 ++++ linux-2.6.23.15-grsec/include/asm-i386/mach-default/apm.h 2008-02-11 10:37:44.000000000 +0000
32247 +@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
32248 + __asm__ __volatile__(APM_DO_ZERO_SEGS
32249 + "pushl %%edi\n\t"
32250 + "pushl %%ebp\n\t"
32251 +- "lcall *%%cs:apm_bios_entry\n\t"
32252 ++ "lcall *%%ss:apm_bios_entry\n\t"
32253 + "setc %%al\n\t"
32254 + "popl %%ebp\n\t"
32255 + "popl %%edi\n\t"
32256 +@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
32257 + __asm__ __volatile__(APM_DO_ZERO_SEGS
32258 + "pushl %%edi\n\t"
32259 + "pushl %%ebp\n\t"
32260 +- "lcall *%%cs:apm_bios_entry\n\t"
32261 ++ "lcall *%%ss:apm_bios_entry\n\t"
32262 + "setc %%bl\n\t"
32263 + "popl %%ebp\n\t"
32264 + "popl %%edi\n\t"
32265 +diff -Nurp linux-2.6.23.15/include/asm-i386/mman.h linux-2.6.23.15-grsec/include/asm-i386/mman.h
32266 +--- linux-2.6.23.15/include/asm-i386/mman.h 2007-10-09 21:31:38.000000000 +0100
32267 ++++ linux-2.6.23.15-grsec/include/asm-i386/mman.h 2008-02-11 10:37:44.000000000 +0000
32268 +@@ -14,4 +14,12 @@
32269 + #define MCL_CURRENT 1 /* lock all current mappings */
32270 + #define MCL_FUTURE 2 /* lock all future mappings */
32271 +
32272 ++#ifdef __KERNEL__
32273 ++#ifndef __ASSEMBLY__
32274 ++#define arch_mmap_check i386_mmap_check
32275 ++int i386_mmap_check(unsigned long addr, unsigned long len,
32276 ++ unsigned long flags);
32277 ++#endif
32278 ++#endif
32279 ++
32280 + #endif /* __I386_MMAN_H__ */
32281 +diff -Nurp linux-2.6.23.15/include/asm-i386/mmu.h linux-2.6.23.15-grsec/include/asm-i386/mmu.h
32282 +--- linux-2.6.23.15/include/asm-i386/mmu.h 2007-10-09 21:31:38.000000000 +0100
32283 ++++ linux-2.6.23.15-grsec/include/asm-i386/mmu.h 2008-02-11 10:37:44.000000000 +0000
32284 +@@ -11,8 +11,19 @@
32285 + typedef struct {
32286 + int size;
32287 + struct semaphore sem;
32288 +- void *ldt;
32289 +- void *vdso;
32290 ++ struct desc_struct *ldt;
32291 ++ unsigned long vdso;
32292 ++
32293 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32294 ++ unsigned long user_cs_base;
32295 ++ unsigned long user_cs_limit;
32296 ++
32297 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
32298 ++ cpumask_t cpu_user_cs_mask;
32299 ++#endif
32300 ++
32301 ++#endif
32302 ++
32303 + } mm_context_t;
32304 +
32305 + #endif
32306 +diff -Nurp linux-2.6.23.15/include/asm-i386/mmu_context.h linux-2.6.23.15-grsec/include/asm-i386/mmu_context.h
32307 +--- linux-2.6.23.15/include/asm-i386/mmu_context.h 2007-10-09 21:31:38.000000000 +0100
32308 ++++ linux-2.6.23.15-grsec/include/asm-i386/mmu_context.h 2008-02-11 10:37:44.000000000 +0000
32309 +@@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s
32310 + */
32311 + if (unlikely(prev->context.ldt != next->context.ldt))
32312 + load_LDT_nolock(&next->context);
32313 ++
32314 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
32315 ++ if (!nx_enabled) {
32316 ++ smp_mb__before_clear_bit();
32317 ++ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
32318 ++ smp_mb__after_clear_bit();
32319 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
32320 ++ }
32321 ++#endif
32322 ++
32323 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32324 ++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
32325 ++ prev->context.user_cs_limit != next->context.user_cs_limit))
32326 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
32327 ++#endif
32328 ++
32329 + }
32330 + #ifdef CONFIG_SMP
32331 + else {
32332 +@@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s
32333 + */
32334 + load_cr3(next->pgd);
32335 + load_LDT_nolock(&next->context);
32336 ++
32337 ++#ifdef CONFIG_PAX_PAGEEXEC
32338 ++ if (!nx_enabled)
32339 ++ cpu_set(cpu, next->context.cpu_user_cs_mask);
32340 ++#endif
32341 ++
32342 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32343 ++#ifdef CONFIG_PAX_PAGEEXEC
32344 ++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
32345 ++#endif
32346 ++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
32347 ++#endif
32348 ++
32349 + }
32350 + }
32351 + #endif
32352 +diff -Nurp linux-2.6.23.15/include/asm-i386/module.h linux-2.6.23.15-grsec/include/asm-i386/module.h
32353 +--- linux-2.6.23.15/include/asm-i386/module.h 2007-10-09 21:31:38.000000000 +0100
32354 ++++ linux-2.6.23.15-grsec/include/asm-i386/module.h 2008-02-11 10:37:44.000000000 +0000
32355 +@@ -70,6 +70,12 @@ struct mod_arch_specific
32356 + #define MODULE_STACKSIZE ""
32357 + #endif
32358 +
32359 +-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
32360 ++#ifdef CONFIG_GRKERNSEC
32361 ++#define MODULE_GRSEC "GRSECURTY "
32362 ++#else
32363 ++#define MODULE_GRSEC ""
32364 ++#endif
32365 ++
32366 ++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
32367 +
32368 + #endif /* _ASM_I386_MODULE_H */
32369 +diff -Nurp linux-2.6.23.15/include/asm-i386/page.h linux-2.6.23.15-grsec/include/asm-i386/page.h
32370 +--- linux-2.6.23.15/include/asm-i386/page.h 2007-10-09 21:31:38.000000000 +0100
32371 ++++ linux-2.6.23.15-grsec/include/asm-i386/page.h 2008-02-11 10:37:44.000000000 +0000
32372 +@@ -10,6 +10,7 @@
32373 + #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
32374 +
32375 + #ifdef __KERNEL__
32376 ++#include <asm/boot.h>
32377 + #ifndef __ASSEMBLY__
32378 +
32379 + #ifdef CONFIG_X86_USE_3DNOW
32380 +@@ -90,7 +91,6 @@ static inline pte_t native_make_pte(unsi
32381 + typedef struct { unsigned long pte_low; } pte_t;
32382 + typedef struct { unsigned long pgd; } pgd_t;
32383 + typedef struct { unsigned long pgprot; } pgprot_t;
32384 +-#define boot_pte_t pte_t /* or would you rather have a typedef */
32385 +
32386 + static inline unsigned long native_pgd_val(pgd_t pgd)
32387 + {
32388 +@@ -175,6 +175,18 @@ extern int page_is_ram(unsigned long pag
32389 + #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
32390 + #endif
32391 +
32392 ++#ifdef CONFIG_PAX_KERNEXEC
32393 ++#ifdef __ASSEMBLY__
32394 ++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 6*1024*1024 - 1) & ~(4*1024*1024 - 1)))
32395 ++#else
32396 ++extern unsigned char KERNEL_TEXT_OFFSET[];
32397 ++#define __KERNEL_TEXT_OFFSET ((unsigned long)KERNEL_TEXT_OFFSET)
32398 ++extern unsigned char MODULES_VADDR[];
32399 ++extern unsigned char MODULES_END[];
32400 ++#endif
32401 ++#else
32402 ++#define __KERNEL_TEXT_OFFSET (0)
32403 ++#endif
32404 +
32405 + #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
32406 + #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
32407 +@@ -197,6 +209,10 @@ extern int page_is_ram(unsigned long pag
32408 + ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
32409 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
32410 +
32411 ++#ifdef CONFIG_PAX_PAGEEXEC
32412 ++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
32413 ++#endif
32414 ++
32415 + #include <asm-generic/memory_model.h>
32416 + #include <asm-generic/page.h>
32417 +
32418 +diff -Nurp linux-2.6.23.15/include/asm-i386/paravirt.h linux-2.6.23.15-grsec/include/asm-i386/paravirt.h
32419 +--- linux-2.6.23.15/include/asm-i386/paravirt.h 2007-10-09 21:31:38.000000000 +0100
32420 ++++ linux-2.6.23.15-grsec/include/asm-i386/paravirt.h 2008-02-11 10:37:44.000000000 +0000
32421 +@@ -1057,23 +1057,23 @@ static inline unsigned long __raw_local_
32422 +
32423 + #define INTERRUPT_RETURN \
32424 + PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \
32425 +- jmp *%cs:paravirt_ops+PARAVIRT_iret)
32426 ++ jmp *%ss:paravirt_ops+PARAVIRT_iret)
32427 +
32428 + #define DISABLE_INTERRUPTS(clobbers) \
32429 + PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \
32430 + pushl %eax; pushl %ecx; pushl %edx; \
32431 +- call *%cs:paravirt_ops+PARAVIRT_irq_disable; \
32432 ++ call *%ss:paravirt_ops+PARAVIRT_irq_disable; \
32433 + popl %edx; popl %ecx; popl %eax) \
32434 +
32435 + #define ENABLE_INTERRUPTS(clobbers) \
32436 + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \
32437 + pushl %eax; pushl %ecx; pushl %edx; \
32438 +- call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
32439 ++ call *%ss:paravirt_ops+PARAVIRT_irq_enable; \
32440 + popl %edx; popl %ecx; popl %eax)
32441 +
32442 + #define ENABLE_INTERRUPTS_SYSEXIT \
32443 + PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \
32444 +- jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
32445 ++ jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit)
32446 +
32447 + #define GET_CR0_INTO_EAX \
32448 + push %ecx; push %edx; \
32449 +diff -Nurp linux-2.6.23.15/include/asm-i386/percpu.h linux-2.6.23.15-grsec/include/asm-i386/percpu.h
32450 +--- linux-2.6.23.15/include/asm-i386/percpu.h 2007-10-09 21:31:38.000000000 +0100
32451 ++++ linux-2.6.23.15-grsec/include/asm-i386/percpu.h 2008-02-11 10:37:44.000000000 +0000
32452 +@@ -22,7 +22,7 @@
32453 + #define PER_CPU_VAR(var) %fs:per_cpu__##var
32454 + #else /* ! SMP */
32455 + #define PER_CPU(var, reg) \
32456 +- movl $per_cpu__##var, reg
32457 ++ movl per_cpu__##var, reg
32458 + #define PER_CPU_VAR(var) per_cpu__##var
32459 + #endif /* SMP */
32460 +
32461 +@@ -42,12 +42,12 @@
32462 + */
32463 + #ifdef CONFIG_SMP
32464 + /* Same as generic implementation except for optimized local access. */
32465 +-#define __GENERIC_PER_CPU
32466 +
32467 + /* This is used for other cpus to find our section. */
32468 + extern unsigned long __per_cpu_offset[];
32469 ++extern void setup_per_cpu_areas(void);
32470 +
32471 +-#define per_cpu_offset(x) (__per_cpu_offset[x])
32472 ++#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
32473 +
32474 + /* Separate out the type, so (int[3], foo) works. */
32475 + #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
32476 +@@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
32477 +
32478 + /* var is in discarded region: offset to particular copy we want */
32479 + #define per_cpu(var, cpu) (*({ \
32480 +- extern int simple_indentifier_##var(void); \
32481 ++ extern int simple_identifier_##var(void); \
32482 + RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
32483 +
32484 + #define __raw_get_cpu_var(var) (*({ \
32485 +- extern int simple_indentifier_##var(void); \
32486 ++ extern int simple_identifier_##var(void); \
32487 + RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \
32488 + }))
32489 +
32490 +@@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
32491 + do { \
32492 + unsigned int __i; \
32493 + for_each_possible_cpu(__i) \
32494 +- memcpy((pcpudst)+__per_cpu_offset[__i], \
32495 ++ memcpy((pcpudst)+per_cpu_offset(__i), \
32496 + (src), (size)); \
32497 + } while (0)
32498 +
32499 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgalloc.h linux-2.6.23.15-grsec/include/asm-i386/pgalloc.h
32500 +--- linux-2.6.23.15/include/asm-i386/pgalloc.h 2007-10-09 21:31:38.000000000 +0100
32501 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgalloc.h 2008-02-11 10:37:44.000000000 +0000
32502 +@@ -15,11 +15,19 @@
32503 + #define paravirt_release_pd(pfn) do { } while (0)
32504 + #endif
32505 +
32506 ++#ifdef CONFIG_COMPAT_VDSO
32507 + #define pmd_populate_kernel(mm, pmd, pte) \
32508 + do { \
32509 + paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
32510 + set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
32511 + } while (0)
32512 ++#else
32513 ++#define pmd_populate_kernel(mm, pmd, pte) \
32514 ++do { \
32515 ++ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \
32516 ++ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
32517 ++} while (0)
32518 ++#endif
32519 +
32520 + #define pmd_populate(mm, pmd, pte) \
32521 + do { \
32522 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable-2level.h linux-2.6.23.15-grsec/include/asm-i386/pgtable-2level.h
32523 +--- linux-2.6.23.15/include/asm-i386/pgtable-2level.h 2007-10-09 21:31:38.000000000 +0100
32524 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable-2level.h 2008-02-11 10:37:44.000000000 +0000
32525 +@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
32526 + }
32527 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
32528 + {
32529 ++
32530 ++#ifdef CONFIG_PAX_KERNEXEC
32531 ++ unsigned long cr0;
32532 ++
32533 ++ pax_open_kernel(cr0);
32534 ++#endif
32535 ++
32536 + *pmdp = pmd;
32537 ++
32538 ++#ifdef CONFIG_PAX_KERNEXEC
32539 ++ pax_close_kernel(cr0);
32540 ++#endif
32541 ++
32542 + }
32543 + #ifndef CONFIG_PARAVIRT
32544 + #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
32545 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable-3level.h linux-2.6.23.15-grsec/include/asm-i386/pgtable-3level.h
32546 +--- linux-2.6.23.15/include/asm-i386/pgtable-3level.h 2007-10-09 21:31:38.000000000 +0100
32547 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable-3level.h 2008-02-11 10:37:44.000000000 +0000
32548 +@@ -67,11 +67,35 @@ static inline void native_set_pte_atomic
32549 + }
32550 + static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
32551 + {
32552 ++
32553 ++#ifdef CONFIG_PAX_KERNEXEC
32554 ++ unsigned long cr0;
32555 ++
32556 ++ pax_open_kernel(cr0);
32557 ++#endif
32558 ++
32559 + set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
32560 ++
32561 ++#ifdef CONFIG_PAX_KERNEXEC
32562 ++ pax_close_kernel(cr0);
32563 ++#endif
32564 ++
32565 + }
32566 + static inline void native_set_pud(pud_t *pudp, pud_t pud)
32567 + {
32568 ++
32569 ++#ifdef CONFIG_PAX_KERNEXEC
32570 ++ unsigned long cr0;
32571 ++
32572 ++ pax_open_kernel(cr0);
32573 ++#endif
32574 ++
32575 + *pudp = pud;
32576 ++
32577 ++#ifdef CONFIG_PAX_KERNEXEC
32578 ++ pax_close_kernel(cr0);
32579 ++#endif
32580 ++
32581 + }
32582 +
32583 + /*
32584 +diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable.h linux-2.6.23.15-grsec/include/asm-i386/pgtable.h
32585 +--- linux-2.6.23.15/include/asm-i386/pgtable.h 2007-10-09 21:31:38.000000000 +0100
32586 ++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable.h 2008-02-11 10:37:44.000000000 +0000
32587 +@@ -34,7 +34,6 @@ struct vm_area_struct;
32588 + */
32589 + #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
32590 + extern unsigned long empty_zero_page[1024];
32591 +-extern pgd_t swapper_pg_dir[1024];
32592 + extern struct kmem_cache *pmd_cache;
32593 + extern spinlock_t pgd_lock;
32594 + extern struct page *pgd_list;
32595 +@@ -58,6 +57,11 @@ void paging_init(void);
32596 + # include <asm/pgtable-2level-defs.h>
32597 + #endif
32598 +
32599 ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
32600 ++#ifdef CONFIG_X86_PAE
32601 ++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
32602 ++#endif
32603 ++
32604 + #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
32605 + #define PGDIR_MASK (~(PGDIR_SIZE-1))
32606 +
32607 +@@ -67,9 +71,11 @@ void paging_init(void);
32608 + #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
32609 + #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
32610 +
32611 ++#ifndef CONFIG_X86_PAE
32612 + #define TWOLEVEL_PGDIR_SHIFT 22
32613 + #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
32614 + #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
32615 ++#endif
32616 +
32617 + /* Just any arbitrary offset to the start of the vmalloc VM area: the
32618 + * current 8MB value just means that there will be a 8MB "hole" after the
32619 +@@ -136,7 +142,7 @@ void paging_init(void);
32620 + #define PAGE_NONE \
32621 + __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
32622 + #define PAGE_SHARED \
32623 +- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
32624 ++ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
32625 +
32626 + #define PAGE_SHARED_EXEC \
32627 + __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
32628 +@@ -202,7 +208,7 @@ extern unsigned long long __PAGE_KERNEL,
32629 + #undef TEST_ACCESS_OK
32630 +
32631 + /* The boot page tables (all created as a single array) */
32632 +-extern unsigned long pg0[];
32633 ++extern pte_t pg0[];
32634 +
32635 + #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
32636 +
32637 +@@ -218,30 +224,55 @@ extern unsigned long pg0[];
32638 + * The following only work if pte_present() is true.
32639 + * Undefined behaviour if not..
32640 + */
32641 ++static inline int pte_user(pte_t pte) { return (pte).pte_low & _PAGE_USER; }
32642 + static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; }
32643 + static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; }
32644 + static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
32645 + static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; }
32646 +
32647 ++#ifdef CONFIG_X86_PAE
32648 ++# include <asm/pgtable-3level.h>
32649 ++#else
32650 ++# include <asm/pgtable-2level.h>
32651 ++#endif
32652 ++
32653 + /*
32654 + * The following only works if pte_present() is not true.
32655 + */
32656 + static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
32657 +
32658 ++static inline pte_t pte_exprotect(pte_t pte)
32659 ++{
32660 ++#ifdef CONFIG_X86_PAE
32661 ++ if (__supported_pte_mask & _PAGE_NX)
32662 ++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
32663 ++ else
32664 ++#endif
32665 ++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
32666 ++ return pte;
32667 ++}
32668 ++
32669 + static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
32670 + static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
32671 + static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
32672 ++static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
32673 ++
32674 ++static inline pte_t pte_mkexec(pte_t pte)
32675 ++{
32676 ++#ifdef CONFIG_X86_PAE
32677 ++ if (__supported_pte_mask & _PAGE_NX)
32678 ++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
32679 ++ else
32680 ++#endif
32681 ++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
32682 ++ return pte;
32683 ++}
32684 ++
32685 + static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
32686 + static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
32687 + static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
32688 + static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
32689 +
32690 +-#ifdef CONFIG_X86_PAE
32691 +-# include <asm/pgtable-3level.h>
32692 +-#else
32693 +-# include <asm/pgtable-2level.h>
32694 +-#endif
32695 +-
32696 + #ifndef CONFIG_PARAVIRT
32697 + /*
32698 + * Rules for using pte_update - it must be called after any PTE update which
32699 +@@ -353,7 +384,19 @@ static inline void ptep_set_wrprotect(st
32700 + */
32701 + static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
32702 + {
32703 +- memcpy(dst, src, count * sizeof(pgd_t));
32704 ++
32705 ++#ifdef CONFIG_PAX_KERNEXEC
32706 ++ unsigned long cr0;
32707 ++
32708 ++ pax_open_kernel(cr0);
32709 ++#endif
32710 ++
32711 ++ memcpy(dst, src, count * sizeof(pgd_t));
32712 ++
32713 ++#ifdef CONFIG_PAX_KERNEXEC
32714 ++ pax_close_kernel(cr0);
32715 ++#endif
32716 ++
32717 + }
32718 +
32719 + /*
32720 +@@ -500,6 +543,9 @@ static inline void paravirt_pagetable_se
32721 +
32722 + #endif /* !__ASSEMBLY__ */
32723 +
32724 ++#define HAVE_ARCH_UNMAPPED_AREA
32725 ++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
32726 ++
32727 + #ifdef CONFIG_FLATMEM
32728 + #define kern_addr_valid(addr) (1)
32729 + #endif /* CONFIG_FLATMEM */
32730 +diff -Nurp linux-2.6.23.15/include/asm-i386/processor.h linux-2.6.23.15-grsec/include/asm-i386/processor.h
32731 +--- linux-2.6.23.15/include/asm-i386/processor.h 2007-10-09 21:31:38.000000000 +0100
32732 ++++ linux-2.6.23.15-grsec/include/asm-i386/processor.h 2008-02-11 10:37:44.000000000 +0000
32733 +@@ -99,8 +99,6 @@ struct cpuinfo_x86 {
32734 +
32735 + extern struct cpuinfo_x86 boot_cpu_data;
32736 + extern struct cpuinfo_x86 new_cpu_data;
32737 +-extern struct tss_struct doublefault_tss;
32738 +-DECLARE_PER_CPU(struct tss_struct, init_tss);
32739 +
32740 + #ifdef CONFIG_SMP
32741 + extern struct cpuinfo_x86 cpu_data[];
32742 +@@ -209,11 +207,19 @@ extern int bootloader_type;
32743 + */
32744 + #define TASK_SIZE (PAGE_OFFSET)
32745 +
32746 ++#ifdef CONFIG_PAX_SEGMEXEC
32747 ++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
32748 ++#endif
32749 ++
32750 + /* This decides where the kernel will search for a free chunk of vm
32751 + * space during mmap's.
32752 + */
32753 + #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
32754 +
32755 ++#ifdef CONFIG_PAX_SEGMEXEC
32756 ++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
32757 ++#endif
32758 ++
32759 + #define HAVE_ARCH_PICK_MMAP_LAYOUT
32760 +
32761 + extern void hard_disable_TSC(void);
32762 +@@ -338,6 +344,9 @@ struct tss_struct {
32763 +
32764 + #define ARCH_MIN_TASKALIGN 16
32765 +
32766 ++extern struct tss_struct doublefault_tss;
32767 ++extern struct tss_struct init_tss[NR_CPUS];
32768 ++
32769 + struct thread_struct {
32770 + /* cached TLS descriptors. */
32771 + struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
32772 +@@ -366,7 +375,7 @@ struct thread_struct {
32773 + };
32774 +
32775 + #define INIT_THREAD { \
32776 +- .esp0 = sizeof(init_stack) + (long)&init_stack, \
32777 ++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
32778 + .vm86_info = NULL, \
32779 + .sysenter_cs = __KERNEL_CS, \
32780 + .io_bitmap_ptr = NULL, \
32781 +@@ -381,7 +390,7 @@ struct thread_struct {
32782 + */
32783 + #define INIT_TSS { \
32784 + .x86_tss = { \
32785 +- .esp0 = sizeof(init_stack) + (long)&init_stack, \
32786 ++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
32787 + .ss0 = __KERNEL_DS, \
32788 + .ss1 = __KERNEL_CS, \
32789 + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
32790 +@@ -422,11 +431,7 @@ void show_trace(struct task_struct *task
32791 + unsigned long get_wchan(struct task_struct *p);
32792 +
32793 + #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
32794 +-#define KSTK_TOP(info) \
32795 +-({ \
32796 +- unsigned long *__ptr = (unsigned long *)(info); \
32797 +- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
32798 +-})
32799 ++#define KSTK_TOP(info) ((info)->task.thread.esp0)
32800 +
32801 + /*
32802 + * The below -8 is to reserve 8 bytes on top of the ring0 stack.
32803 +@@ -441,7 +446,7 @@ unsigned long get_wchan(struct task_stru
32804 + #define task_pt_regs(task) \
32805 + ({ \
32806 + struct pt_regs *__regs__; \
32807 +- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
32808 ++ __regs__ = (struct pt_regs *)((task)->thread.esp0); \
32809 + __regs__ - 1; \
32810 + })
32811 +
32812 +@@ -603,8 +608,8 @@ static inline void cpuid(unsigned int op
32813 + }
32814 +
32815 + /* Some CPUID calls want 'count' to be placed in ecx */
32816 +-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
32817 +- int *edx)
32818 ++static inline void cpuid_count(unsigned int op, unsigned int count, unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
32819 ++ unsigned int *edx)
32820 + {
32821 + *eax = op;
32822 + *ecx = count;
32823 +diff -Nurp linux-2.6.23.15/include/asm-i386/ptrace.h linux-2.6.23.15-grsec/include/asm-i386/ptrace.h
32824 +--- linux-2.6.23.15/include/asm-i386/ptrace.h 2007-10-09 21:31:38.000000000 +0100
32825 ++++ linux-2.6.23.15-grsec/include/asm-i386/ptrace.h 2008-02-11 10:37:44.000000000 +0000
32826 +@@ -35,17 +35,18 @@ struct task_struct;
32827 + extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
32828 +
32829 + /*
32830 +- * user_mode_vm(regs) determines whether a register set came from user mode.
32831 ++ * user_mode(regs) determines whether a register set came from user mode.
32832 + * This is true if V8086 mode was enabled OR if the register set was from
32833 + * protected mode with RPL-3 CS value. This tricky test checks that with
32834 + * one comparison. Many places in the kernel can bypass this full check
32835 +- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
32836 ++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
32837 ++ * be used.
32838 + */
32839 +-static inline int user_mode(struct pt_regs *regs)
32840 ++static inline int user_mode_novm(struct pt_regs *regs)
32841 + {
32842 + return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
32843 + }
32844 +-static inline int user_mode_vm(struct pt_regs *regs)
32845 ++static inline int user_mode(struct pt_regs *regs)
32846 + {
32847 + return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
32848 + }
32849 +diff -Nurp linux-2.6.23.15/include/asm-i386/reboot.h linux-2.6.23.15-grsec/include/asm-i386/reboot.h
32850 +--- linux-2.6.23.15/include/asm-i386/reboot.h 2007-10-09 21:31:38.000000000 +0100
32851 ++++ linux-2.6.23.15-grsec/include/asm-i386/reboot.h 2008-02-11 10:37:44.000000000 +0000
32852 +@@ -15,6 +15,6 @@ struct machine_ops
32853 +
32854 + extern struct machine_ops machine_ops;
32855 +
32856 +-void machine_real_restart(unsigned char *code, int length);
32857 ++void machine_real_restart(const unsigned char *code, unsigned int length);
32858 +
32859 + #endif /* _ASM_REBOOT_H */
32860 +diff -Nurp linux-2.6.23.15/include/asm-i386/segment.h linux-2.6.23.15-grsec/include/asm-i386/segment.h
32861 +--- linux-2.6.23.15/include/asm-i386/segment.h 2007-10-09 21:31:38.000000000 +0100
32862 ++++ linux-2.6.23.15-grsec/include/asm-i386/segment.h 2008-02-11 10:37:44.000000000 +0000
32863 +@@ -81,6 +81,12 @@
32864 + #define __KERNEL_PERCPU 0
32865 + #endif
32866 +
32867 ++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
32868 ++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
32869 ++
32870 ++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
32871 ++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
32872 ++
32873 + #define GDT_ENTRY_DOUBLEFAULT_TSS 31
32874 +
32875 + /*
32876 +@@ -140,9 +146,9 @@
32877 + #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
32878 +
32879 + /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
32880 +-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
32881 ++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
32882 +
32883 + /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
32884 +-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
32885 ++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
32886 +
32887 + #endif
32888 +diff -Nurp linux-2.6.23.15/include/asm-i386/system.h linux-2.6.23.15-grsec/include/asm-i386/system.h
32889 +--- linux-2.6.23.15/include/asm-i386/system.h 2008-02-11 10:36:03.000000000 +0000
32890 ++++ linux-2.6.23.15-grsec/include/asm-i386/system.h 2008-02-11 10:37:44.000000000 +0000
32891 +@@ -183,6 +183,21 @@ static inline void native_wbinvd(void)
32892 + /* Set the 'TS' bit */
32893 + #define stts() write_cr0(8 | read_cr0())
32894 +
32895 ++#define pax_open_kernel(cr0) \
32896 ++do { \
32897 ++ typecheck(unsigned long, cr0); \
32898 ++ preempt_disable(); \
32899 ++ cr0 = read_cr0(); \
32900 ++ write_cr0(cr0 & ~X86_CR0_WP); \
32901 ++} while (0)
32902 ++
32903 ++#define pax_close_kernel(cr0) \
32904 ++do { \
32905 ++ typecheck(unsigned long, cr0); \
32906 ++ write_cr0(cr0); \
32907 ++ preempt_enable_no_resched(); \
32908 ++} while (0)
32909 ++
32910 + #endif /* __KERNEL__ */
32911 +
32912 + static inline unsigned long get_limit(unsigned long segment)
32913 +@@ -190,7 +205,7 @@ static inline unsigned long get_limit(un
32914 + unsigned long __limit;
32915 + __asm__("lsll %1,%0"
32916 + :"=r" (__limit):"r" (segment));
32917 +- return __limit+1;
32918 ++ return __limit;
32919 + }
32920 +
32921 + #define nop() __asm__ __volatile__ ("nop")
32922 +@@ -305,7 +320,7 @@ void enable_hlt(void);
32923 + extern int es7000_plat;
32924 + void cpu_idle_wait(void);
32925 +
32926 +-extern unsigned long arch_align_stack(unsigned long sp);
32927 ++#define arch_align_stack(x) (x)
32928 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
32929 +
32930 + void default_idle(void);
32931 +diff -Nurp linux-2.6.23.15/include/asm-i386/uaccess.h linux-2.6.23.15-grsec/include/asm-i386/uaccess.h
32932 +--- linux-2.6.23.15/include/asm-i386/uaccess.h 2007-10-09 21:31:38.000000000 +0100
32933 ++++ linux-2.6.23.15-grsec/include/asm-i386/uaccess.h 2008-02-11 10:37:44.000000000 +0000
32934 +@@ -9,6 +9,7 @@
32935 + #include <linux/prefetch.h>
32936 + #include <linux/string.h>
32937 + #include <asm/page.h>
32938 ++#include <asm/segment.h>
32939 +
32940 + #define VERIFY_READ 0
32941 + #define VERIFY_WRITE 1
32942 +@@ -29,7 +30,8 @@
32943 +
32944 + #define get_ds() (KERNEL_DS)
32945 + #define get_fs() (current_thread_info()->addr_limit)
32946 +-#define set_fs(x) (current_thread_info()->addr_limit = (x))
32947 ++void __set_fs(mm_segment_t x, int cpu);
32948 ++void set_fs(mm_segment_t x);
32949 +
32950 + #define segment_eq(a,b) ((a).seg == (b).seg)
32951 +
32952 +@@ -101,6 +103,7 @@ struct exception_table_entry
32953 + };
32954 +
32955 + extern int fixup_exception(struct pt_regs *regs);
32956 ++#define ARCH_HAS_SORT_EXTABLE
32957 +
32958 + /*
32959 + * These are the main single-value transfer routines. They automatically
32960 +@@ -280,9 +283,12 @@ extern void __put_user_8(void);
32961 +
32962 + #define __put_user_u64(x, addr, err) \
32963 + __asm__ __volatile__( \
32964 +- "1: movl %%eax,0(%2)\n" \
32965 +- "2: movl %%edx,4(%2)\n" \
32966 ++ " movw %w5,%%ds\n" \
32967 ++ "1: movl %%eax,%%ds:0(%2)\n" \
32968 ++ "2: movl %%edx,%%ds:4(%2)\n" \
32969 + "3:\n" \
32970 ++ " pushl %%ss\n" \
32971 ++ " popl %%ds\n" \
32972 + ".section .fixup,\"ax\"\n" \
32973 + "4: movl %3,%0\n" \
32974 + " jmp 3b\n" \
32975 +@@ -293,7 +299,8 @@ extern void __put_user_8(void);
32976 + " .long 2b,4b\n" \
32977 + ".previous" \
32978 + : "=r"(err) \
32979 +- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
32980 ++ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
32981 ++ "r"(__USER_DS))
32982 +
32983 + #ifdef CONFIG_X86_WP_WORKS_OK
32984 +
32985 +@@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
32986 + */
32987 + #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
32988 + __asm__ __volatile__( \
32989 +- "1: mov"itype" %"rtype"1,%2\n" \
32990 ++ " movw %w5,%%ds\n" \
32991 ++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
32992 + "2:\n" \
32993 ++ " pushl %%ss\n" \
32994 ++ " popl %%ds\n" \
32995 + ".section .fixup,\"ax\"\n" \
32996 + "3: movl %3,%0\n" \
32997 + " jmp 2b\n" \
32998 +@@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
32999 + " .long 1b,3b\n" \
33000 + ".previous" \
33001 + : "=r"(err) \
33002 +- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
33003 ++ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
33004 ++ "r"(__USER_DS))
33005 +
33006 +
33007 + #define __get_user_nocheck(x,ptr,size) \
33008 +@@ -371,8 +382,11 @@ do { \
33009 +
33010 + #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
33011 + __asm__ __volatile__( \
33012 +- "1: mov"itype" %2,%"rtype"1\n" \
33013 ++ " movw %w5,%%ds\n" \
33014 ++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
33015 + "2:\n" \
33016 ++ " pushl %%ss\n" \
33017 ++ " popl %%ds\n" \
33018 + ".section .fixup,\"ax\"\n" \
33019 + "3: movl %3,%0\n" \
33020 + " xor"itype" %"rtype"1,%"rtype"1\n" \
33021 +@@ -383,7 +397,7 @@ do { \
33022 + " .long 1b,3b\n" \
33023 + ".previous" \
33024 + : "=r"(err), ltype (x) \
33025 +- : "m"(__m(addr)), "i"(errret), "0"(err))
33026 ++ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
33027 +
33028 +
33029 + unsigned long __must_check __copy_to_user_ll(void __user *to,
33030 +diff -Nurp linux-2.6.23.15/include/asm-ia64/elf.h linux-2.6.23.15-grsec/include/asm-ia64/elf.h
33031 +--- linux-2.6.23.15/include/asm-ia64/elf.h 2007-10-09 21:31:38.000000000 +0100
33032 ++++ linux-2.6.23.15-grsec/include/asm-ia64/elf.h 2008-02-11 10:37:44.000000000 +0000
33033 +@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
33034 + typedef struct ia64_fpreg elf_fpreg_t;
33035 + typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
33036 +
33037 ++#ifdef CONFIG_PAX_ASLR
33038 ++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
33039 +
33040 ++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
33041 ++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
33042 ++#endif
33043 +
33044 + struct pt_regs; /* forward declaration... */
33045 + extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
33046 +diff -Nurp linux-2.6.23.15/include/asm-ia64/kmap_types.h linux-2.6.23.15-grsec/include/asm-ia64/kmap_types.h
33047 +--- linux-2.6.23.15/include/asm-ia64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33048 ++++ linux-2.6.23.15-grsec/include/asm-ia64/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33049 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
33050 + D(10) KM_IRQ1,
33051 + D(11) KM_SOFTIRQ0,
33052 + D(12) KM_SOFTIRQ1,
33053 +-D(13) KM_TYPE_NR
33054 ++D(13) KM_CLEARPAGE,
33055 ++D(14) KM_TYPE_NR
33056 + };
33057 +
33058 + #undef D
33059 +diff -Nurp linux-2.6.23.15/include/asm-ia64/pgtable.h linux-2.6.23.15-grsec/include/asm-ia64/pgtable.h
33060 +--- linux-2.6.23.15/include/asm-ia64/pgtable.h 2007-10-09 21:31:38.000000000 +0100
33061 ++++ linux-2.6.23.15-grsec/include/asm-ia64/pgtable.h 2008-02-11 10:37:44.000000000 +0000
33062 +@@ -143,6 +143,17 @@
33063 + #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
33064 + #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
33065 + #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
33066 ++
33067 ++#ifdef CONFIG_PAX_PAGEEXEC
33068 ++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
33069 ++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
33070 ++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
33071 ++#else
33072 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
33073 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
33074 ++# define PAGE_COPY_NOEXEC PAGE_COPY
33075 ++#endif
33076 ++
33077 + #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
33078 + #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
33079 + #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
33080 +diff -Nurp linux-2.6.23.15/include/asm-ia64/processor.h linux-2.6.23.15-grsec/include/asm-ia64/processor.h
33081 +--- linux-2.6.23.15/include/asm-ia64/processor.h 2007-10-09 21:31:38.000000000 +0100
33082 ++++ linux-2.6.23.15-grsec/include/asm-ia64/processor.h 2008-02-11 10:37:44.000000000 +0000
33083 +@@ -275,7 +275,7 @@ struct thread_struct {
33084 + .on_ustack = 0, \
33085 + .ksp = 0, \
33086 + .map_base = DEFAULT_MAP_BASE, \
33087 +- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
33088 ++ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
33089 + .task_size = DEFAULT_TASK_SIZE, \
33090 + .last_fph_cpu = -1, \
33091 + INIT_THREAD_IA32 \
33092 +diff -Nurp linux-2.6.23.15/include/asm-ia64/ustack.h linux-2.6.23.15-grsec/include/asm-ia64/ustack.h
33093 +--- linux-2.6.23.15/include/asm-ia64/ustack.h 2007-10-09 21:31:38.000000000 +0100
33094 ++++ linux-2.6.23.15-grsec/include/asm-ia64/ustack.h 2008-02-11 10:37:44.000000000 +0000
33095 +@@ -10,8 +10,8 @@
33096 +
33097 + /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
33098 + #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
33099 +-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
33100 +-#define STACK_TOP_MAX STACK_TOP
33101 ++#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
33102 ++#define STACK_TOP_MAX __STACK_TOP
33103 + #endif
33104 +
33105 + /* Make a default stack size of 2GiB */
33106 +diff -Nurp linux-2.6.23.15/include/asm-m32r/kmap_types.h linux-2.6.23.15-grsec/include/asm-m32r/kmap_types.h
33107 +--- linux-2.6.23.15/include/asm-m32r/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33108 ++++ linux-2.6.23.15-grsec/include/asm-m32r/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33109 +@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
33110 + D(10) KM_IRQ1,
33111 + D(11) KM_SOFTIRQ0,
33112 + D(12) KM_SOFTIRQ1,
33113 +-D(13) KM_TYPE_NR
33114 ++D(13) KM_CLEARPAGE,
33115 ++D(14) KM_TYPE_NR
33116 + };
33117 +
33118 + #undef D
33119 +diff -Nurp linux-2.6.23.15/include/asm-m68k/kmap_types.h linux-2.6.23.15-grsec/include/asm-m68k/kmap_types.h
33120 +--- linux-2.6.23.15/include/asm-m68k/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33121 ++++ linux-2.6.23.15-grsec/include/asm-m68k/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33122 +@@ -15,6 +15,7 @@ enum km_type {
33123 + KM_IRQ1,
33124 + KM_SOFTIRQ0,
33125 + KM_SOFTIRQ1,
33126 ++ KM_CLEARPAGE,
33127 + KM_TYPE_NR
33128 + };
33129 +
33130 +diff -Nurp linux-2.6.23.15/include/asm-m68knommu/kmap_types.h linux-2.6.23.15-grsec/include/asm-m68knommu/kmap_types.h
33131 +--- linux-2.6.23.15/include/asm-m68knommu/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33132 ++++ linux-2.6.23.15-grsec/include/asm-m68knommu/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33133 +@@ -15,6 +15,7 @@ enum km_type {
33134 + KM_IRQ1,
33135 + KM_SOFTIRQ0,
33136 + KM_SOFTIRQ1,
33137 ++ KM_CLEARPAGE,
33138 + KM_TYPE_NR
33139 + };
33140 +
33141 +diff -Nurp linux-2.6.23.15/include/asm-mips/a.out.h linux-2.6.23.15-grsec/include/asm-mips/a.out.h
33142 +--- linux-2.6.23.15/include/asm-mips/a.out.h 2007-10-09 21:31:38.000000000 +0100
33143 ++++ linux-2.6.23.15-grsec/include/asm-mips/a.out.h 2008-02-11 10:37:44.000000000 +0000
33144 +@@ -35,10 +35,10 @@ struct exec
33145 + #ifdef __KERNEL__
33146 +
33147 + #ifdef CONFIG_32BIT
33148 +-#define STACK_TOP TASK_SIZE
33149 ++#define __STACK_TOP TASK_SIZE
33150 + #endif
33151 + #ifdef CONFIG_64BIT
33152 +-#define STACK_TOP \
33153 ++#define __STACK_TOP \
33154 + (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
33155 + #endif
33156 + #define STACK_TOP_MAX TASK_SIZE
33157 +diff -Nurp linux-2.6.23.15/include/asm-mips/elf.h linux-2.6.23.15-grsec/include/asm-mips/elf.h
33158 +--- linux-2.6.23.15/include/asm-mips/elf.h 2007-10-09 21:31:38.000000000 +0100
33159 ++++ linux-2.6.23.15-grsec/include/asm-mips/elf.h 2008-02-11 10:37:44.000000000 +0000
33160 +@@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str
33161 + #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
33162 + #endif
33163 +
33164 ++#ifdef CONFIG_PAX_ASLR
33165 ++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
33166 ++
33167 ++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
33168 ++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
33169 ++#endif
33170 ++
33171 + #endif /* _ASM_ELF_H */
33172 +diff -Nurp linux-2.6.23.15/include/asm-mips/kmap_types.h linux-2.6.23.15-grsec/include/asm-mips/kmap_types.h
33173 +--- linux-2.6.23.15/include/asm-mips/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33174 ++++ linux-2.6.23.15-grsec/include/asm-mips/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33175 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
33176 + D(10) KM_IRQ1,
33177 + D(11) KM_SOFTIRQ0,
33178 + D(12) KM_SOFTIRQ1,
33179 +-D(13) KM_TYPE_NR
33180 ++D(13) KM_CLEARPAGE,
33181 ++D(14) KM_TYPE_NR
33182 + };
33183 +
33184 + #undef D
33185 +diff -Nurp linux-2.6.23.15/include/asm-mips/page.h linux-2.6.23.15-grsec/include/asm-mips/page.h
33186 +--- linux-2.6.23.15/include/asm-mips/page.h 2007-10-09 21:31:38.000000000 +0100
33187 ++++ linux-2.6.23.15-grsec/include/asm-mips/page.h 2008-02-11 10:37:44.000000000 +0000
33188 +@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
33189 + #ifdef CONFIG_CPU_MIPS32
33190 + typedef struct { unsigned long pte_low, pte_high; } pte_t;
33191 + #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
33192 +- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
33193 ++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
33194 + #else
33195 + typedef struct { unsigned long long pte; } pte_t;
33196 + #define pte_val(x) ((x).pte)
33197 +diff -Nurp linux-2.6.23.15/include/asm-mips/system.h linux-2.6.23.15-grsec/include/asm-mips/system.h
33198 +--- linux-2.6.23.15/include/asm-mips/system.h 2007-10-09 21:31:38.000000000 +0100
33199 ++++ linux-2.6.23.15-grsec/include/asm-mips/system.h 2008-02-11 10:37:44.000000000 +0000
33200 +@@ -213,6 +213,6 @@ extern int stop_a_enabled;
33201 + */
33202 + #define __ARCH_WANT_UNLOCKED_CTXSW
33203 +
33204 +-extern unsigned long arch_align_stack(unsigned long sp);
33205 ++#define arch_align_stack(x) (x)
33206 +
33207 + #endif /* _ASM_SYSTEM_H */
33208 +diff -Nurp linux-2.6.23.15/include/asm-parisc/a.out.h linux-2.6.23.15-grsec/include/asm-parisc/a.out.h
33209 +--- linux-2.6.23.15/include/asm-parisc/a.out.h 2007-10-09 21:31:38.000000000 +0100
33210 ++++ linux-2.6.23.15-grsec/include/asm-parisc/a.out.h 2008-02-11 10:37:44.000000000 +0000
33211 +@@ -22,7 +22,7 @@ struct exec
33212 + /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
33213 + * prumpf */
33214 +
33215 +-#define STACK_TOP TASK_SIZE
33216 ++#define __STACK_TOP TASK_SIZE
33217 + #define STACK_TOP_MAX DEFAULT_TASK_SIZE
33218 +
33219 + #endif
33220 +diff -Nurp linux-2.6.23.15/include/asm-parisc/elf.h linux-2.6.23.15-grsec/include/asm-parisc/elf.h
33221 +--- linux-2.6.23.15/include/asm-parisc/elf.h 2007-10-09 21:31:38.000000000 +0100
33222 ++++ linux-2.6.23.15-grsec/include/asm-parisc/elf.h 2008-02-11 10:37:44.000000000 +0000
33223 +@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
33224 +
33225 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
33226 +
33227 ++#ifdef CONFIG_PAX_ASLR
33228 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
33229 ++
33230 ++#define PAX_DELTA_MMAP_LEN 16
33231 ++#define PAX_DELTA_STACK_LEN 16
33232 ++#endif
33233 ++
33234 + /* This yields a mask that user programs can use to figure out what
33235 + instruction set this CPU supports. This could be done in user space,
33236 + but it's not easy, and we've already done it here. */
33237 +diff -Nurp linux-2.6.23.15/include/asm-parisc/kmap_types.h linux-2.6.23.15-grsec/include/asm-parisc/kmap_types.h
33238 +--- linux-2.6.23.15/include/asm-parisc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33239 ++++ linux-2.6.23.15-grsec/include/asm-parisc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33240 +@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
33241 + D(10) KM_IRQ1,
33242 + D(11) KM_SOFTIRQ0,
33243 + D(12) KM_SOFTIRQ1,
33244 +-D(13) KM_TYPE_NR
33245 ++D(13) KM_CLEARPAGE,
33246 ++D(14) KM_TYPE_NR
33247 + };
33248 +
33249 + #undef D
33250 +diff -Nurp linux-2.6.23.15/include/asm-parisc/pgtable.h linux-2.6.23.15-grsec/include/asm-parisc/pgtable.h
33251 +--- linux-2.6.23.15/include/asm-parisc/pgtable.h 2007-10-09 21:31:38.000000000 +0100
33252 ++++ linux-2.6.23.15-grsec/include/asm-parisc/pgtable.h 2008-02-11 10:37:44.000000000 +0000
33253 +@@ -218,6 +218,17 @@ extern void *vmalloc_start;
33254 + #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
33255 + #define PAGE_COPY PAGE_EXECREAD
33256 + #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
33257 ++
33258 ++#ifdef CONFIG_PAX_PAGEEXEC
33259 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
33260 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
33261 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
33262 ++#else
33263 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
33264 ++# define PAGE_COPY_NOEXEC PAGE_COPY
33265 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
33266 ++#endif
33267 ++
33268 + #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
33269 + #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
33270 + #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
33271 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/a.out.h linux-2.6.23.15-grsec/include/asm-powerpc/a.out.h
33272 +--- linux-2.6.23.15/include/asm-powerpc/a.out.h 2007-10-09 21:31:38.000000000 +0100
33273 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/a.out.h 2008-02-11 10:37:44.000000000 +0000
33274 +@@ -23,15 +23,15 @@ struct exec
33275 + #define STACK_TOP_USER64 TASK_SIZE_USER64
33276 + #define STACK_TOP_USER32 TASK_SIZE_USER32
33277 +
33278 +-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
33279 ++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
33280 + STACK_TOP_USER32 : STACK_TOP_USER64)
33281 +
33282 + #define STACK_TOP_MAX STACK_TOP_USER64
33283 +
33284 + #else /* __powerpc64__ */
33285 +
33286 +-#define STACK_TOP TASK_SIZE
33287 +-#define STACK_TOP_MAX STACK_TOP
33288 ++#define __STACK_TOP TASK_SIZE
33289 ++#define STACK_TOP_MAX __STACK_TOP
33290 +
33291 + #endif /* __powerpc64__ */
33292 + #endif /* __KERNEL__ */
33293 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/elf.h linux-2.6.23.15-grsec/include/asm-powerpc/elf.h
33294 +--- linux-2.6.23.15/include/asm-powerpc/elf.h 2007-10-09 21:31:38.000000000 +0100
33295 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/elf.h 2008-02-11 10:37:44.000000000 +0000
33296 +@@ -159,6 +159,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
33297 + typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
33298 + #endif
33299 +
33300 ++#ifdef CONFIG_PAX_ASLR
33301 ++#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
33302 ++
33303 ++#ifdef __powerpc64__
33304 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
33305 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
33306 ++#else
33307 ++#define PAX_DELTA_MMAP_LEN 15
33308 ++#define PAX_DELTA_STACK_LEN 15
33309 ++#endif
33310 ++#endif
33311 ++
33312 + #ifdef __KERNEL__
33313 + /*
33314 + * This is used to ensure we don't load something for the wrong architecture.
33315 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/kmap_types.h linux-2.6.23.15-grsec/include/asm-powerpc/kmap_types.h
33316 +--- linux-2.6.23.15/include/asm-powerpc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33317 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33318 +@@ -26,6 +26,7 @@ enum km_type {
33319 + KM_SOFTIRQ1,
33320 + KM_PPC_SYNC_PAGE,
33321 + KM_PPC_SYNC_ICACHE,
33322 ++ KM_CLEARPAGE,
33323 + KM_TYPE_NR
33324 + };
33325 +
33326 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/page.h linux-2.6.23.15-grsec/include/asm-powerpc/page.h
33327 +--- linux-2.6.23.15/include/asm-powerpc/page.h 2007-10-09 21:31:38.000000000 +0100
33328 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/page.h 2008-02-11 10:37:44.000000000 +0000
33329 +@@ -71,8 +71,9 @@
33330 + * and needs to be executable. This means the whole heap ends
33331 + * up being executable.
33332 + */
33333 +-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
33334 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
33335 ++#define VM_DATA_DEFAULT_FLAGS32 \
33336 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
33337 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
33338 +
33339 + #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
33340 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
33341 +diff -Nurp linux-2.6.23.15/include/asm-powerpc/page_64.h linux-2.6.23.15-grsec/include/asm-powerpc/page_64.h
33342 +--- linux-2.6.23.15/include/asm-powerpc/page_64.h 2007-10-09 21:31:38.000000000 +0100
33343 ++++ linux-2.6.23.15-grsec/include/asm-powerpc/page_64.h 2008-02-11 10:37:44.000000000 +0000
33344 +@@ -158,15 +158,18 @@ extern int is_hugepage_only_range(struct
33345 + * stack by default, so in the absense of a PT_GNU_STACK program header
33346 + * we turn execute permission off.
33347 + */
33348 +-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
33349 +- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
33350 ++#define VM_STACK_DEFAULT_FLAGS32 \
33351 ++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
33352 ++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
33353 +
33354 + #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
33355 + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
33356 +
33357 ++#ifndef CONFIG_PAX_PAGEEXEC
33358 + #define VM_STACK_DEFAULT_FLAGS \
33359 + (test_thread_flag(TIF_32BIT) ? \
33360 + VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
33361 ++#endif
33362 +
33363 + #include <asm-generic/page.h>
33364 +
33365 +diff -Nurp linux-2.6.23.15/include/asm-ppc/mmu_context.h linux-2.6.23.15-grsec/include/asm-ppc/mmu_context.h
33366 +--- linux-2.6.23.15/include/asm-ppc/mmu_context.h 2007-10-09 21:31:38.000000000 +0100
33367 ++++ linux-2.6.23.15-grsec/include/asm-ppc/mmu_context.h 2008-02-11 10:37:44.000000000 +0000
33368 +@@ -145,7 +145,8 @@ static inline void get_mmu_context(struc
33369 + static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
33370 + {
33371 + mm->context.id = NO_CONTEXT;
33372 +- mm->context.vdso_base = 0;
33373 ++ if (t == current)
33374 ++ mm->context.vdso_base = ~0UL;
33375 + return 0;
33376 + }
33377 +
33378 +diff -Nurp linux-2.6.23.15/include/asm-ppc/pgtable.h linux-2.6.23.15-grsec/include/asm-ppc/pgtable.h
33379 +--- linux-2.6.23.15/include/asm-ppc/pgtable.h 2007-10-09 21:31:38.000000000 +0100
33380 ++++ linux-2.6.23.15-grsec/include/asm-ppc/pgtable.h 2008-02-11 10:37:44.000000000 +0000
33381 +@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
33382 +
33383 + #define PAGE_NONE __pgprot(_PAGE_BASE)
33384 + #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
33385 +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
33386 ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
33387 + #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
33388 +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
33389 ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
33390 + #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
33391 +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
33392 ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
33393 ++
33394 ++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
33395 ++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
33396 ++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
33397 ++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
33398 ++#else
33399 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
33400 ++# define PAGE_COPY_NOEXEC PAGE_COPY
33401 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
33402 ++#endif
33403 +
33404 + #define PAGE_KERNEL __pgprot(_PAGE_RAM)
33405 + #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
33406 +@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
33407 + * This is the closest we can get..
33408 + */
33409 + #define __P000 PAGE_NONE
33410 +-#define __P001 PAGE_READONLY_X
33411 +-#define __P010 PAGE_COPY
33412 +-#define __P011 PAGE_COPY_X
33413 +-#define __P100 PAGE_READONLY
33414 ++#define __P001 PAGE_READONLY_NOEXEC
33415 ++#define __P010 PAGE_COPY_NOEXEC
33416 ++#define __P011 PAGE_COPY_NOEXEC
33417 ++#define __P100 PAGE_READONLY_X
33418 + #define __P101 PAGE_READONLY_X
33419 +-#define __P110 PAGE_COPY
33420 ++#define __P110 PAGE_COPY_X
33421 + #define __P111 PAGE_COPY_X
33422 +
33423 + #define __S000 PAGE_NONE
33424 +-#define __S001 PAGE_READONLY_X
33425 +-#define __S010 PAGE_SHARED
33426 +-#define __S011 PAGE_SHARED_X
33427 +-#define __S100 PAGE_READONLY
33428 ++#define __S001 PAGE_READONLY_NOEXEC
33429 ++#define __S010 PAGE_SHARED_NOEXEC
33430 ++#define __S011 PAGE_SHARED_NOEXEC
33431 ++#define __S100 PAGE_READONLY_X
33432 + #define __S101 PAGE_READONLY_X
33433 +-#define __S110 PAGE_SHARED
33434 ++#define __S110 PAGE_SHARED_X
33435 + #define __S111 PAGE_SHARED_X
33436 +
33437 + #ifndef __ASSEMBLY__
33438 +diff -Nurp linux-2.6.23.15/include/asm-s390/kmap_types.h linux-2.6.23.15-grsec/include/asm-s390/kmap_types.h
33439 +--- linux-2.6.23.15/include/asm-s390/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33440 ++++ linux-2.6.23.15-grsec/include/asm-s390/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33441 +@@ -16,6 +16,7 @@ enum km_type {
33442 + KM_IRQ1,
33443 + KM_SOFTIRQ0,
33444 + KM_SOFTIRQ1,
33445 ++ KM_CLEARPAGE,
33446 + KM_TYPE_NR
33447 + };
33448 +
33449 +diff -Nurp linux-2.6.23.15/include/asm-sh/kmap_types.h linux-2.6.23.15-grsec/include/asm-sh/kmap_types.h
33450 +--- linux-2.6.23.15/include/asm-sh/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33451 ++++ linux-2.6.23.15-grsec/include/asm-sh/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33452 +@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
33453 + D(10) KM_IRQ1,
33454 + D(11) KM_SOFTIRQ0,
33455 + D(12) KM_SOFTIRQ1,
33456 +-D(13) KM_TYPE_NR
33457 ++D(13) KM_CLEARPAGE,
33458 ++D(14) KM_TYPE_NR
33459 + };
33460 +
33461 + #undef D
33462 +diff -Nurp linux-2.6.23.15/include/asm-sparc/a.out.h linux-2.6.23.15-grsec/include/asm-sparc/a.out.h
33463 +--- linux-2.6.23.15/include/asm-sparc/a.out.h 2007-10-09 21:31:38.000000000 +0100
33464 ++++ linux-2.6.23.15-grsec/include/asm-sparc/a.out.h 2008-02-11 10:37:44.000000000 +0000
33465 +@@ -91,8 +91,8 @@ struct relocation_info /* used when head
33466 +
33467 + #include <asm/page.h>
33468 +
33469 +-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
33470 +-#define STACK_TOP_MAX STACK_TOP
33471 ++#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
33472 ++#define STACK_TOP_MAX __STACK_TOP
33473 +
33474 + #endif /* __KERNEL__ */
33475 +
33476 +diff -Nurp linux-2.6.23.15/include/asm-sparc/elf.h linux-2.6.23.15-grsec/include/asm-sparc/elf.h
33477 +--- linux-2.6.23.15/include/asm-sparc/elf.h 2007-10-09 21:31:38.000000000 +0100
33478 ++++ linux-2.6.23.15-grsec/include/asm-sparc/elf.h 2008-02-11 10:37:44.000000000 +0000
33479 +@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
33480 +
33481 + #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
33482 +
33483 ++#ifdef CONFIG_PAX_ASLR
33484 ++#define PAX_ELF_ET_DYN_BASE 0x10000UL
33485 ++
33486 ++#define PAX_DELTA_MMAP_LEN 16
33487 ++#define PAX_DELTA_STACK_LEN 16
33488 ++#endif
33489 ++
33490 + /* This yields a mask that user programs can use to figure out what
33491 + instruction set this cpu supports. This can NOT be done in userspace
33492 + on Sparc. */
33493 +diff -Nurp linux-2.6.23.15/include/asm-sparc/kmap_types.h linux-2.6.23.15-grsec/include/asm-sparc/kmap_types.h
33494 +--- linux-2.6.23.15/include/asm-sparc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33495 ++++ linux-2.6.23.15-grsec/include/asm-sparc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33496 +@@ -15,6 +15,7 @@ enum km_type {
33497 + KM_IRQ1,
33498 + KM_SOFTIRQ0,
33499 + KM_SOFTIRQ1,
33500 ++ KM_CLEARPAGE,
33501 + KM_TYPE_NR
33502 + };
33503 +
33504 +diff -Nurp linux-2.6.23.15/include/asm-sparc/pgtable.h linux-2.6.23.15-grsec/include/asm-sparc/pgtable.h
33505 +--- linux-2.6.23.15/include/asm-sparc/pgtable.h 2007-10-09 21:31:38.000000000 +0100
33506 ++++ linux-2.6.23.15-grsec/include/asm-sparc/pgtable.h 2008-02-11 10:37:44.000000000 +0000
33507 +@@ -69,6 +69,16 @@ extern pgprot_t PAGE_SHARED;
33508 + #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
33509 + #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
33510 +
33511 ++#ifdef CONFIG_PAX_PAGEEXEC
33512 ++extern pgprot_t PAGE_SHARED_NOEXEC;
33513 ++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
33514 ++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
33515 ++#else
33516 ++# define PAGE_SHARED_NOEXEC PAGE_SHARED
33517 ++# define PAGE_COPY_NOEXEC PAGE_COPY
33518 ++# define PAGE_READONLY_NOEXEC PAGE_READONLY
33519 ++#endif
33520 ++
33521 + extern unsigned long page_kernel;
33522 +
33523 + #ifdef MODULE
33524 +diff -Nurp linux-2.6.23.15/include/asm-sparc/pgtsrmmu.h linux-2.6.23.15-grsec/include/asm-sparc/pgtsrmmu.h
33525 +--- linux-2.6.23.15/include/asm-sparc/pgtsrmmu.h 2007-10-09 21:31:38.000000000 +0100
33526 ++++ linux-2.6.23.15-grsec/include/asm-sparc/pgtsrmmu.h 2008-02-11 10:37:44.000000000 +0000
33527 +@@ -115,6 +115,16 @@
33528 + SRMMU_EXEC | SRMMU_REF)
33529 + #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
33530 + SRMMU_EXEC | SRMMU_REF)
33531 ++
33532 ++#ifdef CONFIG_PAX_PAGEEXEC
33533 ++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
33534 ++ SRMMU_WRITE | SRMMU_REF)
33535 ++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
33536 ++ SRMMU_REF)
33537 ++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
33538 ++ SRMMU_REF)
33539 ++#endif
33540 ++
33541 + #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
33542 + SRMMU_DIRTY | SRMMU_REF)
33543 +
33544 +diff -Nurp linux-2.6.23.15/include/asm-sparc/uaccess.h linux-2.6.23.15-grsec/include/asm-sparc/uaccess.h
33545 +--- linux-2.6.23.15/include/asm-sparc/uaccess.h 2007-10-09 21:31:38.000000000 +0100
33546 ++++ linux-2.6.23.15-grsec/include/asm-sparc/uaccess.h 2008-02-11 10:37:44.000000000 +0000
33547 +@@ -41,7 +41,7 @@
33548 + * No one can read/write anything from userland in the kernel space by setting
33549 + * large size and address near to PAGE_OFFSET - a fault will break his intentions.
33550 + */
33551 +-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
33552 ++#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
33553 + #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
33554 + #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
33555 + #define access_ok(type, addr, size) \
33556 +diff -Nurp linux-2.6.23.15/include/asm-sparc64/a.out.h linux-2.6.23.15-grsec/include/asm-sparc64/a.out.h
33557 +--- linux-2.6.23.15/include/asm-sparc64/a.out.h 2007-10-09 21:31:38.000000000 +0100
33558 ++++ linux-2.6.23.15-grsec/include/asm-sparc64/a.out.h 2008-02-11 10:37:44.000000000 +0000
33559 +@@ -98,7 +98,7 @@ struct relocation_info /* used when head
33560 + #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
33561 + #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
33562 +
33563 +-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
33564 ++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
33565 + STACK_TOP32 : STACK_TOP64)
33566 +
33567 + #define STACK_TOP_MAX STACK_TOP64
33568 +diff -Nurp linux-2.6.23.15/include/asm-sparc64/elf.h linux-2.6.23.15-grsec/include/asm-sparc64/elf.h
33569 +--- linux-2.6.23.15/include/asm-sparc64/elf.h 2007-10-09 21:31:38.000000000 +0100
33570 ++++ linux-2.6.23.15-grsec/include/asm-sparc64/elf.h 2008-02-11 10:37:44.000000000 +0000
33571 +@@ -143,6 +143,12 @@ typedef struct {
33572 + #define ELF_ET_DYN_BASE 0x0000010000000000UL
33573 + #endif
33574 +
33575 ++#ifdef CONFIG_PAX_ASLR
33576 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
33577 ++
33578 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
33579 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
33580 ++#endif
33581 +
33582 + /* This yields a mask that user programs can use to figure out what
33583 + instruction set this cpu supports. */
33584 +diff -Nurp linux-2.6.23.15/include/asm-sparc64/kmap_types.h linux-2.6.23.15-grsec/include/asm-sparc64/kmap_types.h
33585 +--- linux-2.6.23.15/include/asm-sparc64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33586 ++++ linux-2.6.23.15-grsec/include/asm-sparc64/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33587 +@@ -19,6 +19,7 @@ enum km_type {
33588 + KM_IRQ1,
33589 + KM_SOFTIRQ0,
33590 + KM_SOFTIRQ1,
33591 ++ KM_CLEARPAGE,
33592 + KM_TYPE_NR
33593 + };
33594 +
33595 +diff -Nurp linux-2.6.23.15/include/asm-um/kmap_types.h linux-2.6.23.15-grsec/include/asm-um/kmap_types.h
33596 +--- linux-2.6.23.15/include/asm-um/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33597 ++++ linux-2.6.23.15-grsec/include/asm-um/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33598 +@@ -23,6 +23,7 @@ enum km_type {
33599 + KM_IRQ1,
33600 + KM_SOFTIRQ0,
33601 + KM_SOFTIRQ1,
33602 ++ KM_CLEARPAGE,
33603 + KM_TYPE_NR
33604 + };
33605 +
33606 +diff -Nurp linux-2.6.23.15/include/asm-v850/kmap_types.h linux-2.6.23.15-grsec/include/asm-v850/kmap_types.h
33607 +--- linux-2.6.23.15/include/asm-v850/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33608 ++++ linux-2.6.23.15-grsec/include/asm-v850/kmap_types.h 2008-02-11 10:37:44.000000000 +0000
33609 +@@ -13,6 +13,7 @@ enum km_type {
33610 + KM_PTE1,
33611 + KM_IRQ0,
33612 + KM_IRQ1,
33613 ++ KM_CLEARPAGE,
33614 + KM_TYPE_NR
33615 + };
33616 +
33617 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/a.out.h linux-2.6.23.15-grsec/include/asm-x86_64/a.out.h
33618 +--- linux-2.6.23.15/include/asm-x86_64/a.out.h 2007-10-09 21:31:38.000000000 +0100
33619 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/a.out.h 2008-02-11 10:37:45.000000000 +0000
33620 +@@ -21,7 +21,7 @@ struct exec
33621 +
33622 + #ifdef __KERNEL__
33623 + #include <linux/thread_info.h>
33624 +-#define STACK_TOP TASK_SIZE
33625 ++#define __STACK_TOP TASK_SIZE
33626 + #define STACK_TOP_MAX TASK_SIZE64
33627 + #endif
33628 +
33629 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/apic.h linux-2.6.23.15-grsec/include/asm-x86_64/apic.h
33630 +--- linux-2.6.23.15/include/asm-x86_64/apic.h 2007-10-09 21:31:38.000000000 +0100
33631 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/apic.h 2008-02-11 10:37:45.000000000 +0000
33632 +@@ -7,7 +7,7 @@
33633 + #include <asm/apicdef.h>
33634 + #include <asm/system.h>
33635 +
33636 +-#define Dprintk(x...)
33637 ++#define Dprintk(x...) do {} while (0)
33638 +
33639 + /*
33640 + * Debugging macros
33641 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/elf.h linux-2.6.23.15-grsec/include/asm-x86_64/elf.h
33642 +--- linux-2.6.23.15/include/asm-x86_64/elf.h 2007-10-09 21:31:38.000000000 +0100
33643 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/elf.h 2008-02-11 10:37:45.000000000 +0000
33644 +@@ -92,6 +92,13 @@ typedef struct user_i387_struct elf_fpre
33645 +
33646 + #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
33647 +
33648 ++#ifdef CONFIG_PAX_ASLR
33649 ++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
33650 ++
33651 ++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
33652 ++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
33653 ++#endif
33654 ++
33655 + /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
33656 + now struct_user_regs, they are different). Assumes current is the process
33657 + getting dumped. */
33658 +@@ -172,7 +179,7 @@ extern int vdso_enabled;
33659 +
33660 + #define ARCH_DLINFO \
33661 + do if (vdso_enabled) { \
33662 +- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
33663 ++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
33664 + } while (0)
33665 +
33666 + #endif
33667 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/futex.h linux-2.6.23.15-grsec/include/asm-x86_64/futex.h
33668 +--- linux-2.6.23.15/include/asm-x86_64/futex.h 2007-10-09 21:31:38.000000000 +0100
33669 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/futex.h 2008-02-11 10:37:45.000000000 +0000
33670 +@@ -42,7 +42,7 @@
33671 + : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
33672 +
33673 + static inline int
33674 +-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
33675 ++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
33676 + {
33677 + int op = (encoded_op >> 28) & 7;
33678 + int cmp = (encoded_op >> 24) & 15;
33679 +@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op,
33680 + }
33681 +
33682 + static inline int
33683 +-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
33684 ++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
33685 + {
33686 + if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
33687 + return -EFAULT;
33688 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/ia32.h linux-2.6.23.15-grsec/include/asm-x86_64/ia32.h
33689 +--- linux-2.6.23.15/include/asm-x86_64/ia32.h 2007-10-09 21:31:38.000000000 +0100
33690 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/ia32.h 2008-02-11 10:37:45.000000000 +0000
33691 +@@ -156,7 +156,13 @@ struct ustat32 {
33692 + char f_fpack[6];
33693 + };
33694 +
33695 +-#define IA32_STACK_TOP IA32_PAGE_OFFSET
33696 ++#ifdef CONFIG_PAX_RANDUSTACK
33697 ++#define IA32_DELTA_STACK (current->mm->delta_stack)
33698 ++#else
33699 ++#define IA32_DELTA_STACK 0UL
33700 ++#endif
33701 ++
33702 ++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
33703 +
33704 + #ifdef __KERNEL__
33705 + struct user_desc;
33706 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/kmap_types.h linux-2.6.23.15-grsec/include/asm-x86_64/kmap_types.h
33707 +--- linux-2.6.23.15/include/asm-x86_64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33708 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/kmap_types.h 2008-02-11 10:37:45.000000000 +0000
33709 +@@ -13,6 +13,7 @@ enum km_type {
33710 + KM_IRQ1,
33711 + KM_SOFTIRQ0,
33712 + KM_SOFTIRQ1,
33713 ++ KM_CLEARPAGE,
33714 + KM_TYPE_NR
33715 + };
33716 +
33717 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/mmu.h linux-2.6.23.15-grsec/include/asm-x86_64/mmu.h
33718 +--- linux-2.6.23.15/include/asm-x86_64/mmu.h 2007-10-09 21:31:38.000000000 +0100
33719 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/mmu.h 2008-02-11 10:37:45.000000000 +0000
33720 +@@ -15,7 +15,7 @@ typedef struct {
33721 + rwlock_t ldtlock;
33722 + int size;
33723 + struct semaphore sem;
33724 +- void *vdso;
33725 ++ unsigned long vdso;
33726 + } mm_context_t;
33727 +
33728 + #endif
33729 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/page.h linux-2.6.23.15-grsec/include/asm-x86_64/page.h
33730 +--- linux-2.6.23.15/include/asm-x86_64/page.h 2007-10-09 21:31:38.000000000 +0100
33731 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/page.h 2008-02-11 10:37:45.000000000 +0000
33732 +@@ -94,6 +94,8 @@ extern unsigned long phys_base;
33733 + #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
33734 + #define __PAGE_OFFSET _AC(0xffff810000000000, UL)
33735 +
33736 ++#define __KERNEL_TEXT_OFFSET (0)
33737 ++
33738 + /* to align the pointer to the (next) page boundary */
33739 + #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
33740 +
33741 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/pgalloc.h linux-2.6.23.15-grsec/include/asm-x86_64/pgalloc.h
33742 +--- linux-2.6.23.15/include/asm-x86_64/pgalloc.h 2007-10-09 21:31:38.000000000 +0100
33743 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/pgalloc.h 2008-02-11 10:37:45.000000000 +0000
33744 +@@ -6,7 +6,7 @@
33745 + #include <linux/mm.h>
33746 +
33747 + #define pmd_populate_kernel(mm, pmd, pte) \
33748 +- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
33749 ++ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
33750 + #define pud_populate(mm, pud, pmd) \
33751 + set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
33752 + #define pgd_populate(mm, pgd, pud) \
33753 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/pgtable.h linux-2.6.23.15-grsec/include/asm-x86_64/pgtable.h
33754 +--- linux-2.6.23.15/include/asm-x86_64/pgtable.h 2007-10-09 21:31:38.000000000 +0100
33755 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/pgtable.h 2008-02-11 10:37:45.000000000 +0000
33756 +@@ -179,6 +179,10 @@ static inline pte_t ptep_get_and_clear_f
33757 + #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
33758 + #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
33759 + #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
33760 ++
33761 ++#define PAGE_READONLY_NOEXEC PAGE_READONLY
33762 ++#define PAGE_SHARED_NOEXEC PAGE_SHARED
33763 ++
33764 + #define __PAGE_KERNEL \
33765 + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
33766 + #define __PAGE_KERNEL_EXEC \
33767 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/processor.h linux-2.6.23.15-grsec/include/asm-x86_64/processor.h
33768 +--- linux-2.6.23.15/include/asm-x86_64/processor.h 2007-10-09 21:31:38.000000000 +0100
33769 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/processor.h 2008-02-11 10:37:45.000000000 +0000
33770 +@@ -140,7 +140,7 @@ static inline void clear_in_cr4 (unsigne
33771 + /* This decides where the kernel will search for a free chunk of vm
33772 + * space during mmap's.
33773 + */
33774 +-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000)
33775 ++#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000)
33776 +
33777 + #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64)
33778 + #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64)
33779 +diff -Nurp linux-2.6.23.15/include/asm-x86_64/system.h linux-2.6.23.15-grsec/include/asm-x86_64/system.h
33780 +--- linux-2.6.23.15/include/asm-x86_64/system.h 2008-02-11 10:36:03.000000000 +0000
33781 ++++ linux-2.6.23.15-grsec/include/asm-x86_64/system.h 2008-02-11 10:37:45.000000000 +0000
33782 +@@ -174,7 +174,7 @@ static inline void write_cr8(unsigned lo
33783 +
33784 + void cpu_idle_wait(void);
33785 +
33786 +-extern unsigned long arch_align_stack(unsigned long sp);
33787 ++#define arch_align_stack(x) (x)
33788 + extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
33789 +
33790 + #endif
33791 +diff -Nurp linux-2.6.23.15/include/asm-xtensa/kmap_types.h linux-2.6.23.15-grsec/include/asm-xtensa/kmap_types.h
33792 +--- linux-2.6.23.15/include/asm-xtensa/kmap_types.h 2007-10-09 21:31:38.000000000 +0100
33793 ++++ linux-2.6.23.15-grsec/include/asm-xtensa/kmap_types.h 2008-02-11 10:37:45.000000000 +0000
33794 +@@ -25,6 +25,7 @@ enum km_type {
33795 + KM_IRQ1,
33796 + KM_SOFTIRQ0,
33797 + KM_SOFTIRQ1,
33798 ++ KM_CLEARPAGE,
33799 + KM_TYPE_NR
33800 + };
33801 +
33802 +diff -Nurp linux-2.6.23.15/include/linux/a.out.h linux-2.6.23.15-grsec/include/linux/a.out.h
33803 +--- linux-2.6.23.15/include/linux/a.out.h 2007-10-09 21:31:38.000000000 +0100
33804 ++++ linux-2.6.23.15-grsec/include/linux/a.out.h 2008-02-11 10:37:45.000000000 +0000
33805 +@@ -7,6 +7,16 @@
33806 +
33807 + #include <asm/a.out.h>
33808 +
33809 ++#ifdef CONFIG_PAX_RANDUSTACK
33810 ++#define __DELTA_STACK (current->mm->delta_stack)
33811 ++#else
33812 ++#define __DELTA_STACK 0UL
33813 ++#endif
33814 ++
33815 ++#ifndef STACK_TOP
33816 ++#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
33817 ++#endif
33818 ++
33819 + #endif /* __STRUCT_EXEC_OVERRIDE__ */
33820 +
33821 + /* these go in the N_MACHTYPE field */
33822 +@@ -37,6 +47,14 @@ enum machine_type {
33823 + M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
33824 + };
33825 +
33826 ++/* Constants for the N_FLAGS field */
33827 ++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
33828 ++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
33829 ++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
33830 ++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
33831 ++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
33832 ++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
33833 ++
33834 + #if !defined (N_MAGIC)
33835 + #define N_MAGIC(exec) ((exec).a_info & 0xffff)
33836 + #endif
33837 +diff -Nurp linux-2.6.23.15/include/linux/binfmts.h linux-2.6.23.15-grsec/include/linux/binfmts.h
33838 +--- linux-2.6.23.15/include/linux/binfmts.h 2007-10-09 21:31:38.000000000 +0100
33839 ++++ linux-2.6.23.15-grsec/include/linux/binfmts.h 2008-02-11 10:37:45.000000000 +0000
33840 +@@ -48,6 +48,7 @@ struct linux_binprm{
33841 + unsigned interp_data;
33842 + unsigned long loader, exec;
33843 + unsigned long argv_len;
33844 ++ int misc;
33845 + };
33846 +
33847 + #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
33848 +@@ -99,5 +100,8 @@ extern void compute_creds(struct linux_b
33849 + extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
33850 + extern int set_binfmt(struct linux_binfmt *new);
33851 +
33852 ++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
33853 ++void pax_report_insns(void *pc, void *sp);
33854 ++
33855 + #endif /* __KERNEL__ */
33856 + #endif /* _LINUX_BINFMTS_H */
33857 +diff -Nurp linux-2.6.23.15/include/linux/cache.h linux-2.6.23.15-grsec/include/linux/cache.h
33858 +--- linux-2.6.23.15/include/linux/cache.h 2007-10-09 21:31:38.000000000 +0100
33859 ++++ linux-2.6.23.15-grsec/include/linux/cache.h 2008-02-11 10:37:45.000000000 +0000
33860 +@@ -16,6 +16,10 @@
33861 + #define __read_mostly
33862 + #endif
33863 +
33864 ++#ifndef __read_only
33865 ++#define __read_only
33866 ++#endif
33867 ++
33868 + #ifndef ____cacheline_aligned
33869 + #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
33870 + #endif
33871 +diff -Nurp linux-2.6.23.15/include/linux/capability.h linux-2.6.23.15-grsec/include/linux/capability.h
33872 +--- linux-2.6.23.15/include/linux/capability.h 2007-10-09 21:31:38.000000000 +0100
33873 ++++ linux-2.6.23.15-grsec/include/linux/capability.h 2008-02-11 10:37:45.000000000 +0000
33874 +@@ -359,6 +359,7 @@ static inline kernel_cap_t cap_invert(ke
33875 + #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
33876 +
33877 + int capable(int cap);
33878 ++int capable_nolog(int cap);
33879 + int __capable(struct task_struct *t, int cap);
33880 +
33881 + #endif /* __KERNEL__ */
33882 +diff -Nurp linux-2.6.23.15/include/linux/elf.h linux-2.6.23.15-grsec/include/linux/elf.h
33883 +--- linux-2.6.23.15/include/linux/elf.h 2007-10-09 21:31:38.000000000 +0100
33884 ++++ linux-2.6.23.15-grsec/include/linux/elf.h 2008-02-11 10:37:45.000000000 +0000
33885 +@@ -8,6 +8,10 @@
33886 +
33887 + struct file;
33888 +
33889 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
33890 ++#undef elf_read_implies_exec
33891 ++#endif
33892 ++
33893 + #ifndef elf_read_implies_exec
33894 + /* Executables for which elf_read_implies_exec() returns TRUE will
33895 + have the READ_IMPLIES_EXEC personality flag set automatically.
33896 +@@ -49,6 +53,16 @@ typedef __s64 Elf64_Sxword;
33897 +
33898 + #define PT_GNU_STACK (PT_LOOS + 0x474e551)
33899 +
33900 ++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
33901 ++
33902 ++/* Constants for the e_flags field */
33903 ++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
33904 ++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
33905 ++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
33906 ++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
33907 ++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
33908 ++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
33909 ++
33910 + /* These constants define the different elf file types */
33911 + #define ET_NONE 0
33912 + #define ET_REL 1
33913 +@@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword;
33914 + #define DT_DEBUG 21
33915 + #define DT_TEXTREL 22
33916 + #define DT_JMPREL 23
33917 ++#define DT_FLAGS 30
33918 ++ #define DF_TEXTREL 0x00000004
33919 + #define DT_ENCODING 32
33920 + #define OLD_DT_LOOS 0x60000000
33921 + #define DT_LOOS 0x6000000d
33922 +@@ -229,6 +245,19 @@ typedef struct elf64_hdr {
33923 + #define PF_W 0x2
33924 + #define PF_X 0x1
33925 +
33926 ++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
33927 ++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
33928 ++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
33929 ++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
33930 ++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
33931 ++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
33932 ++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
33933 ++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
33934 ++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
33935 ++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
33936 ++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
33937 ++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
33938 ++
33939 + typedef struct elf32_phdr{
33940 + Elf32_Word p_type;
33941 + Elf32_Off p_offset;
33942 +@@ -321,6 +350,8 @@ typedef struct elf64_shdr {
33943 + #define EI_OSABI 7
33944 + #define EI_PAD 8
33945 +
33946 ++#define EI_PAX 14
33947 ++
33948 + #define ELFMAG0 0x7f /* EI_MAG */
33949 + #define ELFMAG1 'E'
33950 + #define ELFMAG2 'L'
33951 +@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
33952 + #define elf_phdr elf32_phdr
33953 + #define elf_note elf32_note
33954 + #define elf_addr_t Elf32_Off
33955 ++#define elf_dyn Elf32_Dyn
33956 +
33957 + #else
33958 +
33959 +@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
33960 + #define elf_phdr elf64_phdr
33961 + #define elf_note elf64_note
33962 + #define elf_addr_t Elf64_Off
33963 ++#define elf_dyn Elf64_Dyn
33964 +
33965 + #endif
33966 +
33967 +diff -Nurp linux-2.6.23.15/include/linux/ext4_fs_extents.h linux-2.6.23.15-grsec/include/linux/ext4_fs_extents.h
33968 +--- linux-2.6.23.15/include/linux/ext4_fs_extents.h 2007-10-09 21:31:38.000000000 +0100
33969 ++++ linux-2.6.23.15-grsec/include/linux/ext4_fs_extents.h 2008-02-11 10:37:45.000000000 +0000
33970 +@@ -50,7 +50,7 @@
33971 + #ifdef EXT_DEBUG
33972 + #define ext_debug(a...) printk(a)
33973 + #else
33974 +-#define ext_debug(a...)
33975 ++#define ext_debug(a...) do {} while (0)
33976 + #endif
33977 +
33978 + /*
33979 +diff -Nurp linux-2.6.23.15/include/linux/gracl.h linux-2.6.23.15-grsec/include/linux/gracl.h
33980 +--- linux-2.6.23.15/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100
33981 ++++ linux-2.6.23.15-grsec/include/linux/gracl.h 2008-02-11 10:37:45.000000000 +0000
33982 +@@ -0,0 +1,317 @@
33983 ++#ifndef GR_ACL_H
33984 ++#define GR_ACL_H
33985 ++
33986 ++#include <linux/grdefs.h>
33987 ++#include <linux/resource.h>
33988 ++#include <linux/dcache.h>
33989 ++#include <asm/resource.h>
33990 ++
33991 ++/* Major status information */
33992 ++
33993 ++#define GR_VERSION "grsecurity 2.1.11"
33994 ++#define GRSECURITY_VERSION 0x2111
33995 ++
33996 ++enum {
33997 ++
33998 ++ SHUTDOWN = 0,
33999 ++ ENABLE = 1,
34000 ++ SPROLE = 2,
34001 ++ RELOAD = 3,
34002 ++ SEGVMOD = 4,
34003 ++ STATUS = 5,
34004 ++ UNSPROLE = 6,
34005 ++ PASSSET = 7,
34006 ++ SPROLEPAM = 8
34007 ++};
34008 ++
34009 ++/* Password setup definitions
34010 ++ * kernel/grhash.c */
34011 ++enum {
34012 ++ GR_PW_LEN = 128,
34013 ++ GR_SALT_LEN = 16,
34014 ++ GR_SHA_LEN = 32,
34015 ++};
34016 ++
34017 ++enum {
34018 ++ GR_SPROLE_LEN = 64,
34019 ++};
34020 ++
34021 ++#define GR_NLIMITS (RLIMIT_LOCKS + 2)
34022 ++
34023 ++/* Begin Data Structures */
34024 ++
34025 ++struct sprole_pw {
34026 ++ unsigned char *rolename;
34027 ++ unsigned char salt[GR_SALT_LEN];
34028 ++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
34029 ++};
34030 ++
34031 ++struct name_entry {
34032 ++ __u32 key;
34033 ++ ino_t inode;
34034 ++ dev_t device;
34035 ++ char *name;
34036 ++ __u16 len;
34037 ++ __u8 deleted;
34038 ++ struct name_entry *prev;
34039 ++ struct name_entry *next;
34040 ++};
34041 ++
34042 ++struct inodev_entry {
34043 ++ struct name_entry *nentry;
34044 ++ struct inodev_entry *prev;
34045 ++ struct inodev_entry *next;
34046 ++};
34047 ++
34048 ++struct acl_role_db {
34049 ++ struct acl_role_label **r_hash;
34050 ++ __u32 r_size;
34051 ++};
34052 ++
34053 ++struct inodev_db {
34054 ++ struct inodev_entry **i_hash;
34055 ++ __u32 i_size;
34056 ++};
34057 ++
34058 ++struct name_db {
34059 ++ struct name_entry **n_hash;
34060 ++ __u32 n_size;
34061 ++};
34062 ++
34063 ++struct crash_uid {
34064 ++ uid_t uid;
34065 ++ unsigned long expires;
34066 ++};
34067 ++
34068 ++struct gr_hash_struct {
34069 ++ void **table;
34070 ++ void **nametable;
34071 ++ void *first;
34072 ++ __u32 table_size;
34073 ++ __u32 used_size;
34074 ++ int type;
34075 ++};
34076 ++
34077 ++/* Userspace Grsecurity ACL data structures */
34078 ++
34079 ++struct acl_subject_label {
34080 ++ char *filename;
34081 ++ ino_t inode;
34082 ++ dev_t device;
34083 ++ __u32 mode;
34084 ++ __u32 cap_mask;
34085 ++ __u32 cap_lower;
34086 ++
34087 ++ struct rlimit res[GR_NLIMITS];
34088 ++ __u16 resmask;
34089 ++
34090 ++ __u8 user_trans_type;
34091 ++ __u8 group_trans_type;
34092 ++ uid_t *user_transitions;
34093 ++ gid_t *group_transitions;
34094 ++ __u16 user_trans_num;
34095 ++ __u16 group_trans_num;
34096 ++
34097 ++ __u32 ip_proto[8];
34098 ++ __u32 ip_type;
34099 ++ struct acl_ip_label **ips;
34100 ++ __u32 ip_num;
34101 ++
34102 ++ __u32 crashes;
34103 ++ unsigned long expires;
34104 ++
34105 ++ struct acl_subject_label *parent_subject;
34106 ++ struct gr_hash_struct *hash;
34107 ++ struct acl_subject_label *prev;
34108 ++ struct acl_subject_label *next;
34109 ++
34110 ++ struct acl_object_label **obj_hash;
34111 ++ __u32 obj_hash_size;
34112 ++ __u16 pax_flags;
34113 ++};
34114 ++
34115 ++struct role_allowed_ip {
34116 ++ __u32 addr;
34117 ++ __u32 netmask;
34118 ++
34119 ++ struct role_allowed_ip *prev;
34120 ++ struct role_allowed_ip *next;
34121 ++};
34122 ++
34123 ++struct role_transition {
34124 ++ char *rolename;
34125 ++
34126 ++ struct role_transition *prev;
34127 ++ struct role_transition *next;
34128 ++};
34129 ++
34130 ++struct acl_role_label {
34131 ++ char *rolename;
34132 ++ uid_t uidgid;
34133 ++ __u16 roletype;
34134 ++
34135 ++ __u16 auth_attempts;
34136 ++ unsigned long expires;
34137 ++
34138 ++ struct acl_subject_label *root_label;
34139 ++ struct gr_hash_struct *hash;
34140 ++
34141 ++ struct acl_role_label *prev;
34142 ++ struct acl_role_label *next;
34143 ++
34144 ++ struct role_transition *transitions;
34145 ++ struct role_allowed_ip *allowed_ips;
34146 ++ uid_t *domain_children;
34147 ++ __u16 domain_child_num;
34148 ++
34149 ++ struct acl_subject_label **subj_hash;
34150 ++ __u32 subj_hash_size;
34151 ++};
34152 ++
34153 ++struct user_acl_role_db {
34154 ++ struct acl_role_label **r_table;
34155 ++ __u32 num_pointers; /* Number of allocations to track */
34156 ++ __u32 num_roles; /* Number of roles */
34157 ++ __u32 num_domain_children; /* Number of domain children */
34158 ++ __u32 num_subjects; /* Number of subjects */
34159 ++ __u32 num_objects; /* Number of objects */
34160 ++};
34161 ++
34162 ++struct acl_object_label {
34163 ++ char *filename;
34164 ++ ino_t inode;
34165 ++ dev_t device;
34166 ++ __u32 mode;
34167 ++
34168 ++ struct acl_subject_label *nested;
34169 ++ struct acl_object_label *globbed;
34170 ++
34171 ++ /* next two structures not used */
34172 ++
34173 ++ struct acl_object_label *prev;
34174 ++ struct acl_object_label *next;
34175 ++};
34176 ++
34177 ++struct acl_ip_label {
34178 ++ char *iface;
34179 ++ __u32 addr;
34180 ++ __u32 netmask;
34181 ++ __u16 low, high;
34182 ++ __u8 mode;
34183 ++ __u32 type;
34184 ++ __u32 proto[8];
34185 ++
34186 ++ /* next two structures not used */
34187 ++
34188 ++ struct acl_ip_label *prev;
34189 ++ struct acl_ip_label *next;
34190 ++};
34191 ++
34192 ++struct gr_arg {
34193 ++ struct user_acl_role_db role_db;
34194 ++ unsigned char pw[GR_PW_LEN];
34195 ++ unsigned char salt[GR_SALT_LEN];
34196 ++ unsigned char sum[GR_SHA_LEN];
34197 ++ unsigned char sp_role[GR_SPROLE_LEN];
34198 ++ struct sprole_pw *sprole_pws;
34199 ++ dev_t segv_device;
34200 ++ ino_t segv_inode;
34201 ++ uid_t segv_uid;
34202 ++ __u16 num_sprole_pws;
34203 ++ __u16 mode;
34204 ++};
34205 ++
34206 ++struct gr_arg_wrapper {
34207 ++ struct gr_arg *arg;
34208 ++ __u32 version;
34209 ++ __u32 size;
34210 ++};
34211 ++
34212 ++struct subject_map {
34213 ++ struct acl_subject_label *user;
34214 ++ struct acl_subject_label *kernel;
34215 ++ struct subject_map *prev;
34216 ++ struct subject_map *next;
34217 ++};
34218 ++
34219 ++struct acl_subj_map_db {
34220 ++ struct subject_map **s_hash;
34221 ++ __u32 s_size;
34222 ++};
34223 ++
34224 ++/* End Data Structures Section */
34225 ++
34226 ++/* Hash functions generated by empirical testing by Brad Spengler
34227 ++ Makes good use of the low bits of the inode. Generally 0-1 times
34228 ++ in loop for successful match. 0-3 for unsuccessful match.
34229 ++ Shift/add algorithm with modulus of table size and an XOR*/
34230 ++
34231 ++static __inline__ unsigned int
34232 ++rhash(const uid_t uid, const __u16 type, const unsigned int sz)
34233 ++{
34234 ++ return (((uid << type) + (uid ^ type)) % sz);
34235 ++}
34236 ++
34237 ++ static __inline__ unsigned int
34238 ++shash(const struct acl_subject_label *userp, const unsigned int sz)
34239 ++{
34240 ++ return ((const unsigned long)userp % sz);
34241 ++}
34242 ++
34243 ++static __inline__ unsigned int
34244 ++fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
34245 ++{
34246 ++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
34247 ++}
34248 ++
34249 ++static __inline__ unsigned int
34250 ++nhash(const char *name, const __u16 len, const unsigned int sz)
34251 ++{
34252 ++ return full_name_hash(name, len) % sz;
34253 ++}
34254 ++
34255 ++#define FOR_EACH_ROLE_START(role,iter) \
34256 ++ role = NULL; \
34257 ++ iter = 0; \
34258 ++ while (iter < acl_role_set.r_size) { \
34259 ++ if (role == NULL) \
34260 ++ role = acl_role_set.r_hash[iter]; \
34261 ++ if (role == NULL) { \
34262 ++ iter++; \
34263 ++ continue; \
34264 ++ }
34265 ++
34266 ++#define FOR_EACH_ROLE_END(role,iter) \
34267 ++ role = role->next; \
34268 ++ if (role == NULL) \
34269 ++ iter++; \
34270 ++ }
34271 ++
34272 ++#define FOR_EACH_SUBJECT_START(role,subj,iter) \
34273 ++ subj = NULL; \
34274 ++ iter = 0; \
34275 ++ while (iter < role->subj_hash_size) { \
34276 ++ if (subj == NULL) \
34277 ++ subj = role->subj_hash[iter]; \
34278 ++ if (subj == NULL) { \
34279 ++ iter++; \
34280 ++ continue; \
34281 ++ }
34282 ++
34283 ++#define FOR_EACH_SUBJECT_END(subj,iter) \
34284 ++ subj = subj->next; \
34285 ++ if (subj == NULL) \
34286 ++ iter++; \
34287 ++ }
34288 ++
34289 ++
34290 ++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
34291 ++ subj = role->hash->first; \
34292 ++ while (subj != NULL) {
34293 ++
34294 ++#define FOR_EACH_NESTED_SUBJECT_END(subj) \
34295 ++ subj = subj->next; \
34296 ++ }
34297 ++
34298 ++#endif
34299 ++
34300 +diff -Nurp linux-2.6.23.15/include/linux/gralloc.h linux-2.6.23.15-grsec/include/linux/gralloc.h
34301 +--- linux-2.6.23.15/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100
34302 ++++ linux-2.6.23.15-grsec/include/linux/gralloc.h 2008-02-11 10:37:45.000000000 +0000
34303 +@@ -0,0 +1,8 @@
34304 ++#ifndef __GRALLOC_H
34305 ++#define __GRALLOC_H
34306 ++
34307 ++void acl_free_all(void);
34308 ++int acl_alloc_stack_init(unsigned long size);
34309 ++void *acl_alloc(unsigned long len);
34310 ++
34311 ++#endif
34312 +diff -Nurp linux-2.6.23.15/include/linux/grdefs.h linux-2.6.23.15-grsec/include/linux/grdefs.h
34313 +--- linux-2.6.23.15/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100
34314 ++++ linux-2.6.23.15-grsec/include/linux/grdefs.h 2008-02-11 10:37:45.000000000 +0000
34315 +@@ -0,0 +1,131 @@
34316 ++#ifndef GRDEFS_H
34317 ++#define GRDEFS_H
34318 ++
34319 ++/* Begin grsecurity status declarations */
34320 ++
34321 ++enum {
34322 ++ GR_READY = 0x01,
34323 ++ GR_STATUS_INIT = 0x00 // disabled state
34324 ++};
34325 ++
34326 ++/* Begin ACL declarations */
34327 ++
34328 ++/* Role flags */
34329 ++
34330 ++enum {
34331 ++ GR_ROLE_USER = 0x0001,
34332 ++ GR_ROLE_GROUP = 0x0002,
34333 ++ GR_ROLE_DEFAULT = 0x0004,
34334 ++ GR_ROLE_SPECIAL = 0x0008,
34335 ++ GR_ROLE_AUTH = 0x0010,
34336 ++ GR_ROLE_NOPW = 0x0020,
34337 ++ GR_ROLE_GOD = 0x0040,
34338 ++ GR_ROLE_LEARN = 0x0080,
34339 ++ GR_ROLE_TPE = 0x0100,
34340 ++ GR_ROLE_DOMAIN = 0x0200,
34341 ++ GR_ROLE_PAM = 0x0400
34342 ++};
34343 ++
34344 ++/* ACL Subject and Object mode flags */
34345 ++enum {
34346 ++ GR_DELETED = 0x80000000
34347 ++};
34348 ++
34349 ++/* ACL Object-only mode flags */
34350 ++enum {
34351 ++ GR_READ = 0x00000001,
34352 ++ GR_APPEND = 0x00000002,
34353 ++ GR_WRITE = 0x00000004,
34354 ++ GR_EXEC = 0x00000008,
34355 ++ GR_FIND = 0x00000010,
34356 ++ GR_INHERIT = 0x00000020,
34357 ++ GR_SETID = 0x00000040,
34358 ++ GR_CREATE = 0x00000080,
34359 ++ GR_DELETE = 0x00000100,
34360 ++ GR_LINK = 0x00000200,
34361 ++ GR_AUDIT_READ = 0x00000400,
34362 ++ GR_AUDIT_APPEND = 0x00000800,
34363 ++ GR_AUDIT_WRITE = 0x00001000,
34364 ++ GR_AUDIT_EXEC = 0x00002000,
34365 ++ GR_AUDIT_FIND = 0x00004000,
34366 ++ GR_AUDIT_INHERIT= 0x00008000,
34367 ++ GR_AUDIT_SETID = 0x00010000,
34368 ++ GR_AUDIT_CREATE = 0x00020000,
34369 ++ GR_AUDIT_DELETE = 0x00040000,
34370 ++ GR_AUDIT_LINK = 0x00080000,
34371 ++ GR_PTRACERD = 0x00100000,
34372 ++ GR_NOPTRACE = 0x00200000,
34373 ++ GR_SUPPRESS = 0x00400000,
34374 ++ GR_NOLEARN = 0x00800000
34375 ++};
34376 ++
34377 ++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
34378 ++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
34379 ++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
34380 ++
34381 ++/* ACL subject-only mode flags */
34382 ++enum {
34383 ++ GR_KILL = 0x00000001,
34384 ++ GR_VIEW = 0x00000002,
34385 ++ GR_PROTECTED = 0x00000004,
34386 ++ GR_LEARN = 0x00000008,
34387 ++ GR_OVERRIDE = 0x00000010,
34388 ++ /* just a placeholder, this mode is only used in userspace */
34389 ++ GR_DUMMY = 0x00000020,
34390 ++ GR_PROTSHM = 0x00000040,
34391 ++ GR_KILLPROC = 0x00000080,
34392 ++ GR_KILLIPPROC = 0x00000100,
34393 ++ /* just a placeholder, this mode is only used in userspace */
34394 ++ GR_NOTROJAN = 0x00000200,
34395 ++ GR_PROTPROCFD = 0x00000400,
34396 ++ GR_PROCACCT = 0x00000800,
34397 ++ GR_RELAXPTRACE = 0x00001000,
34398 ++ GR_NESTED = 0x00002000,
34399 ++ GR_INHERITLEARN = 0x00004000,
34400 ++ GR_PROCFIND = 0x00008000,
34401 ++ GR_POVERRIDE = 0x00010000,
34402 ++ GR_KERNELAUTH = 0x00020000,
34403 ++};
34404 ++
34405 ++enum {
34406 ++ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
34407 ++ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
34408 ++ GR_PAX_ENABLE_MPROTECT = 0x0004,
34409 ++ GR_PAX_ENABLE_RANDMMAP = 0x0008,
34410 ++ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
34411 ++ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
34412 ++ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
34413 ++ GR_PAX_DISABLE_MPROTECT = 0x0400,
34414 ++ GR_PAX_DISABLE_RANDMMAP = 0x0800,
34415 ++ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
34416 ++};
34417 ++
34418 ++enum {
34419 ++ GR_ID_USER = 0x01,
34420 ++ GR_ID_GROUP = 0x02,
34421 ++};
34422 ++
34423 ++enum {
34424 ++ GR_ID_ALLOW = 0x01,
34425 ++ GR_ID_DENY = 0x02,
34426 ++};
34427 ++
34428 ++#define GR_CRASH_RES 11
34429 ++#define GR_UIDTABLE_MAX 500
34430 ++
34431 ++/* begin resource learning section */
34432 ++enum {
34433 ++ GR_RLIM_CPU_BUMP = 60,
34434 ++ GR_RLIM_FSIZE_BUMP = 50000,
34435 ++ GR_RLIM_DATA_BUMP = 10000,
34436 ++ GR_RLIM_STACK_BUMP = 1000,
34437 ++ GR_RLIM_CORE_BUMP = 10000,
34438 ++ GR_RLIM_RSS_BUMP = 500000,
34439 ++ GR_RLIM_NPROC_BUMP = 1,
34440 ++ GR_RLIM_NOFILE_BUMP = 5,
34441 ++ GR_RLIM_MEMLOCK_BUMP = 50000,
34442 ++ GR_RLIM_AS_BUMP = 500000,
34443 ++ GR_RLIM_LOCKS_BUMP = 2
34444 ++};
34445 ++
34446 ++#endif
34447 +diff -Nurp linux-2.6.23.15/include/linux/grinternal.h linux-2.6.23.15-grsec/include/linux/grinternal.h
34448 +--- linux-2.6.23.15/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100
34449 ++++ linux-2.6.23.15-grsec/include/linux/grinternal.h 2008-02-11 10:37:45.000000000 +0000
34450 +@@ -0,0 +1,210 @@
34451 ++#ifndef __GRINTERNAL_H
34452 ++#define __GRINTERNAL_H
34453 ++
34454 ++#ifdef CONFIG_GRKERNSEC
34455 ++
34456 ++#include <linux/fs.h>
34457 ++#include <linux/gracl.h>
34458 ++#include <linux/grdefs.h>
34459 ++#include <linux/grmsg.h>
34460 ++
34461 ++void gr_add_learn_entry(const char *fmt, ...);
34462 ++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
34463 ++ const struct vfsmount *mnt);
34464 ++__u32 gr_check_create(const struct dentry *new_dentry,
34465 ++ const struct dentry *parent,
34466 ++ const struct vfsmount *mnt, const __u32 mode);
34467 ++int gr_check_protected_task(const struct task_struct *task);
34468 ++__u32 to_gr_audit(const __u32 reqmode);
34469 ++int gr_set_acls(const int type);
34470 ++
34471 ++int gr_acl_is_enabled(void);
34472 ++char gr_roletype_to_char(void);
34473 ++
34474 ++void gr_handle_alertkill(struct task_struct *task);
34475 ++char *gr_to_filename(const struct dentry *dentry,
34476 ++ const struct vfsmount *mnt);
34477 ++char *gr_to_filename1(const struct dentry *dentry,
34478 ++ const struct vfsmount *mnt);
34479 ++char *gr_to_filename2(const struct dentry *dentry,
34480 ++ const struct vfsmount *mnt);
34481 ++char *gr_to_filename3(const struct dentry *dentry,
34482 ++ const struct vfsmount *mnt);
34483 ++
34484 ++extern int grsec_enable_link;
34485 ++extern int grsec_enable_fifo;
34486 ++extern int grsec_enable_execve;
34487 ++extern int grsec_enable_shm;
34488 ++extern int grsec_enable_execlog;
34489 ++extern int grsec_enable_signal;
34490 ++extern int grsec_enable_forkfail;
34491 ++extern int grsec_enable_time;
34492 ++extern int grsec_enable_chroot_shmat;
34493 ++extern int grsec_enable_chroot_findtask;
34494 ++extern int grsec_enable_chroot_mount;
34495 ++extern int grsec_enable_chroot_double;
34496 ++extern int grsec_enable_chroot_pivot;
34497 ++extern int grsec_enable_chroot_chdir;
34498 ++extern int grsec_enable_chroot_chmod;
34499 ++extern int grsec_enable_chroot_mknod;
34500 ++extern int grsec_enable_chroot_fchdir;
34501 ++extern int grsec_enable_chroot_nice;
34502 ++extern int grsec_enable_chroot_execlog;
34503 ++extern int grsec_enable_chroot_caps;
34504 ++extern int grsec_enable_chroot_sysctl;
34505 ++extern int grsec_enable_chroot_unix;
34506 ++extern int grsec_enable_tpe;
34507 ++extern int grsec_tpe_gid;
34508 ++extern int grsec_enable_tpe_all;
34509 ++extern int grsec_enable_sidcaps;
34510 ++extern int grsec_enable_socket_all;
34511 ++extern int grsec_socket_all_gid;
34512 ++extern int grsec_enable_socket_client;
34513 ++extern int grsec_socket_client_gid;
34514 ++extern int grsec_enable_socket_server;
34515 ++extern int grsec_socket_server_gid;
34516 ++extern int grsec_audit_gid;
34517 ++extern int grsec_enable_group;
34518 ++extern int grsec_enable_audit_ipc;
34519 ++extern int grsec_enable_audit_textrel;
34520 ++extern int grsec_enable_mount;
34521 ++extern int grsec_enable_chdir;
34522 ++extern int grsec_resource_logging;
34523 ++extern int grsec_lock;
34524 ++
34525 ++extern spinlock_t grsec_alert_lock;
34526 ++extern unsigned long grsec_alert_wtime;
34527 ++extern unsigned long grsec_alert_fyet;
34528 ++
34529 ++extern spinlock_t grsec_audit_lock;
34530 ++
34531 ++extern rwlock_t grsec_exec_file_lock;
34532 ++
34533 ++#define gr_task_fullpath(tsk) (tsk->exec_file ? \
34534 ++ gr_to_filename2(tsk->exec_file->f_dentry, \
34535 ++ tsk->exec_file->f_vfsmnt) : "/")
34536 ++
34537 ++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
34538 ++ gr_to_filename3(tsk->parent->exec_file->f_dentry, \
34539 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
34540 ++
34541 ++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
34542 ++ gr_to_filename(tsk->exec_file->f_dentry, \
34543 ++ tsk->exec_file->f_vfsmnt) : "/")
34544 ++
34545 ++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
34546 ++ gr_to_filename1(tsk->parent->exec_file->f_dentry, \
34547 ++ tsk->parent->exec_file->f_vfsmnt) : "/")
34548 ++
34549 ++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
34550 ++ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
34551 ++ child_reaper(tsk_a)->fs->root->d_inode->i_sb->s_dev) || \
34552 ++ (tsk_a->fs->root->d_inode->i_ino != \
34553 ++ child_reaper(tsk_a)->fs->root->d_inode->i_ino)))
34554 ++
34555 ++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
34556 ++ (tsk_a->fs->root->d_inode->i_sb->s_dev == \
34557 ++ tsk_b->fs->root->d_inode->i_sb->s_dev) && \
34558 ++ (tsk_a->fs->root->d_inode->i_ino == \
34559 ++ tsk_b->fs->root->d_inode->i_ino))
34560 ++
34561 ++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
34562 ++ task->pid, task->uid, \
34563 ++ task->euid, task->gid, task->egid, \
34564 ++ gr_parent_task_fullpath(task), \
34565 ++ task->parent->comm, task->parent->pid, \
34566 ++ task->parent->uid, task->parent->euid, \
34567 ++ task->parent->gid, task->parent->egid
34568 ++
34569 ++#define GR_CHROOT_CAPS ( \
34570 ++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
34571 ++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
34572 ++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
34573 ++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
34574 ++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
34575 ++ CAP_TO_MASK(CAP_IPC_OWNER))
34576 ++
34577 ++#define security_learn(normal_msg,args...) \
34578 ++({ \
34579 ++ read_lock(&grsec_exec_file_lock); \
34580 ++ gr_add_learn_entry(normal_msg "\n", ## args); \
34581 ++ read_unlock(&grsec_exec_file_lock); \
34582 ++})
34583 ++
34584 ++enum {
34585 ++ GR_DO_AUDIT,
34586 ++ GR_DONT_AUDIT,
34587 ++ GR_DONT_AUDIT_GOOD
34588 ++};
34589 ++
34590 ++enum {
34591 ++ GR_TTYSNIFF,
34592 ++ GR_RBAC,
34593 ++ GR_RBAC_STR,
34594 ++ GR_STR_RBAC,
34595 ++ GR_RBAC_MODE2,
34596 ++ GR_RBAC_MODE3,
34597 ++ GR_FILENAME,
34598 ++ GR_SYSCTL_HIDDEN,
34599 ++ GR_NOARGS,
34600 ++ GR_ONE_INT,
34601 ++ GR_ONE_INT_TWO_STR,
34602 ++ GR_ONE_STR,
34603 ++ GR_STR_INT,
34604 ++ GR_TWO_INT,
34605 ++ GR_THREE_INT,
34606 ++ GR_FIVE_INT_TWO_STR,
34607 ++ GR_TWO_STR,
34608 ++ GR_THREE_STR,
34609 ++ GR_FOUR_STR,
34610 ++ GR_STR_FILENAME,
34611 ++ GR_FILENAME_STR,
34612 ++ GR_FILENAME_TWO_INT,
34613 ++ GR_FILENAME_TWO_INT_STR,
34614 ++ GR_TEXTREL,
34615 ++ GR_PTRACE,
34616 ++ GR_RESOURCE,
34617 ++ GR_CAP,
34618 ++ GR_SIG,
34619 ++ GR_CRASH1,
34620 ++ GR_CRASH2,
34621 ++ GR_PSACCT
34622 ++};
34623 ++
34624 ++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
34625 ++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
34626 ++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
34627 ++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
34628 ++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
34629 ++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
34630 ++#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)
34631 ++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
34632 ++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
34633 ++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
34634 ++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
34635 ++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
34636 ++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
34637 ++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
34638 ++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
34639 ++#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)
34640 ++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
34641 ++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
34642 ++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
34643 ++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
34644 ++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
34645 ++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
34646 ++#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)
34647 ++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
34648 ++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
34649 ++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
34650 ++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
34651 ++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
34652 ++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
34653 ++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
34654 ++#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)
34655 ++
34656 ++void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
34657 ++
34658 ++#endif
34659 ++
34660 ++#endif
34661 +diff -Nurp linux-2.6.23.15/include/linux/grmsg.h linux-2.6.23.15-grsec/include/linux/grmsg.h
34662 +--- linux-2.6.23.15/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100
34663 ++++ linux-2.6.23.15-grsec/include/linux/grmsg.h 2008-02-11 10:37:45.000000000 +0000
34664 +@@ -0,0 +1,108 @@
34665 ++#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"
34666 ++#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"
34667 ++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
34668 ++#define GR_STOPMOD_MSG "denied modification of module state by "
34669 ++#define GR_IOPERM_MSG "denied use of ioperm() by "
34670 ++#define GR_IOPL_MSG "denied use of iopl() by "
34671 ++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
34672 ++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
34673 ++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
34674 ++#define GR_KMEM_MSG "denied write of /dev/kmem by "
34675 ++#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
34676 ++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
34677 ++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
34678 ++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
34679 ++#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"
34680 ++#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"
34681 ++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
34682 ++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
34683 ++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
34684 ++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
34685 ++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
34686 ++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
34687 ++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
34688 ++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
34689 ++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
34690 ++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
34691 ++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
34692 ++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
34693 ++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
34694 ++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
34695 ++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
34696 ++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
34697 ++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
34698 ++#define GR_NPROC_MSG "denied overstep of process limit by "
34699 ++#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
34700 ++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
34701 ++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
34702 ++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
34703 ++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
34704 ++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
34705 ++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
34706 ++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
34707 ++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
34708 ++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
34709 ++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
34710 ++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
34711 ++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
34712 ++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
34713 ++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
34714 ++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
34715 ++#define GR_INITF_ACL_MSG "init_variables() failed %s by "
34716 ++#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"
34717 ++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
34718 ++#define GR_SHUTS_ACL_MSG "shutdown auth success for "
34719 ++#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
34720 ++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
34721 ++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
34722 ++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
34723 ++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
34724 ++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
34725 ++#define GR_ENABLEF_ACL_MSG "unable to load %s for "
34726 ++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
34727 ++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
34728 ++#define GR_RELOADF_ACL_MSG "failed reload of %s for "
34729 ++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
34730 ++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
34731 ++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
34732 ++#define GR_SPROLEF_ACL_MSG "special role %s failure for "
34733 ++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
34734 ++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
34735 ++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
34736 ++#define GR_INVMODE_ACL_MSG "invalid mode %d by "
34737 ++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
34738 ++#define GR_FAILFORK_MSG "failed fork with errno %d by "
34739 ++#define GR_NICE_CHROOT_MSG "denied priority change by "
34740 ++#define GR_UNISIGLOG_MSG "signal %d sent to "
34741 ++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
34742 ++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
34743 ++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
34744 ++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
34745 ++#define GR_TIME_MSG "time set by "
34746 ++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
34747 ++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
34748 ++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
34749 ++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
34750 ++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
34751 ++#define GR_BIND_MSG "denied bind() by "
34752 ++#define GR_CONNECT_MSG "denied connect() by "
34753 ++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
34754 ++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
34755 ++#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"
34756 ++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
34757 ++#define GR_CAP_ACL_MSG "use of %s denied for "
34758 ++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
34759 ++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
34760 ++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
34761 ++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
34762 ++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
34763 ++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
34764 ++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
34765 ++#define GR_MSGQ_AUDIT_MSG "message queue created by "
34766 ++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
34767 ++#define GR_SEM_AUDIT_MSG "semaphore created by "
34768 ++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
34769 ++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
34770 ++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
34771 ++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
34772 ++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
34773 +diff -Nurp linux-2.6.23.15/include/linux/grsecurity.h linux-2.6.23.15-grsec/include/linux/grsecurity.h
34774 +--- linux-2.6.23.15/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100
34775 ++++ linux-2.6.23.15-grsec/include/linux/grsecurity.h 2008-02-11 10:37:45.000000000 +0000
34776 +@@ -0,0 +1,193 @@
34777 ++#ifndef GR_SECURITY_H
34778 ++#define GR_SECURITY_H
34779 ++#include <linux/fs.h>
34780 ++#include <linux/binfmts.h>
34781 ++#include <linux/gracl.h>
34782 ++
34783 ++void gr_handle_brute_attach(struct task_struct *p);
34784 ++void gr_handle_brute_check(void);
34785 ++
34786 ++char gr_roletype_to_char(void);
34787 ++
34788 ++int gr_check_user_change(int real, int effective, int fs);
34789 ++int gr_check_group_change(int real, int effective, int fs);
34790 ++
34791 ++void gr_del_task_from_ip_table(struct task_struct *p);
34792 ++
34793 ++int gr_pid_is_chrooted(struct task_struct *p);
34794 ++int gr_handle_chroot_nice(void);
34795 ++int gr_handle_chroot_sysctl(const int op);
34796 ++int gr_handle_chroot_setpriority(struct task_struct *p,
34797 ++ const int niceval);
34798 ++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
34799 ++int gr_handle_chroot_chroot(const struct dentry *dentry,
34800 ++ const struct vfsmount *mnt);
34801 ++void gr_handle_chroot_caps(struct task_struct *task);
34802 ++void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
34803 ++int gr_handle_chroot_chmod(const struct dentry *dentry,
34804 ++ const struct vfsmount *mnt, const int mode);
34805 ++int gr_handle_chroot_mknod(const struct dentry *dentry,
34806 ++ const struct vfsmount *mnt, const int mode);
34807 ++int gr_handle_chroot_mount(const struct dentry *dentry,
34808 ++ const struct vfsmount *mnt,
34809 ++ const char *dev_name);
34810 ++int gr_handle_chroot_pivot(void);
34811 ++int gr_handle_chroot_unix(const pid_t pid);
34812 ++
34813 ++int gr_handle_rawio(const struct inode *inode);
34814 ++int gr_handle_nproc(void);
34815 ++
34816 ++void gr_handle_ioperm(void);
34817 ++void gr_handle_iopl(void);
34818 ++
34819 ++int gr_tpe_allow(const struct file *file);
34820 ++
34821 ++int gr_random_pid(void);
34822 ++
34823 ++void gr_log_forkfail(const int retval);
34824 ++void gr_log_timechange(void);
34825 ++void gr_log_signal(const int sig, const struct task_struct *t);
34826 ++void gr_log_chdir(const struct dentry *dentry,
34827 ++ const struct vfsmount *mnt);
34828 ++void gr_log_chroot_exec(const struct dentry *dentry,
34829 ++ const struct vfsmount *mnt);
34830 ++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
34831 ++void gr_log_remount(const char *devname, const int retval);
34832 ++void gr_log_unmount(const char *devname, const int retval);
34833 ++void gr_log_mount(const char *from, const char *to, const int retval);
34834 ++void gr_log_msgget(const int ret, const int msgflg);
34835 ++void gr_log_msgrm(const uid_t uid, const uid_t cuid);
34836 ++void gr_log_semget(const int err, const int semflg);
34837 ++void gr_log_semrm(const uid_t uid, const uid_t cuid);
34838 ++void gr_log_shmget(const int err, const int shmflg, const size_t size);
34839 ++void gr_log_shmrm(const uid_t uid, const uid_t cuid);
34840 ++void gr_log_textrel(struct vm_area_struct *vma);
34841 ++
34842 ++int gr_handle_follow_link(const struct inode *parent,
34843 ++ const struct inode *inode,
34844 ++ const struct dentry *dentry,
34845 ++ const struct vfsmount *mnt);
34846 ++int gr_handle_fifo(const struct dentry *dentry,
34847 ++ const struct vfsmount *mnt,
34848 ++ const struct dentry *dir, const int flag,
34849 ++ const int acc_mode);
34850 ++int gr_handle_hardlink(const struct dentry *dentry,
34851 ++ const struct vfsmount *mnt,
34852 ++ struct inode *inode,
34853 ++ const int mode, const char *to);
34854 ++
34855 ++int gr_task_is_capable(struct task_struct *task, const int cap);
34856 ++int gr_is_capable_nolog(const int cap);
34857 ++void gr_learn_resource(const struct task_struct *task, const int limit,
34858 ++ const unsigned long wanted, const int gt);
34859 ++void gr_copy_label(struct task_struct *tsk);
34860 ++void gr_handle_crash(struct task_struct *task, const int sig);
34861 ++int gr_handle_signal(const struct task_struct *p, const int sig);
34862 ++int gr_check_crash_uid(const uid_t uid);
34863 ++int gr_check_protected_task(const struct task_struct *task);
34864 ++int gr_acl_handle_mmap(const struct file *file,
34865 ++ const unsigned long prot);
34866 ++int gr_acl_handle_mprotect(const struct file *file,
34867 ++ const unsigned long prot);
34868 ++int gr_check_hidden_task(const struct task_struct *tsk);
34869 ++__u32 gr_acl_handle_truncate(const struct dentry *dentry,
34870 ++ const struct vfsmount *mnt);
34871 ++__u32 gr_acl_handle_utime(const struct dentry *dentry,
34872 ++ const struct vfsmount *mnt);
34873 ++__u32 gr_acl_handle_access(const struct dentry *dentry,
34874 ++ const struct vfsmount *mnt, const int fmode);
34875 ++__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
34876 ++ const struct vfsmount *mnt, mode_t mode);
34877 ++__u32 gr_acl_handle_chmod(const struct dentry *dentry,
34878 ++ const struct vfsmount *mnt, mode_t mode);
34879 ++__u32 gr_acl_handle_chown(const struct dentry *dentry,
34880 ++ const struct vfsmount *mnt);
34881 ++int gr_handle_ptrace(struct task_struct *task, const long request);
34882 ++int gr_handle_proc_ptrace(struct task_struct *task);
34883 ++__u32 gr_acl_handle_execve(const struct dentry *dentry,
34884 ++ const struct vfsmount *mnt);
34885 ++int gr_check_crash_exec(const struct file *filp);
34886 ++int gr_acl_is_enabled(void);
34887 ++void gr_set_kernel_label(struct task_struct *task);
34888 ++void gr_set_role_label(struct task_struct *task, const uid_t uid,
34889 ++ const gid_t gid);
34890 ++int gr_set_proc_label(const struct dentry *dentry,
34891 ++ const struct vfsmount *mnt);
34892 ++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
34893 ++ const struct vfsmount *mnt);
34894 ++__u32 gr_acl_handle_open(const struct dentry *dentry,
34895 ++ const struct vfsmount *mnt, const int fmode);
34896 ++__u32 gr_acl_handle_creat(const struct dentry *dentry,
34897 ++ const struct dentry *p_dentry,
34898 ++ const struct vfsmount *p_mnt, const int fmode,
34899 ++ const int imode);
34900 ++void gr_handle_create(const struct dentry *dentry,
34901 ++ const struct vfsmount *mnt);
34902 ++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
34903 ++ const struct dentry *parent_dentry,
34904 ++ const struct vfsmount *parent_mnt,
34905 ++ const int mode);
34906 ++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
34907 ++ const struct dentry *parent_dentry,
34908 ++ const struct vfsmount *parent_mnt);
34909 ++__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
34910 ++ const struct vfsmount *mnt);
34911 ++void gr_handle_delete(const ino_t ino, const dev_t dev);
34912 ++__u32 gr_acl_handle_unlink(const struct dentry *dentry,
34913 ++ const struct vfsmount *mnt);
34914 ++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
34915 ++ const struct dentry *parent_dentry,
34916 ++ const struct vfsmount *parent_mnt,
34917 ++ const char *from);
34918 ++__u32 gr_acl_handle_link(const struct dentry *new_dentry,
34919 ++ const struct dentry *parent_dentry,
34920 ++ const struct vfsmount *parent_mnt,
34921 ++ const struct dentry *old_dentry,
34922 ++ const struct vfsmount *old_mnt, const char *to);
34923 ++int gr_acl_handle_rename(struct dentry *new_dentry,
34924 ++ struct dentry *parent_dentry,
34925 ++ const struct vfsmount *parent_mnt,
34926 ++ struct dentry *old_dentry,
34927 ++ struct inode *old_parent_inode,
34928 ++ struct vfsmount *old_mnt, const char *newname);
34929 ++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
34930 ++ struct dentry *old_dentry,
34931 ++ struct dentry *new_dentry,
34932 ++ struct vfsmount *mnt, const __u8 replace);
34933 ++__u32 gr_check_link(const struct dentry *new_dentry,
34934 ++ const struct dentry *parent_dentry,
34935 ++ const struct vfsmount *parent_mnt,
34936 ++ const struct dentry *old_dentry,
34937 ++ const struct vfsmount *old_mnt);
34938 ++int gr_acl_handle_filldir(const struct file *file, const char *name,
34939 ++ const unsigned int namelen, const ino_t ino);
34940 ++
34941 ++__u32 gr_acl_handle_unix(const struct dentry *dentry,
34942 ++ const struct vfsmount *mnt);
34943 ++void gr_acl_handle_exit(void);
34944 ++void gr_acl_handle_psacct(struct task_struct *task, const long code);
34945 ++int gr_acl_handle_procpidmem(const struct task_struct *task);
34946 ++__u32 gr_cap_rtnetlink(void);
34947 ++
34948 ++#ifdef CONFIG_SYSVIPC
34949 ++void gr_shm_exit(struct task_struct *task);
34950 ++#else
34951 ++static inline void gr_shm_exit(struct task_struct *task)
34952 ++{
34953 ++ return;
34954 ++}
34955 ++#endif
34956 ++
34957 ++#ifdef CONFIG_GRKERNSEC
34958 ++void gr_handle_mem_write(void);
34959 ++void gr_handle_kmem_write(void);
34960 ++void gr_handle_open_port(void);
34961 ++int gr_handle_mem_mmap(const unsigned long offset,
34962 ++ struct vm_area_struct *vma);
34963 ++
34964 ++extern int grsec_enable_dmesg;
34965 ++extern int grsec_enable_randsrc;
34966 ++extern int grsec_enable_shm;
34967 ++#endif
34968 ++
34969 ++#endif
34970 +diff -Nurp linux-2.6.23.15/include/linux/highmem.h linux-2.6.23.15-grsec/include/linux/highmem.h
34971 +--- linux-2.6.23.15/include/linux/highmem.h 2007-10-09 21:31:38.000000000 +0100
34972 ++++ linux-2.6.23.15-grsec/include/linux/highmem.h 2008-02-11 10:37:45.000000000 +0000
34973 +@@ -124,6 +124,13 @@ static inline void clear_highpage(struct
34974 + kunmap_atomic(kaddr, KM_USER0);
34975 + }
34976 +
34977 ++static inline void sanitize_highpage(struct page *page)
34978 ++{
34979 ++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
34980 ++ clear_page(kaddr);
34981 ++ kunmap_atomic(kaddr, KM_CLEARPAGE);
34982 ++}
34983 ++
34984 + /*
34985 + * Same but also flushes aliased cache contents to RAM.
34986 + *
34987 +@@ -132,14 +139,14 @@ static inline void clear_highpage(struct
34988 + */
34989 + #define zero_user_page(page, offset, size, km_type) \
34990 + do { \
34991 +- void *kaddr; \
34992 ++ void *__kaddr; \
34993 + \
34994 + BUG_ON((offset) + (size) > PAGE_SIZE); \
34995 + \
34996 +- kaddr = kmap_atomic(page, km_type); \
34997 +- memset((char *)kaddr + (offset), 0, (size)); \
34998 ++ __kaddr = kmap_atomic(page, km_type); \
34999 ++ memset((char *)__kaddr + (offset), 0, (size)); \
35000 + flush_dcache_page(page); \
35001 +- kunmap_atomic(kaddr, (km_type)); \
35002 ++ kunmap_atomic(__kaddr, (km_type)); \
35003 + } while (0)
35004 +
35005 + static inline void __deprecated memclear_highpage_flush(struct page *page,
35006 +diff -Nurp linux-2.6.23.15/include/linux/irqflags.h linux-2.6.23.15-grsec/include/linux/irqflags.h
35007 +--- linux-2.6.23.15/include/linux/irqflags.h 2007-10-09 21:31:38.000000000 +0100
35008 ++++ linux-2.6.23.15-grsec/include/linux/irqflags.h 2008-02-11 10:37:45.000000000 +0000
35009 +@@ -84,10 +84,10 @@
35010 +
35011 + #define irqs_disabled() \
35012 + ({ \
35013 +- unsigned long flags; \
35014 ++ unsigned long __flags; \
35015 + \
35016 +- raw_local_save_flags(flags); \
35017 +- raw_irqs_disabled_flags(flags); \
35018 ++ raw_local_save_flags(__flags); \
35019 ++ raw_irqs_disabled_flags(__flags); \
35020 + })
35021 +
35022 + #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
35023 +diff -Nurp linux-2.6.23.15/include/linux/jbd.h linux-2.6.23.15-grsec/include/linux/jbd.h
35024 +--- linux-2.6.23.15/include/linux/jbd.h 2007-10-09 21:31:38.000000000 +0100
35025 ++++ linux-2.6.23.15-grsec/include/linux/jbd.h 2008-02-11 10:37:45.000000000 +0000
35026 +@@ -68,7 +68,7 @@ extern int journal_enable_debug;
35027 + } \
35028 + } while (0)
35029 + #else
35030 +-#define jbd_debug(f, a...) /**/
35031 ++#define jbd_debug(f, a...) do {} while (0)
35032 + #endif
35033 +
35034 + extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
35035 +diff -Nurp linux-2.6.23.15/include/linux/jbd2.h linux-2.6.23.15-grsec/include/linux/jbd2.h
35036 +--- linux-2.6.23.15/include/linux/jbd2.h 2007-10-09 21:31:38.000000000 +0100
35037 ++++ linux-2.6.23.15-grsec/include/linux/jbd2.h 2008-02-11 10:37:45.000000000 +0000
35038 +@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug;
35039 + } \
35040 + } while (0)
35041 + #else
35042 +-#define jbd_debug(f, a...) /**/
35043 ++#define jbd_debug(f, a...) do {} while (0)
35044 + #endif
35045 +
35046 + extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
35047 +diff -Nurp linux-2.6.23.15/include/linux/libata.h linux-2.6.23.15-grsec/include/linux/libata.h
35048 +--- linux-2.6.23.15/include/linux/libata.h 2008-02-11 10:36:03.000000000 +0000
35049 ++++ linux-2.6.23.15-grsec/include/linux/libata.h 2008-02-11 10:37:45.000000000 +0000
35050 +@@ -63,11 +63,11 @@
35051 + #ifdef ATA_VERBOSE_DEBUG
35052 + #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
35053 + #else
35054 +-#define VPRINTK(fmt, args...)
35055 ++#define VPRINTK(fmt, args...) do {} while (0)
35056 + #endif /* ATA_VERBOSE_DEBUG */
35057 + #else
35058 +-#define DPRINTK(fmt, args...)
35059 +-#define VPRINTK(fmt, args...)
35060 ++#define DPRINTK(fmt, args...) do {} while (0)
35061 ++#define VPRINTK(fmt, args...) do {} while (0)
35062 + #endif /* ATA_DEBUG */
35063 +
35064 + #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
35065 +diff -Nurp linux-2.6.23.15/include/linux/mm.h linux-2.6.23.15-grsec/include/linux/mm.h
35066 +--- linux-2.6.23.15/include/linux/mm.h 2007-10-09 21:31:38.000000000 +0100
35067 ++++ linux-2.6.23.15-grsec/include/linux/mm.h 2008-02-11 10:37:45.000000000 +0000
35068 +@@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout;
35069 + #include <asm/page.h>
35070 + #include <asm/pgtable.h>
35071 + #include <asm/processor.h>
35072 ++#include <asm/mman.h>
35073 +
35074 + #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
35075 +
35076 +@@ -111,6 +112,8 @@ struct vm_area_struct {
35077 + #ifdef CONFIG_NUMA
35078 + struct mempolicy *vm_policy; /* NUMA policy for the VMA */
35079 + #endif
35080 ++
35081 ++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
35082 + };
35083 +
35084 + extern struct kmem_cache *vm_area_cachep;
35085 +@@ -171,6 +174,14 @@ extern unsigned int kobjsize(const void
35086 +
35087 + #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */
35088 +
35089 ++#ifdef CONFIG_PAX_PAGEEXEC
35090 ++#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */
35091 ++#endif
35092 ++
35093 ++#ifdef CONFIG_PAX_MPROTECT
35094 ++#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */
35095 ++#endif
35096 ++
35097 + #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
35098 + #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
35099 + #endif
35100 +@@ -862,6 +873,8 @@ struct shrinker {
35101 + extern void register_shrinker(struct shrinker *);
35102 + extern void unregister_shrinker(struct shrinker *);
35103 +
35104 ++pgprot_t vm_get_page_prot(unsigned long vm_flags);
35105 ++
35106 + int vma_wants_writenotify(struct vm_area_struct *vma);
35107 +
35108 + extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl));
35109 +@@ -1088,6 +1101,7 @@ out:
35110 + }
35111 +
35112 + extern int do_munmap(struct mm_struct *, unsigned long, size_t);
35113 ++extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
35114 +
35115 + extern unsigned long do_brk(unsigned long, unsigned long);
35116 +
35117 +@@ -1142,6 +1156,10 @@ extern struct vm_area_struct * find_vma(
35118 + extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
35119 + struct vm_area_struct **pprev);
35120 +
35121 ++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
35122 ++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
35123 ++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
35124 ++
35125 + /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
35126 + NULL if none. Assume start_addr < end_addr. */
35127 + static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
35128 +@@ -1158,7 +1176,6 @@ static inline unsigned long vma_pages(st
35129 + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
35130 + }
35131 +
35132 +-pgprot_t vm_get_page_prot(unsigned long vm_flags);
35133 + struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
35134 + struct page *vmalloc_to_page(void *addr);
35135 + unsigned long vmalloc_to_pfn(void *addr);
35136 +@@ -1218,5 +1235,11 @@ extern int randomize_va_space;
35137 +
35138 + const char * arch_vma_name(struct vm_area_struct *vma);
35139 +
35140 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35141 ++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
35142 ++#else
35143 ++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
35144 ++#endif
35145 ++
35146 + #endif /* __KERNEL__ */
35147 + #endif /* _LINUX_MM_H */
35148 +diff -Nurp linux-2.6.23.15/include/linux/module.h linux-2.6.23.15-grsec/include/linux/module.h
35149 +--- linux-2.6.23.15/include/linux/module.h 2007-10-09 21:31:38.000000000 +0100
35150 ++++ linux-2.6.23.15-grsec/include/linux/module.h 2008-02-11 10:37:45.000000000 +0000
35151 +@@ -295,16 +295,16 @@ struct module
35152 + int (*init)(void);
35153 +
35154 + /* If this is non-NULL, vfree after init() returns */
35155 +- void *module_init;
35156 ++ void *module_init_rx, *module_init_rw;
35157 +
35158 + /* Here is the actual code + data, vfree'd on unload. */
35159 +- void *module_core;
35160 ++ void *module_core_rx, *module_core_rw;
35161 +
35162 + /* Here are the sizes of the init and core sections */
35163 +- unsigned long init_size, core_size;
35164 ++ unsigned long init_size_rw, core_size_rw;
35165 +
35166 + /* The size of the executable code in each section. */
35167 +- unsigned long init_text_size, core_text_size;
35168 ++ unsigned long init_size_rx, core_size_rx;
35169 +
35170 + /* The handle returned from unwind_add_table. */
35171 + void *unwind_info;
35172 +diff -Nurp linux-2.6.23.15/include/linux/moduleloader.h linux-2.6.23.15-grsec/include/linux/moduleloader.h
35173 +--- linux-2.6.23.15/include/linux/moduleloader.h 2007-10-09 21:31:38.000000000 +0100
35174 ++++ linux-2.6.23.15-grsec/include/linux/moduleloader.h 2008-02-11 10:37:45.000000000 +0000
35175 +@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
35176 + sections. Returns NULL on failure. */
35177 + void *module_alloc(unsigned long size);
35178 +
35179 ++#ifdef CONFIG_PAX_KERNEXEC
35180 ++void *module_alloc_exec(unsigned long size);
35181 ++#else
35182 ++#define module_alloc_exec(x) module_alloc(x)
35183 ++#endif
35184 ++
35185 + /* Free memory returned from module_alloc. */
35186 + void module_free(struct module *mod, void *module_region);
35187 +
35188 ++#ifdef CONFIG_PAX_KERNEXEC
35189 ++void module_free_exec(struct module *mod, void *module_region);
35190 ++#else
35191 ++#define module_free_exec(x, y) module_free(x, y)
35192 ++#endif
35193 ++
35194 + /* Apply the given relocation to the (simplified) ELF. Return -error
35195 + or 0. */
35196 + int apply_relocate(Elf_Shdr *sechdrs,
35197 +diff -Nurp linux-2.6.23.15/include/linux/percpu.h linux-2.6.23.15-grsec/include/linux/percpu.h
35198 +--- linux-2.6.23.15/include/linux/percpu.h 2007-10-09 21:31:38.000000000 +0100
35199 ++++ linux-2.6.23.15-grsec/include/linux/percpu.h 2008-02-11 10:37:45.000000000 +0000
35200 +@@ -18,7 +18,7 @@
35201 + #endif
35202 +
35203 + #define PERCPU_ENOUGH_ROOM \
35204 +- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
35205 ++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
35206 + #endif /* PERCPU_ENOUGH_ROOM */
35207 +
35208 + /*
35209 +diff -Nurp linux-2.6.23.15/include/linux/random.h linux-2.6.23.15-grsec/include/linux/random.h
35210 +--- linux-2.6.23.15/include/linux/random.h 2007-10-09 21:31:38.000000000 +0100
35211 ++++ linux-2.6.23.15-grsec/include/linux/random.h 2008-02-11 10:37:45.000000000 +0000
35212 +@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
35213 + u32 random32(void);
35214 + void srandom32(u32 seed);
35215 +
35216 ++static inline unsigned long pax_get_random_long(void)
35217 ++{
35218 ++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
35219 ++}
35220 ++
35221 + #endif /* __KERNEL___ */
35222 +
35223 + #endif /* _LINUX_RANDOM_H */
35224 +diff -Nurp linux-2.6.23.15/include/linux/sched.h linux-2.6.23.15-grsec/include/linux/sched.h
35225 +--- linux-2.6.23.15/include/linux/sched.h 2008-02-11 10:36:03.000000000 +0000
35226 ++++ linux-2.6.23.15-grsec/include/linux/sched.h 2008-02-11 10:37:45.000000000 +0000
35227 +@@ -92,6 +92,7 @@ struct sched_param {
35228 + struct exec_domain;
35229 + struct futex_pi_state;
35230 + struct bio;
35231 ++struct linux_binprm;
35232 +
35233 + /*
35234 + * List of flags we want to share for kernel threads,
35235 +@@ -432,6 +433,24 @@ struct mm_struct {
35236 + /* aio bits */
35237 + rwlock_t ioctx_list_lock;
35238 + struct kioctx *ioctx_list;
35239 ++
35240 ++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
35241 ++ unsigned long pax_flags;
35242 ++#endif
35243 ++
35244 ++#ifdef CONFIG_PAX_DLRESOLVE
35245 ++ unsigned long call_dl_resolve;
35246 ++#endif
35247 ++
35248 ++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
35249 ++ unsigned long call_syscall;
35250 ++#endif
35251 ++
35252 ++#ifdef CONFIG_PAX_ASLR
35253 ++ unsigned long delta_mmap; /* randomized offset */
35254 ++ unsigned long delta_stack; /* randomized offset */
35255 ++#endif
35256 ++
35257 + };
35258 +
35259 + struct sighand_struct {
35260 +@@ -556,6 +575,15 @@ struct signal_struct {
35261 + unsigned audit_tty;
35262 + struct tty_audit_buf *tty_audit_buf;
35263 + #endif
35264 ++
35265 ++#ifdef CONFIG_GRKERNSEC
35266 ++ u32 curr_ip;
35267 ++ u32 gr_saddr;
35268 ++ u32 gr_daddr;
35269 ++ u16 gr_sport;
35270 ++ u16 gr_dport;
35271 ++ u8 used_accept:1;
35272 ++#endif
35273 + };
35274 +
35275 + /* Context switch must be unlocked if interrupts are to be enabled */
35276 +@@ -1017,8 +1045,8 @@ struct task_struct {
35277 + struct list_head thread_group;
35278 +
35279 + struct completion *vfork_done; /* for vfork() */
35280 +- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
35281 +- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
35282 ++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
35283 ++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
35284 +
35285 + unsigned int rt_priority;
35286 + cputime_t utime, stime;
35287 +@@ -1183,6 +1211,17 @@ struct task_struct {
35288 + struct list_head pi_state_list;
35289 + struct futex_pi_state *pi_state_cache;
35290 +
35291 ++#ifdef CONFIG_GRKERNSEC
35292 ++ /* grsecurity */
35293 ++ struct acl_subject_label *acl;
35294 ++ struct acl_role_label *role;
35295 ++ struct file *exec_file;
35296 ++ u16 acl_role_id;
35297 ++ u8 acl_sp_role:1;
35298 ++ u8 is_writable:1;
35299 ++ u8 brute:1;
35300 ++#endif
35301 ++
35302 + atomic_t fs_excl; /* holding fs exclusive resources */
35303 + struct rcu_head rcu;
35304 +
35305 +@@ -1198,6 +1237,46 @@ struct task_struct {
35306 + #endif
35307 + };
35308 +
35309 ++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
35310 ++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
35311 ++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
35312 ++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
35313 ++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
35314 ++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
35315 ++
35316 ++#ifdef CONFIG_PAX_SOFTMODE
35317 ++extern unsigned int pax_softmode;
35318 ++#endif
35319 ++
35320 ++extern int pax_check_flags(unsigned long *);
35321 ++
35322 ++/* if tsk != current then task_lock must be held on it */
35323 ++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
35324 ++static inline unsigned long pax_get_flags(struct task_struct *tsk)
35325 ++{
35326 ++ if (likely(tsk->mm))
35327 ++ return tsk->mm->pax_flags;
35328 ++ else
35329 ++ return 0UL;
35330 ++}
35331 ++
35332 ++/* if tsk != current then task_lock must be held on it */
35333 ++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
35334 ++{
35335 ++ if (likely(tsk->mm)) {
35336 ++ tsk->mm->pax_flags = flags;
35337 ++ return 0;
35338 ++ }
35339 ++ return -EINVAL;
35340 ++}
35341 ++#endif
35342 ++
35343 ++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
35344 ++extern void pax_set_initial_flags(struct linux_binprm *bprm);
35345 ++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
35346 ++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
35347 ++#endif
35348 ++
35349 + /*
35350 + * Priority of a process goes from 0..MAX_PRIO-1, valid RT
35351 + * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
35352 +@@ -1831,6 +1910,12 @@ extern void arch_pick_mmap_layout(struct
35353 + static inline void arch_pick_mmap_layout(struct mm_struct *mm)
35354 + {
35355 + mm->mmap_base = TASK_UNMAPPED_BASE;
35356 ++
35357 ++#ifdef CONFIG_PAX_RANDMMAP
35358 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
35359 ++ mm->mmap_base += mm->delta_mmap;
35360 ++#endif
35361 ++
35362 + mm->get_unmapped_area = arch_get_unmapped_area;
35363 + mm->unmap_area = arch_unmap_area;
35364 + }
35365 +diff -Nurp linux-2.6.23.15/include/linux/screen_info.h linux-2.6.23.15-grsec/include/linux/screen_info.h
35366 +--- linux-2.6.23.15/include/linux/screen_info.h 2007-10-09 21:31:38.000000000 +0100
35367 ++++ linux-2.6.23.15-grsec/include/linux/screen_info.h 2008-02-11 10:37:45.000000000 +0000
35368 +@@ -42,7 +42,8 @@ struct screen_info {
35369 + u16 pages; /* 0x32 */
35370 + u16 vesa_attributes; /* 0x34 */
35371 + u32 capabilities; /* 0x36 */
35372 +- u8 _reserved[6]; /* 0x3a */
35373 ++ u16 vesapm_size; /* 0x3a */
35374 ++ u8 _reserved[4]; /* 0x3c */
35375 + } __attribute__((packed));
35376 +
35377 + extern struct screen_info screen_info;
35378 +diff -Nurp linux-2.6.23.15/include/linux/security.h linux-2.6.23.15-grsec/include/linux/security.h
35379 +--- linux-2.6.23.15/include/linux/security.h 2007-10-09 21:31:38.000000000 +0100
35380 ++++ linux-2.6.23.15-grsec/include/linux/security.h 2008-02-11 10:37:45.000000000 +0000
35381 +@@ -2796,7 +2796,7 @@ static inline struct dentry *securityfs_
35382 + mode_t mode,
35383 + struct dentry *parent,
35384 + void *data,
35385 +- struct file_operations *fops)
35386 ++ const struct file_operations *fops)
35387 + {
35388 + return ERR_PTR(-ENODEV);
35389 + }
35390 +diff -Nurp linux-2.6.23.15/include/linux/shm.h linux-2.6.23.15-grsec/include/linux/shm.h
35391 +--- linux-2.6.23.15/include/linux/shm.h 2007-10-09 21:31:38.000000000 +0100
35392 ++++ linux-2.6.23.15-grsec/include/linux/shm.h 2008-02-11 10:37:45.000000000 +0000
35393 +@@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
35394 + pid_t shm_cprid;
35395 + pid_t shm_lprid;
35396 + struct user_struct *mlock_user;
35397 ++#ifdef CONFIG_GRKERNSEC
35398 ++ time_t shm_createtime;
35399 ++ pid_t shm_lapid;
35400 ++#endif
35401 + };
35402 +
35403 + /* shm_mode upper byte flags */
35404 +diff -Nurp linux-2.6.23.15/include/linux/skbuff.h linux-2.6.23.15-grsec/include/linux/skbuff.h
35405 +--- linux-2.6.23.15/include/linux/skbuff.h 2008-02-11 10:36:03.000000000 +0000
35406 ++++ linux-2.6.23.15-grsec/include/linux/skbuff.h 2008-02-11 10:37:45.000000000 +0000
35407 +@@ -385,7 +385,7 @@ extern void skb_truesize_bug(struc
35408 +
35409 + static inline void skb_truesize_check(struct sk_buff *skb)
35410 + {
35411 +- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
35412 ++ if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
35413 + skb_truesize_bug(skb);
35414 + }
35415 +
35416 +diff -Nurp linux-2.6.23.15/include/linux/sysctl.h linux-2.6.23.15-grsec/include/linux/sysctl.h
35417 +--- linux-2.6.23.15/include/linux/sysctl.h 2008-02-11 10:36:24.000000000 +0000
35418 ++++ linux-2.6.23.15-grsec/include/linux/sysctl.h 2008-02-11 10:37:45.000000000 +0000
35419 +@@ -168,9 +168,22 @@ enum
35420 + #ifdef CONFIG_ALPHA_UAC_SYSCTL
35421 + KERN_UAC_POLICY=78, /* int: Alpha unaligned access control policy flags */
35422 + #endif /* CONFIG_ALPHA_UAC_SYSCTL */
35423 +-};
35424 +
35425 ++#ifdef CONFIG_GRKERNSEC
35426 ++ KERN_GRSECURITY=98, /* grsecurity */
35427 ++#endif
35428 ++
35429 ++#ifdef CONFIG_PAX_SOFTMODE
35430 ++ KERN_PAX=99, /* PaX control */
35431 ++#endif
35432 ++
35433 ++};
35434 +
35435 ++#ifdef CONFIG_PAX_SOFTMODE
35436 ++enum {
35437 ++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
35438 ++};
35439 ++#endif
35440 +
35441 + /* CTL_VM names: */
35442 + enum
35443 +diff -Nurp linux-2.6.23.15/include/linux/uaccess.h linux-2.6.23.15-grsec/include/linux/uaccess.h
35444 +--- linux-2.6.23.15/include/linux/uaccess.h 2007-10-09 21:31:38.000000000 +0100
35445 ++++ linux-2.6.23.15-grsec/include/linux/uaccess.h 2008-02-11 10:37:45.000000000 +0000
35446 +@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
35447 + long ret; \
35448 + mm_segment_t old_fs = get_fs(); \
35449 + \
35450 +- set_fs(KERNEL_DS); \
35451 + pagefault_disable(); \
35452 ++ set_fs(KERNEL_DS); \
35453 + ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
35454 +- pagefault_enable(); \
35455 + set_fs(old_fs); \
35456 ++ pagefault_enable(); \
35457 + ret; \
35458 + })
35459 +
35460 +diff -Nurp linux-2.6.23.15/include/linux/udf_fs.h linux-2.6.23.15-grsec/include/linux/udf_fs.h
35461 +--- linux-2.6.23.15/include/linux/udf_fs.h 2007-10-09 21:31:38.000000000 +0100
35462 ++++ linux-2.6.23.15-grsec/include/linux/udf_fs.h 2008-02-11 10:37:45.000000000 +0000
35463 +@@ -45,7 +45,7 @@
35464 + printk (f, ##a); \
35465 + }
35466 + #else
35467 +-#define udf_debug(f, a...) /**/
35468 ++#define udf_debug(f, a...) do {} while (0)
35469 + #endif
35470 +
35471 + #define udf_info(f, a...) \
35472 +diff -Nurp linux-2.6.23.15/include/net/sctp/sctp.h linux-2.6.23.15-grsec/include/net/sctp/sctp.h
35473 +--- linux-2.6.23.15/include/net/sctp/sctp.h 2007-10-09 21:31:38.000000000 +0100
35474 ++++ linux-2.6.23.15-grsec/include/net/sctp/sctp.h 2008-02-11 10:37:45.000000000 +0000
35475 +@@ -317,8 +317,8 @@ extern int sctp_debug_flag;
35476 +
35477 + #else /* SCTP_DEBUG */
35478 +
35479 +-#define SCTP_DEBUG_PRINTK(whatever...)
35480 +-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
35481 ++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
35482 ++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
35483 + #define SCTP_ENABLE_DEBUG
35484 + #define SCTP_DISABLE_DEBUG
35485 + #define SCTP_ASSERT(expr, str, func)
35486 +diff -Nurp linux-2.6.23.15/include/sound/core.h linux-2.6.23.15-grsec/include/sound/core.h
35487 +--- linux-2.6.23.15/include/sound/core.h 2007-10-09 21:31:38.000000000 +0100
35488 ++++ linux-2.6.23.15-grsec/include/sound/core.h 2008-02-11 10:37:45.000000000 +0000
35489 +@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
35490 +
35491 + #else /* !CONFIG_SND_DEBUG */
35492 +
35493 +-#define snd_printd(fmt, args...) /* nothing */
35494 ++#define snd_printd(fmt, args...) do {} while (0)
35495 + #define snd_assert(expr, args...) (void)(expr)
35496 +-#define snd_BUG() /* nothing */
35497 ++#define snd_BUG() do {} while (0)
35498 +
35499 + #endif /* CONFIG_SND_DEBUG */
35500 +
35501 +@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
35502 + */
35503 + #define snd_printdd(format, args...) snd_printk(format, ##args)
35504 + #else
35505 +-#define snd_printdd(format, args...) /* nothing */
35506 ++#define snd_printdd(format, args...) do {} while (0)
35507 + #endif
35508 +
35509 +
35510 +diff -Nurp linux-2.6.23.15/init/Kconfig linux-2.6.23.15-grsec/init/Kconfig
35511 +--- linux-2.6.23.15/init/Kconfig 2007-10-09 21:31:38.000000000 +0100
35512 ++++ linux-2.6.23.15-grsec/init/Kconfig 2008-02-11 10:37:45.000000000 +0000
35513 +@@ -384,6 +384,7 @@ config SYSCTL_SYSCALL
35514 + config KALLSYMS
35515 + bool "Load all symbols for debugging/ksymoops" if EMBEDDED
35516 + default y
35517 ++ depends on !GRKERNSEC_HIDESYM
35518 + help
35519 + Say Y here to let the kernel print out symbolic crash information and
35520 + symbolic stack backtraces. This increases the size of the kernel
35521 +diff -Nurp linux-2.6.23.15/init/do_mounts.c linux-2.6.23.15-grsec/init/do_mounts.c
35522 +--- linux-2.6.23.15/init/do_mounts.c 2007-10-09 21:31:38.000000000 +0100
35523 ++++ linux-2.6.23.15-grsec/init/do_mounts.c 2008-02-11 10:37:45.000000000 +0000
35524 +@@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa
35525 +
35526 + /* read device number from .../dev */
35527 +
35528 +- sprintf(path, "/sys/block/%s/dev", name);
35529 +- fd = sys_open(path, 0, 0);
35530 ++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
35531 ++ goto fail;
35532 ++ fd = sys_open((char __user *)path, 0, 0);
35533 + if (fd < 0)
35534 + goto fail;
35535 +- len = sys_read(fd, buf, 32);
35536 ++ len = sys_read(fd, (char __user *)buf, 32);
35537 + sys_close(fd);
35538 + if (len <= 0 || len == 32 || buf[len - 1] != '\n')
35539 + goto fail;
35540 +@@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa
35541 + return res;
35542 +
35543 + /* otherwise read range from .../range */
35544 +- sprintf(path, "/sys/block/%s/range", name);
35545 +- fd = sys_open(path, 0, 0);
35546 ++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
35547 ++ goto fail;
35548 ++ fd = sys_open((char __user *)path, 0, 0);
35549 + if (fd < 0)
35550 + goto fail;
35551 +- len = sys_read(fd, buf, 32);
35552 ++ len = sys_read(fd, (char __user *)buf, 32);
35553 + sys_close(fd);
35554 + if (len <= 0 || len == 32 || buf[len - 1] != '\n')
35555 + goto fail;
35556 +@@ -145,8 +147,8 @@ dev_t name_to_dev_t(char *name)
35557 + int part;
35558 +
35559 + #ifdef CONFIG_SYSFS
35560 +- int mkdir_err = sys_mkdir("/sys", 0700);
35561 +- if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
35562 ++ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
35563 ++ if (sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL) < 0)
35564 + goto out;
35565 + #endif
35566 +
35567 +@@ -198,10 +200,10 @@ dev_t name_to_dev_t(char *name)
35568 + res = try_name(s, part);
35569 + done:
35570 + #ifdef CONFIG_SYSFS
35571 +- sys_umount("/sys", 0);
35572 ++ sys_umount((char __user *)"/sys", 0);
35573 + out:
35574 + if (!mkdir_err)
35575 +- sys_rmdir("/sys");
35576 ++ sys_rmdir((char __user *)"/sys");
35577 + #endif
35578 + return res;
35579 + fail:
35580 +@@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa
35581 +
35582 + static int __init do_mount_root(char *name, char *fs, int flags, void *data)
35583 + {
35584 +- int err = sys_mount(name, "/root", fs, flags, data);
35585 ++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
35586 + if (err)
35587 + return err;
35588 +
35589 +- sys_chdir("/root");
35590 ++ sys_chdir((char __user *)"/root");
35591 + ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
35592 + printk("VFS: Mounted root (%s filesystem)%s.\n",
35593 + current->fs->pwdmnt->mnt_sb->s_type->name,
35594 +@@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ...
35595 + va_start(args, fmt);
35596 + vsprintf(buf, fmt, args);
35597 + va_end(args);
35598 +- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
35599 ++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
35600 + if (fd >= 0) {
35601 + sys_ioctl(fd, FDEJECT, 0);
35602 + sys_close(fd);
35603 + }
35604 + printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
35605 +- fd = sys_open("/dev/console", O_RDWR, 0);
35606 ++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
35607 + if (fd >= 0) {
35608 + sys_ioctl(fd, TCGETS, (long)&termios);
35609 + termios.c_lflag &= ~ICANON;
35610 + sys_ioctl(fd, TCSETSF, (long)&termios);
35611 +- sys_read(fd, &c, 1);
35612 ++ sys_read(fd, (char __user *)&c, 1);
35613 + termios.c_lflag |= ICANON;
35614 + sys_ioctl(fd, TCSETSF, (long)&termios);
35615 + sys_close(fd);
35616 +@@ -468,8 +470,8 @@ void __init prepare_namespace(void)
35617 +
35618 + mount_root();
35619 + out:
35620 +- sys_mount(".", "/", NULL, MS_MOVE, NULL);
35621 +- sys_chroot(".");
35622 ++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
35623 ++ sys_chroot((char __user *)".");
35624 + security_sb_post_mountroot();
35625 + }
35626 +
35627 +diff -Nurp linux-2.6.23.15/init/do_mounts.h linux-2.6.23.15-grsec/init/do_mounts.h
35628 +--- linux-2.6.23.15/init/do_mounts.h 2007-10-09 21:31:38.000000000 +0100
35629 ++++ linux-2.6.23.15-grsec/init/do_mounts.h 2008-02-11 10:37:45.000000000 +0000
35630 +@@ -15,15 +15,15 @@ extern char *root_device_name;
35631 +
35632 + static inline int create_dev(char *name, dev_t dev)
35633 + {
35634 +- sys_unlink(name);
35635 +- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
35636 ++ sys_unlink((char __user *)name);
35637 ++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
35638 + }
35639 +
35640 + #if BITS_PER_LONG == 32
35641 + static inline u32 bstat(char *name)
35642 + {
35643 + struct stat64 stat;
35644 +- if (sys_stat64(name, &stat) != 0)
35645 ++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
35646 + return 0;
35647 + if (!S_ISBLK(stat.st_mode))
35648 + return 0;
35649 +diff -Nurp linux-2.6.23.15/init/do_mounts_md.c linux-2.6.23.15-grsec/init/do_mounts_md.c
35650 +--- linux-2.6.23.15/init/do_mounts_md.c 2007-10-09 21:31:38.000000000 +0100
35651 ++++ linux-2.6.23.15-grsec/init/do_mounts_md.c 2008-02-11 10:37:45.000000000 +0000
35652 +@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
35653 + partitioned ? "_d" : "", minor,
35654 + md_setup_args[ent].device_names);
35655 +
35656 +- fd = sys_open(name, 0, 0);
35657 ++ fd = sys_open((char __user *)name, 0, 0);
35658 + if (fd < 0) {
35659 + printk(KERN_ERR "md: open failed - cannot start "
35660 + "array %s\n", name);
35661 +@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
35662 + * array without it
35663 + */
35664 + sys_close(fd);
35665 +- fd = sys_open(name, 0, 0);
35666 ++ fd = sys_open((char __user *)name, 0, 0);
35667 + sys_ioctl(fd, BLKRRPART, 0);
35668 + }
35669 + sys_close(fd);
35670 +@@ -271,7 +271,7 @@ void __init md_run_setup(void)
35671 + if (raid_noautodetect)
35672 + printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
35673 + else {
35674 +- int fd = sys_open("/dev/md0", 0, 0);
35675 ++ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
35676 + if (fd >= 0) {
35677 + sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
35678 + sys_close(fd);
35679 +diff -Nurp linux-2.6.23.15/init/initramfs.c linux-2.6.23.15-grsec/init/initramfs.c
35680 +--- linux-2.6.23.15/init/initramfs.c 2007-10-09 21:31:38.000000000 +0100
35681 ++++ linux-2.6.23.15-grsec/init/initramfs.c 2008-02-11 10:37:45.000000000 +0000
35682 +@@ -240,7 +240,7 @@ static int __init maybe_link(void)
35683 + if (nlink >= 2) {
35684 + char *old = find_link(major, minor, ino, mode, collected);
35685 + if (old)
35686 +- return (sys_link(old, collected) < 0) ? -1 : 1;
35687 ++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
35688 + }
35689 + return 0;
35690 + }
35691 +@@ -249,11 +249,11 @@ static void __init clean_path(char *path
35692 + {
35693 + struct stat st;
35694 +
35695 +- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
35696 ++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
35697 + if (S_ISDIR(st.st_mode))
35698 +- sys_rmdir(path);
35699 ++ sys_rmdir((char __user *)path);
35700 + else
35701 +- sys_unlink(path);
35702 ++ sys_unlink((char __user *)path);
35703 + }
35704 + }
35705 +
35706 +@@ -276,7 +276,7 @@ static int __init do_name(void)
35707 + int openflags = O_WRONLY|O_CREAT;
35708 + if (ml != 1)
35709 + openflags |= O_TRUNC;
35710 +- wfd = sys_open(collected, openflags, mode);
35711 ++ wfd = sys_open((char __user *)collected, openflags, mode);
35712 +
35713 + if (wfd >= 0) {
35714 + sys_fchown(wfd, uid, gid);
35715 +@@ -285,15 +285,15 @@ static int __init do_name(void)
35716 + }
35717 + }
35718 + } else if (S_ISDIR(mode)) {
35719 +- sys_mkdir(collected, mode);
35720 +- sys_chown(collected, uid, gid);
35721 +- sys_chmod(collected, mode);
35722 ++ sys_mkdir((char __user *)collected, mode);
35723 ++ sys_chown((char __user *)collected, uid, gid);
35724 ++ sys_chmod((char __user *)collected, mode);
35725 + } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
35726 + S_ISFIFO(mode) || S_ISSOCK(mode)) {
35727 + if (maybe_link() == 0) {
35728 +- sys_mknod(collected, mode, rdev);
35729 +- sys_chown(collected, uid, gid);
35730 +- sys_chmod(collected, mode);
35731 ++ sys_mknod((char __user *)collected, mode, rdev);
35732 ++ sys_chown((char __user *)collected, uid, gid);
35733 ++ sys_chmod((char __user *)collected, mode);
35734 + }
35735 + }
35736 + return 0;
35737 +@@ -302,13 +302,13 @@ static int __init do_name(void)
35738 + static int __init do_copy(void)
35739 + {
35740 + if (count >= body_len) {
35741 +- sys_write(wfd, victim, body_len);
35742 ++ sys_write(wfd, (char __user *)victim, body_len);
35743 + sys_close(wfd);
35744 + eat(body_len);
35745 + state = SkipIt;
35746 + return 0;
35747 + } else {
35748 +- sys_write(wfd, victim, count);
35749 ++ sys_write(wfd, (char __user *)victim, count);
35750 + body_len -= count;
35751 + eat(count);
35752 + return 1;
35753 +@@ -319,8 +319,8 @@ static int __init do_symlink(void)
35754 + {
35755 + collected[N_ALIGN(name_len) + body_len] = '\0';
35756 + clean_path(collected, 0);
35757 +- sys_symlink(collected + N_ALIGN(name_len), collected);
35758 +- sys_lchown(collected, uid, gid);
35759 ++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
35760 ++ sys_lchown((char __user *)collected, uid, gid);
35761 + state = SkipIt;
35762 + next_state = Reset;
35763 + return 0;
35764 +diff -Nurp linux-2.6.23.15/init/main.c linux-2.6.23.15-grsec/init/main.c
35765 +--- linux-2.6.23.15/init/main.c 2007-10-09 21:31:38.000000000 +0100
35766 ++++ linux-2.6.23.15-grsec/init/main.c 2008-02-11 10:37:45.000000000 +0000
35767 +@@ -107,6 +107,7 @@ static inline void mark_rodata_ro(void)
35768 + #ifdef CONFIG_TC
35769 + extern void tc_init(void);
35770 + #endif
35771 ++extern void grsecurity_init(void);
35772 +
35773 + enum system_states system_state;
35774 + EXPORT_SYMBOL(system_state);
35775 +@@ -193,6 +194,17 @@ static int __init set_reset_devices(char
35776 +
35777 + __setup("reset_devices", set_reset_devices);
35778 +
35779 ++#ifdef CONFIG_PAX_SOFTMODE
35780 ++unsigned int pax_softmode;
35781 ++
35782 ++static int __init setup_pax_softmode(char *str)
35783 ++{
35784 ++ get_option(&str, &pax_softmode);
35785 ++ return 1;
35786 ++}
35787 ++__setup("pax_softmode=", setup_pax_softmode);
35788 ++#endif
35789 ++
35790 + static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
35791 + char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
35792 + static const char *panic_later, *panic_param;
35793 +@@ -854,6 +866,8 @@ static int __init kernel_init(void * unu
35794 + prepare_namespace();
35795 + }
35796 +
35797 ++ grsecurity_init();
35798 ++
35799 + /*
35800 + * Ok, we have completed the initial bootup, and
35801 + * we're essentially up and running. Get rid of the
35802 +diff -Nurp linux-2.6.23.15/init/noinitramfs.c linux-2.6.23.15-grsec/init/noinitramfs.c
35803 +--- linux-2.6.23.15/init/noinitramfs.c 2007-10-09 21:31:38.000000000 +0100
35804 ++++ linux-2.6.23.15-grsec/init/noinitramfs.c 2008-02-11 10:37:45.000000000 +0000
35805 +@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
35806 + {
35807 + int err;
35808 +
35809 +- err = sys_mkdir("/dev", 0755);
35810 ++ err = sys_mkdir((const char __user *)"/dev", 0755);
35811 + if (err < 0)
35812 + goto out;
35813 +
35814 +@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
35815 + if (err < 0)
35816 + goto out;
35817 +
35818 +- err = sys_mkdir("/root", 0700);
35819 ++ err = sys_mkdir((const char __user *)"/root", 0700);
35820 + if (err < 0)
35821 + goto out;
35822 +
35823 +diff -Nurp linux-2.6.23.15/ipc/ipc_sysctl.c linux-2.6.23.15-grsec/ipc/ipc_sysctl.c
35824 +--- linux-2.6.23.15/ipc/ipc_sysctl.c 2007-10-09 21:31:38.000000000 +0100
35825 ++++ linux-2.6.23.15-grsec/ipc/ipc_sysctl.c 2008-02-11 10:37:45.000000000 +0000
35826 +@@ -161,7 +161,7 @@ static struct ctl_table ipc_kern_table[]
35827 + .proc_handler = proc_ipc_dointvec,
35828 + .strategy = sysctl_ipc_data,
35829 + },
35830 +- {}
35831 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35832 + };
35833 +
35834 + static struct ctl_table ipc_root_table[] = {
35835 +@@ -171,7 +171,7 @@ static struct ctl_table ipc_root_table[]
35836 + .mode = 0555,
35837 + .child = ipc_kern_table,
35838 + },
35839 +- {}
35840 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
35841 + };
35842 +
35843 + static int __init ipc_sysctl_init(void)
35844 +diff -Nurp linux-2.6.23.15/ipc/msg.c linux-2.6.23.15-grsec/ipc/msg.c
35845 +--- linux-2.6.23.15/ipc/msg.c 2007-10-09 21:31:38.000000000 +0100
35846 ++++ linux-2.6.23.15-grsec/ipc/msg.c 2008-02-11 10:37:45.000000000 +0000
35847 +@@ -36,6 +36,7 @@
35848 + #include <linux/seq_file.h>
35849 + #include <linux/mutex.h>
35850 + #include <linux/nsproxy.h>
35851 ++#include <linux/grsecurity.h>
35852 +
35853 + #include <asm/current.h>
35854 + #include <asm/uaccess.h>
35855 +@@ -286,6 +287,8 @@ asmlinkage long sys_msgget(key_t key, in
35856 + }
35857 + mutex_unlock(&msg_ids(ns).mutex);
35858 +
35859 ++ gr_log_msgget(ret, msgflg);
35860 ++
35861 + return ret;
35862 + }
35863 +
35864 +@@ -552,6 +555,7 @@ asmlinkage long sys_msgctl(int msqid, in
35865 + break;
35866 + }
35867 + case IPC_RMID:
35868 ++ gr_log_msgrm(ipcp->uid, ipcp->cuid);
35869 + freeque(ns, msq, msqid);
35870 + break;
35871 + }
35872 +diff -Nurp linux-2.6.23.15/ipc/sem.c linux-2.6.23.15-grsec/ipc/sem.c
35873 +--- linux-2.6.23.15/ipc/sem.c 2007-10-09 21:31:38.000000000 +0100
35874 ++++ linux-2.6.23.15-grsec/ipc/sem.c 2008-02-11 10:37:45.000000000 +0000
35875 +@@ -82,6 +82,7 @@
35876 + #include <linux/seq_file.h>
35877 + #include <linux/mutex.h>
35878 + #include <linux/nsproxy.h>
35879 ++#include <linux/grsecurity.h>
35880 +
35881 + #include <asm/uaccess.h>
35882 + #include "util.h"
35883 +@@ -293,6 +294,9 @@ asmlinkage long sys_semget (key_t key, i
35884 + }
35885 +
35886 + mutex_unlock(&sem_ids(ns).mutex);
35887 ++
35888 ++ gr_log_semget(err, semflg);
35889 ++
35890 + return err;
35891 + }
35892 +
35893 +@@ -894,6 +898,7 @@ static int semctl_down(struct ipc_namesp
35894 +
35895 + switch(cmd){
35896 + case IPC_RMID:
35897 ++ gr_log_semrm(ipcp->uid, ipcp->cuid);
35898 + freeary(ns, sma, semid);
35899 + err = 0;
35900 + break;
35901 +diff -Nurp linux-2.6.23.15/ipc/shm.c linux-2.6.23.15-grsec/ipc/shm.c
35902 +--- linux-2.6.23.15/ipc/shm.c 2007-10-09 21:31:38.000000000 +0100
35903 ++++ linux-2.6.23.15-grsec/ipc/shm.c 2008-02-11 10:37:45.000000000 +0000
35904 +@@ -38,6 +38,7 @@
35905 + #include <linux/mutex.h>
35906 + #include <linux/nsproxy.h>
35907 + #include <linux/mount.h>
35908 ++#include <linux/grsecurity.h>
35909 +
35910 + #include <asm/uaccess.h>
35911 +
35912 +@@ -77,6 +78,14 @@ static void shm_destroy (struct ipc_name
35913 + static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
35914 + #endif
35915 +
35916 ++#ifdef CONFIG_GRKERNSEC
35917 ++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
35918 ++ const time_t shm_createtime, const uid_t cuid,
35919 ++ const int shmid);
35920 ++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
35921 ++ const time_t shm_createtime);
35922 ++#endif
35923 ++
35924 + static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
35925 + {
35926 + ns->ids[IPC_SHM_IDS] = ids;
35927 +@@ -89,6 +98,8 @@ static void __shm_init_ns(struct ipc_nam
35928 +
35929 + static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
35930 + {
35931 ++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
35932 ++
35933 + if (shp->shm_nattch){
35934 + shp->shm_perm.mode |= SHM_DEST;
35935 + /* Do not find it any more */
35936 +@@ -216,6 +227,17 @@ static void shm_close(struct vm_area_str
35937 + shp->shm_lprid = current->tgid;
35938 + shp->shm_dtim = get_seconds();
35939 + shp->shm_nattch--;
35940 ++#ifdef CONFIG_GRKERNSEC_SHM
35941 ++ if (grsec_enable_shm) {
35942 ++ if (shp->shm_nattch == 0) {
35943 ++ shp->shm_perm.mode |= SHM_DEST;
35944 ++ shm_destroy(ns, shp);
35945 ++ } else
35946 ++ shm_unlock(shp);
35947 ++ mutex_unlock(&shm_ids(ns).mutex);
35948 ++ return;
35949 ++ }
35950 ++#endif
35951 + if(shp->shm_nattch == 0 &&
35952 + shp->shm_perm.mode & SHM_DEST)
35953 + shm_destroy(ns, shp);
35954 +@@ -395,6 +417,9 @@ static int newseg (struct ipc_namespace
35955 + shp->shm_lprid = 0;
35956 + shp->shm_atim = shp->shm_dtim = 0;
35957 + shp->shm_ctim = get_seconds();
35958 ++#ifdef CONFIG_GRKERNSEC
35959 ++ shp->shm_createtime = get_seconds();
35960 ++#endif
35961 + shp->shm_segsz = size;
35962 + shp->shm_nattch = 0;
35963 + shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
35964 +@@ -452,6 +477,8 @@ asmlinkage long sys_shmget (key_t key, s
35965 + }
35966 + mutex_unlock(&shm_ids(ns).mutex);
35967 +
35968 ++ gr_log_shmget(err, shmflg, size);
35969 ++
35970 + return err;
35971 + }
35972 +
35973 +@@ -905,9 +932,21 @@ long do_shmat(int shmid, char __user *sh
35974 + if (err)
35975 + goto out_unlock;
35976 +
35977 ++#ifdef CONFIG_GRKERNSEC
35978 ++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
35979 ++ shp->shm_perm.cuid, shmid) ||
35980 ++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
35981 ++ err = -EACCES;
35982 ++ goto out_unlock;
35983 ++ }
35984 ++#endif
35985 ++
35986 + path.dentry = dget(shp->shm_file->f_path.dentry);
35987 + path.mnt = mntget(shp->shm_file->f_path.mnt);
35988 + shp->shm_nattch++;
35989 ++#ifdef CONFIG_GRKERNSEC
35990 ++ shp->shm_lapid = current->pid;
35991 ++#endif
35992 + size = i_size_read(path.dentry->d_inode);
35993 + shm_unlock(shp);
35994 +
35995 +@@ -1111,3 +1150,27 @@ static int sysvipc_shm_proc_show(struct
35996 + shp->shm_ctim);
35997 + }
35998 + #endif
35999 ++
36000 ++void gr_shm_exit(struct task_struct *task)
36001 ++{
36002 ++#ifdef CONFIG_GRKERNSEC_SHM
36003 ++ int i;
36004 ++ struct shmid_kernel *shp;
36005 ++ struct ipc_namespace *ns;
36006 ++
36007 ++ ns = current->nsproxy->ipc_ns;
36008 ++
36009 ++ if (!grsec_enable_shm)
36010 ++ return;
36011 ++
36012 ++ for (i = 0; i <= shm_ids(ns).max_id; i++) {
36013 ++ shp = shm_get(ns, i);
36014 ++ if (shp && (shp->shm_cprid == task->pid) &&
36015 ++ (shp->shm_nattch <= 0)) {
36016 ++ shp->shm_perm.mode |= SHM_DEST;
36017 ++ shm_destroy(ns, shp);
36018 ++ }
36019 ++ }
36020 ++#endif
36021 ++ return;
36022 ++}
36023 +diff -Nurp linux-2.6.23.15/kernel/acct.c linux-2.6.23.15-grsec/kernel/acct.c
36024 +--- linux-2.6.23.15/kernel/acct.c 2007-10-09 21:31:38.000000000 +0100
36025 ++++ linux-2.6.23.15-grsec/kernel/acct.c 2008-02-11 10:37:45.000000000 +0000
36026 +@@ -511,7 +511,7 @@ static void do_acct_process(struct file
36027 + */
36028 + flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
36029 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
36030 +- file->f_op->write(file, (char *)&ac,
36031 ++ file->f_op->write(file, (char __user *)&ac,
36032 + sizeof(acct_t), &file->f_pos);
36033 + current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
36034 + set_fs(fs);
36035 +diff -Nurp linux-2.6.23.15/kernel/capability.c linux-2.6.23.15-grsec/kernel/capability.c
36036 +--- linux-2.6.23.15/kernel/capability.c 2007-10-09 21:31:38.000000000 +0100
36037 ++++ linux-2.6.23.15-grsec/kernel/capability.c 2008-02-11 10:37:45.000000000 +0000
36038 +@@ -12,6 +12,7 @@
36039 + #include <linux/module.h>
36040 + #include <linux/security.h>
36041 + #include <linux/syscalls.h>
36042 ++#include <linux/grsecurity.h>
36043 + #include <asm/uaccess.h>
36044 +
36045 + unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
36046 +@@ -236,14 +237,25 @@ out:
36047 + return ret;
36048 + }
36049 +
36050 ++extern int gr_task_is_capable(struct task_struct *task, const int cap);
36051 ++extern int gr_is_capable_nolog(const int cap);
36052 ++
36053 + int __capable(struct task_struct *t, int cap)
36054 + {
36055 +- if (security_capable(t, cap) == 0) {
36056 ++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
36057 + t->flags |= PF_SUPERPRIV;
36058 + return 1;
36059 + }
36060 + return 0;
36061 + }
36062 ++int capable_nolog(int cap)
36063 ++{
36064 ++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
36065 ++ current->flags |= PF_SUPERPRIV;
36066 ++ return 1;
36067 ++ }
36068 ++ return 0;
36069 ++}
36070 + EXPORT_SYMBOL(__capable);
36071 +
36072 + int capable(int cap)
36073 +@@ -251,3 +263,4 @@ int capable(int cap)
36074 + return __capable(current, cap);
36075 + }
36076 + EXPORT_SYMBOL(capable);
36077 ++EXPORT_SYMBOL(capable_nolog);
36078 +diff -Nurp linux-2.6.23.15/kernel/configs.c linux-2.6.23.15-grsec/kernel/configs.c
36079 +--- linux-2.6.23.15/kernel/configs.c 2007-10-09 21:31:38.000000000 +0100
36080 ++++ linux-2.6.23.15-grsec/kernel/configs.c 2008-02-11 10:37:45.000000000 +0000
36081 +@@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
36082 + struct proc_dir_entry *entry;
36083 +
36084 + /* create the current config file */
36085 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
36086 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
36087 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
36088 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36089 ++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
36090 ++#endif
36091 ++#else
36092 + entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
36093 + &proc_root);
36094 ++#endif
36095 + if (!entry)
36096 + return -ENOMEM;
36097 +
36098 +diff -Nurp linux-2.6.23.15/kernel/exit.c linux-2.6.23.15-grsec/kernel/exit.c
36099 +--- linux-2.6.23.15/kernel/exit.c 2008-02-11 10:36:03.000000000 +0000
36100 ++++ linux-2.6.23.15-grsec/kernel/exit.c 2008-02-11 10:37:45.000000000 +0000
36101 +@@ -45,6 +45,11 @@
36102 + #include <linux/blkdev.h>
36103 + #include <linux/task_io_accounting_ops.h>
36104 + #include <linux/freezer.h>
36105 ++#include <linux/grsecurity.h>
36106 ++
36107 ++#ifdef CONFIG_GRKERNSEC
36108 ++extern rwlock_t grsec_exec_file_lock;
36109 ++#endif
36110 +
36111 + #include <asm/uaccess.h>
36112 + #include <asm/unistd.h>
36113 +@@ -123,6 +128,7 @@ static void __exit_signal(struct task_st
36114 +
36115 + __unhash_process(tsk);
36116 +
36117 ++ gr_del_task_from_ip_table(tsk);
36118 + tsk->signal = NULL;
36119 + tsk->sighand = NULL;
36120 + spin_unlock(&sighand->siglock);
36121 +@@ -274,12 +280,23 @@ static void reparent_to_kthreadd(void)
36122 + {
36123 + write_lock_irq(&tasklist_lock);
36124 +
36125 ++#ifdef CONFIG_GRKERNSEC
36126 ++ write_lock(&grsec_exec_file_lock);
36127 ++ if (current->exec_file) {
36128 ++ fput(current->exec_file);
36129 ++ current->exec_file = NULL;
36130 ++ }
36131 ++ write_unlock(&grsec_exec_file_lock);
36132 ++#endif
36133 ++
36134 + ptrace_unlink(current);
36135 + /* Reparent to init */
36136 + remove_parent(current);
36137 + current->real_parent = current->parent = kthreadd_task;
36138 + add_parent(current);
36139 +
36140 ++ gr_set_kernel_label(current);
36141 ++
36142 + /* Set the exit signal to SIGCHLD so we signal init on exit */
36143 + current->exit_signal = SIGCHLD;
36144 +
36145 +@@ -374,6 +391,17 @@ void daemonize(const char *name, ...)
36146 + vsnprintf(current->comm, sizeof(current->comm), name, args);
36147 + va_end(args);
36148 +
36149 ++#ifdef CONFIG_GRKERNSEC
36150 ++ write_lock(&grsec_exec_file_lock);
36151 ++ if (current->exec_file) {
36152 ++ fput(current->exec_file);
36153 ++ current->exec_file = NULL;
36154 ++ }
36155 ++ write_unlock(&grsec_exec_file_lock);
36156 ++#endif
36157 ++
36158 ++ gr_set_kernel_label(current);
36159 ++
36160 + /*
36161 + * If we were started as result of loading a module, close all of the
36162 + * user space pages. We don't need them, and if we didn't close them
36163 +@@ -969,11 +997,15 @@ fastcall NORET_TYPE void do_exit(long co
36164 + tsk->exit_code = code;
36165 + taskstats_exit(tsk, group_dead);
36166 +
36167 ++ gr_acl_handle_psacct(tsk, code);
36168 ++ gr_acl_handle_exit();
36169 ++
36170 + exit_mm(tsk);
36171 +
36172 + if (group_dead)
36173 + acct_process();
36174 + exit_sem(tsk);
36175 ++ gr_shm_exit(tsk);
36176 + __exit_files(tsk);
36177 + __exit_fs(tsk);
36178 + check_stack_usage();
36179 +@@ -1174,7 +1206,7 @@ static int wait_task_zombie(struct task_
36180 + pid_t pid = p->pid;
36181 + uid_t uid = p->uid;
36182 + int exit_code = p->exit_code;
36183 +- int why, status;
36184 ++ int why;
36185 +
36186 + if (unlikely(p->exit_state != EXIT_ZOMBIE))
36187 + return 0;
36188 +diff -Nurp linux-2.6.23.15/kernel/fork.c linux-2.6.23.15-grsec/kernel/fork.c
36189 +--- linux-2.6.23.15/kernel/fork.c 2008-02-11 10:36:03.000000000 +0000
36190 ++++ linux-2.6.23.15-grsec/kernel/fork.c 2008-02-11 10:37:45.000000000 +0000
36191 +@@ -50,6 +50,7 @@
36192 + #include <linux/taskstats_kern.h>
36193 + #include <linux/random.h>
36194 + #include <linux/tty.h>
36195 ++#include <linux/grsecurity.h>
36196 +
36197 + #include <asm/pgtable.h>
36198 + #include <asm/pgalloc.h>
36199 +@@ -181,7 +182,7 @@ static struct task_struct *dup_task_stru
36200 + setup_thread_stack(tsk, orig);
36201 +
36202 + #ifdef CONFIG_CC_STACKPROTECTOR
36203 +- tsk->stack_canary = get_random_int();
36204 ++ tsk->stack_canary = pax_get_random_long();
36205 + #endif
36206 +
36207 + /* One for us, one for whoever does the "release_task()" (usually parent) */
36208 +@@ -203,6 +204,10 @@ static inline int dup_mmap(struct mm_str
36209 + unsigned long charge;
36210 + struct mempolicy *pol;
36211 +
36212 ++#ifdef CONFIG_PAX_SEGMEXEC
36213 ++ struct vm_area_struct *mpnt_m;
36214 ++#endif
36215 ++
36216 + down_write(&oldmm->mmap_sem);
36217 + flush_cache_dup_mm(oldmm);
36218 + /*
36219 +@@ -213,8 +218,8 @@ static inline int dup_mmap(struct mm_str
36220 + mm->locked_vm = 0;
36221 + mm->mmap = NULL;
36222 + mm->mmap_cache = NULL;
36223 +- mm->free_area_cache = oldmm->mmap_base;
36224 +- mm->cached_hole_size = ~0UL;
36225 ++ mm->free_area_cache = oldmm->free_area_cache;
36226 ++ mm->cached_hole_size = oldmm->cached_hole_size;
36227 + mm->map_count = 0;
36228 + cpus_clear(mm->cpu_vm_mask);
36229 + mm->mm_rb = RB_ROOT;
36230 +@@ -233,6 +238,7 @@ static inline int dup_mmap(struct mm_str
36231 + continue;
36232 + }
36233 + charge = 0;
36234 ++
36235 + if (mpnt->vm_flags & VM_ACCOUNT) {
36236 + unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
36237 + if (security_vm_enough_memory(len))
36238 +@@ -251,6 +257,7 @@ static inline int dup_mmap(struct mm_str
36239 + tmp->vm_flags &= ~VM_LOCKED;
36240 + tmp->vm_mm = mm;
36241 + tmp->vm_next = NULL;
36242 ++ tmp->vm_mirror = NULL;
36243 + anon_vma_link(tmp);
36244 + file = tmp->vm_file;
36245 + if (file) {
36246 +@@ -287,6 +294,29 @@ static inline int dup_mmap(struct mm_str
36247 + if (retval)
36248 + goto out;
36249 + }
36250 ++
36251 ++#ifdef CONFIG_PAX_SEGMEXEC
36252 ++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
36253 ++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
36254 ++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
36255 ++
36256 ++ if (!mpnt->vm_mirror)
36257 ++ continue;
36258 ++
36259 ++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
36260 ++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
36261 ++ mpnt->vm_mirror = mpnt_m;
36262 ++ } else {
36263 ++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
36264 ++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
36265 ++ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
36266 ++ mpnt->vm_mirror->vm_mirror = mpnt;
36267 ++ }
36268 ++ }
36269 ++ BUG_ON(mpnt_m);
36270 ++ }
36271 ++#endif
36272 ++
36273 + /* a new mm has just been created */
36274 + arch_dup_mmap(oldmm, mm);
36275 + retval = 0;
36276 +@@ -464,7 +494,7 @@ void mm_release(struct task_struct *tsk,
36277 + if (tsk->clear_child_tid
36278 + && !(tsk->flags & PF_SIGNALED)
36279 + && atomic_read(&mm->mm_users) > 1) {
36280 +- u32 __user * tidptr = tsk->clear_child_tid;
36281 ++ pid_t __user * tidptr = tsk->clear_child_tid;
36282 + tsk->clear_child_tid = NULL;
36283 +
36284 + /*
36285 +@@ -472,7 +502,7 @@ void mm_release(struct task_struct *tsk,
36286 + * not set up a proper pointer then tough luck.
36287 + */
36288 + put_user(0, tidptr);
36289 +- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
36290 ++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
36291 + }
36292 + }
36293 +
36294 +@@ -1001,6 +1031,9 @@ static struct task_struct *copy_process(
36295 + DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
36296 + #endif
36297 + retval = -EAGAIN;
36298 ++
36299 ++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
36300 ++
36301 + if (atomic_read(&p->user->processes) >=
36302 + p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
36303 + if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
36304 +@@ -1140,6 +1173,8 @@ static struct task_struct *copy_process(
36305 + if (retval)
36306 + goto bad_fork_cleanup_namespaces;
36307 +
36308 ++ gr_copy_label(p);
36309 ++
36310 + p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
36311 + /*
36312 + * Clear TID on mm_release()?
36313 +@@ -1318,6 +1353,8 @@ bad_fork_cleanup_count:
36314 + bad_fork_free:
36315 + free_task(p);
36316 + fork_out:
36317 ++ gr_log_forkfail(retval);
36318 ++
36319 + return ERR_PTR(retval);
36320 + }
36321 +
36322 +@@ -1391,6 +1428,8 @@ long do_fork(unsigned long clone_flags,
36323 + if (!IS_ERR(p)) {
36324 + struct completion vfork;
36325 +
36326 ++ gr_handle_brute_check();
36327 ++
36328 + if (clone_flags & CLONE_VFORK) {
36329 + p->vfork_done = &vfork;
36330 + init_completion(&vfork);
36331 +diff -Nurp linux-2.6.23.15/kernel/futex.c linux-2.6.23.15-grsec/kernel/futex.c
36332 +--- linux-2.6.23.15/kernel/futex.c 2008-02-11 10:36:03.000000000 +0000
36333 ++++ linux-2.6.23.15-grsec/kernel/futex.c 2008-02-11 10:37:45.000000000 +0000
36334 +@@ -186,6 +186,11 @@ int get_futex_key(u32 __user *uaddr, str
36335 + struct page *page;
36336 + int err;
36337 +
36338 ++#ifdef CONFIG_PAX_SEGMEXEC
36339 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
36340 ++ return -EFAULT;
36341 ++#endif
36342 ++
36343 + /*
36344 + * The futex address must be "naturally" aligned.
36345 + */
36346 +@@ -212,8 +217,8 @@ int get_futex_key(u32 __user *uaddr, str
36347 + * The futex is hashed differently depending on whether
36348 + * it's in a shared or private mapping. So check vma first.
36349 + */
36350 +- vma = find_extend_vma(mm, address);
36351 +- if (unlikely(!vma))
36352 ++ vma = find_vma(mm, address);
36353 ++ if (unlikely(!vma || address < vma->vm_start))
36354 + return -EFAULT;
36355 +
36356 + /*
36357 +@@ -1922,7 +1927,7 @@ retry:
36358 + */
36359 + static inline int fetch_robust_entry(struct robust_list __user **entry,
36360 + struct robust_list __user * __user *head,
36361 +- int *pi)
36362 ++ unsigned int *pi)
36363 + {
36364 + unsigned long uentry;
36365 +
36366 +diff -Nurp linux-2.6.23.15/kernel/irq/handle.c linux-2.6.23.15-grsec/kernel/irq/handle.c
36367 +--- linux-2.6.23.15/kernel/irq/handle.c 2007-10-09 21:31:38.000000000 +0100
36368 ++++ linux-2.6.23.15-grsec/kernel/irq/handle.c 2008-02-11 10:37:45.000000000 +0000
36369 +@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
36370 + .depth = 1,
36371 + .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
36372 + #ifdef CONFIG_SMP
36373 +- .affinity = CPU_MASK_ALL
36374 ++ .affinity = CPU_MASK_ALL,
36375 ++ .cpu = 0,
36376 + #endif
36377 + }
36378 + };
36379 +diff -Nurp linux-2.6.23.15/kernel/kallsyms.c linux-2.6.23.15-grsec/kernel/kallsyms.c
36380 +--- linux-2.6.23.15/kernel/kallsyms.c 2007-10-09 21:31:38.000000000 +0100
36381 ++++ linux-2.6.23.15-grsec/kernel/kallsyms.c 2008-02-11 10:37:45.000000000 +0000
36382 +@@ -65,6 +65,19 @@ static inline int is_kernel_text(unsigne
36383 +
36384 + static inline int is_kernel(unsigned long addr)
36385 + {
36386 ++
36387 ++#ifdef CONFIG_PAX_KERNEXEC
36388 ++
36389 ++#ifdef CONFIG_MODULES
36390 ++ if ((unsigned long)MODULES_VADDR <= addr + __KERNEL_TEXT_OFFSET &&
36391 ++ addr + __KERNEL_TEXT_OFFSET < (unsigned long)MODULES_END)
36392 ++ return 0;
36393 ++#endif
36394 ++
36395 ++ if (is_kernel_inittext(addr))
36396 ++ return 1;
36397 ++#endif
36398 ++
36399 + if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
36400 + return 1;
36401 + return in_gate_area_no_task(addr);
36402 +@@ -373,7 +386,6 @@ static unsigned long get_ksymbol_core(st
36403 +
36404 + static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
36405 + {
36406 +- iter->name[0] = '\0';
36407 + iter->nameoff = get_symbol_offset(new_pos);
36408 + iter->pos = new_pos;
36409 + }
36410 +@@ -457,7 +469,7 @@ static int kallsyms_open(struct inode *i
36411 + struct kallsym_iter *iter;
36412 + int ret;
36413 +
36414 +- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
36415 ++ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
36416 + if (!iter)
36417 + return -ENOMEM;
36418 + reset_iter(iter, 0);
36419 +@@ -481,7 +493,15 @@ static int __init kallsyms_init(void)
36420 + {
36421 + struct proc_dir_entry *entry;
36422 +
36423 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
36424 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
36425 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
36426 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
36427 ++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
36428 ++#endif
36429 ++#else
36430 + entry = create_proc_entry("kallsyms", 0444, NULL);
36431 ++#endif
36432 + if (entry)
36433 + entry->proc_fops = &kallsyms_operations;
36434 + return 0;
36435 +diff -Nurp linux-2.6.23.15/kernel/kprobes.c linux-2.6.23.15-grsec/kernel/kprobes.c
36436 +--- linux-2.6.23.15/kernel/kprobes.c 2007-10-09 21:31:38.000000000 +0100
36437 ++++ linux-2.6.23.15-grsec/kernel/kprobes.c 2008-02-11 10:37:45.000000000 +0000
36438 +@@ -168,7 +168,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
36439 + * kernel image and loaded module images reside. This is required
36440 + * so x86_64 can correctly handle the %rip-relative fixups.
36441 + */
36442 +- kip->insns = module_alloc(PAGE_SIZE);
36443 ++ kip->insns = module_alloc_exec(PAGE_SIZE);
36444 + if (!kip->insns) {
36445 + kfree(kip);
36446 + return NULL;
36447 +@@ -200,7 +200,7 @@ static int __kprobes collect_one_slot(st
36448 + hlist_add_head(&kip->hlist,
36449 + &kprobe_insn_pages);
36450 + } else {
36451 +- module_free(NULL, kip->insns);
36452 ++ module_free_exec(NULL, kip->insns);
36453 + kfree(kip);
36454 + }
36455 + return 1;
36456 +diff -Nurp linux-2.6.23.15/kernel/module.c linux-2.6.23.15-grsec/kernel/module.c
36457 +--- linux-2.6.23.15/kernel/module.c 2007-10-09 21:31:38.000000000 +0100
36458 ++++ linux-2.6.23.15-grsec/kernel/module.c 2008-02-11 10:37:45.000000000 +0000
36459 +@@ -44,6 +44,11 @@
36460 + #include <asm/uaccess.h>
36461 + #include <asm/semaphore.h>
36462 + #include <asm/cacheflush.h>
36463 ++
36464 ++#ifdef CONFIG_PAX_KERNEXEC
36465 ++#include <asm/desc.h>
36466 ++#endif
36467 ++
36468 + #include <linux/license.h>
36469 +
36470 + extern int module_sysfs_initialized;
36471 +@@ -68,6 +73,8 @@ static LIST_HEAD(modules);
36472 +
36473 + static BLOCKING_NOTIFIER_HEAD(module_notify_list);
36474 +
36475 ++extern int gr_check_modstop(void);
36476 ++
36477 + int register_module_notifier(struct notifier_block * nb)
36478 + {
36479 + return blocking_notifier_chain_register(&module_notify_list, nb);
36480 +@@ -347,7 +354,7 @@ static void *percpu_modalloc(unsigned lo
36481 + unsigned int i;
36482 + void *ptr;
36483 +
36484 +- if (align > PAGE_SIZE) {
36485 ++ if (align-1 >= PAGE_SIZE) {
36486 + printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
36487 + name, align, PAGE_SIZE);
36488 + align = PAGE_SIZE;
36489 +@@ -660,6 +667,9 @@ sys_delete_module(const char __user *nam
36490 + char name[MODULE_NAME_LEN];
36491 + int ret, forced = 0;
36492 +
36493 ++ if (gr_check_modstop())
36494 ++ return -EPERM;
36495 ++
36496 + if (!capable(CAP_SYS_MODULE))
36497 + return -EPERM;
36498 +
36499 +@@ -1209,16 +1219,19 @@ static void free_module(struct module *m
36500 + module_unload_free(mod);
36501 +
36502 + /* This may be NULL, but that's OK */
36503 +- module_free(mod, mod->module_init);
36504 ++ module_free(mod, mod->module_init_rw);
36505 ++ module_free_exec(mod, mod->module_init_rx);
36506 + kfree(mod->args);
36507 + if (mod->percpu)
36508 + percpu_modfree(mod->percpu);
36509 +
36510 + /* Free lock-classes: */
36511 +- lockdep_free_key_range(mod->module_core, mod->core_size);
36512 ++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
36513 ++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
36514 +
36515 + /* Finally, free the core (containing the module structure) */
36516 +- module_free(mod, mod->module_core);
36517 ++ module_free_exec(mod, mod->module_core_rx);
36518 ++ module_free(mod, mod->module_core_rw);
36519 + }
36520 +
36521 + void *__symbol_get(const char *symbol)
36522 +@@ -1279,10 +1292,14 @@ static int simplify_symbols(Elf_Shdr *se
36523 + struct module *mod)
36524 + {
36525 + Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
36526 +- unsigned long secbase;
36527 ++ unsigned long secbase, symbol;
36528 + unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
36529 + int ret = 0;
36530 +
36531 ++#ifdef CONFIG_PAX_KERNEXEC
36532 ++ unsigned long cr0;
36533 ++#endif
36534 ++
36535 + for (i = 1; i < n; i++) {
36536 + switch (sym[i].st_shndx) {
36537 + case SHN_COMMON:
36538 +@@ -1301,10 +1318,19 @@ static int simplify_symbols(Elf_Shdr *se
36539 + break;
36540 +
36541 + case SHN_UNDEF:
36542 +- sym[i].st_value
36543 +- = resolve_symbol(sechdrs, versindex,
36544 ++ symbol = resolve_symbol(sechdrs, versindex,
36545 + strtab + sym[i].st_name, mod);
36546 +
36547 ++#ifdef CONFIG_PAX_KERNEXEC
36548 ++ pax_open_kernel(cr0);
36549 ++#endif
36550 ++
36551 ++ sym[i].st_value = symbol;
36552 ++
36553 ++#ifdef CONFIG_PAX_KERNEXEC
36554 ++ pax_close_kernel(cr0);
36555 ++#endif
36556 ++
36557 + /* Ok if resolved. */
36558 + if (sym[i].st_value != 0)
36559 + break;
36560 +@@ -1319,11 +1345,27 @@ static int simplify_symbols(Elf_Shdr *se
36561 +
36562 + default:
36563 + /* Divert to percpu allocation if a percpu var. */
36564 +- if (sym[i].st_shndx == pcpuindex)
36565 ++ if (sym[i].st_shndx == pcpuindex) {
36566 ++
36567 ++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
36568 ++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
36569 ++#else
36570 + secbase = (unsigned long)mod->percpu;
36571 +- else
36572 ++#endif
36573 ++
36574 ++ } else
36575 + secbase = sechdrs[sym[i].st_shndx].sh_addr;
36576 ++
36577 ++#ifdef CONFIG_PAX_KERNEXEC
36578 ++ pax_open_kernel(cr0);
36579 ++#endif
36580 ++
36581 + sym[i].st_value += secbase;
36582 ++
36583 ++#ifdef CONFIG_PAX_KERNEXEC
36584 ++ pax_close_kernel(cr0);
36585 ++#endif
36586 ++
36587 + break;
36588 + }
36589 + }
36590 +@@ -1375,11 +1417,14 @@ static void layout_sections(struct modul
36591 + || strncmp(secstrings + s->sh_name,
36592 + ".init", 5) == 0)
36593 + continue;
36594 +- s->sh_entsize = get_offset(&mod->core_size, s);
36595 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
36596 ++ s->sh_entsize = get_offset(&mod->core_size_rw, s);
36597 ++ else
36598 ++ s->sh_entsize = get_offset(&mod->core_size_rx, s);
36599 + DEBUGP("\t%s\n", secstrings + s->sh_name);
36600 + }
36601 + if (m == 0)
36602 +- mod->core_text_size = mod->core_size;
36603 ++ mod->core_size_rx = mod->core_size_rx;
36604 + }
36605 +
36606 + DEBUGP("Init section allocation order:\n");
36607 +@@ -1393,12 +1438,15 @@ static void layout_sections(struct modul
36608 + || strncmp(secstrings + s->sh_name,
36609 + ".init", 5) != 0)
36610 + continue;
36611 +- s->sh_entsize = (get_offset(&mod->init_size, s)
36612 +- | INIT_OFFSET_MASK);
36613 ++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
36614 ++ s->sh_entsize = get_offset(&mod->init_size_rw, s);
36615 ++ else
36616 ++ s->sh_entsize = get_offset(&mod->init_size_rx, s);
36617 ++ s->sh_entsize |= INIT_OFFSET_MASK;
36618 + DEBUGP("\t%s\n", secstrings + s->sh_name);
36619 + }
36620 + if (m == 0)
36621 +- mod->init_text_size = mod->init_size;
36622 ++ mod->init_size_rx = mod->init_size_rx;
36623 + }
36624 + }
36625 +
36626 +@@ -1525,14 +1573,31 @@ static void add_kallsyms(struct module *
36627 + {
36628 + unsigned int i;
36629 +
36630 ++#ifdef CONFIG_PAX_KERNEXEC
36631 ++ unsigned long cr0;
36632 ++#endif
36633 ++
36634 + mod->symtab = (void *)sechdrs[symindex].sh_addr;
36635 + mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
36636 + mod->strtab = (void *)sechdrs[strindex].sh_addr;
36637 +
36638 + /* Set types up while we still have access to sections. */
36639 +- for (i = 0; i < mod->num_symtab; i++)
36640 +- mod->symtab[i].st_info
36641 +- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
36642 ++
36643 ++ for (i = 0; i < mod->num_symtab; i++) {
36644 ++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
36645 ++
36646 ++#ifdef CONFIG_PAX_KERNEXEC
36647 ++ pax_open_kernel(cr0);
36648 ++#endif
36649 ++
36650 ++ mod->symtab[i].st_info = type;
36651 ++
36652 ++#ifdef CONFIG_PAX_KERNEXEC
36653 ++ pax_close_kernel(cr0);
36654 ++#endif
36655 ++
36656 ++ }
36657 ++
36658 + }
36659 + #else
36660 + static inline void add_kallsyms(struct module *mod,
36661 +@@ -1580,6 +1645,10 @@ static struct module *load_module(void _
36662 + struct exception_table_entry *extable;
36663 + mm_segment_t old_fs;
36664 +
36665 ++#ifdef CONFIG_PAX_KERNEXEC
36666 ++ unsigned long cr0;
36667 ++#endif
36668 ++
36669 + DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
36670 + umod, len, uargs);
36671 + if (len < sizeof(*hdr))
36672 +@@ -1738,21 +1807,57 @@ static struct module *load_module(void _
36673 + layout_sections(mod, hdr, sechdrs, secstrings);
36674 +
36675 + /* Do the allocs. */
36676 +- ptr = module_alloc(mod->core_size);
36677 ++ ptr = module_alloc(mod->core_size_rw);
36678 + if (!ptr) {
36679 + err = -ENOMEM;
36680 + goto free_percpu;
36681 + }
36682 +- memset(ptr, 0, mod->core_size);
36683 +- mod->module_core = ptr;
36684 ++ memset(ptr, 0, mod->core_size_rw);
36685 ++ mod->module_core_rw = ptr;
36686 ++
36687 ++ ptr = module_alloc(mod->init_size_rw);
36688 ++ if (!ptr && mod->init_size_rw) {
36689 ++ err = -ENOMEM;
36690 ++ goto free_core_rw;
36691 ++ }
36692 ++ memset(ptr, 0, mod->init_size_rw);
36693 ++ mod->module_init_rw = ptr;
36694 ++
36695 ++ ptr = module_alloc_exec(mod->core_size_rx);
36696 ++ if (!ptr) {
36697 ++ err = -ENOMEM;
36698 ++ goto free_init_rw;
36699 ++ }
36700 ++
36701 ++#ifdef CONFIG_PAX_KERNEXEC
36702 ++ pax_open_kernel(cr0);
36703 ++#endif
36704 +
36705 +- ptr = module_alloc(mod->init_size);
36706 +- if (!ptr && mod->init_size) {
36707 ++ memset(ptr, 0, mod->core_size_rx);
36708 ++
36709 ++#ifdef CONFIG_PAX_KERNEXEC
36710 ++ pax_close_kernel(cr0);
36711 ++#endif
36712 ++
36713 ++ mod->module_core_rx = ptr;
36714 ++
36715 ++ ptr = module_alloc_exec(mod->init_size_rx);
36716 ++ if (!ptr && mod->init_size_rx) {
36717 + err = -ENOMEM;
36718 +- goto free_core;
36719 ++ goto free_core_rx;
36720 + }
36721 +- memset(ptr, 0, mod->init_size);
36722 +- mod->module_init = ptr;
36723 ++
36724 ++#ifdef CONFIG_PAX_KERNEXEC
36725 ++ pax_open_kernel(cr0);
36726 ++#endif
36727 ++
36728 ++ memset(ptr, 0, mod->init_size_rx);
36729 ++
36730 ++#ifdef CONFIG_PAX_KERNEXEC
36731 ++ pax_close_kernel(cr0);
36732 ++#endif
36733 ++
36734 ++ mod->module_init_rx = ptr;
36735 +
36736 + /* Transfer each section which specifies SHF_ALLOC */
36737 + DEBUGP("final section addresses:\n");
36738 +@@ -1762,17 +1867,41 @@ static struct module *load_module(void _
36739 + if (!(sechdrs[i].sh_flags & SHF_ALLOC))
36740 + continue;
36741 +
36742 +- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
36743 +- dest = mod->module_init
36744 +- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36745 +- else
36746 +- dest = mod->module_core + sechdrs[i].sh_entsize;
36747 ++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
36748 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
36749 ++ dest = mod->module_init_rw
36750 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36751 ++ else
36752 ++ dest = mod->module_init_rx
36753 ++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
36754 ++ } else {
36755 ++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
36756 ++ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
36757 ++ else
36758 ++ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
36759 ++ }
36760 ++
36761 ++ if (sechdrs[i].sh_type != SHT_NOBITS) {
36762 +
36763 +- if (sechdrs[i].sh_type != SHT_NOBITS)
36764 +- memcpy(dest, (void *)sechdrs[i].sh_addr,
36765 +- sechdrs[i].sh_size);
36766 ++#ifdef CONFIG_PAX_KERNEXEC
36767 ++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
36768 ++ pax_open_kernel(cr0);
36769 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
36770 ++ pax_close_kernel(cr0);
36771 ++ } else
36772 ++#endif
36773 ++
36774 ++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
36775 ++ }
36776 + /* Update sh_addr to point to copy in image. */
36777 +- sechdrs[i].sh_addr = (unsigned long)dest;
36778 ++
36779 ++#ifdef CONFIG_PAX_KERNEXEC
36780 ++ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
36781 ++ sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
36782 ++ else
36783 ++#endif
36784 ++
36785 ++ sechdrs[i].sh_addr = (unsigned long)dest;
36786 + DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
36787 + }
36788 + /* Module has been moved. */
36789 +@@ -1892,12 +2021,12 @@ static struct module *load_module(void _
36790 + * Do it before processing of module parameters, so the module
36791 + * can provide parameter accessor functions of its own.
36792 + */
36793 +- if (mod->module_init)
36794 +- flush_icache_range((unsigned long)mod->module_init,
36795 +- (unsigned long)mod->module_init
36796 +- + mod->init_size);
36797 +- flush_icache_range((unsigned long)mod->module_core,
36798 +- (unsigned long)mod->module_core + mod->core_size);
36799 ++ if (mod->module_init_rx)
36800 ++ flush_icache_range((unsigned long)mod->module_init_rx,
36801 ++ (unsigned long)mod->module_init_rx
36802 ++ + mod->init_size_rx);
36803 ++ flush_icache_range((unsigned long)mod->module_core_rx,
36804 ++ (unsigned long)mod->module_core_rx + mod->core_size_rx);
36805 +
36806 + set_fs(old_fs);
36807 +
36808 +@@ -1940,9 +2069,13 @@ static struct module *load_module(void _
36809 + module_arch_cleanup(mod);
36810 + cleanup:
36811 + module_unload_free(mod);
36812 +- module_free(mod, mod->module_init);
36813 +- free_core:
36814 +- module_free(mod, mod->module_core);
36815 ++ module_free_exec(mod, mod->module_init_rx);
36816 ++ free_core_rx:
36817 ++ module_free_exec(mod, mod->module_core_rx);
36818 ++ free_init_rw:
36819 ++ module_free(mod, mod->module_init_rw);
36820 ++ free_core_rw:
36821 ++ module_free(mod, mod->module_core_rw);
36822 + free_percpu:
36823 + if (percpu)
36824 + percpu_modfree(percpu);
36825 +@@ -1978,6 +2111,9 @@ sys_init_module(void __user *umod,
36826 + struct module *mod;
36827 + int ret = 0;
36828 +
36829 ++ if (gr_check_modstop())
36830 ++ return -EPERM;
36831 ++
36832 + /* Must have permission */
36833 + if (!capable(CAP_SYS_MODULE))
36834 + return -EPERM;
36835 +@@ -2029,10 +2165,12 @@ sys_init_module(void __user *umod,
36836 + /* Drop initial reference. */
36837 + module_put(mod);
36838 + unwind_remove_table(mod->unwind_info, 1);
36839 +- module_free(mod, mod->module_init);
36840 +- mod->module_init = NULL;
36841 +- mod->init_size = 0;
36842 +- mod->init_text_size = 0;
36843 ++ module_free(mod, mod->module_init_rw);
36844 ++ module_free_exec(mod, mod->module_init_rx);
36845 ++ mod->module_init_rw = NULL;
36846 ++ mod->module_init_rx = NULL;
36847 ++ mod->init_size_rw = 0;
36848 ++ mod->init_size_rx = 0;
36849 + mutex_unlock(&module_mutex);
36850 +
36851 + return 0;
36852 +@@ -2040,6 +2178,13 @@ sys_init_module(void __user *umod,
36853 +
36854 + static inline int within(unsigned long addr, void *start, unsigned long size)
36855 + {
36856 ++
36857 ++#ifdef CONFIG_PAX_KERNEXEC
36858 ++ if (addr + __KERNEL_TEXT_OFFSET >= (unsigned long)start &&
36859 ++ addr + __KERNEL_TEXT_OFFSET < (unsigned long)start + size)
36860 ++ return 1;
36861 ++#endif
36862 ++
36863 + return ((void *)addr >= start && (void *)addr < start + size);
36864 + }
36865 +
36866 +@@ -2063,10 +2208,14 @@ static const char *get_ksymbol(struct mo
36867 + unsigned long nextval;
36868 +
36869 + /* At worse, next value is at end of module */
36870 +- if (within(addr, mod->module_init, mod->init_size))
36871 +- nextval = (unsigned long)mod->module_init+mod->init_text_size;
36872 +- else
36873 +- nextval = (unsigned long)mod->module_core+mod->core_text_size;
36874 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx))
36875 ++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
36876 ++ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
36877 ++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
36878 ++ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
36879 ++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
36880 ++ else
36881 ++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
36882 +
36883 + /* Scan for closest preceeding symbol, and next symbol. (ELF
36884 + starts real symbols at 1). */
36885 +@@ -2109,8 +2258,10 @@ const char *module_address_lookup(unsign
36886 + struct module *mod;
36887 +
36888 + list_for_each_entry(mod, &modules, list) {
36889 +- if (within(addr, mod->module_init, mod->init_size)
36890 +- || within(addr, mod->module_core, mod->core_size)) {
36891 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36892 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36893 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36894 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36895 + if (modname)
36896 + *modname = mod->name;
36897 + return get_ksymbol(mod, addr, size, offset);
36898 +@@ -2125,8 +2276,10 @@ int lookup_module_symbol_name(unsigned l
36899 +
36900 + mutex_lock(&module_mutex);
36901 + list_for_each_entry(mod, &modules, list) {
36902 +- if (within(addr, mod->module_init, mod->init_size) ||
36903 +- within(addr, mod->module_core, mod->core_size)) {
36904 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36905 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36906 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36907 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36908 + const char *sym;
36909 +
36910 + sym = get_ksymbol(mod, addr, NULL, NULL);
36911 +@@ -2149,8 +2302,10 @@ int lookup_module_symbol_attrs(unsigned
36912 +
36913 + mutex_lock(&module_mutex);
36914 + list_for_each_entry(mod, &modules, list) {
36915 +- if (within(addr, mod->module_init, mod->init_size) ||
36916 +- within(addr, mod->module_core, mod->core_size)) {
36917 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
36918 ++ within(addr, mod->module_init_rw, mod->init_size_rw) ||
36919 ++ within(addr, mod->module_core_rx, mod->core_size_rx) ||
36920 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36921 + const char *sym;
36922 +
36923 + sym = get_ksymbol(mod, addr, size, offset);
36924 +@@ -2270,7 +2425,7 @@ static int m_show(struct seq_file *m, vo
36925 + char buf[8];
36926 +
36927 + seq_printf(m, "%s %lu",
36928 +- mod->name, mod->init_size + mod->core_size);
36929 ++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
36930 + print_unload_info(m, mod);
36931 +
36932 + /* Informative for users. */
36933 +@@ -2279,7 +2434,7 @@ static int m_show(struct seq_file *m, vo
36934 + mod->state == MODULE_STATE_COMING ? "Loading":
36935 + "Live");
36936 + /* Used by oprofile and other similar tools. */
36937 +- seq_printf(m, " 0x%p", mod->module_core);
36938 ++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
36939 +
36940 + /* Taints info */
36941 + if (mod->taints)
36942 +@@ -2335,7 +2490,8 @@ int is_module_address(unsigned long addr
36943 + preempt_disable();
36944 +
36945 + list_for_each_entry(mod, &modules, list) {
36946 +- if (within(addr, mod->module_core, mod->core_size)) {
36947 ++ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
36948 ++ within(addr, mod->module_core_rw, mod->core_size_rw)) {
36949 + preempt_enable();
36950 + return 1;
36951 + }
36952 +@@ -2353,8 +2509,8 @@ struct module *__module_text_address(uns
36953 + struct module *mod;
36954 +
36955 + list_for_each_entry(mod, &modules, list)
36956 +- if (within(addr, mod->module_init, mod->init_text_size)
36957 +- || within(addr, mod->module_core, mod->core_text_size))
36958 ++ if (within(addr, mod->module_init_rx, mod->init_size_rx)
36959 ++ || within(addr, mod->module_core_rx, mod->core_size_rx))
36960 + return mod;
36961 + return NULL;
36962 + }
36963 +diff -Nurp linux-2.6.23.15/kernel/mutex.c linux-2.6.23.15-grsec/kernel/mutex.c
36964 +--- linux-2.6.23.15/kernel/mutex.c 2007-10-09 21:31:38.000000000 +0100
36965 ++++ linux-2.6.23.15-grsec/kernel/mutex.c 2008-02-11 10:37:45.000000000 +0000
36966 +@@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
36967 + *
36968 + * This function is similar to (but not equivalent to) down().
36969 + */
36970 +-void inline fastcall __sched mutex_lock(struct mutex *lock)
36971 ++inline void fastcall __sched mutex_lock(struct mutex *lock)
36972 + {
36973 + might_sleep();
36974 + /*
36975 +diff -Nurp linux-2.6.23.15/kernel/params.c linux-2.6.23.15-grsec/kernel/params.c
36976 +--- linux-2.6.23.15/kernel/params.c 2008-02-11 10:36:03.000000000 +0000
36977 ++++ linux-2.6.23.15-grsec/kernel/params.c 2008-02-11 10:37:45.000000000 +0000
36978 +@@ -275,7 +275,7 @@ static int param_array(const char *name,
36979 + unsigned int min, unsigned int max,
36980 + void *elem, int elemsize,
36981 + int (*set)(const char *, struct kernel_param *kp),
36982 +- int *num)
36983 ++ unsigned int *num)
36984 + {
36985 + int ret;
36986 + struct kernel_param kp;
36987 +diff -Nurp linux-2.6.23.15/kernel/pid.c linux-2.6.23.15-grsec/kernel/pid.c
36988 +--- linux-2.6.23.15/kernel/pid.c 2007-10-09 21:31:38.000000000 +0100
36989 ++++ linux-2.6.23.15-grsec/kernel/pid.c 2008-02-11 10:37:45.000000000 +0000
36990 +@@ -28,6 +28,7 @@
36991 + #include <linux/hash.h>
36992 + #include <linux/pid_namespace.h>
36993 + #include <linux/init_task.h>
36994 ++#include <linux/grsecurity.h>
36995 +
36996 + #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
36997 + static struct hlist_head *pid_hash;
36998 +@@ -37,7 +38,7 @@ struct pid init_struct_pid = INIT_STRUCT
36999 +
37000 + int pid_max = PID_MAX_DEFAULT;
37001 +
37002 +-#define RESERVED_PIDS 300
37003 ++#define RESERVED_PIDS 500
37004 +
37005 + int pid_max_min = RESERVED_PIDS + 1;
37006 + int pid_max_max = PID_MAX_LIMIT;
37007 +@@ -309,7 +310,14 @@ struct task_struct * fastcall pid_task(s
37008 + */
37009 + struct task_struct *find_task_by_pid_type(int type, int nr)
37010 + {
37011 +- return pid_task(find_pid(nr), type);
37012 ++ struct task_struct *task;
37013 ++
37014 ++ task = pid_task(find_pid(nr), type);
37015 ++
37016 ++ if (gr_pid_is_chrooted(task))
37017 ++ return NULL;
37018 ++
37019 ++ return task;
37020 + }
37021 +
37022 + EXPORT_SYMBOL(find_task_by_pid_type);
37023 +diff -Nurp linux-2.6.23.15/kernel/posix-cpu-timers.c linux-2.6.23.15-grsec/kernel/posix-cpu-timers.c
37024 +--- linux-2.6.23.15/kernel/posix-cpu-timers.c 2007-10-09 21:31:38.000000000 +0100
37025 ++++ linux-2.6.23.15-grsec/kernel/posix-cpu-timers.c 2008-02-11 10:37:45.000000000 +0000
37026 +@@ -6,6 +6,7 @@
37027 + #include <linux/posix-timers.h>
37028 + #include <asm/uaccess.h>
37029 + #include <linux/errno.h>
37030 ++#include <linux/grsecurity.h>
37031 +
37032 + static int check_clock(const clockid_t which_clock)
37033 + {
37034 +@@ -1144,6 +1145,7 @@ static void check_process_timers(struct
37035 + __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
37036 + return;
37037 + }
37038 ++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
37039 + if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
37040 + /*
37041 + * At the soft limit, send a SIGXCPU every second.
37042 +diff -Nurp linux-2.6.23.15/kernel/power/poweroff.c linux-2.6.23.15-grsec/kernel/power/poweroff.c
37043 +--- linux-2.6.23.15/kernel/power/poweroff.c 2007-10-09 21:31:38.000000000 +0100
37044 ++++ linux-2.6.23.15-grsec/kernel/power/poweroff.c 2008-02-11 10:37:45.000000000 +0000
37045 +@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
37046 + .enable_mask = SYSRQ_ENABLE_BOOT,
37047 + };
37048 +
37049 +-static int pm_sysrq_init(void)
37050 ++static int __init pm_sysrq_init(void)
37051 + {
37052 + register_sysrq_key('o', &sysrq_poweroff_op);
37053 + return 0;
37054 +diff -Nurp linux-2.6.23.15/kernel/printk.c linux-2.6.23.15-grsec/kernel/printk.c
37055 +--- linux-2.6.23.15/kernel/printk.c 2007-10-09 21:31:38.000000000 +0100
37056 ++++ linux-2.6.23.15-grsec/kernel/printk.c 2008-02-11 10:37:45.000000000 +0000
37057 +@@ -31,6 +31,7 @@
37058 + #include <linux/bootmem.h>
37059 + #include <linux/syscalls.h>
37060 + #include <linux/jiffies.h>
37061 ++#include <linux/grsecurity.h>
37062 +
37063 + #include <asm/uaccess.h>
37064 +
37065 +@@ -184,6 +185,11 @@ int do_syslog(int type, char __user *buf
37066 + char c;
37067 + int error = 0;
37068 +
37069 ++#ifdef CONFIG_GRKERNSEC_DMESG
37070 ++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
37071 ++ return -EPERM;
37072 ++#endif
37073 ++
37074 + error = security_syslog(type);
37075 + if (error)
37076 + return error;
37077 +diff -Nurp linux-2.6.23.15/kernel/ptrace.c linux-2.6.23.15-grsec/kernel/ptrace.c
37078 +--- linux-2.6.23.15/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100
37079 ++++ linux-2.6.23.15-grsec/kernel/ptrace.c 2008-02-11 10:37:45.000000000 +0000
37080 +@@ -19,6 +19,7 @@
37081 + #include <linux/security.h>
37082 + #include <linux/signal.h>
37083 + #include <linux/audit.h>
37084 ++#include <linux/grsecurity.h>
37085 +
37086 + #include <asm/pgtable.h>
37087 + #include <asm/uaccess.h>
37088 +@@ -138,12 +139,12 @@ static int may_attach(struct task_struct
37089 + (current->uid != task->uid) ||
37090 + (current->gid != task->egid) ||
37091 + (current->gid != task->sgid) ||
37092 +- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
37093 ++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
37094 + return -EPERM;
37095 + smp_rmb();
37096 + if (task->mm)
37097 + dumpable = get_dumpable(task->mm);
37098 +- if (!dumpable && !capable(CAP_SYS_PTRACE))
37099 ++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
37100 + return -EPERM;
37101 +
37102 + return security_ptrace(current, task);
37103 +@@ -480,6 +481,11 @@ asmlinkage long sys_ptrace(long request,
37104 + if (ret < 0)
37105 + goto out_put_task_struct;
37106 +
37107 ++ if (gr_handle_ptrace(child, request)) {
37108 ++ ret = -EPERM;
37109 ++ goto out_put_task_struct;
37110 ++ }
37111 ++
37112 + ret = arch_ptrace(child, request, addr, data);
37113 + if (ret < 0)
37114 + goto out_put_task_struct;
37115 +diff -Nurp linux-2.6.23.15/kernel/rcupdate.c linux-2.6.23.15-grsec/kernel/rcupdate.c
37116 +--- linux-2.6.23.15/kernel/rcupdate.c 2007-10-09 21:31:38.000000000 +0100
37117 ++++ linux-2.6.23.15-grsec/kernel/rcupdate.c 2008-02-11 10:37:45.000000000 +0000
37118 +@@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
37119 + .cpumask = CPU_MASK_NONE,
37120 + };
37121 +
37122 +-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
37123 +-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
37124 ++DEFINE_PER_CPU(struct rcu_data, rcu_data);
37125 ++DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
37126 +
37127 + /* Fake initialization required by compiler */
37128 +-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
37129 ++static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
37130 + static int blimit = 10;
37131 + static int qhimark = 10000;
37132 + static int qlowmark = 100;
37133 +diff -Nurp linux-2.6.23.15/kernel/relay.c linux-2.6.23.15-grsec/kernel/relay.c
37134 +--- linux-2.6.23.15/kernel/relay.c 2008-02-11 10:36:03.000000000 +0000
37135 ++++ linux-2.6.23.15-grsec/kernel/relay.c 2008-02-11 10:37:45.000000000 +0000
37136 +@@ -1140,7 +1140,7 @@ static int subbuf_splice_actor(struct fi
37137 + return 0;
37138 +
37139 + ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
37140 +- if (ret < 0 || ret < total_len)
37141 ++ if ((int)ret < 0 || ret < total_len)
37142 + return ret;
37143 +
37144 + if (read_start + ret == nonpad_end)
37145 +diff -Nurp linux-2.6.23.15/kernel/resource.c linux-2.6.23.15-grsec/kernel/resource.c
37146 +--- linux-2.6.23.15/kernel/resource.c 2007-10-09 21:31:38.000000000 +0100
37147 ++++ linux-2.6.23.15-grsec/kernel/resource.c 2008-02-11 10:37:45.000000000 +0000
37148 +@@ -133,10 +133,27 @@ static int __init ioresources_init(void)
37149 + {
37150 + struct proc_dir_entry *entry;
37151 +
37152 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
37153 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
37154 ++ entry = create_proc_entry("ioports", S_IRUSR, NULL);
37155 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
37156 ++ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
37157 ++#endif
37158 ++#else
37159 + entry = create_proc_entry("ioports", 0, NULL);
37160 ++#endif
37161 + if (entry)
37162 + entry->proc_fops = &proc_ioports_operations;
37163 ++
37164 ++#ifdef CONFIG_GRKERNSEC_PROC_ADD
37165 ++#ifdef CONFIG_GRKERNSEC_PROC_USER
37166 ++ entry = create_proc_entry("iomem", S_IRUSR, NULL);
37167 ++#elif CONFIG_GRKERNSEC_PROC_USERGROUP
37168 ++ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
37169 ++#endif
37170 ++#else
37171 + entry = create_proc_entry("iomem", 0, NULL);
37172 ++#endif
37173 + if (entry)
37174 + entry->proc_fops = &proc_iomem_operations;
37175 + return 0;
37176 +diff -Nurp linux-2.6.23.15/kernel/sched.c linux-2.6.23.15-grsec/kernel/sched.c
37177 +--- linux-2.6.23.15/kernel/sched.c 2008-02-11 10:36:03.000000000 +0000
37178 ++++ linux-2.6.23.15-grsec/kernel/sched.c 2008-02-11 10:37:45.000000000 +0000
37179 +@@ -61,6 +61,7 @@
37180 + #include <linux/delayacct.h>
37181 + #include <linux/reciprocal_div.h>
37182 + #include <linux/unistd.h>
37183 ++#include <linux/grsecurity.h>
37184 +
37185 + #include <asm/tlb.h>
37186 +
37187 +@@ -3470,7 +3471,7 @@ pick_next_task(struct rq *rq, struct tas
37188 + asmlinkage void __sched schedule(void)
37189 + {
37190 + struct task_struct *prev, *next;
37191 +- long *switch_count;
37192 ++ unsigned long *switch_count;
37193 + struct rq *rq;
37194 + int cpu;
37195 +
37196 +@@ -4079,7 +4080,8 @@ asmlinkage long sys_nice(int increment)
37197 + if (nice > 19)
37198 + nice = 19;
37199 +
37200 +- if (increment < 0 && !can_nice(current, nice))
37201 ++ if (increment < 0 && (!can_nice(current, nice) ||
37202 ++ gr_handle_chroot_nice()))
37203 + return -EPERM;
37204 +
37205 + retval = security_task_setnice(current, nice);
37206 +@@ -5267,7 +5269,7 @@ static struct ctl_table sd_ctl_dir[] = {
37207 + .procname = "sched_domain",
37208 + .mode = 0555,
37209 + },
37210 +- {0,},
37211 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
37212 + };
37213 +
37214 + static struct ctl_table sd_ctl_root[] = {
37215 +@@ -5277,7 +5279,7 @@ static struct ctl_table sd_ctl_root[] =
37216 + .mode = 0555,
37217 + .child = sd_ctl_dir,
37218 + },
37219 +- {0,},
37220 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL },
37221 + };
37222 +
37223 + static struct ctl_table *sd_alloc_ctl_entry(int n)
37224 +diff -Nurp linux-2.6.23.15/kernel/signal.c linux-2.6.23.15-grsec/kernel/signal.c
37225 +--- linux-2.6.23.15/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100
37226 ++++ linux-2.6.23.15-grsec/kernel/signal.c 2008-02-11 10:37:45.000000000 +0000
37227 +@@ -25,6 +25,7 @@
37228 + #include <linux/capability.h>
37229 + #include <linux/freezer.h>
37230 + #include <linux/pid_namespace.h>
37231 ++#include <linux/grsecurity.h>
37232 + #include <linux/nsproxy.h>
37233 +
37234 + #include <asm/param.h>
37235 +@@ -541,7 +542,9 @@ static int check_kill_permission(int sig
37236 + && (current->euid ^ t->suid) && (current->euid ^ t->uid)
37237 + && (current->uid ^ t->suid) && (current->uid ^ t->uid)
37238 + && !capable(CAP_KILL))
37239 +- return error;
37240 ++ return error;
37241 ++ if (gr_handle_signal(t, sig))
37242 ++ return error;
37243 + }
37244 +
37245 + return security_task_kill(t, info, sig, 0);
37246 +@@ -758,7 +761,7 @@ static int __init setup_print_fatal_sign
37247 +
37248 + __setup("print-fatal-signals=", setup_print_fatal_signals);
37249 +
37250 +-static int
37251 ++int
37252 + specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
37253 + {
37254 + int ret = 0;
37255 +@@ -812,8 +815,12 @@ force_sig_info(int sig, struct siginfo *
37256 + }
37257 + }
37258 + ret = specific_send_sig_info(sig, info, t);
37259 ++
37260 + spin_unlock_irqrestore(&t->sighand->siglock, flags);
37261 +
37262 ++ gr_log_signal(sig, t);
37263 ++ gr_handle_crash(t, sig);
37264 ++
37265 + return ret;
37266 + }
37267 +
37268 +diff -Nurp linux-2.6.23.15/kernel/softirq.c linux-2.6.23.15-grsec/kernel/softirq.c
37269 +--- linux-2.6.23.15/kernel/softirq.c 2007-10-09 21:31:38.000000000 +0100
37270 ++++ linux-2.6.23.15-grsec/kernel/softirq.c 2008-02-11 10:37:45.000000000 +0000
37271 +@@ -471,9 +471,9 @@ void tasklet_kill(struct tasklet_struct
37272 + printk("Attempt to kill tasklet from interrupt\n");
37273 +
37274 + while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
37275 +- do
37276 ++ do {
37277 + yield();
37278 +- while (test_bit(TASKLET_STATE_SCHED, &t->state));
37279 ++ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
37280 + }
37281 + tasklet_unlock_wait(t);
37282 + clear_bit(TASKLET_STATE_SCHED, &t->state);
37283 +diff -Nurp linux-2.6.23.15/kernel/sys.c linux-2.6.23.15-grsec/kernel/sys.c
37284 +--- linux-2.6.23.15/kernel/sys.c 2007-10-09 21:31:38.000000000 +0100
37285 ++++ linux-2.6.23.15-grsec/kernel/sys.c 2008-02-11 10:37:45.000000000 +0000
37286 +@@ -33,6 +33,7 @@
37287 + #include <linux/task_io_accounting_ops.h>
37288 + #include <linux/seccomp.h>
37289 + #include <linux/cpu.h>
37290 ++#include <linux/grsecurity.h>
37291 +
37292 + #include <linux/compat.h>
37293 + #include <linux/syscalls.h>
37294 +@@ -651,6 +652,12 @@ static int set_one_prio(struct task_stru
37295 + error = -EACCES;
37296 + goto out;
37297 + }
37298 ++
37299 ++ if (gr_handle_chroot_setpriority(p, niceval)) {
37300 ++ error = -EACCES;
37301 ++ goto out;
37302 ++ }
37303 ++
37304 + no_nice = security_task_setnice(p, niceval);
37305 + if (no_nice) {
37306 + error = no_nice;
37307 +@@ -707,10 +714,10 @@ asmlinkage long sys_setpriority(int whic
37308 + if ((who != current->uid) && !(user = find_user(who)))
37309 + goto out_unlock; /* No processes for this user */
37310 +
37311 +- do_each_thread(g, p)
37312 ++ do_each_thread(g, p) {
37313 + if (p->uid == who)
37314 + error = set_one_prio(p, niceval, error);
37315 +- while_each_thread(g, p);
37316 ++ } while_each_thread(g, p);
37317 + if (who != current->uid)
37318 + free_uid(user); /* For find_user() */
37319 + break;
37320 +@@ -769,13 +776,13 @@ asmlinkage long sys_getpriority(int whic
37321 + if ((who != current->uid) && !(user = find_user(who)))
37322 + goto out_unlock; /* No processes for this user */
37323 +
37324 +- do_each_thread(g, p)
37325 ++ do_each_thread(g, p) {
37326 + if (p->uid == who) {
37327 + niceval = 20 - task_nice(p);
37328 + if (niceval > retval)
37329 + retval = niceval;
37330 + }
37331 +- while_each_thread(g, p);
37332 ++ } while_each_thread(g, p);
37333 + if (who != current->uid)
37334 + free_uid(user); /* for find_user() */
37335 + break;
37336 +@@ -1047,6 +1054,9 @@ asmlinkage long sys_setregid(gid_t rgid,
37337 + if (rgid != (gid_t) -1 ||
37338 + (egid != (gid_t) -1 && egid != old_rgid))
37339 + current->sgid = new_egid;
37340 ++
37341 ++ gr_set_role_label(current, current->uid, new_rgid);
37342 ++
37343 + current->fsgid = new_egid;
37344 + current->egid = new_egid;
37345 + current->gid = new_rgid;
37346 +@@ -1074,6 +1084,9 @@ asmlinkage long sys_setgid(gid_t gid)
37347 + set_dumpable(current->mm, suid_dumpable);
37348 + smp_wmb();
37349 + }
37350 ++
37351 ++ gr_set_role_label(current, current->uid, gid);
37352 ++
37353 + current->gid = current->egid = current->sgid = current->fsgid = gid;
37354 + } else if ((gid == current->gid) || (gid == current->sgid)) {
37355 + if (old_egid != gid) {
37356 +@@ -1111,6 +1124,9 @@ static int set_user(uid_t new_ruid, int
37357 + set_dumpable(current->mm, suid_dumpable);
37358 + smp_wmb();
37359 + }
37360 ++
37361 ++ gr_set_role_label(current, new_ruid, current->gid);
37362 ++
37363 + current->uid = new_ruid;
37364 + return 0;
37365 + }
37366 +@@ -1213,6 +1229,9 @@ asmlinkage long sys_setuid(uid_t uid)
37367 + } else if ((uid != current->uid) && (uid != new_suid))
37368 + return -EPERM;
37369 +
37370 ++ if (gr_check_crash_uid(uid))
37371 ++ return -EPERM;
37372 ++
37373 + if (old_euid != uid) {
37374 + set_dumpable(current->mm, suid_dumpable);
37375 + smp_wmb();
37376 +@@ -1315,8 +1334,10 @@ asmlinkage long sys_setresgid(gid_t rgid
37377 + current->egid = egid;
37378 + }
37379 + current->fsgid = current->egid;
37380 +- if (rgid != (gid_t) -1)
37381 ++ if (rgid != (gid_t) -1) {
37382 ++ gr_set_role_label(current, current->uid, rgid);
37383 + current->gid = rgid;
37384 ++ }
37385 + if (sgid != (gid_t) -1)
37386 + current->sgid = sgid;
37387 +
37388 +@@ -1463,7 +1484,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
37389 + write_lock_irq(&tasklist_lock);
37390 +
37391 + err = -ESRCH;
37392 +- p = find_task_by_pid(pid);
37393 ++ /* grsec: replaced find_task_by_pid with equivalent call
37394 ++ which lacks the chroot restriction
37395 ++ */
37396 ++ p = pid_task(find_pid(pid), PIDTYPE_PID);
37397 + if (!p)
37398 + goto out;
37399 +
37400 +@@ -2183,7 +2207,7 @@ asmlinkage long sys_prctl(int option, un
37401 + error = get_dumpable(current->mm);
37402 + break;
37403 + case PR_SET_DUMPABLE:
37404 +- if (arg2 < 0 || arg2 > 1) {
37405 ++ if (arg2 > 1) {
37406 + error = -EINVAL;
37407 + break;
37408 + }
37409 +diff -Nurp linux-2.6.23.15/kernel/sysctl.c linux-2.6.23.15-grsec/kernel/sysctl.c
37410 +--- linux-2.6.23.15/kernel/sysctl.c 2008-02-11 10:36:24.000000000 +0000
37411 ++++ linux-2.6.23.15-grsec/kernel/sysctl.c 2008-02-11 10:37:45.000000000 +0000
37412 +@@ -56,6 +56,13 @@
37413 + #endif
37414 +
37415 + #if defined(CONFIG_SYSCTL)
37416 ++#include <linux/grsecurity.h>
37417 ++#include <linux/grinternal.h>
37418 ++
37419 ++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
37420 ++extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
37421 ++ const int op);
37422 ++extern int gr_handle_chroot_sysctl(const int op);
37423 +
37424 + /* External variables not in a header file. */
37425 + extern int C_A_D;
37426 +@@ -141,7 +148,7 @@ static int proc_dointvec_taint(ctl_table
37427 +
37428 + static ctl_table root_table[];
37429 + static struct ctl_table_header root_table_header =
37430 +- { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
37431 ++ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
37432 +
37433 + static ctl_table kern_table[];
37434 + static ctl_table vm_table[];
37435 +@@ -158,11 +165,27 @@ extern ctl_table inotify_table[];
37436 + #ifdef CONFIG_ALPHA_UAC_SYSCTL
37437 + extern ctl_table uac_table[];
37438 + #endif
37439 ++extern ctl_table grsecurity_table[];
37440 +
37441 + #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
37442 + int sysctl_legacy_va_layout;
37443 + #endif
37444 +
37445 ++#ifdef CONFIG_PAX_SOFTMODE
37446 ++static ctl_table pax_table[] = {
37447 ++ {
37448 ++ .ctl_name = CTL_UNNUMBERED,
37449 ++ .procname = "softmode",
37450 ++ .data = &pax_softmode,
37451 ++ .maxlen = sizeof(unsigned int),
37452 ++ .mode = 0600,
37453 ++ .proc_handler = &proc_dointvec,
37454 ++ },
37455 ++
37456 ++ { .ctl_name = 0 }
37457 ++};
37458 ++#endif
37459 ++
37460 + extern int prove_locking;
37461 + extern int lock_stat;
37462 +
37463 +@@ -207,6 +230,16 @@ static ctl_table root_table[] = {
37464 + .mode = 0555,
37465 + .child = dev_table,
37466 + },
37467 ++
37468 ++#ifdef CONFIG_PAX_SOFTMODE
37469 ++ {
37470 ++ .ctl_name = CTL_UNNUMBERED,
37471 ++ .procname = "pax",
37472 ++ .mode = 0500,
37473 ++ .child = pax_table,
37474 ++ },
37475 ++#endif
37476 ++
37477 + /*
37478 + * NOTE: do not add new entries to this table unless you have read
37479 + * Documentation/sysctl/ctl_unnumbered.txt
37480 +@@ -777,6 +810,14 @@ static ctl_table kern_table[] = {
37481 + .proc_handler = &proc_dostring,
37482 + .strategy = &sysctl_string,
37483 + },
37484 ++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
37485 ++ {
37486 ++ .ctl_name = KERN_GRSECURITY,
37487 ++ .procname = "grsecurity",
37488 ++ .mode = 0500,
37489 ++ .child = grsecurity_table,
37490 ++ },
37491 ++#endif
37492 + /*
37493 + * NOTE: do not add new entries to this table unless you have read
37494 + * Documentation/sysctl/ctl_unnumbered.txt
37495 +@@ -1388,6 +1429,25 @@ static int test_perm(int mode, int op)
37496 + int sysctl_perm(ctl_table *table, int op)
37497 + {
37498 + int error;
37499 ++ if (table->parent != NULL && table->parent->procname != NULL &&
37500 ++ table->procname != NULL &&
37501 ++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
37502 ++ return -EACCES;
37503 ++ if (gr_handle_chroot_sysctl(op))
37504 ++ return -EACCES;
37505 ++ error = gr_handle_sysctl(table, op);
37506 ++ if (error)
37507 ++ return error;
37508 ++ error = security_sysctl(table, op);
37509 ++ if (error)
37510 ++ return error;
37511 ++ return test_perm(table->mode, op);
37512 ++}
37513 ++
37514 ++int sysctl_perm_nochk(ctl_table *table, int op)
37515 ++{
37516 ++ int error;
37517 ++
37518 + error = security_sysctl(table, op);
37519 + if (error)
37520 + return error;
37521 +@@ -1412,13 +1472,14 @@ repeat:
37522 + if (n == table->ctl_name) {
37523 + int error;
37524 + if (table->child) {
37525 +- if (sysctl_perm(table, 001))
37526 ++ if (sysctl_perm_nochk(table, 001))
37527 + return -EPERM;
37528 + name++;
37529 + nlen--;
37530 + table = table->child;
37531 + goto repeat;
37532 + }
37533 ++
37534 + error = do_sysctl_strategy(table, name, nlen,
37535 + oldval, oldlenp,
37536 + newval, newlen);
37537 +diff -Nurp linux-2.6.23.15/kernel/time.c linux-2.6.23.15-grsec/kernel/time.c
37538 +--- linux-2.6.23.15/kernel/time.c 2007-10-09 21:31:38.000000000 +0100
37539 ++++ linux-2.6.23.15-grsec/kernel/time.c 2008-02-11 10:37:45.000000000 +0000
37540 +@@ -35,6 +35,7 @@
37541 + #include <linux/security.h>
37542 + #include <linux/fs.h>
37543 + #include <linux/module.h>
37544 ++#include <linux/grsecurity.h>
37545 +
37546 + #include <asm/uaccess.h>
37547 + #include <asm/unistd.h>
37548 +@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
37549 + return err;
37550 +
37551 + do_settimeofday(&tv);
37552 ++
37553 ++ gr_log_timechange();
37554 ++
37555 + return 0;
37556 + }
37557 +
37558 +@@ -197,6 +201,8 @@ asmlinkage long sys_settimeofday(struct
37559 + return -EFAULT;
37560 + }
37561 +
37562 ++ gr_log_timechange();
37563 ++
37564 + return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
37565 + }
37566 +
37567 +@@ -235,7 +241,7 @@ EXPORT_SYMBOL(current_fs_time);
37568 + * Avoid unnecessary multiplications/divisions in the
37569 + * two most common HZ cases:
37570 + */
37571 +-unsigned int inline jiffies_to_msecs(const unsigned long j)
37572 ++inline unsigned int jiffies_to_msecs(const unsigned long j)
37573 + {
37574 + #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
37575 + return (MSEC_PER_SEC / HZ) * j;
37576 +@@ -247,7 +253,7 @@ unsigned int inline jiffies_to_msecs(con
37577 + }
37578 + EXPORT_SYMBOL(jiffies_to_msecs);
37579 +
37580 +-unsigned int inline jiffies_to_usecs(const unsigned long j)
37581 ++inline unsigned int jiffies_to_usecs(const unsigned long j)
37582 + {
37583 + #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
37584 + return (USEC_PER_SEC / HZ) * j;
37585 +diff -Nurp linux-2.6.23.15/kernel/utsname_sysctl.c linux-2.6.23.15-grsec/kernel/utsname_sysctl.c
37586 +--- linux-2.6.23.15/kernel/utsname_sysctl.c 2007-10-09 21:31:38.000000000 +0100
37587 ++++ linux-2.6.23.15-grsec/kernel/utsname_sysctl.c 2008-02-11 10:37:45.000000000 +0000
37588 +@@ -121,7 +121,7 @@ static struct ctl_table uts_kern_table[]
37589 + .proc_handler = proc_do_uts_string,
37590 + .strategy = sysctl_uts_string,
37591 + },
37592 +- {}
37593 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37594 + };
37595 +
37596 + static struct ctl_table uts_root_table[] = {
37597 +@@ -131,7 +131,7 @@ static struct ctl_table uts_root_table[]
37598 + .mode = 0555,
37599 + .child = uts_kern_table,
37600 + },
37601 +- {}
37602 ++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
37603 + };
37604 +
37605 + static int __init utsname_sysctl_init(void)
37606 +diff -Nurp linux-2.6.23.15/lib/radix-tree.c linux-2.6.23.15-grsec/lib/radix-tree.c
37607 +--- linux-2.6.23.15/lib/radix-tree.c 2007-10-09 21:31:38.000000000 +0100
37608 ++++ linux-2.6.23.15-grsec/lib/radix-tree.c 2008-02-11 10:37:45.000000000 +0000
37609 +@@ -76,7 +76,7 @@ struct radix_tree_preload {
37610 + int nr;
37611 + struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
37612 + };
37613 +-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
37614 ++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
37615 +
37616 + static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
37617 + {
37618 +diff -Nurp linux-2.6.23.15/mm/filemap.c linux-2.6.23.15-grsec/mm/filemap.c
37619 +--- linux-2.6.23.15/mm/filemap.c 2008-02-11 10:36:03.000000000 +0000
37620 ++++ linux-2.6.23.15-grsec/mm/filemap.c 2008-02-11 10:37:45.000000000 +0000
37621 +@@ -30,6 +30,7 @@
37622 + #include <linux/security.h>
37623 + #include <linux/syscalls.h>
37624 + #include <linux/cpuset.h>
37625 ++#include <linux/grsecurity.h>
37626 + #include "filemap.h"
37627 + #include "internal.h"
37628 +
37629 +@@ -1461,7 +1462,7 @@ int generic_file_mmap(struct file * file
37630 + struct address_space *mapping = file->f_mapping;
37631 +
37632 + if (!mapping->a_ops->readpage)
37633 +- return -ENOEXEC;
37634 ++ return -ENODEV;
37635 + file_accessed(file);
37636 + vma->vm_ops = &generic_file_vm_ops;
37637 + vma->vm_flags |= VM_CAN_NONLINEAR;
37638 +@@ -1726,6 +1727,7 @@ inline int generic_write_checks(struct f
37639 + *pos = i_size_read(inode);
37640 +
37641 + if (limit != RLIM_INFINITY) {
37642 ++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
37643 + if (*pos >= limit) {
37644 + send_sig(SIGXFSZ, current, 0);
37645 + return -EFBIG;
37646 +diff -Nurp linux-2.6.23.15/mm/fremap.c linux-2.6.23.15-grsec/mm/fremap.c
37647 +--- linux-2.6.23.15/mm/fremap.c 2007-10-09 21:31:38.000000000 +0100
37648 ++++ linux-2.6.23.15-grsec/mm/fremap.c 2008-02-11 10:37:45.000000000 +0000
37649 +@@ -148,6 +148,13 @@ asmlinkage long sys_remap_file_pages(uns
37650 + retry:
37651 + vma = find_vma(mm, start);
37652 +
37653 ++#ifdef CONFIG_PAX_SEGMEXEC
37654 ++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
37655 ++ up_read(&mm->mmap_sem);
37656 ++ return err;
37657 ++ }
37658 ++#endif
37659 ++
37660 + /*
37661 + * Make sure the vma is shared, that it supports prefaulting,
37662 + * and that the remapped range is valid and fully within
37663 +diff -Nurp linux-2.6.23.15/mm/hugetlb.c linux-2.6.23.15-grsec/mm/hugetlb.c
37664 +--- linux-2.6.23.15/mm/hugetlb.c 2007-10-09 21:31:38.000000000 +0100
37665 ++++ linux-2.6.23.15-grsec/mm/hugetlb.c 2008-02-11 10:37:45.000000000 +0000
37666 +@@ -460,6 +460,26 @@ void unmap_hugepage_range(struct vm_area
37667 + }
37668 + }
37669 +
37670 ++#ifdef CONFIG_PAX_SEGMEXEC
37671 ++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
37672 ++{
37673 ++ struct mm_struct *mm = vma->vm_mm;
37674 ++ struct vm_area_struct *vma_m;
37675 ++ unsigned long address_m;
37676 ++ pte_t *ptep_m;
37677 ++
37678 ++ vma_m = pax_find_mirror_vma(vma);
37679 ++ if (!vma_m)
37680 ++ return;
37681 ++
37682 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37683 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37684 ++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
37685 ++ get_page(page_m);
37686 ++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
37687 ++}
37688 ++#endif
37689 ++
37690 + static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
37691 + unsigned long address, pte_t *ptep, pte_t pte)
37692 + {
37693 +@@ -493,6 +513,11 @@ static int hugetlb_cow(struct mm_struct
37694 + /* Break COW */
37695 + set_huge_pte_at(mm, address, ptep,
37696 + make_huge_pte(vma, new_page, 1));
37697 ++
37698 ++#ifdef CONFIG_PAX_SEGMEXEC
37699 ++ pax_mirror_huge_pte(vma, address, new_page);
37700 ++#endif
37701 ++
37702 + /* Make the old page be freed below */
37703 + new_page = old_page;
37704 + }
37705 +@@ -563,6 +588,10 @@ retry:
37706 + && (vma->vm_flags & VM_SHARED)));
37707 + set_huge_pte_at(mm, address, ptep, new_pte);
37708 +
37709 ++#ifdef CONFIG_PAX_SEGMEXEC
37710 ++ pax_mirror_huge_pte(vma, address, page);
37711 ++#endif
37712 ++
37713 + if (write_access && !(vma->vm_flags & VM_SHARED)) {
37714 + /* Optimization, do the COW without a second fault */
37715 + ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
37716 +@@ -589,6 +618,27 @@ int hugetlb_fault(struct mm_struct *mm,
37717 + int ret;
37718 + static DEFINE_MUTEX(hugetlb_instantiation_mutex);
37719 +
37720 ++#ifdef CONFIG_PAX_SEGMEXEC
37721 ++ struct vm_area_struct *vma_m;
37722 ++
37723 ++ vma_m = pax_find_mirror_vma(vma);
37724 ++ if (vma_m) {
37725 ++ unsigned long address_m;
37726 ++
37727 ++ if (vma->vm_start > vma_m->vm_start) {
37728 ++ address_m = address;
37729 ++ address -= SEGMEXEC_TASK_SIZE;
37730 ++ vma = vma_m;
37731 ++ } else
37732 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37733 ++
37734 ++ if (!huge_pte_alloc(mm, address_m))
37735 ++ return VM_FAULT_OOM;
37736 ++ address_m &= HPAGE_MASK;
37737 ++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
37738 ++ }
37739 ++#endif
37740 ++
37741 + ptep = huge_pte_alloc(mm, address);
37742 + if (!ptep)
37743 + return VM_FAULT_OOM;
37744 +diff -Nurp linux-2.6.23.15/mm/madvise.c linux-2.6.23.15-grsec/mm/madvise.c
37745 +--- linux-2.6.23.15/mm/madvise.c 2007-10-09 21:31:38.000000000 +0100
37746 ++++ linux-2.6.23.15-grsec/mm/madvise.c 2008-02-11 10:37:45.000000000 +0000
37747 +@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
37748 + pgoff_t pgoff;
37749 + int new_flags = vma->vm_flags;
37750 +
37751 ++#ifdef CONFIG_PAX_SEGMEXEC
37752 ++ struct vm_area_struct *vma_m;
37753 ++#endif
37754 ++
37755 + switch (behavior) {
37756 + case MADV_NORMAL:
37757 + new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
37758 +@@ -92,6 +96,13 @@ success:
37759 + /*
37760 + * vm_flags is protected by the mmap_sem held in write mode.
37761 + */
37762 ++
37763 ++#ifdef CONFIG_PAX_SEGMEXEC
37764 ++ vma_m = pax_find_mirror_vma(vma);
37765 ++ if (vma_m)
37766 ++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
37767 ++#endif
37768 ++
37769 + vma->vm_flags = new_flags;
37770 +
37771 + out:
37772 +@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
37773 +
37774 + case MADV_DONTNEED:
37775 + error = madvise_dontneed(vma, prev, start, end);
37776 ++
37777 ++#ifdef CONFIG_PAX_SEGMEXEC
37778 ++ if (!error) {
37779 ++ struct vm_area_struct *vma_m, *prev_m;
37780 ++
37781 ++ vma_m = pax_find_mirror_vma(vma);
37782 ++ if (vma_m)
37783 ++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
37784 ++ }
37785 ++#endif
37786 ++
37787 + break;
37788 +
37789 + default:
37790 +@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
37791 + if (end < start)
37792 + goto out;
37793 +
37794 ++#ifdef CONFIG_PAX_SEGMEXEC
37795 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
37796 ++ if (end > SEGMEXEC_TASK_SIZE)
37797 ++ goto out;
37798 ++ } else
37799 ++#endif
37800 ++
37801 ++ if (end > TASK_SIZE)
37802 ++ goto out;
37803 ++
37804 + error = 0;
37805 + if (end == start)
37806 + goto out;
37807 +diff -Nurp linux-2.6.23.15/mm/memory.c linux-2.6.23.15-grsec/mm/memory.c
37808 +--- linux-2.6.23.15/mm/memory.c 2007-10-09 21:31:38.000000000 +0100
37809 ++++ linux-2.6.23.15-grsec/mm/memory.c 2008-02-11 10:37:45.000000000 +0000
37810 +@@ -50,6 +50,7 @@
37811 + #include <linux/delayacct.h>
37812 + #include <linux/init.h>
37813 + #include <linux/writeback.h>
37814 ++#include <linux/grsecurity.h>
37815 +
37816 + #include <asm/pgalloc.h>
37817 + #include <asm/uaccess.h>
37818 +@@ -993,7 +994,7 @@ int get_user_pages(struct task_struct *t
37819 + struct vm_area_struct *vma;
37820 + unsigned int foll_flags;
37821 +
37822 +- vma = find_extend_vma(mm, start);
37823 ++ vma = find_vma(mm, start);
37824 + if (!vma && in_gate_area(tsk, start)) {
37825 + unsigned long pg = start & PAGE_MASK;
37826 + struct vm_area_struct *gate_vma = get_gate_vma(tsk);
37827 +@@ -1033,7 +1034,7 @@ int get_user_pages(struct task_struct *t
37828 + continue;
37829 + }
37830 +
37831 +- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
37832 ++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
37833 + || !(vm_flags & vma->vm_flags))
37834 + return i ? : -EFAULT;
37835 +
37836 +@@ -1614,6 +1615,195 @@ static inline void cow_user_page(struct
37837 + copy_user_highpage(dst, src, va, vma);
37838 + }
37839 +
37840 ++#ifdef CONFIG_PAX_SEGMEXEC
37841 ++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
37842 ++{
37843 ++ struct mm_struct *mm = vma->vm_mm;
37844 ++ spinlock_t *ptl;
37845 ++ pte_t *pte, entry;
37846 ++
37847 ++ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
37848 ++ entry = *pte;
37849 ++ if (!pte_present(entry)) {
37850 ++ if (!pte_none(entry)) {
37851 ++ BUG_ON(pte_file(entry));
37852 ++ free_swap_and_cache(pte_to_swp_entry(entry));
37853 ++ pte_clear_not_present_full(mm, address, pte, 0);
37854 ++ }
37855 ++ } else {
37856 ++ struct page *page;
37857 ++
37858 ++ page = vm_normal_page(vma, address, entry);
37859 ++ if (page) {
37860 ++ flush_cache_page(vma, address, pte_pfn(entry));
37861 ++ flush_icache_page(vma, page);
37862 ++ }
37863 ++ ptep_clear_flush(vma, address, pte);
37864 ++ BUG_ON(pte_dirty(entry));
37865 ++ if (page) {
37866 ++ update_hiwater_rss(mm);
37867 ++ if (PageAnon(page))
37868 ++ dec_mm_counter(mm, anon_rss);
37869 ++ else
37870 ++ dec_mm_counter(mm, file_rss);
37871 ++ page_remove_rmap(page, vma);
37872 ++ page_cache_release(page);
37873 ++ }
37874 ++ }
37875 ++ pte_unmap_unlock(pte, ptl);
37876 ++}
37877 ++
37878 ++/* PaX: if vma is mirrored, synchronize the mirror's PTE
37879 ++ *
37880 ++ * the ptl of the lower mapped page is held on entry and is not released on exit
37881 ++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
37882 ++ */
37883 ++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
37884 ++{
37885 ++ struct mm_struct *mm = vma->vm_mm;
37886 ++ unsigned long address_m;
37887 ++ spinlock_t *ptl_m;
37888 ++ struct vm_area_struct *vma_m;
37889 ++ pmd_t *pmd_m;
37890 ++ pte_t *pte_m, entry_m;
37891 ++
37892 ++ BUG_ON(!page_m || !PageAnon(page_m));
37893 ++
37894 ++ vma_m = pax_find_mirror_vma(vma);
37895 ++ if (!vma_m)
37896 ++ return;
37897 ++
37898 ++ BUG_ON(!PageLocked(page_m));
37899 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37900 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37901 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37902 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37903 ++ ptl_m = pte_lockptr(mm, pmd_m);
37904 ++ if (ptl != ptl_m) {
37905 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37906 ++ if (!pte_none(*pte_m)) {
37907 ++ spin_unlock(ptl_m);
37908 ++ pte_unmap_nested(pte_m);
37909 ++ unlock_page(page_m);
37910 ++ return;
37911 ++ }
37912 ++ }
37913 ++
37914 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
37915 ++ page_cache_get(page_m);
37916 ++ page_add_anon_rmap(page_m, vma_m, address_m);
37917 ++ inc_mm_counter(mm, anon_rss);
37918 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37919 ++ update_mmu_cache(vma_m, address_m, entry_m);
37920 ++ lazy_mmu_prot_update(entry_m);
37921 ++ if (ptl != ptl_m)
37922 ++ spin_unlock(ptl_m);
37923 ++ pte_unmap_nested(pte_m);
37924 ++ unlock_page(page_m);
37925 ++}
37926 ++
37927 ++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
37928 ++{
37929 ++ struct mm_struct *mm = vma->vm_mm;
37930 ++ unsigned long address_m;
37931 ++ spinlock_t *ptl_m;
37932 ++ struct vm_area_struct *vma_m;
37933 ++ pmd_t *pmd_m;
37934 ++ pte_t *pte_m, entry_m;
37935 ++
37936 ++ BUG_ON(!page_m || PageAnon(page_m));
37937 ++
37938 ++ vma_m = pax_find_mirror_vma(vma);
37939 ++ if (!vma_m)
37940 ++ return;
37941 ++
37942 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37943 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37944 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37945 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37946 ++ ptl_m = pte_lockptr(mm, pmd_m);
37947 ++ if (ptl != ptl_m) {
37948 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37949 ++ if (!pte_none(*pte_m)) {
37950 ++ spin_unlock(ptl_m);
37951 ++ pte_unmap_nested(pte_m);
37952 ++ return;
37953 ++ }
37954 ++ }
37955 ++
37956 ++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
37957 ++ page_cache_get(page_m);
37958 ++ page_add_file_rmap(page_m);
37959 ++ inc_mm_counter(mm, file_rss);
37960 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37961 ++ update_mmu_cache(vma_m, address_m, entry_m);
37962 ++ lazy_mmu_prot_update(entry_m);
37963 ++ if (ptl != ptl_m)
37964 ++ spin_unlock(ptl_m);
37965 ++ pte_unmap_nested(pte_m);
37966 ++}
37967 ++
37968 ++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
37969 ++{
37970 ++ struct mm_struct *mm = vma->vm_mm;
37971 ++ unsigned long address_m;
37972 ++ spinlock_t *ptl_m;
37973 ++ struct vm_area_struct *vma_m;
37974 ++ pmd_t *pmd_m;
37975 ++ pte_t *pte_m, entry_m;
37976 ++
37977 ++ vma_m = pax_find_mirror_vma(vma);
37978 ++ if (!vma_m)
37979 ++ return;
37980 ++
37981 ++ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
37982 ++ address_m = address + SEGMEXEC_TASK_SIZE;
37983 ++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
37984 ++ pte_m = pte_offset_map_nested(pmd_m, address_m);
37985 ++ ptl_m = pte_lockptr(mm, pmd_m);
37986 ++ if (ptl != ptl_m) {
37987 ++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
37988 ++ if (!pte_none(*pte_m)) {
37989 ++ spin_unlock(ptl_m);
37990 ++ pte_unmap_nested(pte_m);
37991 ++ return;
37992 ++ }
37993 ++ }
37994 ++
37995 ++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
37996 ++ set_pte_at(mm, address_m, pte_m, entry_m);
37997 ++ if (ptl != ptl_m)
37998 ++ spin_unlock(ptl_m);
37999 ++ pte_unmap_nested(pte_m);
38000 ++}
38001 ++
38002 ++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl)
38003 ++{
38004 ++ struct page *page_m;
38005 ++ pte_t entry;
38006 ++
38007 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
38008 ++ return;
38009 ++
38010 ++ entry = *pte;
38011 ++ page_m = vm_normal_page(vma, address, entry);
38012 ++ if (!page_m)
38013 ++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
38014 ++ else if (PageAnon(page_m)) {
38015 ++ if (pax_find_mirror_vma(vma)) {
38016 ++ spin_unlock(ptl);
38017 ++ lock_page(page_m);
38018 ++ spin_lock(ptl);
38019 ++ if (pte_same(entry, *pte))
38020 ++ pax_mirror_anon_pte(vma, address, page_m, ptl);
38021 ++ else
38022 ++ unlock_page(page_m);
38023 ++ }
38024 ++ } else
38025 ++ pax_mirror_file_pte(vma, address, page_m, ptl);
38026 ++}
38027 ++#endif
38028 ++
38029 + /*
38030 + * This routine handles present pages, when users try to write
38031 + * to a shared page. It is done by copying the page to a new address
38032 +@@ -1733,6 +1923,12 @@ gotten:
38033 + */
38034 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
38035 + if (likely(pte_same(*page_table, orig_pte))) {
38036 ++
38037 ++#ifdef CONFIG_PAX_SEGMEXEC
38038 ++ if (pax_find_mirror_vma(vma))
38039 ++ BUG_ON(TestSetPageLocked(new_page));
38040 ++#endif
38041 ++
38042 + if (old_page) {
38043 + page_remove_rmap(old_page, vma);
38044 + if (!PageAnon(old_page)) {
38045 +@@ -1757,6 +1953,10 @@ gotten:
38046 + lru_cache_add_active(new_page);
38047 + page_add_new_anon_rmap(new_page, vma, address);
38048 +
38049 ++#ifdef CONFIG_PAX_SEGMEXEC
38050 ++ pax_mirror_anon_pte(vma, address, new_page, ptl);
38051 ++#endif
38052 ++
38053 + /* Free the old page.. */
38054 + new_page = old_page;
38055 + ret |= VM_FAULT_WRITE;
38056 +@@ -2034,6 +2234,7 @@ int vmtruncate(struct inode * inode, lof
38057 +
38058 + do_expand:
38059 + limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
38060 ++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
38061 + if (limit != RLIM_INFINITY && offset > limit)
38062 + goto out_sig;
38063 + if (offset > inode->i_sb->s_maxbytes)
38064 +@@ -2216,6 +2417,11 @@ static int do_swap_page(struct mm_struct
38065 + swap_free(entry);
38066 + if (vm_swap_full())
38067 + remove_exclusive_swap_page(page);
38068 ++
38069 ++#ifdef CONFIG_PAX_SEGMEXEC
38070 ++ if (write_access || !pax_find_mirror_vma(vma))
38071 ++#endif
38072 ++
38073 + unlock_page(page);
38074 +
38075 + if (write_access) {
38076 +@@ -2228,6 +2434,11 @@ static int do_swap_page(struct mm_struct
38077 +
38078 + /* No need to invalidate - it was non-present before */
38079 + update_mmu_cache(vma, address, pte);
38080 ++
38081 ++#ifdef CONFIG_PAX_SEGMEXEC
38082 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38083 ++#endif
38084 ++
38085 + unlock:
38086 + pte_unmap_unlock(page_table, ptl);
38087 + out:
38088 +@@ -2268,6 +2479,12 @@ static int do_anonymous_page(struct mm_s
38089 + page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
38090 + if (!pte_none(*page_table))
38091 + goto release;
38092 ++
38093 ++#ifdef CONFIG_PAX_SEGMEXEC
38094 ++ if (pax_find_mirror_vma(vma))
38095 ++ BUG_ON(TestSetPageLocked(page));
38096 ++#endif
38097 ++
38098 + inc_mm_counter(mm, anon_rss);
38099 + lru_cache_add_active(page);
38100 + page_add_new_anon_rmap(page, vma, address);
38101 +@@ -2290,6 +2507,14 @@ static int do_anonymous_page(struct mm_s
38102 + /* No need to invalidate - it was non-present before */
38103 + update_mmu_cache(vma, address, entry);
38104 + lazy_mmu_prot_update(entry);
38105 ++
38106 ++#ifdef CONFIG_PAX_SEGMEXEC
38107 ++ if (write_access)
38108 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38109 ++ else
38110 ++ pax_mirror_file_pte(vma, address, page, ptl);
38111 ++#endif
38112 ++
38113 + unlock:
38114 + pte_unmap_unlock(page_table, ptl);
38115 + return 0;
38116 +@@ -2422,6 +2647,12 @@ static int __do_fault(struct mm_struct *
38117 + */
38118 + /* Only go through if we didn't race with anybody else... */
38119 + if (likely(pte_same(*page_table, orig_pte))) {
38120 ++
38121 ++#ifdef CONFIG_PAX_SEGMEXEC
38122 ++ if (anon && pax_find_mirror_vma(vma))
38123 ++ BUG_ON(TestSetPageLocked(page));
38124 ++#endif
38125 ++
38126 + flush_icache_page(vma, page);
38127 + entry = mk_pte(page, vma->vm_page_prot);
38128 + if (flags & FAULT_FLAG_WRITE)
38129 +@@ -2443,6 +2674,14 @@ static int __do_fault(struct mm_struct *
38130 + /* no need to invalidate: a not-present page won't be cached */
38131 + update_mmu_cache(vma, address, entry);
38132 + lazy_mmu_prot_update(entry);
38133 ++
38134 ++#ifdef CONFIG_PAX_SEGMEXEC
38135 ++ if (anon)
38136 ++ pax_mirror_anon_pte(vma, address, page, ptl);
38137 ++ else
38138 ++ pax_mirror_file_pte(vma, address, page, ptl);
38139 ++#endif
38140 ++
38141 + } else {
38142 + if (anon)
38143 + page_cache_release(page);
38144 +@@ -2522,6 +2761,11 @@ static noinline int do_no_pfn(struct mm_
38145 + if (write_access)
38146 + entry = maybe_mkwrite(pte_mkdirty(entry), vma);
38147 + set_pte_at(mm, address, page_table, entry);
38148 ++
38149 ++#ifdef CONFIG_PAX_SEGMEXEC
38150 ++ pax_mirror_pfn_pte(vma, address, pfn, ptl);
38151 ++#endif
38152 ++
38153 + }
38154 + pte_unmap_unlock(page_table, ptl);
38155 + return 0;
38156 +@@ -2625,6 +2869,11 @@ static inline int handle_pte_fault(struc
38157 + if (write_access)
38158 + flush_tlb_page(vma, address);
38159 + }
38160 ++
38161 ++#ifdef CONFIG_PAX_SEGMEXEC
38162 ++ pax_mirror_pte(vma, address, pte, ptl);
38163 ++#endif
38164 ++
38165 + unlock:
38166 + pte_unmap_unlock(pte, ptl);
38167 + return 0;
38168 +@@ -2641,6 +2890,10 @@ int handle_mm_fault(struct mm_struct *mm
38169 + pmd_t *pmd;
38170 + pte_t *pte;
38171 +
38172 ++#ifdef CONFIG_PAX_SEGMEXEC
38173 ++ struct vm_area_struct *vma_m;
38174 ++#endif
38175 ++
38176 + __set_current_state(TASK_RUNNING);
38177 +
38178 + count_vm_event(PGFAULT);
38179 +@@ -2648,6 +2901,34 @@ int handle_mm_fault(struct mm_struct *mm
38180 + if (unlikely(is_vm_hugetlb_page(vma)))
38181 + return hugetlb_fault(mm, vma, address, write_access);
38182 +
38183 ++#ifdef CONFIG_PAX_SEGMEXEC
38184 ++ vma_m = pax_find_mirror_vma(vma);
38185 ++ if (vma_m) {
38186 ++ unsigned long address_m;
38187 ++ pgd_t *pgd_m;
38188 ++ pud_t *pud_m;
38189 ++ pmd_t *pmd_m;
38190 ++
38191 ++ if (vma->vm_start > vma_m->vm_start) {
38192 ++ address_m = address;
38193 ++ address -= SEGMEXEC_TASK_SIZE;
38194 ++ vma = vma_m;
38195 ++ } else
38196 ++ address_m = address + SEGMEXEC_TASK_SIZE;
38197 ++
38198 ++ pgd_m = pgd_offset(mm, address_m);
38199 ++ pud_m = pud_alloc(mm, pgd_m, address_m);
38200 ++ if (!pud_m)
38201 ++ return VM_FAULT_OOM;
38202 ++ pmd_m = pmd_alloc(mm, pud_m, address_m);
38203 ++ if (!pmd_m)
38204 ++ return VM_FAULT_OOM;
38205 ++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
38206 ++ return VM_FAULT_OOM;
38207 ++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
38208 ++ }
38209 ++#endif
38210 ++
38211 + pgd = pgd_offset(mm, address);
38212 + pud = pud_alloc(mm, pgd, address);
38213 + if (!pud)
38214 +@@ -2781,7 +3062,7 @@ static int __init gate_vma_init(void)
38215 + gate_vma.vm_start = FIXADDR_USER_START;
38216 + gate_vma.vm_end = FIXADDR_USER_END;
38217 + gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
38218 +- gate_vma.vm_page_prot = __P101;
38219 ++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
38220 + /*
38221 + * Make sure the vDSO gets into every core dump.
38222 + * Dumping its contents makes post-mortem fully interpretable later
38223 +diff -Nurp linux-2.6.23.15/mm/mempolicy.c linux-2.6.23.15-grsec/mm/mempolicy.c
38224 +--- linux-2.6.23.15/mm/mempolicy.c 2007-10-09 21:31:38.000000000 +0100
38225 ++++ linux-2.6.23.15-grsec/mm/mempolicy.c 2008-02-11 10:37:45.000000000 +0000
38226 +@@ -401,6 +401,10 @@ static int mbind_range(struct vm_area_st
38227 + struct vm_area_struct *next;
38228 + int err;
38229 +
38230 ++#ifdef CONFIG_PAX_SEGMEXEC
38231 ++ struct vm_area_struct *vma_m;
38232 ++#endif
38233 ++
38234 + err = 0;
38235 + for (; vma && vma->vm_start < end; vma = next) {
38236 + next = vma->vm_next;
38237 +@@ -412,6 +416,16 @@ static int mbind_range(struct vm_area_st
38238 + err = policy_vma(vma, new);
38239 + if (err)
38240 + break;
38241 ++
38242 ++#ifdef CONFIG_PAX_SEGMEXEC
38243 ++ vma_m = pax_find_mirror_vma(vma);
38244 ++ if (vma_m) {
38245 ++ err = policy_vma(vma_m, new);
38246 ++ if (err)
38247 ++ break;
38248 ++ }
38249 ++#endif
38250 ++
38251 + }
38252 + return err;
38253 + }
38254 +@@ -732,7 +746,7 @@ static struct page *new_vma_page(struct
38255 + }
38256 + #endif
38257 +
38258 +-long do_mbind(unsigned long start, unsigned long len,
38259 ++static long do_mbind(unsigned long start, unsigned long len,
38260 + unsigned long mode, nodemask_t *nmask, unsigned long flags)
38261 + {
38262 + struct vm_area_struct *vma;
38263 +@@ -760,6 +774,17 @@ long do_mbind(unsigned long start, unsig
38264 +
38265 + if (end < start)
38266 + return -EINVAL;
38267 ++
38268 ++#ifdef CONFIG_PAX_SEGMEXEC
38269 ++ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
38270 ++ if (end > SEGMEXEC_TASK_SIZE)
38271 ++ return -EINVAL;
38272 ++ } else
38273 ++#endif
38274 ++
38275 ++ if (end > TASK_SIZE)
38276 ++ return -EINVAL;
38277 ++
38278 + if (end == start)
38279 + return 0;
38280 +
38281 +diff -Nurp linux-2.6.23.15/mm/mlock.c linux-2.6.23.15-grsec/mm/mlock.c
38282 +--- linux-2.6.23.15/mm/mlock.c 2007-10-09 21:31:38.000000000 +0100
38283 ++++ linux-2.6.23.15-grsec/mm/mlock.c 2008-02-11 10:37:45.000000000 +0000
38284 +@@ -12,6 +12,7 @@
38285 + #include <linux/syscalls.h>
38286 + #include <linux/sched.h>
38287 + #include <linux/module.h>
38288 ++#include <linux/grsecurity.h>
38289 +
38290 + int can_do_mlock(void)
38291 + {
38292 +@@ -95,6 +96,17 @@ static int do_mlock(unsigned long start,
38293 + return -EINVAL;
38294 + if (end == start)
38295 + return 0;
38296 ++
38297 ++#ifdef CONFIG_PAX_SEGMEXEC
38298 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
38299 ++ if (end > SEGMEXEC_TASK_SIZE)
38300 ++ return -EINVAL;
38301 ++ } else
38302 ++#endif
38303 ++
38304 ++ if (end > TASK_SIZE)
38305 ++ return -EINVAL;
38306 ++
38307 + vma = find_vma_prev(current->mm, start, &prev);
38308 + if (!vma || vma->vm_start > start)
38309 + return -ENOMEM;
38310 +@@ -152,6 +164,7 @@ asmlinkage long sys_mlock(unsigned long
38311 + lock_limit >>= PAGE_SHIFT;
38312 +
38313 + /* check against resource limits */
38314 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
38315 + if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
38316 + error = do_mlock(start, len, 1);
38317 + up_write(&current->mm->mmap_sem);
38318 +@@ -173,10 +186,10 @@ asmlinkage long sys_munlock(unsigned lon
38319 + static int do_mlockall(int flags)
38320 + {
38321 + struct vm_area_struct * vma, * prev = NULL;
38322 +- unsigned int def_flags = 0;
38323 ++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
38324 +
38325 + if (flags & MCL_FUTURE)
38326 +- def_flags = VM_LOCKED;
38327 ++ def_flags |= VM_LOCKED;
38328 + current->mm->def_flags = def_flags;
38329 + if (flags == MCL_FUTURE)
38330 + goto out;
38331 +@@ -184,6 +197,12 @@ static int do_mlockall(int flags)
38332 + for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
38333 + unsigned int newflags;
38334 +
38335 ++#ifdef CONFIG_PAX_SEGMEXEC
38336 ++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
38337 ++ break;
38338 ++#endif
38339 ++
38340 ++ BUG_ON(vma->vm_end > TASK_SIZE);
38341 + newflags = vma->vm_flags | VM_LOCKED;
38342 + if (!(flags & MCL_CURRENT))
38343 + newflags &= ~VM_LOCKED;
38344 +@@ -213,6 +232,7 @@ asmlinkage long sys_mlockall(int flags)
38345 + lock_limit >>= PAGE_SHIFT;
38346 +
38347 + ret = -ENOMEM;
38348 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
38349 + if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
38350 + capable(CAP_IPC_LOCK))
38351 + ret = do_mlockall(flags);
38352 +diff -Nurp linux-2.6.23.15/mm/mmap.c linux-2.6.23.15-grsec/mm/mmap.c
38353 +--- linux-2.6.23.15/mm/mmap.c 2008-02-11 10:36:03.000000000 +0000
38354 ++++ linux-2.6.23.15-grsec/mm/mmap.c 2008-02-11 10:43:32.000000000 +0000
38355 +@@ -25,6 +25,7 @@
38356 + #include <linux/mount.h>
38357 + #include <linux/mempolicy.h>
38358 + #include <linux/rmap.h>
38359 ++#include <linux/grsecurity.h>
38360 +
38361 + #include <asm/uaccess.h>
38362 + #include <asm/cacheflush.h>
38363 +@@ -35,6 +36,16 @@
38364 + #define arch_mmap_check(addr, len, flags) (0)
38365 + #endif
38366 +
38367 ++static inline void verify_mm_writelocked(struct mm_struct *mm)
38368 ++{
38369 ++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
38370 ++ if (unlikely(down_read_trylock(&mm->mmap_sem))) {
38371 ++ up_read(&mm->mmap_sem);
38372 ++ BUG();
38373 ++ }
38374 ++#endif
38375 ++}
38376 ++
38377 + static void unmap_region(struct mm_struct *mm,
38378 + struct vm_area_struct *vma, struct vm_area_struct *prev,
38379 + unsigned long start, unsigned long end);
38380 +@@ -60,15 +71,23 @@ static void unmap_region(struct mm_struc
38381 + * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
38382 + *
38383 + */
38384 +-pgprot_t protection_map[16] = {
38385 ++pgprot_t protection_map[16] __read_only = {
38386 + __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
38387 + __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
38388 + };
38389 +
38390 + pgprot_t vm_get_page_prot(unsigned long vm_flags)
38391 + {
38392 +- return protection_map[vm_flags &
38393 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38394 ++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38395 ++
38396 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38397 ++ if (!nx_enabled &&
38398 ++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
38399 ++ (vm_flags & (VM_READ | VM_WRITE)))
38400 ++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
38401 ++#endif
38402 ++
38403 ++ return prot;
38404 + }
38405 + EXPORT_SYMBOL(vm_get_page_prot);
38406 +
38407 +@@ -225,6 +244,7 @@ static struct vm_area_struct *remove_vma
38408 + struct vm_area_struct *next = vma->vm_next;
38409 +
38410 + might_sleep();
38411 ++ BUG_ON(vma->vm_mirror);
38412 + if (vma->vm_ops && vma->vm_ops->close)
38413 + vma->vm_ops->close(vma);
38414 + if (vma->vm_file)
38415 +@@ -252,6 +272,7 @@ asmlinkage unsigned long sys_brk(unsigne
38416 + * not page aligned -Ram Gupta
38417 + */
38418 + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
38419 ++ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
38420 + if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
38421 + goto out;
38422 +
38423 +@@ -352,8 +373,12 @@ find_vma_prepare(struct mm_struct *mm, u
38424 +
38425 + if (vma_tmp->vm_end > addr) {
38426 + vma = vma_tmp;
38427 +- if (vma_tmp->vm_start <= addr)
38428 +- return vma;
38429 ++ if (vma_tmp->vm_start <= addr) {
38430 ++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
38431 ++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
38432 ++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
38433 ++ break;
38434 ++ }
38435 + __rb_link = &__rb_parent->rb_left;
38436 + } else {
38437 + rb_prev = __rb_parent;
38438 +@@ -677,6 +702,12 @@ static int
38439 + can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
38440 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
38441 + {
38442 ++
38443 ++#ifdef CONFIG_PAX_SEGMEXEC
38444 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
38445 ++ return 0;
38446 ++#endif
38447 ++
38448 + if (is_mergeable_vma(vma, file, vm_flags) &&
38449 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
38450 + if (vma->vm_pgoff == vm_pgoff)
38451 +@@ -696,6 +727,12 @@ static int
38452 + can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
38453 + struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
38454 + {
38455 ++
38456 ++#ifdef CONFIG_PAX_SEGMEXEC
38457 ++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
38458 ++ return 0;
38459 ++#endif
38460 ++
38461 + if (is_mergeable_vma(vma, file, vm_flags) &&
38462 + is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
38463 + pgoff_t vm_pglen;
38464 +@@ -738,12 +775,19 @@ can_vma_merge_after(struct vm_area_struc
38465 + struct vm_area_struct *vma_merge(struct mm_struct *mm,
38466 + struct vm_area_struct *prev, unsigned long addr,
38467 + unsigned long end, unsigned long vm_flags,
38468 +- struct anon_vma *anon_vma, struct file *file,
38469 ++ struct anon_vma *anon_vma, struct file *file,
38470 + pgoff_t pgoff, struct mempolicy *policy)
38471 + {
38472 + pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
38473 + struct vm_area_struct *area, *next;
38474 +
38475 ++#ifdef CONFIG_PAX_SEGMEXEC
38476 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
38477 ++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
38478 ++
38479 ++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
38480 ++#endif
38481 ++
38482 + /*
38483 + * We later require that vma->vm_flags == vm_flags,
38484 + * so this tests vma->vm_flags & VM_SPECIAL, too.
38485 +@@ -759,6 +803,15 @@ struct vm_area_struct *vma_merge(struct
38486 + if (next && next->vm_end == end) /* cases 6, 7, 8 */
38487 + next = next->vm_next;
38488 +
38489 ++#ifdef CONFIG_PAX_SEGMEXEC
38490 ++ if (prev)
38491 ++ prev_m = pax_find_mirror_vma(prev);
38492 ++ if (area)
38493 ++ area_m = pax_find_mirror_vma(area);
38494 ++ if (next)
38495 ++ next_m = pax_find_mirror_vma(next);
38496 ++#endif
38497 ++
38498 + /*
38499 + * Can it merge with the predecessor?
38500 + */
38501 +@@ -778,9 +831,24 @@ struct vm_area_struct *vma_merge(struct
38502 + /* cases 1, 6 */
38503 + vma_adjust(prev, prev->vm_start,
38504 + next->vm_end, prev->vm_pgoff, NULL);
38505 +- } else /* cases 2, 5, 7 */
38506 ++
38507 ++#ifdef CONFIG_PAX_SEGMEXEC
38508 ++ if (prev_m)
38509 ++ vma_adjust(prev_m, prev_m->vm_start,
38510 ++ next_m->vm_end, prev_m->vm_pgoff, NULL);
38511 ++#endif
38512 ++
38513 ++ } else { /* cases 2, 5, 7 */
38514 + vma_adjust(prev, prev->vm_start,
38515 + end, prev->vm_pgoff, NULL);
38516 ++
38517 ++#ifdef CONFIG_PAX_SEGMEXEC
38518 ++ if (prev_m)
38519 ++ vma_adjust(prev_m, prev_m->vm_start,
38520 ++ end_m, prev_m->vm_pgoff, NULL);
38521 ++#endif
38522 ++
38523 ++ }
38524 + return prev;
38525 + }
38526 +
38527 +@@ -791,12 +859,27 @@ struct vm_area_struct *vma_merge(struct
38528 + mpol_equal(policy, vma_policy(next)) &&
38529 + can_vma_merge_before(next, vm_flags,
38530 + anon_vma, file, pgoff+pglen)) {
38531 +- if (prev && addr < prev->vm_end) /* case 4 */
38532 ++ if (prev && addr < prev->vm_end) { /* case 4 */
38533 + vma_adjust(prev, prev->vm_start,
38534 + addr, prev->vm_pgoff, NULL);
38535 +- else /* cases 3, 8 */
38536 ++
38537 ++#ifdef CONFIG_PAX_SEGMEXEC
38538 ++ if (prev_m)
38539 ++ vma_adjust(prev_m, prev_m->vm_start,
38540 ++ addr_m, prev_m->vm_pgoff, NULL);
38541 ++#endif
38542 ++
38543 ++ } else { /* cases 3, 8 */
38544 + vma_adjust(area, addr, next->vm_end,
38545 + next->vm_pgoff - pglen, NULL);
38546 ++
38547 ++#ifdef CONFIG_PAX_SEGMEXEC
38548 ++ if (area_m)
38549 ++ vma_adjust(area_m, addr_m, next_m->vm_end,
38550 ++ next_m->vm_pgoff - pglen, NULL);
38551 ++#endif
38552 ++
38553 ++ }
38554 + return area;
38555 + }
38556 +
38557 +@@ -871,14 +954,11 @@ none:
38558 + void vm_stat_account(struct mm_struct *mm, unsigned long flags,
38559 + struct file *file, long pages)
38560 + {
38561 +- const unsigned long stack_flags
38562 +- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
38563 +-
38564 + if (file) {
38565 + mm->shared_vm += pages;
38566 + if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
38567 + mm->exec_vm += pages;
38568 +- } else if (flags & stack_flags)
38569 ++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
38570 + mm->stack_vm += pages;
38571 + if (flags & (VM_RESERVED|VM_IO))
38572 + mm->reserved_vm += pages;
38573 +@@ -906,22 +986,22 @@ unsigned long do_mmap_pgoff(struct file
38574 + * (the exception is when the underlying filesystem is noexec
38575 + * mounted, in which case we dont add PROT_EXEC.)
38576 + */
38577 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
38578 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
38579 + if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
38580 + prot |= PROT_EXEC;
38581 +
38582 + if (!len)
38583 + return -EINVAL;
38584 +
38585 +- error = arch_mmap_check(addr, len, flags);
38586 +- if (error)
38587 +- return error;
38588 +-
38589 + /* Careful about overflows.. */
38590 + len = PAGE_ALIGN(len);
38591 + if (!len || len > TASK_SIZE)
38592 + return -ENOMEM;
38593 +
38594 ++ error = arch_mmap_check(addr, len, flags);
38595 ++ if (error)
38596 ++ return error;
38597 ++
38598 + /* offset overflow? */
38599 + if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
38600 + return -EOVERFLOW;
38601 +@@ -933,7 +1013,7 @@ unsigned long do_mmap_pgoff(struct file
38602 + /* Obtain the address to map to. we verify (or select) it and ensure
38603 + * that it represents a valid section of the address space.
38604 + */
38605 +- addr = get_unmapped_area(file, addr, len, pgoff, flags);
38606 ++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
38607 + if (addr & ~PAGE_MASK)
38608 + return addr;
38609 +
38610 +@@ -944,6 +1024,26 @@ unsigned long do_mmap_pgoff(struct file
38611 + vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
38612 + mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
38613 +
38614 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
38615 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
38616 ++
38617 ++#ifdef CONFIG_PAX_MPROTECT
38618 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
38619 ++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
38620 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
38621 ++ else
38622 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
38623 ++ }
38624 ++#endif
38625 ++
38626 ++ }
38627 ++#endif
38628 ++
38629 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38630 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
38631 ++ vm_flags &= ~VM_PAGEEXEC;
38632 ++#endif
38633 ++
38634 + if (flags & MAP_LOCKED) {
38635 + if (!can_do_mlock())
38636 + return -EPERM;
38637 +@@ -956,6 +1056,7 @@ unsigned long do_mmap_pgoff(struct file
38638 + locked += mm->locked_vm;
38639 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
38640 + lock_limit >>= PAGE_SHIFT;
38641 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
38642 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
38643 + return -EAGAIN;
38644 + }
38645 +@@ -1024,6 +1125,9 @@ unsigned long do_mmap_pgoff(struct file
38646 + if (error)
38647 + return error;
38648 +
38649 ++ if (!gr_acl_handle_mmap(file, prot))
38650 ++ return -EACCES;
38651 ++
38652 + return mmap_region(file, addr, len, flags, vm_flags, pgoff,
38653 + accountable);
38654 + }
38655 +@@ -1037,10 +1141,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
38656 + */
38657 + int vma_wants_writenotify(struct vm_area_struct *vma)
38658 + {
38659 +- unsigned int vm_flags = vma->vm_flags;
38660 ++ unsigned long vm_flags = vma->vm_flags;
38661 +
38662 + /* If it was private or non-writable, the write bit is already clear */
38663 +- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
38664 ++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
38665 + return 0;
38666 +
38667 + /* The backer wishes to know when pages are first written to? */
38668 +@@ -1049,8 +1153,7 @@ int vma_wants_writenotify(struct vm_area
38669 +
38670 + /* The open routine did something to the protections already? */
38671 + if (pgprot_val(vma->vm_page_prot) !=
38672 +- pgprot_val(protection_map[vm_flags &
38673 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
38674 ++ pgprot_val(vm_get_page_prot(vm_flags)))
38675 + return 0;
38676 +
38677 + /* Specialty mapping? */
38678 +@@ -1076,14 +1179,24 @@ unsigned long mmap_region(struct file *f
38679 + unsigned long charged = 0;
38680 + struct inode *inode = file ? file->f_path.dentry->d_inode : NULL;
38681 +
38682 ++#ifdef CONFIG_PAX_SEGMEXEC
38683 ++ struct vm_area_struct *vma_m = NULL;
38684 ++#endif
38685 ++
38686 ++ /*
38687 ++ * mm->mmap_sem is required to protect against another thread
38688 ++ * changing the mappings in case we sleep.
38689 ++ */
38690 ++ verify_mm_writelocked(mm);
38691 ++
38692 + /* Clear old maps */
38693 + error = -ENOMEM;
38694 +-munmap_back:
38695 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
38696 + if (vma && vma->vm_start < addr + len) {
38697 + if (do_munmap(mm, addr, len))
38698 + return -ENOMEM;
38699 +- goto munmap_back;
38700 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
38701 ++ BUG_ON(vma && vma->vm_start < addr + len);
38702 + }
38703 +
38704 + /* Check against address space limit. */
38705 +@@ -1127,12 +1240,22 @@ munmap_back:
38706 + goto unacct_error;
38707 + }
38708 +
38709 ++#ifdef CONFIG_PAX_SEGMEXEC
38710 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
38711 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
38712 ++ if (!vma_m) {
38713 ++ kmem_cache_free(vm_area_cachep, vma);
38714 ++ error = -ENOMEM;
38715 ++ goto unacct_error;
38716 ++ }
38717 ++ }
38718 ++#endif
38719 ++
38720 + vma->vm_mm = mm;
38721 + vma->vm_start = addr;
38722 + vma->vm_end = addr + len;
38723 + vma->vm_flags = vm_flags;
38724 +- vma->vm_page_prot = protection_map[vm_flags &
38725 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
38726 ++ vma->vm_page_prot = vm_get_page_prot(vm_flags);
38727 + vma->vm_pgoff = pgoff;
38728 +
38729 + if (file) {
38730 +@@ -1150,6 +1273,14 @@ munmap_back:
38731 + error = file->f_op->mmap(file, vma);
38732 + if (error)
38733 + goto unmap_and_free_vma;
38734 ++
38735 ++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
38736 ++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
38737 ++ vma->vm_flags |= VM_PAGEEXEC;
38738 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
38739 ++ }
38740 ++#endif
38741 ++
38742 + } else if (vm_flags & VM_SHARED) {
38743 + error = shmem_zero_setup(vma);
38744 + if (error)
38745 +@@ -1174,13 +1305,18 @@ munmap_back:
38746 + vm_flags = vma->vm_flags;
38747 +
38748 + if (vma_wants_writenotify(vma))
38749 +- vma->vm_page_prot =
38750 +- protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
38751 ++ vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
38752 +
38753 + if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
38754 + vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
38755 + file = vma->vm_file;
38756 + vma_link(mm, vma, prev, rb_link, rb_parent);
38757 ++
38758 ++#ifdef CONFIG_PAX_SEGMEXEC
38759 ++ if (vma_m)
38760 ++ pax_mirror_vma(vma_m, vma);
38761 ++#endif
38762 ++
38763 + if (correct_wcount)
38764 + atomic_inc(&inode->i_writecount);
38765 + } else {
38766 +@@ -1191,10 +1327,12 @@ munmap_back:
38767 + }
38768 + mpol_free(vma_policy(vma));
38769 + kmem_cache_free(vm_area_cachep, vma);
38770 ++ vma = NULL;
38771 + }
38772 + out:
38773 + mm->total_vm += len >> PAGE_SHIFT;
38774 + vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
38775 ++ track_exec_limit(mm, addr, addr + len, vm_flags);
38776 + if (vm_flags & VM_LOCKED) {
38777 + mm->locked_vm += len >> PAGE_SHIFT;
38778 + make_pages_present(addr, addr + len);
38779 +@@ -1213,6 +1351,12 @@ unmap_and_free_vma:
38780 + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
38781 + charged = 0;
38782 + free_vma:
38783 ++
38784 ++#ifdef CONFIG_PAX_SEGMEXEC
38785 ++ if (vma_m)
38786 ++ kmem_cache_free(vm_area_cachep, vma_m);
38787 ++#endif
38788 ++
38789 + kmem_cache_free(vm_area_cachep, vma);
38790 + unacct_error:
38791 + if (charged)
38792 +@@ -1246,6 +1390,10 @@ arch_get_unmapped_area(struct file *filp
38793 + if (flags & MAP_FIXED)
38794 + return addr;
38795 +
38796 ++#ifdef CONFIG_PAX_RANDMMAP
38797 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
38798 ++#endif
38799 ++
38800 + if (addr) {
38801 + addr = PAGE_ALIGN(addr);
38802 + vma = find_vma(mm, addr);
38803 +@@ -1254,10 +1402,10 @@ arch_get_unmapped_area(struct file *filp
38804 + return addr;
38805 + }
38806 + if (len > mm->cached_hole_size) {
38807 +- start_addr = addr = mm->free_area_cache;
38808 ++ start_addr = addr = mm->free_area_cache;
38809 + } else {
38810 +- start_addr = addr = TASK_UNMAPPED_BASE;
38811 +- mm->cached_hole_size = 0;
38812 ++ start_addr = addr = mm->mmap_base;
38813 ++ mm->cached_hole_size = 0;
38814 + }
38815 +
38816 + full_search:
38817 +@@ -1268,9 +1416,8 @@ full_search:
38818 + * Start a new search - just in case we missed
38819 + * some holes.
38820 + */
38821 +- if (start_addr != TASK_UNMAPPED_BASE) {
38822 +- addr = TASK_UNMAPPED_BASE;
38823 +- start_addr = addr;
38824 ++ if (start_addr != mm->mmap_base) {
38825 ++ start_addr = addr = mm->mmap_base;
38826 + mm->cached_hole_size = 0;
38827 + goto full_search;
38828 + }
38829 +@@ -1292,10 +1439,16 @@ full_search:
38830 +
38831 + void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
38832 + {
38833 ++
38834 ++#ifdef CONFIG_PAX_SEGMEXEC
38835 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
38836 ++ return;
38837 ++#endif
38838 ++
38839 + /*
38840 + * Is this a new hole at the lowest possible address?
38841 + */
38842 +- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
38843 ++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
38844 + mm->free_area_cache = addr;
38845 + mm->cached_hole_size = ~0UL;
38846 + }
38847 +@@ -1313,7 +1466,7 @@ arch_get_unmapped_area_topdown(struct fi
38848 + {
38849 + struct vm_area_struct *vma;
38850 + struct mm_struct *mm = current->mm;
38851 +- unsigned long addr = addr0;
38852 ++ unsigned long base = mm->mmap_base, addr = addr0;
38853 +
38854 + /* requested length too big for entire address space */
38855 + if (len > TASK_SIZE)
38856 +@@ -1322,6 +1475,10 @@ arch_get_unmapped_area_topdown(struct fi
38857 + if (flags & MAP_FIXED)
38858 + return addr;
38859 +
38860 ++#ifdef CONFIG_PAX_RANDMMAP
38861 ++ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
38862 ++#endif
38863 ++
38864 + /* requesting a specific address */
38865 + if (addr) {
38866 + addr = PAGE_ALIGN(addr);
38867 +@@ -1379,13 +1536,21 @@ bottomup:
38868 + * can happen with large stack limits and large mmap()
38869 + * allocations.
38870 + */
38871 ++ mm->mmap_base = TASK_UNMAPPED_BASE;
38872 ++
38873 ++#ifdef CONFIG_PAX_RANDMMAP
38874 ++ if (mm->pax_flags & MF_PAX_RANDMMAP)
38875 ++ mm->mmap_base += mm->delta_mmap;
38876 ++#endif
38877 ++
38878 ++ mm->free_area_cache = mm->mmap_base;
38879 + mm->cached_hole_size = ~0UL;
38880 +- mm->free_area_cache = TASK_UNMAPPED_BASE;
38881 + addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
38882 + /*
38883 + * Restore the topdown base:
38884 + */
38885 +- mm->free_area_cache = mm->mmap_base;
38886 ++ mm->mmap_base = base;
38887 ++ mm->free_area_cache = base;
38888 + mm->cached_hole_size = ~0UL;
38889 +
38890 + return addr;
38891 +@@ -1394,6 +1559,12 @@ bottomup:
38892 +
38893 + void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
38894 + {
38895 ++
38896 ++#ifdef CONFIG_PAX_SEGMEXEC
38897 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
38898 ++ return;
38899 ++#endif
38900 ++
38901 + /*
38902 + * Is this a new hole at the highest possible address?
38903 + */
38904 +@@ -1401,8 +1572,10 @@ void arch_unmap_area_topdown(struct mm_s
38905 + mm->free_area_cache = addr;
38906 +
38907 + /* dont allow allocations above current base */
38908 +- if (mm->free_area_cache > mm->mmap_base)
38909 ++ if (mm->free_area_cache > mm->mmap_base) {
38910 + mm->free_area_cache = mm->mmap_base;
38911 ++ mm->cached_hole_size = ~0UL;
38912 ++ }
38913 + }
38914 +
38915 + unsigned long
38916 +@@ -1502,6 +1675,32 @@ out:
38917 + return prev ? prev->vm_next : vma;
38918 + }
38919 +
38920 ++#ifdef CONFIG_PAX_SEGMEXEC
38921 ++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
38922 ++{
38923 ++ struct vm_area_struct *vma_m;
38924 ++
38925 ++ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
38926 ++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
38927 ++ BUG_ON(vma->vm_mirror);
38928 ++ return NULL;
38929 ++ }
38930 ++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
38931 ++ vma_m = vma->vm_mirror;
38932 ++ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
38933 ++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
38934 ++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
38935 ++
38936 ++#ifdef CONFIG_PAX_MPROTECT
38937 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
38938 ++#else
38939 ++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
38940 ++#endif
38941 ++
38942 ++ return vma_m;
38943 ++}
38944 ++#endif
38945 ++
38946 + /*
38947 + * Verify that the stack growth is acceptable and
38948 + * update accounting. This is shared with both the
38949 +@@ -1518,6 +1717,7 @@ static int acct_stack_growth(struct vm_a
38950 + return -ENOMEM;
38951 +
38952 + /* Stack limit test */
38953 ++ gr_learn_resource(current, RLIMIT_STACK, size, 1);
38954 + if (size > rlim[RLIMIT_STACK].rlim_cur)
38955 + return -ENOMEM;
38956 +
38957 +@@ -1527,6 +1727,7 @@ static int acct_stack_growth(struct vm_a
38958 + unsigned long limit;
38959 + locked = mm->locked_vm + grow;
38960 + limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
38961 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
38962 + if (locked > limit && !capable(CAP_IPC_LOCK))
38963 + return -ENOMEM;
38964 + }
38965 +@@ -1562,35 +1763,40 @@ static inline
38966 + #endif
38967 + int expand_upwards(struct vm_area_struct *vma, unsigned long address)
38968 + {
38969 +- int error;
38970 ++ int error, locknext;
38971 +
38972 + if (!(vma->vm_flags & VM_GROWSUP))
38973 + return -EFAULT;
38974 +
38975 ++ /* Also guard against wrapping around to address 0. */
38976 ++ if (address < PAGE_ALIGN(address+1))
38977 ++ address = PAGE_ALIGN(address+1);
38978 ++ else
38979 ++ return -ENOMEM;
38980 ++
38981 + /*
38982 + * We must make sure the anon_vma is allocated
38983 + * so that the anon_vma locking is not a noop.
38984 + */
38985 + if (unlikely(anon_vma_prepare(vma)))
38986 + return -ENOMEM;
38987 ++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
38988 ++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
38989 ++ return -ENOMEM;
38990 + anon_vma_lock(vma);
38991 ++ if (locknext)
38992 ++ anon_vma_lock(vma->vm_next);
38993 +
38994 + /*
38995 + * vma->vm_start/vm_end cannot change under us because the caller
38996 + * is required to hold the mmap_sem in read mode. We need the
38997 +- * anon_vma lock to serialize against concurrent expand_stacks.
38998 +- * Also guard against wrapping around to address 0.
38999 ++ * anon_vma locks to serialize against concurrent expand_stacks
39000 ++ * and expand_upwards.
39001 + */
39002 +- if (address < PAGE_ALIGN(address+4))
39003 +- address = PAGE_ALIGN(address+4);
39004 +- else {
39005 +- anon_vma_unlock(vma);
39006 +- return -ENOMEM;
39007 +- }
39008 + error = 0;
39009 +
39010 + /* Somebody else might have raced and expanded it already */
39011 +- if (address > vma->vm_end) {
39012 ++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
39013 + unsigned long size, grow;
39014 +
39015 + size = address - vma->vm_start;
39016 +@@ -1600,6 +1806,8 @@ int expand_upwards(struct vm_area_struct
39017 + if (!error)
39018 + vma->vm_end = address;
39019 + }
39020 ++ if (locknext)
39021 ++ anon_vma_unlock(vma->vm_next);
39022 + anon_vma_unlock(vma);
39023 + return error;
39024 + }
39025 +@@ -1611,7 +1819,8 @@ int expand_upwards(struct vm_area_struct
39026 + static inline int expand_downwards(struct vm_area_struct *vma,
39027 + unsigned long address)
39028 + {
39029 +- int error;
39030 ++ int error, lockprev = 0;
39031 ++ struct vm_area_struct *prev = NULL;
39032 +
39033 + /*
39034 + * We must make sure the anon_vma is allocated
39035 +@@ -1625,6 +1834,15 @@ static inline int expand_downwards(struc
39036 + if (error)
39037 + return error;
39038 +
39039 ++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
39040 ++ find_vma_prev(address, &prev);
39041 ++ lockprev = prev && (prev->vm_flags & VM_GROWSUP);
39042 ++#endif
39043 ++ if (lockprev && unlikely(anon_vma_prepare(prev)))
39044 ++ return -ENOMEM;
39045 ++ if (lockprev)
39046 ++ anon_vma_lock(prev);
39047 ++
39048 + anon_vma_lock(vma);
39049 +
39050 + /*
39051 +@@ -1634,9 +1852,15 @@ static inline int expand_downwards(struc
39052 + */
39053 +
39054 + /* Somebody else might have raced and expanded it already */
39055 +- if (address < vma->vm_start) {
39056 ++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
39057 + unsigned long size, grow;
39058 +
39059 ++#ifdef CONFIG_PAX_SEGMEXEC
39060 ++ struct vm_area_struct *vma_m;
39061 ++
39062 ++ vma_m = pax_find_mirror_vma(vma);
39063 ++#endif
39064 ++
39065 + size = vma->vm_end - address;
39066 + grow = (vma->vm_start - address) >> PAGE_SHIFT;
39067 +
39068 +@@ -1644,9 +1868,20 @@ static inline int expand_downwards(struc
39069 + if (!error) {
39070 + vma->vm_start = address;
39071 + vma->vm_pgoff -= grow;
39072 ++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
39073 ++
39074 ++#ifdef CONFIG_PAX_SEGMEXEC
39075 ++ if (vma_m) {
39076 ++ vma_m->vm_start -= grow << PAGE_SHIFT;
39077 ++ vma_m->vm_pgoff -= grow;
39078 ++ }
39079 ++#endif
39080 ++
39081 + }
39082 + }
39083 + anon_vma_unlock(vma);
39084 ++ if (lockprev)
39085 ++ anon_vma_unlock(prev);
39086 + return error;
39087 + }
39088 +
39089 +@@ -1718,6 +1953,13 @@ static void remove_vma_list(struct mm_st
39090 + do {
39091 + long nrpages = vma_pages(vma);
39092 +
39093 ++#ifdef CONFIG_PAX_SEGMEXEC
39094 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
39095 ++ vma = remove_vma(vma);
39096 ++ continue;
39097 ++ }
39098 ++#endif
39099 ++
39100 + mm->total_vm -= nrpages;
39101 + if (vma->vm_flags & VM_LOCKED)
39102 + mm->locked_vm -= nrpages;
39103 +@@ -1764,6 +2006,16 @@ detach_vmas_to_be_unmapped(struct mm_str
39104 +
39105 + insertion_point = (prev ? &prev->vm_next : &mm->mmap);
39106 + do {
39107 ++
39108 ++#ifdef CONFIG_PAX_SEGMEXEC
39109 ++ if (vma->vm_mirror) {
39110 ++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
39111 ++ vma->vm_mirror->vm_mirror = NULL;
39112 ++ vma->vm_mirror->vm_flags &= ~VM_EXEC;
39113 ++ vma->vm_mirror = NULL;
39114 ++ }
39115 ++#endif
39116 ++
39117 + rb_erase(&vma->vm_rb, &mm->mm_rb);
39118 + mm->map_count--;
39119 + tail_vma = vma;
39120 +@@ -1783,6 +2035,112 @@ detach_vmas_to_be_unmapped(struct mm_str
39121 + * Split a vma into two pieces at address 'addr', a new vma is allocated
39122 + * either for the first part or the tail.
39123 + */
39124 ++
39125 ++#ifdef CONFIG_PAX_SEGMEXEC
39126 ++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
39127 ++ unsigned long addr, int new_below)
39128 ++{
39129 ++ struct mempolicy *pol, *pol_m;
39130 ++ struct vm_area_struct *new, *vma_m, *new_m = NULL;
39131 ++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
39132 ++
39133 ++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
39134 ++ return -EINVAL;
39135 ++
39136 ++ vma_m = pax_find_mirror_vma(vma);
39137 ++ if (vma_m) {
39138 ++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
39139 ++ if (mm->map_count >= sysctl_max_map_count-1)
39140 ++ return -ENOMEM;
39141 ++ } else if (mm->map_count >= sysctl_max_map_count)
39142 ++ return -ENOMEM;
39143 ++
39144 ++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
39145 ++ if (!new)
39146 ++ return -ENOMEM;
39147 ++
39148 ++ if (vma_m) {
39149 ++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
39150 ++ if (!new_m) {
39151 ++ kmem_cache_free(vm_area_cachep, new);
39152 ++ return -ENOMEM;
39153 ++ }
39154 ++ }
39155 ++
39156 ++ /* most fields are the same, copy all, and then fixup */
39157 ++ *new = *vma;
39158 ++
39159 ++ if (new_below)
39160 ++ new->vm_end = addr;
39161 ++ else {
39162 ++ new->vm_start = addr;
39163 ++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
39164 ++ }
39165 ++
39166 ++ if (vma_m) {
39167 ++ *new_m = *vma_m;
39168 ++ new_m->vm_mirror = new;
39169 ++ new->vm_mirror = new_m;
39170 ++
39171 ++ if (new_below)
39172 ++ new_m->vm_end = addr_m;
39173 ++ else {
39174 ++ new_m->vm_start = addr_m;
39175 ++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
39176 ++ }
39177 ++ }
39178 ++
39179 ++ pol = mpol_copy(vma_policy(vma));
39180 ++ if (IS_ERR(pol)) {
39181 ++ if (new_m)
39182 ++ kmem_cache_free(vm_area_cachep, new_m);
39183 ++ kmem_cache_free(vm_area_cachep, new);
39184 ++ return PTR_ERR(pol);
39185 ++ }
39186 ++
39187 ++ if (vma_m) {
39188 ++ pol_m = mpol_copy(vma_policy(vma_m));
39189 ++ if (IS_ERR(pol_m)) {
39190 ++ mpol_free(pol);
39191 ++ kmem_cache_free(vm_area_cachep, new_m);
39192 ++ kmem_cache_free(vm_area_cachep, new);
39193 ++ return PTR_ERR(pol);
39194 ++ }
39195 ++ }
39196 ++
39197 ++ vma_set_policy(new, pol);
39198 ++
39199 ++ if (new->vm_file)
39200 ++ get_file(new->vm_file);
39201 ++
39202 ++ if (new->vm_ops && new->vm_ops->open)
39203 ++ new->vm_ops->open(new);
39204 ++
39205 ++ if (new_below)
39206 ++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
39207 ++ ((addr - new->vm_start) >> PAGE_SHIFT), new);
39208 ++ else
39209 ++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
39210 ++
39211 ++ if (vma_m) {
39212 ++ vma_set_policy(new_m, pol_m);
39213 ++
39214 ++ if (new_m->vm_file)
39215 ++ get_file(new_m->vm_file);
39216 ++
39217 ++ if (new_m->vm_ops && new_m->vm_ops->open)
39218 ++ new_m->vm_ops->open(new_m);
39219 ++
39220 ++ if (new_below)
39221 ++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
39222 ++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
39223 ++ else
39224 ++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
39225 ++ }
39226 ++
39227 ++ return 0;
39228 ++}
39229 ++#else
39230 + int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
39231 + unsigned long addr, int new_below)
39232 + {
39233 +@@ -1830,17 +2188,37 @@ int split_vma(struct mm_struct * mm, str
39234 +
39235 + return 0;
39236 + }
39237 ++#endif
39238 +
39239 + /* Munmap is split into 2 main parts -- this part which finds
39240 + * what needs doing, and the areas themselves, which do the
39241 + * work. This now handles partial unmappings.
39242 + * Jeremy Fitzhardinge <jeremy@××××.org>
39243 + */
39244 ++#ifdef CONFIG_PAX_SEGMEXEC
39245 + int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39246 + {
39247 ++ int ret = __do_munmap(mm, start, len);
39248 ++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
39249 ++ return ret;
39250 ++
39251 ++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
39252 ++}
39253 ++
39254 ++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39255 ++#else
39256 ++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
39257 ++#endif
39258 ++{
39259 + unsigned long end;
39260 + struct vm_area_struct *vma, *prev, *last;
39261 +
39262 ++ /*
39263 ++ * mm->mmap_sem is required to protect against another thread
39264 ++ * changing the mappings in case we sleep.
39265 ++ */
39266 ++ verify_mm_writelocked(mm);
39267 ++
39268 + if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
39269 + return -EINVAL;
39270 +
39271 +@@ -1890,6 +2268,8 @@ int do_munmap(struct mm_struct *mm, unsi
39272 + /* Fix up all other VM information */
39273 + remove_vma_list(mm, vma);
39274 +
39275 ++ track_exec_limit(mm, start, end, 0UL);
39276 ++
39277 + return 0;
39278 + }
39279 +
39280 +@@ -1902,22 +2282,18 @@ asmlinkage long sys_munmap(unsigned long
39281 +
39282 + profile_munmap(addr);
39283 +
39284 ++#ifdef CONFIG_PAX_SEGMEXEC
39285 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
39286 ++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
39287 ++ return -EINVAL;
39288 ++#endif
39289 ++
39290 + down_write(&mm->mmap_sem);
39291 + ret = do_munmap(mm, addr, len);
39292 + up_write(&mm->mmap_sem);
39293 + return ret;
39294 + }
39295 +
39296 +-static inline void verify_mm_writelocked(struct mm_struct *mm)
39297 +-{
39298 +-#ifdef CONFIG_DEBUG_VM
39299 +- if (unlikely(down_read_trylock(&mm->mmap_sem))) {
39300 +- WARN_ON(1);
39301 +- up_read(&mm->mmap_sem);
39302 +- }
39303 +-#endif
39304 +-}
39305 +-
39306 + /*
39307 + * this is really a simplified "do_mmap". it only handles
39308 + * anonymous maps. eventually we may be able to do some
39309 +@@ -1931,6 +2307,11 @@ unsigned long do_brk(unsigned long addr,
39310 + struct rb_node ** rb_link, * rb_parent;
39311 + pgoff_t pgoff = addr >> PAGE_SHIFT;
39312 + int error;
39313 ++ unsigned long charged;
39314 ++
39315 ++#ifdef CONFIG_PAX_SEGMEXEC
39316 ++ struct vm_area_struct *vma_m = NULL;
39317 ++#endif
39318 +
39319 + len = PAGE_ALIGN(len);
39320 + if (!len)
39321 +@@ -1948,19 +2329,34 @@ unsigned long do_brk(unsigned long addr,
39322 +
39323 + flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
39324 +
39325 ++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
39326 ++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
39327 ++ flags &= ~VM_EXEC;
39328 ++
39329 ++#ifdef CONFIG_PAX_MPROTECT
39330 ++ if (mm->pax_flags & MF_PAX_MPROTECT)
39331 ++ flags &= ~VM_MAYEXEC;
39332 ++#endif
39333 ++
39334 ++ }
39335 ++#endif
39336 ++
39337 + error = arch_mmap_check(addr, len, flags);
39338 + if (error)
39339 + return error;
39340 +
39341 ++ charged = len >> PAGE_SHIFT;
39342 ++
39343 + /*
39344 + * mlock MCL_FUTURE?
39345 + */
39346 + if (mm->def_flags & VM_LOCKED) {
39347 + unsigned long locked, lock_limit;
39348 +- locked = len >> PAGE_SHIFT;
39349 ++ locked = charged;
39350 + locked += mm->locked_vm;
39351 + lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
39352 + lock_limit >>= PAGE_SHIFT;
39353 ++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
39354 + if (locked > lock_limit && !capable(CAP_IPC_LOCK))
39355 + return -EAGAIN;
39356 + }
39357 +@@ -1974,22 +2370,22 @@ unsigned long do_brk(unsigned long addr,
39358 + /*
39359 + * Clear old maps. this also does some error checking for us
39360 + */
39361 +- munmap_back:
39362 + vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
39363 + if (vma && vma->vm_start < addr + len) {
39364 + if (do_munmap(mm, addr, len))
39365 + return -ENOMEM;
39366 +- goto munmap_back;
39367 ++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
39368 ++ BUG_ON(vma && vma->vm_start < addr + len);
39369 + }
39370 +
39371 + /* Check against address space limits *after* clearing old maps... */
39372 +- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
39373 ++ if (!may_expand_vm(mm, charged))
39374 + return -ENOMEM;
39375 +
39376 + if (mm->map_count > sysctl_max_map_count)
39377 + return -ENOMEM;
39378 +
39379 +- if (security_vm_enough_memory(len >> PAGE_SHIFT))
39380 ++ if (security_vm_enough_memory(charged))
39381 + return -ENOMEM;
39382 +
39383 + /* Can we just expand an old private anonymous mapping? */
39384 +@@ -2002,24 +2398,41 @@ unsigned long do_brk(unsigned long addr,
39385 + */
39386 + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39387 + if (!vma) {
39388 +- vm_unacct_memory(len >> PAGE_SHIFT);
39389 ++ vm_unacct_memory(charged);
39390 + return -ENOMEM;
39391 + }
39392 +
39393 ++#ifdef CONFIG_PAX_SEGMEXEC
39394 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
39395 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39396 ++ if (!vma_m) {
39397 ++ kmem_cache_free(vm_area_cachep, vma);
39398 ++ vm_unacct_memory(charged);
39399 ++ return -ENOMEM;
39400 ++ }
39401 ++ }
39402 ++#endif
39403 ++
39404 + vma->vm_mm = mm;
39405 + vma->vm_start = addr;
39406 + vma->vm_end = addr + len;
39407 + vma->vm_pgoff = pgoff;
39408 + vma->vm_flags = flags;
39409 +- vma->vm_page_prot = protection_map[flags &
39410 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
39411 ++ vma->vm_page_prot = vm_get_page_prot(flags);
39412 + vma_link(mm, vma, prev, rb_link, rb_parent);
39413 ++
39414 ++#ifdef CONFIG_PAX_SEGMEXEC
39415 ++ if (vma_m)
39416 ++ pax_mirror_vma(vma_m, vma);
39417 ++#endif
39418 ++
39419 + out:
39420 +- mm->total_vm += len >> PAGE_SHIFT;
39421 ++ mm->total_vm += charged;
39422 + if (flags & VM_LOCKED) {
39423 +- mm->locked_vm += len >> PAGE_SHIFT;
39424 ++ mm->locked_vm += charged;
39425 + make_pages_present(addr, addr + len);
39426 + }
39427 ++ track_exec_limit(mm, addr, addr + len, flags);
39428 + return addr;
39429 + }
39430 +
39431 +@@ -2050,8 +2463,10 @@ void exit_mmap(struct mm_struct *mm)
39432 + * Walk the list again, actually closing and freeing it,
39433 + * with preemption enabled, without holding any MM locks.
39434 + */
39435 +- while (vma)
39436 ++ while (vma) {
39437 ++ vma->vm_mirror = NULL;
39438 + vma = remove_vma(vma);
39439 ++ }
39440 +
39441 + BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
39442 + }
39443 +@@ -2065,6 +2480,10 @@ int insert_vm_struct(struct mm_struct *
39444 + struct vm_area_struct * __vma, * prev;
39445 + struct rb_node ** rb_link, * rb_parent;
39446 +
39447 ++#ifdef CONFIG_PAX_SEGMEXEC
39448 ++ struct vm_area_struct *vma_m = NULL;
39449 ++#endif
39450 ++
39451 + /*
39452 + * The vm_pgoff of a purely anonymous vma should be irrelevant
39453 + * until its first write fault, when page's anon_vma and index
39454 +@@ -2087,7 +2506,22 @@ int insert_vm_struct(struct mm_struct *
39455 + if ((vma->vm_flags & VM_ACCOUNT) &&
39456 + security_vm_enough_memory_mm(mm, vma_pages(vma)))
39457 + return -ENOMEM;
39458 ++
39459 ++#ifdef CONFIG_PAX_SEGMEXEC
39460 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
39461 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39462 ++ if (!vma_m)
39463 ++ return -ENOMEM;
39464 ++ }
39465 ++#endif
39466 ++
39467 + vma_link(mm, vma, prev, rb_link, rb_parent);
39468 ++
39469 ++#ifdef CONFIG_PAX_SEGMEXEC
39470 ++ if (vma_m)
39471 ++ pax_mirror_vma(vma_m, vma);
39472 ++#endif
39473 ++
39474 + return 0;
39475 + }
39476 +
39477 +@@ -2145,6 +2579,30 @@ struct vm_area_struct *copy_vma(struct v
39478 + return new_vma;
39479 + }
39480 +
39481 ++#ifdef CONFIG_PAX_SEGMEXEC
39482 ++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
39483 ++{
39484 ++ struct vm_area_struct *prev_m;
39485 ++ struct rb_node **rb_link_m, *rb_parent_m;
39486 ++
39487 ++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
39488 ++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma));
39489 ++ *vma_m = *vma;
39490 ++ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
39491 ++ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
39492 ++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
39493 ++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
39494 ++ if (vma_m->vm_file)
39495 ++ get_file(vma_m->vm_file);
39496 ++ if (vma_m->vm_ops && vma_m->vm_ops->open)
39497 ++ vma_m->vm_ops->open(vma_m);
39498 ++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
39499 ++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
39500 ++ vma_m->vm_mirror = vma;
39501 ++ vma->vm_mirror = vma_m;
39502 ++}
39503 ++#endif
39504 ++
39505 + /*
39506 + * Return true if the calling process may expand its vm space by the passed
39507 + * number of pages
39508 +@@ -2155,7 +2613,7 @@ int may_expand_vm(struct mm_struct *mm,
39509 + unsigned long lim;
39510 +
39511 + lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
39512 +-
39513 ++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
39514 + if (cur + npages > lim)
39515 + return 0;
39516 + return 1;
39517 +@@ -2167,7 +2625,7 @@ static struct page *special_mapping_nopa
39518 + {
39519 + struct page **pages;
39520 +
39521 +- BUG_ON(address < vma->vm_start || address >= vma->vm_end);
39522 ++ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
39523 +
39524 + address -= vma->vm_start;
39525 + for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
39526 +@@ -2217,8 +2675,17 @@ int install_special_mapping(struct mm_st
39527 + vma->vm_start = addr;
39528 + vma->vm_end = addr + len;
39529 +
39530 ++#ifdef CONFIG_PAX_MPROTECT
39531 ++ if (mm->pax_flags & MF_PAX_MPROTECT) {
39532 ++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
39533 ++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
39534 ++ else
39535 ++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
39536 ++ }
39537 ++#endif
39538 ++
39539 + vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
39540 +- vma->vm_page_prot = protection_map[vma->vm_flags & 7];
39541 ++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
39542 +
39543 + vma->vm_ops = &special_mapping_vmops;
39544 + vma->vm_private_data = pages;
39545 +diff -Nurp linux-2.6.23.15/mm/mprotect.c linux-2.6.23.15-grsec/mm/mprotect.c
39546 +--- linux-2.6.23.15/mm/mprotect.c 2007-10-09 21:31:38.000000000 +0100
39547 ++++ linux-2.6.23.15-grsec/mm/mprotect.c 2008-02-11 10:37:45.000000000 +0000
39548 +@@ -21,10 +21,17 @@
39549 + #include <linux/syscalls.h>
39550 + #include <linux/swap.h>
39551 + #include <linux/swapops.h>
39552 ++#include <linux/grsecurity.h>
39553 ++
39554 ++#ifdef CONFIG_PAX_MPROTECT
39555 ++#include <linux/elf.h>
39556 ++#endif
39557 ++
39558 + #include <asm/uaccess.h>
39559 + #include <asm/pgtable.h>
39560 + #include <asm/cacheflush.h>
39561 + #include <asm/tlbflush.h>
39562 ++#include <asm/mmu_context.h>
39563 +
39564 + static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
39565 + unsigned long addr, unsigned long end, pgprot_t newprot,
39566 +@@ -128,6 +135,48 @@ static void change_protection(struct vm_
39567 + flush_tlb_range(vma, start, end);
39568 + }
39569 +
39570 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
39571 ++/* called while holding the mmap semaphor for writing except stack expansion */
39572 ++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
39573 ++{
39574 ++ unsigned long oldlimit, newlimit = 0UL;
39575 ++
39576 ++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
39577 ++ return;
39578 ++
39579 ++ spin_lock(&mm->page_table_lock);
39580 ++ oldlimit = mm->context.user_cs_limit;
39581 ++ if ((prot & VM_EXEC) && oldlimit < end)
39582 ++ /* USER_CS limit moved up */
39583 ++ newlimit = end;
39584 ++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
39585 ++ /* USER_CS limit moved down */
39586 ++ newlimit = start;
39587 ++
39588 ++ if (newlimit) {
39589 ++ mm->context.user_cs_limit = newlimit;
39590 ++
39591 ++#ifdef CONFIG_SMP
39592 ++ wmb();
39593 ++ cpus_clear(mm->context.cpu_user_cs_mask);
39594 ++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
39595 ++#endif
39596 ++
39597 ++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
39598 ++ }
39599 ++ spin_unlock(&mm->page_table_lock);
39600 ++ if (newlimit == end) {
39601 ++ struct vm_area_struct *vma = find_vma(mm, oldlimit);
39602 ++
39603 ++ for (; vma && vma->vm_start < end; vma = vma->vm_next)
39604 ++ if (is_vm_hugetlb_page(vma))
39605 ++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
39606 ++ else
39607 ++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
39608 ++ }
39609 ++}
39610 ++#endif
39611 ++
39612 + int
39613 + mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
39614 + unsigned long start, unsigned long end, unsigned long newflags)
39615 +@@ -140,11 +189,39 @@ mprotect_fixup(struct vm_area_struct *vm
39616 + int error;
39617 + int dirty_accountable = 0;
39618 +
39619 ++#ifdef CONFIG_PAX_SEGMEXEC
39620 ++ struct vm_area_struct *vma_m = NULL;
39621 ++ unsigned long start_m, end_m;
39622 ++
39623 ++ start_m = start + SEGMEXEC_TASK_SIZE;
39624 ++ end_m = end + SEGMEXEC_TASK_SIZE;
39625 ++#endif
39626 ++
39627 + if (newflags == oldflags) {
39628 + *pprev = vma;
39629 + return 0;
39630 + }
39631 +
39632 ++#ifdef CONFIG_PAX_SEGMEXEC
39633 ++ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
39634 ++ if (start != vma->vm_start) {
39635 ++ error = split_vma(mm, vma, start, 1);
39636 ++ if (error)
39637 ++ return -ENOMEM;
39638 ++ }
39639 ++
39640 ++ if (end != vma->vm_end) {
39641 ++ error = split_vma(mm, vma, end, 0);
39642 ++ if (error)
39643 ++ return -ENOMEM;
39644 ++ }
39645 ++
39646 ++ error = __do_munmap(mm, start_m, end_m - start_m);
39647 ++ if (error)
39648 ++ return -ENOMEM;
39649 ++ }
39650 ++#endif
39651 ++
39652 + /*
39653 + * If we make a private mapping writable we increase our commit;
39654 + * but (without finer accounting) cannot reduce our commit if we
39655 +@@ -187,17 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm
39656 + goto fail;
39657 + }
39658 +
39659 ++#ifdef CONFIG_PAX_SEGMEXEC
39660 ++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
39661 ++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
39662 ++ if (!vma_m) {
39663 ++ error = -ENOMEM;
39664 ++ goto fail;
39665 ++ }
39666 ++ }
39667 ++#endif
39668 ++
39669 + success:
39670 + /*
39671 + * vm_flags and vm_page_prot are protected by the mmap_sem
39672 + * held in write mode.
39673 + */
39674 + vma->vm_flags = newflags;
39675 +- vma->vm_page_prot = protection_map[newflags &
39676 +- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
39677 ++ vma->vm_page_prot = vm_get_page_prot(newflags);
39678 + if (vma_wants_writenotify(vma)) {
39679 +- vma->vm_page_prot = protection_map[newflags &
39680 +- (VM_READ|VM_WRITE|VM_EXEC)];
39681 ++ vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
39682 + dirty_accountable = 1;
39683 + }
39684 +
39685 +@@ -205,6 +290,12 @@ success:
39686 + hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
39687 + else
39688 + change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
39689 ++
39690 ++#ifdef CONFIG_PAX_SEGMEXEC
39691 ++ if (vma_m)
39692 ++ pax_mirror_vma(vma_m, vma);
39693 ++#endif
39694 ++
39695 + vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
39696 + vm_stat_account(mm, newflags, vma->vm_file, nrpages);
39697 + return 0;
39698 +@@ -214,6 +305,70 @@ fail:
39699 + return error;
39700 + }
39701 +
39702 ++#ifdef CONFIG_PAX_MPROTECT
39703 ++/* PaX: non-PIC ELF libraries need relocations on their executable segments
39704 ++ * therefore we'll grant them VM_MAYWRITE once during their life.
39705 ++ *
39706 ++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
39707 ++ * basis because we want to allow the common case and not the special ones.
39708 ++ */
39709 ++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
39710 ++{
39711 ++ struct elfhdr elf_h;
39712 ++ struct elf_phdr elf_p;
39713 ++ elf_addr_t dyn_offset = 0UL;
39714 ++ elf_dyn dyn;
39715 ++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
39716 ++
39717 ++#ifndef CONFIG_PAX_NOELFRELOCS
39718 ++ if ((vma->vm_start != start) ||
39719 ++ !vma->vm_file ||
39720 ++ !(vma->vm_flags & VM_MAYEXEC) ||
39721 ++ (vma->vm_flags & VM_MAYNOTWRITE))
39722 ++#endif
39723 ++
39724 ++ return;
39725 ++
39726 ++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
39727 ++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
39728 ++
39729 ++#ifdef CONFIG_PAX_ETEXECRELOCS
39730 ++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
39731 ++#else
39732 ++ elf_h.e_type != ET_DYN ||
39733 ++#endif
39734 ++
39735 ++ !elf_check_arch(&elf_h) ||
39736 ++ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
39737 ++ elf_h.e_phnum > j)
39738 ++ return;
39739 ++
39740 ++ for (i = 0UL; i < elf_h.e_phnum; i++) {
39741 ++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
39742 ++ return;
39743 ++ if (elf_p.p_type == PT_DYNAMIC) {
39744 ++ dyn_offset = elf_p.p_offset;
39745 ++ j = i;
39746 ++ }
39747 ++ }
39748 ++ if (elf_h.e_phnum <= j)
39749 ++ return;
39750 ++
39751 ++ i = 0UL;
39752 ++ do {
39753 ++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
39754 ++ return;
39755 ++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
39756 ++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
39757 ++ gr_log_textrel(vma);
39758 ++ return;
39759 ++ }
39760 ++ i++;
39761 ++ } while (dyn.d_tag != DT_NULL);
39762 ++ return;
39763 ++}
39764 ++#endif
39765 ++
39766 + asmlinkage long
39767 + sys_mprotect(unsigned long start, size_t len, unsigned long prot)
39768 + {
39769 +@@ -233,6 +388,17 @@ sys_mprotect(unsigned long start, size_t
39770 + end = start + len;
39771 + if (end <= start)
39772 + return -ENOMEM;
39773 ++
39774 ++#ifdef CONFIG_PAX_SEGMEXEC
39775 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
39776 ++ if (end > SEGMEXEC_TASK_SIZE)
39777 ++ return -EINVAL;
39778 ++ } else
39779 ++#endif
39780 ++
39781 ++ if (end > TASK_SIZE)
39782 ++ return -EINVAL;
39783 ++
39784 + if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
39785 + return -EINVAL;
39786 +
39787 +@@ -240,7 +406,7 @@ sys_mprotect(unsigned long start, size_t
39788 + /*
39789 + * Does the application expect PROT_READ to imply PROT_EXEC:
39790 + */
39791 +- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
39792 ++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
39793 + prot |= PROT_EXEC;
39794 +
39795 + vm_flags = calc_vm_prot_bits(prot);
39796 +@@ -272,6 +438,16 @@ sys_mprotect(unsigned long start, size_t
39797 + if (start > vma->vm_start)
39798 + prev = vma;
39799 +
39800 ++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
39801 ++ error = -EACCES;
39802 ++ goto out;
39803 ++ }
39804 ++
39805 ++#ifdef CONFIG_PAX_MPROTECT
39806 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
39807 ++ pax_handle_maywrite(vma, start);
39808 ++#endif
39809 ++
39810 + for (nstart = start ; ; ) {
39811 + unsigned long newflags;
39812 +
39813 +@@ -285,6 +461,12 @@ sys_mprotect(unsigned long start, size_t
39814 + goto out;
39815 + }
39816 +
39817 ++#ifdef CONFIG_PAX_MPROTECT
39818 ++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
39819 ++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
39820 ++ newflags &= ~VM_MAYWRITE;
39821 ++#endif
39822 ++
39823 + error = security_file_mprotect(vma, reqprot, prot);
39824 + if (error)
39825 + goto out;
39826 +@@ -295,6 +477,9 @@ sys_mprotect(unsigned long start, size_t
39827 + error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
39828 + if (error)
39829 + goto out;
39830 ++
39831 ++ track_exec_limit(current->mm, nstart, tmp, vm_flags);
39832 ++
39833 + nstart = tmp;
39834 +
39835 + if (nstart < prev->vm_end)
39836 +diff -Nurp linux-2.6.23.15/mm/mremap.c linux-2.6.23.15-grsec/mm/mremap.c
39837 +--- linux-2.6.23.15/mm/mremap.c 2007-10-09 21:31:38.000000000 +0100
39838 ++++ linux-2.6.23.15-grsec/mm/mremap.c 2008-02-11 10:37:45.000000000 +0000
39839 +@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
39840 + continue;
39841 + pte = ptep_clear_flush(vma, old_addr, old_pte);
39842 + pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
39843 ++
39844 ++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
39845 ++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
39846 ++ pte = pte_exprotect(pte);
39847 ++#endif
39848 ++
39849 + set_pte_at(mm, new_addr, new_pte, pte);
39850 + }
39851 +
39852 +@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
39853 + struct vm_area_struct *vma;
39854 + unsigned long ret = -EINVAL;
39855 + unsigned long charged = 0;
39856 ++ unsigned long task_size = TASK_SIZE;
39857 +
39858 + if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
39859 + goto out;
39860 +@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
39861 + if (!new_len)
39862 + goto out;
39863 +
39864 ++#ifdef CONFIG_PAX_SEGMEXEC
39865 ++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
39866 ++ task_size = SEGMEXEC_TASK_SIZE;
39867 ++#endif
39868 ++
39869 ++ if (new_len > task_size || addr > task_size-new_len ||
39870 ++ old_len > task_size || addr > task_size-old_len)
39871 ++ goto out;
39872 ++
39873 + /* new_addr is only valid if MREMAP_FIXED is specified */
39874 + if (flags & MREMAP_FIXED) {
39875 + if (new_addr & ~PAGE_MASK)
39876 +@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
39877 + if (!(flags & MREMAP_MAYMOVE))
39878 + goto out;
39879 +
39880 +- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
39881 ++ if (new_addr > task_size - new_len)
39882 + goto out;
39883 +
39884 + /* Check if the location we're moving into overlaps the
39885 + * old location at all, and fail if it does.
39886 + */
39887 +- if ((new_addr <= addr) && (new_addr+new_len) > addr)
39888 +- goto out;
39889 +-
39890 +- if ((addr <= new_addr) && (addr+old_len) > new_addr)
39891 ++ if (addr + old_len > new_addr && new_addr + new_len > addr)
39892 + goto out;
39893 +
39894 + ret = security_file_mmap(0, 0, 0, 0, new_addr, 1);
39895 +@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad
39896 + ret = -EINVAL;
39897 + goto out;
39898 + }
39899 ++
39900 ++#ifdef CONFIG_PAX_SEGMEXEC
39901 ++ if (pax_find_mirror_vma(vma)) {
39902 ++ ret = -EINVAL;
39903 ++ goto out;
39904 ++ }
39905 ++#endif
39906 ++
39907 + /* We can't remap across vm area boundaries */
39908 + if (old_len > vma->vm_end - addr)
39909 + goto out;
39910 +@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad
39911 + if (old_len == vma->vm_end - addr &&
39912 + !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
39913 + (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
39914 +- unsigned long max_addr = TASK_SIZE;
39915 ++ unsigned long max_addr = task_size;
39916 + if (vma->vm_next)
39917 + max_addr = vma->vm_next->vm_start;
39918 + /* can we just expand the current mapping? */
39919 +@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad
39920 + addr + new_len);
39921 + }
39922 + ret = addr;
39923 ++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
39924 + goto out;
39925 + }
39926 + }
39927 +@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad
39928 + */
39929 + ret = -ENOMEM;
39930 + if (flags & MREMAP_MAYMOVE) {
39931 ++ unsigned long map_flags = 0;
39932 + if (!(flags & MREMAP_FIXED)) {
39933 +- unsigned long map_flags = 0;
39934 + if (vma->vm_flags & VM_MAYSHARE)
39935 + map_flags |= MAP_SHARED;
39936 +
39937 +@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad
39938 + if (ret)
39939 + goto out;
39940 + }
39941 ++ map_flags = vma->vm_flags;
39942 + ret = move_vma(vma, addr, old_len, new_len, new_addr);
39943 ++ if (!(ret & ~PAGE_MASK)) {
39944 ++ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
39945 ++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
39946 ++ }
39947 + }
39948 + out:
39949 + if (ret & ~PAGE_MASK)
39950 +diff -Nurp linux-2.6.23.15/mm/nommu.c linux-2.6.23.15-grsec/mm/nommu.c
39951 +--- linux-2.6.23.15/mm/nommu.c 2007-10-09 21:31:38.000000000 +0100
39952 ++++ linux-2.6.23.15-grsec/mm/nommu.c 2008-02-11 10:37:45.000000000 +0000
39953 +@@ -376,15 +376,6 @@ struct vm_area_struct *find_vma(struct m
39954 + }
39955 + EXPORT_SYMBOL(find_vma);
39956 +
39957 +-/*
39958 +- * find a VMA
39959 +- * - we don't extend stack VMAs under NOMMU conditions
39960 +- */
39961 +-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
39962 +-{
39963 +- return find_vma(mm, addr);
39964 +-}
39965 +-
39966 + int expand_stack(struct vm_area_struct *vma, unsigned long address)
39967 + {
39968 + return -ENOMEM;
39969 +diff -Nurp linux-2.6.23.15/mm/page_alloc.c linux-2.6.23.15-grsec/mm/page_alloc.c
39970 +--- linux-2.6.23.15/mm/page_alloc.c 2007-10-09 21:31:38.000000000 +0100
39971 ++++ linux-2.6.23.15-grsec/mm/page_alloc.c 2008-02-11 10:37:45.000000000 +0000
39972 +@@ -402,7 +402,7 @@ static inline int page_is_buddy(struct p
39973 + static inline void __free_one_page(struct page *page,
39974 + struct zone *zone, unsigned int order)
39975 + {
39976 +- unsigned long page_idx;
39977 ++ unsigned long page_idx, index;
39978 + int order_size = 1 << order;
39979 +
39980 + if (unlikely(PageCompound(page)))
39981 +@@ -413,6 +413,11 @@ static inline void __free_one_page(struc
39982 + VM_BUG_ON(page_idx & (order_size - 1));
39983 + VM_BUG_ON(bad_range(zone, page));
39984 +
39985 ++#ifdef CONFIG_PAX_MEMORY_SANITIZE
39986 ++ for (index = order_size; index; --index)
39987 ++ sanitize_highpage(page + index - 1);
39988 ++#endif
39989 ++
39990 + __mod_zone_page_state(zone, NR_FREE_PAGES, order_size);
39991 + while (order < MAX_ORDER-1) {
39992 + unsigned long combined_idx;
39993 +diff -Nurp linux-2.6.23.15/mm/rmap.c linux-2.6.23.15-grsec/mm/rmap.c
39994 +--- linux-2.6.23.15/mm/rmap.c 2007-10-09 21:31:38.000000000 +0100
39995 ++++ linux-2.6.23.15-grsec/mm/rmap.c 2008-02-11 10:37:45.000000000 +0000
39996 +@@ -63,6 +63,10 @@ int anon_vma_prepare(struct vm_area_stru
39997 + struct mm_struct *mm = vma->vm_mm;
39998 + struct anon_vma *allocated, *locked;
39999 +
40000 ++#ifdef CONFIG_PAX_SEGMEXEC
40001 ++ struct vm_area_struct *vma_m;
40002 ++#endif
40003 ++
40004 + anon_vma = find_mergeable_anon_vma(vma);
40005 + if (anon_vma) {
40006 + allocated = NULL;
40007 +@@ -79,6 +83,15 @@ int anon_vma_prepare(struct vm_area_stru
40008 + /* page_table_lock to protect against threads */
40009 + spin_lock(&mm->page_table_lock);
40010 + if (likely(!vma->anon_vma)) {
40011 ++
40012 ++#ifdef CONFIG_PAX_SEGMEXEC
40013 ++ vma_m = pax_find_mirror_vma(vma);
40014 ++ if (vma_m) {
40015 ++ vma_m->anon_vma = anon_vma;
40016 ++ __anon_vma_link(vma_m);
40017 ++ }
40018 ++#endif
40019 ++
40020 + vma->anon_vma = anon_vma;
40021 + list_add_tail(&vma->anon_vma_node, &anon_vma->head);
40022 + allocated = NULL;
40023 +diff -Nurp linux-2.6.23.15/mm/shmem.c linux-2.6.23.15-grsec/mm/shmem.c
40024 +--- linux-2.6.23.15/mm/shmem.c 2008-02-11 10:36:03.000000000 +0000
40025 ++++ linux-2.6.23.15-grsec/mm/shmem.c 2008-02-11 10:37:45.000000000 +0000
40026 +@@ -2452,7 +2452,7 @@ static struct file_system_type tmpfs_fs_
40027 + .get_sb = shmem_get_sb,
40028 + .kill_sb = kill_litter_super,
40029 + };
40030 +-static struct vfsmount *shm_mnt;
40031 ++struct vfsmount *shm_mnt;
40032 +
40033 + static int __init init_tmpfs(void)
40034 + {
40035 +diff -Nurp linux-2.6.23.15/mm/slab.c linux-2.6.23.15-grsec/mm/slab.c
40036 +--- linux-2.6.23.15/mm/slab.c 2007-10-09 21:31:38.000000000 +0100
40037 ++++ linux-2.6.23.15-grsec/mm/slab.c 2008-02-11 10:37:45.000000000 +0000
40038 +@@ -306,7 +306,7 @@ struct kmem_list3 {
40039 + * Need this for bootstrapping a per node allocator.
40040 + */
40041 + #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
40042 +-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
40043 ++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
40044 + #define CACHE_CACHE 0
40045 + #define SIZE_AC 1
40046 + #define SIZE_L3 (1 + MAX_NUMNODES)
40047 +@@ -655,14 +655,14 @@ struct cache_names {
40048 + static struct cache_names __initdata cache_names[] = {
40049 + #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
40050 + #include <linux/kmalloc_sizes.h>
40051 +- {NULL,}
40052 ++ {NULL, NULL}
40053 + #undef CACHE
40054 + };
40055 +
40056 + static struct arraycache_init initarray_cache __initdata =
40057 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
40058 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
40059 + static struct arraycache_init initarray_generic =
40060 +- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
40061 ++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
40062 +
40063 + /* internal cache of cache description objs */
40064 + static struct kmem_cache cache_cache = {
40065 +@@ -2980,7 +2980,7 @@ retry:
40066 + * there must be at least one object available for
40067 + * allocation.
40068 + */
40069 +- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
40070 ++ BUG_ON(slabp->inuse >= cachep->num);
40071 +
40072 + while (slabp->inuse < cachep->num && batchcount--) {
40073 + STATS_INC_ALLOCED(cachep);
40074 +diff -Nurp linux-2.6.23.15/mm/slub.c linux-2.6.23.15-grsec/mm/slub.c
40075 +--- linux-2.6.23.15/mm/slub.c 2008-02-11 10:36:03.000000000 +0000
40076 ++++ linux-2.6.23.15-grsec/mm/slub.c 2008-02-11 10:37:45.000000000 +0000
40077 +@@ -1530,7 +1530,7 @@ debug:
40078 + *
40079 + * Otherwise we can simply pick the next object from the lockless free list.
40080 + */
40081 +-static void __always_inline *slab_alloc(struct kmem_cache *s,
40082 ++static __always_inline void *slab_alloc(struct kmem_cache *s,
40083 + gfp_t gfpflags, int node, void *addr)
40084 + {
40085 + struct page *page;
40086 +@@ -1639,7 +1639,7 @@ debug:
40087 + * If fastpath is not possible then fall back to __slab_free where we deal
40088 + * with all sorts of special processing.
40089 + */
40090 +-static void __always_inline slab_free(struct kmem_cache *s,
40091 ++static __always_inline void slab_free(struct kmem_cache *s,
40092 + struct page *page, void *x, void *addr)
40093 + {
40094 + void **object = (void *)x;
40095 +diff -Nurp linux-2.6.23.15/mm/swap.c linux-2.6.23.15-grsec/mm/swap.c
40096 +--- linux-2.6.23.15/mm/swap.c 2007-10-09 21:31:38.000000000 +0100
40097 ++++ linux-2.6.23.15-grsec/mm/swap.c 2008-02-11 10:37:45.000000000 +0000
40098 +@@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed);
40099 + * lru_cache_add: add a page to the page lists
40100 + * @page: the page to add
40101 + */
40102 +-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
40103 +-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
40104 ++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
40105 ++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
40106 +
40107 + void fastcall lru_cache_add(struct page *page)
40108 + {
40109 +diff -Nurp linux-2.6.23.15/mm/tiny-shmem.c linux-2.6.23.15-grsec/mm/tiny-shmem.c
40110 +--- linux-2.6.23.15/mm/tiny-shmem.c 2007-10-09 21:31:38.000000000 +0100
40111 ++++ linux-2.6.23.15-grsec/mm/tiny-shmem.c 2008-02-11 10:37:45.000000000 +0000
40112 +@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
40113 + .kill_sb = kill_litter_super,
40114 + };
40115 +
40116 +-static struct vfsmount *shm_mnt;
40117 ++struct vfsmount *shm_mnt;
40118 +
40119 + static int __init init_tmpfs(void)
40120 + {
40121 +diff -Nurp linux-2.6.23.15/mm/vmalloc.c linux-2.6.23.15-grsec/mm/vmalloc.c
40122 +--- linux-2.6.23.15/mm/vmalloc.c 2007-10-09 21:31:38.000000000 +0100
40123 ++++ linux-2.6.23.15-grsec/mm/vmalloc.c 2008-02-11 10:37:45.000000000 +0000
40124 +@@ -201,6 +201,8 @@ static struct vm_struct *__get_vm_area_n
40125 +
40126 + write_lock(&vmlist_lock);
40127 + for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
40128 ++ if (addr > end - size)
40129 ++ goto out;
40130 + if ((unsigned long)tmp->addr < addr) {
40131 + if((unsigned long)tmp->addr + tmp->size >= addr)
40132 + addr = ALIGN(tmp->size +
40133 +@@ -212,8 +214,6 @@ static struct vm_struct *__get_vm_area_n
40134 + if (size + addr <= (unsigned long)tmp->addr)
40135 + goto found;
40136 + addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
40137 +- if (addr > end - size)
40138 +- goto out;
40139 + }
40140 +
40141 + found:
40142 +diff -Nurp linux-2.6.23.15/net/core/flow.c linux-2.6.23.15-grsec/net/core/flow.c
40143 +--- linux-2.6.23.15/net/core/flow.c 2007-10-09 21:31:38.000000000 +0100
40144 ++++ linux-2.6.23.15-grsec/net/core/flow.c 2008-02-11 10:37:45.000000000 +0000
40145 +@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
40146 +
40147 + static u32 flow_hash_shift;
40148 + #define flow_hash_size (1 << flow_hash_shift)
40149 +-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
40150 ++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
40151 +
40152 + #define flow_table(cpu) (per_cpu(flow_tables, cpu))
40153 +
40154 +@@ -53,7 +53,7 @@ struct flow_percpu_info {
40155 + u32 hash_rnd;
40156 + int count;
40157 + } ____cacheline_aligned;
40158 +-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
40159 ++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
40160 +
40161 + #define flow_hash_rnd_recalc(cpu) \
40162 + (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
40163 +@@ -70,7 +70,7 @@ struct flow_flush_info {
40164 + atomic_t cpuleft;
40165 + struct completion completion;
40166 + };
40167 +-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
40168 ++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
40169 +
40170 + #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
40171 +
40172 +diff -Nurp linux-2.6.23.15/net/dccp/ccids/ccid3.c linux-2.6.23.15-grsec/net/dccp/ccids/ccid3.c
40173 +--- linux-2.6.23.15/net/dccp/ccids/ccid3.c 2007-10-09 21:31:38.000000000 +0100
40174 ++++ linux-2.6.23.15-grsec/net/dccp/ccids/ccid3.c 2008-02-11 10:37:45.000000000 +0000
40175 +@@ -44,7 +44,7 @@
40176 + static int ccid3_debug;
40177 + #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
40178 + #else
40179 +-#define ccid3_pr_debug(format, a...)
40180 ++#define ccid3_pr_debug(format, a...) do {} while (0)
40181 + #endif
40182 +
40183 + static struct dccp_tx_hist *ccid3_tx_hist;
40184 +diff -Nurp linux-2.6.23.15/net/dccp/dccp.h linux-2.6.23.15-grsec/net/dccp/dccp.h
40185 +--- linux-2.6.23.15/net/dccp/dccp.h 2007-10-09 21:31:38.000000000 +0100
40186 ++++ linux-2.6.23.15-grsec/net/dccp/dccp.h 2008-02-11 10:37:45.000000000 +0000
40187 +@@ -42,8 +42,8 @@ extern int dccp_debug;
40188 + #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
40189 + #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
40190 + #else
40191 +-#define dccp_pr_debug(format, a...)
40192 +-#define dccp_pr_debug_cat(format, a...)
40193 ++#define dccp_pr_debug(format, a...) do {} while (0)
40194 ++#define dccp_pr_debug_cat(format, a...) do {} while (0)
40195 + #endif
40196 +
40197 + extern struct inet_hashinfo dccp_hashinfo;
40198 +diff -Nurp linux-2.6.23.15/net/ipv4/inet_connection_sock.c linux-2.6.23.15-grsec/net/ipv4/inet_connection_sock.c
40199 +--- linux-2.6.23.15/net/ipv4/inet_connection_sock.c 2007-10-09 21:31:38.000000000 +0100
40200 ++++ linux-2.6.23.15-grsec/net/ipv4/inet_connection_sock.c 2008-02-11 10:37:45.000000000 +0000
40201 +@@ -15,6 +15,7 @@
40202 +
40203 + #include <linux/module.h>
40204 + #include <linux/jhash.h>
40205 ++#include <linux/grsecurity.h>
40206 +
40207 + #include <net/inet_connection_sock.h>
40208 + #include <net/inet_hashtables.h>
40209 +diff -Nurp linux-2.6.23.15/net/ipv4/inet_hashtables.c linux-2.6.23.15-grsec/net/ipv4/inet_hashtables.c
40210 +--- linux-2.6.23.15/net/ipv4/inet_hashtables.c 2007-10-09 21:31:38.000000000 +0100
40211 ++++ linux-2.6.23.15-grsec/net/ipv4/inet_hashtables.c 2008-02-11 10:37:45.000000000 +0000
40212 +@@ -18,11 +18,14 @@
40213 + #include <linux/sched.h>
40214 + #include <linux/slab.h>
40215 + #include <linux/wait.h>
40216 ++#include <linux/grsecurity.h>
40217 +
40218 + #include <net/inet_connection_sock.h>
40219 + #include <net/inet_hashtables.h>
40220 + #include <net/ip.h>
40221 +
40222 ++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
40223 ++
40224 + /*
40225 + * Allocate and initialize a new local port bind bucket.
40226 + * The bindhash mutex for snum's hash chain must be held here.
40227 +@@ -338,6 +341,8 @@ ok:
40228 + }
40229 + spin_unlock(&head->lock);
40230 +
40231 ++ gr_update_task_in_ip_table(current, inet_sk(sk));
40232 ++
40233 + if (tw) {
40234 + inet_twsk_deschedule(tw, death_row);
40235 + inet_twsk_put(tw);
40236 +diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/Kconfig linux-2.6.23.15-grsec/net/ipv4/netfilter/Kconfig
40237 +--- linux-2.6.23.15/net/ipv4/netfilter/Kconfig 2007-10-09 21:31:38.000000000 +0100
40238 ++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/Kconfig 2008-02-11 10:37:45.000000000 +0000
40239 +@@ -130,6 +130,21 @@ config IP_NF_MATCH_ADDRTYPE
40240 + If you want to compile it as a module, say M here and read
40241 + <file:Documentation/modules.txt>. If unsure, say `N'.
40242 +
40243 ++config IP_NF_MATCH_STEALTH
40244 ++ tristate "stealth match support"
40245 ++ depends on IP_NF_IPTABLES
40246 ++ help
40247 ++ Enabling this option will drop all syn packets coming to unserved tcp
40248 ++ ports as well as all packets coming to unserved udp ports. If you
40249 ++ are using your system to route any type of packets (ie. via NAT)
40250 ++ you should put this module at the end of your ruleset, since it will
40251 ++ drop packets that aren't going to ports that are listening on your
40252 ++ machine itself, it doesn't take into account that the packet might be
40253 ++ destined for someone on your internal network if you're using NAT for
40254 ++ instance.
40255 ++
40256 ++ To compile it as a module, choose M here. If unsure, say N.
40257 ++
40258 + # `filter', generic and specific targets
40259 + config IP_NF_FILTER
40260 + tristate "Packet filtering"
40261 +@@ -403,4 +418,3 @@ config IP_NF_ARP_MANGLE
40262 + hardware and network addresses.
40263 +
40264 + endmenu
40265 +-
40266 +diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/Makefile linux-2.6.23.15-grsec/net/ipv4/netfilter/Makefile
40267 +--- linux-2.6.23.15/net/ipv4/netfilter/Makefile 2007-10-09 21:31:38.000000000 +0100
40268 ++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/Makefile 2008-02-11 10:37:45.000000000 +0000
40269 +@@ -49,6 +49,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn
40270 + obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
40271 + obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
40272 + obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
40273 ++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
40274 +
40275 + # targets
40276 + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
40277 +diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/ipt_stealth.c linux-2.6.23.15-grsec/net/ipv4/netfilter/ipt_stealth.c
40278 +--- linux-2.6.23.15/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100
40279 ++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/ipt_stealth.c 2008-02-11 10:37:45.000000000 +0000
40280 +@@ -0,0 +1,114 @@
40281 ++/* Kernel module to add stealth support.
40282 ++ *
40283 ++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net>
40284 ++ *
40285 ++ */
40286 ++
40287 ++#include <linux/kernel.h>
40288 ++#include <linux/module.h>
40289 ++#include <linux/skbuff.h>
40290 ++#include <linux/net.h>
40291 ++#include <linux/sched.h>
40292 ++#include <linux/inet.h>
40293 ++#include <linux/stddef.h>
40294 ++
40295 ++#include <net/ip.h>
40296 ++#include <net/sock.h>
40297 ++#include <net/tcp.h>
40298 ++#include <net/udp.h>
40299 ++#include <net/route.h>
40300 ++#include <net/inet_common.h>
40301 ++
40302 ++#include <linux/netfilter_ipv4/ip_tables.h>
40303 ++
40304 ++MODULE_LICENSE("GPL");
40305 ++
40306 ++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
40307 ++
40308 ++static int
40309 ++match(const struct sk_buff *skb,
40310 ++ const struct net_device *in,
40311 ++ const struct net_device *out,
40312 ++ const struct xt_match *match,
40313 ++ const void *matchinfo,
40314 ++ int offset,
40315 ++ unsigned int protoff,
40316 ++ int *hotdrop)
40317 ++{
40318 ++ struct iphdr *ip = ip_hdr(skb);
40319 ++ struct tcphdr th;
40320 ++ struct udphdr uh;
40321 ++ struct sock *sk = NULL;
40322 ++
40323 ++ if (!ip || offset) return 0;
40324 ++
40325 ++ switch(ip->protocol) {
40326 ++ case IPPROTO_TCP:
40327 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
40328 ++ *hotdrop = 1;
40329 ++ return 0;
40330 ++ }
40331 ++ if (!(th.syn && !th.ack)) return 0;
40332 ++ sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
40333 ++ break;
40334 ++ case IPPROTO_UDP:
40335 ++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
40336 ++ *hotdrop = 1;
40337 ++ return 0;
40338 ++ }
40339 ++ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
40340 ++ break;
40341 ++ default:
40342 ++ return 0;
40343 ++ }
40344 ++
40345 ++ if(!sk) // port is being listened on, match this
40346 ++ return 1;
40347 ++ else {
40348 ++ sock_put(sk);
40349 ++ return 0;
40350 ++ }
40351 ++}
40352 ++
40353 ++/* Called when user tries to insert an entry of this type. */
40354 ++static int
40355 ++checkentry(const char *tablename,
40356 ++ const void *nip,
40357 ++ const struct xt_match *match,
40358 ++ void *matchinfo,
40359 ++ unsigned int hook_mask)
40360 ++{
40361 ++ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
40362 ++
40363 ++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
40364 ++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
40365 ++ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
40366 ++ return 1;
40367 ++
40368 ++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
40369 ++
40370 ++ return 0;
40371 ++}
40372 ++
40373 ++
40374 ++static struct xt_match stealth_match = {
40375 ++ .name = "stealth",
40376 ++ .family = AF_INET,
40377 ++ .match = match,
40378 ++ .checkentry = checkentry,
40379 ++ .destroy = NULL,
40380 ++ .me = THIS_MODULE
40381 ++};
40382 ++
40383 ++static int __init init(void)
40384 ++{
40385 ++ return xt_register_match(&stealth_match);
40386 ++}
40387 ++
40388 ++static void __exit fini(void)
40389 ++{
40390 ++ xt_unregister_match(&stealth_match);
40391 ++}
40392 ++
40393 ++module_init(init);
40394 ++module_exit(fini);
40395 +diff -Nurp linux-2.6.23.15/net/ipv4/tcp.c linux-2.6.23.15-grsec/net/ipv4/tcp.c
40396 +--- linux-2.6.23.15/net/ipv4/tcp.c 2007-10-09 21:31:38.000000000 +0100
40397 ++++ linux-2.6.23.15-grsec/net/ipv4/tcp.c 2008-02-11 10:37:45.000000000 +0000
40398 +@@ -1053,7 +1053,8 @@ int tcp_read_sock(struct sock *sk, read_
40399 + return -ENOTCONN;
40400 + while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) {
40401 + if (offset < skb->len) {
40402 +- size_t used, len;
40403 ++ int used;
40404 ++ size_t len;
40405 +
40406 + len = skb->len - offset;
40407 + /* Stop reading if we hit a patch of urgent data */
40408 +diff -Nurp linux-2.6.23.15/net/ipv4/tcp_ipv4.c linux-2.6.23.15-grsec/net/ipv4/tcp_ipv4.c
40409 +--- linux-2.6.23.15/net/ipv4/tcp_ipv4.c 2007-10-09 21:31:38.000000000 +0100
40410 ++++ linux-2.6.23.15-grsec/net/ipv4/tcp_ipv4.c 2008-02-11 10:37:45.000000000 +0000
40411 +@@ -61,6 +61,7 @@
40412 + #include <linux/jhash.h>
40413 + #include <linux/init.h>
40414 + #include <linux/times.h>
40415 ++#include <linux/grsecurity.h>
40416 +
40417 + #include <net/icmp.h>
40418 + #include <net/inet_hashtables.h>
40419 +diff -Nurp linux-2.6.23.15/net/ipv4/udp.c linux-2.6.23.15-grsec/net/ipv4/udp.c
40420 +--- linux-2.6.23.15/net/ipv4/udp.c 2007-10-09 21:31:38.000000000 +0100
40421 ++++ linux-2.6.23.15-grsec/net/ipv4/udp.c 2008-02-11 10:37:45.000000000 +0000
40422 +@@ -98,12 +98,19 @@
40423 + #include <linux/skbuff.h>
40424 + #include <linux/proc_fs.h>
40425 + #include <linux/seq_file.h>
40426 ++#include <linux/grsecurity.h>
40427 + #include <net/icmp.h>
40428 + #include <net/route.h>
40429 + #include <net/checksum.h>
40430 + #include <net/xfrm.h>
40431 + #include "udp_impl.h"
40432 +
40433 ++extern int gr_search_udp_recvmsg(const struct sock *sk,
40434 ++ const struct sk_buff *skb);
40435 ++extern int gr_search_udp_sendmsg(const struct sock *sk,
40436 ++ const struct sockaddr_in *addr);
40437 ++
40438 ++
40439 + /*
40440 + * Snmp MIB for the UDP layer
40441 + */
40442 +@@ -287,6 +294,13 @@ static struct sock *__udp4_lib_lookup(__
40443 + return result;
40444 + }
40445 +
40446 ++struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
40447 ++ __be32 daddr, __be16 dport, int dif)
40448 ++{
40449 ++ return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
40450 ++}
40451 ++
40452 ++
40453 + static inline struct sock *udp_v4_mcast_next(struct sock *sk,
40454 + __be16 loc_port, __be32 loc_addr,
40455 + __be16 rmt_port, __be32 rmt_addr,
40456 +@@ -572,9 +586,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
40457 + dport = usin->sin_port;
40458 + if (dport == 0)
40459 + return -EINVAL;
40460 ++
40461 ++ if (!gr_search_udp_sendmsg(sk, usin))
40462 ++ return -EPERM;
40463 + } else {
40464 + if (sk->sk_state != TCP_ESTABLISHED)
40465 + return -EDESTADDRREQ;
40466 ++
40467 ++ if (!gr_search_udp_sendmsg(sk, NULL))
40468 ++ return -EPERM;
40469 ++
40470 + daddr = inet->daddr;
40471 + dport = inet->dport;
40472 + /* Open fast path for connected socket.
40473 +@@ -834,6 +855,11 @@ try_again:
40474 + if (!skb)
40475 + goto out;
40476 +
40477 ++ if (!gr_search_udp_recvmsg(sk, skb)) {
40478 ++ err = -EPERM;
40479 ++ goto out_free;
40480 ++ }
40481 ++
40482 + ulen = skb->len - sizeof(struct udphdr);
40483 + copied = len;
40484 + if (copied > ulen)
40485 +diff -Nurp linux-2.6.23.15/net/ipv6/exthdrs.c linux-2.6.23.15-grsec/net/ipv6/exthdrs.c
40486 +--- linux-2.6.23.15/net/ipv6/exthdrs.c 2007-10-09 21:31:38.000000000 +0100
40487 ++++ linux-2.6.23.15-grsec/net/ipv6/exthdrs.c 2008-02-11 10:37:45.000000000 +0000
40488 +@@ -645,7 +645,7 @@ static struct tlvtype_proc tlvprochopopt
40489 + .type = IPV6_TLV_JUMBO,
40490 + .func = ipv6_hop_jumbo,
40491 + },
40492 +- { -1, }
40493 ++ { -1, NULL }
40494 + };
40495 +
40496 + int ipv6_parse_hopopts(struct sk_buff **skbp)
40497 +diff -Nurp linux-2.6.23.15/net/ipv6/raw.c linux-2.6.23.15-grsec/net/ipv6/raw.c
40498 +--- linux-2.6.23.15/net/ipv6/raw.c 2007-10-09 21:31:38.000000000 +0100
40499 ++++ linux-2.6.23.15-grsec/net/ipv6/raw.c 2008-02-11 10:37:45.000000000 +0000
40500 +@@ -577,7 +577,7 @@ out:
40501 + return err;
40502 + }
40503 +
40504 +-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
40505 ++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
40506 + struct flowi *fl, struct rt6_info *rt,
40507 + unsigned int flags)
40508 + {
40509 +diff -Nurp linux-2.6.23.15/net/irda/ircomm/ircomm_tty.c linux-2.6.23.15-grsec/net/irda/ircomm/ircomm_tty.c
40510 +--- linux-2.6.23.15/net/irda/ircomm/ircomm_tty.c 2007-10-09 21:31:38.000000000 +0100
40511 ++++ linux-2.6.23.15-grsec/net/irda/ircomm/ircomm_tty.c 2008-02-11 10:37:45.000000000 +0000
40512 +@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
40513 + IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
40514 +
40515 + line = tty->index;
40516 +- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
40517 ++ if (line >= IRCOMM_TTY_PORTS) {
40518 + return -ENODEV;
40519 + }
40520 +
40521 +diff -Nurp linux-2.6.23.15/net/mac80211/ieee80211.c linux-2.6.23.15-grsec/net/mac80211/ieee80211.c
40522 +--- linux-2.6.23.15/net/mac80211/ieee80211.c 2008-02-11 10:36:03.000000000 +0000
40523 ++++ linux-2.6.23.15-grsec/net/mac80211/ieee80211.c 2008-02-11 10:37:45.000000000 +0000
40524 +@@ -1260,7 +1260,7 @@ __ieee80211_parse_tx_radiotap(
40525 + }
40526 +
40527 +
40528 +-static ieee80211_txrx_result inline
40529 ++static inline ieee80211_txrx_result
40530 + __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
40531 + struct sk_buff *skb,
40532 + struct net_device *dev,
40533 +@@ -1332,7 +1332,7 @@ __ieee80211_tx_prepare(struct ieee80211_
40534 + return res;
40535 + }
40536 +
40537 +-static int inline is_ieee80211_device(struct net_device *dev,
40538 ++static inline int is_ieee80211_device(struct net_device *dev,
40539 + struct net_device *master)
40540 + {
40541 + return (wdev_priv(dev->ieee80211_ptr) ==
40542 +@@ -1341,7 +1341,7 @@ static int inline is_ieee80211_device(st
40543 +
40544 + /* Device in tx->dev has a reference added; use dev_put(tx->dev) when
40545 + * finished with it. */
40546 +-static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
40547 ++static inline int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
40548 + struct sk_buff *skb,
40549 + struct net_device *mdev,
40550 + struct ieee80211_tx_control *control)
40551 +diff -Nurp linux-2.6.23.15/net/mac80211/regdomain.c linux-2.6.23.15-grsec/net/mac80211/regdomain.c
40552 +--- linux-2.6.23.15/net/mac80211/regdomain.c 2007-10-09 21:31:38.000000000 +0100
40553 ++++ linux-2.6.23.15-grsec/net/mac80211/regdomain.c 2008-02-11 10:37:45.000000000 +0000
40554 +@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra
40555 + { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
40556 + { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
40557 + { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
40558 +- { 0 }
40559 ++ { 0, 0, 0, 0 }
40560 + };
40561 +
40562 + static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
40563 + { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
40564 + { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
40565 + { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
40566 +- { 0 }
40567 ++ { 0, 0, 0, 0 }
40568 + };
40569 +
40570 +
40571 +diff -Nurp linux-2.6.23.15/net/sctp/socket.c linux-2.6.23.15-grsec/net/sctp/socket.c
40572 +--- linux-2.6.23.15/net/sctp/socket.c 2007-10-09 21:31:38.000000000 +0100
40573 ++++ linux-2.6.23.15-grsec/net/sctp/socket.c 2008-02-11 10:37:45.000000000 +0000
40574 +@@ -1370,7 +1370,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
40575 + struct sctp_sndrcvinfo *sinfo;
40576 + struct sctp_initmsg *sinit;
40577 + sctp_assoc_t associd = 0;
40578 +- sctp_cmsgs_t cmsgs = { NULL };
40579 ++ sctp_cmsgs_t cmsgs = { NULL, NULL };
40580 + int err;
40581 + sctp_scope_t scope;
40582 + long timeo;
40583 +diff -Nurp linux-2.6.23.15/net/socket.c linux-2.6.23.15-grsec/net/socket.c
40584 +--- linux-2.6.23.15/net/socket.c 2008-02-11 10:36:03.000000000 +0000
40585 ++++ linux-2.6.23.15-grsec/net/socket.c 2008-02-11 10:37:45.000000000 +0000
40586 +@@ -84,6 +84,7 @@
40587 + #include <linux/kmod.h>
40588 + #include <linux/audit.h>
40589 + #include <linux/wireless.h>
40590 ++#include <linux/in.h>
40591 +
40592 + #include <asm/uaccess.h>
40593 + #include <asm/unistd.h>
40594 +@@ -93,6 +94,21 @@
40595 + #include <net/sock.h>
40596 + #include <linux/netfilter.h>
40597 +
40598 ++extern void gr_attach_curr_ip(const struct sock *sk);
40599 ++extern int gr_handle_sock_all(const int family, const int type,
40600 ++ const int protocol);
40601 ++extern int gr_handle_sock_server(const struct sockaddr *sck);
40602 ++extern int gr_handle_sock_server_other(const struct socket *sck);
40603 ++extern int gr_handle_sock_client(const struct sockaddr *sck);
40604 ++extern int gr_search_connect(const struct socket * sock,
40605 ++ const struct sockaddr_in * addr);
40606 ++extern int gr_search_bind(const struct socket * sock,
40607 ++ const struct sockaddr_in * addr);
40608 ++extern int gr_search_listen(const struct socket * sock);
40609 ++extern int gr_search_accept(const struct socket * sock);
40610 ++extern int gr_search_socket(const int domain, const int type,
40611 ++ const int protocol);
40612 ++
40613 + static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
40614 + static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
40615 + unsigned long nr_segs, loff_t pos);
40616 +@@ -292,7 +308,7 @@ static int sockfs_get_sb(struct file_sys
40617 + mnt);
40618 + }
40619 +
40620 +-static struct vfsmount *sock_mnt __read_mostly;
40621 ++struct vfsmount *sock_mnt __read_mostly;
40622 +
40623 + static struct file_system_type sock_fs_type = {
40624 + .name = "sockfs",
40625 +@@ -1199,6 +1215,16 @@ asmlinkage long sys_socket(int family, i
40626 + int retval;
40627 + struct socket *sock;
40628 +
40629 ++ if(!gr_search_socket(family, type, protocol)) {
40630 ++ retval = -EACCES;
40631 ++ goto out;
40632 ++ }
40633 ++
40634 ++ if (gr_handle_sock_all(family, type, protocol)) {
40635 ++ retval = -EACCES;
40636 ++ goto out;
40637 ++ }
40638 ++
40639 + retval = sock_create(family, type, protocol, &sock);
40640 + if (retval < 0)
40641 + goto out;
40642 +@@ -1329,6 +1355,12 @@ asmlinkage long sys_bind(int fd, struct
40643 + if (sock) {
40644 + err = move_addr_to_kernel(umyaddr, addrlen, address);
40645 + if (err >= 0) {
40646 ++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
40647 ++ gr_handle_sock_server((struct sockaddr *)address)) {
40648 ++ err = -EACCES;
40649 ++ goto error;
40650 ++ }
40651 ++
40652 + err = security_socket_bind(sock,
40653 + (struct sockaddr *)address,
40654 + addrlen);
40655 +@@ -1337,6 +1369,7 @@ asmlinkage long sys_bind(int fd, struct
40656 + (struct sockaddr *)
40657 + address, addrlen);
40658 + }
40659 ++error:
40660 + fput_light(sock->file, fput_needed);
40661 + }
40662 + return err;
40663 +@@ -1360,10 +1393,17 @@ asmlinkage long sys_listen(int fd, int b
40664 + if ((unsigned)backlog > sysctl_somaxconn)
40665 + backlog = sysctl_somaxconn;
40666 +
40667 ++ if (gr_handle_sock_server_other(sock) ||
40668 ++ !gr_search_listen(sock)) {
40669 ++ err = -EPERM;
40670 ++ goto error;
40671 ++ }
40672 ++
40673 + err = security_socket_listen(sock, backlog);
40674 + if (!err)
40675 + err = sock->ops->listen(sock, backlog);
40676 +
40677 ++error:
40678 + fput_light(sock->file, fput_needed);
40679 + }
40680 + return err;
40681 +@@ -1400,6 +1440,13 @@ asmlinkage long sys_accept(int fd, struc
40682 + newsock->type = sock->type;
40683 + newsock->ops = sock->ops;
40684 +
40685 ++ if (gr_handle_sock_server_other(sock) ||
40686 ++ !gr_search_accept(sock)) {
40687 ++ err = -EPERM;
40688 ++ sock_release(newsock);
40689 ++ goto out_put;
40690 ++ }
40691 ++
40692 + /*
40693 + * We don't need try_module_get here, as the listening socket (sock)
40694 + * has the protocol module (sock->ops->owner) held.
40695 +@@ -1443,6 +1490,7 @@ asmlinkage long sys_accept(int fd, struc
40696 + err = newfd;
40697 +
40698 + security_socket_post_accept(sock, newsock);
40699 ++ gr_attach_curr_ip(newsock->sk);
40700 +
40701 + out_put:
40702 + fput_light(sock->file, fput_needed);
40703 +@@ -1476,6 +1524,7 @@ asmlinkage long sys_connect(int fd, stru
40704 + {
40705 + struct socket *sock;
40706 + char address[MAX_SOCK_ADDR];
40707 ++ struct sockaddr *sck;
40708 + int err, fput_needed;
40709 +
40710 + sock = sockfd_lookup_light(fd, &err, &fput_needed);
40711 +@@ -1485,6 +1534,13 @@ asmlinkage long sys_connect(int fd, stru
40712 + if (err < 0)
40713 + goto out_put;
40714 +
40715 ++ sck = (struct sockaddr *)address;
40716 ++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
40717 ++ gr_handle_sock_client(sck)) {
40718 ++ err = -EACCES;
40719 ++ goto out_put;
40720 ++ }
40721 ++
40722 + err =
40723 + security_socket_connect(sock, (struct sockaddr *)address, addrlen);
40724 + if (err)
40725 +@@ -1762,6 +1818,7 @@ asmlinkage long sys_shutdown(int fd, int
40726 + err = sock->ops->shutdown(sock, how);
40727 + fput_light(sock->file, fput_needed);
40728 + }
40729 ++
40730 + return err;
40731 + }
40732 +
40733 +diff -Nurp linux-2.6.23.15/net/unix/af_unix.c linux-2.6.23.15-grsec/net/unix/af_unix.c
40734 +--- linux-2.6.23.15/net/unix/af_unix.c 2008-02-11 10:36:03.000000000 +0000
40735 ++++ linux-2.6.23.15-grsec/net/unix/af_unix.c 2008-02-11 10:37:45.000000000 +0000
40736 +@@ -115,6 +115,7 @@
40737 + #include <linux/mount.h>
40738 + #include <net/checksum.h>
40739 + #include <linux/security.h>
40740 ++#include <linux/grsecurity.h>
40741 +
40742 + int sysctl_unix_max_dgram_qlen __read_mostly = 10;
40743 +
40744 +@@ -733,6 +734,11 @@ static struct sock *unix_find_other(stru
40745 + if (err)
40746 + goto put_fail;
40747 +
40748 ++ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
40749 ++ err = -EACCES;
40750 ++ goto put_fail;
40751 ++ }
40752 ++
40753 + err = -ECONNREFUSED;
40754 + if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
40755 + goto put_fail;
40756 +@@ -756,6 +762,13 @@ static struct sock *unix_find_other(stru
40757 + if (u) {
40758 + struct dentry *dentry;
40759 + dentry = unix_sk(u)->dentry;
40760 ++
40761 ++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
40762 ++ err = -EPERM;
40763 ++ sock_put(u);
40764 ++ goto fail;
40765 ++ }
40766 ++
40767 + if (dentry)
40768 + touch_atime(unix_sk(u)->mnt, dentry);
40769 + } else
40770 +@@ -834,9 +847,18 @@ static int unix_bind(struct socket *sock
40771 + */
40772 + mode = S_IFSOCK |
40773 + (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
40774 ++
40775 ++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
40776 ++ err = -EACCES;
40777 ++ goto out_mknod_dput;
40778 ++ }
40779 ++
40780 + err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
40781 + if (err)
40782 + goto out_mknod_dput;
40783 ++
40784 ++ gr_handle_create(dentry, nd.mnt);
40785 ++
40786 + mutex_unlock(&nd.dentry->d_inode->i_mutex);
40787 + dput(nd.dentry);
40788 + nd.dentry = dentry;
40789 +@@ -854,6 +876,10 @@ static int unix_bind(struct socket *sock
40790 + goto out_unlock;
40791 + }
40792 +
40793 ++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
40794 ++ sk->sk_peercred.pid = current->pid;
40795 ++#endif
40796 ++
40797 + list = &unix_socket_table[addr->hash];
40798 + } else {
40799 + list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
40800 +diff -Nurp linux-2.6.23.15/scripts/pnmtologo.c linux-2.6.23.15-grsec/scripts/pnmtologo.c
40801 +--- linux-2.6.23.15/scripts/pnmtologo.c 2007-10-09 21:31:38.000000000 +0100
40802 ++++ linux-2.6.23.15-grsec/scripts/pnmtologo.c 2008-02-11 10:37:45.000000000 +0000
40803 +@@ -237,14 +237,14 @@ static void write_header(void)
40804 + fprintf(out, " * Linux logo %s\n", logoname);
40805 + fputs(" */\n\n", out);
40806 + fputs("#include <linux/linux_logo.h>\n\n", out);
40807 +- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
40808 ++ fprintf(out, "static unsigned char %s_data[] = {\n",
40809 + logoname);
40810 + }
40811 +
40812 + static void write_footer(void)
40813 + {
40814 + fputs("\n};\n\n", out);
40815 +- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
40816 ++ fprintf(out, "struct linux_logo %s = {\n", logoname);
40817 + fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
40818 + fprintf(out, " .width\t= %d,\n", logo_width);
40819 + fprintf(out, " .height\t= %d,\n", logo_height);
40820 +@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
40821 + fputs("\n};\n\n", out);
40822 +
40823 + /* write logo clut */
40824 +- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
40825 ++ fprintf(out, "static unsigned char %s_clut[] = {\n",
40826 + logoname);
40827 + write_hex_cnt = 0;
40828 + for (i = 0; i < logo_clutsize; i++) {
40829 +diff -Nurp linux-2.6.23.15/security/Kconfig linux-2.6.23.15-grsec/security/Kconfig
40830 +--- linux-2.6.23.15/security/Kconfig 2007-10-09 21:31:38.000000000 +0100
40831 ++++ linux-2.6.23.15-grsec/security/Kconfig 2008-02-11 10:37:45.000000000 +0000
40832 +@@ -4,6 +4,429 @@
40833 +
40834 + menu "Security options"
40835 +
40836 ++source grsecurity/Kconfig
40837 ++
40838 ++menu "PaX"
40839 ++
40840 ++config PAX
40841 ++ bool "Enable various PaX features"
40842 ++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
40843 ++ help
40844 ++ This allows you to enable various PaX features. PaX adds
40845 ++ intrusion prevention mechanisms to the kernel that reduce
40846 ++ the risks posed by exploitable memory corruption bugs.
40847 ++
40848 ++menu "PaX Control"
40849 ++ depends on PAX
40850 ++
40851 ++config PAX_SOFTMODE
40852 ++ bool 'Support soft mode'
40853 ++ help
40854 ++ Enabling this option will allow you to run PaX in soft mode, that
40855 ++ is, PaX features will not be enforced by default, only on executables
40856 ++ marked explicitly. You must also enable PT_PAX_FLAGS support as it
40857 ++ is the only way to mark executables for soft mode use.
40858 ++
40859 ++ Soft mode can be activated by using the "pax_softmode=1" kernel command
40860 ++ line option on boot. Furthermore you can control various PaX features
40861 ++ at runtime via the entries in /proc/sys/kernel/pax.
40862 ++
40863 ++config PAX_EI_PAX
40864 ++ bool 'Use legacy ELF header marking'
40865 ++ help
40866 ++ Enabling this option will allow you to control PaX features on
40867 ++ a per executable basis via the 'chpax' utility available at
40868 ++ http://pax.grsecurity.net/. The control flags will be read from
40869 ++ an otherwise reserved part of the ELF header. This marking has
40870 ++ numerous drawbacks (no support for soft-mode, toolchain does not
40871 ++ know about the non-standard use of the ELF header) therefore it
40872 ++ has been deprecated in favour of PT_PAX_FLAGS support.
40873 ++
40874 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
40875 ++ program header then you MUST enable this option otherwise they
40876 ++ will not get any protection.
40877 ++
40878 ++ Note that if you enable PT_PAX_FLAGS marking support as well,
40879 ++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
40880 ++
40881 ++config PAX_PT_PAX_FLAGS
40882 ++ bool 'Use ELF program header marking'
40883 ++ help
40884 ++ Enabling this option will allow you to control PaX features on
40885 ++ a per executable basis via the 'paxctl' utility available at
40886 ++ http://pax.grsecurity.net/. The control flags will be read from
40887 ++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
40888 ++ has the benefits of supporting both soft mode and being fully
40889 ++ integrated into the toolchain (the binutils patch is available
40890 ++ from http://pax.grsecurity.net).
40891 ++
40892 ++ If you have applications not marked by the PT_PAX_FLAGS ELF
40893 ++ program header then you MUST enable the EI_PAX marking support
40894 ++ otherwise they will not get any protection.
40895 ++
40896 ++ Note that if you enable the legacy EI_PAX marking support as well,
40897 ++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
40898 ++
40899 ++choice
40900 ++ prompt 'MAC system integration'
40901 ++ default PAX_HAVE_ACL_FLAGS
40902 ++ help
40903 ++ Mandatory Access Control systems have the option of controlling
40904 ++ PaX flags on a per executable basis, choose the method supported
40905 ++ by your particular system.
40906 ++
40907 ++ - "none": if your MAC system does not interact with PaX,
40908 ++ - "direct": if your MAC system defines pax_set_initial_flags() itself,
40909 ++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
40910 ++
40911 ++ NOTE: this option is for developers/integrators only.
40912 ++
40913 ++ config PAX_NO_ACL_FLAGS
40914 ++ bool 'none'
40915 ++
40916 ++ config PAX_HAVE_ACL_FLAGS
40917 ++ bool 'direct'
40918 ++
40919 ++ config PAX_HOOK_ACL_FLAGS
40920 ++ bool 'hook'
40921 ++endchoice
40922 ++
40923 ++endmenu
40924 ++
40925 ++menu "Non-executable pages"
40926 ++ depends on PAX
40927 ++
40928 ++config PAX_NOEXEC
40929 ++ bool "Enforce non-executable pages"
40930 ++ 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)
40931 ++ help
40932 ++ By design some architectures do not allow for protecting memory
40933 ++ pages against execution or even if they do, Linux does not make
40934 ++ use of this feature. In practice this means that if a page is
40935 ++ readable (such as the stack or heap) it is also executable.
40936 ++
40937 ++ There is a well known exploit technique that makes use of this
40938 ++ fact and a common programming mistake where an attacker can
40939 ++ introduce code of his choice somewhere in the attacked program's
40940 ++ memory (typically the stack or the heap) and then execute it.
40941 ++
40942 ++ If the attacked program was running with different (typically
40943 ++ higher) privileges than that of the attacker, then he can elevate
40944 ++ his own privilege level (e.g. get a root shell, write to files for
40945 ++ which he does not have write access to, etc).
40946 ++
40947 ++ Enabling this option will let you choose from various features
40948 ++ that prevent the injection and execution of 'foreign' code in
40949 ++ a program.
40950 ++
40951 ++ This will also break programs that rely on the old behaviour and
40952 ++ expect that dynamically allocated memory via the malloc() family
40953 ++ of functions is executable (which it is not). Notable examples
40954 ++ are the XFree86 4.x server, the java runtime and wine.
40955 ++
40956 ++config PAX_PAGEEXEC
40957 ++ bool "Paging based non-executable pages"
40958 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
40959 ++ help
40960 ++ This implementation is based on the paging feature of the CPU.
40961 ++ On i386 without hardware non-executable bit support there is a
40962 ++ variable but usually low performance impact, however on Intel's
40963 ++ P4 core based CPUs it is very high so you should not enable this
40964 ++ for kernels meant to be used on such CPUs.
40965 ++
40966 ++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
40967 ++ with hardware non-executable bit support there is no performance
40968 ++ impact, on ppc the impact is negligible.
40969 ++
40970 ++ Note that several architectures require various emulations due to
40971 ++ badly designed userland ABIs, this will cause a performance impact
40972 ++ but will disappear as soon as userland is fixed (e.g., ppc users
40973 ++ can make use of the secure-plt feature found in binutils).
40974 ++
40975 ++config PAX_SEGMEXEC
40976 ++ bool "Segmentation based non-executable pages"
40977 ++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
40978 ++ help
40979 ++ This implementation is based on the segmentation feature of the
40980 ++ CPU and has a very small performance impact, however applications
40981 ++ will be limited to a 1.5 GB address space instead of the normal
40982 ++ 3 GB.
40983 ++
40984 ++config PAX_EMUTRAMP
40985 ++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
40986 ++ default y if PARISC || PPC32
40987 ++ help
40988 ++ There are some programs and libraries that for one reason or
40989 ++ another attempt to execute special small code snippets from
40990 ++ non-executable memory pages. Most notable examples are the
40991 ++ signal handler return code generated by the kernel itself and
40992 ++ the GCC trampolines.
40993 ++
40994 ++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
40995 ++ such programs will no longer work under your kernel.
40996 ++
40997 ++ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
40998 ++ utilities to enable trampoline emulation for the affected programs
40999 ++ yet still have the protection provided by the non-executable pages.
41000 ++
41001 ++ On parisc and ppc you MUST enable this option and EMUSIGRT as
41002 ++ well, otherwise your system will not even boot.
41003 ++
41004 ++ Alternatively you can say N here and use the 'chpax' or 'paxctl'
41005 ++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
41006 ++ for the affected files.
41007 ++
41008 ++ NOTE: enabling this feature *may* open up a loophole in the
41009 ++ protection provided by non-executable pages that an attacker
41010 ++ could abuse. Therefore the best solution is to not have any
41011 ++ files on your system that would require this option. This can
41012 ++ be achieved by not using libc5 (which relies on the kernel
41013 ++ signal handler return code) and not using or rewriting programs
41014 ++ that make use of the nested function implementation of GCC.
41015 ++ Skilled users can just fix GCC itself so that it implements
41016 ++ nested function calls in a way that does not interfere with PaX.
41017 ++
41018 ++config PAX_EMUSIGRT
41019 ++ bool "Automatically emulate sigreturn trampolines"
41020 ++ depends on PAX_EMUTRAMP && (PARISC || PPC32)
41021 ++ default y
41022 ++ help
41023 ++ Enabling this option will have the kernel automatically detect
41024 ++ and emulate signal return trampolines executing on the stack
41025 ++ that would otherwise lead to task termination.
41026 ++
41027 ++ This solution is intended as a temporary one for users with
41028 ++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
41029 ++ Modula-3 runtime, etc) or executables linked to such, basically
41030 ++ everything that does not specify its own SA_RESTORER function in
41031 ++ normal executable memory like glibc 2.1+ does.
41032 ++
41033 ++ On parisc and ppc you MUST enable this option, otherwise your
41034 ++ system will not even boot.
41035 ++
41036 ++ NOTE: this feature cannot be disabled on a per executable basis
41037 ++ and since it *does* open up a loophole in the protection provided
41038 ++ by non-executable pages, the best solution is to not have any
41039 ++ files on your system that would require this option.
41040 ++
41041 ++config PAX_MPROTECT
41042 ++ bool "Restrict mprotect()"
41043 ++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
41044 ++ help
41045 ++ Enabling this option will prevent programs from
41046 ++ - changing the executable status of memory pages that were
41047 ++ not originally created as executable,
41048 ++ - making read-only executable pages writable again,
41049 ++ - creating executable pages from anonymous memory.
41050 ++
41051 ++ You should say Y here to complete the protection provided by
41052 ++ the enforcement of non-executable pages.
41053 ++
41054 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
41055 ++ this feature on a per file basis.
41056 ++
41057 ++config PAX_NOELFRELOCS
41058 ++ bool "Disallow ELF text relocations"
41059 ++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
41060 ++ help
41061 ++ Non-executable pages and mprotect() restrictions are effective
41062 ++ in preventing the introduction of new executable code into an
41063 ++ attacked task's address space. There remain only two venues
41064 ++ for this kind of attack: if the attacker can execute already
41065 ++ existing code in the attacked task then he can either have it
41066 ++ create and mmap() a file containing his code or have it mmap()
41067 ++ an already existing ELF library that does not have position
41068 ++ independent code in it and use mprotect() on it to make it
41069 ++ writable and copy his code there. While protecting against
41070 ++ the former approach is beyond PaX, the latter can be prevented
41071 ++ by having only PIC ELF libraries on one's system (which do not
41072 ++ need to relocate their code). If you are sure this is your case,
41073 ++ then enable this option otherwise be careful as you may not even
41074 ++ be able to boot or log on your system (for example, some PAM
41075 ++ modules are erroneously compiled as non-PIC by default).
41076 ++
41077 ++ NOTE: if you are using dynamic ELF executables (as suggested
41078 ++ when using ASLR) then you must have made sure that you linked
41079 ++ your files using the PIC version of crt1 (the et_dyn.tar.gz package
41080 ++ referenced there has already been updated to support this).
41081 ++
41082 ++config PAX_ETEXECRELOCS
41083 ++ bool "Allow ELF ET_EXEC text relocations"
41084 ++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
41085 ++ default y
41086 ++ help
41087 ++ On some architectures there are incorrectly created applications
41088 ++ that require text relocations and would not work without enabling
41089 ++ this option. If you are an alpha, ia64 or parisc user, you should
41090 ++ enable this option and disable it once you have made sure that
41091 ++ none of your applications need it.
41092 ++
41093 ++config PAX_EMUPLT
41094 ++ bool "Automatically emulate ELF PLT"
41095 ++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41096 ++ default y
41097 ++ help
41098 ++ Enabling this option will have the kernel automatically detect
41099 ++ and emulate the Procedure Linkage Table entries in ELF files.
41100 ++ On some architectures such entries are in writable memory, and
41101 ++ become non-executable leading to task termination. Therefore
41102 ++ it is mandatory that you enable this option on alpha, parisc,
41103 ++ ppc (if secure-plt is not used throughout in userland), sparc
41104 ++ and sparc64, otherwise your system would not even boot.
41105 ++
41106 ++ NOTE: this feature *does* open up a loophole in the protection
41107 ++ provided by the non-executable pages, therefore the proper
41108 ++ solution is to modify the toolchain to produce a PLT that does
41109 ++ not need to be writable.
41110 ++
41111 ++config PAX_DLRESOLVE
41112 ++ bool
41113 ++ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
41114 ++ default y
41115 ++
41116 ++config PAX_SYSCALL
41117 ++ bool
41118 ++ depends on PAX_PAGEEXEC && PPC32
41119 ++ default y
41120 ++
41121 ++config PAX_KERNEXEC
41122 ++ bool "Enforce non-executable kernel pages"
41123 ++ depends on PAX_NOEXEC && X86_32 && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK && !PARAVIRT
41124 ++ help
41125 ++ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
41126 ++ that is, enabling this option will make it harder to inject
41127 ++ and execute 'foreign' code in kernel memory itself.
41128 ++
41129 ++endmenu
41130 ++
41131 ++menu "Address Space Layout Randomization"
41132 ++ depends on PAX
41133 ++
41134 ++config PAX_ASLR
41135 ++ bool "Address Space Layout Randomization"
41136 ++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
41137 ++ help
41138 ++ Many if not most exploit techniques rely on the knowledge of
41139 ++ certain addresses in the attacked program. The following options
41140 ++ will allow the kernel to apply a certain amount of randomization
41141 ++ to specific parts of the program thereby forcing an attacker to
41142 ++ guess them in most cases. Any failed guess will most likely crash
41143 ++ the attacked program which allows the kernel to detect such attempts
41144 ++ and react on them. PaX itself provides no reaction mechanisms,
41145 ++ instead it is strongly encouraged that you make use of Nergal's
41146 ++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
41147 ++ (http://www.grsecurity.net/) built-in crash detection features or
41148 ++ develop one yourself.
41149 ++
41150 ++ By saying Y here you can choose to randomize the following areas:
41151 ++ - top of the task's kernel stack
41152 ++ - top of the task's userland stack
41153 ++ - base address for mmap() requests that do not specify one
41154 ++ (this includes all libraries)
41155 ++ - base address of the main executable
41156 ++
41157 ++ It is strongly recommended to say Y here as address space layout
41158 ++ randomization has negligible impact on performance yet it provides
41159 ++ a very effective protection.
41160 ++
41161 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
41162 ++ this feature on a per file basis.
41163 ++
41164 ++config PAX_RANDKSTACK
41165 ++ bool "Randomize kernel stack base"
41166 ++ depends on PAX_ASLR && X86_TSC && X86_32
41167 ++ help
41168 ++ By saying Y here the kernel will randomize every task's kernel
41169 ++ stack on every system call. This will not only force an attacker
41170 ++ to guess it but also prevent him from making use of possible
41171 ++ leaked information about it.
41172 ++
41173 ++ Since the kernel stack is a rather scarce resource, randomization
41174 ++ may cause unexpected stack overflows, therefore you should very
41175 ++ carefully test your system. Note that once enabled in the kernel
41176 ++ configuration, this feature cannot be disabled on a per file basis.
41177 ++
41178 ++config PAX_RANDUSTACK
41179 ++ bool "Randomize user stack base"
41180 ++ depends on PAX_ASLR
41181 ++ help
41182 ++ By saying Y here the kernel will randomize every task's userland
41183 ++ stack. The randomization is done in two steps where the second
41184 ++ one may apply a big amount of shift to the top of the stack and
41185 ++ cause problems for programs that want to use lots of memory (more
41186 ++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
41187 ++ For this reason the second step can be controlled by 'chpax' or
41188 ++ 'paxctl' on a per file basis.
41189 ++
41190 ++config PAX_RANDMMAP
41191 ++ bool "Randomize mmap() base"
41192 ++ depends on PAX_ASLR
41193 ++ help
41194 ++ By saying Y here the kernel will use a randomized base address for
41195 ++ mmap() requests that do not specify one themselves. As a result
41196 ++ all dynamically loaded libraries will appear at random addresses
41197 ++ and therefore be harder to exploit by a technique where an attacker
41198 ++ attempts to execute library code for his purposes (e.g. spawn a
41199 ++ shell from an exploited program that is running at an elevated
41200 ++ privilege level).
41201 ++
41202 ++ Furthermore, if a program is relinked as a dynamic ELF file, its
41203 ++ base address will be randomized as well, completing the full
41204 ++ randomization of the address space layout. Attacking such programs
41205 ++ becomes a guess game. You can find an example of doing this at
41206 ++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
41207 ++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
41208 ++
41209 ++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
41210 ++ feature on a per file basis.
41211 ++
41212 ++endmenu
41213 ++
41214 ++menu "Miscellaneous hardening features"
41215 ++
41216 ++config PAX_MEMORY_SANITIZE
41217 ++ bool "Sanitize all freed memory"
41218 ++ help
41219 ++ By saying Y here the kernel will erase memory pages as soon as they
41220 ++ are freed. This in turn reduces the lifetime of data stored in the
41221 ++ pages, making it less likely that sensitive information such as
41222 ++ passwords, cryptographic secrets, etc stay in memory for too long.
41223 ++
41224 ++ This is especially useful for programs whose runtime is short, long
41225 ++ lived processes and the kernel itself benefit from this as long as
41226 ++ they operate on whole memory pages and ensure timely freeing of pages
41227 ++ that may hold sensitive information.
41228 ++
41229 ++ The tradeoff is performance impact, on a single CPU system kernel
41230 ++ compilation sees a 3% slowdown, other systems and workloads may vary
41231 ++ and you are advised to test this feature on your expected workload
41232 ++ before deploying it.
41233 ++
41234 ++ Note that this feature does not protect data stored in live pages,
41235 ++ e.g., process memory swapped to disk may stay there for a long time.
41236 ++
41237 ++config PAX_MEMORY_UDEREF
41238 ++ bool "Prevent invalid userland pointer dereference"
41239 ++ depends on X86_32 && !COMPAT_VDSO
41240 ++ help
41241 ++ By saying Y here the kernel will be prevented from dereferencing
41242 ++ userland pointers in contexts where the kernel expects only kernel
41243 ++ pointers. This is both a useful runtime debugging feature and a
41244 ++ security measure that prevents exploiting a class of kernel bugs.
41245 ++
41246 ++ The tradeoff is that some virtualization solutions may experience
41247 ++ a huge slowdown and therefore you should not enable this feature
41248 ++ for kernels meant to run in such environments. Whether a given VM
41249 ++ solution is affected or not is best determined by simply trying it
41250 ++ out, the performance impact will be obvious right on boot as this
41251 ++ mechanism engages from very early on. A good rule of thumb is that
41252 ++ VMs running on CPUs without hardware virtualization support (i.e.,
41253 ++ the majority of IA-32 CPUs) will likely experience the slowdown.
41254 ++
41255 ++endmenu
41256 ++
41257 ++endmenu
41258 ++
41259 + config KEYS
41260 + bool "Enable access key retention support"
41261 + help
41262 +diff -Nurp linux-2.6.23.15/security/commoncap.c linux-2.6.23.15-grsec/security/commoncap.c
41263 +--- linux-2.6.23.15/security/commoncap.c 2007-10-09 21:31:38.000000000 +0100
41264 ++++ linux-2.6.23.15-grsec/security/commoncap.c 2008-02-11 10:37:45.000000000 +0000
41265 +@@ -22,10 +22,11 @@
41266 + #include <linux/ptrace.h>
41267 + #include <linux/xattr.h>
41268 + #include <linux/hugetlb.h>
41269 ++#include <linux/grsecurity.h>
41270 +
41271 + int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
41272 + {
41273 +- NETLINK_CB(skb).eff_cap = current->cap_effective;
41274 ++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
41275 + return 0;
41276 + }
41277 +
41278 +@@ -43,7 +44,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
41279 + int cap_capable (struct task_struct *tsk, int cap)
41280 + {
41281 + /* Derived from include/linux/sched.h:capable. */
41282 +- if (cap_raised(tsk->cap_effective, cap))
41283 ++ if (cap_raised (tsk->cap_effective, cap))
41284 ++ return 0;
41285 ++ return -EPERM;
41286 ++}
41287 ++
41288 ++int cap_capable_nolog (struct task_struct *tsk, int cap)
41289 ++{
41290 ++ /* tsk = current for all callers */
41291 ++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
41292 + return 0;
41293 + return -EPERM;
41294 + }
41295 +@@ -162,8 +171,11 @@ void cap_bprm_apply_creds (struct linux_
41296 + }
41297 + }
41298 +
41299 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
41300 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
41301 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
41302 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
41303 ++
41304 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
41305 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
41306 +
41307 + /* For init, we want to retain the capabilities set
41308 + * in the init_task struct. Thus we skip the usual
41309 +@@ -174,6 +186,8 @@ void cap_bprm_apply_creds (struct linux_
41310 + cap_intersect (new_permitted, bprm->cap_effective);
41311 + }
41312 +
41313 ++ gr_handle_chroot_caps(current);
41314 ++
41315 + /* AUD: Audit candidate if current->cap_effective is set */
41316 +
41317 + current->keep_capabilities = 0;
41318 +@@ -319,12 +333,13 @@ int cap_vm_enough_memory(struct mm_struc
41319 + {
41320 + int cap_sys_admin = 0;
41321 +
41322 +- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
41323 ++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
41324 + cap_sys_admin = 1;
41325 + return __vm_enough_memory(mm, pages, cap_sys_admin);
41326 + }
41327 +
41328 + EXPORT_SYMBOL(cap_capable);
41329 ++EXPORT_SYMBOL(cap_capable_nolog);
41330 + EXPORT_SYMBOL(cap_settime);
41331 + EXPORT_SYMBOL(cap_ptrace);
41332 + EXPORT_SYMBOL(cap_capget);
41333 +diff -Nurp linux-2.6.23.15/security/dummy.c linux-2.6.23.15-grsec/security/dummy.c
41334 +--- linux-2.6.23.15/security/dummy.c 2007-10-09 21:31:38.000000000 +0100
41335 ++++ linux-2.6.23.15-grsec/security/dummy.c 2008-02-11 10:37:45.000000000 +0000
41336 +@@ -28,6 +28,7 @@
41337 + #include <linux/hugetlb.h>
41338 + #include <linux/ptrace.h>
41339 + #include <linux/file.h>
41340 ++#include <linux/grsecurity.h>
41341 +
41342 + static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
41343 + {
41344 +@@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
41345 + }
41346 + }
41347 +
41348 +- current->suid = current->euid = current->fsuid = bprm->e_uid;
41349 +- current->sgid = current->egid = current->fsgid = bprm->e_gid;
41350 ++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
41351 ++ current->suid = current->euid = current->fsuid = bprm->e_uid;
41352 ++
41353 ++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
41354 ++ current->sgid = current->egid = current->fsgid = bprm->e_gid;
41355 +
41356 + dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
41357 + }
41358 +diff -Nurp linux-2.6.23.15/sound/core/oss/pcm_oss.c linux-2.6.23.15-grsec/sound/core/oss/pcm_oss.c
41359 +--- linux-2.6.23.15/sound/core/oss/pcm_oss.c 2007-10-09 21:31:38.000000000 +0100
41360 ++++ linux-2.6.23.15-grsec/sound/core/oss/pcm_oss.c 2008-02-11 10:37:45.000000000 +0000
41361 +@@ -2880,8 +2880,8 @@ static void snd_pcm_oss_proc_done(struct
41362 + }
41363 + }
41364 + #else /* !CONFIG_SND_VERBOSE_PROCFS */
41365 +-#define snd_pcm_oss_proc_init(pcm)
41366 +-#define snd_pcm_oss_proc_done(pcm)
41367 ++#define snd_pcm_oss_proc_init(pcm) do {} while (0)
41368 ++#define snd_pcm_oss_proc_done(pcm) do {} while (0)
41369 + #endif /* CONFIG_SND_VERBOSE_PROCFS */
41370 +
41371 + /*
41372 +diff -Nurp linux-2.6.23.15/sound/core/seq/seq_lock.h linux-2.6.23.15-grsec/sound/core/seq/seq_lock.h
41373 +--- linux-2.6.23.15/sound/core/seq/seq_lock.h 2007-10-09 21:31:38.000000000 +0100
41374 ++++ linux-2.6.23.15-grsec/sound/core/seq/seq_lock.h 2008-02-11 10:37:45.000000000 +0000
41375 +@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
41376 + #else /* SMP || CONFIG_SND_DEBUG */
41377 +
41378 + typedef spinlock_t snd_use_lock_t; /* dummy */
41379 +-#define snd_use_lock_init(lockp) /**/
41380 +-#define snd_use_lock_use(lockp) /**/
41381 +-#define snd_use_lock_free(lockp) /**/
41382 +-#define snd_use_lock_sync(lockp) /**/
41383 ++#define snd_use_lock_init(lockp) do {} while (0)
41384 ++#define snd_use_lock_use(lockp) do {} while (0)
41385 ++#define snd_use_lock_free(lockp) do {} while (0)
41386 ++#define snd_use_lock_sync(lockp) do {} while (0)
41387 +
41388 + #endif /* SMP || CONFIG_SND_DEBUG */
41389 +
41390 +diff -Nurp linux-2.6.23.15/sound/pci/ac97/ac97_patch.c linux-2.6.23.15-grsec/sound/pci/ac97/ac97_patch.c
41391 +--- linux-2.6.23.15/sound/pci/ac97/ac97_patch.c 2007-10-09 21:31:38.000000000 +0100
41392 ++++ linux-2.6.23.15-grsec/sound/pci/ac97/ac97_patch.c 2008-02-11 10:37:45.000000000 +0000
41393 +@@ -1415,7 +1415,7 @@ static const struct snd_ac97_res_table a
41394 + { AC97_VIDEO, 0x9f1f },
41395 + { AC97_AUX, 0x9f1f },
41396 + { AC97_PCM, 0x9f1f },
41397 +- { } /* terminator */
41398 ++ { 0, 0 } /* terminator */
41399 + };
41400 +
41401 + static int patch_ad1819(struct snd_ac97 * ac97)
41402 +@@ -3489,7 +3489,7 @@ static struct snd_ac97_res_table lm4550_
41403 + { AC97_AUX, 0x1f1f },
41404 + { AC97_PCM, 0x1f1f },
41405 + { AC97_REC_GAIN, 0x0f0f },
41406 +- { } /* terminator */
41407 ++ { 0, 0 } /* terminator */
41408 + };
41409 +
41410 + static int patch_lm4550(struct snd_ac97 *ac97)
41411 +diff -Nurp linux-2.6.23.15/sound/pci/ens1370.c linux-2.6.23.15-grsec/sound/pci/ens1370.c
41412 +--- linux-2.6.23.15/sound/pci/ens1370.c 2007-10-09 21:31:38.000000000 +0100
41413 ++++ linux-2.6.23.15-grsec/sound/pci/ens1370.c 2008-02-11 10:37:45.000000000 +0000
41414 +@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci
41415 + { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
41416 + { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
41417 + #endif
41418 +- { 0, }
41419 ++ { 0, 0, 0, 0, 0, 0, 0 }
41420 + };
41421 +
41422 + MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
41423 +diff -Nurp linux-2.6.23.15/sound/pci/intel8x0.c linux-2.6.23.15-grsec/sound/pci/intel8x0.c
41424 +--- linux-2.6.23.15/sound/pci/intel8x0.c 2007-10-09 21:31:38.000000000 +0100
41425 ++++ linux-2.6.23.15-grsec/sound/pci/intel8x0.c 2008-02-11 10:37:45.000000000 +0000
41426 +@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0
41427 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
41428 + { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
41429 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
41430 +- { 0, }
41431 ++ { 0, 0, 0, 0, 0, 0, 0 }
41432 + };
41433 +
41434 + MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
41435 +@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
41436 + .type = AC97_TUNE_HP_ONLY
41437 + },
41438 + #endif
41439 +- { } /* terminator */
41440 ++ { 0, 0, 0, 0, NULL, 0 } /* terminator */
41441 + };
41442 +
41443 + static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
41444 +diff -Nurp linux-2.6.23.15/sound/pci/intel8x0m.c linux-2.6.23.15-grsec/sound/pci/intel8x0m.c
41445 +--- linux-2.6.23.15/sound/pci/intel8x0m.c 2007-10-09 21:31:38.000000000 +0100
41446 ++++ linux-2.6.23.15-grsec/sound/pci/intel8x0m.c 2008-02-11 10:37:45.000000000 +0000
41447 +@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0
41448 + { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
41449 + { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
41450 + #endif
41451 +- { 0, }
41452 ++ { 0, 0, 0, 0, 0, 0, 0 }
41453 + };
41454 +
41455 + MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
41456 +@@ -1261,7 +1261,7 @@ static struct shortname_table {
41457 + { 0x5455, "ALi M5455" },
41458 + { 0x746d, "AMD AMD8111" },
41459 + #endif
41460 +- { 0 },
41461 ++ { 0, NULL },
41462 + };
41463 +
41464 + static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
41465
41466 Added: hardened-sources/2.6/tags/2.6.23-5/4455_grsec-2.1.10-mute-warnings.patch
41467 ===================================================================
41468 --- hardened-sources/2.6/tags/2.6.23-5/4455_grsec-2.1.10-mute-warnings.patch (rev 0)
41469 +++ hardened-sources/2.6/tags/2.6.23-5/4455_grsec-2.1.10-mute-warnings.patch 2008-04-30 11:40:48 UTC (rev 95)
41470 @@ -0,0 +1,23 @@
41471 +From: Alexander Gabert <gaberta@××××××××.de>
41472 +
41473 +This patch removes the warnings introduced by grsec patch 2.1.9 and later.
41474 +It removes the -W options added by the patch and restores the original
41475 +warning flags of vanilla kernel versions.
41476 +
41477 +Acked-by: Christian Heim <phreak@g.o>
41478 +
41479 +---
41480 + Makefile | 5 +++--
41481 + 1 file changed, 3 insertions(+), 2 deletions(-)
41482 +
41483 +--- a/Makefile
41484 ++++ b/Makefile
41485 +@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
41486 +
41487 + CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
41488 +
41489 +-CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
41490 ++CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
41491 + -fno-strict-aliasing -fno-common \
41492 + -Werror-implicit-function-declaration
41493 + AFLAGS := -D__ASSEMBLY__
41494
41495 Added: hardened-sources/2.6/tags/2.6.23-5/4460_grsec-2.1.10-pax_curr_ip-fixes.patch
41496 ===================================================================
41497 --- hardened-sources/2.6/tags/2.6.23-5/4460_grsec-2.1.10-pax_curr_ip-fixes.patch (rev 0)
41498 +++ hardened-sources/2.6/tags/2.6.23-5/4460_grsec-2.1.10-pax_curr_ip-fixes.patch 2008-04-30 11:40:48 UTC (rev 95)
41499 @@ -0,0 +1,46 @@
41500 +---
41501 + arch/i386/mm/fault.c | 2 ++
41502 + fs/exec.c | 2 ++
41503 + security/Kconfig | 2 +-
41504 + 3 files changed, 5 insertions(+), 1 deletion(-)
41505 +
41506 +--- a/arch/i386/mm/fault.c
41507 ++++ b/arch/i386/mm/fault.c
41508 +@@ -722,10 +722,12 @@ no_context:
41509 + #else
41510 + else if (init_mm.start_code <= address && address < init_mm.end_code)
41511 + #endif
41512 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
41513 + if (tsk->signal->curr_ip)
41514 + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
41515 + NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
41516 + else
41517 ++#endif
41518 + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
41519 + tsk->comm, tsk->pid, tsk->uid, tsk->euid);
41520 + #endif
41521 +--- a/fs/exec.c
41522 ++++ b/fs/exec.c
41523 +@@ -1733,9 +1733,11 @@ void pax_report_fault(struct pt_regs *re
41524 + }
41525 + up_read(&mm->mmap_sem);
41526 + }
41527 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
41528 + if (tsk->signal->curr_ip)
41529 + 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);
41530 + else
41531 ++#endif
41532 + printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
41533 + printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
41534 + "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
41535 +--- a/security/Kconfig
41536 ++++ b/security/Kconfig
41537 +@@ -10,7 +10,7 @@ menu "PaX"
41538 +
41539 + config PAX
41540 + bool "Enable various PaX features"
41541 +- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
41542 ++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
41543 + help
41544 + This allows you to enable various PaX features. PaX adds
41545 + intrusion prevention mechanisms to the kernel that reduce
41546
41547 Added: hardened-sources/2.6/tags/2.6.23-5/4465_grsec-kconfig-gentoo.patch
41548 ===================================================================
41549 --- hardened-sources/2.6/tags/2.6.23-5/4465_grsec-kconfig-gentoo.patch (rev 0)
41550 +++ hardened-sources/2.6/tags/2.6.23-5/4465_grsec-kconfig-gentoo.patch 2008-04-30 11:40:48 UTC (rev 95)
41551 @@ -0,0 +1,86 @@
41552 +From: Ned Ludd <solar@g.o>
41553 +Description: Add a Hardened Gentoo target to the list of security levels.
41554 +
41555 +This makes it much easier for beginners to just select what _we_ consider a sane
41556 +default.
41557 +
41558 +--- a/grsecurity/Kconfig
41559 ++++ b/grsecurity/Kconfig
41560 +@@ -182,6 +182,77 @@ config GRKERNSEC_HIGH
41561 + - Kernel symbol hiding
41562 + - Destroy unused shared memory
41563 + - Prevention of memory exhaustion-based exploits
41564 ++
41565 ++config GRKERNSEC_HARDENED
41566 ++ bool "Hardened [Gentoo]"
41567 ++ select GRKERNSEC_AUDIT_CHDIR
41568 ++ select GRKERNSEC_AUDIT_IPC
41569 ++ select GRKERNSEC_AUDIT_MOUNT
41570 ++ select GRKERNSEC_BRUTE
41571 ++ select GRKERNSEC_CHROOT
41572 ++ select GRKERNSEC_CHROOT_CAPS
41573 ++ select GRKERNSEC_CHROOT_CHDIR
41574 ++ select GRKERNSEC_CHROOT_CHMOD
41575 ++ select GRKERNSEC_CHROOT_DOUBLE
41576 ++ select GRKERNSEC_CHROOT_EXECLOG
41577 ++ select GRKERNSEC_CHROOT_FCHDIR
41578 ++ select GRKERNSEC_CHROOT_FINDTASK
41579 ++ select GRKERNSEC_CHROOT_MKNOD
41580 ++ select GRKERNSEC_CHROOT_MOUNT
41581 ++ select GRKERNSEC_CHROOT_NICE
41582 ++ select GRKERNSEC_CHROOT_PIVOT
41583 ++ select GRKERNSEC_CHROOT_SHMAT
41584 ++ select GRKERNSEC_CHROOT_SYSCTL
41585 ++ select GRKERNSEC_CHROOT_UNIX
41586 ++ select GRKERNSEC_DMESG
41587 ++ select GRKERNSEC_EXECLOG
41588 ++ select GRKERNSEC_EXECVE
41589 ++ select GRKERNSEC_FIFO
41590 ++ select GRKERNSEC_FORKFAIL
41591 ++ select GRKERNSEC_HIDESYM
41592 ++ select GRKERNSEC_KMEM if (!MODULES)
41593 ++ select GRKERNSEC_LINK
41594 ++ select GRKERNSEC_MODSTOP if (MODULES)
41595 ++ select GRKERNSEC_PROC
41596 ++ select GRKERNSEC_PROC_ADD
41597 ++ select GRKERNSEC_PROC_IPADDR
41598 ++ select GRKERNSEC_PROC_MEMMAP if (X86 || X86_64)
41599 ++ select GRKERNSEC_PROC_USERGROUP
41600 ++ select GRKERNSEC_RANDNET
41601 ++ select GRKERNSEC_RESLOG
41602 ++ select GRKERNSEC_SHM if (SYSVIPC)
41603 ++ select GRKERNSEC_SIGNAL
41604 ++ select GRKERNSEC_SYSCTL
41605 ++ select GRKERNSEC_TIME
41606 ++ select GRKERNSEC_TPE
41607 ++ select GRKERNSEC_TPE_ALL
41608 ++ select GRKERNSEC_TPE_INVERT
41609 ++ select PAX
41610 ++ select PAX_ASLR
41611 ++ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
41612 ++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
41613 ++ select PAX_EMUSIGRT if (PARISC)
41614 ++ select PAX_EMUTRAMP if (PARISC)
41615 ++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
41616 ++ select PAX_HAVE_ACL_FLAGS
41617 ++ select PAX_KERNEXEC if (!X86_64 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
41618 ++ select PAX_MPROTECT
41619 ++ select PAX_NOEXEC
41620 ++ select PAX_PAGEEXEC if (!X86)
41621 ++ select PAX_PT_PAX_FLAGS
41622 ++ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
41623 ++ select PAX_RANDMMAP
41624 ++ select PAX_RANDUSTACK
41625 ++ select PAX_SEGMEXEC if (X86 && !X86_64)
41626 ++ help
41627 ++ If you say Y here, many of the features of grsecurity and PaX will
41628 ++ be enabled, which will protect you against many kinds of attacks
41629 ++ against your system. The heightened security comes at a cost
41630 ++ of an increased chance of incompatibilities with rare software
41631 ++ on your machine. Since this security level enables PaX, you should
41632 ++ view <http://pax.grsecurity.net> and read about the PaX
41633 ++ project.
41634 ++
41635 + config GRKERNSEC_CUSTOM
41636 + bool "Custom"
41637 + help
41638
41639 Added: hardened-sources/2.6/tags/2.6.23-5/4470_selinux-avc_audit-log-curr_ip.patch
41640 ===================================================================
41641 --- hardened-sources/2.6/tags/2.6.23-5/4470_selinux-avc_audit-log-curr_ip.patch (rev 0)
41642 +++ hardened-sources/2.6/tags/2.6.23-5/4470_selinux-avc_audit-log-curr_ip.patch 2008-04-30 11:40:48 UTC (rev 95)
41643 @@ -0,0 +1,26 @@
41644 +
41645 +Provides support for a new field ipaddr within the SELinux
41646 +AVC audit log, relying in task_struct->curr_ip (ipv4 only)
41647 +provided by grSecurity patch to be applied before.
41648 +
41649 +Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org>
41650 +---
41651 +
41652 + security/selinux/avc.c | 6 ++++++
41653 + 1 file changed, 6 insertions(+)
41654 +
41655 +--- a/security/selinux/avc.c
41656 ++++ b/security/selinux/avc.c
41657 +@@ -202,6 +202,12 @@ static void avc_dump_query(struct audit_
41658 + char *scontext;
41659 + u32 scontext_len;
41660 +
41661 ++/* CONFIG_PROC_IPADDR if task-signal-curr_ip patch from lorenzo@×××.org is present */
41662 ++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
41663 ++ if (current->signal->curr_ip)
41664 ++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip));
41665 ++#endif /* CONFIG_GRKERNSEC_PROC_IPADDR */
41666 ++
41667 + rc = security_sid_to_context(ssid, &scontext, &scontext_len);
41668 + if (rc)
41669 + audit_log_format(ab, "ssid=%d", ssid);
41670
41671 Added: hardened-sources/2.6/tags/2.6.23-5/4475_compat_vdso-defconfig.patch
41672 ===================================================================
41673 --- hardened-sources/2.6/tags/2.6.23-5/4475_compat_vdso-defconfig.patch (rev 0)
41674 +++ hardened-sources/2.6/tags/2.6.23-5/4475_compat_vdso-defconfig.patch 2008-04-30 11:40:48 UTC (rev 95)
41675 @@ -0,0 +1,20 @@
41676 +Disable CONFIG_COMPAT_VDSO in the default config for i386 arch. It is
41677 +inappropriate for any Gentoo user to activate this option. Moreover, it
41678 +prevents users from selecting a number of important PaX options -
41679 +notably PAX_PAGEEXEC and PAX_SEGMEXEC. Under these circumstances, it is
41680 +impossible for the user to enforce non-executable pages. Unfortunately,
41681 +this is far from obvious to first-time users.
41682 +
41683 +Signed-off-by: Kerin Millar <kerframil@×××××.com>
41684 +
41685 +--- linux-2.6.23.15.orig/arch/i386/defconfig 2007-10-09 21:31:38.000000000 +0100
41686 ++++ linux-2.6.23.15/arch/i386/defconfig 2008-02-10 23:18:19.000000000 +0000
41687 +@@ -231,7 +231,7 @@
41688 + # CONFIG_RELOCATABLE is not set
41689 + CONFIG_PHYSICAL_ALIGN=0x100000
41690 + # CONFIG_HOTPLUG_CPU is not set
41691 +-CONFIG_COMPAT_VDSO=y
41692 ++CONFIG_COMPAT_VDSO=n
41693 + CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
41694 +
41695 + #
41696
41697 Added: hardened-sources/2.6/tags/2.6.23-5/4480_x86_64-bogus-acpi-symbols-defconfig.patch
41698 ===================================================================
41699 --- hardened-sources/2.6/tags/2.6.23-5/4480_x86_64-bogus-acpi-symbols-defconfig.patch (rev 0)
41700 +++ hardened-sources/2.6/tags/2.6.23-5/4480_x86_64-bogus-acpi-symbols-defconfig.patch 2008-04-30 11:40:48 UTC (rev 95)
41701 @@ -0,0 +1,17 @@
41702 +Remove references to non-existent symbols ACPI_SLEEP_PROC_FS and
41703 +ACPI_SLEEP_PROC_SLEEP in arch/x86_64/defconfig, thus preventing two
41704 +potential warnings to that effect from appearing.
41705 +
41706 +Signed-off-by: Kerin Millar <kerframil@×××××.com>
41707 +
41708 +--- linux-2.6.23.15.orig/arch/x86_64/defconfig 2007-10-09 21:31:38.000000000 +0100
41709 ++++ linux-2.6.23.15/arch/x86_64/defconfig 2008-02-11 00:11:59.000000000 +0000
41710 +@@ -207,8 +207,6 @@
41711 + #
41712 + CONFIG_ACPI=y
41713 + CONFIG_ACPI_SLEEP=y
41714 +-CONFIG_ACPI_SLEEP_PROC_FS=y
41715 +-CONFIG_ACPI_SLEEP_PROC_SLEEP=y
41716 + CONFIG_ACPI_PROCFS=y
41717 + CONFIG_ACPI_AC=y
41718 + CONFIG_ACPI_BATTERY=y
41719
41720 --
41721 gentoo-commits@l.g.o mailing list