1 |
Author: phreak |
2 |
Date: 2008-04-30 11:41:42 +0000 (Wed, 30 Apr 2008) |
3 |
New Revision: 96 |
4 |
|
5 |
Added: |
6 |
hardened-sources/2.6/tags/2.6.23-6/ |
7 |
hardened-sources/2.6/tags/2.6.23-6/1015_2.6.23.Q_scsi-sd-handle-bad-lba-in-sense-information.patch |
8 |
hardened-sources/2.6/tags/2.6.23-6/1016_2.6.23.Q_nfs-fix-a-potential-file-corruption-issue-when-writing.patch |
9 |
hardened-sources/2.6/tags/2.6.23-6/1017_2.6.23.Q_netfilter-nf_conntrack_tcp-conntrack-reopening-fix.patch |
10 |
hardened-sources/2.6/tags/2.6.23-6/1018_2.6.23.Q_hrtimer-check-relative-timeouts-for-overflow.patch |
11 |
hardened-sources/2.6/tags/2.6.23-6/1019_2.6.23.Q_genirq-do-not-leave-interupts-enabled-on-free_irq.patch |
12 |
hardened-sources/2.6/tags/2.6.23-6/1020_2.6.23.Q_disable-g5-nap-mode-during-smu-commands-on-u3.patch |
13 |
hardened-sources/2.6/tags/2.6.23-6/1021_2.6.23.Q_be-more-robust-about-bad-arguments-in-get_user_pages.patch |
14 |
hardened-sources/2.6/tags/2.6.23-6/1022_2.6.23.Q_x86_64-cpa-fix-cache-attribute-inconsistency-bug.patch |
15 |
hardened-sources/2.6/tags/2.6.23-6/4405_alpha-sysctl-uac-for-hardened-extras.patch |
16 |
hardened-sources/2.6/tags/2.6.23-6/4450_grsec-2.1.11-2.6.23.15-20080210.patch |
17 |
hardened-sources/2.6/tags/2.6.23-6/4455_grsec-2.1.10-mute-warnings.patch |
18 |
hardened-sources/2.6/tags/2.6.23-6/4460_grsec-2.1.10-pax_curr_ip-fixes.patch |
19 |
hardened-sources/2.6/tags/2.6.23-6/4465_grsec-kconfig-gentoo.patch |
20 |
hardened-sources/2.6/tags/2.6.23-6/4470_selinux-avc_audit-log-curr_ip.patch |
21 |
hardened-sources/2.6/tags/2.6.23-6/4475_disable-compat_vdso.patch |
22 |
hardened-sources/2.6/tags/2.6.23-6/4480_acct_stack_growth-null-deref.patch |
23 |
hardened-sources/2.6/tags/2.6.23-6/4485_pax-vma-mirroring-fixes.patch |
24 |
hardened-sources/2.6/tags/2.6.23-6/4490_vesafb-pmi-kernexec-fix.patch |
25 |
hardened-sources/2.6/tags/2.6.23-6/4495_pax-hook-build-error.patch |
26 |
hardened-sources/2.6/tags/2.6.23-6/4500_deselect-kernexec-on-unsupported-arches.patch |
27 |
Log: |
28 |
Importing patchset for 2.6.23-6 (from hardened-patches-2.6.23-6.extras.tar.bz2). |
29 |
|
30 |
Added: hardened-sources/2.6/tags/2.6.23-6/1015_2.6.23.Q_scsi-sd-handle-bad-lba-in-sense-information.patch |
31 |
=================================================================== |
32 |
--- hardened-sources/2.6/tags/2.6.23-6/1015_2.6.23.Q_scsi-sd-handle-bad-lba-in-sense-information.patch (rev 0) |
33 |
+++ hardened-sources/2.6/tags/2.6.23-6/1015_2.6.23.Q_scsi-sd-handle-bad-lba-in-sense-information.patch 2008-04-30 11:41:42 UTC (rev 96) |
34 |
@@ -0,0 +1,76 @@ |
35 |
+From 366c246de9cec909c5eba4f784c92d1e75b4dc38 Mon Sep 17 00:00:00 2001 |
36 |
+From: James Bottomley <James.Bottomley@×××××××××××××××××.com> |
37 |
+Date: Sat, 2 Feb 2008 16:06:23 -0600 |
38 |
+Subject: SCSI: sd: handle bad lba in sense information |
39 |
+ |
40 |
+From: James Bottomley <James.Bottomley@×××××××××××××××××.com> |
41 |
+ |
42 |
+patch 366c246de9cec909c5eba4f784c92d1e75b4dc38 in mainline. |
43 |
+ |
44 |
+Some devices report medium error locations incorrectly. Add guards to |
45 |
+make sure the reported bad lba is actually in the request that caused |
46 |
+it. Additionally remove the large case statment for sector sizes and |
47 |
+replace it with the proper u64 divisions. |
48 |
+ |
49 |
+Tested-by: Mike Snitzer <snitzer@×××××.com> |
50 |
+Cc: Stable Tree <stable@××××××.org> |
51 |
+Cc: Tony Battersby <tonyb@×××××××××××.com> |
52 |
+Signed-off-by: James Bottomley <James.Bottomley@×××××××××××××××××.com> |
53 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
54 |
+ |
55 |
+--- |
56 |
+ drivers/scsi/sd.c | 34 ++++++++++++++++------------------ |
57 |
+ 1 file changed, 16 insertions(+), 18 deletions(-) |
58 |
+ |
59 |
+--- a/drivers/scsi/sd.c |
60 |
++++ b/drivers/scsi/sd.c |
61 |
+@@ -901,6 +901,7 @@ static void sd_rw_intr(struct scsi_cmnd |
62 |
+ unsigned int xfer_size = SCpnt->request_bufflen; |
63 |
+ unsigned int good_bytes = result ? 0 : xfer_size; |
64 |
+ u64 start_lba = SCpnt->request->sector; |
65 |
++ u64 end_lba = SCpnt->request->sector + (xfer_size / 512); |
66 |
+ u64 bad_lba; |
67 |
+ struct scsi_sense_hdr sshdr; |
68 |
+ int sense_valid = 0; |
69 |
+@@ -939,26 +940,23 @@ static void sd_rw_intr(struct scsi_cmnd |
70 |
+ goto out; |
71 |
+ if (xfer_size <= SCpnt->device->sector_size) |
72 |
+ goto out; |
73 |
+- switch (SCpnt->device->sector_size) { |
74 |
+- case 256: |
75 |
++ if (SCpnt->device->sector_size < 512) { |
76 |
++ /* only legitimate sector_size here is 256 */ |
77 |
+ start_lba <<= 1; |
78 |
+- break; |
79 |
+- case 512: |
80 |
+- break; |
81 |
+- case 1024: |
82 |
+- start_lba >>= 1; |
83 |
+- break; |
84 |
+- case 2048: |
85 |
+- start_lba >>= 2; |
86 |
+- break; |
87 |
+- case 4096: |
88 |
+- start_lba >>= 3; |
89 |
+- break; |
90 |
+- default: |
91 |
+- /* Print something here with limiting frequency. */ |
92 |
+- goto out; |
93 |
+- break; |
94 |
++ end_lba <<= 1; |
95 |
++ } else { |
96 |
++ /* be careful ... don't want any overflows */ |
97 |
++ u64 factor = SCpnt->device->sector_size / 512; |
98 |
++ do_div(start_lba, factor); |
99 |
++ do_div(end_lba, factor); |
100 |
+ } |
101 |
++ |
102 |
++ if (bad_lba < start_lba || bad_lba >= end_lba) |
103 |
++ /* the bad lba was reported incorrectly, we have |
104 |
++ * no idea where the error is |
105 |
++ */ |
106 |
++ goto out; |
107 |
++ |
108 |
+ /* This computation should always be done in terms of |
109 |
+ * the resolution of the device's medium. |
110 |
+ */ |
111 |
|
112 |
Added: hardened-sources/2.6/tags/2.6.23-6/1016_2.6.23.Q_nfs-fix-a-potential-file-corruption-issue-when-writing.patch |
113 |
=================================================================== |
114 |
--- hardened-sources/2.6/tags/2.6.23-6/1016_2.6.23.Q_nfs-fix-a-potential-file-corruption-issue-when-writing.patch (rev 0) |
115 |
+++ hardened-sources/2.6/tags/2.6.23-6/1016_2.6.23.Q_nfs-fix-a-potential-file-corruption-issue-when-writing.patch 2008-04-30 11:41:42 UTC (rev 96) |
116 |
@@ -0,0 +1,80 @@ |
117 |
+From stable-bounces@××××××××××××.org Fri Feb 8 11:13:23 2008 |
118 |
+From: Trond Myklebust <Trond.Myklebust@××××××.com> |
119 |
+Date: Fri, 08 Feb 2008 14:12:11 -0500 |
120 |
+Subject: NFS: Fix a potential file corruption issue when writing |
121 |
+To: stable@××××××.org |
122 |
+Message-ID: <1202497931.8383.9.camel@×××××××××××××××××.org> |
123 |
+ |
124 |
+From: Trond Myklebust <Trond.Myklebust@××××××.com> |
125 |
+ |
126 |
+patch 5d47a35600270e7115061cb1320ee60ae9bcb6b8 in mainline. |
127 |
+ |
128 |
+If the inode is flagged as having an invalid mapping, then we can't rely on |
129 |
+the PageUptodate() flag. Ensure that we don't use the "anti-fragmentation" |
130 |
+write optimisation in nfs_updatepage(), since that will cause NFS to write |
131 |
+out areas of the page that are no longer guaranteed to be up to date. |
132 |
+ |
133 |
+A potential corruption could occur in the following scenario: |
134 |
+ |
135 |
+client 1 client 2 |
136 |
+=============== =============== |
137 |
+ fd=open("f",O_CREAT|O_WRONLY,0644); |
138 |
+ write(fd,"fubar\n",6); // cache last page |
139 |
+ close(fd); |
140 |
+fd=open("f",O_WRONLY|O_APPEND); |
141 |
+write(fd,"foo\n",4); |
142 |
+close(fd); |
143 |
+ |
144 |
+ fd=open("f",O_WRONLY|O_APPEND); |
145 |
+ write(fd,"bar\n",4); |
146 |
+ close(fd); |
147 |
+----- |
148 |
+The bug may lead to the file "f" reading 'fubar\n\0\0\0\nbar\n' because |
149 |
+client 2 does not update the cached page after re-opening the file for |
150 |
+write. Instead it keeps it marked as PageUptodate() until someone calls |
151 |
+invaldate_inode_pages2() (typically by calling read()). |
152 |
+ |
153 |
+Signed-off-by: Trond Myklebust <Trond.Myklebust@××××××.com> |
154 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
155 |
+ |
156 |
+--- |
157 |
+ fs/nfs/write.c | 20 +++++++++++++++++--- |
158 |
+ 1 file changed, 17 insertions(+), 3 deletions(-) |
159 |
+ |
160 |
+--- a/fs/nfs/write.c |
161 |
++++ b/fs/nfs/write.c |
162 |
+@@ -717,6 +717,17 @@ int nfs_flush_incompatible(struct file * |
163 |
+ } |
164 |
+ |
165 |
+ /* |
166 |
++ * If the page cache is marked as unsafe or invalid, then we can't rely on |
167 |
++ * the PageUptodate() flag. In this case, we will need to turn off |
168 |
++ * write optimisations that depend on the page contents being correct. |
169 |
++ */ |
170 |
++static int nfs_write_pageuptodate(struct page *page, struct inode *inode) |
171 |
++{ |
172 |
++ return PageUptodate(page) && |
173 |
++ !(NFS_I(inode)->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_DATA)); |
174 |
++} |
175 |
++ |
176 |
++/* |
177 |
+ * Update and possibly write a cached page of an NFS file. |
178 |
+ * |
179 |
+ * XXX: Keep an eye on generic_file_read to make sure it doesn't do bad |
180 |
+@@ -737,10 +748,13 @@ int nfs_updatepage(struct file *file, st |
181 |
+ (long long)(page_offset(page) +offset)); |
182 |
+ |
183 |
+ /* If we're not using byte range locks, and we know the page |
184 |
+- * is entirely in cache, it may be more efficient to avoid |
185 |
+- * fragmenting write requests. |
186 |
++ * is up to date, it may be more efficient to extend the write |
187 |
++ * to cover the entire page in order to avoid fragmentation |
188 |
++ * inefficiencies. |
189 |
+ */ |
190 |
+- if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
191 |
++ if (nfs_write_pageuptodate(page, inode) && |
192 |
++ inode->i_flock == NULL && |
193 |
++ !(file->f_mode & O_SYNC)) { |
194 |
+ count = max(count + offset, nfs_page_length(page)); |
195 |
+ offset = 0; |
196 |
+ } |
197 |
|
198 |
Added: hardened-sources/2.6/tags/2.6.23-6/1017_2.6.23.Q_netfilter-nf_conntrack_tcp-conntrack-reopening-fix.patch |
199 |
=================================================================== |
200 |
--- hardened-sources/2.6/tags/2.6.23-6/1017_2.6.23.Q_netfilter-nf_conntrack_tcp-conntrack-reopening-fix.patch (rev 0) |
201 |
+++ hardened-sources/2.6/tags/2.6.23-6/1017_2.6.23.Q_netfilter-nf_conntrack_tcp-conntrack-reopening-fix.patch 2008-04-30 11:41:42 UTC (rev 96) |
202 |
@@ -0,0 +1,111 @@ |
203 |
+From stable-bounces@××××××××××××.org Tue Feb 19 07:43:54 2008 |
204 |
+From: Jozsef Kadlecsik <kadlec@××××××××××××××.hu> |
205 |
+From: Patrick McHardy <kaber@×××××.net> |
206 |
+Date: Tue, 19 Feb 2008 16:24:01 +0100 |
207 |
+Subject: NETFILTER: nf_conntrack_tcp: conntrack reopening fix |
208 |
+To: stable@××××××.org |
209 |
+Cc: Netfilter Development Mailinglist <netfilter-devel@×××××××××××.org>, "David S. Miller" <davem@×××××××××.net> |
210 |
+Message-ID: <47BAF491.6060601@×××××.net> |
211 |
+ |
212 |
+From: Jozsef Kadlecsik <kadlec@××××××××××××××.hu> |
213 |
+ |
214 |
+[NETFILTER]: nf_conntrack_tcp: conntrack reopening fix |
215 |
+ |
216 |
+[Upstream commits b2155e7f + d0c1fd7a] |
217 |
+ |
218 |
+TCP connection tracking in netfilter did not handle TCP reopening |
219 |
+properly: active close was taken into account for one side only and |
220 |
+not for any side, which is fixed now. The patch includes more comments |
221 |
+to explain the logic how the different cases are handled. |
222 |
+The bug was discovered by Jeff Chua. |
223 |
+ |
224 |
+Signed-off-by: Jozsef Kadlecsik <kadlec@××××××××××××××.hu> |
225 |
+Signed-off-by: Patrick McHardy <kaber@×××××.net> |
226 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
227 |
+ |
228 |
+--- |
229 |
+ net/netfilter/nf_conntrack_proto_tcp.c | 35 +++++++++++++++++++++++++-------- |
230 |
+ 1 file changed, 27 insertions(+), 8 deletions(-) |
231 |
+ |
232 |
+--- a/net/netfilter/nf_conntrack_proto_tcp.c |
233 |
++++ b/net/netfilter/nf_conntrack_proto_tcp.c |
234 |
+@@ -135,7 +135,7 @@ enum tcp_bit_set { |
235 |
+ * CLOSE_WAIT: ACK seen (after FIN) |
236 |
+ * LAST_ACK: FIN seen (after FIN) |
237 |
+ * TIME_WAIT: last ACK seen |
238 |
+- * CLOSE: closed connection |
239 |
++ * CLOSE: closed connection (RST) |
240 |
+ * |
241 |
+ * LISTEN state is not used. |
242 |
+ * |
243 |
+@@ -834,8 +834,21 @@ static int tcp_packet(struct nf_conn *co |
244 |
+ case TCP_CONNTRACK_SYN_SENT: |
245 |
+ if (old_state < TCP_CONNTRACK_TIME_WAIT) |
246 |
+ break; |
247 |
+- if ((conntrack->proto.tcp.seen[!dir].flags & |
248 |
+- IP_CT_TCP_FLAG_CLOSE_INIT) |
249 |
++ /* RFC 1122: "When a connection is closed actively, |
250 |
++ * it MUST linger in TIME-WAIT state for a time 2xMSL |
251 |
++ * (Maximum Segment Lifetime). However, it MAY accept |
252 |
++ * a new SYN from the remote TCP to reopen the connection |
253 |
++ * directly from TIME-WAIT state, if..." |
254 |
++ * We ignore the conditions because we are in the |
255 |
++ * TIME-WAIT state anyway. |
256 |
++ * |
257 |
++ * Handle aborted connections: we and the server |
258 |
++ * think there is an existing connection but the client |
259 |
++ * aborts it and starts a new one. |
260 |
++ */ |
261 |
++ if (((conntrack->proto.tcp.seen[dir].flags |
262 |
++ | conntrack->proto.tcp.seen[!dir].flags) |
263 |
++ & IP_CT_TCP_FLAG_CLOSE_INIT) |
264 |
+ || (conntrack->proto.tcp.last_dir == dir |
265 |
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) { |
266 |
+ /* Attempt to reopen a closed/aborted connection. |
267 |
+@@ -848,18 +861,25 @@ static int tcp_packet(struct nf_conn *co |
268 |
+ } |
269 |
+ /* Fall through */ |
270 |
+ case TCP_CONNTRACK_IGNORE: |
271 |
+- /* Ignored packets: |
272 |
++ /* Ignored packets: |
273 |
++ * |
274 |
++ * Our connection entry may be out of sync, so ignore |
275 |
++ * packets which may signal the real connection between |
276 |
++ * the client and the server. |
277 |
+ * |
278 |
+ * a) SYN in ORIGINAL |
279 |
+ * b) SYN/ACK in REPLY |
280 |
+ * c) ACK in reply direction after initial SYN in original. |
281 |
++ * |
282 |
++ * If the ignored packet is invalid, the receiver will send |
283 |
++ * a RST we'll catch below. |
284 |
+ */ |
285 |
+ if (index == TCP_SYNACK_SET |
286 |
+ && conntrack->proto.tcp.last_index == TCP_SYN_SET |
287 |
+ && conntrack->proto.tcp.last_dir != dir |
288 |
+ && ntohl(th->ack_seq) == |
289 |
+ conntrack->proto.tcp.last_end) { |
290 |
+- /* This SYN/ACK acknowledges a SYN that we earlier |
291 |
++ /* b) This SYN/ACK acknowledges a SYN that we earlier |
292 |
+ * ignored as invalid. This means that the client and |
293 |
+ * the server are both in sync, while the firewall is |
294 |
+ * not. We kill this session and block the SYN/ACK so |
295 |
+@@ -884,7 +904,7 @@ static int tcp_packet(struct nf_conn *co |
296 |
+ write_unlock_bh(&tcp_lock); |
297 |
+ if (LOG_INVALID(IPPROTO_TCP)) |
298 |
+ nf_log_packet(pf, 0, skb, NULL, NULL, NULL, |
299 |
+- "nf_ct_tcp: invalid packed ignored "); |
300 |
++ "nf_ct_tcp: invalid packet ignored "); |
301 |
+ return NF_ACCEPT; |
302 |
+ case TCP_CONNTRACK_MAX: |
303 |
+ /* Invalid packet */ |
304 |
+@@ -938,8 +958,7 @@ static int tcp_packet(struct nf_conn *co |
305 |
+ |
306 |
+ conntrack->proto.tcp.state = new_state; |
307 |
+ if (old_state != new_state |
308 |
+- && (new_state == TCP_CONNTRACK_FIN_WAIT |
309 |
+- || new_state == TCP_CONNTRACK_CLOSE)) |
310 |
++ && new_state == TCP_CONNTRACK_FIN_WAIT) |
311 |
+ conntrack->proto.tcp.seen[dir].flags |= IP_CT_TCP_FLAG_CLOSE_INIT; |
312 |
+ timeout = conntrack->proto.tcp.retrans >= nf_ct_tcp_max_retrans |
313 |
+ && *tcp_timeouts[new_state] > nf_ct_tcp_timeout_max_retrans |
314 |
|
315 |
Added: hardened-sources/2.6/tags/2.6.23-6/1018_2.6.23.Q_hrtimer-check-relative-timeouts-for-overflow.patch |
316 |
=================================================================== |
317 |
--- hardened-sources/2.6/tags/2.6.23-6/1018_2.6.23.Q_hrtimer-check-relative-timeouts-for-overflow.patch (rev 0) |
318 |
+++ hardened-sources/2.6/tags/2.6.23-6/1018_2.6.23.Q_hrtimer-check-relative-timeouts-for-overflow.patch 2008-04-30 11:41:42 UTC (rev 96) |
319 |
@@ -0,0 +1,154 @@ |
320 |
+From stable-bounces@××××××××××××.org Tue Feb 19 16:03:26 2008 |
321 |
+From: Thomas Gleixner <tglx@××××××××××.de> |
322 |
+Date: Wed, 20 Feb 2008 01:03:00 +0100 (CET) |
323 |
+Subject: hrtimer: check relative timeouts for overflow |
324 |
+To: Stable Team <stable@××××××.org> |
325 |
+Message-ID: <alpine.LFD.1.00.0802200100000.7583@×××××××××××××××××××××.de> |
326 |
+ |
327 |
+From: Thomas Gleixner <tglx@××××××××××.de> |
328 |
+ |
329 |
+commit: 5a7780e725d1bb4c3094fcc12f1c5c5faea1e988 |
330 |
+ |
331 |
+Various user space callers ask for relative timeouts. While we fixed |
332 |
+that overflow issue in hrtimer_start(), the sites which convert |
333 |
+relative user space values to absolute timeouts themself were uncovered. |
334 |
+ |
335 |
+Instead of putting overflow checks into each place add a function |
336 |
+which does the sanity checking and convert all affected callers to use |
337 |
+it. |
338 |
+ |
339 |
+Thanks to Frans Pop, who reported the problem and tested the fixes. |
340 |
+ |
341 |
+Signed-off-by: Thomas Gleixner <tglx@××××××××××.de> |
342 |
+Acked-by: Ingo Molnar <mingo@××××.hu> |
343 |
+Tested-by: Frans Pop <elendil@××××××.nl> |
344 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
345 |
+ |
346 |
+ |
347 |
+--- |
348 |
+ include/linux/ktime.h | 2 ++ |
349 |
+ kernel/futex.c | 2 +- |
350 |
+ kernel/futex_compat.c | 2 +- |
351 |
+ kernel/hrtimer.c | 38 +++++++++++++++++++++----------------- |
352 |
+ kernel/posix-timers.c | 8 +++++--- |
353 |
+ 5 files changed, 30 insertions(+), 22 deletions(-) |
354 |
+ |
355 |
+--- a/include/linux/ktime.h |
356 |
++++ b/include/linux/ktime.h |
357 |
+@@ -289,6 +289,8 @@ static inline ktime_t ktime_add_us(const |
358 |
+ return ktime_add_ns(kt, usec * 1000); |
359 |
+ } |
360 |
+ |
361 |
++extern ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs); |
362 |
++ |
363 |
+ /* |
364 |
+ * The resolution of the clocks. The resolution value is returned in |
365 |
+ * the clock_getres() system call to give application programmers an |
366 |
+--- a/kernel/futex.c |
367 |
++++ b/kernel/futex.c |
368 |
+@@ -2063,7 +2063,7 @@ asmlinkage long sys_futex(u32 __user *ua |
369 |
+ |
370 |
+ t = timespec_to_ktime(ts); |
371 |
+ if (cmd == FUTEX_WAIT) |
372 |
+- t = ktime_add(ktime_get(), t); |
373 |
++ t = ktime_add_safe(ktime_get(), t); |
374 |
+ tp = &t; |
375 |
+ } |
376 |
+ /* |
377 |
+--- a/kernel/futex_compat.c |
378 |
++++ b/kernel/futex_compat.c |
379 |
+@@ -175,7 +175,7 @@ asmlinkage long compat_sys_futex(u32 __u |
380 |
+ |
381 |
+ t = timespec_to_ktime(ts); |
382 |
+ if (cmd == FUTEX_WAIT) |
383 |
+- t = ktime_add(ktime_get(), t); |
384 |
++ t = ktime_add_safe(ktime_get(), t); |
385 |
+ tp = &t; |
386 |
+ } |
387 |
+ if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE) |
388 |
+--- a/kernel/hrtimer.c |
389 |
++++ b/kernel/hrtimer.c |
390 |
+@@ -301,6 +301,24 @@ unsigned long ktime_divns(const ktime_t |
391 |
+ } |
392 |
+ #endif /* BITS_PER_LONG >= 64 */ |
393 |
+ |
394 |
++/* |
395 |
++ * Add two ktime values and do a safety check for overflow: |
396 |
++ */ |
397 |
++ |
398 |
++ktime_t ktime_add_safe(const ktime_t lhs, const ktime_t rhs) |
399 |
++{ |
400 |
++ ktime_t res = ktime_add(lhs, rhs); |
401 |
++ |
402 |
++ /* |
403 |
++ * We use KTIME_SEC_MAX here, the maximum timeout which we can |
404 |
++ * return to user space in a timespec: |
405 |
++ */ |
406 |
++ if (res.tv64 < 0 || res.tv64 < lhs.tv64 || res.tv64 < rhs.tv64) |
407 |
++ res = ktime_set(KTIME_SEC_MAX, 0); |
408 |
++ |
409 |
++ return res; |
410 |
++} |
411 |
++ |
412 |
+ /* High resolution timer related functions */ |
413 |
+ #ifdef CONFIG_HIGH_RES_TIMERS |
414 |
+ |
415 |
+@@ -658,13 +676,7 @@ hrtimer_forward(struct hrtimer *timer, k |
416 |
+ */ |
417 |
+ orun++; |
418 |
+ } |
419 |
+- timer->expires = ktime_add(timer->expires, interval); |
420 |
+- /* |
421 |
+- * Make sure, that the result did not wrap with a very large |
422 |
+- * interval. |
423 |
+- */ |
424 |
+- if (timer->expires.tv64 < 0) |
425 |
+- timer->expires = ktime_set(KTIME_SEC_MAX, 0); |
426 |
++ timer->expires = ktime_add_safe(timer->expires, interval); |
427 |
+ |
428 |
+ return orun; |
429 |
+ } |
430 |
+@@ -815,7 +827,7 @@ hrtimer_start(struct hrtimer *timer, kti |
431 |
+ new_base = switch_hrtimer_base(timer, base); |
432 |
+ |
433 |
+ if (mode == HRTIMER_MODE_REL) { |
434 |
+- tim = ktime_add(tim, new_base->get_time()); |
435 |
++ tim = ktime_add_safe(tim, new_base->get_time()); |
436 |
+ /* |
437 |
+ * CONFIG_TIME_LOW_RES is a temporary way for architectures |
438 |
+ * to signal that they simply return xtime in |
439 |
+@@ -824,16 +836,8 @@ hrtimer_start(struct hrtimer *timer, kti |
440 |
+ * timeouts. This will go away with the GTOD framework. |
441 |
+ */ |
442 |
+ #ifdef CONFIG_TIME_LOW_RES |
443 |
+- tim = ktime_add(tim, base->resolution); |
444 |
++ tim = ktime_add_safe(tim, base->resolution); |
445 |
+ #endif |
446 |
+- /* |
447 |
+- * Careful here: User space might have asked for a |
448 |
+- * very long sleep, so the add above might result in a |
449 |
+- * negative number, which enqueues the timer in front |
450 |
+- * of the queue. |
451 |
+- */ |
452 |
+- if (tim.tv64 < 0) |
453 |
+- tim.tv64 = KTIME_MAX; |
454 |
+ } |
455 |
+ timer->expires = tim; |
456 |
+ |
457 |
+--- a/kernel/posix-timers.c |
458 |
++++ b/kernel/posix-timers.c |
459 |
+@@ -765,9 +765,11 @@ common_timer_set(struct k_itimer *timr, |
460 |
+ /* SIGEV_NONE timers are not queued ! See common_timer_get */ |
461 |
+ if (((timr->it_sigev_notify & ~SIGEV_THREAD_ID) == SIGEV_NONE)) { |
462 |
+ /* Setup correct expiry time for relative timers */ |
463 |
+- if (mode == HRTIMER_MODE_REL) |
464 |
+- timer->expires = ktime_add(timer->expires, |
465 |
+- timer->base->get_time()); |
466 |
++ if (mode == HRTIMER_MODE_REL) { |
467 |
++ timer->expires = |
468 |
++ ktime_add_safe(timer->expires, |
469 |
++ timer->base->get_time()); |
470 |
++ } |
471 |
+ return 0; |
472 |
+ } |
473 |
+ |
474 |
|
475 |
Added: hardened-sources/2.6/tags/2.6.23-6/1019_2.6.23.Q_genirq-do-not-leave-interupts-enabled-on-free_irq.patch |
476 |
=================================================================== |
477 |
--- hardened-sources/2.6/tags/2.6.23-6/1019_2.6.23.Q_genirq-do-not-leave-interupts-enabled-on-free_irq.patch (rev 0) |
478 |
+++ hardened-sources/2.6/tags/2.6.23-6/1019_2.6.23.Q_genirq-do-not-leave-interupts-enabled-on-free_irq.patch 2008-04-30 11:41:42 UTC (rev 96) |
479 |
@@ -0,0 +1,76 @@ |
480 |
+From stable-bounces@××××××××××××.org Tue Feb 19 15:29:28 2008 |
481 |
+From: Thomas Gleixner <tglx@××××××××××.de> |
482 |
+Date: Wed, 20 Feb 2008 00:29:02 +0100 (CET) |
483 |
+Subject: genirq: do not leave interupts enabled on free_irq |
484 |
+To: Stable Team <stable@××××××.org> |
485 |
+Message-ID: <alpine.LFD.1.00.0802200026480.7583@×××××××××××××××××××××.de> |
486 |
+ |
487 |
+From: Thomas Gleixner <tglx@××××××××××.de> |
488 |
+ |
489 |
+commit 89d694b9dbe769ca1004e01db0ca43964806a611 |
490 |
+ |
491 |
+The default_disable() function was changed in commit: |
492 |
+ |
493 |
+ 76d2160147f43f982dfe881404cfde9fd0a9da21 |
494 |
+ genirq: do not mask interrupts by default |
495 |
+ |
496 |
+It removed the mask function in favour of the default delayed |
497 |
+interrupt disabling. Unfortunately this also broke the shutdown in |
498 |
+free_irq() when the last handler is removed from the interrupt for |
499 |
+those architectures which rely on the default implementations. Now we |
500 |
+can end up with a enabled interrupt line after the last handler was |
501 |
+removed, which can result in spurious interrupts. |
502 |
+ |
503 |
+Fix this by adding a default_shutdown function, which is only |
504 |
+installed, when the irqchip implementation does provide neither a |
505 |
+shutdown nor a disable function. |
506 |
+ |
507 |
+ |
508 |
+Pointed-out-by: Michael Hennerich <Michael.Hennerich@××××××.com> |
509 |
+Signed-off-by: Thomas Gleixner <tglx@××××××××××.de> |
510 |
+Acked-by: Ingo Molnar <mingo@××××.hu> |
511 |
+Tested-by: Michael Hennerich <Michael.Hennerich@××××××.com> |
512 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
513 |
+ |
514 |
+ |
515 |
+--- |
516 |
+ kernel/irq/chip.c | 20 +++++++++++++++++++- |
517 |
+ 1 file changed, 19 insertions(+), 1 deletion(-) |
518 |
+ |
519 |
+--- a/kernel/irq/chip.c |
520 |
++++ b/kernel/irq/chip.c |
521 |
+@@ -246,6 +246,17 @@ static unsigned int default_startup(unsi |
522 |
+ } |
523 |
+ |
524 |
+ /* |
525 |
++ * default shutdown function |
526 |
++ */ |
527 |
++static void default_shutdown(unsigned int irq) |
528 |
++{ |
529 |
++ struct irq_desc *desc = irq_desc + irq; |
530 |
++ |
531 |
++ desc->chip->mask(irq); |
532 |
++ desc->status |= IRQ_MASKED; |
533 |
++} |
534 |
++ |
535 |
++/* |
536 |
+ * Fixup enable/disable function pointers |
537 |
+ */ |
538 |
+ void irq_chip_set_defaults(struct irq_chip *chip) |
539 |
+@@ -256,8 +267,15 @@ void irq_chip_set_defaults(struct irq_ch |
540 |
+ chip->disable = default_disable; |
541 |
+ if (!chip->startup) |
542 |
+ chip->startup = default_startup; |
543 |
++ /* |
544 |
++ * We use chip->disable, when the user provided its own. When |
545 |
++ * we have default_disable set for chip->disable, then we need |
546 |
++ * to use default_shutdown, otherwise the irq line is not |
547 |
++ * disabled on free_irq(): |
548 |
++ */ |
549 |
+ if (!chip->shutdown) |
550 |
+- chip->shutdown = chip->disable; |
551 |
++ chip->shutdown = chip->disable != default_disable ? |
552 |
++ chip->disable : default_shutdown; |
553 |
+ if (!chip->name) |
554 |
+ chip->name = chip->typename; |
555 |
+ if (!chip->end) |
556 |
|
557 |
Added: hardened-sources/2.6/tags/2.6.23-6/1020_2.6.23.Q_disable-g5-nap-mode-during-smu-commands-on-u3.patch |
558 |
=================================================================== |
559 |
--- hardened-sources/2.6/tags/2.6.23-6/1020_2.6.23.Q_disable-g5-nap-mode-during-smu-commands-on-u3.patch (rev 0) |
560 |
+++ hardened-sources/2.6/tags/2.6.23-6/1020_2.6.23.Q_disable-g5-nap-mode-during-smu-commands-on-u3.patch 2008-04-30 11:41:42 UTC (rev 96) |
561 |
@@ -0,0 +1,144 @@ |
562 |
+From 592a607bbc053bc6f614a0e619326009f4b3829e Mon Sep 17 00:00:00 2001 |
563 |
+From: Benjamin Herrenschmidt <benh@×××××××××××××××.org> |
564 |
+Date: Thu, 7 Feb 2008 14:29:43 +1100 |
565 |
+Subject: [PATCH] [POWERPC] Disable G5 NAP mode during SMU commands on U3 |
566 |
+ |
567 |
+From: Benjamin Herrenschmidt <benh@×××××××××××××××.org> |
568 |
+ |
569 |
+patch 592a607bbc053bc6f614a0e619326009f4b3829e in mainline. |
570 |
+ |
571 |
+It appears that with the U3 northbridge, if the processor is in NAP |
572 |
+mode the whole time while waiting for an SMU command to complete, |
573 |
+then the SMU will fail. It could be related to the weird backward |
574 |
+mechanism the SMU uses to get to system memory via i2c to the |
575 |
+northbridge that doesn't operate properly when the said bridge is |
576 |
+in napping along with the CPU. That is on U3 at least, U4 doesn't |
577 |
+seem to be affected. |
578 |
+ |
579 |
+This didn't show before NO_HZ as the timer wakeup was enough to make |
580 |
+it work it seems, but that is no longer the case. |
581 |
+ |
582 |
+This fixes it by disabling NAP mode on those machines while |
583 |
+an SMU command is in flight. |
584 |
+ |
585 |
+Signed-off-by: Benjamin Herrenschmidt <benh@×××××××××××××××.org> |
586 |
+Signed-off-by: Paul Mackerras <paulus@×××××.org> |
587 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
588 |
+ |
589 |
+--- |
590 |
+ arch/powerpc/platforms/powermac/feature.c | 11 ++++++++++- |
591 |
+ drivers/macintosh/smu.c | 25 ++++++++++++++++++++++++- |
592 |
+ include/asm-powerpc/pmac_feature.h | 8 ++++++++ |
593 |
+ 3 files changed, 42 insertions(+), 2 deletions(-) |
594 |
+ |
595 |
+--- a/arch/powerpc/platforms/powermac/feature.c |
596 |
++++ b/arch/powerpc/platforms/powermac/feature.c |
597 |
+@@ -2565,6 +2565,8 @@ static void __init probe_uninorth(void) |
598 |
+ |
599 |
+ /* Locate core99 Uni-N */ |
600 |
+ uninorth_node = of_find_node_by_name(NULL, "uni-n"); |
601 |
++ uninorth_maj = 1; |
602 |
++ |
603 |
+ /* Locate G5 u3 */ |
604 |
+ if (uninorth_node == NULL) { |
605 |
+ uninorth_node = of_find_node_by_name(NULL, "u3"); |
606 |
+@@ -2575,8 +2577,10 @@ static void __init probe_uninorth(void) |
607 |
+ uninorth_node = of_find_node_by_name(NULL, "u4"); |
608 |
+ uninorth_maj = 4; |
609 |
+ } |
610 |
+- if (uninorth_node == NULL) |
611 |
++ if (uninorth_node == NULL) { |
612 |
++ uninorth_maj = 0; |
613 |
+ return; |
614 |
++ } |
615 |
+ |
616 |
+ addrp = of_get_property(uninorth_node, "reg", NULL); |
617 |
+ if (addrp == NULL) |
618 |
+@@ -3029,3 +3033,8 @@ void pmac_resume_agp_for_card(struct pci |
619 |
+ pmac_agp_resume(pmac_agp_bridge); |
620 |
+ } |
621 |
+ EXPORT_SYMBOL(pmac_resume_agp_for_card); |
622 |
++ |
623 |
++int pmac_get_uninorth_variant(void) |
624 |
++{ |
625 |
++ return uninorth_maj; |
626 |
++} |
627 |
+--- a/drivers/macintosh/smu.c |
628 |
++++ b/drivers/macintosh/smu.c |
629 |
+@@ -85,6 +85,7 @@ struct smu_device { |
630 |
+ u32 cmd_buf_abs; /* command buffer absolute */ |
631 |
+ struct list_head cmd_list; |
632 |
+ struct smu_cmd *cmd_cur; /* pending command */ |
633 |
++ int broken_nap; |
634 |
+ struct list_head cmd_i2c_list; |
635 |
+ struct smu_i2c_cmd *cmd_i2c_cur; /* pending i2c command */ |
636 |
+ struct timer_list i2c_timer; |
637 |
+@@ -135,6 +136,19 @@ static void smu_start_cmd(void) |
638 |
+ fend = faddr + smu->cmd_buf->length + 2; |
639 |
+ flush_inval_dcache_range(faddr, fend); |
640 |
+ |
641 |
++ |
642 |
++ /* We also disable NAP mode for the duration of the command |
643 |
++ * on U3 based machines. |
644 |
++ * This is slightly racy as it can be written back to 1 by a sysctl |
645 |
++ * but that never happens in practice. There seem to be an issue with |
646 |
++ * U3 based machines such as the iMac G5 where napping for the |
647 |
++ * whole duration of the command prevents the SMU from fetching it |
648 |
++ * from memory. This might be related to the strange i2c based |
649 |
++ * mechanism the SMU uses to access memory. |
650 |
++ */ |
651 |
++ if (smu->broken_nap) |
652 |
++ powersave_nap = 0; |
653 |
++ |
654 |
+ /* This isn't exactly a DMA mapping here, I suspect |
655 |
+ * the SMU is actually communicating with us via i2c to the |
656 |
+ * northbridge or the CPU to access RAM. |
657 |
+@@ -211,6 +225,10 @@ static irqreturn_t smu_db_intr(int irq, |
658 |
+ misc = cmd->misc; |
659 |
+ mb(); |
660 |
+ cmd->status = rc; |
661 |
++ |
662 |
++ /* Re-enable NAP mode */ |
663 |
++ if (smu->broken_nap) |
664 |
++ powersave_nap = 1; |
665 |
+ bail: |
666 |
+ /* Start next command if any */ |
667 |
+ smu_start_cmd(); |
668 |
+@@ -461,7 +479,7 @@ int __init smu_init (void) |
669 |
+ if (np == NULL) |
670 |
+ return -ENODEV; |
671 |
+ |
672 |
+- printk(KERN_INFO "SMU driver %s %s\n", VERSION, AUTHOR); |
673 |
++ printk(KERN_INFO "SMU: Driver %s %s\n", VERSION, AUTHOR); |
674 |
+ |
675 |
+ if (smu_cmdbuf_abs == 0) { |
676 |
+ printk(KERN_ERR "SMU: Command buffer not allocated !\n"); |
677 |
+@@ -533,6 +551,11 @@ int __init smu_init (void) |
678 |
+ goto fail; |
679 |
+ } |
680 |
+ |
681 |
++ /* U3 has an issue with NAP mode when issuing SMU commands */ |
682 |
++ smu->broken_nap = pmac_get_uninorth_variant() < 4; |
683 |
++ if (smu->broken_nap) |
684 |
++ printk(KERN_INFO "SMU: using NAP mode workaround\n"); |
685 |
++ |
686 |
+ sys_ctrler = SYS_CTRLER_SMU; |
687 |
+ return 0; |
688 |
+ |
689 |
+--- a/include/asm-powerpc/pmac_feature.h |
690 |
++++ b/include/asm-powerpc/pmac_feature.h |
691 |
+@@ -392,6 +392,14 @@ extern u32 __iomem *uninorth_base; |
692 |
+ #define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) |
693 |
+ #define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) |
694 |
+ |
695 |
++/* Uninorth variant: |
696 |
++ * |
697 |
++ * 0 = not uninorth |
698 |
++ * 1 = U1.x or U2.x |
699 |
++ * 3 = U3 |
700 |
++ * 4 = U4 |
701 |
++ */ |
702 |
++extern int pmac_get_uninorth_variant(void); |
703 |
+ |
704 |
+ #endif /* __ASM_POWERPC_PMAC_FEATURE_H */ |
705 |
+ #endif /* __KERNEL__ */ |
706 |
|
707 |
Added: hardened-sources/2.6/tags/2.6.23-6/1021_2.6.23.Q_be-more-robust-about-bad-arguments-in-get_user_pages.patch |
708 |
=================================================================== |
709 |
--- hardened-sources/2.6/tags/2.6.23-6/1021_2.6.23.Q_be-more-robust-about-bad-arguments-in-get_user_pages.patch (rev 0) |
710 |
+++ hardened-sources/2.6/tags/2.6.23-6/1021_2.6.23.Q_be-more-robust-about-bad-arguments-in-get_user_pages.patch 2008-04-30 11:41:42 UTC (rev 96) |
711 |
@@ -0,0 +1,47 @@ |
712 |
+From 900cf086fd2fbad07f72f4575449e0d0958f860f Mon Sep 17 00:00:00 2001 |
713 |
+From: Jonathan Corbet <corbet@×××.net> |
714 |
+Date: Mon, 11 Feb 2008 16:17:33 -0700 |
715 |
+Subject: [PATCH] Be more robust about bad arguments in get_user_pages() |
716 |
+ |
717 |
+From: Jonathan Corbet <corbet@×××.net> |
718 |
+ |
719 |
+patch 900cf086fd2fbad07f72f4575449e0d0958f860f in mainline. |
720 |
+ |
721 |
+So I spent a while pounding my head against my monitor trying to figure |
722 |
+out the vmsplice() vulnerability - how could a failure to check for |
723 |
+*read* access turn into a root exploit? It turns out that it's a buffer |
724 |
+overflow problem which is made easy by the way get_user_pages() is |
725 |
+coded. |
726 |
+ |
727 |
+In particular, "len" is a signed int, and it is only checked at the |
728 |
+*end* of a do {} while() loop. So, if it is passed in as zero, the loop |
729 |
+will execute once and decrement len to -1. At that point, the loop will |
730 |
+proceed until the next invalid address is found; in the process, it will |
731 |
+likely overflow the pages array passed in to get_user_pages(). |
732 |
+ |
733 |
+I think that, if get_user_pages() has been asked to grab zero pages, |
734 |
+that's what it should do. Thus this patch; it is, among other things, |
735 |
+enough to block the (already fixed) root exploit and any others which |
736 |
+might be lurking in similar code. I also think that the number of pages |
737 |
+should be unsigned, but changing the prototype of this function probably |
738 |
+requires some more careful review. |
739 |
+ |
740 |
+Signed-off-by: Jonathan Corbet <corbet@×××.net> |
741 |
+Signed-off-by: Linus Torvalds <torvalds@××××××××××××××××.org> |
742 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
743 |
+ |
744 |
+--- |
745 |
+ mm/memory.c | 2 ++ |
746 |
+ 1 file changed, 2 insertions(+) |
747 |
+ |
748 |
+--- a/mm/memory.c |
749 |
++++ b/mm/memory.c |
750 |
+@@ -981,6 +981,8 @@ int get_user_pages(struct task_struct *t |
751 |
+ int i; |
752 |
+ unsigned int vm_flags; |
753 |
+ |
754 |
++ if (len <= 0) |
755 |
++ return 0; |
756 |
+ /* |
757 |
+ * Require read or write permissions. |
758 |
+ * If 'force' is set, we only require the "MAY" flags. |
759 |
|
760 |
Added: hardened-sources/2.6/tags/2.6.23-6/1022_2.6.23.Q_x86_64-cpa-fix-cache-attribute-inconsistency-bug.patch |
761 |
=================================================================== |
762 |
--- hardened-sources/2.6/tags/2.6.23-6/1022_2.6.23.Q_x86_64-cpa-fix-cache-attribute-inconsistency-bug.patch (rev 0) |
763 |
+++ hardened-sources/2.6/tags/2.6.23-6/1022_2.6.23.Q_x86_64-cpa-fix-cache-attribute-inconsistency-bug.patch 2008-04-30 11:41:42 UTC (rev 96) |
764 |
@@ -0,0 +1,62 @@ |
765 |
+From linux-kernel-owner+greg=40kroah.com-S1761718AbYBOT7Z@×××××××××××.org Fri Feb 15 12:00:56 2008 |
766 |
+From: Ingo Molnar <mingo@××××.hu> |
767 |
+Date: Fri, 15 Feb 2008 20:58:54 +0100 |
768 |
+Subject: x86_64: CPA, fix cache attribute inconsistency bug |
769 |
+To: stable@××××××.org |
770 |
+Cc: linux-kernel@×××××××××××.org, Thomas Gleixner <tglx@××××××××××.de>, Andi Kleen <andi@××××××××××.org> |
771 |
+Message-ID: <20080215195854.GB15432@××××.hu> |
772 |
+Content-Disposition: inline |
773 |
+ |
774 |
+From: Ingo Molnar <mingo@××××.hu> |
775 |
+ |
776 |
+no upstream git id as the code has been rewritten. |
777 |
+ |
778 |
+fix CPA cache attribute bug in v2.6.23. When phys_base is nonzero |
779 |
+(when CONFIG_RELOCATABLE=y) then change_page_attr_addr() miscalculates |
780 |
+the secondary alias address by -14 MB (depending on the configured |
781 |
+offset). |
782 |
+ |
783 |
+The default 64-bit kernels of Fedora and Ubuntu are affected: |
784 |
+ |
785 |
+ $ grep RELOCA /boot/config-2.6.23.9-85.fc8 |
786 |
+ CONFIG_RELOCATABLE=y |
787 |
+ |
788 |
+ $ grep RELOC /boot/config-2.6.22-14-generic |
789 |
+ CONFIG_RELOCATABLE=y |
790 |
+ |
791 |
+and probably on many other distros as well. |
792 |
+ |
793 |
+the bug affects all pages in the first 40 MB of physical RAM that |
794 |
+are allocated by some subsystem that does ioremap_nocache() on them: |
795 |
+ |
796 |
+ if (__pa(address) < KERNEL_TEXT_SIZE) { |
797 |
+ |
798 |
+Hence we might leave page table entries with inconsistent cache |
799 |
+attributes around (pages mapped at both UnCacheable and Write-Back), |
800 |
+and we can also set the wrong kernel text pages to UnCacheable. |
801 |
+ |
802 |
+the effects of this bug can be random slowdowns and other misbehavior. |
803 |
+If for example AGP allocates its aperture pages into the first 40 MB |
804 |
+of physical RAM, then the -14 MB bug might mark random kernel texto |
805 |
+pages as uncacheable, slowing down a random portion of the 64-bit |
806 |
+kernel until the AGP driver is unloaded. |
807 |
+ |
808 |
+Signed-off-by: Ingo Molnar <mingo@××××.hu> |
809 |
+Acked-by: Thomas Gleixner <tglx@××××××××××.de> |
810 |
+Signed-off-by: Greg Kroah-Hartman <gregkh@××××.de> |
811 |
+ |
812 |
+--- |
813 |
+ arch/x86_64/mm/pageattr.c | 2 +- |
814 |
+ 1 file changed, 1 insertion(+), 1 deletion(-) |
815 |
+ |
816 |
+--- a/arch/x86_64/mm/pageattr.c |
817 |
++++ b/arch/x86_64/mm/pageattr.c |
818 |
+@@ -207,7 +207,7 @@ int change_page_attr_addr(unsigned long |
819 |
+ if (__pa(address) < KERNEL_TEXT_SIZE) { |
820 |
+ unsigned long addr2; |
821 |
+ pgprot_t prot2; |
822 |
+- addr2 = __START_KERNEL_map + __pa(address); |
823 |
++ addr2 = __START_KERNEL_map + __pa(address) - phys_base; |
824 |
+ /* Make sure the kernel mappings stay executable */ |
825 |
+ prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); |
826 |
+ err = __change_page_attr(addr2, pfn, prot2, |
827 |
|
828 |
Added: hardened-sources/2.6/tags/2.6.23-6/4405_alpha-sysctl-uac-for-hardened-extras.patch |
829 |
=================================================================== |
830 |
--- hardened-sources/2.6/tags/2.6.23-6/4405_alpha-sysctl-uac-for-hardened-extras.patch (rev 0) |
831 |
+++ hardened-sources/2.6/tags/2.6.23-6/4405_alpha-sysctl-uac-for-hardened-extras.patch 2008-04-30 11:41:42 UTC (rev 96) |
832 |
@@ -0,0 +1,187 @@ |
833 |
+--- |
834 |
+ arch/alpha/Kconfig | 26 ++++++++++++++++++++++++ |
835 |
+ arch/alpha/kernel/traps.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ |
836 |
+ include/linux/sysctl.h | 14 +++++++++++++ |
837 |
+ kernel/sysctl.c | 12 ++++++++++- |
838 |
+ 4 files changed, 100 insertions(+), 1 deletion(-) |
839 |
+ |
840 |
+--- a/arch/alpha/Kconfig |
841 |
++++ b/arch/alpha/Kconfig |
842 |
+@@ -616,6 +616,32 @@ config VERBOSE_MCHECK_ON |
843 |
+ |
844 |
+ Take the default (1) unless you want more control or more info. |
845 |
+ |
846 |
++config ALPHA_UAC_SYSCTL |
847 |
++ bool "Configure UAC policy via sysctl" |
848 |
++ depends on SYSCTL |
849 |
++ default y |
850 |
++ ---help--- |
851 |
++ Configuring the UAC (unaligned access control) policy on a Linux |
852 |
++ system usually involves setting a compile time define. If you say |
853 |
++ Y here, you will be able to modify the UAC policy at runtime using |
854 |
++ the /proc interface. |
855 |
++ |
856 |
++ The UAC policy defines the action Linux should take when an |
857 |
++ unaligned memory access occurs. The action can include printing a |
858 |
++ warning message (NOPRINT), sending a signal to the offending |
859 |
++ program to help developers debug their applications (SIGBUS), or |
860 |
++ disabling the transparent fixing (NOFIX). |
861 |
++ |
862 |
++ The sysctls will be initialized to the compile-time defined UAC |
863 |
++ policy. You can change these manually, or with the sysctl(8) |
864 |
++ userspace utility. |
865 |
++ |
866 |
++ To disable the warning messages at runtime, you would use |
867 |
++ |
868 |
++ echo 1 > /proc/sys/kernel/uac/noprint |
869 |
++ |
870 |
++ This is pretty harmless. Say Y if you're not sure. |
871 |
++ |
872 |
+ source "drivers/pci/Kconfig" |
873 |
+ source "drivers/eisa/Kconfig" |
874 |
+ |
875 |
+--- a/arch/alpha/kernel/traps.c |
876 |
++++ b/arch/alpha/kernel/traps.c |
877 |
+@@ -14,6 +14,7 @@ |
878 |
+ #include <linux/delay.h> |
879 |
+ #include <linux/smp_lock.h> |
880 |
+ #include <linux/module.h> |
881 |
++#include <linux/sysctl.h> |
882 |
+ #include <linux/init.h> |
883 |
+ #include <linux/kallsyms.h> |
884 |
+ |
885 |
+@@ -102,6 +103,38 @@ static char * ireg_name[] = {"v0", "t0", |
886 |
+ "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"}; |
887 |
+ #endif |
888 |
+ |
889 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
890 |
++static struct ctl_table_header *uac_sysctl_header; |
891 |
++ |
892 |
++static int enabled_noprint = 0; |
893 |
++static int enabled_sigbus = 0; |
894 |
++static int enabled_nofix = 0; |
895 |
++ |
896 |
++ctl_table uac_table[] = { |
897 |
++ {KERN_UAC_NOPRINT, "noprint", &enabled_noprint, sizeof (int), 0644, NULL, NULL, &proc_dointvec}, |
898 |
++ {KERN_UAC_SIGBUS, "sigbus", &enabled_sigbus, sizeof (int), 0644, NULL, NULL, &proc_dointvec}, |
899 |
++ {KERN_UAC_NOFIX, "nofix", &enabled_nofix, sizeof (int), 0644, NULL, NULL, &proc_dointvec}, |
900 |
++ {0} |
901 |
++}; |
902 |
++ |
903 |
++static int __init init_uac_sysctl(void) |
904 |
++{ |
905 |
++ /* Initialize sysctls with the #defined UAC policy */ |
906 |
++ enabled_noprint = (test_thread_flag (TIF_UAC_NOPRINT)) ? 1 : 0; |
907 |
++ enabled_sigbus = (test_thread_flag (TIF_UAC_SIGBUS)) ? 1 : 0; |
908 |
++ enabled_nofix = (test_thread_flag (TIF_UAC_NOFIX)) ? 1 : 0; |
909 |
++ |
910 |
++ /* save this for later so we can clean up */ |
911 |
++ uac_sysctl_header = register_sysctl_table(uac_table); |
912 |
++ return 0; |
913 |
++} |
914 |
++ |
915 |
++static void __exit exit_uac_sysctl(void) |
916 |
++{ |
917 |
++ unregister_sysctl_table(uac_sysctl_header); |
918 |
++} |
919 |
++#endif |
920 |
++ |
921 |
+ static void |
922 |
+ dik_show_code(unsigned int *pc) |
923 |
+ { |
924 |
+@@ -780,7 +813,11 @@ do_entUnaUser(void __user * va, unsigned |
925 |
+ /* Check the UAC bits to decide what the user wants us to do |
926 |
+ with the unaliged access. */ |
927 |
+ |
928 |
++#ifndef CONFIG_ALPHA_UAC_SYSCTL |
929 |
+ if (!test_thread_flag (TIF_UAC_NOPRINT)) { |
930 |
++#else /* CONFIG_ALPHA_UAC_SYSCTL */ |
931 |
++ if (!(enabled_noprint)) { |
932 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
933 |
+ if (cnt >= 5 && jiffies - last_time > 5*HZ) { |
934 |
+ cnt = 0; |
935 |
+ } |
936 |
+@@ -791,10 +828,18 @@ do_entUnaUser(void __user * va, unsigned |
937 |
+ } |
938 |
+ last_time = jiffies; |
939 |
+ } |
940 |
++#ifndef CONFIG_ALPHA_UAC_SYSCTL |
941 |
+ if (test_thread_flag (TIF_UAC_SIGBUS)) |
942 |
++#else /* CONFIG_ALPHA_UAC_SYSCTL */ |
943 |
++ if (enabled_sigbus) |
944 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
945 |
+ goto give_sigbus; |
946 |
+ /* Not sure why you'd want to use this, but... */ |
947 |
++#ifndef CONFIG_ALPHA_UAC_SYSCTL |
948 |
+ if (test_thread_flag (TIF_UAC_NOFIX)) |
949 |
++#else /* CONFIG_ALPHA_UAC_SYSCTL */ |
950 |
++ if (enabled_nofix) |
951 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
952 |
+ return; |
953 |
+ |
954 |
+ /* Don't bother reading ds in the access check since we already |
955 |
+@@ -1089,3 +1134,7 @@ trap_init(void) |
956 |
+ wrent(entSys, 5); |
957 |
+ wrent(entDbg, 6); |
958 |
+ } |
959 |
++ |
960 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
961 |
++__initcall(init_uac_sysctl); |
962 |
++#endif |
963 |
+--- a/include/linux/sysctl.h |
964 |
++++ b/include/linux/sysctl.h |
965 |
+@@ -165,6 +165,9 @@ enum |
966 |
+ KERN_MAX_LOCK_DEPTH=74, |
967 |
+ KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */ |
968 |
+ KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */ |
969 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
970 |
++ KERN_UAC_POLICY=78, /* int: Alpha unaligned access control policy flags */ |
971 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
972 |
+ }; |
973 |
+ |
974 |
+ |
975 |
+@@ -258,6 +261,17 @@ enum |
976 |
+ PTY_NR=2 |
977 |
+ }; |
978 |
+ |
979 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
980 |
++/* /proc/sys/kernel/uac */ |
981 |
++enum |
982 |
++{ |
983 |
++ /* UAC policy on Alpha */ |
984 |
++ KERN_UAC_NOPRINT=1, /* int: printk() on unaligned access */ |
985 |
++ KERN_UAC_SIGBUS=2, /* int: send SIGBUS on unaligned access */ |
986 |
++ KERN_UAC_NOFIX=3, /* int: don't fix the unaligned access */ |
987 |
++}; |
988 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
989 |
++ |
990 |
+ /* /proc/sys/bus/isa */ |
991 |
+ enum |
992 |
+ { |
993 |
+--- a/kernel/sysctl.c |
994 |
++++ b/kernel/sysctl.c |
995 |
+@@ -155,6 +155,9 @@ extern ctl_table pty_table[]; |
996 |
+ #ifdef CONFIG_INOTIFY_USER |
997 |
+ extern ctl_table inotify_table[]; |
998 |
+ #endif |
999 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
1000 |
++extern ctl_table uac_table[]; |
1001 |
++#endif |
1002 |
+ |
1003 |
+ #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
1004 |
+ int sysctl_legacy_va_layout; |
1005 |
+@@ -208,6 +211,14 @@ static ctl_table root_table[] = { |
1006 |
+ * NOTE: do not add new entries to this table unless you have read |
1007 |
+ * Documentation/sysctl/ctl_unnumbered.txt |
1008 |
+ */ |
1009 |
++#ifdef CONFIG_ALPHA_UAC_SYSCTL |
1010 |
++ { |
1011 |
++ .ctl_name = KERN_UAC_POLICY, |
1012 |
++ .procname = "uac", |
1013 |
++ .mode = 0555, |
1014 |
++ .child = uac_table, |
1015 |
++ }, |
1016 |
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
1017 |
+ { .ctl_name = 0 } |
1018 |
+ }; |
1019 |
+ |
1020 |
|
1021 |
Added: hardened-sources/2.6/tags/2.6.23-6/4450_grsec-2.1.11-2.6.23.15-20080210.patch |
1022 |
=================================================================== |
1023 |
--- hardened-sources/2.6/tags/2.6.23-6/4450_grsec-2.1.11-2.6.23.15-20080210.patch (rev 0) |
1024 |
+++ hardened-sources/2.6/tags/2.6.23-6/4450_grsec-2.1.11-2.6.23.15-20080210.patch 2008-04-30 11:41:42 UTC (rev 96) |
1025 |
@@ -0,0 +1,35665 @@ |
1026 |
+From: Kerin Millar <kerframil@×××××.com> |
1027 |
+ |
1028 |
+grsecurity-2.1.11-2.6.23.14-200801231800 forward ported to 2.6.23.15 for |
1029 |
+the Hardened Gentoo project. Thanks to pipacs for some advice concerning |
1030 |
+mmap.c changes. |
1031 |
+ |
1032 |
+diff -Nurp linux-2.6.23.15/Documentation/dontdiff linux-2.6.23.15-grsec/Documentation/dontdiff |
1033 |
+--- linux-2.6.23.15/Documentation/dontdiff 2007-10-09 21:31:38.000000000 +0100 |
1034 |
++++ linux-2.6.23.15-grsec/Documentation/dontdiff 2008-02-11 10:37:44.000000000 +0000 |
1035 |
+@@ -176,14 +176,18 @@ times.h* |
1036 |
+ tkparse |
1037 |
+ trix_boot.h |
1038 |
+ utsrelease.h* |
1039 |
++vdso.lds |
1040 |
+ version.h* |
1041 |
+ vmlinux |
1042 |
+ vmlinux-* |
1043 |
+ vmlinux.aout |
1044 |
++vmlinux.bin.all |
1045 |
+ vmlinux.lds |
1046 |
++vmlinux.relocs |
1047 |
+ vsyscall.lds |
1048 |
+ wanxlfw.inc |
1049 |
+ uImage |
1050 |
+ unifdef |
1051 |
++utsrelease.h |
1052 |
+ zImage* |
1053 |
+ zconf.hash.c |
1054 |
+diff -Nurp linux-2.6.23.15/Makefile linux-2.6.23.15-grsec/Makefile |
1055 |
+--- linux-2.6.23.15/Makefile 2008-02-11 10:36:03.000000000 +0000 |
1056 |
++++ linux-2.6.23.15-grsec/Makefile 2008-02-11 10:37:44.000000000 +0000 |
1057 |
+@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \ |
1058 |
+ |
1059 |
+ CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) |
1060 |
+ |
1061 |
+-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
1062 |
++CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
1063 |
+ -fno-strict-aliasing -fno-common \ |
1064 |
+ -Werror-implicit-function-declaration |
1065 |
+ AFLAGS := -D__ASSEMBLY__ |
1066 |
+@@ -560,7 +560,7 @@ export mod_strip_cmd |
1067 |
+ |
1068 |
+ |
1069 |
+ ifeq ($(KBUILD_EXTMOD),) |
1070 |
+-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ |
1071 |
++core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/ |
1072 |
+ |
1073 |
+ vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ |
1074 |
+ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ |
1075 |
+diff -Nurp linux-2.6.23.15/arch/alpha/kernel/module.c linux-2.6.23.15-grsec/arch/alpha/kernel/module.c |
1076 |
+--- linux-2.6.23.15/arch/alpha/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
1077 |
++++ linux-2.6.23.15-grsec/arch/alpha/kernel/module.c 2008-02-11 10:37:44.000000000 +0000 |
1078 |
+@@ -176,7 +176,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, |
1079 |
+ |
1080 |
+ /* The small sections were sorted to the end of the segment. |
1081 |
+ The following should definitely cover them. */ |
1082 |
+- gp = (u64)me->module_core + me->core_size - 0x8000; |
1083 |
++ gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000; |
1084 |
+ got = sechdrs[me->arch.gotsecindex].sh_addr; |
1085 |
+ |
1086 |
+ for (i = 0; i < n; i++) { |
1087 |
+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 |
1088 |
+--- linux-2.6.23.15/arch/alpha/kernel/osf_sys.c 2007-10-09 21:31:38.000000000 +0100 |
1089 |
++++ linux-2.6.23.15-grsec/arch/alpha/kernel/osf_sys.c 2008-02-11 10:37:44.000000000 +0000 |
1090 |
+@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp |
1091 |
+ merely specific addresses, but regions of memory -- perhaps |
1092 |
+ this feature should be incorporated into all ports? */ |
1093 |
+ |
1094 |
++#ifdef CONFIG_PAX_RANDMMAP |
1095 |
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
1096 |
++#endif |
1097 |
++ |
1098 |
+ if (addr) { |
1099 |
+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); |
1100 |
+ if (addr != (unsigned long) -ENOMEM) |
1101 |
+@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp |
1102 |
+ } |
1103 |
+ |
1104 |
+ /* Next, try allocating at TASK_UNMAPPED_BASE. */ |
1105 |
+- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), |
1106 |
+- len, limit); |
1107 |
++ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit); |
1108 |
++ |
1109 |
+ if (addr != (unsigned long) -ENOMEM) |
1110 |
+ return addr; |
1111 |
+ |
1112 |
+diff -Nurp linux-2.6.23.15/arch/alpha/kernel/ptrace.c linux-2.6.23.15-grsec/arch/alpha/kernel/ptrace.c |
1113 |
+--- linux-2.6.23.15/arch/alpha/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100 |
1114 |
++++ linux-2.6.23.15-grsec/arch/alpha/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000 |
1115 |
+@@ -15,6 +15,7 @@ |
1116 |
+ #include <linux/slab.h> |
1117 |
+ #include <linux/security.h> |
1118 |
+ #include <linux/signal.h> |
1119 |
++#include <linux/grsecurity.h> |
1120 |
+ |
1121 |
+ #include <asm/uaccess.h> |
1122 |
+ #include <asm/pgtable.h> |
1123 |
+@@ -283,6 +284,11 @@ do_sys_ptrace(long request, long pid, lo |
1124 |
+ goto out_notsk; |
1125 |
+ } |
1126 |
+ |
1127 |
++ if (gr_handle_ptrace(child, request)) { |
1128 |
++ ret = -EPERM; |
1129 |
++ goto out; |
1130 |
++ } |
1131 |
++ |
1132 |
+ if (request == PTRACE_ATTACH) { |
1133 |
+ ret = ptrace_attach(child); |
1134 |
+ goto out; |
1135 |
+diff -Nurp linux-2.6.23.15/arch/alpha/mm/fault.c linux-2.6.23.15-grsec/arch/alpha/mm/fault.c |
1136 |
+--- linux-2.6.23.15/arch/alpha/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
1137 |
++++ linux-2.6.23.15-grsec/arch/alpha/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
1138 |
+@@ -23,6 +23,7 @@ |
1139 |
+ #include <linux/smp.h> |
1140 |
+ #include <linux/interrupt.h> |
1141 |
+ #include <linux/module.h> |
1142 |
++#include <linux/binfmts.h> |
1143 |
+ |
1144 |
+ #include <asm/system.h> |
1145 |
+ #include <asm/uaccess.h> |
1146 |
+@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct * |
1147 |
+ __reload_thread(pcb); |
1148 |
+ } |
1149 |
+ |
1150 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1151 |
++/* |
1152 |
++ * PaX: decide what to do with offenders (regs->pc = fault address) |
1153 |
++ * |
1154 |
++ * returns 1 when task should be killed |
1155 |
++ * 2 when patched PLT trampoline was detected |
1156 |
++ * 3 when unpatched PLT trampoline was detected |
1157 |
++ */ |
1158 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
1159 |
++{ |
1160 |
++ |
1161 |
++#ifdef CONFIG_PAX_EMUPLT |
1162 |
++ int err; |
1163 |
++ |
1164 |
++ do { /* PaX: patched PLT emulation #1 */ |
1165 |
++ unsigned int ldah, ldq, jmp; |
1166 |
++ |
1167 |
++ err = get_user(ldah, (unsigned int *)regs->pc); |
1168 |
++ err |= get_user(ldq, (unsigned int *)(regs->pc+4)); |
1169 |
++ err |= get_user(jmp, (unsigned int *)(regs->pc+8)); |
1170 |
++ |
1171 |
++ if (err) |
1172 |
++ break; |
1173 |
++ |
1174 |
++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && |
1175 |
++ (ldq & 0xFFFF0000U) == 0xA77B0000U && |
1176 |
++ jmp == 0x6BFB0000U) |
1177 |
++ { |
1178 |
++ unsigned long r27, addr; |
1179 |
++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; |
1180 |
++ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL; |
1181 |
++ |
1182 |
++ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); |
1183 |
++ err = get_user(r27, (unsigned long *)addr); |
1184 |
++ if (err) |
1185 |
++ break; |
1186 |
++ |
1187 |
++ regs->r27 = r27; |
1188 |
++ regs->pc = r27; |
1189 |
++ return 2; |
1190 |
++ } |
1191 |
++ } while (0); |
1192 |
++ |
1193 |
++ do { /* PaX: patched PLT emulation #2 */ |
1194 |
++ unsigned int ldah, lda, br; |
1195 |
++ |
1196 |
++ err = get_user(ldah, (unsigned int *)regs->pc); |
1197 |
++ err |= get_user(lda, (unsigned int *)(regs->pc+4)); |
1198 |
++ err |= get_user(br, (unsigned int *)(regs->pc+8)); |
1199 |
++ |
1200 |
++ if (err) |
1201 |
++ break; |
1202 |
++ |
1203 |
++ if ((ldah & 0xFFFF0000U) == 0x277B0000U && |
1204 |
++ (lda & 0xFFFF0000U) == 0xA77B0000U && |
1205 |
++ (br & 0xFFE00000U) == 0xC3E00000U) |
1206 |
++ { |
1207 |
++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL; |
1208 |
++ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; |
1209 |
++ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL; |
1210 |
++ |
1211 |
++ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); |
1212 |
++ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); |
1213 |
++ return 2; |
1214 |
++ } |
1215 |
++ } while (0); |
1216 |
++ |
1217 |
++ do { /* PaX: unpatched PLT emulation */ |
1218 |
++ unsigned int br; |
1219 |
++ |
1220 |
++ err = get_user(br, (unsigned int *)regs->pc); |
1221 |
++ |
1222 |
++ if (!err && (br & 0xFFE00000U) == 0xC3800000U) { |
1223 |
++ unsigned int br2, ldq, nop, jmp; |
1224 |
++ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver; |
1225 |
++ |
1226 |
++ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); |
1227 |
++ err = get_user(br2, (unsigned int *)addr); |
1228 |
++ err |= get_user(ldq, (unsigned int *)(addr+4)); |
1229 |
++ err |= get_user(nop, (unsigned int *)(addr+8)); |
1230 |
++ err |= get_user(jmp, (unsigned int *)(addr+12)); |
1231 |
++ err |= get_user(resolver, (unsigned long *)(addr+16)); |
1232 |
++ |
1233 |
++ if (err) |
1234 |
++ break; |
1235 |
++ |
1236 |
++ if (br2 == 0xC3600000U && |
1237 |
++ ldq == 0xA77B000CU && |
1238 |
++ nop == 0x47FF041FU && |
1239 |
++ jmp == 0x6B7B0000U) |
1240 |
++ { |
1241 |
++ regs->r28 = regs->pc+4; |
1242 |
++ regs->r27 = addr+16; |
1243 |
++ regs->pc = resolver; |
1244 |
++ return 3; |
1245 |
++ } |
1246 |
++ } |
1247 |
++ } while (0); |
1248 |
++#endif |
1249 |
++ |
1250 |
++ return 1; |
1251 |
++} |
1252 |
++ |
1253 |
++void pax_report_insns(void *pc, void *sp) |
1254 |
++{ |
1255 |
++ unsigned long i; |
1256 |
++ |
1257 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
1258 |
++ for (i = 0; i < 5; i++) { |
1259 |
++ unsigned int c; |
1260 |
++ if (get_user(c, (unsigned int *)pc+i)) |
1261 |
++ printk("???????? "); |
1262 |
++ else |
1263 |
++ printk("%08x ", c); |
1264 |
++ } |
1265 |
++ printk("\n"); |
1266 |
++} |
1267 |
++#endif |
1268 |
+ |
1269 |
+ /* |
1270 |
+ * This routine handles page faults. It determines the address, |
1271 |
+@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns |
1272 |
+ good_area: |
1273 |
+ si_code = SEGV_ACCERR; |
1274 |
+ if (cause < 0) { |
1275 |
+- if (!(vma->vm_flags & VM_EXEC)) |
1276 |
++ if (!(vma->vm_flags & VM_EXEC)) { |
1277 |
++ |
1278 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1279 |
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc) |
1280 |
++ goto bad_area; |
1281 |
++ |
1282 |
++ up_read(&mm->mmap_sem); |
1283 |
++ switch (pax_handle_fetch_fault(regs)) { |
1284 |
++ |
1285 |
++#ifdef CONFIG_PAX_EMUPLT |
1286 |
++ case 2: |
1287 |
++ case 3: |
1288 |
++ return; |
1289 |
++#endif |
1290 |
++ |
1291 |
++ } |
1292 |
++ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp()); |
1293 |
++ do_exit(SIGKILL); |
1294 |
++#else |
1295 |
+ goto bad_area; |
1296 |
++#endif |
1297 |
++ |
1298 |
++ } |
1299 |
+ } else if (!cause) { |
1300 |
+ /* Allow reads even for write-only mappings */ |
1301 |
+ if (!(vma->vm_flags & (VM_READ | VM_WRITE))) |
1302 |
+diff -Nurp linux-2.6.23.15/arch/arm/mm/mmap.c linux-2.6.23.15-grsec/arch/arm/mm/mmap.c |
1303 |
+--- linux-2.6.23.15/arch/arm/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100 |
1304 |
++++ linux-2.6.23.15-grsec/arch/arm/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000 |
1305 |
+@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp |
1306 |
+ if (len > TASK_SIZE) |
1307 |
+ return -ENOMEM; |
1308 |
+ |
1309 |
++#ifdef CONFIG_PAX_RANDMMAP |
1310 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
1311 |
++#endif |
1312 |
++ |
1313 |
+ if (addr) { |
1314 |
+ if (do_align) |
1315 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
1316 |
+@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp |
1317 |
+ return addr; |
1318 |
+ } |
1319 |
+ if (len > mm->cached_hole_size) { |
1320 |
+- start_addr = addr = mm->free_area_cache; |
1321 |
++ start_addr = addr = mm->free_area_cache; |
1322 |
+ } else { |
1323 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
1324 |
+- mm->cached_hole_size = 0; |
1325 |
++ start_addr = addr = mm->mmap_base; |
1326 |
++ mm->cached_hole_size = 0; |
1327 |
+ } |
1328 |
+ |
1329 |
+ full_search: |
1330 |
+@@ -91,8 +95,8 @@ full_search: |
1331 |
+ * Start a new search - just in case we missed |
1332 |
+ * some holes. |
1333 |
+ */ |
1334 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
1335 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
1336 |
++ if (start_addr != mm->mmap_base) { |
1337 |
++ start_addr = addr = mm->mmap_base; |
1338 |
+ mm->cached_hole_size = 0; |
1339 |
+ goto full_search; |
1340 |
+ } |
1341 |
+diff -Nurp linux-2.6.23.15/arch/avr32/mm/fault.c linux-2.6.23.15-grsec/arch/avr32/mm/fault.c |
1342 |
+--- linux-2.6.23.15/arch/avr32/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
1343 |
++++ linux-2.6.23.15-grsec/arch/avr32/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
1344 |
+@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru |
1345 |
+ |
1346 |
+ int exception_trace = 1; |
1347 |
+ |
1348 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1349 |
++void pax_report_insns(void *pc, void *sp) |
1350 |
++{ |
1351 |
++ unsigned long i; |
1352 |
++ |
1353 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
1354 |
++ for (i = 0; i < 20; i++) { |
1355 |
++ unsigned char c; |
1356 |
++ if (get_user(c, (unsigned char *)pc+i)) |
1357 |
++ printk("???????? "); |
1358 |
++ else |
1359 |
++ printk("%02x ", c); |
1360 |
++ } |
1361 |
++ printk("\n"); |
1362 |
++} |
1363 |
++#endif |
1364 |
++ |
1365 |
+ /* |
1366 |
+ * This routine handles page faults. It determines the address and the |
1367 |
+ * problem, and then passes it off to one of the appropriate routines. |
1368 |
+@@ -157,6 +174,16 @@ bad_area: |
1369 |
+ up_read(&mm->mmap_sem); |
1370 |
+ |
1371 |
+ if (user_mode(regs)) { |
1372 |
++ |
1373 |
++#ifdef CONFIG_PAX_PAGEEXEC |
1374 |
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { |
1375 |
++ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) { |
1376 |
++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp); |
1377 |
++ do_exit(SIGKILL); |
1378 |
++ } |
1379 |
++ } |
1380 |
++#endif |
1381 |
++ |
1382 |
+ if (exception_trace && printk_ratelimit()) |
1383 |
+ printk("%s%s[%d]: segfault at %08lx pc %08lx " |
1384 |
+ "sp %08lx ecr %lu\n", |
1385 |
+diff -Nurp linux-2.6.23.15/arch/i386/Kconfig linux-2.6.23.15-grsec/arch/i386/Kconfig |
1386 |
+--- linux-2.6.23.15/arch/i386/Kconfig 2007-10-09 21:31:38.000000000 +0100 |
1387 |
++++ linux-2.6.23.15-grsec/arch/i386/Kconfig 2008-02-11 10:37:44.000000000 +0000 |
1388 |
+@@ -592,7 +592,7 @@ config PAGE_OFFSET |
1389 |
+ hex |
1390 |
+ default 0xB0000000 if VMSPLIT_3G_OPT |
1391 |
+ default 0x80000000 if VMSPLIT_2G |
1392 |
+- default 0x78000000 if VMSPLIT_2G_OPT |
1393 |
++ default 0x70000000 if VMSPLIT_2G_OPT |
1394 |
+ default 0x40000000 if VMSPLIT_1G |
1395 |
+ default 0xC0000000 |
1396 |
+ |
1397 |
+@@ -831,7 +831,7 @@ config CRASH_DUMP |
1398 |
+ config PHYSICAL_START |
1399 |
+ hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) |
1400 |
+ default "0x1000000" if X86_NUMAQ |
1401 |
+- default "0x100000" |
1402 |
++ default "0x200000" |
1403 |
+ help |
1404 |
+ This gives the physical address where the kernel is loaded. |
1405 |
+ |
1406 |
+@@ -916,7 +916,7 @@ config HOTPLUG_CPU |
1407 |
+ |
1408 |
+ config COMPAT_VDSO |
1409 |
+ bool "Compat VDSO support" |
1410 |
+- default y |
1411 |
++ default n |
1412 |
+ help |
1413 |
+ Map the VDSO to the predictable old-style address too. |
1414 |
+ ---help--- |
1415 |
+@@ -1092,7 +1092,7 @@ config PCI |
1416 |
+ choice |
1417 |
+ prompt "PCI access mode" |
1418 |
+ depends on PCI && !X86_VISWS |
1419 |
+- default PCI_GOANY |
1420 |
++ default PCI_GODIRECT |
1421 |
+ ---help--- |
1422 |
+ On PCI systems, the BIOS can be used to detect the PCI devices and |
1423 |
+ determine their configuration. However, some old PCI motherboards |
1424 |
+diff -Nurp linux-2.6.23.15/arch/i386/Kconfig.cpu linux-2.6.23.15-grsec/arch/i386/Kconfig.cpu |
1425 |
+--- linux-2.6.23.15/arch/i386/Kconfig.cpu 2007-10-09 21:31:38.000000000 +0100 |
1426 |
++++ linux-2.6.23.15-grsec/arch/i386/Kconfig.cpu 2008-02-11 10:37:44.000000000 +0000 |
1427 |
+@@ -274,7 +274,7 @@ config X86_PPRO_FENCE |
1428 |
+ |
1429 |
+ config X86_F00F_BUG |
1430 |
+ bool |
1431 |
+- depends on M586MMX || M586TSC || M586 || M486 || M386 |
1432 |
++ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC |
1433 |
+ default y |
1434 |
+ |
1435 |
+ config X86_WP_WORKS_OK |
1436 |
+@@ -299,7 +299,7 @@ config X86_POPAD_OK |
1437 |
+ |
1438 |
+ config X86_ALIGNMENT_16 |
1439 |
+ bool |
1440 |
+- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
1441 |
++ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
1442 |
+ default y |
1443 |
+ |
1444 |
+ config X86_GOOD_APIC |
1445 |
+diff -Nurp linux-2.6.23.15/arch/i386/Kconfig.debug linux-2.6.23.15-grsec/arch/i386/Kconfig.debug |
1446 |
+--- linux-2.6.23.15/arch/i386/Kconfig.debug 2007-10-09 21:31:38.000000000 +0100 |
1447 |
++++ linux-2.6.23.15-grsec/arch/i386/Kconfig.debug 2008-02-11 10:37:44.000000000 +0000 |
1448 |
+@@ -46,16 +46,6 @@ config DEBUG_PAGEALLOC |
1449 |
+ This results in a large slowdown, but helps to find certain types |
1450 |
+ of memory corruptions. |
1451 |
+ |
1452 |
+-config DEBUG_RODATA |
1453 |
+- bool "Write protect kernel read-only data structures" |
1454 |
+- depends on DEBUG_KERNEL |
1455 |
+- help |
1456 |
+- Mark the kernel read-only data as write-protected in the pagetables, |
1457 |
+- in order to catch accidental (and incorrect) writes to such const |
1458 |
+- data. This option may have a slight performance impact because a |
1459 |
+- portion of the kernel code won't be covered by a 2MB TLB anymore. |
1460 |
+- If in doubt, say "N". |
1461 |
+- |
1462 |
+ config 4KSTACKS |
1463 |
+ bool "Use 4Kb for kernel stacks instead of 8Kb" |
1464 |
+ depends on DEBUG_KERNEL |
1465 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/bitops.h linux-2.6.23.15-grsec/arch/i386/boot/bitops.h |
1466 |
+--- linux-2.6.23.15/arch/i386/boot/bitops.h 2007-10-09 21:31:38.000000000 +0100 |
1467 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/bitops.h 2008-02-11 10:37:44.000000000 +0000 |
1468 |
+@@ -28,7 +28,7 @@ static inline int variable_test_bit(int |
1469 |
+ u8 v; |
1470 |
+ const u32 *p = (const u32 *)addr; |
1471 |
+ |
1472 |
+- asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr)); |
1473 |
++ asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr)); |
1474 |
+ return v; |
1475 |
+ } |
1476 |
+ |
1477 |
+@@ -39,7 +39,7 @@ static inline int variable_test_bit(int |
1478 |
+ |
1479 |
+ static inline void set_bit(int nr, void *addr) |
1480 |
+ { |
1481 |
+- asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr)); |
1482 |
++ asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr)); |
1483 |
+ } |
1484 |
+ |
1485 |
+ #endif /* BOOT_BITOPS_H */ |
1486 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/boot.h linux-2.6.23.15-grsec/arch/i386/boot/boot.h |
1487 |
+--- linux-2.6.23.15/arch/i386/boot/boot.h 2008-02-11 10:36:03.000000000 +0000 |
1488 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/boot.h 2008-02-11 10:37:44.000000000 +0000 |
1489 |
+@@ -78,7 +78,7 @@ static inline void io_delay(void) |
1490 |
+ static inline u16 ds(void) |
1491 |
+ { |
1492 |
+ u16 seg; |
1493 |
+- asm("movw %%ds,%0" : "=rm" (seg)); |
1494 |
++ asm volatile("movw %%ds,%0" : "=rm" (seg)); |
1495 |
+ return seg; |
1496 |
+ } |
1497 |
+ |
1498 |
+@@ -174,7 +174,7 @@ static inline void wrgs32(u32 v, addr_t |
1499 |
+ static inline int memcmp(const void *s1, const void *s2, size_t len) |
1500 |
+ { |
1501 |
+ u8 diff; |
1502 |
+- asm("repe; cmpsb; setnz %0" |
1503 |
++ asm volatile("repe; cmpsb; setnz %0" |
1504 |
+ : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len)); |
1505 |
+ return diff; |
1506 |
+ } |
1507 |
+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 |
1508 |
+--- linux-2.6.23.15/arch/i386/boot/compressed/head.S 2007-10-09 21:31:38.000000000 +0100 |
1509 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/compressed/head.S 2008-02-11 10:37:44.000000000 +0000 |
1510 |
+@@ -159,9 +159,8 @@ relocated: |
1511 |
+ */ |
1512 |
+ |
1513 |
+ 1: subl $4, %edi |
1514 |
+- movl 0(%edi), %ecx |
1515 |
+- testl %ecx, %ecx |
1516 |
+- jz 2f |
1517 |
++ movl (%edi), %ecx |
1518 |
++ jecxz 2f |
1519 |
+ addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) |
1520 |
+ jmp 1b |
1521 |
+ 2: |
1522 |
+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 |
1523 |
+--- linux-2.6.23.15/arch/i386/boot/compressed/relocs.c 2007-10-09 21:31:38.000000000 +0100 |
1524 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/compressed/relocs.c 2008-02-11 10:37:44.000000000 +0000 |
1525 |
+@@ -10,9 +10,13 @@ |
1526 |
+ #define USE_BSD |
1527 |
+ #include <endian.h> |
1528 |
+ |
1529 |
++#include "../../../../include/linux/autoconf.h" |
1530 |
++ |
1531 |
++#define MAX_PHDRS 100 |
1532 |
+ #define MAX_SHDRS 100 |
1533 |
+ #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
1534 |
+ static Elf32_Ehdr ehdr; |
1535 |
++static Elf32_Phdr phdr[MAX_PHDRS]; |
1536 |
+ static Elf32_Shdr shdr[MAX_SHDRS]; |
1537 |
+ static Elf32_Sym *symtab[MAX_SHDRS]; |
1538 |
+ static Elf32_Rel *reltab[MAX_SHDRS]; |
1539 |
+@@ -246,6 +250,34 @@ static void read_ehdr(FILE *fp) |
1540 |
+ } |
1541 |
+ } |
1542 |
+ |
1543 |
++static void read_phdrs(FILE *fp) |
1544 |
++{ |
1545 |
++ int i; |
1546 |
++ if (ehdr.e_phnum > MAX_PHDRS) { |
1547 |
++ die("%d program headers supported: %d\n", |
1548 |
++ ehdr.e_phnum, MAX_PHDRS); |
1549 |
++ } |
1550 |
++ if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) { |
1551 |
++ die("Seek to %d failed: %s\n", |
1552 |
++ ehdr.e_phoff, strerror(errno)); |
1553 |
++ } |
1554 |
++ if (fread(&phdr, sizeof(phdr[0]), ehdr.e_phnum, fp) != ehdr.e_phnum) { |
1555 |
++ die("Cannot read ELF program headers: %s\n", |
1556 |
++ strerror(errno)); |
1557 |
++ } |
1558 |
++ for(i = 0; i < ehdr.e_phnum; i++) { |
1559 |
++ phdr[i].p_type = elf32_to_cpu(phdr[i].p_type); |
1560 |
++ phdr[i].p_offset = elf32_to_cpu(phdr[i].p_offset); |
1561 |
++ phdr[i].p_vaddr = elf32_to_cpu(phdr[i].p_vaddr); |
1562 |
++ phdr[i].p_paddr = elf32_to_cpu(phdr[i].p_paddr); |
1563 |
++ phdr[i].p_filesz = elf32_to_cpu(phdr[i].p_filesz); |
1564 |
++ phdr[i].p_memsz = elf32_to_cpu(phdr[i].p_memsz); |
1565 |
++ phdr[i].p_flags = elf32_to_cpu(phdr[i].p_flags); |
1566 |
++ phdr[i].p_align = elf32_to_cpu(phdr[i].p_align); |
1567 |
++ } |
1568 |
++ |
1569 |
++} |
1570 |
++ |
1571 |
+ static void read_shdrs(FILE *fp) |
1572 |
+ { |
1573 |
+ int i; |
1574 |
+@@ -332,6 +364,8 @@ static void read_symtabs(FILE *fp) |
1575 |
+ static void read_relocs(FILE *fp) |
1576 |
+ { |
1577 |
+ int i,j; |
1578 |
++ uint32_t base; |
1579 |
++ |
1580 |
+ for(i = 0; i < ehdr.e_shnum; i++) { |
1581 |
+ if (shdr[i].sh_type != SHT_REL) { |
1582 |
+ continue; |
1583 |
+@@ -349,8 +383,17 @@ static void read_relocs(FILE *fp) |
1584 |
+ die("Cannot read symbol table: %s\n", |
1585 |
+ strerror(errno)); |
1586 |
+ } |
1587 |
++ base = 0; |
1588 |
++ for (j = 0; j < ehdr.e_phnum; j++) { |
1589 |
++ if (phdr[j].p_type != PT_LOAD ) |
1590 |
++ continue; |
1591 |
++ 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) |
1592 |
++ continue; |
1593 |
++ base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr; |
1594 |
++ break; |
1595 |
++ } |
1596 |
+ for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { |
1597 |
+- reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset); |
1598 |
++ reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset) + base; |
1599 |
+ reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info); |
1600 |
+ } |
1601 |
+ } |
1602 |
+@@ -487,6 +530,27 @@ static void walk_relocs(void (*visit)(El |
1603 |
+ if (sym->st_shndx == SHN_ABS) { |
1604 |
+ continue; |
1605 |
+ } |
1606 |
++ /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */ |
1607 |
++ if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10)) { |
1608 |
++ continue; |
1609 |
++ } |
1610 |
++#ifdef CONFIG_PAX_KERNEXEC |
1611 |
++ /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */ |
1612 |
++ if (!strcmp(sec_name(sym->st_shndx), ".init.text")) { |
1613 |
++ continue; |
1614 |
++ } |
1615 |
++ if (!strcmp(sec_name(sym->st_shndx), ".exit.text")) { |
1616 |
++ continue; |
1617 |
++ } |
1618 |
++ if (!strcmp(sec_name(sym->st_shndx), ".text.head")) |
1619 |
++ if (strcmp(sym_name(sym_strtab, sym), "__init_end") && |
1620 |
++ strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET")) { |
1621 |
++ continue; |
1622 |
++ } |
1623 |
++ if (!strcmp(sec_name(sym->st_shndx), ".text")) { |
1624 |
++ continue; |
1625 |
++ } |
1626 |
++#endif |
1627 |
+ if (r_type == R_386_PC32) { |
1628 |
+ /* PC relative relocations don't need to be adjusted */ |
1629 |
+ } |
1630 |
+@@ -614,6 +678,7 @@ int main(int argc, char **argv) |
1631 |
+ fname, strerror(errno)); |
1632 |
+ } |
1633 |
+ read_ehdr(fp); |
1634 |
++ read_phdrs(fp); |
1635 |
+ read_shdrs(fp); |
1636 |
+ read_strtabs(fp); |
1637 |
+ read_symtabs(fp); |
1638 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/cpucheck.c linux-2.6.23.15-grsec/arch/i386/boot/cpucheck.c |
1639 |
+--- linux-2.6.23.15/arch/i386/boot/cpucheck.c 2007-10-09 21:31:38.000000000 +0100 |
1640 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/cpucheck.c 2008-02-11 10:37:44.000000000 +0000 |
1641 |
+@@ -90,7 +90,7 @@ static int has_fpu(void) |
1642 |
+ u16 fcw = -1, fsw = -1; |
1643 |
+ u32 cr0; |
1644 |
+ |
1645 |
+- asm("movl %%cr0,%0" : "=r" (cr0)); |
1646 |
++ asm volatile("movl %%cr0,%0" : "=r" (cr0)); |
1647 |
+ if (cr0 & (X86_CR0_EM|X86_CR0_TS)) { |
1648 |
+ cr0 &= ~(X86_CR0_EM|X86_CR0_TS); |
1649 |
+ asm volatile("movl %0,%%cr0" : : "r" (cr0)); |
1650 |
+@@ -106,7 +106,7 @@ static int has_eflag(u32 mask) |
1651 |
+ { |
1652 |
+ u32 f0, f1; |
1653 |
+ |
1654 |
+- asm("pushfl ; " |
1655 |
++ asm volatile("pushfl ; " |
1656 |
+ "pushfl ; " |
1657 |
+ "popl %0 ; " |
1658 |
+ "movl %0,%1 ; " |
1659 |
+@@ -131,7 +131,7 @@ static void get_flags(void) |
1660 |
+ set_bit(X86_FEATURE_FPU, cpu.flags); |
1661 |
+ |
1662 |
+ if (has_eflag(X86_EFLAGS_ID)) { |
1663 |
+- asm("cpuid" |
1664 |
++ asm volatile("cpuid" |
1665 |
+ : "=a" (max_intel_level), |
1666 |
+ "=b" (cpu_vendor[0]), |
1667 |
+ "=d" (cpu_vendor[1]), |
1668 |
+@@ -140,7 +140,7 @@ static void get_flags(void) |
1669 |
+ |
1670 |
+ if (max_intel_level >= 0x00000001 && |
1671 |
+ max_intel_level <= 0x0000ffff) { |
1672 |
+- asm("cpuid" |
1673 |
++ asm volatile("cpuid" |
1674 |
+ : "=a" (tfms), |
1675 |
+ "=c" (cpu.flags[4]), |
1676 |
+ "=d" (cpu.flags[0]) |
1677 |
+@@ -152,7 +152,7 @@ static void get_flags(void) |
1678 |
+ cpu.model += ((tfms >> 16) & 0xf) << 4; |
1679 |
+ } |
1680 |
+ |
1681 |
+- asm("cpuid" |
1682 |
++ asm volatile("cpuid" |
1683 |
+ : "=a" (max_amd_level) |
1684 |
+ : "a" (0x80000000) |
1685 |
+ : "ebx", "ecx", "edx"); |
1686 |
+@@ -160,7 +160,7 @@ static void get_flags(void) |
1687 |
+ if (max_amd_level >= 0x80000001 && |
1688 |
+ max_amd_level <= 0x8000ffff) { |
1689 |
+ u32 eax = 0x80000001; |
1690 |
+- asm("cpuid" |
1691 |
++ asm volatile("cpuid" |
1692 |
+ : "+a" (eax), |
1693 |
+ "=c" (cpu.flags[6]), |
1694 |
+ "=d" (cpu.flags[1]) |
1695 |
+@@ -219,9 +219,9 @@ int check_cpu(int *cpu_level_ptr, int *r |
1696 |
+ u32 ecx = MSR_K7_HWCR; |
1697 |
+ u32 eax, edx; |
1698 |
+ |
1699 |
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
1700 |
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
1701 |
+ eax &= ~(1 << 15); |
1702 |
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
1703 |
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
1704 |
+ |
1705 |
+ get_flags(); /* Make sure it really did something */ |
1706 |
+ err = check_flags(); |
1707 |
+@@ -234,9 +234,9 @@ int check_cpu(int *cpu_level_ptr, int *r |
1708 |
+ u32 ecx = MSR_VIA_FCR; |
1709 |
+ u32 eax, edx; |
1710 |
+ |
1711 |
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
1712 |
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
1713 |
+ eax |= (1<<1)|(1<<7); |
1714 |
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
1715 |
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
1716 |
+ |
1717 |
+ set_bit(X86_FEATURE_CX8, cpu.flags); |
1718 |
+ err = check_flags(); |
1719 |
+@@ -247,12 +247,12 @@ int check_cpu(int *cpu_level_ptr, int *r |
1720 |
+ u32 eax, edx; |
1721 |
+ u32 level = 1; |
1722 |
+ |
1723 |
+- asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
1724 |
+- asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); |
1725 |
+- asm("cpuid" |
1726 |
++ asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx)); |
1727 |
++ asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx)); |
1728 |
++ asm volatile("cpuid" |
1729 |
+ : "+a" (level), "=d" (cpu.flags[0]) |
1730 |
+ : : "ecx", "ebx"); |
1731 |
+- asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
1732 |
++ asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx)); |
1733 |
+ |
1734 |
+ err = check_flags(); |
1735 |
+ } |
1736 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/edd.c linux-2.6.23.15-grsec/arch/i386/boot/edd.c |
1737 |
+--- linux-2.6.23.15/arch/i386/boot/edd.c 2007-10-09 21:31:38.000000000 +0100 |
1738 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/edd.c 2008-02-11 10:37:44.000000000 +0000 |
1739 |
+@@ -78,7 +78,7 @@ static int get_edd_info(u8 devno, struct |
1740 |
+ ax = 0x4100; |
1741 |
+ bx = EDDMAGIC1; |
1742 |
+ dx = devno; |
1743 |
+- asm("pushfl; stc; int $0x13; setc %%al; popfl" |
1744 |
++ asm volatile("pushfl; stc; int $0x13; setc %%al; popfl" |
1745 |
+ : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx) |
1746 |
+ : : "esi", "edi"); |
1747 |
+ |
1748 |
+@@ -97,7 +97,7 @@ static int get_edd_info(u8 devno, struct |
1749 |
+ ei->params.length = sizeof(ei->params); |
1750 |
+ ax = 0x4800; |
1751 |
+ dx = devno; |
1752 |
+- asm("pushfl; int $0x13; popfl" |
1753 |
++ asm volatile("pushfl; int $0x13; popfl" |
1754 |
+ : "+a" (ax), "+d" (dx), "=m" (ei->params) |
1755 |
+ : "S" (&ei->params) |
1756 |
+ : "ebx", "ecx", "edi"); |
1757 |
+@@ -108,7 +108,7 @@ static int get_edd_info(u8 devno, struct |
1758 |
+ ax = 0x0800; |
1759 |
+ dx = devno; |
1760 |
+ di = 0; |
1761 |
+- asm("pushw %%es; " |
1762 |
++ asm volatile("pushw %%es; " |
1763 |
+ "movw %%di,%%es; " |
1764 |
+ "pushfl; stc; int $0x13; setc %%al; popfl; " |
1765 |
+ "popw %%es" |
1766 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/main.c linux-2.6.23.15-grsec/arch/i386/boot/main.c |
1767 |
+--- linux-2.6.23.15/arch/i386/boot/main.c 2007-10-09 21:31:38.000000000 +0100 |
1768 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/main.c 2008-02-11 10:37:44.000000000 +0000 |
1769 |
+@@ -77,7 +77,7 @@ static void keyboard_set_repeat(void) |
1770 |
+ */ |
1771 |
+ static void query_ist(void) |
1772 |
+ { |
1773 |
+- asm("int $0x15" |
1774 |
++ asm volatile("int $0x15" |
1775 |
+ : "=a" (boot_params.ist_info.signature), |
1776 |
+ "=b" (boot_params.ist_info.command), |
1777 |
+ "=c" (boot_params.ist_info.event), |
1778 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/mca.c linux-2.6.23.15-grsec/arch/i386/boot/mca.c |
1779 |
+--- linux-2.6.23.15/arch/i386/boot/mca.c 2007-10-09 21:31:38.000000000 +0100 |
1780 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/mca.c 2008-02-11 10:37:44.000000000 +0000 |
1781 |
+@@ -21,7 +21,7 @@ int query_mca(void) |
1782 |
+ u8 err; |
1783 |
+ u16 es, bx, len; |
1784 |
+ |
1785 |
+- asm("pushw %%es ; " |
1786 |
++ asm volatile("pushw %%es ; " |
1787 |
+ "int $0x15 ; " |
1788 |
+ "setc %0 ; " |
1789 |
+ "movw %%es, %1 ; " |
1790 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/memory.c linux-2.6.23.15-grsec/arch/i386/boot/memory.c |
1791 |
+--- linux-2.6.23.15/arch/i386/boot/memory.c 2007-10-09 21:31:38.000000000 +0100 |
1792 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/memory.c 2008-02-11 10:37:44.000000000 +0000 |
1793 |
+@@ -32,7 +32,7 @@ static int detect_memory_e820(void) |
1794 |
+ /* Important: %edx is clobbered by some BIOSes, |
1795 |
+ so it must be either used for the error output |
1796 |
+ or explicitly marked clobbered. */ |
1797 |
+- asm("int $0x15; setc %0" |
1798 |
++ asm volatile("int $0x15; setc %0" |
1799 |
+ : "=d" (err), "+b" (next), "=a" (id), "+c" (size), |
1800 |
+ "=m" (*desc) |
1801 |
+ : "D" (desc), "d" (SMAP), "a" (0xe820)); |
1802 |
+@@ -64,7 +64,7 @@ static int detect_memory_e801(void) |
1803 |
+ |
1804 |
+ bx = cx = dx = 0; |
1805 |
+ ax = 0xe801; |
1806 |
+- asm("stc; int $0x15; setc %0" |
1807 |
++ asm volatile("stc; int $0x15; setc %0" |
1808 |
+ : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx)); |
1809 |
+ |
1810 |
+ if (err) |
1811 |
+@@ -94,7 +94,7 @@ static int detect_memory_88(void) |
1812 |
+ u8 err; |
1813 |
+ |
1814 |
+ ax = 0x8800; |
1815 |
+- asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax)); |
1816 |
++ asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax)); |
1817 |
+ |
1818 |
+ boot_params.screen_info.ext_mem_k = ax; |
1819 |
+ |
1820 |
+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 |
1821 |
+--- linux-2.6.23.15/arch/i386/boot/video-vesa.c 2008-02-11 10:36:03.000000000 +0000 |
1822 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/video-vesa.c 2008-02-11 10:37:44.000000000 +0000 |
1823 |
+@@ -41,7 +41,7 @@ static int vesa_probe(void) |
1824 |
+ |
1825 |
+ ax = 0x4f00; |
1826 |
+ di = (size_t)&vginfo; |
1827 |
+- asm(INT10 |
1828 |
++ asm volatile(INT10 |
1829 |
+ : "+a" (ax), "+D" (di), "=m" (vginfo) |
1830 |
+ : : "ebx", "ecx", "edx", "esi"); |
1831 |
+ |
1832 |
+@@ -68,7 +68,7 @@ static int vesa_probe(void) |
1833 |
+ ax = 0x4f01; |
1834 |
+ cx = mode; |
1835 |
+ di = (size_t)&vminfo; |
1836 |
+- asm(INT10 |
1837 |
++ asm volatile(INT10 |
1838 |
+ : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) |
1839 |
+ : : "ebx", "edx", "esi"); |
1840 |
+ |
1841 |
+@@ -115,7 +115,7 @@ static int vesa_set_mode(struct mode_inf |
1842 |
+ ax = 0x4f01; |
1843 |
+ cx = vesa_mode; |
1844 |
+ di = (size_t)&vminfo; |
1845 |
+- asm(INT10 |
1846 |
++ asm volatile(INT10 |
1847 |
+ : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo) |
1848 |
+ : : "ebx", "edx", "esi"); |
1849 |
+ |
1850 |
+@@ -193,19 +193,20 @@ static void vesa_dac_set_8bits(void) |
1851 |
+ /* Save the VESA protected mode info */ |
1852 |
+ static void vesa_store_pm_info(void) |
1853 |
+ { |
1854 |
+- u16 ax, bx, di, es; |
1855 |
++ u16 ax, bx, cx, di, es; |
1856 |
+ |
1857 |
+ ax = 0x4f0a; |
1858 |
+- bx = di = 0; |
1859 |
+- asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es" |
1860 |
+- : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di) |
1861 |
+- : : "ecx", "esi"); |
1862 |
++ bx = cx = di = 0; |
1863 |
++ asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es" |
1864 |
++ : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di) |
1865 |
++ : : "esi"); |
1866 |
+ |
1867 |
+ if (ax != 0x004f) |
1868 |
+ return; |
1869 |
+ |
1870 |
+ boot_params.screen_info.vesapm_seg = es; |
1871 |
+ boot_params.screen_info.vesapm_off = di; |
1872 |
++ boot_params.screen_info.vesapm_size = cx; |
1873 |
+ } |
1874 |
+ |
1875 |
+ /* |
1876 |
+@@ -259,7 +260,7 @@ void vesa_store_edid(void) |
1877 |
+ /* Note: The VBE DDC spec is different from the main VESA spec; |
1878 |
+ we genuinely have to assume all registers are destroyed here. */ |
1879 |
+ |
1880 |
+- asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" |
1881 |
++ asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es" |
1882 |
+ : "+a" (ax), "+b" (bx) |
1883 |
+ : "c" (cx), "D" (di) |
1884 |
+ : "esi"); |
1885 |
+@@ -275,7 +276,7 @@ void vesa_store_edid(void) |
1886 |
+ cx = 0; /* Controller 0 */ |
1887 |
+ dx = 0; /* EDID block number */ |
1888 |
+ di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ |
1889 |
+- asm(INT10 |
1890 |
++ asm volatile(INT10 |
1891 |
+ : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info) |
1892 |
+ : "c" (cx), "D" (di) |
1893 |
+ : "esi"); |
1894 |
+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 |
1895 |
+--- linux-2.6.23.15/arch/i386/boot/video-vga.c 2007-10-09 21:31:38.000000000 +0100 |
1896 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/video-vga.c 2008-02-11 10:37:44.000000000 +0000 |
1897 |
+@@ -225,7 +225,7 @@ static int vga_probe(void) |
1898 |
+ }; |
1899 |
+ u8 vga_flag; |
1900 |
+ |
1901 |
+- asm(INT10 |
1902 |
++ asm volatile(INT10 |
1903 |
+ : "=b" (boot_params.screen_info.orig_video_ega_bx) |
1904 |
+ : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */ |
1905 |
+ : "ecx", "edx", "esi", "edi"); |
1906 |
+@@ -233,7 +233,7 @@ static int vga_probe(void) |
1907 |
+ /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */ |
1908 |
+ if ((u8)boot_params.screen_info.orig_video_ega_bx != 0x10) { |
1909 |
+ /* EGA/VGA */ |
1910 |
+- asm(INT10 |
1911 |
++ asm volatile(INT10 |
1912 |
+ : "=a" (vga_flag) |
1913 |
+ : "a" (0x1a00) |
1914 |
+ : "ebx", "ecx", "edx", "esi", "edi"); |
1915 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/video.c linux-2.6.23.15-grsec/arch/i386/boot/video.c |
1916 |
+--- linux-2.6.23.15/arch/i386/boot/video.c 2008-02-11 10:36:03.000000000 +0000 |
1917 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/video.c 2008-02-11 10:37:44.000000000 +0000 |
1918 |
+@@ -40,7 +40,7 @@ static void store_cursor_position(void) |
1919 |
+ |
1920 |
+ ax = 0x0300; |
1921 |
+ bx = 0; |
1922 |
+- asm(INT10 |
1923 |
++ asm volatile(INT10 |
1924 |
+ : "=d" (curpos), "+a" (ax), "+b" (bx) |
1925 |
+ : : "ecx", "esi", "edi"); |
1926 |
+ |
1927 |
+@@ -55,7 +55,7 @@ static void store_video_mode(void) |
1928 |
+ /* N.B.: the saving of the video page here is a bit silly, |
1929 |
+ since we pretty much assume page 0 everywhere. */ |
1930 |
+ ax = 0x0f00; |
1931 |
+- asm(INT10 |
1932 |
++ asm volatile(INT10 |
1933 |
+ : "+a" (ax), "=b" (page) |
1934 |
+ : : "ecx", "edx", "esi", "edi"); |
1935 |
+ |
1936 |
+diff -Nurp linux-2.6.23.15/arch/i386/boot/voyager.c linux-2.6.23.15-grsec/arch/i386/boot/voyager.c |
1937 |
+--- linux-2.6.23.15/arch/i386/boot/voyager.c 2007-10-09 21:31:38.000000000 +0100 |
1938 |
++++ linux-2.6.23.15-grsec/arch/i386/boot/voyager.c 2008-02-11 10:37:44.000000000 +0000 |
1939 |
+@@ -27,7 +27,7 @@ int query_voyager(void) |
1940 |
+ |
1941 |
+ data_ptr[0] = 0xff; /* Flag on config not found(?) */ |
1942 |
+ |
1943 |
+- asm("pushw %%es ; " |
1944 |
++ asm volatile("pushw %%es ; " |
1945 |
+ "int $0x15 ; " |
1946 |
+ "setc %0 ; " |
1947 |
+ "movw %%es, %1 ; " |
1948 |
+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 |
1949 |
+--- linux-2.6.23.15/arch/i386/kernel/acpi/boot.c 2007-10-09 21:31:38.000000000 +0100 |
1950 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/boot.c 2008-02-11 10:37:44.000000000 +0000 |
1951 |
+@@ -1123,7 +1123,7 @@ static struct dmi_system_id __initdata a |
1952 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
1953 |
+ }, |
1954 |
+ }, |
1955 |
+- {} |
1956 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
1957 |
+ }; |
1958 |
+ |
1959 |
+ #endif /* __i386__ */ |
1960 |
+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 |
1961 |
+--- linux-2.6.23.15/arch/i386/kernel/acpi/sleep.c 2007-10-09 21:31:38.000000000 +0100 |
1962 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/sleep.c 2008-02-11 10:37:44.000000000 +0000 |
1963 |
+@@ -98,7 +98,7 @@ static __initdata struct dmi_system_id a |
1964 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"), |
1965 |
+ }, |
1966 |
+ }, |
1967 |
+- {} |
1968 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
1969 |
+ }; |
1970 |
+ |
1971 |
+ static int __init acpisleep_dmi_init(void) |
1972 |
+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 |
1973 |
+--- linux-2.6.23.15/arch/i386/kernel/acpi/wakeup.S 2007-10-09 21:31:38.000000000 +0100 |
1974 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/acpi/wakeup.S 2008-02-11 10:37:44.000000000 +0000 |
1975 |
+@@ -2,6 +2,7 @@ |
1976 |
+ #include <linux/linkage.h> |
1977 |
+ #include <asm/segment.h> |
1978 |
+ #include <asm/page.h> |
1979 |
++#include <asm/msr-index.h> |
1980 |
+ |
1981 |
+ # |
1982 |
+ # wakeup_code runs in real mode, and at unknown address (determined at run-time). |
1983 |
+@@ -84,7 +85,7 @@ wakeup_code: |
1984 |
+ # restore efer setting |
1985 |
+ movl real_save_efer_edx - wakeup_code, %edx |
1986 |
+ movl real_save_efer_eax - wakeup_code, %eax |
1987 |
+- mov $0xc0000080, %ecx |
1988 |
++ mov $MSR_EFER, %ecx |
1989 |
+ wrmsr |
1990 |
+ 4: |
1991 |
+ # make sure %cr4 is set correctly (features, etc) |
1992 |
+@@ -209,13 +210,11 @@ wakeup_pmode_return: |
1993 |
+ # and restore the stack ... but you need gdt for this to work |
1994 |
+ movl saved_context_esp, %esp |
1995 |
+ |
1996 |
+- movl %cs:saved_magic, %eax |
1997 |
+- cmpl $0x12345678, %eax |
1998 |
++ cmpl $0x12345678, saved_magic |
1999 |
+ jne bogus_magic |
2000 |
+ |
2001 |
+ # jump to place where we left off |
2002 |
+- movl saved_eip,%eax |
2003 |
+- jmp *%eax |
2004 |
++ jmp *(saved_eip) |
2005 |
+ |
2006 |
+ bogus_magic: |
2007 |
+ movw $0x0e00 + 'B', 0xb8018 |
2008 |
+@@ -247,7 +246,7 @@ ENTRY(acpi_copy_wakeup_routine) |
2009 |
+ # save efer setting |
2010 |
+ pushl %eax |
2011 |
+ movl %eax, %ebx |
2012 |
+- mov $0xc0000080, %ecx |
2013 |
++ mov $MSR_EFER, %ecx |
2014 |
+ rdmsr |
2015 |
+ movl %edx, real_save_efer_edx - wakeup_start (%ebx) |
2016 |
+ movl %eax, real_save_efer_eax - wakeup_start (%ebx) |
2017 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/alternative.c linux-2.6.23.15-grsec/arch/i386/kernel/alternative.c |
2018 |
+--- linux-2.6.23.15/arch/i386/kernel/alternative.c 2007-10-09 21:31:38.000000000 +0100 |
2019 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/alternative.c 2008-02-11 10:37:44.000000000 +0000 |
2020 |
+@@ -443,7 +443,20 @@ void __init alternative_instructions(voi |
2021 |
+ */ |
2022 |
+ void __kprobes text_poke(void *addr, unsigned char *opcode, int len) |
2023 |
+ { |
2024 |
++ |
2025 |
++#ifdef CONFIG_PAX_KERNEXEC |
2026 |
++ unsigned long cr0; |
2027 |
++ |
2028 |
++ pax_open_kernel(cr0); |
2029 |
++#endif |
2030 |
++ |
2031 |
++ addr += __KERNEL_TEXT_OFFSET; |
2032 |
+ memcpy(addr, opcode, len); |
2033 |
++ |
2034 |
++#ifdef CONFIG_PAX_KERNEXEC |
2035 |
++ pax_close_kernel(cr0); |
2036 |
++#endif |
2037 |
++ |
2038 |
+ sync_core(); |
2039 |
+ /* Could also do a CLFLUSH here to speed up CPU recovery; but |
2040 |
+ that causes hangs on some VIA CPUs. */ |
2041 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/apm.c linux-2.6.23.15-grsec/arch/i386/kernel/apm.c |
2042 |
+--- linux-2.6.23.15/arch/i386/kernel/apm.c 2008-02-11 10:36:03.000000000 +0000 |
2043 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/apm.c 2008-02-11 10:37:44.000000000 +0000 |
2044 |
+@@ -407,7 +407,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq |
2045 |
+ static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); |
2046 |
+ static struct apm_user * user_list; |
2047 |
+ static DEFINE_SPINLOCK(user_list_lock); |
2048 |
+-static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
2049 |
++static const struct desc_struct bad_bios_desc = { 0, 0x00409300 }; |
2050 |
+ |
2051 |
+ static const char driver_version[] = "1.16ac"; /* no spaces */ |
2052 |
+ |
2053 |
+@@ -601,19 +601,42 @@ static u8 apm_bios_call(u32 func, u32 eb |
2054 |
+ struct desc_struct save_desc_40; |
2055 |
+ struct desc_struct *gdt; |
2056 |
+ |
2057 |
++#ifdef CONFIG_PAX_KERNEXEC |
2058 |
++ unsigned long cr0; |
2059 |
++#endif |
2060 |
++ |
2061 |
+ cpus = apm_save_cpus(); |
2062 |
+ |
2063 |
+ cpu = get_cpu(); |
2064 |
+ gdt = get_cpu_gdt_table(cpu); |
2065 |
+ save_desc_40 = gdt[0x40 / 8]; |
2066 |
++ |
2067 |
++#ifdef CONFIG_PAX_KERNEXEC |
2068 |
++ pax_open_kernel(cr0); |
2069 |
++#endif |
2070 |
++ |
2071 |
+ gdt[0x40 / 8] = bad_bios_desc; |
2072 |
+ |
2073 |
++#ifdef CONFIG_PAX_KERNEXEC |
2074 |
++ pax_close_kernel(cr0); |
2075 |
++#endif |
2076 |
++ |
2077 |
+ apm_irq_save(flags); |
2078 |
+ APM_DO_SAVE_SEGS; |
2079 |
+ apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); |
2080 |
+ APM_DO_RESTORE_SEGS; |
2081 |
+ apm_irq_restore(flags); |
2082 |
++ |
2083 |
++#ifdef CONFIG_PAX_KERNEXEC |
2084 |
++ pax_open_kernel(cr0); |
2085 |
++#endif |
2086 |
++ |
2087 |
+ gdt[0x40 / 8] = save_desc_40; |
2088 |
++ |
2089 |
++#ifdef CONFIG_PAX_KERNEXEC |
2090 |
++ pax_close_kernel(cr0); |
2091 |
++#endif |
2092 |
++ |
2093 |
+ put_cpu(); |
2094 |
+ apm_restore_cpus(cpus); |
2095 |
+ |
2096 |
+@@ -644,19 +667,42 @@ static u8 apm_bios_call_simple(u32 func, |
2097 |
+ struct desc_struct save_desc_40; |
2098 |
+ struct desc_struct *gdt; |
2099 |
+ |
2100 |
++#ifdef CONFIG_PAX_KERNEXEC |
2101 |
++ unsigned long cr0; |
2102 |
++#endif |
2103 |
++ |
2104 |
+ cpus = apm_save_cpus(); |
2105 |
+ |
2106 |
+ cpu = get_cpu(); |
2107 |
+ gdt = get_cpu_gdt_table(cpu); |
2108 |
+ save_desc_40 = gdt[0x40 / 8]; |
2109 |
++ |
2110 |
++#ifdef CONFIG_PAX_KERNEXEC |
2111 |
++ pax_open_kernel(cr0); |
2112 |
++#endif |
2113 |
++ |
2114 |
+ gdt[0x40 / 8] = bad_bios_desc; |
2115 |
+ |
2116 |
++#ifdef CONFIG_PAX_KERNEXEC |
2117 |
++ pax_close_kernel(cr0); |
2118 |
++#endif |
2119 |
++ |
2120 |
+ apm_irq_save(flags); |
2121 |
+ APM_DO_SAVE_SEGS; |
2122 |
+ error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); |
2123 |
+ APM_DO_RESTORE_SEGS; |
2124 |
+ apm_irq_restore(flags); |
2125 |
++ |
2126 |
++#ifdef CONFIG_PAX_KERNEXEC |
2127 |
++ pax_open_kernel(cr0); |
2128 |
++#endif |
2129 |
++ |
2130 |
+ gdt[0x40 / 8] = save_desc_40; |
2131 |
++ |
2132 |
++#ifdef CONFIG_PAX_KERNEXEC |
2133 |
++ pax_close_kernel(cr0); |
2134 |
++#endif |
2135 |
++ |
2136 |
+ put_cpu(); |
2137 |
+ apm_restore_cpus(cpus); |
2138 |
+ return error; |
2139 |
+@@ -924,7 +970,7 @@ recalc: |
2140 |
+ |
2141 |
+ static void apm_power_off(void) |
2142 |
+ { |
2143 |
+- unsigned char po_bios_call[] = { |
2144 |
++ const unsigned char po_bios_call[] = { |
2145 |
+ 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ |
2146 |
+ 0x8e, 0xd0, /* movw ax,ss */ |
2147 |
+ 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ |
2148 |
+@@ -1864,7 +1910,10 @@ static const struct file_operations apm_ |
2149 |
+ static struct miscdevice apm_device = { |
2150 |
+ APM_MINOR_DEV, |
2151 |
+ "apm_bios", |
2152 |
+- &apm_bios_fops |
2153 |
++ &apm_bios_fops, |
2154 |
++ {NULL, NULL}, |
2155 |
++ NULL, |
2156 |
++ NULL |
2157 |
+ }; |
2158 |
+ |
2159 |
+ |
2160 |
+@@ -1974,210 +2023,210 @@ static struct dmi_system_id __initdata a |
2161 |
+ print_if_true, |
2162 |
+ KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.", |
2163 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), |
2164 |
+- DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, |
2165 |
++ DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL |
2166 |
+ }, |
2167 |
+ { /* Handle problems with APM on the C600 */ |
2168 |
+ broken_ps2_resume, "Dell Latitude C600", |
2169 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "Dell"), |
2170 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, |
2171 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL |
2172 |
+ }, |
2173 |
+ { /* Allow interrupts during suspend on Dell Latitude laptops*/ |
2174 |
+ set_apm_ints, "Dell Latitude", |
2175 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
2176 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), } |
2177 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL |
2178 |
+ }, |
2179 |
+ { /* APM crashes */ |
2180 |
+ apm_is_horked, "Dell Inspiron 2500", |
2181 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
2182 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"), |
2183 |
+ DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
2184 |
+- DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, |
2185 |
++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL |
2186 |
+ }, |
2187 |
+ { /* Allow interrupts during suspend on Dell Inspiron laptops*/ |
2188 |
+ set_apm_ints, "Dell Inspiron", { |
2189 |
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
2190 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, |
2191 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL |
2192 |
+ }, |
2193 |
+ { /* Handle problems with APM on Inspiron 5000e */ |
2194 |
+ broken_apm_power, "Dell Inspiron 5000e", |
2195 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2196 |
+ DMI_MATCH(DMI_BIOS_VERSION, "A04"), |
2197 |
+- DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, |
2198 |
++ DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL |
2199 |
+ }, |
2200 |
+ { /* Handle problems with APM on Inspiron 2500 */ |
2201 |
+ broken_apm_power, "Dell Inspiron 2500", |
2202 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2203 |
+ DMI_MATCH(DMI_BIOS_VERSION, "A12"), |
2204 |
+- DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, |
2205 |
++ DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL |
2206 |
+ }, |
2207 |
+ { /* APM crashes */ |
2208 |
+ apm_is_horked, "Dell Dimension 4100", |
2209 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
2210 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), |
2211 |
+ DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."), |
2212 |
+- DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, |
2213 |
++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL |
2214 |
+ }, |
2215 |
+ { /* Allow interrupts during suspend on Compaq Laptops*/ |
2216 |
+ set_apm_ints, "Compaq 12XL125", |
2217 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"), |
2218 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"), |
2219 |
+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2220 |
+- DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, |
2221 |
++ DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL |
2222 |
+ }, |
2223 |
+ { /* Allow interrupts during APM or the clock goes slow */ |
2224 |
+ set_apm_ints, "ASUSTeK", |
2225 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
2226 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, |
2227 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL |
2228 |
+ }, |
2229 |
+ { /* APM blows on shutdown */ |
2230 |
+ apm_is_horked, "ABIT KX7-333[R]", |
2231 |
+ { DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"), |
2232 |
+- DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, |
2233 |
++ DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL |
2234 |
+ }, |
2235 |
+ { /* APM crashes */ |
2236 |
+ apm_is_horked, "Trigem Delhi3", |
2237 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"), |
2238 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, |
2239 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL |
2240 |
+ }, |
2241 |
+ { /* APM crashes */ |
2242 |
+ apm_is_horked, "Fujitsu-Siemens", |
2243 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"), |
2244 |
+- DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, |
2245 |
++ DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL |
2246 |
+ }, |
2247 |
+ { /* APM crashes */ |
2248 |
+ apm_is_horked_d850md, "Intel D850MD", |
2249 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."), |
2250 |
+- DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, |
2251 |
++ DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL |
2252 |
+ }, |
2253 |
+ { /* APM crashes */ |
2254 |
+ apm_is_horked, "Intel D810EMO", |
2255 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."), |
2256 |
+- DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, |
2257 |
++ DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL |
2258 |
+ }, |
2259 |
+ { /* APM crashes */ |
2260 |
+ apm_is_horked, "Dell XPS-Z", |
2261 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."), |
2262 |
+ DMI_MATCH(DMI_BIOS_VERSION, "A11"), |
2263 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, |
2264 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL |
2265 |
+ }, |
2266 |
+ { /* APM crashes */ |
2267 |
+ apm_is_horked, "Sharp PC-PJ/AX", |
2268 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"), |
2269 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"), |
2270 |
+ DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"), |
2271 |
+- DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, |
2272 |
++ DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL |
2273 |
+ }, |
2274 |
+ { /* APM crashes */ |
2275 |
+ apm_is_horked, "Dell Inspiron 2500", |
2276 |
+ { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), |
2277 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"), |
2278 |
+ DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
2279 |
+- DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, |
2280 |
++ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL |
2281 |
+ }, |
2282 |
+ { /* APM idle hangs */ |
2283 |
+ apm_likes_to_melt, "Jabil AMD", |
2284 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), |
2285 |
+- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, |
2286 |
++ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL |
2287 |
+ }, |
2288 |
+ { /* APM idle hangs */ |
2289 |
+ apm_likes_to_melt, "AMI Bios", |
2290 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), |
2291 |
+- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, |
2292 |
++ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL |
2293 |
+ }, |
2294 |
+ { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */ |
2295 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2296 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2297 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0206H"), |
2298 |
+- DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, |
2299 |
++ DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL |
2300 |
+ }, |
2301 |
+ { /* Handle problems with APM on Sony Vaio PCG-N505VX */ |
2302 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2303 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2304 |
+ DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"), |
2305 |
+- DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, |
2306 |
++ DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL |
2307 |
+ }, |
2308 |
+ { /* Handle problems with APM on Sony Vaio PCG-XG29 */ |
2309 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2310 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2311 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"), |
2312 |
+- DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, |
2313 |
++ DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL |
2314 |
+ }, |
2315 |
+ { /* Handle problems with APM on Sony Vaio PCG-Z600NE */ |
2316 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2317 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2318 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"), |
2319 |
+- DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, |
2320 |
++ DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL |
2321 |
+ }, |
2322 |
+ { /* Handle problems with APM on Sony Vaio PCG-Z600NE */ |
2323 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2324 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2325 |
+ DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"), |
2326 |
+- DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, |
2327 |
++ DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL |
2328 |
+ }, |
2329 |
+ { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */ |
2330 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2331 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2332 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"), |
2333 |
+- DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, |
2334 |
++ DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL |
2335 |
+ }, |
2336 |
+ { /* Handle problems with APM on Sony Vaio PCG-Z505LS */ |
2337 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2338 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2339 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"), |
2340 |
+- DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, |
2341 |
++ DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL |
2342 |
+ }, |
2343 |
+ { /* Handle problems with APM on Sony Vaio PCG-Z505LS */ |
2344 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2345 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2346 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"), |
2347 |
+- DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, |
2348 |
++ DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL |
2349 |
+ }, |
2350 |
+ { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */ |
2351 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2352 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2353 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"), |
2354 |
+- DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, |
2355 |
++ DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL |
2356 |
+ }, |
2357 |
+ { /* Handle problems with APM on Sony Vaio PCG-F104K */ |
2358 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2359 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2360 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"), |
2361 |
+- DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, |
2362 |
++ DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL |
2363 |
+ }, |
2364 |
+ |
2365 |
+ { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */ |
2366 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2367 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2368 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"), |
2369 |
+- DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, |
2370 |
++ DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL |
2371 |
+ }, |
2372 |
+ { /* Handle problems with APM on Sony Vaio PCG-C1VE */ |
2373 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2374 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2375 |
+ DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"), |
2376 |
+- DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, |
2377 |
++ DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL |
2378 |
+ }, |
2379 |
+ { /* Handle problems with APM on Sony Vaio PCG-C1VE */ |
2380 |
+ swab_apm_power_in_minutes, "Sony VAIO", |
2381 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), |
2382 |
+ DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"), |
2383 |
+- DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, |
2384 |
++ DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL |
2385 |
+ }, |
2386 |
+ { /* broken PM poweroff bios */ |
2387 |
+ set_realmode_power_off, "Award Software v4.60 PGMA", |
2388 |
+ { DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."), |
2389 |
+ DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"), |
2390 |
+- DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, |
2391 |
++ DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL |
2392 |
+ }, |
2393 |
+ |
2394 |
+ /* Generic per vendor APM settings */ |
2395 |
+ |
2396 |
+ { /* Allow interrupts during suspend on IBM laptops */ |
2397 |
+ set_apm_ints, "IBM", |
2398 |
+- { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, |
2399 |
++ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL |
2400 |
+ }, |
2401 |
+ |
2402 |
+- { } |
2403 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL} |
2404 |
+ }; |
2405 |
+ |
2406 |
+ /* |
2407 |
+@@ -2196,6 +2245,10 @@ static int __init apm_init(void) |
2408 |
+ struct desc_struct *gdt; |
2409 |
+ int err; |
2410 |
+ |
2411 |
++#ifdef CONFIG_PAX_KERNEXEC |
2412 |
++ unsigned long cr0; |
2413 |
++#endif |
2414 |
++ |
2415 |
+ dmi_check_system(apm_dmi_table); |
2416 |
+ |
2417 |
+ if (apm_info.bios.version == 0 || paravirt_enabled()) { |
2418 |
+@@ -2269,9 +2322,18 @@ static int __init apm_init(void) |
2419 |
+ * This is for buggy BIOS's that refer to (real mode) segment 0x40 |
2420 |
+ * even though they are called in protected mode. |
2421 |
+ */ |
2422 |
++ |
2423 |
++#ifdef CONFIG_PAX_KERNEXEC |
2424 |
++ pax_open_kernel(cr0); |
2425 |
++#endif |
2426 |
++ |
2427 |
+ set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
2428 |
+ _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
2429 |
+ |
2430 |
++#ifdef CONFIG_PAX_KERNEXEC |
2431 |
++ pax_close_kernel(cr0); |
2432 |
++#endif |
2433 |
++ |
2434 |
+ /* |
2435 |
+ * Set up the long jump entry point to the APM BIOS, which is called |
2436 |
+ * from inline assembly. |
2437 |
+@@ -2290,6 +2352,11 @@ static int __init apm_init(void) |
2438 |
+ * code to that CPU. |
2439 |
+ */ |
2440 |
+ gdt = get_cpu_gdt_table(0); |
2441 |
++ |
2442 |
++#ifdef CONFIG_PAX_KERNEXEC |
2443 |
++ pax_open_kernel(cr0); |
2444 |
++#endif |
2445 |
++ |
2446 |
+ set_base(gdt[APM_CS >> 3], |
2447 |
+ __va((unsigned long)apm_info.bios.cseg << 4)); |
2448 |
+ set_base(gdt[APM_CS_16 >> 3], |
2449 |
+@@ -2297,6 +2364,10 @@ static int __init apm_init(void) |
2450 |
+ set_base(gdt[APM_DS >> 3], |
2451 |
+ __va((unsigned long)apm_info.bios.dseg << 4)); |
2452 |
+ |
2453 |
++#ifdef CONFIG_PAX_KERNEXEC |
2454 |
++ pax_close_kernel(cr0); |
2455 |
++#endif |
2456 |
++ |
2457 |
+ apm_proc = create_proc_entry("apm", 0, NULL); |
2458 |
+ if (apm_proc) |
2459 |
+ apm_proc->proc_fops = &apm_file_ops; |
2460 |
+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 |
2461 |
+--- linux-2.6.23.15/arch/i386/kernel/asm-offsets.c 2007-10-09 21:31:38.000000000 +0100 |
2462 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/asm-offsets.c 2008-02-11 10:37:44.000000000 +0000 |
2463 |
+@@ -109,6 +109,7 @@ void foo(void) |
2464 |
+ DEFINE(PTRS_PER_PTE, PTRS_PER_PTE); |
2465 |
+ DEFINE(PTRS_PER_PMD, PTRS_PER_PMD); |
2466 |
+ DEFINE(PTRS_PER_PGD, PTRS_PER_PGD); |
2467 |
++ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE); |
2468 |
+ |
2469 |
+ DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK); |
2470 |
+ |
2471 |
+@@ -122,6 +123,7 @@ void foo(void) |
2472 |
+ OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit); |
2473 |
+ OFFSET(PARAVIRT_iret, paravirt_ops, iret); |
2474 |
+ OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0); |
2475 |
++ OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0); |
2476 |
+ #endif |
2477 |
+ |
2478 |
+ #ifdef CONFIG_XEN |
2479 |
+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 |
2480 |
+--- linux-2.6.23.15/arch/i386/kernel/cpu/common.c 2007-10-09 21:31:38.000000000 +0100 |
2481 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/common.c 2008-02-11 10:37:44.000000000 +0000 |
2482 |
+@@ -4,7 +4,6 @@ |
2483 |
+ #include <linux/smp.h> |
2484 |
+ #include <linux/module.h> |
2485 |
+ #include <linux/percpu.h> |
2486 |
+-#include <linux/bootmem.h> |
2487 |
+ #include <asm/semaphore.h> |
2488 |
+ #include <asm/processor.h> |
2489 |
+ #include <asm/i387.h> |
2490 |
+@@ -21,39 +20,15 @@ |
2491 |
+ |
2492 |
+ #include "cpu.h" |
2493 |
+ |
2494 |
+-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { |
2495 |
+- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 }, |
2496 |
+- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 }, |
2497 |
+- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 }, |
2498 |
+- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 }, |
2499 |
+- /* |
2500 |
+- * Segments used for calling PnP BIOS have byte granularity. |
2501 |
+- * They code segments and data segments have fixed 64k limits, |
2502 |
+- * the transfer segment sizes are set at run time. |
2503 |
+- */ |
2504 |
+- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ |
2505 |
+- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */ |
2506 |
+- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */ |
2507 |
+- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */ |
2508 |
+- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */ |
2509 |
+- /* |
2510 |
+- * The APM segments have byte granularity and their bases |
2511 |
+- * are set at run time. All have 64k limits. |
2512 |
+- */ |
2513 |
+- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */ |
2514 |
+- /* 16-bit code */ |
2515 |
+- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 }, |
2516 |
+- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */ |
2517 |
+- |
2518 |
+- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 }, |
2519 |
+- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 }, |
2520 |
+-} }; |
2521 |
+-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page); |
2522 |
+- |
2523 |
+ static int cachesize_override __cpuinitdata = -1; |
2524 |
+ static int disable_x86_fxsr __cpuinitdata; |
2525 |
+ static int disable_x86_serial_nr __cpuinitdata = 1; |
2526 |
+-static int disable_x86_sep __cpuinitdata; |
2527 |
++ |
2528 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) |
2529 |
++int disable_x86_sep __cpuinitdata = 1; |
2530 |
++#else |
2531 |
++int disable_x86_sep __cpuinitdata; |
2532 |
++#endif |
2533 |
+ |
2534 |
+ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; |
2535 |
+ |
2536 |
+@@ -261,10 +236,10 @@ static int __cpuinit have_cpuid_p(void) |
2537 |
+ void __init cpu_detect(struct cpuinfo_x86 *c) |
2538 |
+ { |
2539 |
+ /* Get vendor name */ |
2540 |
+- cpuid(0x00000000, &c->cpuid_level, |
2541 |
+- (int *)&c->x86_vendor_id[0], |
2542 |
+- (int *)&c->x86_vendor_id[8], |
2543 |
+- (int *)&c->x86_vendor_id[4]); |
2544 |
++ cpuid(0x00000000, (unsigned int *)&c->cpuid_level, |
2545 |
++ (unsigned int *)&c->x86_vendor_id[0], |
2546 |
++ (unsigned int *)&c->x86_vendor_id[8], |
2547 |
++ (unsigned int *)&c->x86_vendor_id[4]); |
2548 |
+ |
2549 |
+ c->x86 = 4; |
2550 |
+ if (c->cpuid_level >= 0x00000001) { |
2551 |
+@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void |
2552 |
+ |
2553 |
+ static void __cpuinit generic_identify(struct cpuinfo_x86 * c) |
2554 |
+ { |
2555 |
+- u32 tfms, xlvl; |
2556 |
+- int ebx; |
2557 |
++ u32 tfms, xlvl, ebx; |
2558 |
+ |
2559 |
+ if (have_cpuid_p()) { |
2560 |
+ /* Get vendor name */ |
2561 |
+- cpuid(0x00000000, &c->cpuid_level, |
2562 |
+- (int *)&c->x86_vendor_id[0], |
2563 |
+- (int *)&c->x86_vendor_id[8], |
2564 |
+- (int *)&c->x86_vendor_id[4]); |
2565 |
++ cpuid(0x00000000, (unsigned int *)&c->cpuid_level, |
2566 |
++ (unsigned int *)&c->x86_vendor_id[0], |
2567 |
++ (unsigned int *)&c->x86_vendor_id[8], |
2568 |
++ (unsigned int *)&c->x86_vendor_id[4]); |
2569 |
+ |
2570 |
+ get_cpu_vendor(c, 0); |
2571 |
+ /* Initialize the standard set of capabilities */ |
2572 |
+@@ -644,7 +618,7 @@ void switch_to_new_gdt(void) |
2573 |
+ { |
2574 |
+ struct Xgt_desc_struct gdt_descr; |
2575 |
+ |
2576 |
+- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id()); |
2577 |
++ gdt_descr.address = get_cpu_gdt_table(smp_processor_id()); |
2578 |
+ gdt_descr.size = GDT_SIZE - 1; |
2579 |
+ load_gdt(&gdt_descr); |
2580 |
+ asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory"); |
2581 |
+@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void) |
2582 |
+ { |
2583 |
+ int cpu = smp_processor_id(); |
2584 |
+ struct task_struct *curr = current; |
2585 |
+- struct tss_struct * t = &per_cpu(init_tss, cpu); |
2586 |
++ struct tss_struct *t = init_tss + cpu; |
2587 |
+ struct thread_struct *thread = &curr->thread; |
2588 |
+ |
2589 |
+ if (cpu_test_and_set(cpu, cpu_initialized)) { |
2590 |
+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 |
2591 |
+--- linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-10-09 21:31:38.000000000 +0100 |
2592 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2008-02-11 10:37:44.000000000 +0000 |
2593 |
+@@ -549,7 +549,7 @@ static struct dmi_system_id sw_any_bug_d |
2594 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"), |
2595 |
+ }, |
2596 |
+ }, |
2597 |
+- { } |
2598 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
2599 |
+ }; |
2600 |
+ #endif |
2601 |
+ |
2602 |
+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 |
2603 |
+--- linux-2.6.23.15/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-10-09 21:31:38.000000000 +0100 |
2604 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2008-02-11 10:37:44.000000000 +0000 |
2605 |
+@@ -223,7 +223,7 @@ static struct cpu_model models[] = |
2606 |
+ { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL }, |
2607 |
+ { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL }, |
2608 |
+ |
2609 |
+- { NULL, } |
2610 |
++ { NULL, NULL, 0, NULL} |
2611 |
+ }; |
2612 |
+ #undef _BANIAS |
2613 |
+ #undef BANIAS |
2614 |
+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 |
2615 |
+--- linux-2.6.23.15/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-10-09 21:31:38.000000000 +0100 |
2616 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/intel_cacheinfo.c 2008-02-11 10:37:44.000000000 +0000 |
2617 |
+@@ -351,8 +351,8 @@ unsigned int __cpuinit init_intel_cachei |
2618 |
+ */ |
2619 |
+ if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { |
2620 |
+ /* supports eax=2 call */ |
2621 |
+- int i, j, n; |
2622 |
+- int regs[4]; |
2623 |
++ int j, n; |
2624 |
++ unsigned int regs[4]; |
2625 |
+ unsigned char *dp = (unsigned char *)regs; |
2626 |
+ int only_trace = 0; |
2627 |
+ |
2628 |
+@@ -367,7 +367,7 @@ unsigned int __cpuinit init_intel_cachei |
2629 |
+ |
2630 |
+ /* If bit 31 is set, this is an unknown format */ |
2631 |
+ for ( j = 0 ; j < 3 ; j++ ) { |
2632 |
+- if ( regs[j] < 0 ) regs[j] = 0; |
2633 |
++ if ( (int)regs[j] < 0 ) regs[j] = 0; |
2634 |
+ } |
2635 |
+ |
2636 |
+ /* Byte 0 is level count, not a descriptor */ |
2637 |
+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 |
2638 |
+--- linux-2.6.23.15/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-10-09 21:31:38.000000000 +0100 |
2639 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mcheck/therm_throt.c 2008-02-11 10:37:44.000000000 +0000 |
2640 |
+@@ -152,7 +152,7 @@ static __cpuinit int thermal_throttle_cp |
2641 |
+ return NOTIFY_OK; |
2642 |
+ } |
2643 |
+ |
2644 |
+-static struct notifier_block thermal_throttle_cpu_notifier = |
2645 |
++static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier = |
2646 |
+ { |
2647 |
+ .notifier_call = thermal_throttle_cpu_callback, |
2648 |
+ }; |
2649 |
+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 |
2650 |
+--- linux-2.6.23.15/arch/i386/kernel/cpu/mtrr/generic.c 2007-10-09 21:31:38.000000000 +0100 |
2651 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/cpu/mtrr/generic.c 2008-02-11 10:37:44.000000000 +0000 |
2652 |
+@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra |
2653 |
+ { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */ |
2654 |
+ { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */ |
2655 |
+ { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */ |
2656 |
+- {} |
2657 |
++ { 0, 0 } |
2658 |
+ }; |
2659 |
+ |
2660 |
+ static unsigned long smp_changes_mask; |
2661 |
+-static struct mtrr_state mtrr_state = {}; |
2662 |
++static struct mtrr_state mtrr_state; |
2663 |
+ |
2664 |
+ #undef MODULE_PARAM_PREFIX |
2665 |
+ #define MODULE_PARAM_PREFIX "mtrr." |
2666 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/crash.c linux-2.6.23.15-grsec/arch/i386/kernel/crash.c |
2667 |
+--- linux-2.6.23.15/arch/i386/kernel/crash.c 2007-10-09 21:31:38.000000000 +0100 |
2668 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/crash.c 2008-02-11 10:37:44.000000000 +0000 |
2669 |
+@@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not |
2670 |
+ return NOTIFY_STOP; |
2671 |
+ local_irq_disable(); |
2672 |
+ |
2673 |
+- if (!user_mode_vm(regs)) { |
2674 |
++ if (!user_mode(regs)) { |
2675 |
+ crash_fixup_ss_esp(&fixed_regs, regs); |
2676 |
+ regs = &fixed_regs; |
2677 |
+ } |
2678 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/doublefault.c linux-2.6.23.15-grsec/arch/i386/kernel/doublefault.c |
2679 |
+--- linux-2.6.23.15/arch/i386/kernel/doublefault.c 2007-10-09 21:31:38.000000000 +0100 |
2680 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/doublefault.c 2008-02-11 10:37:44.000000000 +0000 |
2681 |
+@@ -11,17 +11,17 @@ |
2682 |
+ |
2683 |
+ #define DOUBLEFAULT_STACKSIZE (1024) |
2684 |
+ static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE]; |
2685 |
+-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE) |
2686 |
++#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2) |
2687 |
+ |
2688 |
+ #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM) |
2689 |
+ |
2690 |
+ static void doublefault_fn(void) |
2691 |
+ { |
2692 |
+- struct Xgt_desc_struct gdt_desc = {0, 0}; |
2693 |
++ struct Xgt_desc_struct gdt_desc = {0, NULL, 0}; |
2694 |
+ unsigned long gdt, tss; |
2695 |
+ |
2696 |
+ store_gdt(&gdt_desc); |
2697 |
+- gdt = gdt_desc.address; |
2698 |
++ gdt = (unsigned long)gdt_desc.address; |
2699 |
+ |
2700 |
+ printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); |
2701 |
+ |
2702 |
+@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach |
2703 |
+ /* 0x2 bit is always set */ |
2704 |
+ .eflags = X86_EFLAGS_SF | 0x2, |
2705 |
+ .esp = STACK_START, |
2706 |
+- .es = __USER_DS, |
2707 |
++ .es = __KERNEL_DS, |
2708 |
+ .cs = __KERNEL_CS, |
2709 |
+ .ss = __KERNEL_DS, |
2710 |
+- .ds = __USER_DS, |
2711 |
++ .ds = __KERNEL_DS, |
2712 |
+ .fs = __KERNEL_PERCPU, |
2713 |
+ |
2714 |
+ .__cr3 = __pa(swapper_pg_dir) |
2715 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/efi.c linux-2.6.23.15-grsec/arch/i386/kernel/efi.c |
2716 |
+--- linux-2.6.23.15/arch/i386/kernel/efi.c 2007-10-09 21:31:38.000000000 +0100 |
2717 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/efi.c 2008-02-11 10:37:44.000000000 +0000 |
2718 |
+@@ -63,45 +63,23 @@ extern void * boot_ioremap(unsigned long |
2719 |
+ |
2720 |
+ static unsigned long efi_rt_eflags; |
2721 |
+ static DEFINE_SPINLOCK(efi_rt_lock); |
2722 |
+-static pgd_t efi_bak_pg_dir_pointer[2]; |
2723 |
++static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096))); |
2724 |
+ |
2725 |
+ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) |
2726 |
+ { |
2727 |
+- unsigned long cr4; |
2728 |
+- unsigned long temp; |
2729 |
+ struct Xgt_desc_struct gdt_descr; |
2730 |
+ |
2731 |
+ spin_lock(&efi_rt_lock); |
2732 |
+ local_irq_save(efi_rt_eflags); |
2733 |
+ |
2734 |
+- /* |
2735 |
+- * If I don't have PSE, I should just duplicate two entries in page |
2736 |
+- * directory. If I have PSE, I just need to duplicate one entry in |
2737 |
+- * page directory. |
2738 |
+- */ |
2739 |
+- cr4 = read_cr4(); |
2740 |
+- |
2741 |
+- if (cr4 & X86_CR4_PSE) { |
2742 |
+- efi_bak_pg_dir_pointer[0].pgd = |
2743 |
+- swapper_pg_dir[pgd_index(0)].pgd; |
2744 |
+- swapper_pg_dir[0].pgd = |
2745 |
+- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; |
2746 |
+- } else { |
2747 |
+- efi_bak_pg_dir_pointer[0].pgd = |
2748 |
+- swapper_pg_dir[pgd_index(0)].pgd; |
2749 |
+- efi_bak_pg_dir_pointer[1].pgd = |
2750 |
+- swapper_pg_dir[pgd_index(0x400000)].pgd; |
2751 |
+- swapper_pg_dir[pgd_index(0)].pgd = |
2752 |
+- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd; |
2753 |
+- temp = PAGE_OFFSET + 0x400000; |
2754 |
+- swapper_pg_dir[pgd_index(0x400000)].pgd = |
2755 |
+- swapper_pg_dir[pgd_index(temp)].pgd; |
2756 |
+- } |
2757 |
++ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS); |
2758 |
++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
2759 |
++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); |
2760 |
+ |
2761 |
+ /* |
2762 |
+ * After the lock is released, the original page table is restored. |
2763 |
+ */ |
2764 |
+- local_flush_tlb(); |
2765 |
++ __flush_tlb_all(); |
2766 |
+ |
2767 |
+ gdt_descr.address = __pa(get_cpu_gdt_table(0)); |
2768 |
+ gdt_descr.size = GDT_SIZE - 1; |
2769 |
+@@ -110,35 +88,23 @@ static void efi_call_phys_prelog(void) _ |
2770 |
+ |
2771 |
+ static void efi_call_phys_epilog(void) __releases(efi_rt_lock) |
2772 |
+ { |
2773 |
+- unsigned long cr4; |
2774 |
+ struct Xgt_desc_struct gdt_descr; |
2775 |
+ |
2776 |
+- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0); |
2777 |
++ gdt_descr.address = get_cpu_gdt_table(0); |
2778 |
+ gdt_descr.size = GDT_SIZE - 1; |
2779 |
+ load_gdt(&gdt_descr); |
2780 |
+- |
2781 |
+- cr4 = read_cr4(); |
2782 |
+- |
2783 |
+- if (cr4 & X86_CR4_PSE) { |
2784 |
+- swapper_pg_dir[pgd_index(0)].pgd = |
2785 |
+- efi_bak_pg_dir_pointer[0].pgd; |
2786 |
+- } else { |
2787 |
+- swapper_pg_dir[pgd_index(0)].pgd = |
2788 |
+- efi_bak_pg_dir_pointer[0].pgd; |
2789 |
+- swapper_pg_dir[pgd_index(0x400000)].pgd = |
2790 |
+- efi_bak_pg_dir_pointer[1].pgd; |
2791 |
+- } |
2792 |
++ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS); |
2793 |
+ |
2794 |
+ /* |
2795 |
+ * After the lock is released, the original page table is restored. |
2796 |
+ */ |
2797 |
+- local_flush_tlb(); |
2798 |
++ __flush_tlb_all(); |
2799 |
+ |
2800 |
+ local_irq_restore(efi_rt_eflags); |
2801 |
+ spin_unlock(&efi_rt_lock); |
2802 |
+ } |
2803 |
+ |
2804 |
+-static efi_status_t |
2805 |
++static efi_status_t __init |
2806 |
+ phys_efi_set_virtual_address_map(unsigned long memory_map_size, |
2807 |
+ unsigned long descriptor_size, |
2808 |
+ u32 descriptor_version, |
2809 |
+@@ -154,7 +120,7 @@ phys_efi_set_virtual_address_map(unsigne |
2810 |
+ return status; |
2811 |
+ } |
2812 |
+ |
2813 |
+-static efi_status_t |
2814 |
++static efi_status_t __init |
2815 |
+ phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
2816 |
+ { |
2817 |
+ efi_status_t status; |
2818 |
+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 |
2819 |
+--- linux-2.6.23.15/arch/i386/kernel/efi_stub.S 2007-10-09 21:31:38.000000000 +0100 |
2820 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/efi_stub.S 2008-02-11 10:37:44.000000000 +0000 |
2821 |
+@@ -6,6 +6,7 @@ |
2822 |
+ */ |
2823 |
+ |
2824 |
+ #include <linux/linkage.h> |
2825 |
++#include <linux/init.h> |
2826 |
+ #include <asm/page.h> |
2827 |
+ |
2828 |
+ /* |
2829 |
+@@ -20,7 +21,7 @@ |
2830 |
+ * service functions will comply with gcc calling convention, too. |
2831 |
+ */ |
2832 |
+ |
2833 |
+-.text |
2834 |
++__INIT |
2835 |
+ ENTRY(efi_call_phys) |
2836 |
+ /* |
2837 |
+ * 0. The function can only be called in Linux kernel. So CS has been |
2838 |
+@@ -36,9 +37,7 @@ ENTRY(efi_call_phys) |
2839 |
+ * The mapping of lower virtual memory has been created in prelog and |
2840 |
+ * epilog. |
2841 |
+ */ |
2842 |
+- movl $1f, %edx |
2843 |
+- subl $__PAGE_OFFSET, %edx |
2844 |
+- jmp *%edx |
2845 |
++ jmp 1f-__PAGE_OFFSET |
2846 |
+ 1: |
2847 |
+ |
2848 |
+ /* |
2849 |
+@@ -47,14 +46,8 @@ ENTRY(efi_call_phys) |
2850 |
+ * parameter 2, ..., param n. To make things easy, we save the return |
2851 |
+ * address of efi_call_phys in a global variable. |
2852 |
+ */ |
2853 |
+- popl %edx |
2854 |
+- movl %edx, saved_return_addr |
2855 |
+- /* get the function pointer into ECX*/ |
2856 |
+- popl %ecx |
2857 |
+- movl %ecx, efi_rt_function_ptr |
2858 |
+- movl $2f, %edx |
2859 |
+- subl $__PAGE_OFFSET, %edx |
2860 |
+- pushl %edx |
2861 |
++ popl (saved_return_addr) |
2862 |
++ popl (efi_rt_function_ptr) |
2863 |
+ |
2864 |
+ /* |
2865 |
+ * 3. Clear PG bit in %CR0. |
2866 |
+@@ -73,9 +66,8 @@ ENTRY(efi_call_phys) |
2867 |
+ /* |
2868 |
+ * 5. Call the physical function. |
2869 |
+ */ |
2870 |
+- jmp *%ecx |
2871 |
++ call *(efi_rt_function_ptr-__PAGE_OFFSET) |
2872 |
+ |
2873 |
+-2: |
2874 |
+ /* |
2875 |
+ * 6. After EFI runtime service returns, control will return to |
2876 |
+ * following instruction. We'd better readjust stack pointer first. |
2877 |
+@@ -88,34 +80,27 @@ ENTRY(efi_call_phys) |
2878 |
+ movl %cr0, %edx |
2879 |
+ orl $0x80000000, %edx |
2880 |
+ movl %edx, %cr0 |
2881 |
+- jmp 1f |
2882 |
+-1: |
2883 |
++ |
2884 |
+ /* |
2885 |
+ * 8. Now restore the virtual mode from flat mode by |
2886 |
+ * adding EIP with PAGE_OFFSET. |
2887 |
+ */ |
2888 |
+- movl $1f, %edx |
2889 |
+- jmp *%edx |
2890 |
++ jmp 1f+__PAGE_OFFSET |
2891 |
+ 1: |
2892 |
+ |
2893 |
+ /* |
2894 |
+ * 9. Balance the stack. And because EAX contain the return value, |
2895 |
+ * we'd better not clobber it. |
2896 |
+ */ |
2897 |
+- leal efi_rt_function_ptr, %edx |
2898 |
+- movl (%edx), %ecx |
2899 |
+- pushl %ecx |
2900 |
++ pushl (efi_rt_function_ptr) |
2901 |
+ |
2902 |
+ /* |
2903 |
+- * 10. Push the saved return address onto the stack and return. |
2904 |
++ * 10. Return to the saved return address. |
2905 |
+ */ |
2906 |
+- leal saved_return_addr, %edx |
2907 |
+- movl (%edx), %ecx |
2908 |
+- pushl %ecx |
2909 |
+- ret |
2910 |
++ jmpl *(saved_return_addr) |
2911 |
+ .previous |
2912 |
+ |
2913 |
+-.data |
2914 |
++__INITDATA |
2915 |
+ saved_return_addr: |
2916 |
+ .long 0 |
2917 |
+ efi_rt_function_ptr: |
2918 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/entry.S linux-2.6.23.15-grsec/arch/i386/kernel/entry.S |
2919 |
+--- linux-2.6.23.15/arch/i386/kernel/entry.S 2007-10-09 21:31:38.000000000 +0100 |
2920 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/entry.S 2008-02-11 10:37:44.000000000 +0000 |
2921 |
+@@ -97,7 +97,7 @@ VM_MASK = 0x00020000 |
2922 |
+ #define resume_userspace_sig resume_userspace |
2923 |
+ #endif |
2924 |
+ |
2925 |
+-#define SAVE_ALL \ |
2926 |
++#define __SAVE_ALL(_DS) \ |
2927 |
+ cld; \ |
2928 |
+ pushl %fs; \ |
2929 |
+ CFI_ADJUST_CFA_OFFSET 4;\ |
2930 |
+@@ -129,12 +129,26 @@ VM_MASK = 0x00020000 |
2931 |
+ pushl %ebx; \ |
2932 |
+ CFI_ADJUST_CFA_OFFSET 4;\ |
2933 |
+ CFI_REL_OFFSET ebx, 0;\ |
2934 |
+- movl $(__USER_DS), %edx; \ |
2935 |
++ movl $(_DS), %edx; \ |
2936 |
+ movl %edx, %ds; \ |
2937 |
+ movl %edx, %es; \ |
2938 |
+ movl $(__KERNEL_PERCPU), %edx; \ |
2939 |
+ movl %edx, %fs |
2940 |
+ |
2941 |
++#ifdef CONFIG_PAX_KERNEXEC |
2942 |
++#define SAVE_ALL \ |
2943 |
++ __SAVE_ALL(__KERNEL_DS); \ |
2944 |
++ GET_CR0_INTO_EDX; \ |
2945 |
++ movl %edx, %esi; \ |
2946 |
++ orl $X86_CR0_WP, %edx; \ |
2947 |
++ xorl %edx, %esi; \ |
2948 |
++ SET_CR0_FROM_EDX |
2949 |
++#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF) |
2950 |
++#define SAVE_ALL __SAVE_ALL(__KERNEL_DS) |
2951 |
++#else |
2952 |
++#define SAVE_ALL __SAVE_ALL(__USER_DS) |
2953 |
++#endif |
2954 |
++ |
2955 |
+ #define RESTORE_INT_REGS \ |
2956 |
+ popl %ebx; \ |
2957 |
+ CFI_ADJUST_CFA_OFFSET -4;\ |
2958 |
+@@ -248,7 +262,17 @@ check_userspace: |
2959 |
+ movb PT_CS(%esp), %al |
2960 |
+ andl $(VM_MASK | SEGMENT_RPL_MASK), %eax |
2961 |
+ cmpl $USER_RPL, %eax |
2962 |
++ |
2963 |
++#ifdef CONFIG_PAX_KERNEXEC |
2964 |
++ jae resume_userspace |
2965 |
++ |
2966 |
++ GET_CR0_INTO_EDX |
2967 |
++ xorl %esi, %edx |
2968 |
++ SET_CR0_FROM_EDX |
2969 |
++ jmp resume_kernel |
2970 |
++#else |
2971 |
+ jb resume_kernel # not returning to v8086 or userspace |
2972 |
++#endif |
2973 |
+ |
2974 |
+ ENTRY(resume_userspace) |
2975 |
+ DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt |
2976 |
+@@ -307,10 +331,9 @@ sysenter_past_esp: |
2977 |
+ /*CFI_REL_OFFSET cs, 0*/ |
2978 |
+ /* |
2979 |
+ * Push current_thread_info()->sysenter_return to the stack. |
2980 |
+- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words |
2981 |
+- * pushed above; +8 corresponds to copy_thread's esp0 setting. |
2982 |
+ */ |
2983 |
+- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) |
2984 |
++ GET_THREAD_INFO(%ebp) |
2985 |
++ pushl TI_sysenter_return(%ebp) |
2986 |
+ CFI_ADJUST_CFA_OFFSET 4 |
2987 |
+ CFI_REL_OFFSET eip, 0 |
2988 |
+ |
2989 |
+@@ -318,9 +341,17 @@ sysenter_past_esp: |
2990 |
+ * Load the potential sixth argument from user stack. |
2991 |
+ * Careful about security. |
2992 |
+ */ |
2993 |
++ movl 12(%esp),%ebp |
2994 |
++ |
2995 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
2996 |
++ mov 16(%esp),%ds |
2997 |
++1: movl %ds:(%ebp),%ebp |
2998 |
++#else |
2999 |
+ cmpl $__PAGE_OFFSET-3,%ebp |
3000 |
+ jae syscall_fault |
3001 |
+ 1: movl (%ebp),%ebp |
3002 |
++#endif |
3003 |
++ |
3004 |
+ .section __ex_table,"a" |
3005 |
+ .align 4 |
3006 |
+ .long 1b,syscall_fault |
3007 |
+@@ -343,20 +374,37 @@ sysenter_past_esp: |
3008 |
+ movl TI_flags(%ebp), %ecx |
3009 |
+ testw $_TIF_ALLWORK_MASK, %cx |
3010 |
+ jne syscall_exit_work |
3011 |
++ |
3012 |
++#ifdef CONFIG_PAX_RANDKSTACK |
3013 |
++ pushl %eax |
3014 |
++ CFI_ADJUST_CFA_OFFSET 4 |
3015 |
++ call pax_randomize_kstack |
3016 |
++ popl %eax |
3017 |
++ CFI_ADJUST_CFA_OFFSET -4 |
3018 |
++#endif |
3019 |
++ |
3020 |
+ /* if something modifies registers it must also disable sysexit */ |
3021 |
+ movl PT_EIP(%esp), %edx |
3022 |
+ movl PT_OLDESP(%esp), %ecx |
3023 |
+ xorl %ebp,%ebp |
3024 |
+ TRACE_IRQS_ON |
3025 |
+ 1: mov PT_FS(%esp), %fs |
3026 |
++2: mov PT_DS(%esp), %ds |
3027 |
++3: mov PT_ES(%esp), %es |
3028 |
+ ENABLE_INTERRUPTS_SYSEXIT |
3029 |
+ CFI_ENDPROC |
3030 |
+ .pushsection .fixup,"ax" |
3031 |
+-2: movl $0,PT_FS(%esp) |
3032 |
++4: movl $0,PT_FS(%esp) |
3033 |
+ jmp 1b |
3034 |
++5: movl $0,PT_DS(%esp) |
3035 |
++ jmp 2b |
3036 |
++6: movl $0,PT_ES(%esp) |
3037 |
++ jmp 3b |
3038 |
+ .section __ex_table,"a" |
3039 |
+ .align 4 |
3040 |
+- .long 1b,2b |
3041 |
++ .long 1b,4b |
3042 |
++ .long 2b,5b |
3043 |
++ .long 3b,6b |
3044 |
+ .popsection |
3045 |
+ ENDPROC(sysenter_entry) |
3046 |
+ |
3047 |
+@@ -389,6 +437,10 @@ no_singlestep: |
3048 |
+ testw $_TIF_ALLWORK_MASK, %cx # current->work |
3049 |
+ jne syscall_exit_work |
3050 |
+ |
3051 |
++#ifdef CONFIG_PAX_RANDKSTACK |
3052 |
++ call pax_randomize_kstack |
3053 |
++#endif |
3054 |
++ |
3055 |
+ restore_all: |
3056 |
+ movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS |
3057 |
+ # Warning: PT_OLDSS(%esp) contains the wrong/random values if we |
3058 |
+@@ -552,17 +604,24 @@ syscall_badsys: |
3059 |
+ END(syscall_badsys) |
3060 |
+ CFI_ENDPROC |
3061 |
+ |
3062 |
+-#define FIXUP_ESPFIX_STACK \ |
3063 |
+- /* since we are on a wrong stack, we cant make it a C code :( */ \ |
3064 |
+- PER_CPU(gdt_page, %ebx); \ |
3065 |
+- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ |
3066 |
+- addl %esp, %eax; \ |
3067 |
+- pushl $__KERNEL_DS; \ |
3068 |
+- CFI_ADJUST_CFA_OFFSET 4; \ |
3069 |
+- pushl %eax; \ |
3070 |
+- CFI_ADJUST_CFA_OFFSET 4; \ |
3071 |
+- lss (%esp), %esp; \ |
3072 |
++.macro FIXUP_ESPFIX_STACK |
3073 |
++ /* since we are on a wrong stack, we cant make it a C code :( */ |
3074 |
++#ifdef CONFIG_SMP |
3075 |
++ movl PER_CPU_VAR(cpu_number), %ebx; |
3076 |
++ shll $PAGE_SHIFT_asm, %ebx; |
3077 |
++ addl $cpu_gdt_table, %ebx; |
3078 |
++#else |
3079 |
++ movl $cpu_gdt_table, %ebx; |
3080 |
++#endif |
3081 |
++ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); |
3082 |
++ addl %esp, %eax; |
3083 |
++ pushl $__KERNEL_DS; |
3084 |
++ CFI_ADJUST_CFA_OFFSET 4; |
3085 |
++ pushl %eax; |
3086 |
++ CFI_ADJUST_CFA_OFFSET 4; |
3087 |
++ lss (%esp), %esp; |
3088 |
+ CFI_ADJUST_CFA_OFFSET -8; |
3089 |
++.endm |
3090 |
+ #define UNWIND_ESPFIX_STACK \ |
3091 |
+ movl %ss, %eax; \ |
3092 |
+ /* see if on espfix stack */ \ |
3093 |
+@@ -579,7 +638,7 @@ END(syscall_badsys) |
3094 |
+ * Build the entry stubs and pointer table with |
3095 |
+ * some assembler magic. |
3096 |
+ */ |
3097 |
+-.data |
3098 |
++.section .rodata,"a",@progbits |
3099 |
+ ENTRY(interrupt) |
3100 |
+ .text |
3101 |
+ |
3102 |
+@@ -679,12 +738,21 @@ error_code: |
3103 |
+ popl %ecx |
3104 |
+ CFI_ADJUST_CFA_OFFSET -4 |
3105 |
+ /*CFI_REGISTER es, ecx*/ |
3106 |
++ |
3107 |
++#ifdef CONFIG_PAX_KERNEXEC |
3108 |
++ GET_CR0_INTO_EDX |
3109 |
++ movl %edx, %esi |
3110 |
++ orl $X86_CR0_WP, %edx |
3111 |
++ xorl %edx, %esi |
3112 |
++ SET_CR0_FROM_EDX |
3113 |
++#endif |
3114 |
++ |
3115 |
+ movl PT_FS(%esp), %edi # get the function address |
3116 |
+ movl PT_ORIG_EAX(%esp), %edx # get the error code |
3117 |
+ movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart |
3118 |
+ mov %ecx, PT_FS(%esp) |
3119 |
+ /*CFI_REL_OFFSET fs, ES*/ |
3120 |
+- movl $(__USER_DS), %ecx |
3121 |
++ movl $(__KERNEL_DS), %ecx |
3122 |
+ movl %ecx, %ds |
3123 |
+ movl %ecx, %es |
3124 |
+ movl %esp,%eax # pt_regs pointer |
3125 |
+@@ -818,6 +886,13 @@ nmi_stack_correct: |
3126 |
+ xorl %edx,%edx # zero error code |
3127 |
+ movl %esp,%eax # pt_regs pointer |
3128 |
+ call do_nmi |
3129 |
++ |
3130 |
++#ifdef CONFIG_PAX_KERNEXEC |
3131 |
++ GET_CR0_INTO_EDX |
3132 |
++ xorl %esi, %edx |
3133 |
++ SET_CR0_FROM_EDX |
3134 |
++#endif |
3135 |
++ |
3136 |
+ jmp restore_nocheck_notrace |
3137 |
+ CFI_ENDPROC |
3138 |
+ |
3139 |
+@@ -858,6 +933,13 @@ nmi_espfix_stack: |
3140 |
+ FIXUP_ESPFIX_STACK # %eax == %esp |
3141 |
+ xorl %edx,%edx # zero error code |
3142 |
+ call do_nmi |
3143 |
++ |
3144 |
++#ifdef CONFIG_PAX_KERNEXEC |
3145 |
++ GET_CR0_INTO_EDX |
3146 |
++ xorl %esi, %edx |
3147 |
++ SET_CR0_FROM_EDX |
3148 |
++#endif |
3149 |
++ |
3150 |
+ RESTORE_REGS |
3151 |
+ lss 12+4(%esp), %esp # back to espfix stack |
3152 |
+ CFI_ADJUST_CFA_OFFSET -24 |
3153 |
+@@ -1106,7 +1188,6 @@ ENDPROC(xen_failsafe_callback) |
3154 |
+ |
3155 |
+ #endif /* CONFIG_XEN */ |
3156 |
+ |
3157 |
+-.section .rodata,"a" |
3158 |
+ #include "syscall_table.S" |
3159 |
+ |
3160 |
+ syscall_table_size=(.-sys_call_table) |
3161 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/head.S linux-2.6.23.15-grsec/arch/i386/kernel/head.S |
3162 |
+--- linux-2.6.23.15/arch/i386/kernel/head.S 2007-10-09 21:31:38.000000000 +0100 |
3163 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/head.S 2008-02-11 10:37:44.000000000 +0000 |
3164 |
+@@ -18,6 +18,7 @@ |
3165 |
+ #include <asm/thread_info.h> |
3166 |
+ #include <asm/asm-offsets.h> |
3167 |
+ #include <asm/setup.h> |
3168 |
++#include <asm/msr-index.h> |
3169 |
+ |
3170 |
+ /* |
3171 |
+ * References to members of the new_cpu_data structure. |
3172 |
+@@ -51,17 +52,22 @@ |
3173 |
+ */ |
3174 |
+ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm) |
3175 |
+ |
3176 |
+-#if PTRS_PER_PMD > 1 |
3177 |
+-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD |
3178 |
+-#else |
3179 |
+-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD) |
3180 |
+-#endif |
3181 |
++PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE) |
3182 |
+ BOOTBITMAP_SIZE = LOW_PAGES / 8 |
3183 |
+ ALLOCATOR_SLOP = 4 |
3184 |
+ |
3185 |
+ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm |
3186 |
+ |
3187 |
+ /* |
3188 |
++ * Real beginning of normal "text" segment |
3189 |
++ */ |
3190 |
++ENTRY(stext) |
3191 |
++ENTRY(_stext) |
3192 |
++ |
3193 |
++.section .text.startup,"ax",@progbits |
3194 |
++ ljmp $(__BOOT_CS),$phys_startup_32 |
3195 |
++ |
3196 |
++/* |
3197 |
+ * 32-bit kernel entrypoint; only used by the boot CPU. On entry, |
3198 |
+ * %esi points to the real-mode code as a 32-bit pointer. |
3199 |
+ * CS and DS must be 4 GB flat segments, but we don't depend on |
3200 |
+@@ -69,6 +75,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + |
3201 |
+ * can. |
3202 |
+ */ |
3203 |
+ .section .text.head,"ax",@progbits |
3204 |
++ |
3205 |
++#ifdef CONFIG_PAX_KERNEXEC |
3206 |
++/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */ |
3207 |
++.fill 4096,1,0xcc |
3208 |
++#endif |
3209 |
++ |
3210 |
+ ENTRY(startup_32) |
3211 |
+ |
3212 |
+ /* |
3213 |
+@@ -82,6 +94,43 @@ ENTRY(startup_32) |
3214 |
+ movl %eax,%fs |
3215 |
+ movl %eax,%gs |
3216 |
+ |
3217 |
++ movl $__per_cpu_start,%eax |
3218 |
++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2) |
3219 |
++ rorl $16,%eax |
3220 |
++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4) |
3221 |
++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7) |
3222 |
++ movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax |
3223 |
++ subl $__per_cpu_start,%eax |
3224 |
++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0) |
3225 |
++ |
3226 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
3227 |
++ /* check for VMware */ |
3228 |
++ movl $0x564d5868,%eax |
3229 |
++ xorl %ebx,%ebx |
3230 |
++ movl $0xa,%ecx |
3231 |
++ movl $0x5658,%edx |
3232 |
++ in (%dx),%eax |
3233 |
++ cmpl $0x564d5868,%ebx |
3234 |
++ jz 1f |
3235 |
++ |
3236 |
++ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax |
3237 |
++ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4) |
3238 |
++1: |
3239 |
++#endif |
3240 |
++ |
3241 |
++#ifdef CONFIG_PAX_KERNEXEC |
3242 |
++ movl $KERNEL_TEXT_OFFSET,%eax |
3243 |
++ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2) |
3244 |
++ rorl $16,%eax |
3245 |
++ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4) |
3246 |
++ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7) |
3247 |
++ |
3248 |
++ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4) |
3249 |
++ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7) |
3250 |
++ rorl $16,%eax |
3251 |
++ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2) |
3252 |
++#endif |
3253 |
++ |
3254 |
+ /* |
3255 |
+ * Clear BSS first so that there are no surprises... |
3256 |
+ * No need to cld as DF is already clear from cld above... |
3257 |
+@@ -129,24 +178,42 @@ ENTRY(startup_32) |
3258 |
+ * Warning: don't use %esi or the stack in this code. However, %esp |
3259 |
+ * can be used as a GPR if you really need it... |
3260 |
+ */ |
3261 |
+-page_pde_offset = (__PAGE_OFFSET >> 20); |
3262 |
+- |
3263 |
++#ifdef CONFIG_X86_PAE |
3264 |
++page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE)); |
3265 |
++#else |
3266 |
++page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE)); |
3267 |
++#endif |
3268 |
+ movl $(pg0 - __PAGE_OFFSET), %edi |
3269 |
++#ifdef CONFIG_X86_PAE |
3270 |
++ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx |
3271 |
++#else |
3272 |
+ movl $(swapper_pg_dir - __PAGE_OFFSET), %edx |
3273 |
+- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ |
3274 |
++#endif |
3275 |
++ movl $0x063, %eax /* 0x063 = PRESENT+RW+ACCESSED+DIRTY */ |
3276 |
+ 10: |
3277 |
+- leal 0x007(%edi),%ecx /* Create PDE entry */ |
3278 |
++ leal 0x063(%edi),%ecx /* Create PDE entry */ |
3279 |
+ movl %ecx,(%edx) /* Store identity PDE entry */ |
3280 |
+ movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ |
3281 |
++#ifdef CONFIG_X86_PAE |
3282 |
++ movl $0,4(%edx) |
3283 |
++ movl $0,page_pde_offset+4(%edx) |
3284 |
++ addl $8,%edx |
3285 |
++ movl $512, %ecx |
3286 |
++#else |
3287 |
+ addl $4,%edx |
3288 |
+ movl $1024, %ecx |
3289 |
++#endif |
3290 |
+ 11: |
3291 |
+ stosl |
3292 |
++#ifdef CONFIG_X86_PAE |
3293 |
++ movl $0,(%edi) |
3294 |
++ addl $4,%edi |
3295 |
++#endif |
3296 |
+ addl $0x1000,%eax |
3297 |
+ loop 11b |
3298 |
+ /* End condition: we must map up to and including INIT_MAP_BEYOND_END */ |
3299 |
+- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */ |
3300 |
+- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp |
3301 |
++ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */ |
3302 |
++ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp |
3303 |
+ cmpl %ebp,%eax |
3304 |
+ jb 10b |
3305 |
+ movl %edi,(init_pg_tables_end - __PAGE_OFFSET) |
3306 |
+@@ -167,10 +234,12 @@ page_pde_offset = (__PAGE_OFFSET >> 20); |
3307 |
+ #endif |
3308 |
+ |
3309 |
+ /* Do an early initialization of the fixmap area */ |
3310 |
+- movl $(swapper_pg_dir - __PAGE_OFFSET), %edx |
3311 |
+- movl $(swapper_pg_pmd - __PAGE_OFFSET), %eax |
3312 |
+- addl $0x007, %eax /* 0x007 = PRESENT+RW+USER */ |
3313 |
+- movl %eax, 4092(%edx) |
3314 |
++ /* 0x067 = PRESENT+RW+USER+ACCESSED+DIRTY */ |
3315 |
++#ifdef CONFIG_X86_PAE |
3316 |
++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pm_dir - __PAGE_OFFSET + 4096 - 8) |
3317 |
++#else |
3318 |
++ movl $(swapper_pg_pmd - __PAGE_OFFSET + 0x067), (swapper_pg_dir - __PAGE_OFFSET + 4096 - 4) |
3319 |
++#endif |
3320 |
+ |
3321 |
+ #ifdef CONFIG_SMP |
3322 |
+ ENTRY(startup_32_smp) |
3323 |
+@@ -181,6 +250,11 @@ ENTRY(startup_32_smp) |
3324 |
+ movl %eax,%fs |
3325 |
+ movl %eax,%gs |
3326 |
+ |
3327 |
++ /* This is a secondary processor (AP) */ |
3328 |
++ xorl %ebx,%ebx |
3329 |
++ incl %ebx |
3330 |
++#endif /* CONFIG_SMP */ |
3331 |
++ |
3332 |
+ /* |
3333 |
+ * New page tables may be in 4Mbyte page mode and may |
3334 |
+ * be using the global pages. |
3335 |
+@@ -196,42 +270,47 @@ ENTRY(startup_32_smp) |
3336 |
+ * not yet offset PAGE_OFFSET.. |
3337 |
+ */ |
3338 |
+ #define cr4_bits mmu_cr4_features-__PAGE_OFFSET |
3339 |
++3: |
3340 |
+ movl cr4_bits,%edx |
3341 |
+ andl %edx,%edx |
3342 |
+- jz 6f |
3343 |
++ jz 5f |
3344 |
+ movl %cr4,%eax # Turn on paging options (PSE,PAE,..) |
3345 |
+ orl %edx,%eax |
3346 |
+ movl %eax,%cr4 |
3347 |
+ |
3348 |
+- btl $5, %eax # check if PAE is enabled |
3349 |
+- jnc 6f |
3350 |
++#ifdef CONFIG_X86_PAE |
3351 |
++ movl %ebx,%edi |
3352 |
+ |
3353 |
+ /* Check if extended functions are implemented */ |
3354 |
+ movl $0x80000000, %eax |
3355 |
+ cpuid |
3356 |
+ cmpl $0x80000000, %eax |
3357 |
+- jbe 6f |
3358 |
++ jbe 4f |
3359 |
+ mov $0x80000001, %eax |
3360 |
+ cpuid |
3361 |
+ /* Execute Disable bit supported? */ |
3362 |
+ btl $20, %edx |
3363 |
+- jnc 6f |
3364 |
++ jnc 4f |
3365 |
+ |
3366 |
+ /* Setup EFER (Extended Feature Enable Register) */ |
3367 |
+- movl $0xc0000080, %ecx |
3368 |
++ movl $MSR_EFER, %ecx |
3369 |
+ rdmsr |
3370 |
+ |
3371 |
+ btsl $11, %eax |
3372 |
+ /* Make changes effective */ |
3373 |
+ wrmsr |
3374 |
+ |
3375 |
+-6: |
3376 |
+- /* This is a secondary processor (AP) */ |
3377 |
+- xorl %ebx,%ebx |
3378 |
+- incl %ebx |
3379 |
++ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET |
3380 |
++ movl $1,nx_enabled-__PAGE_OFFSET |
3381 |
+ |
3382 |
+-#endif /* CONFIG_SMP */ |
3383 |
+-3: |
3384 |
++#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF) |
3385 |
++ movl $0,disable_x86_sep-__PAGE_OFFSET |
3386 |
++#endif |
3387 |
++ |
3388 |
++4: |
3389 |
++ movl %edi,%ebx |
3390 |
++#endif |
3391 |
++5: |
3392 |
+ |
3393 |
+ /* |
3394 |
+ * Enable paging |
3395 |
+@@ -256,9 +335,7 @@ ENTRY(startup_32_smp) |
3396 |
+ |
3397 |
+ #ifdef CONFIG_SMP |
3398 |
+ andl %ebx,%ebx |
3399 |
+- jz 1f /* Initial CPU cleans BSS */ |
3400 |
+- jmp checkCPUtype |
3401 |
+-1: |
3402 |
++ jnz checkCPUtype /* Initial CPU cleans BSS */ |
3403 |
+ #endif /* CONFIG_SMP */ |
3404 |
+ |
3405 |
+ /* |
3406 |
+@@ -335,12 +412,12 @@ is386: movl $2,%ecx # set MP |
3407 |
+ ljmp $(__KERNEL_CS),$1f |
3408 |
+ 1: movl $(__KERNEL_DS),%eax # reload all the segment registers |
3409 |
+ movl %eax,%ss # after changing gdt. |
3410 |
+- movl %eax,%fs # gets reset once there's real percpu |
3411 |
+- |
3412 |
+- movl $(__USER_DS),%eax # DS/ES contains default USER segment |
3413 |
+ movl %eax,%ds |
3414 |
+ movl %eax,%es |
3415 |
+ |
3416 |
++ movl $(__KERNEL_PERCPU), %eax |
3417 |
++ movl %eax,%fs # set this cpu's percpu |
3418 |
++ |
3419 |
+ xorl %eax,%eax # Clear GS and LDT |
3420 |
+ movl %eax,%gs |
3421 |
+ lldt %ax |
3422 |
+@@ -351,11 +428,7 @@ is386: movl $2,%ecx # set MP |
3423 |
+ movb ready, %cl |
3424 |
+ movb $1, ready |
3425 |
+ cmpb $0,%cl # the first CPU calls start_kernel |
3426 |
+- je 1f |
3427 |
+- movl $(__KERNEL_PERCPU), %eax |
3428 |
+- movl %eax,%fs # set this cpu's percpu |
3429 |
+- jmp initialize_secondary # all other CPUs call initialize_secondary |
3430 |
+-1: |
3431 |
++ jne initialize_secondary # all other CPUs call initialize_secondary |
3432 |
+ #endif /* CONFIG_SMP */ |
3433 |
+ jmp start_kernel |
3434 |
+ |
3435 |
+@@ -441,8 +514,8 @@ early_page_fault: |
3436 |
+ jmp early_fault |
3437 |
+ |
3438 |
+ early_fault: |
3439 |
+- cld |
3440 |
+ #ifdef CONFIG_PRINTK |
3441 |
++ cld |
3442 |
+ movl $(__KERNEL_DS),%eax |
3443 |
+ movl %eax,%ds |
3444 |
+ movl %eax,%es |
3445 |
+@@ -466,8 +539,8 @@ hlt_loop: |
3446 |
+ /* This is the default interrupt "handler" :-) */ |
3447 |
+ ALIGN |
3448 |
+ ignore_int: |
3449 |
+- cld |
3450 |
+ #ifdef CONFIG_PRINTK |
3451 |
++ cld |
3452 |
+ pushl %eax |
3453 |
+ pushl %ecx |
3454 |
+ pushl %edx |
3455 |
+@@ -498,31 +571,58 @@ ignore_int: |
3456 |
+ #endif |
3457 |
+ iret |
3458 |
+ |
3459 |
+-.section .text |
3460 |
+-/* |
3461 |
+- * Real beginning of normal "text" segment |
3462 |
+- */ |
3463 |
+-ENTRY(stext) |
3464 |
+-ENTRY(_stext) |
3465 |
+- |
3466 |
+ /* |
3467 |
+ * BSS section |
3468 |
+ */ |
3469 |
+-.section ".bss.page_aligned","wa" |
3470 |
++.section .swapper_pg_dir,"a",@progbits |
3471 |
+ .align PAGE_SIZE_asm |
3472 |
+ ENTRY(swapper_pg_dir) |
3473 |
++#ifdef CONFIG_X86_PAE |
3474 |
++ .long swapper_pm_dir-__PAGE_OFFSET+1 |
3475 |
++ .long 0 |
3476 |
++ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1 |
3477 |
++ .long 0 |
3478 |
++ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1 |
3479 |
++ .long 0 |
3480 |
++ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1 |
3481 |
++ .long 0 |
3482 |
++#else |
3483 |
+ .fill 1024,4,0 |
3484 |
++#endif |
3485 |
++ |
3486 |
++.section .swapper_pm_dir,"a",@progbits |
3487 |
++#ifdef CONFIG_X86_PAE |
3488 |
++ENTRY(swapper_pm_dir) |
3489 |
++ .fill 512,8,0 |
3490 |
++ .fill 512,8,0 |
3491 |
++ .fill 512,8,0 |
3492 |
++ .fill 512,8,0 |
3493 |
++#endif |
3494 |
++ |
3495 |
+ ENTRY(swapper_pg_pmd) |
3496 |
+ .fill 1024,4,0 |
3497 |
++ |
3498 |
++.section .empty_zero_page,"a",@progbits |
3499 |
+ ENTRY(empty_zero_page) |
3500 |
+ .fill 4096,1,0 |
3501 |
+ |
3502 |
+ /* |
3503 |
++ * The IDT has to be page-aligned to simplify the Pentium |
3504 |
++ * F0 0F bug workaround.. We have a special link segment |
3505 |
++ * for this. |
3506 |
++ */ |
3507 |
++.section .idt,"a",@progbits |
3508 |
++ENTRY(idt_table) |
3509 |
++ .fill 256,8,0 |
3510 |
++ |
3511 |
++/* |
3512 |
+ * This starts the data section. |
3513 |
+ */ |
3514 |
+ .data |
3515 |
++ |
3516 |
++.section .rodata,"a",@progbits |
3517 |
+ ENTRY(stack_start) |
3518 |
+- .long init_thread_union+THREAD_SIZE |
3519 |
++ .long init_thread_union+THREAD_SIZE-8 |
3520 |
+ .long __BOOT_DS |
3521 |
+ |
3522 |
+ ready: .byte 0 |
3523 |
+@@ -565,7 +665,7 @@ idt_descr: |
3524 |
+ .word 0 # 32 bit align gdt_desc.address |
3525 |
+ ENTRY(early_gdt_descr) |
3526 |
+ .word GDT_ENTRIES*8-1 |
3527 |
+- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */ |
3528 |
++ .long cpu_gdt_table /* Overwritten for secondary CPUs */ |
3529 |
+ |
3530 |
+ /* |
3531 |
+ * The boot_gdt must mirror the equivalent in setup.S and is |
3532 |
+@@ -574,5 +674,61 @@ ENTRY(early_gdt_descr) |
3533 |
+ .align L1_CACHE_BYTES |
3534 |
+ ENTRY(boot_gdt) |
3535 |
+ .fill GDT_ENTRY_BOOT_CS,8,0 |
3536 |
+- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */ |
3537 |
+- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */ |
3538 |
++ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */ |
3539 |
++ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */ |
3540 |
++ |
3541 |
++ .align PAGE_SIZE_asm |
3542 |
++ENTRY(cpu_gdt_table) |
3543 |
++ .quad 0x0000000000000000 /* NULL descriptor */ |
3544 |
++ .quad 0x0000000000000000 /* 0x0b reserved */ |
3545 |
++ .quad 0x0000000000000000 /* 0x13 reserved */ |
3546 |
++ .quad 0x0000000000000000 /* 0x1b reserved */ |
3547 |
++ .quad 0x0000000000000000 /* 0x20 unused */ |
3548 |
++ .quad 0x0000000000000000 /* 0x28 unused */ |
3549 |
++ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */ |
3550 |
++ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */ |
3551 |
++ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */ |
3552 |
++ .quad 0x0000000000000000 /* 0x4b reserved */ |
3553 |
++ .quad 0x0000000000000000 /* 0x53 reserved */ |
3554 |
++ .quad 0x0000000000000000 /* 0x5b reserved */ |
3555 |
++ |
3556 |
++ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */ |
3557 |
++ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */ |
3558 |
++ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */ |
3559 |
++ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */ |
3560 |
++ |
3561 |
++ .quad 0x0000000000000000 /* 0x80 TSS descriptor */ |
3562 |
++ .quad 0x0000000000000000 /* 0x88 LDT descriptor */ |
3563 |
++ |
3564 |
++ /* |
3565 |
++ * Segments used for calling PnP BIOS have byte granularity. |
3566 |
++ * The code segments and data segments have fixed 64k limits, |
3567 |
++ * the transfer segment sizes are set at run time. |
3568 |
++ */ |
3569 |
++ .quad 0x00409b000000ffff /* 0x90 32-bit code */ |
3570 |
++ .quad 0x00009b000000ffff /* 0x98 16-bit code */ |
3571 |
++ .quad 0x000093000000ffff /* 0xa0 16-bit data */ |
3572 |
++ .quad 0x0000930000000000 /* 0xa8 16-bit data */ |
3573 |
++ .quad 0x0000930000000000 /* 0xb0 16-bit data */ |
3574 |
++ |
3575 |
++ /* |
3576 |
++ * The APM segments have byte granularity and their bases |
3577 |
++ * are set at run time. All have 64k limits. |
3578 |
++ */ |
3579 |
++ .quad 0x00409b000000ffff /* 0xb8 APM CS code */ |
3580 |
++ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */ |
3581 |
++ .quad 0x004093000000ffff /* 0xc8 APM DS data */ |
3582 |
++ |
3583 |
++ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */ |
3584 |
++ .quad 0x0040930000000000 /* 0xd8 - PERCPU */ |
3585 |
++ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */ |
3586 |
++ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */ |
3587 |
++ .quad 0x0000000000000000 /* 0xf0 - unused */ |
3588 |
++ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ |
3589 |
++ |
3590 |
++ /* Be sure this is zeroed to avoid false validations in Xen */ |
3591 |
++ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0 |
3592 |
++ |
3593 |
++#ifdef CONFIG_SMP |
3594 |
++ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */ |
3595 |
++#endif |
3596 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/hpet.c linux-2.6.23.15-grsec/arch/i386/kernel/hpet.c |
3597 |
+--- linux-2.6.23.15/arch/i386/kernel/hpet.c 2007-10-09 21:31:38.000000000 +0100 |
3598 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/hpet.c 2008-02-11 10:37:44.000000000 +0000 |
3599 |
+@@ -96,7 +96,7 @@ static void hpet_reserve_platform_timers |
3600 |
+ hd.hd_irq[1] = HPET_LEGACY_RTC; |
3601 |
+ |
3602 |
+ for (i = 2; i < nrtimers; timer++, i++) |
3603 |
+- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >> |
3604 |
++ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >> |
3605 |
+ Tn_INT_ROUTE_CNF_SHIFT; |
3606 |
+ |
3607 |
+ hpet_alloc(&hd); |
3608 |
+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 |
3609 |
+--- linux-2.6.23.15/arch/i386/kernel/i386_ksyms.c 2007-10-09 21:31:38.000000000 +0100 |
3610 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/i386_ksyms.c 2008-02-11 10:37:44.000000000 +0000 |
3611 |
+@@ -2,12 +2,16 @@ |
3612 |
+ #include <asm/checksum.h> |
3613 |
+ #include <asm/desc.h> |
3614 |
+ |
3615 |
++EXPORT_SYMBOL_GPL(cpu_gdt_table); |
3616 |
++ |
3617 |
+ EXPORT_SYMBOL(__down_failed); |
3618 |
+ EXPORT_SYMBOL(__down_failed_interruptible); |
3619 |
+ EXPORT_SYMBOL(__down_failed_trylock); |
3620 |
+ EXPORT_SYMBOL(__up_wakeup); |
3621 |
+ /* Networking helper routines. */ |
3622 |
+ EXPORT_SYMBOL(csum_partial_copy_generic); |
3623 |
++EXPORT_SYMBOL(csum_partial_copy_generic_to_user); |
3624 |
++EXPORT_SYMBOL(csum_partial_copy_generic_from_user); |
3625 |
+ |
3626 |
+ EXPORT_SYMBOL(__get_user_1); |
3627 |
+ EXPORT_SYMBOL(__get_user_2); |
3628 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/i8259.c linux-2.6.23.15-grsec/arch/i386/kernel/i8259.c |
3629 |
+--- linux-2.6.23.15/arch/i386/kernel/i8259.c 2007-10-09 21:31:38.000000000 +0100 |
3630 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/i8259.c 2008-02-11 10:37:44.000000000 +0000 |
3631 |
+@@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp |
3632 |
+ * New motherboards sometimes make IRQ 13 be a PCI interrupt, |
3633 |
+ * so allow interrupt sharing. |
3634 |
+ */ |
3635 |
+-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL }; |
3636 |
++static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL }; |
3637 |
+ |
3638 |
+ void __init init_ISA_irqs (void) |
3639 |
+ { |
3640 |
+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 |
3641 |
+--- linux-2.6.23.15/arch/i386/kernel/init_task.c 2007-10-09 21:31:38.000000000 +0100 |
3642 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/init_task.c 2008-02-11 10:37:44.000000000 +0000 |
3643 |
+@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task); |
3644 |
+ * per-CPU TSS segments. Threads are completely 'soft' on Linux, |
3645 |
+ * no more per-task TSS's. |
3646 |
+ */ |
3647 |
+-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS; |
3648 |
++struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS }; |
3649 |
+ |
3650 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/ioport.c linux-2.6.23.15-grsec/arch/i386/kernel/ioport.c |
3651 |
+--- linux-2.6.23.15/arch/i386/kernel/ioport.c 2007-10-09 21:31:38.000000000 +0100 |
3652 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/ioport.c 2008-02-11 10:37:44.000000000 +0000 |
3653 |
+@@ -16,6 +16,7 @@ |
3654 |
+ #include <linux/slab.h> |
3655 |
+ #include <linux/thread_info.h> |
3656 |
+ #include <linux/syscalls.h> |
3657 |
++#include <linux/grsecurity.h> |
3658 |
+ |
3659 |
+ /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ |
3660 |
+ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) |
3661 |
+@@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long |
3662 |
+ |
3663 |
+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) |
3664 |
+ return -EINVAL; |
3665 |
++#ifdef CONFIG_GRKERNSEC_IO |
3666 |
++ if (turn_on) { |
3667 |
++ gr_handle_ioperm(); |
3668 |
++#else |
3669 |
+ if (turn_on && !capable(CAP_SYS_RAWIO)) |
3670 |
++#endif |
3671 |
+ return -EPERM; |
3672 |
+- |
3673 |
++#ifdef CONFIG_GRKERNSEC_IO |
3674 |
++ } |
3675 |
++#endif |
3676 |
+ /* |
3677 |
+ * If it's the first ioperm() call in this thread's lifetime, set the |
3678 |
+ * IO bitmap up. ioperm() is much less timing critical than clone(), |
3679 |
+@@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long |
3680 |
+ * because the ->io_bitmap_max value must match the bitmap |
3681 |
+ * contents: |
3682 |
+ */ |
3683 |
+- tss = &per_cpu(init_tss, get_cpu()); |
3684 |
++ tss = init_tss + get_cpu(); |
3685 |
+ |
3686 |
+ set_bitmap(t->io_bitmap_ptr, from, num, !turn_on); |
3687 |
+ |
3688 |
+@@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u |
3689 |
+ return -EINVAL; |
3690 |
+ /* Trying to gain more privileges? */ |
3691 |
+ if (level > old) { |
3692 |
++#ifdef CONFIG_GRKERNSEC_IO |
3693 |
++ gr_handle_iopl(); |
3694 |
++ return -EPERM; |
3695 |
++#else |
3696 |
+ if (!capable(CAP_SYS_RAWIO)) |
3697 |
+ return -EPERM; |
3698 |
++#endif |
3699 |
+ } |
3700 |
+ t->iopl = level << 12; |
3701 |
+ regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl; |
3702 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/irq.c linux-2.6.23.15-grsec/arch/i386/kernel/irq.c |
3703 |
+--- linux-2.6.23.15/arch/i386/kernel/irq.c 2007-10-09 21:31:38.000000000 +0100 |
3704 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/irq.c 2008-02-11 10:37:44.000000000 +0000 |
3705 |
+@@ -117,7 +117,7 @@ fastcall unsigned int do_IRQ(struct pt_r |
3706 |
+ int arg1, arg2, ebx; |
3707 |
+ |
3708 |
+ /* build the stack frame on the IRQ stack */ |
3709 |
+- isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); |
3710 |
++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2; |
3711 |
+ irqctx->tinfo.task = curctx->tinfo.task; |
3712 |
+ irqctx->tinfo.previous_esp = current_stack_pointer; |
3713 |
+ |
3714 |
+@@ -213,7 +213,7 @@ asmlinkage void do_softirq(void) |
3715 |
+ irqctx->tinfo.previous_esp = current_stack_pointer; |
3716 |
+ |
3717 |
+ /* build the stack frame on the softirq stack */ |
3718 |
+- isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); |
3719 |
++ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2; |
3720 |
+ |
3721 |
+ asm volatile( |
3722 |
+ " xchgl %%ebx,%%esp \n" |
3723 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/kprobes.c linux-2.6.23.15-grsec/arch/i386/kernel/kprobes.c |
3724 |
+--- linux-2.6.23.15/arch/i386/kernel/kprobes.c 2007-10-09 21:31:38.000000000 +0100 |
3725 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/kprobes.c 2008-02-11 10:37:44.000000000 +0000 |
3726 |
+@@ -49,9 +49,24 @@ static __always_inline void set_jmp_op(v |
3727 |
+ char op; |
3728 |
+ long raddr; |
3729 |
+ } __attribute__((packed)) *jop; |
3730 |
+- jop = (struct __arch_jmp_op *)from; |
3731 |
++ |
3732 |
++#ifdef CONFIG_PAX_KERNEXEC |
3733 |
++ unsigned long cr0; |
3734 |
++#endif |
3735 |
++ |
3736 |
++ jop = (struct __arch_jmp_op *)(from + __KERNEL_TEXT_OFFSET); |
3737 |
++ |
3738 |
++#ifdef CONFIG_PAX_KERNEXEC |
3739 |
++ pax_open_kernel(cr0); |
3740 |
++#endif |
3741 |
++ |
3742 |
+ jop->raddr = (long)(to) - ((long)(from) + 5); |
3743 |
+ jop->op = RELATIVEJUMP_INSTRUCTION; |
3744 |
++ |
3745 |
++#ifdef CONFIG_PAX_KERNEXEC |
3746 |
++ pax_close_kernel(cr0); |
3747 |
++#endif |
3748 |
++ |
3749 |
+ } |
3750 |
+ |
3751 |
+ /* |
3752 |
+@@ -153,14 +168,28 @@ static int __kprobes is_IF_modifier(kpro |
3753 |
+ |
3754 |
+ int __kprobes arch_prepare_kprobe(struct kprobe *p) |
3755 |
+ { |
3756 |
++ |
3757 |
++#ifdef CONFIG_PAX_KERNEXEC |
3758 |
++ unsigned long cr0; |
3759 |
++#endif |
3760 |
++ |
3761 |
+ /* insn: must be on special executable page on i386. */ |
3762 |
+ p->ainsn.insn = get_insn_slot(); |
3763 |
+ if (!p->ainsn.insn) |
3764 |
+ return -ENOMEM; |
3765 |
+ |
3766 |
+- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
3767 |
+- p->opcode = *p->addr; |
3768 |
+- if (can_boost(p->addr)) { |
3769 |
++#ifdef CONFIG_PAX_KERNEXEC |
3770 |
++ pax_open_kernel(cr0); |
3771 |
++#endif |
3772 |
++ |
3773 |
++ memcpy(p->ainsn.insn, p->addr + __KERNEL_TEXT_OFFSET, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); |
3774 |
++ |
3775 |
++#ifdef CONFIG_PAX_KERNEXEC |
3776 |
++ pax_close_kernel(cr0); |
3777 |
++#endif |
3778 |
++ |
3779 |
++ p->opcode = *(p->addr + __KERNEL_TEXT_OFFSET); |
3780 |
++ if (can_boost(p->addr + __KERNEL_TEXT_OFFSET)) { |
3781 |
+ p->ainsn.boostable = 0; |
3782 |
+ } else { |
3783 |
+ p->ainsn.boostable = -1; |
3784 |
+@@ -219,7 +248,7 @@ static void __kprobes prepare_singlestep |
3785 |
+ if (p->opcode == BREAKPOINT_INSTRUCTION) |
3786 |
+ regs->eip = (unsigned long)p->addr; |
3787 |
+ else |
3788 |
+- regs->eip = (unsigned long)p->ainsn.insn; |
3789 |
++ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET; |
3790 |
+ } |
3791 |
+ |
3792 |
+ /* Called with kretprobe_lock held */ |
3793 |
+@@ -325,7 +354,7 @@ ss_probe: |
3794 |
+ if (p->ainsn.boostable == 1 && !p->post_handler){ |
3795 |
+ /* Boost up -- we can execute copied instructions directly */ |
3796 |
+ reset_current_kprobe(); |
3797 |
+- regs->eip = (unsigned long)p->ainsn.insn; |
3798 |
++ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET; |
3799 |
+ preempt_enable_no_resched(); |
3800 |
+ return 1; |
3801 |
+ } |
3802 |
+@@ -475,7 +504,7 @@ static void __kprobes resume_execution(s |
3803 |
+ struct pt_regs *regs, struct kprobe_ctlblk *kcb) |
3804 |
+ { |
3805 |
+ unsigned long *tos = (unsigned long *)®s->esp; |
3806 |
+- unsigned long copy_eip = (unsigned long)p->ainsn.insn; |
3807 |
++ unsigned long copy_eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET; |
3808 |
+ unsigned long orig_eip = (unsigned long)p->addr; |
3809 |
+ |
3810 |
+ regs->eflags &= ~TF_MASK; |
3811 |
+@@ -648,7 +677,7 @@ int __kprobes kprobe_exceptions_notify(s |
3812 |
+ struct die_args *args = (struct die_args *)data; |
3813 |
+ int ret = NOTIFY_DONE; |
3814 |
+ |
3815 |
+- if (args->regs && user_mode_vm(args->regs)) |
3816 |
++ if (args->regs && user_mode(args->regs)) |
3817 |
+ return ret; |
3818 |
+ |
3819 |
+ switch (val) { |
3820 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/ldt.c linux-2.6.23.15-grsec/arch/i386/kernel/ldt.c |
3821 |
+--- linux-2.6.23.15/arch/i386/kernel/ldt.c 2007-10-09 21:31:38.000000000 +0100 |
3822 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/ldt.c 2008-02-11 10:37:44.000000000 +0000 |
3823 |
+@@ -58,7 +58,7 @@ static int alloc_ldt(mm_context_t *pc, i |
3824 |
+ #ifdef CONFIG_SMP |
3825 |
+ cpumask_t mask; |
3826 |
+ preempt_disable(); |
3827 |
+- load_LDT(pc); |
3828 |
++ load_LDT_nolock(pc); |
3829 |
+ mask = cpumask_of_cpu(smp_processor_id()); |
3830 |
+ if (!cpus_equal(current->mm->cpu_vm_mask, mask)) |
3831 |
+ smp_call_function(flush_ldt, NULL, 1, 1); |
3832 |
+@@ -102,6 +102,22 @@ int init_new_context(struct task_struct |
3833 |
+ retval = copy_ldt(&mm->context, &old_mm->context); |
3834 |
+ up(&old_mm->context.sem); |
3835 |
+ } |
3836 |
++ |
3837 |
++ if (tsk == current) { |
3838 |
++ mm->context.vdso = ~0UL; |
3839 |
++ |
3840 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
3841 |
++ mm->context.user_cs_base = 0UL; |
3842 |
++ mm->context.user_cs_limit = ~0UL; |
3843 |
++ |
3844 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) |
3845 |
++ cpus_clear(mm->context.cpu_user_cs_mask); |
3846 |
++#endif |
3847 |
++ |
3848 |
++#endif |
3849 |
++ |
3850 |
++ } |
3851 |
++ |
3852 |
+ return retval; |
3853 |
+ } |
3854 |
+ |
3855 |
+@@ -212,6 +228,13 @@ static int write_ldt(void __user * ptr, |
3856 |
+ } |
3857 |
+ } |
3858 |
+ |
3859 |
++#ifdef CONFIG_PAX_SEGMEXEC |
3860 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) { |
3861 |
++ error = -EINVAL; |
3862 |
++ goto out_unlock; |
3863 |
++ } |
3864 |
++#endif |
3865 |
++ |
3866 |
+ entry_1 = LDT_entry_a(&ldt_info); |
3867 |
+ entry_2 = LDT_entry_b(&ldt_info); |
3868 |
+ if (oldmode) |
3869 |
+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 |
3870 |
+--- linux-2.6.23.15/arch/i386/kernel/machine_kexec.c 2007-10-09 21:31:38.000000000 +0100 |
3871 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/machine_kexec.c 2008-02-11 10:37:44.000000000 +0000 |
3872 |
+@@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED |
3873 |
+ static u32 kexec_pte0[1024] PAGE_ALIGNED; |
3874 |
+ static u32 kexec_pte1[1024] PAGE_ALIGNED; |
3875 |
+ |
3876 |
+-static void set_idt(void *newidt, __u16 limit) |
3877 |
++static void set_idt(struct desc_struct *newidt, __u16 limit) |
3878 |
+ { |
3879 |
+ struct Xgt_desc_struct curidt; |
3880 |
+ |
3881 |
+ /* ia32 supports unaliged loads & stores */ |
3882 |
+ curidt.size = limit; |
3883 |
+- curidt.address = (unsigned long)newidt; |
3884 |
++ curidt.address = newidt; |
3885 |
+ |
3886 |
+ load_idt(&curidt); |
3887 |
+ }; |
3888 |
+ |
3889 |
+ |
3890 |
+-static void set_gdt(void *newgdt, __u16 limit) |
3891 |
++static void set_gdt(struct desc_struct *newgdt, __u16 limit) |
3892 |
+ { |
3893 |
+ struct Xgt_desc_struct curgdt; |
3894 |
+ |
3895 |
+ /* ia32 supports unaligned loads & stores */ |
3896 |
+ curgdt.size = limit; |
3897 |
+- curgdt.address = (unsigned long)newgdt; |
3898 |
++ curgdt.address = newgdt; |
3899 |
+ |
3900 |
+ load_gdt(&curgdt); |
3901 |
+ }; |
3902 |
+@@ -110,10 +110,10 @@ NORET_TYPE void machine_kexec(struct kim |
3903 |
+ local_irq_disable(); |
3904 |
+ |
3905 |
+ control_page = page_address(image->control_code_page); |
3906 |
+- memcpy(control_page, relocate_kernel, PAGE_SIZE); |
3907 |
++ memcpy(control_page, relocate_kernel + __KERNEL_TEXT_OFFSET, PAGE_SIZE); |
3908 |
+ |
3909 |
+ page_list[PA_CONTROL_PAGE] = __pa(control_page); |
3910 |
+- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; |
3911 |
++ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel + __KERNEL_TEXT_OFFSET; |
3912 |
+ page_list[PA_PGD] = __pa(kexec_pgd); |
3913 |
+ page_list[VA_PGD] = (unsigned long)kexec_pgd; |
3914 |
+ #ifdef CONFIG_X86_PAE |
3915 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/module.c linux-2.6.23.15-grsec/arch/i386/kernel/module.c |
3916 |
+--- linux-2.6.23.15/arch/i386/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
3917 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/module.c 2008-02-11 10:37:44.000000000 +0000 |
3918 |
+@@ -23,6 +23,8 @@ |
3919 |
+ #include <linux/kernel.h> |
3920 |
+ #include <linux/bug.h> |
3921 |
+ |
3922 |
++#include <asm/desc.h> |
3923 |
++ |
3924 |
+ #if 0 |
3925 |
+ #define DEBUGP printk |
3926 |
+ #else |
3927 |
+@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size) |
3928 |
+ { |
3929 |
+ if (size == 0) |
3930 |
+ return NULL; |
3931 |
++ |
3932 |
++#ifdef CONFIG_PAX_KERNEXEC |
3933 |
++ return vmalloc(size); |
3934 |
++#else |
3935 |
+ return vmalloc_exec(size); |
3936 |
++#endif |
3937 |
++ |
3938 |
+ } |
3939 |
+ |
3940 |
++#ifdef CONFIG_PAX_KERNEXEC |
3941 |
++void *module_alloc_exec(unsigned long size) |
3942 |
++{ |
3943 |
++ struct vm_struct *area; |
3944 |
++ |
3945 |
++ if (size == 0) |
3946 |
++ return NULL; |
3947 |
++ |
3948 |
++ area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END); |
3949 |
++ if (area) |
3950 |
++ return area->addr; |
3951 |
++ |
3952 |
++ return NULL; |
3953 |
++} |
3954 |
++#endif |
3955 |
+ |
3956 |
+ /* Free memory returned from module_alloc */ |
3957 |
+ void module_free(struct module *mod, void *module_region) |
3958 |
+@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi |
3959 |
+ table entries. */ |
3960 |
+ } |
3961 |
+ |
3962 |
++#ifdef CONFIG_PAX_KERNEXEC |
3963 |
++void module_free_exec(struct module *mod, void *module_region) |
3964 |
++{ |
3965 |
++ struct vm_struct **p, *tmp; |
3966 |
++ |
3967 |
++ if (!module_region) |
3968 |
++ return; |
3969 |
++ |
3970 |
++ if ((PAGE_SIZE-1) & (unsigned long)module_region) { |
3971 |
++ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region); |
3972 |
++ WARN_ON(1); |
3973 |
++ return; |
3974 |
++ } |
3975 |
++ |
3976 |
++ write_lock(&vmlist_lock); |
3977 |
++ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) |
3978 |
++ if (tmp->addr == module_region) |
3979 |
++ break; |
3980 |
++ |
3981 |
++ if (tmp) { |
3982 |
++ unsigned long cr0; |
3983 |
++ |
3984 |
++ pax_open_kernel(cr0); |
3985 |
++ memset(tmp->addr, 0xCC, tmp->size); |
3986 |
++ pax_close_kernel(cr0); |
3987 |
++ |
3988 |
++ *p = tmp->next; |
3989 |
++ kfree(tmp); |
3990 |
++ } |
3991 |
++ write_unlock(&vmlist_lock); |
3992 |
++ |
3993 |
++ if (!tmp) { |
3994 |
++ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n", |
3995 |
++ module_region); |
3996 |
++ WARN_ON(1); |
3997 |
++ } |
3998 |
++} |
3999 |
++#endif |
4000 |
++ |
4001 |
+ /* We don't need anything special. */ |
4002 |
+ int module_frob_arch_sections(Elf_Ehdr *hdr, |
4003 |
+ Elf_Shdr *sechdrs, |
4004 |
+@@ -63,14 +125,20 @@ int apply_relocate(Elf32_Shdr *sechdrs, |
4005 |
+ unsigned int i; |
4006 |
+ Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr; |
4007 |
+ Elf32_Sym *sym; |
4008 |
+- uint32_t *location; |
4009 |
++ uint32_t *plocation, location; |
4010 |
++ |
4011 |
++#ifdef CONFIG_PAX_KERNEXEC |
4012 |
++ unsigned long cr0; |
4013 |
++#endif |
4014 |
+ |
4015 |
+ DEBUGP("Applying relocate section %u to %u\n", relsec, |
4016 |
+ sechdrs[relsec].sh_info); |
4017 |
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) { |
4018 |
+ /* This is where to make the change */ |
4019 |
+- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr |
4020 |
+- + rel[i].r_offset; |
4021 |
++ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset; |
4022 |
++ location = (uint32_t)plocation; |
4023 |
++ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR) |
4024 |
++ plocation = (void *)plocation + __KERNEL_TEXT_OFFSET; |
4025 |
+ /* This is the symbol it is referring to. Note that all |
4026 |
+ undefined symbols have been resolved. */ |
4027 |
+ sym = (Elf32_Sym *)sechdrs[symindex].sh_addr |
4028 |
+@@ -78,12 +146,32 @@ int apply_relocate(Elf32_Shdr *sechdrs, |
4029 |
+ |
4030 |
+ switch (ELF32_R_TYPE(rel[i].r_info)) { |
4031 |
+ case R_386_32: |
4032 |
++ |
4033 |
++#ifdef CONFIG_PAX_KERNEXEC |
4034 |
++ pax_open_kernel(cr0); |
4035 |
++#endif |
4036 |
++ |
4037 |
+ /* We add the value into the location given */ |
4038 |
+- *location += sym->st_value; |
4039 |
++ *plocation += sym->st_value; |
4040 |
++ |
4041 |
++#ifdef CONFIG_PAX_KERNEXEC |
4042 |
++ pax_close_kernel(cr0); |
4043 |
++#endif |
4044 |
++ |
4045 |
+ break; |
4046 |
+ case R_386_PC32: |
4047 |
++ |
4048 |
++#ifdef CONFIG_PAX_KERNEXEC |
4049 |
++ pax_open_kernel(cr0); |
4050 |
++#endif |
4051 |
++ |
4052 |
+ /* Add the value, subtract its postition */ |
4053 |
+- *location += sym->st_value - (uint32_t)location; |
4054 |
++ *plocation += sym->st_value - location; |
4055 |
++ |
4056 |
++#ifdef CONFIG_PAX_KERNEXEC |
4057 |
++ pax_close_kernel(cr0); |
4058 |
++#endif |
4059 |
++ |
4060 |
+ break; |
4061 |
+ default: |
4062 |
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n", |
4063 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/paravirt.c linux-2.6.23.15-grsec/arch/i386/kernel/paravirt.c |
4064 |
+--- linux-2.6.23.15/arch/i386/kernel/paravirt.c 2007-10-09 21:31:38.000000000 +0100 |
4065 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/paravirt.c 2008-02-11 10:37:44.000000000 +0000 |
4066 |
+@@ -198,7 +198,7 @@ unsigned paravirt_patch_insns(void *insn |
4067 |
+ if (insn_len > len || start == NULL) |
4068 |
+ insn_len = len; |
4069 |
+ else |
4070 |
+- memcpy(insnbuf, start, insn_len); |
4071 |
++ memcpy(insnbuf, start + __KERNEL_TEXT_OFFSET, insn_len); |
4072 |
+ |
4073 |
+ return insn_len; |
4074 |
+ } |
4075 |
+@@ -273,7 +273,7 @@ int paravirt_disable_iospace(void) |
4076 |
+ return ret; |
4077 |
+ } |
4078 |
+ |
4079 |
+-struct paravirt_ops paravirt_ops = { |
4080 |
++struct paravirt_ops paravirt_ops __read_only = { |
4081 |
+ .name = "bare hardware", |
4082 |
+ .paravirt_enabled = 0, |
4083 |
+ .kernel_rpl = 0, |
4084 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/process.c linux-2.6.23.15-grsec/arch/i386/kernel/process.c |
4085 |
+--- linux-2.6.23.15/arch/i386/kernel/process.c 2007-10-09 21:31:38.000000000 +0100 |
4086 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/process.c 2008-02-11 10:37:44.000000000 +0000 |
4087 |
+@@ -68,15 +68,17 @@ EXPORT_SYMBOL(boot_option_idle_override) |
4088 |
+ DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; |
4089 |
+ EXPORT_PER_CPU_SYMBOL(current_task); |
4090 |
+ |
4091 |
++#ifdef CONFIG_SMP |
4092 |
+ DEFINE_PER_CPU(int, cpu_number); |
4093 |
+ EXPORT_PER_CPU_SYMBOL(cpu_number); |
4094 |
++#endif |
4095 |
+ |
4096 |
+ /* |
4097 |
+ * Return saved PC of a blocked thread. |
4098 |
+ */ |
4099 |
+ unsigned long thread_saved_pc(struct task_struct *tsk) |
4100 |
+ { |
4101 |
+- return ((unsigned long *)tsk->thread.esp)[3]; |
4102 |
++ return tsk->thread.eip; |
4103 |
+ } |
4104 |
+ |
4105 |
+ /* |
4106 |
+@@ -307,7 +309,7 @@ void show_regs(struct pt_regs * regs) |
4107 |
+ printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); |
4108 |
+ print_symbol("EIP is at %s\n", regs->eip); |
4109 |
+ |
4110 |
+- if (user_mode_vm(regs)) |
4111 |
++ if (user_mode(regs)) |
4112 |
+ printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); |
4113 |
+ printk(" EFLAGS: %08lx %s (%s %.*s)\n", |
4114 |
+ regs->eflags, print_tainted(), init_utsname()->release, |
4115 |
+@@ -358,8 +360,8 @@ int kernel_thread(int (*fn)(void *), voi |
4116 |
+ regs.ebx = (unsigned long) fn; |
4117 |
+ regs.edx = (unsigned long) arg; |
4118 |
+ |
4119 |
+- regs.xds = __USER_DS; |
4120 |
+- regs.xes = __USER_DS; |
4121 |
++ regs.xds = __KERNEL_DS; |
4122 |
++ regs.xes = __KERNEL_DS; |
4123 |
+ regs.xfs = __KERNEL_PERCPU; |
4124 |
+ regs.orig_eax = -1; |
4125 |
+ regs.eip = (unsigned long) kernel_thread_helper; |
4126 |
+@@ -381,7 +383,7 @@ void exit_thread(void) |
4127 |
+ struct task_struct *tsk = current; |
4128 |
+ struct thread_struct *t = &tsk->thread; |
4129 |
+ int cpu = get_cpu(); |
4130 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
4131 |
++ struct tss_struct *tss = init_tss + cpu; |
4132 |
+ |
4133 |
+ kfree(t->io_bitmap_ptr); |
4134 |
+ t->io_bitmap_ptr = NULL; |
4135 |
+@@ -402,6 +404,7 @@ void flush_thread(void) |
4136 |
+ { |
4137 |
+ struct task_struct *tsk = current; |
4138 |
+ |
4139 |
++ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory"); |
4140 |
+ memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); |
4141 |
+ memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); |
4142 |
+ clear_tsk_thread_flag(tsk, TIF_DEBUG); |
4143 |
+@@ -435,7 +438,7 @@ int copy_thread(int nr, unsigned long cl |
4144 |
+ struct task_struct *tsk; |
4145 |
+ int err; |
4146 |
+ |
4147 |
+- childregs = task_pt_regs(p); |
4148 |
++ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8; |
4149 |
+ *childregs = *regs; |
4150 |
+ childregs->eax = 0; |
4151 |
+ childregs->esp = esp; |
4152 |
+@@ -477,6 +480,11 @@ int copy_thread(int nr, unsigned long cl |
4153 |
+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) |
4154 |
+ goto out; |
4155 |
+ |
4156 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4157 |
++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) |
4158 |
++ goto out; |
4159 |
++#endif |
4160 |
++ |
4161 |
+ desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; |
4162 |
+ desc->a = LDT_entry_a(&info); |
4163 |
+ desc->b = LDT_entry_b(&info); |
4164 |
+@@ -663,7 +671,7 @@ struct task_struct fastcall * __switch_t |
4165 |
+ struct thread_struct *prev = &prev_p->thread, |
4166 |
+ *next = &next_p->thread; |
4167 |
+ int cpu = smp_processor_id(); |
4168 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
4169 |
++ struct tss_struct *tss = init_tss + cpu; |
4170 |
+ |
4171 |
+ /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ |
4172 |
+ |
4173 |
+@@ -691,6 +699,11 @@ struct task_struct fastcall * __switch_t |
4174 |
+ */ |
4175 |
+ savesegment(gs, prev->gs); |
4176 |
+ |
4177 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
4178 |
++ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit)) |
4179 |
++ __set_fs(task_thread_info(next_p)->addr_limit, cpu); |
4180 |
++#endif |
4181 |
++ |
4182 |
+ /* |
4183 |
+ * Load the per-thread Thread-Local Storage descriptor. |
4184 |
+ */ |
4185 |
+@@ -855,6 +868,12 @@ asmlinkage int sys_set_thread_area(struc |
4186 |
+ |
4187 |
+ if (copy_from_user(&info, u_info, sizeof(info))) |
4188 |
+ return -EFAULT; |
4189 |
++ |
4190 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4191 |
++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) |
4192 |
++ return -EINVAL; |
4193 |
++#endif |
4194 |
++ |
4195 |
+ idx = info.entry_number; |
4196 |
+ |
4197 |
+ /* |
4198 |
+@@ -943,9 +962,28 @@ asmlinkage int sys_get_thread_area(struc |
4199 |
+ return 0; |
4200 |
+ } |
4201 |
+ |
4202 |
+-unsigned long arch_align_stack(unsigned long sp) |
4203 |
++#ifdef CONFIG_PAX_RANDKSTACK |
4204 |
++asmlinkage void pax_randomize_kstack(void) |
4205 |
+ { |
4206 |
+- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
4207 |
+- sp -= get_random_int() % 8192; |
4208 |
+- return sp & ~0xf; |
4209 |
++ struct tss_struct *tss; |
4210 |
++ unsigned long time; |
4211 |
++ |
4212 |
++ if (!randomize_va_space) |
4213 |
++ return; |
4214 |
++ |
4215 |
++ tss = init_tss + smp_processor_id(); |
4216 |
++ rdtscl(time); |
4217 |
++ |
4218 |
++ /* P4 seems to return a 0 LSB, ignore it */ |
4219 |
++#ifdef CONFIG_MPENTIUM4 |
4220 |
++ time &= 0x1EUL; |
4221 |
++ time <<= 2; |
4222 |
++#else |
4223 |
++ time &= 0xFUL; |
4224 |
++ time <<= 3; |
4225 |
++#endif |
4226 |
++ |
4227 |
++ tss->x86_tss.esp0 ^= time; |
4228 |
++ current->thread.esp0 = tss->x86_tss.esp0; |
4229 |
+ } |
4230 |
++#endif |
4231 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/ptrace.c linux-2.6.23.15-grsec/arch/i386/kernel/ptrace.c |
4232 |
+--- linux-2.6.23.15/arch/i386/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100 |
4233 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000 |
4234 |
+@@ -161,22 +161,20 @@ static unsigned long convert_eip_to_line |
4235 |
+ * and APM bios ones we just ignore here. |
4236 |
+ */ |
4237 |
+ if (seg & LDT_SEGMENT) { |
4238 |
+- u32 *desc; |
4239 |
++ struct desc_struct *desc; |
4240 |
+ unsigned long base; |
4241 |
+ |
4242 |
+ seg &= ~7UL; |
4243 |
+ |
4244 |
+ down(&child->mm->context.sem); |
4245 |
+ if (unlikely((seg >> 3) >= child->mm->context.size)) |
4246 |
+- addr = -1L; /* bogus selector, access would fault */ |
4247 |
++ addr = -EINVAL; |
4248 |
+ else { |
4249 |
+- desc = child->mm->context.ldt + seg; |
4250 |
+- base = ((desc[0] >> 16) | |
4251 |
+- ((desc[1] & 0xff) << 16) | |
4252 |
+- (desc[1] & 0xff000000)); |
4253 |
++ desc = &child->mm->context.ldt[seg >> 3]; |
4254 |
++ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000); |
4255 |
+ |
4256 |
+ /* 16-bit code segment? */ |
4257 |
+- if (!((desc[1] >> 22) & 1)) |
4258 |
++ if (!((desc->b >> 22) & 1)) |
4259 |
+ addr &= 0xffff; |
4260 |
+ addr += base; |
4261 |
+ } |
4262 |
+@@ -191,6 +189,9 @@ static inline int is_setting_trap_flag(s |
4263 |
+ unsigned char opcode[15]; |
4264 |
+ unsigned long addr = convert_eip_to_linear(child, regs); |
4265 |
+ |
4266 |
++ if (addr == -EINVAL) |
4267 |
++ return 0; |
4268 |
++ |
4269 |
+ copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); |
4270 |
+ for (i = 0; i < copied; i++) { |
4271 |
+ switch (opcode[i]) { |
4272 |
+@@ -341,6 +342,11 @@ ptrace_set_thread_area(struct task_struc |
4273 |
+ if (copy_from_user(&info, user_desc, sizeof(info))) |
4274 |
+ return -EFAULT; |
4275 |
+ |
4276 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4277 |
++ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE)) |
4278 |
++ return -EINVAL; |
4279 |
++#endif |
4280 |
++ |
4281 |
+ if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) |
4282 |
+ return -EINVAL; |
4283 |
+ |
4284 |
+@@ -420,6 +426,17 @@ long arch_ptrace(struct task_struct *chi |
4285 |
+ if(addr == (long) &dummy->u_debugreg[5]) break; |
4286 |
+ if(addr < (long) &dummy->u_debugreg[4] && |
4287 |
+ ((unsigned long) data) >= TASK_SIZE-3) break; |
4288 |
++ |
4289 |
++#ifdef CONFIG_GRKERNSEC |
4290 |
++ if(addr >= (long) &dummy->u_debugreg[0] && |
4291 |
++ addr <= (long) &dummy->u_debugreg[3]){ |
4292 |
++ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2; |
4293 |
++ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3; |
4294 |
++ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3; |
4295 |
++ if((type & 1) && (data & align)) |
4296 |
++ break; |
4297 |
++ } |
4298 |
++#endif |
4299 |
+ |
4300 |
+ /* Sanity-check data. Take one half-byte at once with |
4301 |
+ * check = (val >> (16 + 4*i)) & 0xf. It contains the |
4302 |
+@@ -636,7 +653,7 @@ void send_sigtrap(struct task_struct *ts |
4303 |
+ info.si_code = TRAP_BRKPT; |
4304 |
+ |
4305 |
+ /* User-mode eip? */ |
4306 |
+- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL; |
4307 |
++ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL; |
4308 |
+ |
4309 |
+ /* Send us the fakey SIGTRAP */ |
4310 |
+ force_sig_info(SIGTRAP, &info, tsk); |
4311 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/reboot.c linux-2.6.23.15-grsec/arch/i386/kernel/reboot.c |
4312 |
+--- linux-2.6.23.15/arch/i386/kernel/reboot.c 2007-10-09 21:31:38.000000000 +0100 |
4313 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/reboot.c 2008-02-11 10:37:44.000000000 +0000 |
4314 |
+@@ -26,7 +26,7 @@ |
4315 |
+ void (*pm_power_off)(void); |
4316 |
+ EXPORT_SYMBOL(pm_power_off); |
4317 |
+ |
4318 |
+-static int reboot_mode; |
4319 |
++static unsigned short reboot_mode; |
4320 |
+ static int reboot_thru_bios; |
4321 |
+ |
4322 |
+ #ifdef CONFIG_SMP |
4323 |
+@@ -138,7 +138,7 @@ static struct dmi_system_id __initdata r |
4324 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), |
4325 |
+ }, |
4326 |
+ }, |
4327 |
+- { } |
4328 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
4329 |
+ }; |
4330 |
+ |
4331 |
+ static int __init reboot_init(void) |
4332 |
+@@ -156,18 +156,18 @@ core_initcall(reboot_init); |
4333 |
+ doesn't work with at least one type of 486 motherboard. It is easy |
4334 |
+ to stop this code working; hence the copious comments. */ |
4335 |
+ |
4336 |
+-static unsigned long long |
4337 |
+-real_mode_gdt_entries [3] = |
4338 |
++static struct desc_struct |
4339 |
++real_mode_gdt_entries [3] __read_only = |
4340 |
+ { |
4341 |
+- 0x0000000000000000ULL, /* Null descriptor */ |
4342 |
+- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */ |
4343 |
+- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ |
4344 |
++ {0x00000000, 0x00000000}, /* Null descriptor */ |
4345 |
++ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */ |
4346 |
++ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */ |
4347 |
+ }; |
4348 |
+ |
4349 |
+-static struct Xgt_desc_struct |
4350 |
+-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries }, |
4351 |
+-real_mode_idt = { 0x3ff, 0 }, |
4352 |
+-no_idt = { 0, 0 }; |
4353 |
++static const struct Xgt_desc_struct |
4354 |
++real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 }, |
4355 |
++real_mode_idt = { 0x3ff, NULL, 0 }, |
4356 |
++no_idt = { 0, NULL, 0 }; |
4357 |
+ |
4358 |
+ |
4359 |
+ /* This is 16-bit protected mode code to disable paging and the cache, |
4360 |
+@@ -189,7 +189,7 @@ no_idt = { 0, 0 }; |
4361 |
+ More could be done here to set up the registers as if a CPU reset had |
4362 |
+ occurred; hopefully real BIOSs don't assume much. */ |
4363 |
+ |
4364 |
+-static unsigned char real_mode_switch [] = |
4365 |
++static const unsigned char real_mode_switch [] = |
4366 |
+ { |
4367 |
+ 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ |
4368 |
+ 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */ |
4369 |
+@@ -203,7 +203,7 @@ static unsigned char real_mode_switch [] |
4370 |
+ 0x24, 0x10, /* f: andb $0x10,al */ |
4371 |
+ 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ |
4372 |
+ }; |
4373 |
+-static unsigned char jump_to_bios [] = |
4374 |
++static const unsigned char jump_to_bios [] = |
4375 |
+ { |
4376 |
+ 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */ |
4377 |
+ }; |
4378 |
+@@ -213,7 +213,7 @@ static unsigned char jump_to_bios [] = |
4379 |
+ * specified by the code and length parameters. |
4380 |
+ * We assume that length will aways be less that 100! |
4381 |
+ */ |
4382 |
+-void machine_real_restart(unsigned char *code, int length) |
4383 |
++void machine_real_restart(const unsigned char *code, unsigned int length) |
4384 |
+ { |
4385 |
+ local_irq_disable(); |
4386 |
+ |
4387 |
+@@ -234,9 +234,8 @@ void machine_real_restart(unsigned char |
4388 |
+ /* Remap the kernel at virtual address zero, as well as offset zero |
4389 |
+ from the kernel segment. This assumes the kernel segment starts at |
4390 |
+ virtual address PAGE_OFFSET. */ |
4391 |
+- |
4392 |
+- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
4393 |
+- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS); |
4394 |
++ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, |
4395 |
++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); |
4396 |
+ |
4397 |
+ /* |
4398 |
+ * Use `swapper_pg_dir' as our page directory. |
4399 |
+@@ -249,7 +248,7 @@ void machine_real_restart(unsigned char |
4400 |
+ REBOOT.COM programs, and the previous reset routine did this |
4401 |
+ too. */ |
4402 |
+ |
4403 |
+- *((unsigned short *)0x472) = reboot_mode; |
4404 |
++ *(unsigned short *)(__va(0x472)) = reboot_mode; |
4405 |
+ |
4406 |
+ /* For the switch to real mode, copy some code to low memory. It has |
4407 |
+ to be in the first 64k because it is running in 16-bit mode, and it |
4408 |
+@@ -257,9 +256,8 @@ void machine_real_restart(unsigned char |
4409 |
+ off paging. Copy it near the end of the first page, out of the way |
4410 |
+ of BIOS variables. */ |
4411 |
+ |
4412 |
+- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100), |
4413 |
+- real_mode_switch, sizeof (real_mode_switch)); |
4414 |
+- memcpy ((void *) (0x1000 - 100), code, length); |
4415 |
++ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch)); |
4416 |
++ memcpy(__va(0x1000 - 100), code, length); |
4417 |
+ |
4418 |
+ /* Set up the IDT for real mode. */ |
4419 |
+ |
4420 |
+@@ -345,7 +343,7 @@ static void native_machine_emergency_res |
4421 |
+ __asm__ __volatile__("int3"); |
4422 |
+ } |
4423 |
+ /* rebooting needs to touch the page at absolute addr 0 */ |
4424 |
+- *((unsigned short *)__va(0x472)) = reboot_mode; |
4425 |
++ *(unsigned short *)(__va(0x472)) = reboot_mode; |
4426 |
+ for (;;) { |
4427 |
+ mach_reboot_fixups(); /* for board specific fixups */ |
4428 |
+ mach_reboot(); |
4429 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/setup.c linux-2.6.23.15-grsec/arch/i386/kernel/setup.c |
4430 |
+--- linux-2.6.23.15/arch/i386/kernel/setup.c 2007-10-09 21:31:38.000000000 +0100 |
4431 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/setup.c 2008-02-11 10:37:44.000000000 +0000 |
4432 |
+@@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini |
4433 |
+ struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; |
4434 |
+ EXPORT_SYMBOL(boot_cpu_data); |
4435 |
+ |
4436 |
++#ifdef CONFIG_X86_PAE |
4437 |
++unsigned long mmu_cr4_features = X86_CR4_PAE; |
4438 |
++#else |
4439 |
+ unsigned long mmu_cr4_features; |
4440 |
++#endif |
4441 |
+ |
4442 |
+ /* for MCA, but anyone else can use it if they want */ |
4443 |
+ unsigned int machine_id; |
4444 |
+@@ -395,8 +399,8 @@ void __init setup_bootmem_allocator(void |
4445 |
+ * the (very unlikely) case of us accidentally initializing the |
4446 |
+ * bootmem allocator with an invalid RAM area. |
4447 |
+ */ |
4448 |
+- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + |
4449 |
+- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text)); |
4450 |
++ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) + |
4451 |
++ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR); |
4452 |
+ |
4453 |
+ /* |
4454 |
+ * reserve physical page 0 - it's a special BIOS page on many boxes, |
4455 |
+@@ -549,14 +553,14 @@ void __init setup_arch(char **cmdline_p) |
4456 |
+ |
4457 |
+ if (!MOUNT_ROOT_RDONLY) |
4458 |
+ root_mountflags &= ~MS_RDONLY; |
4459 |
+- init_mm.start_code = (unsigned long) _text; |
4460 |
+- init_mm.end_code = (unsigned long) _etext; |
4461 |
++ init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET; |
4462 |
++ init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET; |
4463 |
+ init_mm.end_data = (unsigned long) _edata; |
4464 |
+ init_mm.brk = init_pg_tables_end + PAGE_OFFSET; |
4465 |
+ |
4466 |
+- code_resource.start = virt_to_phys(_text); |
4467 |
+- code_resource.end = virt_to_phys(_etext)-1; |
4468 |
+- data_resource.start = virt_to_phys(_etext); |
4469 |
++ code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET); |
4470 |
++ code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1; |
4471 |
++ data_resource.start = virt_to_phys(_data); |
4472 |
+ data_resource.end = virt_to_phys(_edata)-1; |
4473 |
+ |
4474 |
+ parse_early_param(); |
4475 |
+@@ -651,3 +655,23 @@ void __init setup_arch(char **cmdline_p) |
4476 |
+ #endif |
4477 |
+ #endif |
4478 |
+ } |
4479 |
++ |
4480 |
++unsigned long __per_cpu_offset[NR_CPUS] __read_only; |
4481 |
++ |
4482 |
++EXPORT_SYMBOL(__per_cpu_offset); |
4483 |
++ |
4484 |
++void __init setup_per_cpu_areas(void) |
4485 |
++{ |
4486 |
++ unsigned long size, i; |
4487 |
++ char *ptr; |
4488 |
++ |
4489 |
++ /* Copy section for each CPU (we discard the original) */ |
4490 |
++ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE); |
4491 |
++ ptr = alloc_bootmem_pages(size * num_possible_cpus()); |
4492 |
++ |
4493 |
++ for_each_possible_cpu(i) { |
4494 |
++ __per_cpu_offset[i] = (unsigned long)ptr; |
4495 |
++ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); |
4496 |
++ ptr += size; |
4497 |
++ } |
4498 |
++} |
4499 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/signal.c linux-2.6.23.15-grsec/arch/i386/kernel/signal.c |
4500 |
+--- linux-2.6.23.15/arch/i386/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100 |
4501 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/signal.c 2008-02-11 10:37:44.000000000 +0000 |
4502 |
+@@ -357,9 +357,9 @@ static int setup_frame(int sig, struct k |
4503 |
+ } |
4504 |
+ |
4505 |
+ if (current->binfmt->hasvdso) |
4506 |
+- restorer = (void *)VDSO_SYM(&__kernel_sigreturn); |
4507 |
++ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn); |
4508 |
+ else |
4509 |
+- restorer = (void *)&frame->retcode; |
4510 |
++ restorer = (void __user *)&frame->retcode; |
4511 |
+ if (ka->sa.sa_flags & SA_RESTORER) |
4512 |
+ restorer = ka->sa.sa_restorer; |
4513 |
+ |
4514 |
+@@ -455,7 +455,8 @@ static int setup_rt_frame(int sig, struc |
4515 |
+ goto give_sigsegv; |
4516 |
+ |
4517 |
+ /* Set up to return from userspace. */ |
4518 |
+- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn); |
4519 |
++ |
4520 |
++ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn); |
4521 |
+ if (ka->sa.sa_flags & SA_RESTORER) |
4522 |
+ restorer = ka->sa.sa_restorer; |
4523 |
+ err |= __put_user(restorer, &frame->pretcode); |
4524 |
+@@ -588,7 +589,7 @@ static void fastcall do_signal(struct pt |
4525 |
+ * before reaching here, so testing against kernel |
4526 |
+ * CS suffices. |
4527 |
+ */ |
4528 |
+- if (!user_mode(regs)) |
4529 |
++ if (!user_mode_novm(regs)) |
4530 |
+ return; |
4531 |
+ |
4532 |
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
4533 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/smp.c linux-2.6.23.15-grsec/arch/i386/kernel/smp.c |
4534 |
+--- linux-2.6.23.15/arch/i386/kernel/smp.c 2007-10-09 21:31:38.000000000 +0100 |
4535 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/smp.c 2008-02-11 10:37:44.000000000 +0000 |
4536 |
+@@ -104,7 +104,7 @@ |
4537 |
+ * about nothing of note with C stepping upwards. |
4538 |
+ */ |
4539 |
+ |
4540 |
+-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, }; |
4541 |
++DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} }; |
4542 |
+ |
4543 |
+ /* |
4544 |
+ * the following functions deal with sending IPIs between CPUs. |
4545 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/smpboot.c linux-2.6.23.15-grsec/arch/i386/kernel/smpboot.c |
4546 |
+--- linux-2.6.23.15/arch/i386/kernel/smpboot.c 2007-10-09 21:31:38.000000000 +0100 |
4547 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/smpboot.c 2008-02-11 10:37:44.000000000 +0000 |
4548 |
+@@ -118,7 +118,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 }; |
4549 |
+ * has made sure it's suitably aligned. |
4550 |
+ */ |
4551 |
+ |
4552 |
+-static unsigned long __devinit setup_trampoline(void) |
4553 |
++static unsigned long __cpuinit setup_trampoline(void) |
4554 |
+ { |
4555 |
+ memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); |
4556 |
+ return virt_to_phys(trampoline_base); |
4557 |
+@@ -772,6 +772,10 @@ static int __cpuinit do_boot_cpu(int api |
4558 |
+ unsigned long start_eip; |
4559 |
+ unsigned short nmi_high = 0, nmi_low = 0; |
4560 |
+ |
4561 |
++#ifdef CONFIG_PAX_KERNEXEC |
4562 |
++ unsigned long cr0; |
4563 |
++#endif |
4564 |
++ |
4565 |
+ /* |
4566 |
+ * Save current MTRR state in case it was changed since early boot |
4567 |
+ * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync: |
4568 |
+@@ -788,7 +792,16 @@ static int __cpuinit do_boot_cpu(int api |
4569 |
+ |
4570 |
+ init_gdt(cpu); |
4571 |
+ per_cpu(current_task, cpu) = idle; |
4572 |
+- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
4573 |
++ |
4574 |
++#ifdef CONFIG_PAX_KERNEXEC |
4575 |
++ pax_open_kernel(cr0); |
4576 |
++#endif |
4577 |
++ |
4578 |
++ early_gdt_descr.address = get_cpu_gdt_table(cpu); |
4579 |
++ |
4580 |
++#ifdef CONFIG_PAX_KERNEXEC |
4581 |
++ pax_close_kernel(cr0); |
4582 |
++#endif |
4583 |
+ |
4584 |
+ idle->thread.eip = (unsigned long) start_secondary; |
4585 |
+ /* start_eip had better be page-aligned! */ |
4586 |
+@@ -1105,7 +1118,7 @@ static void __init smp_boot_cpus(unsigne |
4587 |
+ * construct cpu_sibling_map[], so that we can tell sibling CPUs |
4588 |
+ * efficiently. |
4589 |
+ */ |
4590 |
+- for (cpu = 0; cpu < NR_CPUS; cpu++) { |
4591 |
++ for_each_possible_cpu(cpu) { |
4592 |
+ cpus_clear(cpu_sibling_map[cpu]); |
4593 |
+ cpus_clear(cpu_core_map[cpu]); |
4594 |
+ } |
4595 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/smpcommon.c linux-2.6.23.15-grsec/arch/i386/kernel/smpcommon.c |
4596 |
+--- linux-2.6.23.15/arch/i386/kernel/smpcommon.c 2007-10-09 21:31:38.000000000 +0100 |
4597 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/smpcommon.c 2008-02-11 10:37:44.000000000 +0000 |
4598 |
+@@ -3,6 +3,7 @@ |
4599 |
+ */ |
4600 |
+ #include <linux/module.h> |
4601 |
+ #include <asm/smp.h> |
4602 |
++#include <asm/sections.h> |
4603 |
+ |
4604 |
+ DEFINE_PER_CPU(unsigned long, this_cpu_off); |
4605 |
+ EXPORT_PER_CPU_SYMBOL(this_cpu_off); |
4606 |
+@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu) |
4607 |
+ { |
4608 |
+ struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
4609 |
+ |
4610 |
+- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a, |
4611 |
+- (u32 *)&gdt[GDT_ENTRY_PERCPU].b, |
4612 |
+- __per_cpu_offset[cpu], 0xFFFFF, |
4613 |
+- 0x80 | DESCTYPE_S | 0x2, 0x8); |
4614 |
++#ifdef CONFIG_PAX_KERNEXEC |
4615 |
++ unsigned long cr0; |
4616 |
++ |
4617 |
++ pax_open_kernel(cr0); |
4618 |
++#endif |
4619 |
++ |
4620 |
++ if (cpu) |
4621 |
++ memcpy(gdt, cpu_gdt_table, GDT_SIZE); |
4622 |
++ |
4623 |
++ if (PERCPU_ENOUGH_ROOM <= 64*1024*1024) |
4624 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a, |
4625 |
++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b, |
4626 |
++ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1, |
4627 |
++ 0x80 | DESCTYPE_S | 0x3, 0x4); |
4628 |
++ else |
4629 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a, |
4630 |
++ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b, |
4631 |
++ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT), |
4632 |
++ 0x80 | DESCTYPE_S | 0x3, 0xC); |
4633 |
++ |
4634 |
++#ifdef CONFIG_PAX_KERNEXEC |
4635 |
++ pax_close_kernel(cr0); |
4636 |
++#endif |
4637 |
+ |
4638 |
+ per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu]; |
4639 |
+ per_cpu(cpu_number, cpu) = cpu; |
4640 |
+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 |
4641 |
+--- linux-2.6.23.15/arch/i386/kernel/sys_i386.c 2007-10-09 21:31:38.000000000 +0100 |
4642 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/sys_i386.c 2008-02-11 10:37:44.000000000 +0000 |
4643 |
+@@ -41,6 +41,21 @@ asmlinkage int sys_pipe(unsigned long __ |
4644 |
+ return error; |
4645 |
+ } |
4646 |
+ |
4647 |
++int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) |
4648 |
++{ |
4649 |
++ unsigned long task_size = TASK_SIZE; |
4650 |
++ |
4651 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4652 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) |
4653 |
++ task_size = SEGMEXEC_TASK_SIZE; |
4654 |
++#endif |
4655 |
++ |
4656 |
++ if (len > task_size || addr > task_size - len) |
4657 |
++ return -EINVAL; |
4658 |
++ |
4659 |
++ return 0; |
4660 |
++} |
4661 |
++ |
4662 |
+ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, |
4663 |
+ unsigned long prot, unsigned long flags, |
4664 |
+ unsigned long fd, unsigned long pgoff) |
4665 |
+@@ -100,6 +115,205 @@ out: |
4666 |
+ return err; |
4667 |
+ } |
4668 |
+ |
4669 |
++unsigned long |
4670 |
++arch_get_unmapped_area(struct file *filp, unsigned long addr, |
4671 |
++ unsigned long len, unsigned long pgoff, unsigned long flags) |
4672 |
++{ |
4673 |
++ struct mm_struct *mm = current->mm; |
4674 |
++ struct vm_area_struct *vma; |
4675 |
++ unsigned long start_addr, task_size = TASK_SIZE; |
4676 |
++ |
4677 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4678 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
4679 |
++ task_size = SEGMEXEC_TASK_SIZE; |
4680 |
++#endif |
4681 |
++ |
4682 |
++ if (len > task_size) |
4683 |
++ return -ENOMEM; |
4684 |
++ |
4685 |
++ if (flags & MAP_FIXED) |
4686 |
++ return addr; |
4687 |
++ |
4688 |
++#ifdef CONFIG_PAX_RANDMMAP |
4689 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
4690 |
++#endif |
4691 |
++ |
4692 |
++ if (addr) { |
4693 |
++ addr = PAGE_ALIGN(addr); |
4694 |
++ vma = find_vma(mm, addr); |
4695 |
++ if (task_size - len >= addr && |
4696 |
++ (!vma || addr + len <= vma->vm_start)) |
4697 |
++ return addr; |
4698 |
++ } |
4699 |
++ if (len > mm->cached_hole_size) { |
4700 |
++ start_addr = addr = mm->free_area_cache; |
4701 |
++ } else { |
4702 |
++ start_addr = addr = mm->mmap_base; |
4703 |
++ mm->cached_hole_size = 0; |
4704 |
++ } |
4705 |
++ |
4706 |
++#ifdef CONFIG_PAX_PAGEEXEC |
4707 |
++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) { |
4708 |
++ start_addr = 0x00110000UL; |
4709 |
++ |
4710 |
++#ifdef CONFIG_PAX_RANDMMAP |
4711 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
4712 |
++ start_addr += mm->delta_mmap & 0x03FFF000UL; |
4713 |
++#endif |
4714 |
++ |
4715 |
++ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base) |
4716 |
++ start_addr = addr = mm->mmap_base; |
4717 |
++ else |
4718 |
++ addr = start_addr; |
4719 |
++ } |
4720 |
++#endif |
4721 |
++ |
4722 |
++full_search: |
4723 |
++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { |
4724 |
++ /* At this point: (!vma || addr < vma->vm_end). */ |
4725 |
++ if (task_size - len < addr) { |
4726 |
++ /* |
4727 |
++ * Start a new search - just in case we missed |
4728 |
++ * some holes. |
4729 |
++ */ |
4730 |
++ if (start_addr != mm->mmap_base) { |
4731 |
++ start_addr = addr = mm->mmap_base; |
4732 |
++ mm->cached_hole_size = 0; |
4733 |
++ goto full_search; |
4734 |
++ } |
4735 |
++ return -ENOMEM; |
4736 |
++ } |
4737 |
++ if (!vma || addr + len <= vma->vm_start) { |
4738 |
++ /* |
4739 |
++ * Remember the place where we stopped the search: |
4740 |
++ */ |
4741 |
++ mm->free_area_cache = addr + len; |
4742 |
++ return addr; |
4743 |
++ } |
4744 |
++ if (addr + mm->cached_hole_size < vma->vm_start) |
4745 |
++ mm->cached_hole_size = vma->vm_start - addr; |
4746 |
++ addr = vma->vm_end; |
4747 |
++ if (mm->start_brk <= addr && addr < mm->mmap_base) { |
4748 |
++ start_addr = addr = mm->mmap_base; |
4749 |
++ mm->cached_hole_size = 0; |
4750 |
++ goto full_search; |
4751 |
++ } |
4752 |
++ } |
4753 |
++} |
4754 |
++ |
4755 |
++unsigned long |
4756 |
++arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, |
4757 |
++ const unsigned long len, const unsigned long pgoff, |
4758 |
++ const unsigned long flags) |
4759 |
++{ |
4760 |
++ struct vm_area_struct *vma; |
4761 |
++ struct mm_struct *mm = current->mm; |
4762 |
++ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE; |
4763 |
++ |
4764 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4765 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
4766 |
++ task_size = SEGMEXEC_TASK_SIZE; |
4767 |
++#endif |
4768 |
++ |
4769 |
++ /* requested length too big for entire address space */ |
4770 |
++ if (len > task_size) |
4771 |
++ return -ENOMEM; |
4772 |
++ |
4773 |
++ if (flags & MAP_FIXED) |
4774 |
++ return addr; |
4775 |
++ |
4776 |
++#ifdef CONFIG_PAX_PAGEEXEC |
4777 |
++ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE)) |
4778 |
++ goto bottomup; |
4779 |
++#endif |
4780 |
++ |
4781 |
++#ifdef CONFIG_PAX_RANDMMAP |
4782 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
4783 |
++#endif |
4784 |
++ |
4785 |
++ /* requesting a specific address */ |
4786 |
++ if (addr) { |
4787 |
++ addr = PAGE_ALIGN(addr); |
4788 |
++ vma = find_vma(mm, addr); |
4789 |
++ if (task_size - len >= addr && |
4790 |
++ (!vma || addr + len <= vma->vm_start)) |
4791 |
++ return addr; |
4792 |
++ } |
4793 |
++ |
4794 |
++ /* check if free_area_cache is useful for us */ |
4795 |
++ if (len <= mm->cached_hole_size) { |
4796 |
++ mm->cached_hole_size = 0; |
4797 |
++ mm->free_area_cache = mm->mmap_base; |
4798 |
++ } |
4799 |
++ |
4800 |
++ /* either no address requested or can't fit in requested address hole */ |
4801 |
++ addr = mm->free_area_cache; |
4802 |
++ |
4803 |
++ /* make sure it can fit in the remaining address space */ |
4804 |
++ if (addr > len) { |
4805 |
++ vma = find_vma(mm, addr-len); |
4806 |
++ if (!vma || addr <= vma->vm_start) |
4807 |
++ /* remember the address as a hint for next time */ |
4808 |
++ return (mm->free_area_cache = addr-len); |
4809 |
++ } |
4810 |
++ |
4811 |
++ if (mm->mmap_base < len) |
4812 |
++ goto bottomup; |
4813 |
++ |
4814 |
++ addr = mm->mmap_base-len; |
4815 |
++ |
4816 |
++ do { |
4817 |
++ /* |
4818 |
++ * Lookup failure means no vma is above this address, |
4819 |
++ * else if new region fits below vma->vm_start, |
4820 |
++ * return with success: |
4821 |
++ */ |
4822 |
++ vma = find_vma(mm, addr); |
4823 |
++ if (!vma || addr+len <= vma->vm_start) |
4824 |
++ /* remember the address as a hint for next time */ |
4825 |
++ return (mm->free_area_cache = addr); |
4826 |
++ |
4827 |
++ /* remember the largest hole we saw so far */ |
4828 |
++ if (addr + mm->cached_hole_size < vma->vm_start) |
4829 |
++ mm->cached_hole_size = vma->vm_start - addr; |
4830 |
++ |
4831 |
++ /* try just below the current vma->vm_start */ |
4832 |
++ addr = vma->vm_start-len; |
4833 |
++ } while (len < vma->vm_start); |
4834 |
++ |
4835 |
++bottomup: |
4836 |
++ /* |
4837 |
++ * A failed mmap() very likely causes application failure, |
4838 |
++ * so fall back to the bottom-up function here. This scenario |
4839 |
++ * can happen with large stack limits and large mmap() |
4840 |
++ * allocations. |
4841 |
++ */ |
4842 |
++ |
4843 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4844 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
4845 |
++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; |
4846 |
++ else |
4847 |
++#endif |
4848 |
++ |
4849 |
++ mm->mmap_base = TASK_UNMAPPED_BASE; |
4850 |
++ |
4851 |
++#ifdef CONFIG_PAX_RANDMMAP |
4852 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
4853 |
++ mm->mmap_base += mm->delta_mmap; |
4854 |
++#endif |
4855 |
++ |
4856 |
++ mm->free_area_cache = mm->mmap_base; |
4857 |
++ mm->cached_hole_size = ~0UL; |
4858 |
++ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); |
4859 |
++ /* |
4860 |
++ * Restore the topdown base: |
4861 |
++ */ |
4862 |
++ mm->mmap_base = base; |
4863 |
++ mm->free_area_cache = base; |
4864 |
++ mm->cached_hole_size = ~0UL; |
4865 |
++ |
4866 |
++ return addr; |
4867 |
++} |
4868 |
+ |
4869 |
+ struct sel_arg_struct { |
4870 |
+ unsigned long n; |
4871 |
+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 |
4872 |
+--- linux-2.6.23.15/arch/i386/kernel/syscall_table.S 2007-10-09 21:31:38.000000000 +0100 |
4873 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/syscall_table.S 2008-02-11 10:37:44.000000000 +0000 |
4874 |
+@@ -1,3 +1,4 @@ |
4875 |
++.section .rodata,"a",@progbits |
4876 |
+ ENTRY(sys_call_table) |
4877 |
+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */ |
4878 |
+ .long sys_exit |
4879 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/sysenter.c linux-2.6.23.15-grsec/arch/i386/kernel/sysenter.c |
4880 |
+--- linux-2.6.23.15/arch/i386/kernel/sysenter.c 2007-10-09 21:31:38.000000000 +0100 |
4881 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/sysenter.c 2008-02-11 10:37:44.000000000 +0000 |
4882 |
+@@ -177,7 +177,7 @@ static __init void relocate_vdso(Elf32_E |
4883 |
+ void enable_sep_cpu(void) |
4884 |
+ { |
4885 |
+ int cpu = get_cpu(); |
4886 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
4887 |
++ struct tss_struct *tss = init_tss + cpu; |
4888 |
+ |
4889 |
+ if (!boot_cpu_has(X86_FEATURE_SEP)) { |
4890 |
+ put_cpu(); |
4891 |
+@@ -200,7 +200,7 @@ static int __init gate_vma_init(void) |
4892 |
+ gate_vma.vm_start = FIXADDR_USER_START; |
4893 |
+ gate_vma.vm_end = FIXADDR_USER_END; |
4894 |
+ gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; |
4895 |
+- gate_vma.vm_page_prot = __P101; |
4896 |
++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags); |
4897 |
+ /* |
4898 |
+ * Make sure the vDSO gets into every core dump. |
4899 |
+ * Dumping its contents makes post-mortem fully interpretable later |
4900 |
+@@ -283,7 +283,7 @@ int arch_setup_additional_pages(struct l |
4901 |
+ if (compat) |
4902 |
+ addr = VDSO_HIGH_BASE; |
4903 |
+ else { |
4904 |
+- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); |
4905 |
++ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE); |
4906 |
+ if (IS_ERR_VALUE(addr)) { |
4907 |
+ ret = addr; |
4908 |
+ goto up_fail; |
4909 |
+@@ -308,7 +308,7 @@ int arch_setup_additional_pages(struct l |
4910 |
+ goto up_fail; |
4911 |
+ } |
4912 |
+ |
4913 |
+- current->mm->context.vdso = (void *)addr; |
4914 |
++ current->mm->context.vdso = addr; |
4915 |
+ current_thread_info()->sysenter_return = |
4916 |
+ (void *)VDSO_SYM(&SYSENTER_RETURN); |
4917 |
+ |
4918 |
+@@ -320,8 +320,14 @@ int arch_setup_additional_pages(struct l |
4919 |
+ |
4920 |
+ const char *arch_vma_name(struct vm_area_struct *vma) |
4921 |
+ { |
4922 |
+- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) |
4923 |
++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso) |
4924 |
+ return "[vdso]"; |
4925 |
++ |
4926 |
++#ifdef CONFIG_PAX_SEGMEXEC |
4927 |
++ if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso) |
4928 |
++ return "[vdso]"; |
4929 |
++#endif |
4930 |
++ |
4931 |
+ return NULL; |
4932 |
+ } |
4933 |
+ |
4934 |
+@@ -330,7 +336,7 @@ struct vm_area_struct *get_gate_vma(stru |
4935 |
+ struct mm_struct *mm = tsk->mm; |
4936 |
+ |
4937 |
+ /* Check to see if this task was created in compat vdso mode */ |
4938 |
+- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE) |
4939 |
++ if (mm && mm->context.vdso == VDSO_HIGH_BASE) |
4940 |
+ return &gate_vma; |
4941 |
+ return NULL; |
4942 |
+ } |
4943 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/time.c linux-2.6.23.15-grsec/arch/i386/kernel/time.c |
4944 |
+--- linux-2.6.23.15/arch/i386/kernel/time.c 2007-10-09 21:31:38.000000000 +0100 |
4945 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/time.c 2008-02-11 10:37:44.000000000 +0000 |
4946 |
+@@ -132,20 +132,30 @@ unsigned long profile_pc(struct pt_regs |
4947 |
+ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) && |
4948 |
+ in_lock_functions(pc)) { |
4949 |
+ #ifdef CONFIG_FRAME_POINTER |
4950 |
+- return *(unsigned long *)(regs->ebp + 4); |
4951 |
++ return *(unsigned long *)(regs->ebp + 4) + __KERNEL_TEXT_OFFSET; |
4952 |
+ #else |
4953 |
+ unsigned long *sp = (unsigned long *)®s->esp; |
4954 |
+ |
4955 |
+ /* Return address is either directly at stack pointer |
4956 |
+ or above a saved eflags. Eflags has bits 22-31 zero, |
4957 |
+ kernel addresses don't. */ |
4958 |
++ |
4959 |
++#ifdef CONFIG_PAX_KERNEXEC |
4960 |
++ return sp[0] + __KERNEL_TEXT_OFFSET; |
4961 |
++#else |
4962 |
+ if (sp[0] >> 22) |
4963 |
+ return sp[0]; |
4964 |
+ if (sp[1] >> 22) |
4965 |
+ return sp[1]; |
4966 |
+ #endif |
4967 |
++ |
4968 |
++#endif |
4969 |
+ } |
4970 |
+ #endif |
4971 |
++ |
4972 |
++ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs)) |
4973 |
++ pc += __KERNEL_TEXT_OFFSET; |
4974 |
++ |
4975 |
+ return pc; |
4976 |
+ } |
4977 |
+ EXPORT_SYMBOL(profile_pc); |
4978 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/traps.c linux-2.6.23.15-grsec/arch/i386/kernel/traps.c |
4979 |
+--- linux-2.6.23.15/arch/i386/kernel/traps.c 2007-10-09 21:31:38.000000000 +0100 |
4980 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/traps.c 2008-02-11 10:37:44.000000000 +0000 |
4981 |
+@@ -31,6 +31,7 @@ |
4982 |
+ #include <linux/uaccess.h> |
4983 |
+ #include <linux/nmi.h> |
4984 |
+ #include <linux/bug.h> |
4985 |
++#include <linux/binfmts.h> |
4986 |
+ |
4987 |
+ #ifdef CONFIG_EISA |
4988 |
+ #include <linux/ioport.h> |
4989 |
+@@ -70,12 +71,7 @@ asmlinkage int system_call(void); |
4990 |
+ /* Do we ignore FPU interrupts ? */ |
4991 |
+ char ignore_fpu_irq = 0; |
4992 |
+ |
4993 |
+-/* |
4994 |
+- * The IDT has to be page-aligned to simplify the Pentium |
4995 |
+- * F0 0F bug workaround.. We have a special link segment |
4996 |
+- * for this. |
4997 |
+- */ |
4998 |
+-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; |
4999 |
++extern struct desc_struct idt_table[256]; |
5000 |
+ |
5001 |
+ asmlinkage void divide_error(void); |
5002 |
+ asmlinkage void debug(void); |
5003 |
+@@ -297,7 +293,7 @@ void show_registers(struct pt_regs *regs |
5004 |
+ esp = (unsigned long) (®s->esp); |
5005 |
+ savesegment(ss, ss); |
5006 |
+ savesegment(gs, gs); |
5007 |
+- if (user_mode_vm(regs)) { |
5008 |
++ if (user_mode(regs)) { |
5009 |
+ in_kernel = 0; |
5010 |
+ esp = regs->esp; |
5011 |
+ ss = regs->xss & 0xffff; |
5012 |
+@@ -329,17 +325,18 @@ void show_registers(struct pt_regs *regs |
5013 |
+ unsigned int code_prologue = code_bytes * 43 / 64; |
5014 |
+ unsigned int code_len = code_bytes; |
5015 |
+ unsigned char c; |
5016 |
++ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]); |
5017 |
+ |
5018 |
+ printk("\n" KERN_EMERG "Stack: "); |
5019 |
+ show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG); |
5020 |
+ |
5021 |
+ printk(KERN_EMERG "Code: "); |
5022 |
+ |
5023 |
+- eip = (u8 *)regs->eip - code_prologue; |
5024 |
++ eip = (u8 *)regs->eip - code_prologue + cs_base; |
5025 |
+ if (eip < (u8 *)PAGE_OFFSET || |
5026 |
+ probe_kernel_address(eip, c)) { |
5027 |
+ /* try starting at EIP */ |
5028 |
+- eip = (u8 *)regs->eip; |
5029 |
++ eip = (u8 *)regs->eip + cs_base; |
5030 |
+ code_len = code_len - code_prologue + 1; |
5031 |
+ } |
5032 |
+ for (i = 0; i < code_len; i++, eip++) { |
5033 |
+@@ -348,7 +345,7 @@ void show_registers(struct pt_regs *regs |
5034 |
+ printk(" Bad EIP value."); |
5035 |
+ break; |
5036 |
+ } |
5037 |
+- if (eip == (u8 *)regs->eip) |
5038 |
++ if (eip == (u8 *)regs->eip + cs_base) |
5039 |
+ printk("<%02x> ", c); |
5040 |
+ else |
5041 |
+ printk("%02x ", c); |
5042 |
+@@ -361,6 +358,7 @@ int is_valid_bugaddr(unsigned long eip) |
5043 |
+ { |
5044 |
+ unsigned short ud2; |
5045 |
+ |
5046 |
++ eip += __KERNEL_TEXT_OFFSET; |
5047 |
+ if (eip < PAGE_OFFSET) |
5048 |
+ return 0; |
5049 |
+ if (probe_kernel_address((unsigned short *)eip, ud2)) |
5050 |
+@@ -468,7 +466,7 @@ void die(const char * str, struct pt_reg |
5051 |
+ |
5052 |
+ static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) |
5053 |
+ { |
5054 |
+- if (!user_mode_vm(regs)) |
5055 |
++ if (!user_mode(regs)) |
5056 |
+ die(str, regs, err); |
5057 |
+ } |
5058 |
+ |
5059 |
+@@ -484,7 +482,7 @@ static void __kprobes do_trap(int trapnr |
5060 |
+ goto trap_signal; |
5061 |
+ } |
5062 |
+ |
5063 |
+- if (!user_mode(regs)) |
5064 |
++ if (!user_mode_novm(regs)) |
5065 |
+ goto kernel_trap; |
5066 |
+ |
5067 |
+ trap_signal: { |
5068 |
+@@ -589,7 +587,7 @@ fastcall void __kprobes do_general_prote |
5069 |
+ long error_code) |
5070 |
+ { |
5071 |
+ int cpu = get_cpu(); |
5072 |
+- struct tss_struct *tss = &per_cpu(init_tss, cpu); |
5073 |
++ struct tss_struct *tss = &init_tss[cpu]; |
5074 |
+ struct thread_struct *thread = ¤t->thread; |
5075 |
+ |
5076 |
+ /* |
5077 |
+@@ -622,9 +620,25 @@ fastcall void __kprobes do_general_prote |
5078 |
+ if (regs->eflags & VM_MASK) |
5079 |
+ goto gp_in_vm86; |
5080 |
+ |
5081 |
+- if (!user_mode(regs)) |
5082 |
++ if (!user_mode_novm(regs)) |
5083 |
+ goto gp_in_kernel; |
5084 |
+ |
5085 |
++#ifdef CONFIG_PAX_PAGEEXEC |
5086 |
++ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) { |
5087 |
++ struct mm_struct *mm = current->mm; |
5088 |
++ unsigned long limit; |
5089 |
++ |
5090 |
++ down_write(&mm->mmap_sem); |
5091 |
++ limit = mm->context.user_cs_limit; |
5092 |
++ if (limit < TASK_SIZE) { |
5093 |
++ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC); |
5094 |
++ up_write(&mm->mmap_sem); |
5095 |
++ return; |
5096 |
++ } |
5097 |
++ up_write(&mm->mmap_sem); |
5098 |
++ } |
5099 |
++#endif |
5100 |
++ |
5101 |
+ current->thread.error_code = error_code; |
5102 |
+ current->thread.trap_no = 13; |
5103 |
+ if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && |
5104 |
+@@ -649,6 +663,13 @@ gp_in_kernel: |
5105 |
+ if (notify_die(DIE_GPF, "general protection fault", regs, |
5106 |
+ error_code, 13, SIGSEGV) == NOTIFY_STOP) |
5107 |
+ return; |
5108 |
++ |
5109 |
++#ifdef CONFIG_PAX_KERNEXEC |
5110 |
++ if ((regs->xcs & 0xFFFF) == __KERNEL_CS) |
5111 |
++ die("PAX: suspicious general protection fault", regs, error_code); |
5112 |
++ else |
5113 |
++#endif |
5114 |
++ |
5115 |
+ die("general protection fault", regs, error_code); |
5116 |
+ } |
5117 |
+ } |
5118 |
+@@ -738,7 +759,7 @@ void __kprobes die_nmi(struct pt_regs *r |
5119 |
+ /* If we are in kernel we are probably nested up pretty bad |
5120 |
+ * and might aswell get out now while we still can. |
5121 |
+ */ |
5122 |
+- if (!user_mode_vm(regs)) { |
5123 |
++ if (!user_mode(regs)) { |
5124 |
+ current->thread.trap_no = 2; |
5125 |
+ crash_kexec(regs); |
5126 |
+ } |
5127 |
+@@ -885,7 +906,7 @@ fastcall void __kprobes do_debug(struct |
5128 |
+ * check for kernel mode by just checking the CPL |
5129 |
+ * of CS. |
5130 |
+ */ |
5131 |
+- if (!user_mode(regs)) |
5132 |
++ if (!user_mode_novm(regs)) |
5133 |
+ goto clear_TF_reenable; |
5134 |
+ } |
5135 |
+ |
5136 |
+@@ -1063,18 +1084,14 @@ fastcall void do_spurious_interrupt_bug( |
5137 |
+ fastcall unsigned long patch_espfix_desc(unsigned long uesp, |
5138 |
+ unsigned long kesp) |
5139 |
+ { |
5140 |
+- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt; |
5141 |
+ unsigned long base = (kesp - uesp) & -THREAD_SIZE; |
5142 |
+ unsigned long new_kesp = kesp - base; |
5143 |
+ unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; |
5144 |
+- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; |
5145 |
++ __u32 a, b; |
5146 |
++ |
5147 |
+ /* Set up base for espfix segment */ |
5148 |
+- desc &= 0x00f0ff0000000000ULL; |
5149 |
+- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | |
5150 |
+- ((((__u64)base) << 32) & 0xff00000000000000ULL) | |
5151 |
+- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | |
5152 |
+- (lim_pages & 0xffff); |
5153 |
+- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; |
5154 |
++ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC); |
5155 |
++ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b); |
5156 |
+ return new_kesp; |
5157 |
+ } |
5158 |
+ |
5159 |
+@@ -1123,7 +1140,7 @@ void __init trap_init_f00f_bug(void) |
5160 |
+ * Update the IDT descriptor and reload the IDT so that |
5161 |
+ * it uses the read-only mapped virtual address. |
5162 |
+ */ |
5163 |
+- idt_descr.address = fix_to_virt(FIX_F00F_IDT); |
5164 |
++ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT); |
5165 |
+ load_idt(&idt_descr); |
5166 |
+ } |
5167 |
+ #endif |
5168 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/tsc.c linux-2.6.23.15-grsec/arch/i386/kernel/tsc.c |
5169 |
+--- linux-2.6.23.15/arch/i386/kernel/tsc.c 2008-02-11 10:36:03.000000000 +0000 |
5170 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/tsc.c 2008-02-11 10:37:44.000000000 +0000 |
5171 |
+@@ -322,7 +322,7 @@ static struct dmi_system_id __initdata b |
5172 |
+ DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), |
5173 |
+ }, |
5174 |
+ }, |
5175 |
+- {} |
5176 |
++ { NULL, NULL, {{0, NULL}}, NULL} |
5177 |
+ }; |
5178 |
+ |
5179 |
+ /* |
5180 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/vm86.c linux-2.6.23.15-grsec/arch/i386/kernel/vm86.c |
5181 |
+--- linux-2.6.23.15/arch/i386/kernel/vm86.c 2007-10-09 21:31:38.000000000 +0100 |
5182 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/vm86.c 2008-02-11 10:37:44.000000000 +0000 |
5183 |
+@@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state |
5184 |
+ do_exit(SIGSEGV); |
5185 |
+ } |
5186 |
+ |
5187 |
+- tss = &per_cpu(init_tss, get_cpu()); |
5188 |
++ tss = init_tss + get_cpu(); |
5189 |
+ current->thread.esp0 = current->thread.saved_esp0; |
5190 |
+ current->thread.sysenter_cs = __KERNEL_CS; |
5191 |
+ load_esp0(tss, ¤t->thread); |
5192 |
+@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm |
5193 |
+ tsk->thread.saved_fs = info->regs32->xfs; |
5194 |
+ savesegment(gs, tsk->thread.saved_gs); |
5195 |
+ |
5196 |
+- tss = &per_cpu(init_tss, get_cpu()); |
5197 |
++ tss = init_tss + get_cpu(); |
5198 |
+ tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; |
5199 |
+ if (cpu_has_sep) |
5200 |
+ tsk->thread.sysenter_cs = 0; |
5201 |
+diff -Nurp linux-2.6.23.15/arch/i386/kernel/vmi.c linux-2.6.23.15-grsec/arch/i386/kernel/vmi.c |
5202 |
+--- linux-2.6.23.15/arch/i386/kernel/vmi.c 2007-10-09 21:31:38.000000000 +0100 |
5203 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/vmi.c 2008-02-11 10:37:44.000000000 +0000 |
5204 |
+@@ -98,18 +98,43 @@ static unsigned patch_internal(int call, |
5205 |
+ { |
5206 |
+ u64 reloc; |
5207 |
+ struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc; |
5208 |
++ |
5209 |
++#ifdef CONFIG_PAX_KERNEXEC |
5210 |
++ unsigned long cr0; |
5211 |
++#endif |
5212 |
++ |
5213 |
+ reloc = call_vrom_long_func(vmi_rom, get_reloc, call); |
5214 |
+ switch(rel->type) { |
5215 |
+ case VMI_RELOCATION_CALL_REL: |
5216 |
+ BUG_ON(len < 5); |
5217 |
++ |
5218 |
++#ifdef CONFIG_PAX_KERNEXEC |
5219 |
++ pax_open_kernel(cr0); |
5220 |
++#endif |
5221 |
++ |
5222 |
+ *(char *)insnbuf = MNEM_CALL; |
5223 |
+ patch_offset(insnbuf, eip, (unsigned long)rel->eip); |
5224 |
++ |
5225 |
++#ifdef CONFIG_PAX_KERNEXEC |
5226 |
++ pax_close_kernel(cr0); |
5227 |
++#endif |
5228 |
++ |
5229 |
+ return 5; |
5230 |
+ |
5231 |
+ case VMI_RELOCATION_JUMP_REL: |
5232 |
+ BUG_ON(len < 5); |
5233 |
++ |
5234 |
++#ifdef CONFIG_PAX_KERNEXEC |
5235 |
++ pax_open_kernel(cr0); |
5236 |
++#endif |
5237 |
++ |
5238 |
+ *(char *)insnbuf = MNEM_JMP; |
5239 |
+ patch_offset(insnbuf, eip, (unsigned long)rel->eip); |
5240 |
++ |
5241 |
++#ifdef CONFIG_PAX_KERNEXEC |
5242 |
++ pax_close_kernel(cr0); |
5243 |
++#endif |
5244 |
++ |
5245 |
+ return 5; |
5246 |
+ |
5247 |
+ case VMI_RELOCATION_NOP: |
5248 |
+@@ -492,14 +517,14 @@ static void vmi_set_pud(pud_t *pudp, pud |
5249 |
+ |
5250 |
+ static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
5251 |
+ { |
5252 |
+- const pte_t pte = { 0 }; |
5253 |
++ const pte_t pte = __pte(0ULL); |
5254 |
+ vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE); |
5255 |
+ vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0)); |
5256 |
+ } |
5257 |
+ |
5258 |
+ static void vmi_pmd_clear(pmd_t *pmd) |
5259 |
+ { |
5260 |
+- const pte_t pte = { 0 }; |
5261 |
++ const pte_t pte = __pte(0ULL); |
5262 |
+ vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD); |
5263 |
+ vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD); |
5264 |
+ } |
5265 |
+@@ -528,8 +553,8 @@ vmi_startup_ipi_hook(int phys_apicid, un |
5266 |
+ ap.ss = __KERNEL_DS; |
5267 |
+ ap.esp = (unsigned long) start_esp; |
5268 |
+ |
5269 |
+- ap.ds = __USER_DS; |
5270 |
+- ap.es = __USER_DS; |
5271 |
++ ap.ds = __KERNEL_DS; |
5272 |
++ ap.es = __KERNEL_DS; |
5273 |
+ ap.fs = __KERNEL_PERCPU; |
5274 |
+ ap.gs = 0; |
5275 |
+ |
5276 |
+@@ -726,12 +751,20 @@ static inline int __init activate_vmi(vo |
5277 |
+ u64 reloc; |
5278 |
+ const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc; |
5279 |
+ |
5280 |
++#ifdef CONFIG_PAX_KERNEXEC |
5281 |
++ unsigned long cr0; |
5282 |
++#endif |
5283 |
++ |
5284 |
+ if (call_vrom_func(vmi_rom, vmi_init) != 0) { |
5285 |
+ printk(KERN_ERR "VMI ROM failed to initialize!"); |
5286 |
+ return 0; |
5287 |
+ } |
5288 |
+ savesegment(cs, kernel_cs); |
5289 |
+ |
5290 |
++#ifdef CONFIG_PAX_KERNEXEC |
5291 |
++ pax_open_kernel(cr0); |
5292 |
++#endif |
5293 |
++ |
5294 |
+ paravirt_ops.paravirt_enabled = 1; |
5295 |
+ paravirt_ops.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK; |
5296 |
+ |
5297 |
+@@ -910,6 +943,10 @@ static inline int __init activate_vmi(vo |
5298 |
+ |
5299 |
+ para_fill(safe_halt, Halt); |
5300 |
+ |
5301 |
++#ifdef CONFIG_PAX_KERNEXEC |
5302 |
++ pax_close_kernel(cr0); |
5303 |
++#endif |
5304 |
++ |
5305 |
+ /* |
5306 |
+ * Alternative instruction rewriting doesn't happen soon enough |
5307 |
+ * to convert VMI_IRET to a call instead of a jump; so we have |
5308 |
+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 |
5309 |
+--- linux-2.6.23.15/arch/i386/kernel/vmlinux.lds.S 2007-10-09 21:31:38.000000000 +0100 |
5310 |
++++ linux-2.6.23.15-grsec/arch/i386/kernel/vmlinux.lds.S 2008-02-11 10:37:44.000000000 +0000 |
5311 |
+@@ -21,6 +21,13 @@ |
5312 |
+ #include <asm/page.h> |
5313 |
+ #include <asm/cache.h> |
5314 |
+ #include <asm/boot.h> |
5315 |
++#include <asm/segment.h> |
5316 |
++ |
5317 |
++#ifdef CONFIG_X86_PAE |
5318 |
++#define PMD_SHIFT 21 |
5319 |
++#else |
5320 |
++#define PMD_SHIFT 22 |
5321 |
++#endif |
5322 |
+ |
5323 |
+ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") |
5324 |
+ OUTPUT_ARCH(i386) |
5325 |
+@@ -28,22 +35,124 @@ ENTRY(phys_startup_32) |
5326 |
+ jiffies = jiffies_64; |
5327 |
+ |
5328 |
+ PHDRS { |
5329 |
+- text PT_LOAD FLAGS(5); /* R_E */ |
5330 |
+- data PT_LOAD FLAGS(7); /* RWE */ |
5331 |
+- note PT_NOTE FLAGS(0); /* ___ */ |
5332 |
++ initdata PT_LOAD FLAGS(6); /* RW_ */ |
5333 |
++ percpu PT_LOAD FLAGS(6); /* RW_ */ |
5334 |
++ inittext PT_LOAD FLAGS(5); /* R_E */ |
5335 |
++ text PT_LOAD FLAGS(5); /* R_E */ |
5336 |
++ rodata PT_LOAD FLAGS(4); /* R__ */ |
5337 |
++ data PT_LOAD FLAGS(6); /* RW_ */ |
5338 |
++ note PT_NOTE FLAGS(0); /* ___ */ |
5339 |
+ } |
5340 |
+ SECTIONS |
5341 |
+ { |
5342 |
+ . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; |
5343 |
+- phys_startup_32 = startup_32 - LOAD_OFFSET; |
5344 |
+ |
5345 |
+- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) { |
5346 |
+- _text = .; /* Text and read-only data */ |
5347 |
++ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) { |
5348 |
++ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET; |
5349 |
++ *(.text.startup) |
5350 |
++ } :initdata |
5351 |
++ |
5352 |
++ /* might get freed after init */ |
5353 |
++ . = ALIGN(4096); |
5354 |
++ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
5355 |
++ __smp_locks = .; |
5356 |
++ *(.smp_locks) |
5357 |
++ __smp_locks_end = .; |
5358 |
++ } |
5359 |
++ /* will be freed after init |
5360 |
++ * Following ALIGN() is required to make sure no other data falls on the |
5361 |
++ * same page where __smp_alt_end is pointing as that page might be freed |
5362 |
++ * after boot. Always make sure that ALIGN() directive is present after |
5363 |
++ * the section which contains __smp_alt_end. |
5364 |
++ */ |
5365 |
++ . = ALIGN(4096); |
5366 |
++ |
5367 |
++ /* will be freed after init */ |
5368 |
++ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { |
5369 |
++ __init_begin = .; |
5370 |
++ *(.init.data) |
5371 |
++ } |
5372 |
++ . = ALIGN(16); |
5373 |
++ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { |
5374 |
++ __setup_start = .; |
5375 |
++ *(.init.setup) |
5376 |
++ __setup_end = .; |
5377 |
++ } |
5378 |
++ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
5379 |
++ __initcall_start = .; |
5380 |
++ INITCALLS |
5381 |
++ __initcall_end = .; |
5382 |
++ } |
5383 |
++ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
5384 |
++ __con_initcall_start = .; |
5385 |
++ *(.con_initcall.init) |
5386 |
++ __con_initcall_end = .; |
5387 |
++ } |
5388 |
++ SECURITY_INIT |
5389 |
++ . = ALIGN(4); |
5390 |
++ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
5391 |
++ __alt_instructions = .; |
5392 |
++ *(.altinstructions) |
5393 |
++ __alt_instructions_end = .; |
5394 |
++ } |
5395 |
++ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
5396 |
++ *(.altinstr_replacement) |
5397 |
++ } |
5398 |
++ . = ALIGN(4); |
5399 |
++ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { |
5400 |
++ __parainstructions = .; |
5401 |
++ *(.parainstructions) |
5402 |
++ __parainstructions_end = .; |
5403 |
++ } |
5404 |
++ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
5405 |
++#if defined(CONFIG_BLK_DEV_INITRD) |
5406 |
++ . = ALIGN(4096); |
5407 |
++ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { |
5408 |
++ __initramfs_start = .; |
5409 |
++ *(.init.ramfs) |
5410 |
++ __initramfs_end = .; |
5411 |
++ } |
5412 |
++#endif |
5413 |
++ . = ALIGN(4096); |
5414 |
++ per_cpu_start = .; |
5415 |
++ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) { |
5416 |
++ __per_cpu_start = . + per_cpu_start; |
5417 |
++ LONG(0) |
5418 |
++ *(.data.percpu) |
5419 |
++ *(.data.percpu.shared_aligned) |
5420 |
++ __per_cpu_end = . + per_cpu_start; |
5421 |
++ } :percpu |
5422 |
++ . += per_cpu_start; |
5423 |
++ |
5424 |
++ /* read-only */ |
5425 |
++ |
5426 |
++ . = ALIGN(4096); /* Init code and data */ |
5427 |
++ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
5428 |
++ _sinittext = .; |
5429 |
++ *(.init.text) |
5430 |
++ _einittext = .; |
5431 |
++ } :inittext |
5432 |
++ |
5433 |
++ /* .exit.text is discard at runtime, not link time, to deal with references |
5434 |
++ from .altinstructions and .eh_frame */ |
5435 |
++ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) } |
5436 |
++ |
5437 |
++ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
5438 |
++ BYTE(0) |
5439 |
++ . = ALIGN(4*1024*1024) - 1; |
5440 |
++ } |
5441 |
++ |
5442 |
++ /* freed after init ends here */ |
5443 |
++ |
5444 |
++ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
5445 |
++ __init_end = . + __KERNEL_TEXT_OFFSET; |
5446 |
++ KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET; |
5447 |
++ _text = .; /* Text and read-only data */ |
5448 |
+ *(.text.head) |
5449 |
+ } :text = 0x9090 |
5450 |
+ |
5451 |
+ /* read-only */ |
5452 |
+- .text : AT(ADDR(.text) - LOAD_OFFSET) { |
5453 |
++ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { |
5454 |
+ TEXT_TEXT |
5455 |
+ SCHED_TEXT |
5456 |
+ LOCK_TEXT |
5457 |
+@@ -53,16 +162,17 @@ SECTIONS |
5458 |
+ _etext = .; /* End of text section */ |
5459 |
+ } :text = 0x9090 |
5460 |
+ |
5461 |
+- . = ALIGN(16); /* Exception table */ |
5462 |
++ . += __KERNEL_TEXT_OFFSET; |
5463 |
++ . = ALIGN(4096); /* Exception table */ |
5464 |
+ __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { |
5465 |
+ __start___ex_table = .; |
5466 |
+ *(__ex_table) |
5467 |
+ __stop___ex_table = .; |
5468 |
+- } |
5469 |
++ } :rodata |
5470 |
+ |
5471 |
+- NOTES :text :note |
5472 |
++ NOTES :rodata :note |
5473 |
+ |
5474 |
+- BUG_TABLE :text |
5475 |
++ BUG_TABLE :rodata |
5476 |
+ |
5477 |
+ . = ALIGN(4); |
5478 |
+ .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { |
5479 |
+@@ -73,9 +183,36 @@ SECTIONS |
5480 |
+ |
5481 |
+ RODATA |
5482 |
+ |
5483 |
++ . = ALIGN(4096); |
5484 |
++ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) { |
5485 |
++ *(.idt) |
5486 |
++ . = ALIGN(4096); |
5487 |
++ *(.empty_zero_page) |
5488 |
++ *(.swapper_pm_dir) |
5489 |
++ *(.swapper_pg_dir) |
5490 |
++ } |
5491 |
++ |
5492 |
++#ifdef CONFIG_PAX_KERNEXEC |
5493 |
++ |
5494 |
++#ifdef CONFIG_MODULES |
5495 |
++ . = ALIGN(4096); |
5496 |
++ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) { |
5497 |
++ MODULES_VADDR = .; |
5498 |
++ BYTE(0) |
5499 |
++ . += (6 * 1024 * 1024); |
5500 |
++ . = ALIGN(1 << PMD_SHIFT) - 1; |
5501 |
++ MODULES_END = .; |
5502 |
++ } |
5503 |
++#else |
5504 |
++ . = ALIGN(1 << PMD_SHIFT) - 1; |
5505 |
++#endif |
5506 |
++ |
5507 |
++#endif |
5508 |
++ |
5509 |
+ /* writeable */ |
5510 |
+ . = ALIGN(4096); |
5511 |
+ .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ |
5512 |
++ _data = .; |
5513 |
+ DATA_DATA |
5514 |
+ CONSTRUCTORS |
5515 |
+ } :data |
5516 |
+@@ -91,7 +228,6 @@ SECTIONS |
5517 |
+ . = ALIGN(4096); |
5518 |
+ .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { |
5519 |
+ *(.data.page_aligned) |
5520 |
+- *(.data.idt) |
5521 |
+ } |
5522 |
+ |
5523 |
+ . = ALIGN(32); |
5524 |
+@@ -111,86 +247,7 @@ SECTIONS |
5525 |
+ *(.data.init_task) |
5526 |
+ } |
5527 |
+ |
5528 |
+- /* might get freed after init */ |
5529 |
+- . = ALIGN(4096); |
5530 |
+- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { |
5531 |
+- __smp_locks = .; |
5532 |
+- *(.smp_locks) |
5533 |
+- __smp_locks_end = .; |
5534 |
+- } |
5535 |
+- /* will be freed after init |
5536 |
+- * Following ALIGN() is required to make sure no other data falls on the |
5537 |
+- * same page where __smp_alt_end is pointing as that page might be freed |
5538 |
+- * after boot. Always make sure that ALIGN() directive is present after |
5539 |
+- * the section which contains __smp_alt_end. |
5540 |
+- */ |
5541 |
+- . = ALIGN(4096); |
5542 |
+- |
5543 |
+- /* will be freed after init */ |
5544 |
+- . = ALIGN(4096); /* Init code and data */ |
5545 |
+- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { |
5546 |
+- __init_begin = .; |
5547 |
+- _sinittext = .; |
5548 |
+- *(.init.text) |
5549 |
+- _einittext = .; |
5550 |
+- } |
5551 |
+- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } |
5552 |
+- . = ALIGN(16); |
5553 |
+- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { |
5554 |
+- __setup_start = .; |
5555 |
+- *(.init.setup) |
5556 |
+- __setup_end = .; |
5557 |
+- } |
5558 |
+- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { |
5559 |
+- __initcall_start = .; |
5560 |
+- INITCALLS |
5561 |
+- __initcall_end = .; |
5562 |
+- } |
5563 |
+- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { |
5564 |
+- __con_initcall_start = .; |
5565 |
+- *(.con_initcall.init) |
5566 |
+- __con_initcall_end = .; |
5567 |
+- } |
5568 |
+- SECURITY_INIT |
5569 |
+- . = ALIGN(4); |
5570 |
+- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { |
5571 |
+- __alt_instructions = .; |
5572 |
+- *(.altinstructions) |
5573 |
+- __alt_instructions_end = .; |
5574 |
+- } |
5575 |
+- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { |
5576 |
+- *(.altinstr_replacement) |
5577 |
+- } |
5578 |
+- . = ALIGN(4); |
5579 |
+- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { |
5580 |
+- __parainstructions = .; |
5581 |
+- *(.parainstructions) |
5582 |
+- __parainstructions_end = .; |
5583 |
+- } |
5584 |
+- /* .exit.text is discard at runtime, not link time, to deal with references |
5585 |
+- from .altinstructions and .eh_frame */ |
5586 |
+- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } |
5587 |
+- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } |
5588 |
+-#if defined(CONFIG_BLK_DEV_INITRD) |
5589 |
+- . = ALIGN(4096); |
5590 |
+- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { |
5591 |
+- __initramfs_start = .; |
5592 |
+- *(.init.ramfs) |
5593 |
+- __initramfs_end = .; |
5594 |
+- } |
5595 |
+-#endif |
5596 |
+- . = ALIGN(4096); |
5597 |
+- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { |
5598 |
+- __per_cpu_start = .; |
5599 |
+- *(.data.percpu) |
5600 |
+- *(.data.percpu.shared_aligned) |
5601 |
+- __per_cpu_end = .; |
5602 |
+- } |
5603 |
+- . = ALIGN(4096); |
5604 |
+- /* freed after init ends here */ |
5605 |
+- |
5606 |
+ .bss : AT(ADDR(.bss) - LOAD_OFFSET) { |
5607 |
+- __init_end = .; |
5608 |
+ __bss_start = .; /* BSS */ |
5609 |
+ *(.bss.page_aligned) |
5610 |
+ *(.bss) |
5611 |
+diff -Nurp linux-2.6.23.15/arch/i386/lib/checksum.S linux-2.6.23.15-grsec/arch/i386/lib/checksum.S |
5612 |
+--- linux-2.6.23.15/arch/i386/lib/checksum.S 2007-10-09 21:31:38.000000000 +0100 |
5613 |
++++ linux-2.6.23.15-grsec/arch/i386/lib/checksum.S 2008-02-11 10:37:44.000000000 +0000 |
5614 |
+@@ -28,7 +28,8 @@ |
5615 |
+ #include <linux/linkage.h> |
5616 |
+ #include <asm/dwarf2.h> |
5617 |
+ #include <asm/errno.h> |
5618 |
+- |
5619 |
++#include <asm/segment.h> |
5620 |
++ |
5621 |
+ /* |
5622 |
+ * computes a partial checksum, e.g. for TCP/UDP fragments |
5623 |
+ */ |
5624 |
+@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic ( |
5625 |
+ |
5626 |
+ #define ARGBASE 16 |
5627 |
+ #define FP 12 |
5628 |
+- |
5629 |
+-ENTRY(csum_partial_copy_generic) |
5630 |
++ |
5631 |
++ENTRY(csum_partial_copy_generic_to_user) |
5632 |
+ CFI_STARTPROC |
5633 |
++ pushl $(__USER_DS) |
5634 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5635 |
++ popl %es |
5636 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5637 |
++ jmp csum_partial_copy_generic |
5638 |
++ |
5639 |
++ENTRY(csum_partial_copy_generic_from_user) |
5640 |
++ pushl $(__USER_DS) |
5641 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5642 |
++ popl %ds |
5643 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5644 |
++ |
5645 |
++ENTRY(csum_partial_copy_generic) |
5646 |
+ subl $4,%esp |
5647 |
+ CFI_ADJUST_CFA_OFFSET 4 |
5648 |
+ pushl %edi |
5649 |
+@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic) |
5650 |
+ jmp 4f |
5651 |
+ SRC(1: movw (%esi), %bx ) |
5652 |
+ addl $2, %esi |
5653 |
+-DST( movw %bx, (%edi) ) |
5654 |
++DST( movw %bx, %es:(%edi) ) |
5655 |
+ addl $2, %edi |
5656 |
+ addw %bx, %ax |
5657 |
+ adcl $0, %eax |
5658 |
+@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) ) |
5659 |
+ SRC(1: movl (%esi), %ebx ) |
5660 |
+ SRC( movl 4(%esi), %edx ) |
5661 |
+ adcl %ebx, %eax |
5662 |
+-DST( movl %ebx, (%edi) ) |
5663 |
++DST( movl %ebx, %es:(%edi) ) |
5664 |
+ adcl %edx, %eax |
5665 |
+-DST( movl %edx, 4(%edi) ) |
5666 |
++DST( movl %edx, %es:4(%edi) ) |
5667 |
+ |
5668 |
+ SRC( movl 8(%esi), %ebx ) |
5669 |
+ SRC( movl 12(%esi), %edx ) |
5670 |
+ adcl %ebx, %eax |
5671 |
+-DST( movl %ebx, 8(%edi) ) |
5672 |
++DST( movl %ebx, %es:8(%edi) ) |
5673 |
+ adcl %edx, %eax |
5674 |
+-DST( movl %edx, 12(%edi) ) |
5675 |
++DST( movl %edx, %es:12(%edi) ) |
5676 |
+ |
5677 |
+ SRC( movl 16(%esi), %ebx ) |
5678 |
+ SRC( movl 20(%esi), %edx ) |
5679 |
+ adcl %ebx, %eax |
5680 |
+-DST( movl %ebx, 16(%edi) ) |
5681 |
++DST( movl %ebx, %es:16(%edi) ) |
5682 |
+ adcl %edx, %eax |
5683 |
+-DST( movl %edx, 20(%edi) ) |
5684 |
++DST( movl %edx, %es:20(%edi) ) |
5685 |
+ |
5686 |
+ SRC( movl 24(%esi), %ebx ) |
5687 |
+ SRC( movl 28(%esi), %edx ) |
5688 |
+ adcl %ebx, %eax |
5689 |
+-DST( movl %ebx, 24(%edi) ) |
5690 |
++DST( movl %ebx, %es:24(%edi) ) |
5691 |
+ adcl %edx, %eax |
5692 |
+-DST( movl %edx, 28(%edi) ) |
5693 |
++DST( movl %edx, %es:28(%edi) ) |
5694 |
+ |
5695 |
+ lea 32(%esi), %esi |
5696 |
+ lea 32(%edi), %edi |
5697 |
+@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) ) |
5698 |
+ shrl $2, %edx # This clears CF |
5699 |
+ SRC(3: movl (%esi), %ebx ) |
5700 |
+ adcl %ebx, %eax |
5701 |
+-DST( movl %ebx, (%edi) ) |
5702 |
++DST( movl %ebx, %es:(%edi) ) |
5703 |
+ lea 4(%esi), %esi |
5704 |
+ lea 4(%edi), %edi |
5705 |
+ dec %edx |
5706 |
+@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) ) |
5707 |
+ jb 5f |
5708 |
+ SRC( movw (%esi), %cx ) |
5709 |
+ leal 2(%esi), %esi |
5710 |
+-DST( movw %cx, (%edi) ) |
5711 |
++DST( movw %cx, %es:(%edi) ) |
5712 |
+ leal 2(%edi), %edi |
5713 |
+ je 6f |
5714 |
+ shll $16,%ecx |
5715 |
+ SRC(5: movb (%esi), %cl ) |
5716 |
+-DST( movb %cl, (%edi) ) |
5717 |
++DST( movb %cl, %es:(%edi) ) |
5718 |
+ 6: addl %ecx, %eax |
5719 |
+ adcl $0, %eax |
5720 |
+ 7: |
5721 |
+@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) ) |
5722 |
+ |
5723 |
+ 6001: |
5724 |
+ movl ARGBASE+20(%esp), %ebx # src_err_ptr |
5725 |
+- movl $-EFAULT, (%ebx) |
5726 |
++ movl $-EFAULT, %ss:(%ebx) |
5727 |
+ |
5728 |
+ # zero the complete destination - computing the rest |
5729 |
+ # is too much work |
5730 |
+@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) ) |
5731 |
+ |
5732 |
+ 6002: |
5733 |
+ movl ARGBASE+24(%esp), %ebx # dst_err_ptr |
5734 |
+- movl $-EFAULT,(%ebx) |
5735 |
++ movl $-EFAULT,%ss:(%ebx) |
5736 |
+ jmp 5000b |
5737 |
+ |
5738 |
+ .previous |
5739 |
+ |
5740 |
++ pushl %ss |
5741 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5742 |
++ popl %ds |
5743 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5744 |
++ pushl %ss |
5745 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5746 |
++ popl %es |
5747 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5748 |
+ popl %ebx |
5749 |
+ CFI_ADJUST_CFA_OFFSET -4 |
5750 |
+ CFI_RESTORE ebx |
5751 |
+@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) ) |
5752 |
+ CFI_ADJUST_CFA_OFFSET -4 |
5753 |
+ ret |
5754 |
+ CFI_ENDPROC |
5755 |
+-ENDPROC(csum_partial_copy_generic) |
5756 |
++ENDPROC(csum_partial_copy_generic_to_user) |
5757 |
+ |
5758 |
+ #else |
5759 |
+ |
5760 |
+ /* Version for PentiumII/PPro */ |
5761 |
+ |
5762 |
+ #define ROUND1(x) \ |
5763 |
++ nop; nop; nop; \ |
5764 |
+ SRC(movl x(%esi), %ebx ) ; \ |
5765 |
+ addl %ebx, %eax ; \ |
5766 |
+- DST(movl %ebx, x(%edi) ) ; |
5767 |
++ DST(movl %ebx, %es:x(%edi)) ; |
5768 |
+ |
5769 |
+ #define ROUND(x) \ |
5770 |
++ nop; nop; nop; \ |
5771 |
+ SRC(movl x(%esi), %ebx ) ; \ |
5772 |
+ adcl %ebx, %eax ; \ |
5773 |
+- DST(movl %ebx, x(%edi) ) ; |
5774 |
++ DST(movl %ebx, %es:x(%edi)) ; |
5775 |
+ |
5776 |
+ #define ARGBASE 12 |
5777 |
+- |
5778 |
+-ENTRY(csum_partial_copy_generic) |
5779 |
++ |
5780 |
++ENTRY(csum_partial_copy_generic_to_user) |
5781 |
+ CFI_STARTPROC |
5782 |
++ pushl $(__USER_DS) |
5783 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5784 |
++ popl %es |
5785 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5786 |
++ jmp csum_partial_copy_generic |
5787 |
++ |
5788 |
++ENTRY(csum_partial_copy_generic_from_user) |
5789 |
++ pushl $(__USER_DS) |
5790 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5791 |
++ popl %ds |
5792 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5793 |
++ |
5794 |
++ENTRY(csum_partial_copy_generic) |
5795 |
+ pushl %ebx |
5796 |
+ CFI_ADJUST_CFA_OFFSET 4 |
5797 |
+ CFI_REL_OFFSET ebx, 0 |
5798 |
+@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic) |
5799 |
+ subl %ebx, %edi |
5800 |
+ lea -1(%esi),%edx |
5801 |
+ andl $-32,%edx |
5802 |
+- lea 3f(%ebx,%ebx), %ebx |
5803 |
++ lea 3f(%ebx,%ebx,2), %ebx |
5804 |
+ testl %esi, %esi |
5805 |
+ jmp *%ebx |
5806 |
+ 1: addl $64,%esi |
5807 |
+@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic) |
5808 |
+ jb 5f |
5809 |
+ SRC( movw (%esi), %dx ) |
5810 |
+ leal 2(%esi), %esi |
5811 |
+-DST( movw %dx, (%edi) ) |
5812 |
++DST( movw %dx, %es:(%edi) ) |
5813 |
+ leal 2(%edi), %edi |
5814 |
+ je 6f |
5815 |
+ shll $16,%edx |
5816 |
+ 5: |
5817 |
+ SRC( movb (%esi), %dl ) |
5818 |
+-DST( movb %dl, (%edi) ) |
5819 |
++DST( movb %dl, %es:(%edi) ) |
5820 |
+ 6: addl %edx, %eax |
5821 |
+ adcl $0, %eax |
5822 |
+ 7: |
5823 |
+ .section .fixup, "ax" |
5824 |
+ 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr |
5825 |
+- movl $-EFAULT, (%ebx) |
5826 |
++ movl $-EFAULT, %ss:(%ebx) |
5827 |
+ # zero the complete destination (computing the rest is too much work) |
5828 |
+ movl ARGBASE+8(%esp),%edi # dst |
5829 |
+ movl ARGBASE+12(%esp),%ecx # len |
5830 |
+@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) ) |
5831 |
+ rep; stosb |
5832 |
+ jmp 7b |
5833 |
+ 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr |
5834 |
+- movl $-EFAULT, (%ebx) |
5835 |
++ movl $-EFAULT, %ss:(%ebx) |
5836 |
+ jmp 7b |
5837 |
+ .previous |
5838 |
+ |
5839 |
++ pushl %ss |
5840 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5841 |
++ popl %ds |
5842 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5843 |
++ pushl %ss |
5844 |
++ CFI_ADJUST_CFA_OFFSET 4 |
5845 |
++ popl %es |
5846 |
++ CFI_ADJUST_CFA_OFFSET -4 |
5847 |
+ popl %esi |
5848 |
+ CFI_ADJUST_CFA_OFFSET -4 |
5849 |
+ CFI_RESTORE esi |
5850 |
+@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) ) |
5851 |
+ CFI_RESTORE ebx |
5852 |
+ ret |
5853 |
+ CFI_ENDPROC |
5854 |
+-ENDPROC(csum_partial_copy_generic) |
5855 |
++ENDPROC(csum_partial_copy_generic_to_user) |
5856 |
+ |
5857 |
+ #undef ROUND |
5858 |
+ #undef ROUND1 |
5859 |
+diff -Nurp linux-2.6.23.15/arch/i386/lib/getuser.S linux-2.6.23.15-grsec/arch/i386/lib/getuser.S |
5860 |
+--- linux-2.6.23.15/arch/i386/lib/getuser.S 2007-10-09 21:31:38.000000000 +0100 |
5861 |
++++ linux-2.6.23.15-grsec/arch/i386/lib/getuser.S 2008-02-11 10:37:44.000000000 +0000 |
5862 |
+@@ -11,7 +11,7 @@ |
5863 |
+ #include <linux/linkage.h> |
5864 |
+ #include <asm/dwarf2.h> |
5865 |
+ #include <asm/thread_info.h> |
5866 |
+- |
5867 |
++#include <asm/segment.h> |
5868 |
+ |
5869 |
+ /* |
5870 |
+ * __get_user_X |
5871 |
+@@ -31,7 +31,11 @@ ENTRY(__get_user_1) |
5872 |
+ GET_THREAD_INFO(%edx) |
5873 |
+ cmpl TI_addr_limit(%edx),%eax |
5874 |
+ jae bad_get_user |
5875 |
++ pushl $(__USER_DS) |
5876 |
++ popl %ds |
5877 |
+ 1: movzbl (%eax),%edx |
5878 |
++ pushl %ss |
5879 |
++ pop %ds |
5880 |
+ xorl %eax,%eax |
5881 |
+ ret |
5882 |
+ CFI_ENDPROC |
5883 |
+@@ -44,7 +48,11 @@ ENTRY(__get_user_2) |
5884 |
+ GET_THREAD_INFO(%edx) |
5885 |
+ cmpl TI_addr_limit(%edx),%eax |
5886 |
+ jae bad_get_user |
5887 |
++ pushl $(__USER_DS) |
5888 |
++ popl %ds |
5889 |
+ 2: movzwl -1(%eax),%edx |
5890 |
++ pushl %ss |
5891 |
++ pop %ds |
5892 |
+ xorl %eax,%eax |
5893 |
+ ret |
5894 |
+ CFI_ENDPROC |
5895 |
+@@ -57,7 +65,11 @@ ENTRY(__get_user_4) |
5896 |
+ GET_THREAD_INFO(%edx) |
5897 |
+ cmpl TI_addr_limit(%edx),%eax |
5898 |
+ jae bad_get_user |
5899 |
++ pushl $(__USER_DS) |
5900 |
++ popl %ds |
5901 |
+ 3: movl -3(%eax),%edx |
5902 |
++ pushl %ss |
5903 |
++ pop %ds |
5904 |
+ xorl %eax,%eax |
5905 |
+ ret |
5906 |
+ CFI_ENDPROC |
5907 |
+@@ -65,6 +77,8 @@ ENDPROC(__get_user_4) |
5908 |
+ |
5909 |
+ bad_get_user: |
5910 |
+ CFI_STARTPROC |
5911 |
++ pushl %ss |
5912 |
++ pop %ds |
5913 |
+ xorl %edx,%edx |
5914 |
+ movl $-14,%eax |
5915 |
+ ret |
5916 |
+diff -Nurp linux-2.6.23.15/arch/i386/lib/mmx.c linux-2.6.23.15-grsec/arch/i386/lib/mmx.c |
5917 |
+--- linux-2.6.23.15/arch/i386/lib/mmx.c 2007-10-09 21:31:38.000000000 +0100 |
5918 |
++++ linux-2.6.23.15-grsec/arch/i386/lib/mmx.c 2008-02-11 10:37:44.000000000 +0000 |
5919 |
+@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void * |
5920 |
+ { |
5921 |
+ void *p; |
5922 |
+ int i; |
5923 |
++ unsigned long cr0; |
5924 |
+ |
5925 |
+ if (unlikely(in_interrupt())) |
5926 |
+ return __memcpy(to, from, len); |
5927 |
+@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void * |
5928 |
+ kernel_fpu_begin(); |
5929 |
+ |
5930 |
+ __asm__ __volatile__ ( |
5931 |
+- "1: prefetch (%0)\n" /* This set is 28 bytes */ |
5932 |
+- " prefetch 64(%0)\n" |
5933 |
+- " prefetch 128(%0)\n" |
5934 |
+- " prefetch 192(%0)\n" |
5935 |
+- " prefetch 256(%0)\n" |
5936 |
++ "1: prefetch (%1)\n" /* This set is 28 bytes */ |
5937 |
++ " prefetch 64(%1)\n" |
5938 |
++ " prefetch 128(%1)\n" |
5939 |
++ " prefetch 192(%1)\n" |
5940 |
++ " prefetch 256(%1)\n" |
5941 |
+ "2: \n" |
5942 |
+ ".section .fixup, \"ax\"\n" |
5943 |
+- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
5944 |
++ "3: \n" |
5945 |
++ |
5946 |
++#ifdef CONFIG_PAX_KERNEXEC |
5947 |
++ " movl %%cr0, %0\n" |
5948 |
++ " movl %0, %%eax\n" |
5949 |
++ " andl $0xFFFEFFFF, %%eax\n" |
5950 |
++ " movl %%eax, %%cr0\n" |
5951 |
++#endif |
5952 |
++ |
5953 |
++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
5954 |
++ |
5955 |
++#ifdef CONFIG_PAX_KERNEXEC |
5956 |
++ " movl %0, %%cr0\n" |
5957 |
++#endif |
5958 |
++ |
5959 |
+ " jmp 2b\n" |
5960 |
+ ".previous\n" |
5961 |
+ ".section __ex_table,\"a\"\n" |
5962 |
+ " .align 4\n" |
5963 |
+ " .long 1b, 3b\n" |
5964 |
+ ".previous" |
5965 |
+- : : "r" (from) ); |
5966 |
++ : "=&r" (cr0) : "r" (from) : "ax"); |
5967 |
+ |
5968 |
+ |
5969 |
+ for(; i>5; i--) |
5970 |
+ { |
5971 |
+ __asm__ __volatile__ ( |
5972 |
+- "1: prefetch 320(%0)\n" |
5973 |
+- "2: movq (%0), %%mm0\n" |
5974 |
+- " movq 8(%0), %%mm1\n" |
5975 |
+- " movq 16(%0), %%mm2\n" |
5976 |
+- " movq 24(%0), %%mm3\n" |
5977 |
+- " movq %%mm0, (%1)\n" |
5978 |
+- " movq %%mm1, 8(%1)\n" |
5979 |
+- " movq %%mm2, 16(%1)\n" |
5980 |
+- " movq %%mm3, 24(%1)\n" |
5981 |
+- " movq 32(%0), %%mm0\n" |
5982 |
+- " movq 40(%0), %%mm1\n" |
5983 |
+- " movq 48(%0), %%mm2\n" |
5984 |
+- " movq 56(%0), %%mm3\n" |
5985 |
+- " movq %%mm0, 32(%1)\n" |
5986 |
+- " movq %%mm1, 40(%1)\n" |
5987 |
+- " movq %%mm2, 48(%1)\n" |
5988 |
+- " movq %%mm3, 56(%1)\n" |
5989 |
++ "1: prefetch 320(%1)\n" |
5990 |
++ "2: movq (%1), %%mm0\n" |
5991 |
++ " movq 8(%1), %%mm1\n" |
5992 |
++ " movq 16(%1), %%mm2\n" |
5993 |
++ " movq 24(%1), %%mm3\n" |
5994 |
++ " movq %%mm0, (%2)\n" |
5995 |
++ " movq %%mm1, 8(%2)\n" |
5996 |
++ " movq %%mm2, 16(%2)\n" |
5997 |
++ " movq %%mm3, 24(%2)\n" |
5998 |
++ " movq 32(%1), %%mm0\n" |
5999 |
++ " movq 40(%1), %%mm1\n" |
6000 |
++ " movq 48(%1), %%mm2\n" |
6001 |
++ " movq 56(%1), %%mm3\n" |
6002 |
++ " movq %%mm0, 32(%2)\n" |
6003 |
++ " movq %%mm1, 40(%2)\n" |
6004 |
++ " movq %%mm2, 48(%2)\n" |
6005 |
++ " movq %%mm3, 56(%2)\n" |
6006 |
+ ".section .fixup, \"ax\"\n" |
6007 |
+- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
6008 |
++ "3:\n" |
6009 |
++ |
6010 |
++#ifdef CONFIG_PAX_KERNEXEC |
6011 |
++ " movl %%cr0, %0\n" |
6012 |
++ " movl %0, %%eax\n" |
6013 |
++ " andl $0xFFFEFFFF, %%eax\n" |
6014 |
++ " movl %%eax, %%cr0\n" |
6015 |
++#endif |
6016 |
++ |
6017 |
++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
6018 |
++ |
6019 |
++#ifdef CONFIG_PAX_KERNEXEC |
6020 |
++ " movl %0, %%cr0\n" |
6021 |
++#endif |
6022 |
++ |
6023 |
+ " jmp 2b\n" |
6024 |
+ ".previous\n" |
6025 |
+ ".section __ex_table,\"a\"\n" |
6026 |
+ " .align 4\n" |
6027 |
+ " .long 1b, 3b\n" |
6028 |
+ ".previous" |
6029 |
+- : : "r" (from), "r" (to) : "memory"); |
6030 |
++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); |
6031 |
+ from+=64; |
6032 |
+ to+=64; |
6033 |
+ } |
6034 |
+@@ -164,6 +193,7 @@ static void fast_clear_page(void *page) |
6035 |
+ static void fast_copy_page(void *to, void *from) |
6036 |
+ { |
6037 |
+ int i; |
6038 |
++ unsigned long cr0; |
6039 |
+ |
6040 |
+ kernel_fpu_begin(); |
6041 |
+ |
6042 |
+@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi |
6043 |
+ * but that is for later. -AV |
6044 |
+ */ |
6045 |
+ __asm__ __volatile__ ( |
6046 |
+- "1: prefetch (%0)\n" |
6047 |
+- " prefetch 64(%0)\n" |
6048 |
+- " prefetch 128(%0)\n" |
6049 |
+- " prefetch 192(%0)\n" |
6050 |
+- " prefetch 256(%0)\n" |
6051 |
++ "1: prefetch (%1)\n" |
6052 |
++ " prefetch 64(%1)\n" |
6053 |
++ " prefetch 128(%1)\n" |
6054 |
++ " prefetch 192(%1)\n" |
6055 |
++ " prefetch 256(%1)\n" |
6056 |
+ "2: \n" |
6057 |
+ ".section .fixup, \"ax\"\n" |
6058 |
+- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
6059 |
++ "3: \n" |
6060 |
++ |
6061 |
++#ifdef CONFIG_PAX_KERNEXEC |
6062 |
++ " movl %%cr0, %0\n" |
6063 |
++ " movl %0, %%eax\n" |
6064 |
++ " andl $0xFFFEFFFF, %%eax\n" |
6065 |
++ " movl %%eax, %%cr0\n" |
6066 |
++#endif |
6067 |
++ |
6068 |
++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
6069 |
++ |
6070 |
++#ifdef CONFIG_PAX_KERNEXEC |
6071 |
++ " movl %0, %%cr0\n" |
6072 |
++#endif |
6073 |
++ |
6074 |
+ " jmp 2b\n" |
6075 |
+ ".previous\n" |
6076 |
+ ".section __ex_table,\"a\"\n" |
6077 |
+ " .align 4\n" |
6078 |
+ " .long 1b, 3b\n" |
6079 |
+ ".previous" |
6080 |
+- : : "r" (from) ); |
6081 |
++ : "=&r" (cr0) : "r" (from) : "ax"); |
6082 |
+ |
6083 |
+ for(i=0; i<(4096-320)/64; i++) |
6084 |
+ { |
6085 |
+ __asm__ __volatile__ ( |
6086 |
+- "1: prefetch 320(%0)\n" |
6087 |
+- "2: movq (%0), %%mm0\n" |
6088 |
+- " movntq %%mm0, (%1)\n" |
6089 |
+- " movq 8(%0), %%mm1\n" |
6090 |
+- " movntq %%mm1, 8(%1)\n" |
6091 |
+- " movq 16(%0), %%mm2\n" |
6092 |
+- " movntq %%mm2, 16(%1)\n" |
6093 |
+- " movq 24(%0), %%mm3\n" |
6094 |
+- " movntq %%mm3, 24(%1)\n" |
6095 |
+- " movq 32(%0), %%mm4\n" |
6096 |
+- " movntq %%mm4, 32(%1)\n" |
6097 |
+- " movq 40(%0), %%mm5\n" |
6098 |
+- " movntq %%mm5, 40(%1)\n" |
6099 |
+- " movq 48(%0), %%mm6\n" |
6100 |
+- " movntq %%mm6, 48(%1)\n" |
6101 |
+- " movq 56(%0), %%mm7\n" |
6102 |
+- " movntq %%mm7, 56(%1)\n" |
6103 |
++ "1: prefetch 320(%1)\n" |
6104 |
++ "2: movq (%1), %%mm0\n" |
6105 |
++ " movntq %%mm0, (%2)\n" |
6106 |
++ " movq 8(%1), %%mm1\n" |
6107 |
++ " movntq %%mm1, 8(%2)\n" |
6108 |
++ " movq 16(%1), %%mm2\n" |
6109 |
++ " movntq %%mm2, 16(%2)\n" |
6110 |
++ " movq 24(%1), %%mm3\n" |
6111 |
++ " movntq %%mm3, 24(%2)\n" |
6112 |
++ " movq 32(%1), %%mm4\n" |
6113 |
++ " movntq %%mm4, 32(%2)\n" |
6114 |
++ " movq 40(%1), %%mm5\n" |
6115 |
++ " movntq %%mm5, 40(%2)\n" |
6116 |
++ " movq 48(%1), %%mm6\n" |
6117 |
++ " movntq %%mm6, 48(%2)\n" |
6118 |
++ " movq 56(%1), %%mm7\n" |
6119 |
++ " movntq %%mm7, 56(%2)\n" |
6120 |
+ ".section .fixup, \"ax\"\n" |
6121 |
+- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
6122 |
++ "3:\n" |
6123 |
++ |
6124 |
++#ifdef CONFIG_PAX_KERNEXEC |
6125 |
++ " movl %%cr0, %0\n" |
6126 |
++ " movl %0, %%eax\n" |
6127 |
++ " andl $0xFFFEFFFF, %%eax\n" |
6128 |
++ " movl %%eax, %%cr0\n" |
6129 |
++#endif |
6130 |
++ |
6131 |
++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
6132 |
++ |
6133 |
++#ifdef CONFIG_PAX_KERNEXEC |
6134 |
++ " movl %0, %%cr0\n" |
6135 |
++#endif |
6136 |
++ |
6137 |
+ " jmp 2b\n" |
6138 |
+ ".previous\n" |
6139 |
+ ".section __ex_table,\"a\"\n" |
6140 |
+ " .align 4\n" |
6141 |
+ " .long 1b, 3b\n" |
6142 |
+ ".previous" |
6143 |
+- : : "r" (from), "r" (to) : "memory"); |
6144 |
++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); |
6145 |
+ from+=64; |
6146 |
+ to+=64; |
6147 |
+ } |
6148 |
+@@ -296,56 +354,84 @@ static void fast_clear_page(void *page) |
6149 |
+ static void fast_copy_page(void *to, void *from) |
6150 |
+ { |
6151 |
+ int i; |
6152 |
+- |
6153 |
+- |
6154 |
++ unsigned long cr0; |
6155 |
++ |
6156 |
+ kernel_fpu_begin(); |
6157 |
+ |
6158 |
+ __asm__ __volatile__ ( |
6159 |
+- "1: prefetch (%0)\n" |
6160 |
+- " prefetch 64(%0)\n" |
6161 |
+- " prefetch 128(%0)\n" |
6162 |
+- " prefetch 192(%0)\n" |
6163 |
+- " prefetch 256(%0)\n" |
6164 |
++ "1: prefetch (%1)\n" |
6165 |
++ " prefetch 64(%1)\n" |
6166 |
++ " prefetch 128(%1)\n" |
6167 |
++ " prefetch 192(%1)\n" |
6168 |
++ " prefetch 256(%1)\n" |
6169 |
+ "2: \n" |
6170 |
+ ".section .fixup, \"ax\"\n" |
6171 |
+- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
6172 |
++ "3: \n" |
6173 |
++ |
6174 |
++#ifdef CONFIG_PAX_KERNEXEC |
6175 |
++ " movl %%cr0, %0\n" |
6176 |
++ " movl %0, %%eax\n" |
6177 |
++ " andl $0xFFFEFFFF, %%eax\n" |
6178 |
++ " movl %%eax, %%cr0\n" |
6179 |
++#endif |
6180 |
++ |
6181 |
++ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ |
6182 |
++ |
6183 |
++#ifdef CONFIG_PAX_KERNEXEC |
6184 |
++ " movl %0, %%cr0\n" |
6185 |
++#endif |
6186 |
++ |
6187 |
+ " jmp 2b\n" |
6188 |
+ ".previous\n" |
6189 |
+ ".section __ex_table,\"a\"\n" |
6190 |
+ " .align 4\n" |
6191 |
+ " .long 1b, 3b\n" |
6192 |
+ ".previous" |
6193 |
+- : : "r" (from) ); |
6194 |
++ : "=&r" (cr0) : "r" (from) : "ax"); |
6195 |
+ |
6196 |
+ for(i=0; i<4096/64; i++) |
6197 |
+ { |
6198 |
+ __asm__ __volatile__ ( |
6199 |
+- "1: prefetch 320(%0)\n" |
6200 |
+- "2: movq (%0), %%mm0\n" |
6201 |
+- " movq 8(%0), %%mm1\n" |
6202 |
+- " movq 16(%0), %%mm2\n" |
6203 |
+- " movq 24(%0), %%mm3\n" |
6204 |
+- " movq %%mm0, (%1)\n" |
6205 |
+- " movq %%mm1, 8(%1)\n" |
6206 |
+- " movq %%mm2, 16(%1)\n" |
6207 |
+- " movq %%mm3, 24(%1)\n" |
6208 |
+- " movq 32(%0), %%mm0\n" |
6209 |
+- " movq 40(%0), %%mm1\n" |
6210 |
+- " movq 48(%0), %%mm2\n" |
6211 |
+- " movq 56(%0), %%mm3\n" |
6212 |
+- " movq %%mm0, 32(%1)\n" |
6213 |
+- " movq %%mm1, 40(%1)\n" |
6214 |
+- " movq %%mm2, 48(%1)\n" |
6215 |
+- " movq %%mm3, 56(%1)\n" |
6216 |
++ "1: prefetch 320(%1)\n" |
6217 |
++ "2: movq (%1), %%mm0\n" |
6218 |
++ " movq 8(%1), %%mm1\n" |
6219 |
++ " movq 16(%1), %%mm2\n" |
6220 |
++ " movq 24(%1), %%mm3\n" |
6221 |
++ " movq %%mm0, (%2)\n" |
6222 |
++ " movq %%mm1, 8(%2)\n" |
6223 |
++ " movq %%mm2, 16(%2)\n" |
6224 |
++ " movq %%mm3, 24(%2)\n" |
6225 |
++ " movq 32(%1), %%mm0\n" |
6226 |
++ " movq 40(%1), %%mm1\n" |
6227 |
++ " movq 48(%1), %%mm2\n" |
6228 |
++ " movq 56(%1), %%mm3\n" |
6229 |
++ " movq %%mm0, 32(%2)\n" |
6230 |
++ " movq %%mm1, 40(%2)\n" |
6231 |
++ " movq %%mm2, 48(%2)\n" |
6232 |
++ " movq %%mm3, 56(%2)\n" |
6233 |
+ ".section .fixup, \"ax\"\n" |
6234 |
+- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
6235 |
++ "3:\n" |
6236 |
++ |
6237 |
++#ifdef CONFIG_PAX_KERNEXEC |
6238 |
++ " movl %%cr0, %0\n" |
6239 |
++ " movl %0, %%eax\n" |
6240 |
++ " andl $0xFFFEFFFF, %%eax\n" |
6241 |
++ " movl %%eax, %%cr0\n" |
6242 |
++#endif |
6243 |
++ |
6244 |
++ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ |
6245 |
++ |
6246 |
++#ifdef CONFIG_PAX_KERNEXEC |
6247 |
++ " movl %0, %%cr0\n" |
6248 |
++#endif |
6249 |
++ |
6250 |
+ " jmp 2b\n" |
6251 |
+ ".previous\n" |
6252 |
+ ".section __ex_table,\"a\"\n" |
6253 |
+ " .align 4\n" |
6254 |
+ " .long 1b, 3b\n" |
6255 |
+ ".previous" |
6256 |
+- : : "r" (from), "r" (to) : "memory"); |
6257 |
++ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); |
6258 |
+ from+=64; |
6259 |
+ to+=64; |
6260 |
+ } |
6261 |
+diff -Nurp linux-2.6.23.15/arch/i386/lib/putuser.S linux-2.6.23.15-grsec/arch/i386/lib/putuser.S |
6262 |
+--- linux-2.6.23.15/arch/i386/lib/putuser.S 2007-10-09 21:31:38.000000000 +0100 |
6263 |
++++ linux-2.6.23.15-grsec/arch/i386/lib/putuser.S 2008-02-11 10:37:44.000000000 +0000 |
6264 |
+@@ -11,7 +11,7 @@ |
6265 |
+ #include <linux/linkage.h> |
6266 |
+ #include <asm/dwarf2.h> |
6267 |
+ #include <asm/thread_info.h> |
6268 |
+- |
6269 |
++#include <asm/segment.h> |
6270 |
+ |
6271 |
+ /* |
6272 |
+ * __put_user_X |
6273 |
+@@ -41,7 +41,11 @@ ENTRY(__put_user_1) |
6274 |
+ ENTER |
6275 |
+ cmpl TI_addr_limit(%ebx),%ecx |
6276 |
+ jae bad_put_user |
6277 |
++ pushl $(__USER_DS) |
6278 |
++ popl %ds |
6279 |
+ 1: movb %al,(%ecx) |
6280 |
++ pushl %ss |
6281 |
++ popl %ds |
6282 |
+ xorl %eax,%eax |
6283 |
+ EXIT |
6284 |
+ ENDPROC(__put_user_1) |
6285 |
+@@ -52,7 +56,11 @@ ENTRY(__put_user_2) |
6286 |
+ subl $1,%ebx |
6287 |
+ cmpl %ebx,%ecx |
6288 |
+ jae bad_put_user |
6289 |
++ pushl $(__USER_DS) |
6290 |
++ popl %ds |
6291 |
+ 2: movw %ax,(%ecx) |
6292 |
++ pushl %ss |
6293 |
++ popl %ds |
6294 |
+ xorl %eax,%eax |
6295 |
+ EXIT |
6296 |
+ ENDPROC(__put_user_2) |
6297 |
+@@ -63,7 +71,11 @@ ENTRY(__put_user_4) |
6298 |
+ subl $3,%ebx |
6299 |
+ cmpl %ebx,%ecx |
6300 |
+ jae bad_put_user |
6301 |
++ pushl $(__USER_DS) |
6302 |
++ popl %ds |
6303 |
+ 3: movl %eax,(%ecx) |
6304 |
++ pushl %ss |
6305 |
++ popl %ds |
6306 |
+ xorl %eax,%eax |
6307 |
+ EXIT |
6308 |
+ ENDPROC(__put_user_4) |
6309 |
+@@ -74,8 +86,12 @@ ENTRY(__put_user_8) |
6310 |
+ subl $7,%ebx |
6311 |
+ cmpl %ebx,%ecx |
6312 |
+ jae bad_put_user |
6313 |
++ pushl $(__USER_DS) |
6314 |
++ popl %ds |
6315 |
+ 4: movl %eax,(%ecx) |
6316 |
+ 5: movl %edx,4(%ecx) |
6317 |
++ pushl %ss |
6318 |
++ popl %ds |
6319 |
+ xorl %eax,%eax |
6320 |
+ EXIT |
6321 |
+ ENDPROC(__put_user_8) |
6322 |
+@@ -85,6 +101,10 @@ bad_put_user: |
6323 |
+ CFI_DEF_CFA esp, 2*4 |
6324 |
+ CFI_OFFSET eip, -1*4 |
6325 |
+ CFI_OFFSET ebx, -2*4 |
6326 |
++ pushl %ss |
6327 |
++ CFI_ADJUST_CFA_OFFSET 4 |
6328 |
++ popl %ds |
6329 |
++ CFI_ADJUST_CFA_OFFSET -4 |
6330 |
+ movl $-14,%eax |
6331 |
+ EXIT |
6332 |
+ END(bad_put_user) |
6333 |
+diff -Nurp linux-2.6.23.15/arch/i386/lib/usercopy.c linux-2.6.23.15-grsec/arch/i386/lib/usercopy.c |
6334 |
+--- linux-2.6.23.15/arch/i386/lib/usercopy.c 2007-10-09 21:31:38.000000000 +0100 |
6335 |
++++ linux-2.6.23.15-grsec/arch/i386/lib/usercopy.c 2008-02-11 10:37:44.000000000 +0000 |
6336 |
+@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned |
6337 |
+ * Copy a null terminated string from userspace. |
6338 |
+ */ |
6339 |
+ |
6340 |
+-#define __do_strncpy_from_user(dst,src,count,res) \ |
6341 |
+-do { \ |
6342 |
+- int __d0, __d1, __d2; \ |
6343 |
+- might_sleep(); \ |
6344 |
+- __asm__ __volatile__( \ |
6345 |
+- " testl %1,%1\n" \ |
6346 |
+- " jz 2f\n" \ |
6347 |
+- "0: lodsb\n" \ |
6348 |
+- " stosb\n" \ |
6349 |
+- " testb %%al,%%al\n" \ |
6350 |
+- " jz 1f\n" \ |
6351 |
+- " decl %1\n" \ |
6352 |
+- " jnz 0b\n" \ |
6353 |
+- "1: subl %1,%0\n" \ |
6354 |
+- "2:\n" \ |
6355 |
+- ".section .fixup,\"ax\"\n" \ |
6356 |
+- "3: movl %5,%0\n" \ |
6357 |
+- " jmp 2b\n" \ |
6358 |
+- ".previous\n" \ |
6359 |
+- ".section __ex_table,\"a\"\n" \ |
6360 |
+- " .align 4\n" \ |
6361 |
+- " .long 0b,3b\n" \ |
6362 |
+- ".previous" \ |
6363 |
+- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ |
6364 |
+- "=&D" (__d2) \ |
6365 |
+- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ |
6366 |
+- : "memory"); \ |
6367 |
+-} while (0) |
6368 |
++static long __do_strncpy_from_user(char *dst, const char __user *src, long count) |
6369 |
++{ |
6370 |
++ int __d0, __d1, __d2; |
6371 |
++ long res = -EFAULT; |
6372 |
++ |
6373 |
++ might_sleep(); |
6374 |
++ __asm__ __volatile__( |
6375 |
++ " movw %w10,%%ds\n" |
6376 |
++ " testl %1,%1\n" |
6377 |
++ " jz 2f\n" |
6378 |
++ "0: lodsb\n" |
6379 |
++ " stosb\n" |
6380 |
++ " testb %%al,%%al\n" |
6381 |
++ " jz 1f\n" |
6382 |
++ " decl %1\n" |
6383 |
++ " jnz 0b\n" |
6384 |
++ "1: subl %1,%0\n" |
6385 |
++ "2:\n" |
6386 |
++ " pushl %%ss\n" |
6387 |
++ " popl %%ds\n" |
6388 |
++ ".section .fixup,\"ax\"\n" |
6389 |
++ "3: movl %5,%0\n" |
6390 |
++ " jmp 2b\n" |
6391 |
++ ".previous\n" |
6392 |
++ ".section __ex_table,\"a\"\n" |
6393 |
++ " .align 4\n" |
6394 |
++ " .long 0b,3b\n" |
6395 |
++ ".previous" |
6396 |
++ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), |
6397 |
++ "=&D" (__d2) |
6398 |
++ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst), |
6399 |
++ "r"(__USER_DS) |
6400 |
++ : "memory"); |
6401 |
++ return res; |
6402 |
++} |
6403 |
+ |
6404 |
+ /** |
6405 |
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking. |
6406 |
+@@ -81,9 +88,7 @@ do { \ |
6407 |
+ long |
6408 |
+ __strncpy_from_user(char *dst, const char __user *src, long count) |
6409 |
+ { |
6410 |
+- long res; |
6411 |
+- __do_strncpy_from_user(dst, src, count, res); |
6412 |
+- return res; |
6413 |
++ return __do_strncpy_from_user(dst, src, count); |
6414 |
+ } |
6415 |
+ EXPORT_SYMBOL(__strncpy_from_user); |
6416 |
+ |
6417 |
+@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char |
6418 |
+ { |
6419 |
+ long res = -EFAULT; |
6420 |
+ if (access_ok(VERIFY_READ, src, 1)) |
6421 |
+- __do_strncpy_from_user(dst, src, count, res); |
6422 |
++ res = __do_strncpy_from_user(dst, src, count); |
6423 |
+ return res; |
6424 |
+ } |
6425 |
+ EXPORT_SYMBOL(strncpy_from_user); |
6426 |
+@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user); |
6427 |
+ * Zero Userspace |
6428 |
+ */ |
6429 |
+ |
6430 |
+-#define __do_clear_user(addr,size) \ |
6431 |
+-do { \ |
6432 |
+- int __d0; \ |
6433 |
+- might_sleep(); \ |
6434 |
+- __asm__ __volatile__( \ |
6435 |
+- "0: rep; stosl\n" \ |
6436 |
+- " movl %2,%0\n" \ |
6437 |
+- "1: rep; stosb\n" \ |
6438 |
+- "2:\n" \ |
6439 |
+- ".section .fixup,\"ax\"\n" \ |
6440 |
+- "3: lea 0(%2,%0,4),%0\n" \ |
6441 |
+- " jmp 2b\n" \ |
6442 |
+- ".previous\n" \ |
6443 |
+- ".section __ex_table,\"a\"\n" \ |
6444 |
+- " .align 4\n" \ |
6445 |
+- " .long 0b,3b\n" \ |
6446 |
+- " .long 1b,2b\n" \ |
6447 |
+- ".previous" \ |
6448 |
+- : "=&c"(size), "=&D" (__d0) \ |
6449 |
+- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ |
6450 |
+-} while (0) |
6451 |
++static unsigned long __do_clear_user(void __user *addr, unsigned long size) |
6452 |
++{ |
6453 |
++ int __d0; |
6454 |
++ |
6455 |
++ might_sleep(); |
6456 |
++ __asm__ __volatile__( |
6457 |
++ " movw %w6,%%es\n" |
6458 |
++ "0: rep; stosl\n" |
6459 |
++ " movl %2,%0\n" |
6460 |
++ "1: rep; stosb\n" |
6461 |
++ "2:\n" |
6462 |
++ " pushl %%ss\n" |
6463 |
++ " popl %%es\n" |
6464 |
++ ".section .fixup,\"ax\"\n" |
6465 |
++ "3: lea 0(%2,%0,4),%0\n" |
6466 |
++ " jmp 2b\n" |
6467 |
++ ".previous\n" |
6468 |
++ ".section __ex_table,\"a\"\n" |
6469 |
++ " .align 4\n" |
6470 |
++ " .long 0b,3b\n" |
6471 |
++ " .long 1b,2b\n" |
6472 |
++ ".previous" |
6473 |
++ : "=&c"(size), "=&D" (__d0) |
6474 |
++ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0), |
6475 |
++ "r"(__USER_DS)); |
6476 |
++ return size; |
6477 |
++} |
6478 |
+ |
6479 |
+ /** |
6480 |
+ * clear_user: - Zero a block of memory in user space. |
6481 |
+@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon |
6482 |
+ { |
6483 |
+ might_sleep(); |
6484 |
+ if (access_ok(VERIFY_WRITE, to, n)) |
6485 |
+- __do_clear_user(to, n); |
6486 |
++ n = __do_clear_user(to, n); |
6487 |
+ return n; |
6488 |
+ } |
6489 |
+ EXPORT_SYMBOL(clear_user); |
6490 |
+@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user); |
6491 |
+ unsigned long |
6492 |
+ __clear_user(void __user *to, unsigned long n) |
6493 |
+ { |
6494 |
+- __do_clear_user(to, n); |
6495 |
+- return n; |
6496 |
++ return __do_clear_user(to, n); |
6497 |
+ } |
6498 |
+ EXPORT_SYMBOL(__clear_user); |
6499 |
+ |
6500 |
+@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s, |
6501 |
+ might_sleep(); |
6502 |
+ |
6503 |
+ __asm__ __volatile__( |
6504 |
++ " movw %w8,%%es\n" |
6505 |
+ " testl %0, %0\n" |
6506 |
+ " jz 3f\n" |
6507 |
+- " andl %0,%%ecx\n" |
6508 |
++ " movl %0,%%ecx\n" |
6509 |
+ "0: repne; scasb\n" |
6510 |
+ " setne %%al\n" |
6511 |
+ " subl %%ecx,%0\n" |
6512 |
+ " addl %0,%%eax\n" |
6513 |
+ "1:\n" |
6514 |
++ " pushl %%ss\n" |
6515 |
++ " popl %%es\n" |
6516 |
+ ".section .fixup,\"ax\"\n" |
6517 |
+ "2: xorl %%eax,%%eax\n" |
6518 |
+ " jmp 1b\n" |
6519 |
+@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s, |
6520 |
+ " .long 0b,2b\n" |
6521 |
+ ".previous" |
6522 |
+ :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp) |
6523 |
+- :"0" (n), "1" (s), "2" (0), "3" (mask) |
6524 |
++ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS) |
6525 |
+ :"cc"); |
6526 |
+ return res & mask; |
6527 |
+ } |
6528 |
+@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user); |
6529 |
+ |
6530 |
+ #ifdef CONFIG_X86_INTEL_USERCOPY |
6531 |
+ static unsigned long |
6532 |
+-__copy_user_intel(void __user *to, const void *from, unsigned long size) |
6533 |
++__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size) |
6534 |
++{ |
6535 |
++ int d0, d1; |
6536 |
++ __asm__ __volatile__( |
6537 |
++ " movw %w6, %%es\n" |
6538 |
++ " .align 2,0x90\n" |
6539 |
++ "1: movl 32(%4), %%eax\n" |
6540 |
++ " cmpl $67, %0\n" |
6541 |
++ " jbe 3f\n" |
6542 |
++ "2: movl 64(%4), %%eax\n" |
6543 |
++ " .align 2,0x90\n" |
6544 |
++ "3: movl 0(%4), %%eax\n" |
6545 |
++ "4: movl 4(%4), %%edx\n" |
6546 |
++ "5: movl %%eax, %%es:0(%3)\n" |
6547 |
++ "6: movl %%edx, %%es:4(%3)\n" |
6548 |
++ "7: movl 8(%4), %%eax\n" |
6549 |
++ "8: movl 12(%4),%%edx\n" |
6550 |
++ "9: movl %%eax, %%es:8(%3)\n" |
6551 |
++ "10: movl %%edx, %%es:12(%3)\n" |
6552 |
++ "11: movl 16(%4), %%eax\n" |
6553 |
++ "12: movl 20(%4), %%edx\n" |
6554 |
++ "13: movl %%eax, %%es:16(%3)\n" |
6555 |
++ "14: movl %%edx, %%es:20(%3)\n" |
6556 |
++ "15: movl 24(%4), %%eax\n" |
6557 |
++ "16: movl 28(%4), %%edx\n" |
6558 |
++ "17: movl %%eax, %%es:24(%3)\n" |
6559 |
++ "18: movl %%edx, %%es:28(%3)\n" |
6560 |
++ "19: movl 32(%4), %%eax\n" |
6561 |
++ "20: movl 36(%4), %%edx\n" |
6562 |
++ "21: movl %%eax, %%es:32(%3)\n" |
6563 |
++ "22: movl %%edx, %%es:36(%3)\n" |
6564 |
++ "23: movl 40(%4), %%eax\n" |
6565 |
++ "24: movl 44(%4), %%edx\n" |
6566 |
++ "25: movl %%eax, %%es:40(%3)\n" |
6567 |
++ "26: movl %%edx, %%es:44(%3)\n" |
6568 |
++ "27: movl 48(%4), %%eax\n" |
6569 |
++ "28: movl 52(%4), %%edx\n" |
6570 |
++ "29: movl %%eax, %%es:48(%3)\n" |
6571 |
++ "30: movl %%edx, %%es:52(%3)\n" |
6572 |
++ "31: movl 56(%4), %%eax\n" |
6573 |
++ "32: movl 60(%4), %%edx\n" |
6574 |
++ "33: movl %%eax, %%es:56(%3)\n" |
6575 |
++ "34: movl %%edx, %%es:60(%3)\n" |
6576 |
++ " addl $-64, %0\n" |
6577 |
++ " addl $64, %4\n" |
6578 |
++ " addl $64, %3\n" |
6579 |
++ " cmpl $63, %0\n" |
6580 |
++ " ja 1b\n" |
6581 |
++ "35: movl %0, %%eax\n" |
6582 |
++ " shrl $2, %0\n" |
6583 |
++ " andl $3, %%eax\n" |
6584 |
++ " cld\n" |
6585 |
++ "99: rep; movsl\n" |
6586 |
++ "36: movl %%eax, %0\n" |
6587 |
++ "37: rep; movsb\n" |
6588 |
++ "100:\n" |
6589 |
++ " pushl %%ss\n" |
6590 |
++ " popl %%es\n" |
6591 |
++ ".section .fixup,\"ax\"\n" |
6592 |
++ "101: lea 0(%%eax,%0,4),%0\n" |
6593 |
++ " jmp 100b\n" |
6594 |
++ ".previous\n" |
6595 |
++ ".section __ex_table,\"a\"\n" |
6596 |
++ " .align 4\n" |
6597 |
++ " .long 1b,100b\n" |
6598 |
++ " .long 2b,100b\n" |
6599 |
++ " .long 3b,100b\n" |
6600 |
++ " .long 4b,100b\n" |
6601 |
++ " .long 5b,100b\n" |
6602 |
++ " .long 6b,100b\n" |
6603 |
++ " .long 7b,100b\n" |
6604 |
++ " .long 8b,100b\n" |
6605 |
++ " .long 9b,100b\n" |
6606 |
++ " .long 10b,100b\n" |
6607 |
++ " .long 11b,100b\n" |
6608 |
++ " .long 12b,100b\n" |
6609 |
++ " .long 13b,100b\n" |
6610 |
++ " .long 14b,100b\n" |
6611 |
++ " .long 15b,100b\n" |
6612 |
++ " .long 16b,100b\n" |
6613 |
++ " .long 17b,100b\n" |
6614 |
++ " .long 18b,100b\n" |
6615 |
++ " .long 19b,100b\n" |
6616 |
++ " .long 20b,100b\n" |
6617 |
++ " .long 21b,100b\n" |
6618 |
++ " .long 22b,100b\n" |
6619 |
++ " .long 23b,100b\n" |
6620 |
++ " .long 24b,100b\n" |
6621 |
++ " .long 25b,100b\n" |
6622 |
++ " .long 26b,100b\n" |
6623 |
++ " .long 27b,100b\n" |
6624 |
++ " .long 28b,100b\n" |
6625 |
++ " .long 29b,100b\n" |
6626 |
++ " .long 30b,100b\n" |
6627 |
++ " .long 31b,100b\n" |
6628 |
++ " .long 32b,100b\n" |
6629 |
++ " .long 33b,100b\n" |
6630 |
++ " .long 34b,100b\n" |
6631 |
++ " .long 35b,100b\n" |
6632 |
++ " .long 36b,100b\n" |
6633 |
++ " .long 37b,100b\n" |
6634 |
++ " .long 99b,101b\n" |
6635 |
++ ".previous" |
6636 |
++ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
6637 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
6638 |
++ : "eax", "edx", "memory"); |
6639 |
++ return size; |
6640 |
++} |
6641 |
++ |
6642 |
++static unsigned long |
6643 |
++__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size) |
6644 |
+ { |
6645 |
+ int d0, d1; |
6646 |
+ __asm__ __volatile__( |
6647 |
++ " movw %w6, %%ds\n" |
6648 |
+ " .align 2,0x90\n" |
6649 |
+ "1: movl 32(%4), %%eax\n" |
6650 |
+ " cmpl $67, %0\n" |
6651 |
+@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const |
6652 |
+ " .align 2,0x90\n" |
6653 |
+ "3: movl 0(%4), %%eax\n" |
6654 |
+ "4: movl 4(%4), %%edx\n" |
6655 |
+- "5: movl %%eax, 0(%3)\n" |
6656 |
+- "6: movl %%edx, 4(%3)\n" |
6657 |
++ "5: movl %%eax, %%es:0(%3)\n" |
6658 |
++ "6: movl %%edx, %%es:4(%3)\n" |
6659 |
+ "7: movl 8(%4), %%eax\n" |
6660 |
+ "8: movl 12(%4),%%edx\n" |
6661 |
+- "9: movl %%eax, 8(%3)\n" |
6662 |
+- "10: movl %%edx, 12(%3)\n" |
6663 |
++ "9: movl %%eax, %%es:8(%3)\n" |
6664 |
++ "10: movl %%edx, %%es:12(%3)\n" |
6665 |
+ "11: movl 16(%4), %%eax\n" |
6666 |
+ "12: movl 20(%4), %%edx\n" |
6667 |
+- "13: movl %%eax, 16(%3)\n" |
6668 |
+- "14: movl %%edx, 20(%3)\n" |
6669 |
++ "13: movl %%eax, %%es:16(%3)\n" |
6670 |
++ "14: movl %%edx, %%es:20(%3)\n" |
6671 |
+ "15: movl 24(%4), %%eax\n" |
6672 |
+ "16: movl 28(%4), %%edx\n" |
6673 |
+- "17: movl %%eax, 24(%3)\n" |
6674 |
+- "18: movl %%edx, 28(%3)\n" |
6675 |
++ "17: movl %%eax, %%es:24(%3)\n" |
6676 |
++ "18: movl %%edx, %%es:28(%3)\n" |
6677 |
+ "19: movl 32(%4), %%eax\n" |
6678 |
+ "20: movl 36(%4), %%edx\n" |
6679 |
+- "21: movl %%eax, 32(%3)\n" |
6680 |
+- "22: movl %%edx, 36(%3)\n" |
6681 |
++ "21: movl %%eax, %%es:32(%3)\n" |
6682 |
++ "22: movl %%edx, %%es:36(%3)\n" |
6683 |
+ "23: movl 40(%4), %%eax\n" |
6684 |
+ "24: movl 44(%4), %%edx\n" |
6685 |
+- "25: movl %%eax, 40(%3)\n" |
6686 |
+- "26: movl %%edx, 44(%3)\n" |
6687 |
++ "25: movl %%eax, %%es:40(%3)\n" |
6688 |
++ "26: movl %%edx, %%es:44(%3)\n" |
6689 |
+ "27: movl 48(%4), %%eax\n" |
6690 |
+ "28: movl 52(%4), %%edx\n" |
6691 |
+- "29: movl %%eax, 48(%3)\n" |
6692 |
+- "30: movl %%edx, 52(%3)\n" |
6693 |
++ "29: movl %%eax, %%es:48(%3)\n" |
6694 |
++ "30: movl %%edx, %%es:52(%3)\n" |
6695 |
+ "31: movl 56(%4), %%eax\n" |
6696 |
+ "32: movl 60(%4), %%edx\n" |
6697 |
+- "33: movl %%eax, 56(%3)\n" |
6698 |
+- "34: movl %%edx, 60(%3)\n" |
6699 |
++ "33: movl %%eax, %%es:56(%3)\n" |
6700 |
++ "34: movl %%edx, %%es:60(%3)\n" |
6701 |
+ " addl $-64, %0\n" |
6702 |
+ " addl $64, %4\n" |
6703 |
+ " addl $64, %3\n" |
6704 |
+@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const |
6705 |
+ "36: movl %%eax, %0\n" |
6706 |
+ "37: rep; movsb\n" |
6707 |
+ "100:\n" |
6708 |
++ " pushl %%ss\n" |
6709 |
++ " popl %%ds\n" |
6710 |
+ ".section .fixup,\"ax\"\n" |
6711 |
+ "101: lea 0(%%eax,%0,4),%0\n" |
6712 |
+ " jmp 100b\n" |
6713 |
+@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const |
6714 |
+ " .long 99b,101b\n" |
6715 |
+ ".previous" |
6716 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
6717 |
+- : "1"(to), "2"(from), "0"(size) |
6718 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
6719 |
+ : "eax", "edx", "memory"); |
6720 |
+ return size; |
6721 |
+ } |
6722 |
+@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons |
6723 |
+ { |
6724 |
+ int d0, d1; |
6725 |
+ __asm__ __volatile__( |
6726 |
++ " movw %w6, %%ds\n" |
6727 |
+ " .align 2,0x90\n" |
6728 |
+ "0: movl 32(%4), %%eax\n" |
6729 |
+ " cmpl $67, %0\n" |
6730 |
+@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons |
6731 |
+ " .align 2,0x90\n" |
6732 |
+ "2: movl 0(%4), %%eax\n" |
6733 |
+ "21: movl 4(%4), %%edx\n" |
6734 |
+- " movl %%eax, 0(%3)\n" |
6735 |
+- " movl %%edx, 4(%3)\n" |
6736 |
++ " movl %%eax, %%es:0(%3)\n" |
6737 |
++ " movl %%edx, %%es:4(%3)\n" |
6738 |
+ "3: movl 8(%4), %%eax\n" |
6739 |
+ "31: movl 12(%4),%%edx\n" |
6740 |
+- " movl %%eax, 8(%3)\n" |
6741 |
+- " movl %%edx, 12(%3)\n" |
6742 |
++ " movl %%eax, %%es:8(%3)\n" |
6743 |
++ " movl %%edx, %%es:12(%3)\n" |
6744 |
+ "4: movl 16(%4), %%eax\n" |
6745 |
+ "41: movl 20(%4), %%edx\n" |
6746 |
+- " movl %%eax, 16(%3)\n" |
6747 |
+- " movl %%edx, 20(%3)\n" |
6748 |
++ " movl %%eax, %%es:16(%3)\n" |
6749 |
++ " movl %%edx, %%es:20(%3)\n" |
6750 |
+ "10: movl 24(%4), %%eax\n" |
6751 |
+ "51: movl 28(%4), %%edx\n" |
6752 |
+- " movl %%eax, 24(%3)\n" |
6753 |
+- " movl %%edx, 28(%3)\n" |
6754 |
++ " movl %%eax, %%es:24(%3)\n" |
6755 |
++ " movl %%edx, %%es:28(%3)\n" |
6756 |
+ "11: movl 32(%4), %%eax\n" |
6757 |
+ "61: movl 36(%4), %%edx\n" |
6758 |
+- " movl %%eax, 32(%3)\n" |
6759 |
+- " movl %%edx, 36(%3)\n" |
6760 |
++ " movl %%eax, %%es:32(%3)\n" |
6761 |
++ " movl %%edx, %%es:36(%3)\n" |
6762 |
+ "12: movl 40(%4), %%eax\n" |
6763 |
+ "71: movl 44(%4), %%edx\n" |
6764 |
+- " movl %%eax, 40(%3)\n" |
6765 |
+- " movl %%edx, 44(%3)\n" |
6766 |
++ " movl %%eax, %%es:40(%3)\n" |
6767 |
++ " movl %%edx, %%es:44(%3)\n" |
6768 |
+ "13: movl 48(%4), %%eax\n" |
6769 |
+ "81: movl 52(%4), %%edx\n" |
6770 |
+- " movl %%eax, 48(%3)\n" |
6771 |
+- " movl %%edx, 52(%3)\n" |
6772 |
++ " movl %%eax, %%es:48(%3)\n" |
6773 |
++ " movl %%edx, %%es:52(%3)\n" |
6774 |
+ "14: movl 56(%4), %%eax\n" |
6775 |
+ "91: movl 60(%4), %%edx\n" |
6776 |
+- " movl %%eax, 56(%3)\n" |
6777 |
+- " movl %%edx, 60(%3)\n" |
6778 |
++ " movl %%eax, %%es:56(%3)\n" |
6779 |
++ " movl %%edx, %%es:60(%3)\n" |
6780 |
+ " addl $-64, %0\n" |
6781 |
+ " addl $64, %4\n" |
6782 |
+ " addl $64, %3\n" |
6783 |
+@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons |
6784 |
+ " movl %%eax,%0\n" |
6785 |
+ "7: rep; movsb\n" |
6786 |
+ "8:\n" |
6787 |
++ " pushl %%ss\n" |
6788 |
++ " popl %%ds\n" |
6789 |
+ ".section .fixup,\"ax\"\n" |
6790 |
+ "9: lea 0(%%eax,%0,4),%0\n" |
6791 |
+ "16: pushl %0\n" |
6792 |
+@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons |
6793 |
+ " .long 7b,16b\n" |
6794 |
+ ".previous" |
6795 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
6796 |
+- : "1"(to), "2"(from), "0"(size) |
6797 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
6798 |
+ : "eax", "edx", "memory"); |
6799 |
+ return size; |
6800 |
+ } |
6801 |
+@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing |
6802 |
+ int d0, d1; |
6803 |
+ |
6804 |
+ __asm__ __volatile__( |
6805 |
++ " movw %w6, %%ds\n" |
6806 |
+ " .align 2,0x90\n" |
6807 |
+ "0: movl 32(%4), %%eax\n" |
6808 |
+ " cmpl $67, %0\n" |
6809 |
+@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing |
6810 |
+ " .align 2,0x90\n" |
6811 |
+ "2: movl 0(%4), %%eax\n" |
6812 |
+ "21: movl 4(%4), %%edx\n" |
6813 |
+- " movnti %%eax, 0(%3)\n" |
6814 |
+- " movnti %%edx, 4(%3)\n" |
6815 |
++ " movnti %%eax, %%es:0(%3)\n" |
6816 |
++ " movnti %%edx, %%es:4(%3)\n" |
6817 |
+ "3: movl 8(%4), %%eax\n" |
6818 |
+ "31: movl 12(%4),%%edx\n" |
6819 |
+- " movnti %%eax, 8(%3)\n" |
6820 |
+- " movnti %%edx, 12(%3)\n" |
6821 |
++ " movnti %%eax, %%es:8(%3)\n" |
6822 |
++ " movnti %%edx, %%es:12(%3)\n" |
6823 |
+ "4: movl 16(%4), %%eax\n" |
6824 |
+ "41: movl 20(%4), %%edx\n" |
6825 |
+- " movnti %%eax, 16(%3)\n" |
6826 |
+- " movnti %%edx, 20(%3)\n" |
6827 |
++ " movnti %%eax, %%es:16(%3)\n" |
6828 |
++ " movnti %%edx, %%es:20(%3)\n" |
6829 |
+ "10: movl 24(%4), %%eax\n" |
6830 |
+ "51: movl 28(%4), %%edx\n" |
6831 |
+- " movnti %%eax, 24(%3)\n" |
6832 |
+- " movnti %%edx, 28(%3)\n" |
6833 |
++ " movnti %%eax, %%es:24(%3)\n" |
6834 |
++ " movnti %%edx, %%es:28(%3)\n" |
6835 |
+ "11: movl 32(%4), %%eax\n" |
6836 |
+ "61: movl 36(%4), %%edx\n" |
6837 |
+- " movnti %%eax, 32(%3)\n" |
6838 |
+- " movnti %%edx, 36(%3)\n" |
6839 |
++ " movnti %%eax, %%es:32(%3)\n" |
6840 |
++ " movnti %%edx, %%es:36(%3)\n" |
6841 |
+ "12: movl 40(%4), %%eax\n" |
6842 |
+ "71: movl 44(%4), %%edx\n" |
6843 |
+- " movnti %%eax, 40(%3)\n" |
6844 |
+- " movnti %%edx, 44(%3)\n" |
6845 |
++ " movnti %%eax, %%es:40(%3)\n" |
6846 |
++ " movnti %%edx, %%es:44(%3)\n" |
6847 |
+ "13: movl 48(%4), %%eax\n" |
6848 |
+ "81: movl 52(%4), %%edx\n" |
6849 |
+- " movnti %%eax, 48(%3)\n" |
6850 |
+- " movnti %%edx, 52(%3)\n" |
6851 |
++ " movnti %%eax, %%es:48(%3)\n" |
6852 |
++ " movnti %%edx, %%es:52(%3)\n" |
6853 |
+ "14: movl 56(%4), %%eax\n" |
6854 |
+ "91: movl 60(%4), %%edx\n" |
6855 |
+- " movnti %%eax, 56(%3)\n" |
6856 |
+- " movnti %%edx, 60(%3)\n" |
6857 |
++ " movnti %%eax, %%es:56(%3)\n" |
6858 |
++ " movnti %%edx, %%es:60(%3)\n" |
6859 |
+ " addl $-64, %0\n" |
6860 |
+ " addl $64, %4\n" |
6861 |
+ " addl $64, %3\n" |
6862 |
+@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing |
6863 |
+ " movl %%eax,%0\n" |
6864 |
+ "7: rep; movsb\n" |
6865 |
+ "8:\n" |
6866 |
++ " pushl %%ss\n" |
6867 |
++ " popl %%ds\n" |
6868 |
+ ".section .fixup,\"ax\"\n" |
6869 |
+ "9: lea 0(%%eax,%0,4),%0\n" |
6870 |
+ "16: pushl %0\n" |
6871 |
+@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing |
6872 |
+ " .long 7b,16b\n" |
6873 |
+ ".previous" |
6874 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
6875 |
+- : "1"(to), "2"(from), "0"(size) |
6876 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
6877 |
+ : "eax", "edx", "memory"); |
6878 |
+ return size; |
6879 |
+ } |
6880 |
+@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n |
6881 |
+ int d0, d1; |
6882 |
+ |
6883 |
+ __asm__ __volatile__( |
6884 |
++ " movw %w6, %%ds\n" |
6885 |
+ " .align 2,0x90\n" |
6886 |
+ "0: movl 32(%4), %%eax\n" |
6887 |
+ " cmpl $67, %0\n" |
6888 |
+@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n |
6889 |
+ " .align 2,0x90\n" |
6890 |
+ "2: movl 0(%4), %%eax\n" |
6891 |
+ "21: movl 4(%4), %%edx\n" |
6892 |
+- " movnti %%eax, 0(%3)\n" |
6893 |
+- " movnti %%edx, 4(%3)\n" |
6894 |
++ " movnti %%eax, %%es:0(%3)\n" |
6895 |
++ " movnti %%edx, %%es:4(%3)\n" |
6896 |
+ "3: movl 8(%4), %%eax\n" |
6897 |
+ "31: movl 12(%4),%%edx\n" |
6898 |
+- " movnti %%eax, 8(%3)\n" |
6899 |
+- " movnti %%edx, 12(%3)\n" |
6900 |
++ " movnti %%eax, %%es:8(%3)\n" |
6901 |
++ " movnti %%edx, %%es:12(%3)\n" |
6902 |
+ "4: movl 16(%4), %%eax\n" |
6903 |
+ "41: movl 20(%4), %%edx\n" |
6904 |
+- " movnti %%eax, 16(%3)\n" |
6905 |
+- " movnti %%edx, 20(%3)\n" |
6906 |
++ " movnti %%eax, %%es:16(%3)\n" |
6907 |
++ " movnti %%edx, %%es:20(%3)\n" |
6908 |
+ "10: movl 24(%4), %%eax\n" |
6909 |
+ "51: movl 28(%4), %%edx\n" |
6910 |
+- " movnti %%eax, 24(%3)\n" |
6911 |
+- " movnti %%edx, 28(%3)\n" |
6912 |
++ " movnti %%eax, %%es:24(%3)\n" |
6913 |
++ " movnti %%edx, %%es:28(%3)\n" |
6914 |
+ "11: movl 32(%4), %%eax\n" |
6915 |
+ "61: movl 36(%4), %%edx\n" |
6916 |
+- " movnti %%eax, 32(%3)\n" |
6917 |
+- " movnti %%edx, 36(%3)\n" |
6918 |
++ " movnti %%eax, %%es:32(%3)\n" |
6919 |
++ " movnti %%edx, %%es:36(%3)\n" |
6920 |
+ "12: movl 40(%4), %%eax\n" |
6921 |
+ "71: movl 44(%4), %%edx\n" |
6922 |
+- " movnti %%eax, 40(%3)\n" |
6923 |
+- " movnti %%edx, 44(%3)\n" |
6924 |
++ " movnti %%eax, %%es:40(%3)\n" |
6925 |
++ " movnti %%edx, %%es:44(%3)\n" |
6926 |
+ "13: movl 48(%4), %%eax\n" |
6927 |
+ "81: movl 52(%4), %%edx\n" |
6928 |
+- " movnti %%eax, 48(%3)\n" |
6929 |
+- " movnti %%edx, 52(%3)\n" |
6930 |
++ " movnti %%eax, %%es:48(%3)\n" |
6931 |
++ " movnti %%edx, %%es:52(%3)\n" |
6932 |
+ "14: movl 56(%4), %%eax\n" |
6933 |
+ "91: movl 60(%4), %%edx\n" |
6934 |
+- " movnti %%eax, 56(%3)\n" |
6935 |
+- " movnti %%edx, 60(%3)\n" |
6936 |
++ " movnti %%eax, %%es:56(%3)\n" |
6937 |
++ " movnti %%edx, %%es:60(%3)\n" |
6938 |
+ " addl $-64, %0\n" |
6939 |
+ " addl $64, %4\n" |
6940 |
+ " addl $64, %3\n" |
6941 |
+@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n |
6942 |
+ " movl %%eax,%0\n" |
6943 |
+ "7: rep; movsb\n" |
6944 |
+ "8:\n" |
6945 |
++ " pushl %%ss\n" |
6946 |
++ " popl %%ds\n" |
6947 |
+ ".section .fixup,\"ax\"\n" |
6948 |
+ "9: lea 0(%%eax,%0,4),%0\n" |
6949 |
+ "16: jmp 8b\n" |
6950 |
+@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n |
6951 |
+ " .long 7b,16b\n" |
6952 |
+ ".previous" |
6953 |
+ : "=&c"(size), "=&D" (d0), "=&S" (d1) |
6954 |
+- : "1"(to), "2"(from), "0"(size) |
6955 |
++ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS) |
6956 |
+ : "eax", "edx", "memory"); |
6957 |
+ return size; |
6958 |
+ } |
6959 |
+@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n |
6960 |
+ */ |
6961 |
+ unsigned long __copy_user_zeroing_intel(void *to, const void __user *from, |
6962 |
+ unsigned long size); |
6963 |
+-unsigned long __copy_user_intel(void __user *to, const void *from, |
6964 |
++unsigned long __generic_copy_to_user_intel(void __user *to, const void *from, |
6965 |
++ unsigned long size); |
6966 |
++unsigned long __generic_copy_from_user_intel(void *to, const void __user *from, |
6967 |
+ unsigned long size); |
6968 |
+ unsigned long __copy_user_zeroing_intel_nocache(void *to, |
6969 |
+ const void __user *from, unsigned long size); |
6970 |
+ #endif /* CONFIG_X86_INTEL_USERCOPY */ |
6971 |
+ |
6972 |
+ /* Generic arbitrary sized copy. */ |
6973 |
+-#define __copy_user(to,from,size) \ |
6974 |
+-do { \ |
6975 |
+- int __d0, __d1, __d2; \ |
6976 |
+- __asm__ __volatile__( \ |
6977 |
+- " cmp $7,%0\n" \ |
6978 |
+- " jbe 1f\n" \ |
6979 |
+- " movl %1,%0\n" \ |
6980 |
+- " negl %0\n" \ |
6981 |
+- " andl $7,%0\n" \ |
6982 |
+- " subl %0,%3\n" \ |
6983 |
+- "4: rep; movsb\n" \ |
6984 |
+- " movl %3,%0\n" \ |
6985 |
+- " shrl $2,%0\n" \ |
6986 |
+- " andl $3,%3\n" \ |
6987 |
+- " .align 2,0x90\n" \ |
6988 |
+- "0: rep; movsl\n" \ |
6989 |
+- " movl %3,%0\n" \ |
6990 |
+- "1: rep; movsb\n" \ |
6991 |
+- "2:\n" \ |
6992 |
+- ".section .fixup,\"ax\"\n" \ |
6993 |
+- "5: addl %3,%0\n" \ |
6994 |
+- " jmp 2b\n" \ |
6995 |
+- "3: lea 0(%3,%0,4),%0\n" \ |
6996 |
+- " jmp 2b\n" \ |
6997 |
+- ".previous\n" \ |
6998 |
+- ".section __ex_table,\"a\"\n" \ |
6999 |
+- " .align 4\n" \ |
7000 |
+- " .long 4b,5b\n" \ |
7001 |
+- " .long 0b,3b\n" \ |
7002 |
+- " .long 1b,2b\n" \ |
7003 |
+- ".previous" \ |
7004 |
+- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ |
7005 |
+- : "3"(size), "0"(size), "1"(to), "2"(from) \ |
7006 |
+- : "memory"); \ |
7007 |
+-} while (0) |
7008 |
+- |
7009 |
+-#define __copy_user_zeroing(to,from,size) \ |
7010 |
+-do { \ |
7011 |
+- int __d0, __d1, __d2; \ |
7012 |
+- __asm__ __volatile__( \ |
7013 |
+- " cmp $7,%0\n" \ |
7014 |
+- " jbe 1f\n" \ |
7015 |
+- " movl %1,%0\n" \ |
7016 |
+- " negl %0\n" \ |
7017 |
+- " andl $7,%0\n" \ |
7018 |
+- " subl %0,%3\n" \ |
7019 |
+- "4: rep; movsb\n" \ |
7020 |
+- " movl %3,%0\n" \ |
7021 |
+- " shrl $2,%0\n" \ |
7022 |
+- " andl $3,%3\n" \ |
7023 |
+- " .align 2,0x90\n" \ |
7024 |
+- "0: rep; movsl\n" \ |
7025 |
+- " movl %3,%0\n" \ |
7026 |
+- "1: rep; movsb\n" \ |
7027 |
+- "2:\n" \ |
7028 |
+- ".section .fixup,\"ax\"\n" \ |
7029 |
+- "5: addl %3,%0\n" \ |
7030 |
+- " jmp 6f\n" \ |
7031 |
+- "3: lea 0(%3,%0,4),%0\n" \ |
7032 |
+- "6: pushl %0\n" \ |
7033 |
+- " pushl %%eax\n" \ |
7034 |
+- " xorl %%eax,%%eax\n" \ |
7035 |
+- " rep; stosb\n" \ |
7036 |
+- " popl %%eax\n" \ |
7037 |
+- " popl %0\n" \ |
7038 |
+- " jmp 2b\n" \ |
7039 |
+- ".previous\n" \ |
7040 |
+- ".section __ex_table,\"a\"\n" \ |
7041 |
+- " .align 4\n" \ |
7042 |
+- " .long 4b,5b\n" \ |
7043 |
+- " .long 0b,3b\n" \ |
7044 |
+- " .long 1b,6b\n" \ |
7045 |
+- ".previous" \ |
7046 |
+- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \ |
7047 |
+- : "3"(size), "0"(size), "1"(to), "2"(from) \ |
7048 |
+- : "memory"); \ |
7049 |
+-} while (0) |
7050 |
++static unsigned long |
7051 |
++__generic_copy_to_user(void __user *to, const void *from, unsigned long size) |
7052 |
++{ |
7053 |
++ int __d0, __d1, __d2; |
7054 |
++ |
7055 |
++ __asm__ __volatile__( |
7056 |
++ " movw %w8,%%es\n" |
7057 |
++ " cmp $7,%0\n" |
7058 |
++ " jbe 1f\n" |
7059 |
++ " movl %1,%0\n" |
7060 |
++ " negl %0\n" |
7061 |
++ " andl $7,%0\n" |
7062 |
++ " subl %0,%3\n" |
7063 |
++ "4: rep; movsb\n" |
7064 |
++ " movl %3,%0\n" |
7065 |
++ " shrl $2,%0\n" |
7066 |
++ " andl $3,%3\n" |
7067 |
++ " .align 2,0x90\n" |
7068 |
++ "0: rep; movsl\n" |
7069 |
++ " movl %3,%0\n" |
7070 |
++ "1: rep; movsb\n" |
7071 |
++ "2:\n" |
7072 |
++ " pushl %%ss\n" |
7073 |
++ " popl %%es\n" |
7074 |
++ ".section .fixup,\"ax\"\n" |
7075 |
++ "5: addl %3,%0\n" |
7076 |
++ " jmp 2b\n" |
7077 |
++ "3: lea 0(%3,%0,4),%0\n" |
7078 |
++ " jmp 2b\n" |
7079 |
++ ".previous\n" |
7080 |
++ ".section __ex_table,\"a\"\n" |
7081 |
++ " .align 4\n" |
7082 |
++ " .long 4b,5b\n" |
7083 |
++ " .long 0b,3b\n" |
7084 |
++ " .long 1b,2b\n" |
7085 |
++ ".previous" |
7086 |
++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) |
7087 |
++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) |
7088 |
++ : "memory"); |
7089 |
++ return size; |
7090 |
++} |
7091 |
++ |
7092 |
++static unsigned long |
7093 |
++__generic_copy_from_user(void *to, const void __user *from, unsigned long size) |
7094 |
++{ |
7095 |
++ int __d0, __d1, __d2; |
7096 |
++ |
7097 |
++ __asm__ __volatile__( |
7098 |
++ " movw %w8,%%ds\n" |
7099 |
++ " cmp $7,%0\n" |
7100 |
++ " jbe 1f\n" |
7101 |
++ " movl %1,%0\n" |
7102 |
++ " negl %0\n" |
7103 |
++ " andl $7,%0\n" |
7104 |
++ " subl %0,%3\n" |
7105 |
++ "4: rep; movsb\n" |
7106 |
++ " movl %3,%0\n" |
7107 |
++ " shrl $2,%0\n" |
7108 |
++ " andl $3,%3\n" |
7109 |
++ " .align 2,0x90\n" |
7110 |
++ "0: rep; movsl\n" |
7111 |
++ " movl %3,%0\n" |
7112 |
++ "1: rep; movsb\n" |
7113 |
++ "2:\n" |
7114 |
++ " pushl %%ss\n" |
7115 |
++ " popl %%ds\n" |
7116 |
++ ".section .fixup,\"ax\"\n" |
7117 |
++ "5: addl %3,%0\n" |
7118 |
++ " jmp 2b\n" |
7119 |
++ "3: lea 0(%3,%0,4),%0\n" |
7120 |
++ " jmp 2b\n" |
7121 |
++ ".previous\n" |
7122 |
++ ".section __ex_table,\"a\"\n" |
7123 |
++ " .align 4\n" |
7124 |
++ " .long 4b,5b\n" |
7125 |
++ " .long 0b,3b\n" |
7126 |
++ " .long 1b,2b\n" |
7127 |
++ ".previous" |
7128 |
++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) |
7129 |
++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) |
7130 |
++ : "memory"); |
7131 |
++ return size; |
7132 |
++} |
7133 |
++ |
7134 |
++static unsigned long |
7135 |
++__copy_user_zeroing(void *to, const void __user *from, unsigned long size) |
7136 |
++{ |
7137 |
++ int __d0, __d1, __d2; |
7138 |
++ |
7139 |
++ __asm__ __volatile__( |
7140 |
++ " movw %w8,%%ds\n" |
7141 |
++ " cmp $7,%0\n" |
7142 |
++ " jbe 1f\n" |
7143 |
++ " movl %1,%0\n" |
7144 |
++ " negl %0\n" |
7145 |
++ " andl $7,%0\n" |
7146 |
++ " subl %0,%3\n" |
7147 |
++ "4: rep; movsb\n" |
7148 |
++ " movl %3,%0\n" |
7149 |
++ " shrl $2,%0\n" |
7150 |
++ " andl $3,%3\n" |
7151 |
++ " .align 2,0x90\n" |
7152 |
++ "0: rep; movsl\n" |
7153 |
++ " movl %3,%0\n" |
7154 |
++ "1: rep; movsb\n" |
7155 |
++ "2:\n" |
7156 |
++ " pushl %%ss\n" |
7157 |
++ " popl %%ds\n" |
7158 |
++ ".section .fixup,\"ax\"\n" |
7159 |
++ "5: addl %3,%0\n" |
7160 |
++ " jmp 6f\n" |
7161 |
++ "3: lea 0(%3,%0,4),%0\n" |
7162 |
++ "6: pushl %0\n" |
7163 |
++ " pushl %%eax\n" |
7164 |
++ " xorl %%eax,%%eax\n" |
7165 |
++ " rep; stosb\n" |
7166 |
++ " popl %%eax\n" |
7167 |
++ " popl %0\n" |
7168 |
++ " jmp 2b\n" |
7169 |
++ ".previous\n" |
7170 |
++ ".section __ex_table,\"a\"\n" |
7171 |
++ " .align 4\n" |
7172 |
++ " .long 4b,5b\n" |
7173 |
++ " .long 0b,3b\n" |
7174 |
++ " .long 1b,6b\n" |
7175 |
++ ".previous" |
7176 |
++ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) |
7177 |
++ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS) |
7178 |
++ : "memory"); |
7179 |
++ return size; |
7180 |
++} |
7181 |
+ |
7182 |
+ unsigned long __copy_to_user_ll(void __user *to, const void *from, |
7183 |
+ unsigned long n) |
7184 |
+@@ -774,9 +965,9 @@ survive: |
7185 |
+ } |
7186 |
+ #endif |
7187 |
+ if (movsl_is_ok(to, from, n)) |
7188 |
+- __copy_user(to, from, n); |
7189 |
++ n = __generic_copy_to_user(to, from, n); |
7190 |
+ else |
7191 |
+- n = __copy_user_intel(to, from, n); |
7192 |
++ n = __generic_copy_to_user_intel(to, from, n); |
7193 |
+ return n; |
7194 |
+ } |
7195 |
+ EXPORT_SYMBOL(__copy_to_user_ll); |
7196 |
+@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void * |
7197 |
+ unsigned long n) |
7198 |
+ { |
7199 |
+ if (movsl_is_ok(to, from, n)) |
7200 |
+- __copy_user_zeroing(to, from, n); |
7201 |
++ n = __copy_user_zeroing(to, from, n); |
7202 |
+ else |
7203 |
+ n = __copy_user_zeroing_intel(to, from, n); |
7204 |
+ return n; |
7205 |
+@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero |
7206 |
+ unsigned long n) |
7207 |
+ { |
7208 |
+ if (movsl_is_ok(to, from, n)) |
7209 |
+- __copy_user(to, from, n); |
7210 |
++ n = __generic_copy_from_user(to, from, n); |
7211 |
+ else |
7212 |
+- n = __copy_user_intel((void __user *)to, |
7213 |
++ n = __generic_copy_from_user_intel((void __user *)to, |
7214 |
+ (const void *)from, n); |
7215 |
+ return n; |
7216 |
+ } |
7217 |
+@@ -809,11 +1000,11 @@ unsigned long __copy_from_user_ll_nocach |
7218 |
+ { |
7219 |
+ #ifdef CONFIG_X86_INTEL_USERCOPY |
7220 |
+ if ( n > 64 && cpu_has_xmm2) |
7221 |
+- n = __copy_user_zeroing_intel_nocache(to, from, n); |
7222 |
++ n = __copy_user_zeroing_intel_nocache(to, from, n); |
7223 |
+ else |
7224 |
+- __copy_user_zeroing(to, from, n); |
7225 |
++ n = __copy_user_zeroing(to, from, n); |
7226 |
+ #else |
7227 |
+- __copy_user_zeroing(to, from, n); |
7228 |
++ n = __copy_user_zeroing(to, from, n); |
7229 |
+ #endif |
7230 |
+ return n; |
7231 |
+ } |
7232 |
+@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach |
7233 |
+ { |
7234 |
+ #ifdef CONFIG_X86_INTEL_USERCOPY |
7235 |
+ if ( n > 64 && cpu_has_xmm2) |
7236 |
+- n = __copy_user_intel_nocache(to, from, n); |
7237 |
++ n = __copy_user_intel_nocache(to, from, n); |
7238 |
+ else |
7239 |
+- __copy_user(to, from, n); |
7240 |
++ n = __generic_copy_from_user(to, from, n); |
7241 |
+ #else |
7242 |
+- __copy_user(to, from, n); |
7243 |
++ n = __generic_copy_from_user(to, from, n); |
7244 |
+ #endif |
7245 |
+ return n; |
7246 |
+ } |
7247 |
+@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us |
7248 |
+ return n; |
7249 |
+ } |
7250 |
+ EXPORT_SYMBOL(copy_from_user); |
7251 |
++ |
7252 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
7253 |
++void __set_fs(mm_segment_t x, int cpu) |
7254 |
++{ |
7255 |
++ unsigned long limit = x.seg; |
7256 |
++ __u32 a, b; |
7257 |
++ |
7258 |
++ current_thread_info()->addr_limit = x; |
7259 |
++ if (likely(limit)) |
7260 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
7261 |
++ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC); |
7262 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b); |
7263 |
++} |
7264 |
++ |
7265 |
++void set_fs(mm_segment_t x) |
7266 |
++{ |
7267 |
++ __set_fs(x, get_cpu()); |
7268 |
++ put_cpu_no_resched(); |
7269 |
++} |
7270 |
++#else |
7271 |
++void set_fs(mm_segment_t x) |
7272 |
++{ |
7273 |
++ current_thread_info()->addr_limit = x; |
7274 |
++} |
7275 |
++#endif |
7276 |
++ |
7277 |
++EXPORT_SYMBOL(set_fs); |
7278 |
+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 |
7279 |
+--- linux-2.6.23.15/arch/i386/mach-default/setup.c 2007-10-09 21:31:38.000000000 +0100 |
7280 |
++++ linux-2.6.23.15-grsec/arch/i386/mach-default/setup.c 2008-02-11 10:37:44.000000000 +0000 |
7281 |
+@@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void) |
7282 |
+ /* |
7283 |
+ * IRQ2 is cascade interrupt to second interrupt controller |
7284 |
+ */ |
7285 |
+-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; |
7286 |
++static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL}; |
7287 |
+ |
7288 |
+ /** |
7289 |
+ * intr_init_hook - post gate setup interrupt initialisation |
7290 |
+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 |
7291 |
+--- linux-2.6.23.15/arch/i386/mach-voyager/voyager_basic.c 2007-10-09 21:31:38.000000000 +0100 |
7292 |
++++ linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_basic.c 2008-02-11 10:37:44.000000000 +0000 |
7293 |
+@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32 |
7294 |
+ __u8 cmos[4]; |
7295 |
+ ClickMap_t *map; |
7296 |
+ unsigned long map_addr; |
7297 |
+- unsigned long old; |
7298 |
++ pte_t old; |
7299 |
+ |
7300 |
+ if(region >= CLICK_ENTRIES) { |
7301 |
+ printk("Voyager: Illegal ClickMap region %d\n", region); |
7302 |
+@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32 |
7303 |
+ |
7304 |
+ /* steal page 0 for this */ |
7305 |
+ old = pg0[0]; |
7306 |
+- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); |
7307 |
++ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); |
7308 |
+ local_flush_tlb(); |
7309 |
+ /* now clear everything out but page 0 */ |
7310 |
+ map = (ClickMap_t *)(map_addr & (~PAGE_MASK)); |
7311 |
+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 |
7312 |
+--- linux-2.6.23.15/arch/i386/mach-voyager/voyager_smp.c 2007-10-09 21:31:38.000000000 +0100 |
7313 |
++++ linux-2.6.23.15-grsec/arch/i386/mach-voyager/voyager_smp.c 2008-02-11 10:37:44.000000000 +0000 |
7314 |
+@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu) |
7315 |
+ __u32 *hijack_vector; |
7316 |
+ __u32 start_phys_address = setup_trampoline(); |
7317 |
+ |
7318 |
++#ifdef CONFIG_PAX_KERNEXEC |
7319 |
++ unsigned long cr0; |
7320 |
++#endif |
7321 |
++ |
7322 |
+ /* There's a clever trick to this: The linux trampoline is |
7323 |
+ * compiled to begin at absolute location zero, so make the |
7324 |
+ * address zero but have the data segment selector compensate |
7325 |
+@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu) |
7326 |
+ |
7327 |
+ init_gdt(cpu); |
7328 |
+ per_cpu(current_task, cpu) = idle; |
7329 |
+- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu); |
7330 |
++ |
7331 |
++#ifdef CONFIG_PAX_KERNEXEC |
7332 |
++ pax_open_kernel(cr0); |
7333 |
++#endif |
7334 |
++ |
7335 |
++ early_gdt_descr.address = get_cpu_gdt_table(cpu); |
7336 |
++ |
7337 |
++#ifdef CONFIG_PAX_KERNEXEC |
7338 |
++ pax_close_kernel(cr0); |
7339 |
++#endif |
7340 |
++ |
7341 |
+ irq_ctx_init(cpu); |
7342 |
+ |
7343 |
+ /* Note: Don't modify initial ss override */ |
7344 |
+@@ -1276,7 +1290,7 @@ smp_local_timer_interrupt(void) |
7345 |
+ per_cpu(prof_counter, cpu); |
7346 |
+ } |
7347 |
+ |
7348 |
+- update_process_times(user_mode_vm(get_irq_regs())); |
7349 |
++ update_process_times(user_mode(get_irq_regs())); |
7350 |
+ } |
7351 |
+ |
7352 |
+ if( ((1<<cpu) & voyager_extended_vic_processors) == 0) |
7353 |
+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 |
7354 |
+--- linux-2.6.23.15/arch/i386/mm/boot_ioremap.c 2007-10-09 21:31:38.000000000 +0100 |
7355 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/boot_ioremap.c 2008-02-11 10:37:44.000000000 +0000 |
7356 |
+@@ -7,57 +7,37 @@ |
7357 |
+ * Written by Dave Hansen <haveblue@××××××.com> |
7358 |
+ */ |
7359 |
+ |
7360 |
+- |
7361 |
+-/* |
7362 |
+- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE |
7363 |
+- * keeps that from happenning. If anyone has a better way, I'm listening. |
7364 |
+- * |
7365 |
+- * boot_pte_t is defined only if this all works correctly |
7366 |
+- */ |
7367 |
+- |
7368 |
+-#undef CONFIG_X86_PAE |
7369 |
+ #undef CONFIG_PARAVIRT |
7370 |
+ #include <asm/page.h> |
7371 |
+ #include <asm/pgtable.h> |
7372 |
+ #include <asm/tlbflush.h> |
7373 |
+ #include <linux/init.h> |
7374 |
+ #include <linux/stddef.h> |
7375 |
+- |
7376 |
+-/* |
7377 |
+- * I'm cheating here. It is known that the two boot PTE pages are |
7378 |
+- * allocated next to each other. I'm pretending that they're just |
7379 |
+- * one big array. |
7380 |
+- */ |
7381 |
+- |
7382 |
+-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2) |
7383 |
+- |
7384 |
+-static unsigned long boot_pte_index(unsigned long vaddr) |
7385 |
+-{ |
7386 |
+- return __pa(vaddr) >> PAGE_SHIFT; |
7387 |
+-} |
7388 |
+- |
7389 |
+-static inline boot_pte_t* boot_vaddr_to_pte(void *address) |
7390 |
+-{ |
7391 |
+- boot_pte_t* boot_pg = (boot_pte_t*)pg0; |
7392 |
+- return &boot_pg[boot_pte_index((unsigned long)address)]; |
7393 |
+-} |
7394 |
++#include <linux/sched.h> |
7395 |
+ |
7396 |
+ /* |
7397 |
+ * This is only for a caller who is clever enough to page-align |
7398 |
+ * phys_addr and virtual_source, and who also has a preference |
7399 |
+ * about which virtual address from which to steal ptes |
7400 |
+ */ |
7401 |
+-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, |
7402 |
+- void* virtual_source) |
7403 |
++static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, |
7404 |
++ char* virtual_source) |
7405 |
+ { |
7406 |
+- boot_pte_t* pte; |
7407 |
+- int i; |
7408 |
+- char *vaddr = virtual_source; |
7409 |
++ pgd_t *pgd; |
7410 |
++ pud_t *pud; |
7411 |
++ pmd_t *pmd; |
7412 |
++ pte_t* pte; |
7413 |
++ unsigned int i; |
7414 |
++ unsigned long vaddr = (unsigned long)virtual_source; |
7415 |
++ |
7416 |
++ pgd = pgd_offset_k(vaddr); |
7417 |
++ pud = pud_offset(pgd, vaddr); |
7418 |
++ pmd = pmd_offset(pud, vaddr); |
7419 |
++ pte = pte_offset_kernel(pmd, vaddr); |
7420 |
+ |
7421 |
+- pte = boot_vaddr_to_pte(virtual_source); |
7422 |
+ for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) { |
7423 |
+ set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL)); |
7424 |
+- __flush_tlb_one(&vaddr[i*PAGE_SIZE]); |
7425 |
++ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]); |
7426 |
+ } |
7427 |
+ } |
7428 |
+ |
7429 |
+diff -Nurp linux-2.6.23.15/arch/i386/mm/extable.c linux-2.6.23.15-grsec/arch/i386/mm/extable.c |
7430 |
+--- linux-2.6.23.15/arch/i386/mm/extable.c 2007-10-09 21:31:38.000000000 +0100 |
7431 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/extable.c 2008-02-11 10:37:44.000000000 +0000 |
7432 |
+@@ -4,14 +4,63 @@ |
7433 |
+ |
7434 |
+ #include <linux/module.h> |
7435 |
+ #include <linux/spinlock.h> |
7436 |
++#include <linux/sort.h> |
7437 |
+ #include <asm/uaccess.h> |
7438 |
+ |
7439 |
++/* |
7440 |
++ * The exception table needs to be sorted so that the binary |
7441 |
++ * search that we use to find entries in it works properly. |
7442 |
++ * This is used both for the kernel exception table and for |
7443 |
++ * the exception tables of modules that get loaded. |
7444 |
++ */ |
7445 |
++static int cmp_ex(const void *a, const void *b) |
7446 |
++{ |
7447 |
++ const struct exception_table_entry *x = a, *y = b; |
7448 |
++ |
7449 |
++ /* avoid overflow */ |
7450 |
++ if (x->insn > y->insn) |
7451 |
++ return 1; |
7452 |
++ if (x->insn < y->insn) |
7453 |
++ return -1; |
7454 |
++ return 0; |
7455 |
++} |
7456 |
++ |
7457 |
++static void swap_ex(void *a, void *b, int size) |
7458 |
++{ |
7459 |
++ struct exception_table_entry t, *x = a, *y = b; |
7460 |
++ |
7461 |
++#ifdef CONFIG_PAX_KERNEXEC |
7462 |
++ unsigned long cr0; |
7463 |
++#endif |
7464 |
++ |
7465 |
++ t = *x; |
7466 |
++ |
7467 |
++#ifdef CONFIG_PAX_KERNEXEC |
7468 |
++ pax_open_kernel(cr0); |
7469 |
++#endif |
7470 |
++ |
7471 |
++ *x = *y; |
7472 |
++ *y = t; |
7473 |
++ |
7474 |
++#ifdef CONFIG_PAX_KERNEXEC |
7475 |
++ pax_close_kernel(cr0); |
7476 |
++#endif |
7477 |
++ |
7478 |
++} |
7479 |
++ |
7480 |
++void sort_extable(struct exception_table_entry *start, |
7481 |
++ struct exception_table_entry *finish) |
7482 |
++{ |
7483 |
++ sort(start, finish - start, sizeof(struct exception_table_entry), |
7484 |
++ cmp_ex, swap_ex); |
7485 |
++} |
7486 |
++ |
7487 |
+ int fixup_exception(struct pt_regs *regs) |
7488 |
+ { |
7489 |
+ const struct exception_table_entry *fixup; |
7490 |
+ |
7491 |
+ #ifdef CONFIG_PNPBIOS |
7492 |
+- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs))) |
7493 |
++ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs))) |
7494 |
+ { |
7495 |
+ extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; |
7496 |
+ extern u32 pnp_bios_is_utter_crap; |
7497 |
+diff -Nurp linux-2.6.23.15/arch/i386/mm/fault.c linux-2.6.23.15-grsec/arch/i386/mm/fault.c |
7498 |
+--- linux-2.6.23.15/arch/i386/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
7499 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
7500 |
+@@ -25,10 +25,14 @@ |
7501 |
+ #include <linux/kprobes.h> |
7502 |
+ #include <linux/uaccess.h> |
7503 |
+ #include <linux/kdebug.h> |
7504 |
++#include <linux/unistd.h> |
7505 |
++#include <linux/compiler.h> |
7506 |
++#include <linux/binfmts.h> |
7507 |
+ |
7508 |
+ #include <asm/system.h> |
7509 |
+ #include <asm/desc.h> |
7510 |
+ #include <asm/segment.h> |
7511 |
++#include <asm/tlbflush.h> |
7512 |
+ |
7513 |
+ extern void die(const char *,struct pt_regs *,long); |
7514 |
+ |
7515 |
+@@ -79,7 +83,8 @@ static inline unsigned long get_segment_ |
7516 |
+ { |
7517 |
+ unsigned long eip = regs->eip; |
7518 |
+ unsigned seg = regs->xcs & 0xffff; |
7519 |
+- u32 seg_ar, seg_limit, base, *desc; |
7520 |
++ u32 seg_ar, seg_limit, base; |
7521 |
++ struct desc_struct *desc; |
7522 |
+ |
7523 |
+ /* Unlikely, but must come before segment checks. */ |
7524 |
+ if (unlikely(regs->eflags & VM_MASK)) { |
7525 |
+@@ -93,7 +98,7 @@ static inline unsigned long get_segment_ |
7526 |
+ |
7527 |
+ /* By far the most common cases. */ |
7528 |
+ if (likely(SEGMENT_IS_FLAT_CODE(seg))) |
7529 |
+- return eip; |
7530 |
++ return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0); |
7531 |
+ |
7532 |
+ /* Check the segment exists, is within the current LDT/GDT size, |
7533 |
+ that kernel/user (ring 0..3) has the appropriate privilege, |
7534 |
+@@ -111,16 +116,19 @@ static inline unsigned long get_segment_ |
7535 |
+ if (seg & (1<<2)) { |
7536 |
+ /* Must lock the LDT while reading it. */ |
7537 |
+ down(¤t->mm->context.sem); |
7538 |
+- desc = current->mm->context.ldt; |
7539 |
+- desc = (void *)desc + (seg & ~7); |
7540 |
++ if ((seg >> 3) >= current->mm->context.size) { |
7541 |
++ up(¤t->mm->context.sem); |
7542 |
++ *eip_limit = 0; |
7543 |
++ return 1; /* So that returned eip > *eip_limit. */ |
7544 |
++ } |
7545 |
++ desc = ¤t->mm->context.ldt[seg >> 3]; |
7546 |
+ } else { |
7547 |
+ /* Must disable preemption while reading the GDT. */ |
7548 |
+- desc = (u32 *)get_cpu_gdt_table(get_cpu()); |
7549 |
+- desc = (void *)desc + (seg & ~7); |
7550 |
++ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3]; |
7551 |
+ } |
7552 |
+ |
7553 |
+ /* Decode the code segment base from the descriptor */ |
7554 |
+- base = get_desc_base((unsigned long *)desc); |
7555 |
++ base = get_desc_base(desc); |
7556 |
+ |
7557 |
+ if (seg & (1<<2)) { |
7558 |
+ up(¤t->mm->context.sem); |
7559 |
+@@ -221,6 +229,30 @@ static noinline void force_sig_info_faul |
7560 |
+ |
7561 |
+ fastcall void do_invalid_op(struct pt_regs *, unsigned long); |
7562 |
+ |
7563 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
7564 |
++static int pax_handle_fetch_fault(struct pt_regs *regs); |
7565 |
++#endif |
7566 |
++ |
7567 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7568 |
++static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address) |
7569 |
++{ |
7570 |
++ pgd_t *pgd; |
7571 |
++ pud_t *pud; |
7572 |
++ pmd_t *pmd; |
7573 |
++ |
7574 |
++ pgd = pgd_offset(mm, address); |
7575 |
++ if (!pgd_present(*pgd)) |
7576 |
++ return NULL; |
7577 |
++ pud = pud_offset(pgd, address); |
7578 |
++ if (!pud_present(*pud)) |
7579 |
++ return NULL; |
7580 |
++ pmd = pmd_offset(pud, address); |
7581 |
++ if (!pmd_present(*pmd)) |
7582 |
++ return NULL; |
7583 |
++ return pmd; |
7584 |
++} |
7585 |
++#endif |
7586 |
++ |
7587 |
+ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address) |
7588 |
+ { |
7589 |
+ unsigned index = pgd_index(address); |
7590 |
+@@ -304,14 +336,21 @@ fastcall void __kprobes do_page_fault(st |
7591 |
+ struct task_struct *tsk; |
7592 |
+ struct mm_struct *mm; |
7593 |
+ struct vm_area_struct * vma; |
7594 |
+- unsigned long address; |
7595 |
+ int write, si_code; |
7596 |
+ int fault; |
7597 |
++ pte_t *pte; |
7598 |
++ |
7599 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7600 |
++ pmd_t *pmd; |
7601 |
++ spinlock_t *ptl; |
7602 |
++ unsigned char pte_mask; |
7603 |
++#endif |
7604 |
+ |
7605 |
+ /* get the address */ |
7606 |
+- address = read_cr2(); |
7607 |
++ const unsigned long address = read_cr2(); |
7608 |
+ |
7609 |
+ tsk = current; |
7610 |
++ mm = tsk->mm; |
7611 |
+ |
7612 |
+ si_code = SEGV_MAPERR; |
7613 |
+ |
7614 |
+@@ -348,14 +387,12 @@ fastcall void __kprobes do_page_fault(st |
7615 |
+ if (regs->eflags & (X86_EFLAGS_IF|VM_MASK)) |
7616 |
+ local_irq_enable(); |
7617 |
+ |
7618 |
+- mm = tsk->mm; |
7619 |
+- |
7620 |
+ /* |
7621 |
+ * If we're in an interrupt, have no user context or are running in an |
7622 |
+ * atomic region then we must not take the fault.. |
7623 |
+ */ |
7624 |
+ if (in_atomic() || !mm) |
7625 |
+- goto bad_area_nosemaphore; |
7626 |
++ goto bad_area_nopax; |
7627 |
+ |
7628 |
+ /* When running in the kernel we expect faults to occur only to |
7629 |
+ * addresses in user space. All other faults represent errors in the |
7630 |
+@@ -375,10 +412,104 @@ fastcall void __kprobes do_page_fault(st |
7631 |
+ if (!down_read_trylock(&mm->mmap_sem)) { |
7632 |
+ if ((error_code & 4) == 0 && |
7633 |
+ !search_exception_tables(regs->eip)) |
7634 |
+- goto bad_area_nosemaphore; |
7635 |
++ goto bad_area_nopax; |
7636 |
+ down_read(&mm->mmap_sem); |
7637 |
+ } |
7638 |
+ |
7639 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7640 |
++ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) || |
7641 |
++ !(mm->pax_flags & MF_PAX_PAGEEXEC)) |
7642 |
++ goto not_pax_fault; |
7643 |
++ |
7644 |
++ /* PaX: it's our fault, let's handle it if we can */ |
7645 |
++ |
7646 |
++ /* PaX: take a look at read faults before acquiring any locks */ |
7647 |
++ if (unlikely(!(error_code & 2) && (regs->eip == address))) { |
7648 |
++ /* instruction fetch attempt from a protected page in user mode */ |
7649 |
++ up_read(&mm->mmap_sem); |
7650 |
++ |
7651 |
++#ifdef CONFIG_PAX_EMUTRAMP |
7652 |
++ switch (pax_handle_fetch_fault(regs)) { |
7653 |
++ case 2: |
7654 |
++ return; |
7655 |
++ } |
7656 |
++#endif |
7657 |
++ |
7658 |
++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp); |
7659 |
++ do_exit(SIGKILL); |
7660 |
++ } |
7661 |
++ |
7662 |
++ pmd = pax_get_pmd(mm, address); |
7663 |
++ if (unlikely(!pmd)) |
7664 |
++ goto not_pax_fault; |
7665 |
++ |
7666 |
++ pte = pte_offset_map_lock(mm, pmd, address, &ptl); |
7667 |
++ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) { |
7668 |
++ pte_unmap_unlock(pte, ptl); |
7669 |
++ goto not_pax_fault; |
7670 |
++ } |
7671 |
++ |
7672 |
++ if (unlikely((error_code & 2) && !pte_write(*pte))) { |
7673 |
++ /* write attempt to a protected page in user mode */ |
7674 |
++ pte_unmap_unlock(pte, ptl); |
7675 |
++ goto not_pax_fault; |
7676 |
++ } |
7677 |
++ |
7678 |
++#ifdef CONFIG_SMP |
7679 |
++ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask))) |
7680 |
++#else |
7681 |
++ if (likely(address > get_limit(regs->xcs))) |
7682 |
++#endif |
7683 |
++ { |
7684 |
++ set_pte(pte, pte_mkread(*pte)); |
7685 |
++ __flush_tlb_one(address); |
7686 |
++ pte_unmap_unlock(pte, ptl); |
7687 |
++ up_read(&mm->mmap_sem); |
7688 |
++ return; |
7689 |
++ } |
7690 |
++ |
7691 |
++ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1)); |
7692 |
++ |
7693 |
++ /* |
7694 |
++ * PaX: fill DTLB with user rights and retry |
7695 |
++ */ |
7696 |
++ __asm__ __volatile__ ( |
7697 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
7698 |
++ "movw %w4,%%es\n" |
7699 |
++#endif |
7700 |
++ "orb %2,(%1)\n" |
7701 |
++#if defined(CONFIG_M586) || defined(CONFIG_M586TSC) |
7702 |
++/* |
7703 |
++ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's |
7704 |
++ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any* |
7705 |
++ * page fault when examined during a TLB load attempt. this is true not only |
7706 |
++ * for PTEs holding a non-present entry but also present entries that will |
7707 |
++ * raise a page fault (such as those set up by PaX, or the copy-on-write |
7708 |
++ * mechanism). in effect it means that we do *not* need to flush the TLBs |
7709 |
++ * for our target pages since their PTEs are simply not in the TLBs at all. |
7710 |
++ |
7711 |
++ * the best thing in omitting it is that we gain around 15-20% speed in the |
7712 |
++ * fast path of the page fault handler and can get rid of tracing since we |
7713 |
++ * can no longer flush unintended entries. |
7714 |
++ */ |
7715 |
++ "invlpg (%0)\n" |
7716 |
++#endif |
7717 |
++ "testb $0,%%es:(%0)\n" |
7718 |
++ "xorb %3,(%1)\n" |
7719 |
++#ifdef CONFIG_PAX_MEMORY_UDEREF |
7720 |
++ "pushl %%ss\n" |
7721 |
++ "popl %%es\n" |
7722 |
++#endif |
7723 |
++ : |
7724 |
++ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS) |
7725 |
++ : "memory", "cc"); |
7726 |
++ pte_unmap_unlock(pte, ptl); |
7727 |
++ up_read(&mm->mmap_sem); |
7728 |
++ return; |
7729 |
++ |
7730 |
++not_pax_fault: |
7731 |
++#endif |
7732 |
++ |
7733 |
+ vma = find_vma(mm, address); |
7734 |
+ if (!vma) |
7735 |
+ goto bad_area; |
7736 |
+@@ -396,6 +527,12 @@ fastcall void __kprobes do_page_fault(st |
7737 |
+ if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp) |
7738 |
+ goto bad_area; |
7739 |
+ } |
7740 |
++ |
7741 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7742 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1) |
7743 |
++ goto bad_area; |
7744 |
++#endif |
7745 |
++ |
7746 |
+ if (expand_stack(vma, address)) |
7747 |
+ goto bad_area; |
7748 |
+ /* |
7749 |
+@@ -405,6 +542,8 @@ fastcall void __kprobes do_page_fault(st |
7750 |
+ good_area: |
7751 |
+ si_code = SEGV_ACCERR; |
7752 |
+ write = 0; |
7753 |
++ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) |
7754 |
++ goto bad_area; |
7755 |
+ switch (error_code & 3) { |
7756 |
+ default: /* 3: write, present */ |
7757 |
+ /* fall through */ |
7758 |
+@@ -458,6 +597,41 @@ bad_area: |
7759 |
+ up_read(&mm->mmap_sem); |
7760 |
+ |
7761 |
+ bad_area_nosemaphore: |
7762 |
++ |
7763 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
7764 |
++ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) { |
7765 |
++ /* |
7766 |
++ * It's possible to have interrupts off here. |
7767 |
++ */ |
7768 |
++ local_irq_enable(); |
7769 |
++ |
7770 |
++#ifdef CONFIG_PAX_PAGEEXEC |
7771 |
++ if ((nx_enabled && (error_code & 16)) || |
7772 |
++ ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address))) { |
7773 |
++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp); |
7774 |
++ do_exit(SIGKILL); |
7775 |
++ } |
7776 |
++#endif |
7777 |
++ |
7778 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7779 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) { |
7780 |
++ |
7781 |
++#ifdef CONFIG_PAX_EMUTRAMP |
7782 |
++ switch (pax_handle_fetch_fault(regs)) { |
7783 |
++ case 2: |
7784 |
++ return; |
7785 |
++ } |
7786 |
++#endif |
7787 |
++ |
7788 |
++ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp); |
7789 |
++ do_exit(SIGKILL); |
7790 |
++ } |
7791 |
++#endif |
7792 |
++ |
7793 |
++ } |
7794 |
++#endif |
7795 |
++ |
7796 |
++bad_area_nopax: |
7797 |
+ /* User mode accesses just cause a SIGSEGV */ |
7798 |
+ if (error_code & 4) { |
7799 |
+ /* |
7800 |
+@@ -495,7 +669,7 @@ bad_area_nosemaphore: |
7801 |
+ if (boot_cpu_data.f00f_bug) { |
7802 |
+ unsigned long nr; |
7803 |
+ |
7804 |
+- nr = (address - idt_descr.address) >> 3; |
7805 |
++ nr = (address - (unsigned long)idt_descr.address) >> 3; |
7806 |
+ |
7807 |
+ if (nr == 6) { |
7808 |
+ do_invalid_op(regs, 0); |
7809 |
+@@ -528,18 +702,34 @@ no_context: |
7810 |
+ __typeof__(pte_val(__pte(0))) page; |
7811 |
+ |
7812 |
+ #ifdef CONFIG_X86_PAE |
7813 |
+- if (error_code & 16) { |
7814 |
+- pte_t *pte = lookup_address(address); |
7815 |
++ if (nx_enabled && (error_code & 16)) { |
7816 |
++ pte = lookup_address(address); |
7817 |
+ |
7818 |
+ if (pte && pte_present(*pte) && !pte_exec_kernel(*pte)) |
7819 |
+ printk(KERN_CRIT "kernel tried to execute " |
7820 |
+ "NX-protected page - exploit attempt? " |
7821 |
+- "(uid: %d)\n", current->uid); |
7822 |
++ "(uid: %d, task: %s, pid: %d)\n", |
7823 |
++ current->uid, current->comm, current->pid); |
7824 |
+ } |
7825 |
+ #endif |
7826 |
+ if (address < PAGE_SIZE) |
7827 |
+ printk(KERN_ALERT "BUG: unable to handle kernel NULL " |
7828 |
+ "pointer dereference"); |
7829 |
++ |
7830 |
++#ifdef CONFIG_PAX_KERNEXEC |
7831 |
++#ifdef CONFIG_MODULES |
7832 |
++ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END) |
7833 |
++#else |
7834 |
++ else if (init_mm.start_code <= address && address < init_mm.end_code) |
7835 |
++#endif |
7836 |
++ if (tsk->signal->curr_ip) |
7837 |
++ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
7838 |
++ NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid); |
7839 |
++ else |
7840 |
++ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
7841 |
++ tsk->comm, tsk->pid, tsk->uid, tsk->euid); |
7842 |
++#endif |
7843 |
++ |
7844 |
+ else |
7845 |
+ printk(KERN_ALERT "BUG: unable to handle kernel paging" |
7846 |
+ " request"); |
7847 |
+@@ -570,7 +760,7 @@ no_context: |
7848 |
+ * it's allocated already. |
7849 |
+ */ |
7850 |
+ if ((page >> PAGE_SHIFT) < max_low_pfn |
7851 |
+- && (page & _PAGE_PRESENT)) { |
7852 |
++ && (page & (_PAGE_PRESENT | _PAGE_PSE)) == _PAGE_PRESENT) { |
7853 |
+ page &= PAGE_MASK; |
7854 |
+ page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT) |
7855 |
+ & (PTRS_PER_PTE - 1)]; |
7856 |
+@@ -655,3 +845,92 @@ void vmalloc_sync_all(void) |
7857 |
+ start = address + PGDIR_SIZE; |
7858 |
+ } |
7859 |
+ } |
7860 |
++ |
7861 |
++#ifdef CONFIG_PAX_EMUTRAMP |
7862 |
++/* |
7863 |
++ * PaX: decide what to do with offenders (regs->eip = fault address) |
7864 |
++ * |
7865 |
++ * returns 1 when task should be killed |
7866 |
++ * 2 when gcc trampoline was detected |
7867 |
++ */ |
7868 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
7869 |
++{ |
7870 |
++ int err; |
7871 |
++ |
7872 |
++ if (regs->eflags & X86_EFLAGS_VM) |
7873 |
++ return 1; |
7874 |
++ |
7875 |
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) |
7876 |
++ return 1; |
7877 |
++ |
7878 |
++ do { /* PaX: gcc trampoline emulation #1 */ |
7879 |
++ unsigned char mov1, mov2; |
7880 |
++ unsigned short jmp; |
7881 |
++ unsigned long addr1, addr2; |
7882 |
++ |
7883 |
++ err = get_user(mov1, (unsigned char __user *)regs->eip); |
7884 |
++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1)); |
7885 |
++ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5)); |
7886 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6)); |
7887 |
++ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10)); |
7888 |
++ |
7889 |
++ if (err) |
7890 |
++ break; |
7891 |
++ |
7892 |
++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) { |
7893 |
++ regs->ecx = addr1; |
7894 |
++ regs->eax = addr2; |
7895 |
++ regs->eip = addr2; |
7896 |
++ return 2; |
7897 |
++ } |
7898 |
++ } while (0); |
7899 |
++ |
7900 |
++ do { /* PaX: gcc trampoline emulation #2 */ |
7901 |
++ unsigned char mov, jmp; |
7902 |
++ unsigned long addr1, addr2; |
7903 |
++ |
7904 |
++ err = get_user(mov, (unsigned char __user *)regs->eip); |
7905 |
++ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1)); |
7906 |
++ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5)); |
7907 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6)); |
7908 |
++ |
7909 |
++ if (err) |
7910 |
++ break; |
7911 |
++ |
7912 |
++ if (mov == 0xB9 && jmp == 0xE9) { |
7913 |
++ regs->ecx = addr1; |
7914 |
++ regs->eip += addr2 + 10; |
7915 |
++ return 2; |
7916 |
++ } |
7917 |
++ } while (0); |
7918 |
++ |
7919 |
++ return 1; /* PaX in action */ |
7920 |
++} |
7921 |
++#endif |
7922 |
++ |
7923 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
7924 |
++void pax_report_insns(void *pc, void *sp) |
7925 |
++{ |
7926 |
++ long i; |
7927 |
++ |
7928 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
7929 |
++ for (i = 0; i < 20; i++) { |
7930 |
++ unsigned char c; |
7931 |
++ if (get_user(c, (unsigned char __user *)pc+i)) |
7932 |
++ printk("?? "); |
7933 |
++ else |
7934 |
++ printk("%02x ", c); |
7935 |
++ } |
7936 |
++ printk("\n"); |
7937 |
++ |
7938 |
++ printk(KERN_ERR "PAX: bytes at SP-4: "); |
7939 |
++ for (i = -1; i < 20; i++) { |
7940 |
++ unsigned long c; |
7941 |
++ if (get_user(c, (unsigned long __user *)sp+i)) |
7942 |
++ printk("???????? "); |
7943 |
++ else |
7944 |
++ printk("%08lx ", c); |
7945 |
++ } |
7946 |
++ printk("\n"); |
7947 |
++} |
7948 |
++#endif |
7949 |
+diff -Nurp linux-2.6.23.15/arch/i386/mm/hugetlbpage.c linux-2.6.23.15-grsec/arch/i386/mm/hugetlbpage.c |
7950 |
+--- linux-2.6.23.15/arch/i386/mm/hugetlbpage.c 2007-10-09 21:31:38.000000000 +0100 |
7951 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/hugetlbpage.c 2008-02-11 10:37:44.000000000 +0000 |
7952 |
+@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe |
7953 |
+ { |
7954 |
+ struct mm_struct *mm = current->mm; |
7955 |
+ struct vm_area_struct *vma; |
7956 |
+- unsigned long start_addr; |
7957 |
++ unsigned long start_addr, task_size = TASK_SIZE; |
7958 |
++ |
7959 |
++#ifdef CONFIG_PAX_SEGMEXEC |
7960 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
7961 |
++ task_size = SEGMEXEC_TASK_SIZE; |
7962 |
++#endif |
7963 |
+ |
7964 |
+ if (len > mm->cached_hole_size) { |
7965 |
+- start_addr = mm->free_area_cache; |
7966 |
++ start_addr = mm->free_area_cache; |
7967 |
+ } else { |
7968 |
+- start_addr = TASK_UNMAPPED_BASE; |
7969 |
+- mm->cached_hole_size = 0; |
7970 |
++ start_addr = mm->mmap_base; |
7971 |
++ mm->cached_hole_size = 0; |
7972 |
+ } |
7973 |
+ |
7974 |
+ full_search: |
7975 |
+@@ -243,13 +248,13 @@ full_search: |
7976 |
+ |
7977 |
+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { |
7978 |
+ /* At this point: (!vma || addr < vma->vm_end). */ |
7979 |
+- if (TASK_SIZE - len < addr) { |
7980 |
++ if (task_size - len < addr) { |
7981 |
+ /* |
7982 |
+ * Start a new search - just in case we missed |
7983 |
+ * some holes. |
7984 |
+ */ |
7985 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
7986 |
+- start_addr = TASK_UNMAPPED_BASE; |
7987 |
++ if (start_addr != mm->mmap_base) { |
7988 |
++ start_addr = mm->mmap_base; |
7989 |
+ mm->cached_hole_size = 0; |
7990 |
+ goto full_search; |
7991 |
+ } |
7992 |
+@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe |
7993 |
+ { |
7994 |
+ struct mm_struct *mm = current->mm; |
7995 |
+ struct vm_area_struct *vma, *prev_vma; |
7996 |
+- unsigned long base = mm->mmap_base, addr = addr0; |
7997 |
++ unsigned long base = mm->mmap_base, addr; |
7998 |
+ unsigned long largest_hole = mm->cached_hole_size; |
7999 |
+- int first_time = 1; |
8000 |
+ |
8001 |
+ /* don't allow allocations above current base */ |
8002 |
+ if (mm->free_area_cache > base) |
8003 |
+@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe |
8004 |
+ largest_hole = 0; |
8005 |
+ mm->free_area_cache = base; |
8006 |
+ } |
8007 |
+-try_again: |
8008 |
++ |
8009 |
+ /* make sure it can fit in the remaining address space */ |
8010 |
+ if (mm->free_area_cache < len) |
8011 |
+ goto fail; |
8012 |
+@@ -325,22 +329,26 @@ try_again: |
8013 |
+ |
8014 |
+ fail: |
8015 |
+ /* |
8016 |
+- * if hint left us with no space for the requested |
8017 |
+- * mapping then try again: |
8018 |
+- */ |
8019 |
+- if (first_time) { |
8020 |
+- mm->free_area_cache = base; |
8021 |
+- largest_hole = 0; |
8022 |
+- first_time = 0; |
8023 |
+- goto try_again; |
8024 |
+- } |
8025 |
+- /* |
8026 |
+ * A failed mmap() very likely causes application failure, |
8027 |
+ * so fall back to the bottom-up function here. This scenario |
8028 |
+ * can happen with large stack limits and large mmap() |
8029 |
+ * allocations. |
8030 |
+ */ |
8031 |
+- mm->free_area_cache = TASK_UNMAPPED_BASE; |
8032 |
++ |
8033 |
++#ifdef CONFIG_PAX_SEGMEXEC |
8034 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
8035 |
++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; |
8036 |
++ else |
8037 |
++#endif |
8038 |
++ |
8039 |
++ mm->mmap_base = TASK_UNMAPPED_BASE; |
8040 |
++ |
8041 |
++#ifdef CONFIG_PAX_RANDMMAP |
8042 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
8043 |
++ mm->mmap_base += mm->delta_mmap; |
8044 |
++#endif |
8045 |
++ |
8046 |
++ mm->free_area_cache = mm->mmap_base; |
8047 |
+ mm->cached_hole_size = ~0UL; |
8048 |
+ addr = hugetlb_get_unmapped_area_bottomup(file, addr0, |
8049 |
+ len, pgoff, flags); |
8050 |
+@@ -348,6 +356,7 @@ fail: |
8051 |
+ /* |
8052 |
+ * Restore the topdown base: |
8053 |
+ */ |
8054 |
++ mm->mmap_base = base; |
8055 |
+ mm->free_area_cache = base; |
8056 |
+ mm->cached_hole_size = ~0UL; |
8057 |
+ |
8058 |
+@@ -360,10 +369,17 @@ hugetlb_get_unmapped_area(struct file *f |
8059 |
+ { |
8060 |
+ struct mm_struct *mm = current->mm; |
8061 |
+ struct vm_area_struct *vma; |
8062 |
++ unsigned long task_size = TASK_SIZE; |
8063 |
+ |
8064 |
+ if (len & ~HPAGE_MASK) |
8065 |
+ return -EINVAL; |
8066 |
+- if (len > TASK_SIZE) |
8067 |
++ |
8068 |
++#ifdef CONFIG_PAX_SEGMEXEC |
8069 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
8070 |
++ task_size = SEGMEXEC_TASK_SIZE; |
8071 |
++#endif |
8072 |
++ |
8073 |
++ if (len > task_size) |
8074 |
+ return -ENOMEM; |
8075 |
+ |
8076 |
+ if (flags & MAP_FIXED) { |
8077 |
+@@ -375,7 +391,7 @@ hugetlb_get_unmapped_area(struct file *f |
8078 |
+ if (addr) { |
8079 |
+ addr = ALIGN(addr, HPAGE_SIZE); |
8080 |
+ vma = find_vma(mm, addr); |
8081 |
+- if (TASK_SIZE - len >= addr && |
8082 |
++ if (task_size - len >= addr && |
8083 |
+ (!vma || addr + len <= vma->vm_start)) |
8084 |
+ return addr; |
8085 |
+ } |
8086 |
+diff -Nurp linux-2.6.23.15/arch/i386/mm/init.c linux-2.6.23.15-grsec/arch/i386/mm/init.c |
8087 |
+--- linux-2.6.23.15/arch/i386/mm/init.c 2007-10-09 21:31:38.000000000 +0100 |
8088 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/init.c 2008-02-11 10:37:44.000000000 +0000 |
8089 |
+@@ -44,6 +44,7 @@ |
8090 |
+ #include <asm/tlbflush.h> |
8091 |
+ #include <asm/sections.h> |
8092 |
+ #include <asm/paravirt.h> |
8093 |
++#include <asm/desc.h> |
8094 |
+ |
8095 |
+ unsigned int __VMALLOC_RESERVE = 128 << 20; |
8096 |
+ |
8097 |
+@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn |
8098 |
+ static int noinline do_test_wp_bit(void); |
8099 |
+ |
8100 |
+ /* |
8101 |
+- * Creates a middle page table and puts a pointer to it in the |
8102 |
+- * given global directory entry. This only returns the gd entry |
8103 |
+- * in non-PAE compilation mode, since the middle layer is folded. |
8104 |
+- */ |
8105 |
+-static pmd_t * __init one_md_table_init(pgd_t *pgd) |
8106 |
+-{ |
8107 |
+- pud_t *pud; |
8108 |
+- pmd_t *pmd_table; |
8109 |
+- |
8110 |
+-#ifdef CONFIG_X86_PAE |
8111 |
+- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) { |
8112 |
+- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); |
8113 |
+- |
8114 |
+- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT); |
8115 |
+- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); |
8116 |
+- pud = pud_offset(pgd, 0); |
8117 |
+- if (pmd_table != pmd_offset(pud, 0)) |
8118 |
+- BUG(); |
8119 |
+- } |
8120 |
+-#endif |
8121 |
+- pud = pud_offset(pgd, 0); |
8122 |
+- pmd_table = pmd_offset(pud, 0); |
8123 |
+- return pmd_table; |
8124 |
+-} |
8125 |
+- |
8126 |
+-/* |
8127 |
+ * Create a page table and place a pointer to it in a middle page |
8128 |
+ * directory entry. |
8129 |
+ */ |
8130 |
+@@ -88,7 +63,11 @@ static pte_t * __init one_page_table_ini |
8131 |
+ pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); |
8132 |
+ |
8133 |
+ paravirt_alloc_pt(&init_mm, __pa(page_table) >> PAGE_SHIFT); |
8134 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
8135 |
++ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE)); |
8136 |
++#else |
8137 |
+ set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); |
8138 |
++#endif |
8139 |
+ BUG_ON(page_table != pte_offset_kernel(pmd, 0)); |
8140 |
+ } |
8141 |
+ |
8142 |
+@@ -109,6 +88,7 @@ static pte_t * __init one_page_table_ini |
8143 |
+ static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base) |
8144 |
+ { |
8145 |
+ pgd_t *pgd; |
8146 |
++ pud_t *pud; |
8147 |
+ pmd_t *pmd; |
8148 |
+ int pgd_idx, pmd_idx; |
8149 |
+ unsigned long vaddr; |
8150 |
+@@ -119,8 +99,13 @@ static void __init page_table_range_init |
8151 |
+ pgd = pgd_base + pgd_idx; |
8152 |
+ |
8153 |
+ for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) { |
8154 |
+- pmd = one_md_table_init(pgd); |
8155 |
+- pmd = pmd + pmd_index(vaddr); |
8156 |
++ pud = pud_offset(pgd, vaddr); |
8157 |
++ pmd = pmd_offset(pud, vaddr); |
8158 |
++ |
8159 |
++#ifdef CONFIG_X86_PAE |
8160 |
++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); |
8161 |
++#endif |
8162 |
++ |
8163 |
+ for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) { |
8164 |
+ one_page_table_init(pmd); |
8165 |
+ |
8166 |
+@@ -130,11 +115,23 @@ static void __init page_table_range_init |
8167 |
+ } |
8168 |
+ } |
8169 |
+ |
8170 |
+-static inline int is_kernel_text(unsigned long addr) |
8171 |
++static inline int is_kernel_text(unsigned long start, unsigned long end) |
8172 |
+ { |
8173 |
+- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end) |
8174 |
+- return 1; |
8175 |
+- return 0; |
8176 |
++ unsigned long etext; |
8177 |
++ |
8178 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
8179 |
++ etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET; |
8180 |
++#else |
8181 |
++ etext = (unsigned long)&_etext; |
8182 |
++#endif |
8183 |
++ |
8184 |
++ if ((start > etext + __KERNEL_TEXT_OFFSET || |
8185 |
++ end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) && |
8186 |
++ (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET || |
8187 |
++ end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET) && |
8188 |
++ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000))) |
8189 |
++ return 0; |
8190 |
++ return 1; |
8191 |
+ } |
8192 |
+ |
8193 |
+ /* |
8194 |
+@@ -146,25 +143,29 @@ static void __init kernel_physical_mappi |
8195 |
+ { |
8196 |
+ unsigned long pfn; |
8197 |
+ pgd_t *pgd; |
8198 |
++ pud_t *pud; |
8199 |
+ pmd_t *pmd; |
8200 |
+ pte_t *pte; |
8201 |
+- int pgd_idx, pmd_idx, pte_ofs; |
8202 |
++ unsigned int pgd_idx, pmd_idx, pte_ofs; |
8203 |
+ |
8204 |
+ pgd_idx = pgd_index(PAGE_OFFSET); |
8205 |
+ pgd = pgd_base + pgd_idx; |
8206 |
+ pfn = 0; |
8207 |
+ |
8208 |
+- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) { |
8209 |
+- pmd = one_md_table_init(pgd); |
8210 |
+- if (pfn >= max_low_pfn) |
8211 |
+- continue; |
8212 |
++ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) { |
8213 |
++ pud = pud_offset(pgd, 0); |
8214 |
++ pmd = pmd_offset(pud, 0); |
8215 |
++ |
8216 |
++#ifdef CONFIG_X86_PAE |
8217 |
++ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT); |
8218 |
++#endif |
8219 |
++ |
8220 |
+ for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) { |
8221 |
+- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET; |
8222 |
++ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET; |
8223 |
+ |
8224 |
+ /* Map with big pages if possible, otherwise create normal page tables. */ |
8225 |
+- if (cpu_has_pse) { |
8226 |
+- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1; |
8227 |
+- if (is_kernel_text(address) || is_kernel_text(address2)) |
8228 |
++ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) { |
8229 |
++ if (is_kernel_text(address, address + PMD_SIZE)) |
8230 |
+ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); |
8231 |
+ else |
8232 |
+ set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE)); |
8233 |
+@@ -176,7 +177,7 @@ static void __init kernel_physical_mappi |
8234 |
+ for (pte_ofs = 0; |
8235 |
+ pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; |
8236 |
+ pte++, pfn++, pte_ofs++, address += PAGE_SIZE) { |
8237 |
+- if (is_kernel_text(address)) |
8238 |
++ if (is_kernel_text(address, address + PAGE_SIZE)) |
8239 |
+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); |
8240 |
+ else |
8241 |
+ set_pte(pte, pfn_pte(pfn, PAGE_KERNEL)); |
8242 |
+@@ -326,9 +327,9 @@ static void __init set_highmem_pages_ini |
8243 |
+ #define set_highmem_pages_init(bad_ppro) do { } while (0) |
8244 |
+ #endif /* CONFIG_HIGHMEM */ |
8245 |
+ |
8246 |
+-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; |
8247 |
++unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL; |
8248 |
+ EXPORT_SYMBOL(__PAGE_KERNEL); |
8249 |
+-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; |
8250 |
++unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC; |
8251 |
+ |
8252 |
+ #ifdef CONFIG_NUMA |
8253 |
+ extern void __init remap_numa_kva(void); |
8254 |
+@@ -339,26 +340,10 @@ extern void __init remap_numa_kva(void); |
8255 |
+ void __init native_pagetable_setup_start(pgd_t *base) |
8256 |
+ { |
8257 |
+ #ifdef CONFIG_X86_PAE |
8258 |
+- int i; |
8259 |
++ unsigned int i; |
8260 |
+ |
8261 |
+- /* |
8262 |
+- * Init entries of the first-level page table to the |
8263 |
+- * zero page, if they haven't already been set up. |
8264 |
+- * |
8265 |
+- * In a normal native boot, we'll be running on a |
8266 |
+- * pagetable rooted in swapper_pg_dir, but not in PAE |
8267 |
+- * mode, so this will end up clobbering the mappings |
8268 |
+- * for the lower 24Mbytes of the address space, |
8269 |
+- * without affecting the kernel address space. |
8270 |
+- */ |
8271 |
+- for (i = 0; i < USER_PTRS_PER_PGD; i++) |
8272 |
+- set_pgd(&base[i], |
8273 |
+- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); |
8274 |
+- |
8275 |
+- /* Make sure kernel address space is empty so that a pagetable |
8276 |
+- will be allocated for it. */ |
8277 |
+- memset(&base[USER_PTRS_PER_PGD], 0, |
8278 |
+- KERNEL_PGD_PTRS * sizeof(pgd_t)); |
8279 |
++ for (i = 0; i < PTRS_PER_PGD; i++) |
8280 |
++ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT); |
8281 |
+ #else |
8282 |
+ paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT); |
8283 |
+ #endif |
8284 |
+@@ -366,16 +351,6 @@ void __init native_pagetable_setup_start |
8285 |
+ |
8286 |
+ void __init native_pagetable_setup_done(pgd_t *base) |
8287 |
+ { |
8288 |
+-#ifdef CONFIG_X86_PAE |
8289 |
+- /* |
8290 |
+- * Add low memory identity-mappings - SMP needs it when |
8291 |
+- * starting up on an AP from real-mode. In the non-PAE |
8292 |
+- * case we already have these mappings through head.S. |
8293 |
+- * All user-space mappings are explicitly cleared after |
8294 |
+- * SMP startup. |
8295 |
+- */ |
8296 |
+- set_pgd(&base[0], base[USER_PTRS_PER_PGD]); |
8297 |
+-#endif |
8298 |
+ } |
8299 |
+ |
8300 |
+ /* |
8301 |
+@@ -437,12 +412,12 @@ static void __init pagetable_init (void) |
8302 |
+ * Swap suspend & friends need this for resume because things like the intel-agp |
8303 |
+ * driver might have split up a kernel 4MB mapping. |
8304 |
+ */ |
8305 |
+-char __nosavedata swsusp_pg_dir[PAGE_SIZE] |
8306 |
++pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD] |
8307 |
+ __attribute__ ((aligned (PAGE_SIZE))); |
8308 |
+ |
8309 |
+ static inline void save_pg_dir(void) |
8310 |
+ { |
8311 |
+- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE); |
8312 |
++ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD); |
8313 |
+ } |
8314 |
+ #else |
8315 |
+ static inline void save_pg_dir(void) |
8316 |
+@@ -471,12 +446,11 @@ void zap_low_mappings (void) |
8317 |
+ flush_tlb_all(); |
8318 |
+ } |
8319 |
+ |
8320 |
+-int nx_enabled = 0; |
8321 |
++int nx_enabled; |
8322 |
+ |
8323 |
+ #ifdef CONFIG_X86_PAE |
8324 |
+ |
8325 |
+-static int disable_nx __initdata = 0; |
8326 |
+-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; |
8327 |
++u64 __supported_pte_mask __read_only = ~_PAGE_NX; |
8328 |
+ EXPORT_SYMBOL_GPL(__supported_pte_mask); |
8329 |
+ |
8330 |
+ /* |
8331 |
+@@ -487,36 +461,31 @@ EXPORT_SYMBOL_GPL(__supported_pte_mask); |
8332 |
+ * on Enable |
8333 |
+ * off Disable |
8334 |
+ */ |
8335 |
++#if !defined(CONFIG_PAX_PAGEEXEC) |
8336 |
+ static int __init noexec_setup(char *str) |
8337 |
+ { |
8338 |
+ if (!str || !strcmp(str, "on")) { |
8339 |
+- if (cpu_has_nx) { |
8340 |
+- __supported_pte_mask |= _PAGE_NX; |
8341 |
+- disable_nx = 0; |
8342 |
+- } |
8343 |
++ if (cpu_has_nx) |
8344 |
++ nx_enabled = 1; |
8345 |
+ } else if (!strcmp(str,"off")) { |
8346 |
+- disable_nx = 1; |
8347 |
+- __supported_pte_mask &= ~_PAGE_NX; |
8348 |
++ nx_enabled = 0; |
8349 |
+ } else |
8350 |
+ return -EINVAL; |
8351 |
+ |
8352 |
+ return 0; |
8353 |
+ } |
8354 |
+ early_param("noexec", noexec_setup); |
8355 |
++#endif |
8356 |
+ |
8357 |
+ static void __init set_nx(void) |
8358 |
+ { |
8359 |
+- unsigned int v[4], l, h; |
8360 |
++ if (!nx_enabled && cpu_has_nx) { |
8361 |
++ unsigned l, h; |
8362 |
+ |
8363 |
+- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) { |
8364 |
+- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]); |
8365 |
+- if ((v[3] & (1 << 20)) && !disable_nx) { |
8366 |
+- rdmsr(MSR_EFER, l, h); |
8367 |
+- l |= EFER_NX; |
8368 |
+- wrmsr(MSR_EFER, l, h); |
8369 |
+- nx_enabled = 1; |
8370 |
+- __supported_pte_mask |= _PAGE_NX; |
8371 |
+- } |
8372 |
++ __supported_pte_mask &= ~_PAGE_NX; |
8373 |
++ rdmsr(MSR_EFER, l, h); |
8374 |
++ l &= ~EFER_NX; |
8375 |
++ wrmsr(MSR_EFER, l, h); |
8376 |
+ } |
8377 |
+ } |
8378 |
+ |
8379 |
+@@ -569,14 +538,6 @@ void __init paging_init(void) |
8380 |
+ |
8381 |
+ load_cr3(swapper_pg_dir); |
8382 |
+ |
8383 |
+-#ifdef CONFIG_X86_PAE |
8384 |
+- /* |
8385 |
+- * We will bail out later - printk doesn't work right now so |
8386 |
+- * the user would just see a hanging kernel. |
8387 |
+- */ |
8388 |
+- if (cpu_has_pae) |
8389 |
+- set_in_cr4(X86_CR4_PAE); |
8390 |
+-#endif |
8391 |
+ __flush_tlb_all(); |
8392 |
+ |
8393 |
+ kmap_init(); |
8394 |
+@@ -647,7 +608,7 @@ void __init mem_init(void) |
8395 |
+ set_highmem_pages_init(bad_ppro); |
8396 |
+ |
8397 |
+ codesize = (unsigned long) &_etext - (unsigned long) &_text; |
8398 |
+- datasize = (unsigned long) &_edata - (unsigned long) &_etext; |
8399 |
++ datasize = (unsigned long) &_edata - (unsigned long) &_data; |
8400 |
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; |
8401 |
+ |
8402 |
+ kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); |
8403 |
+@@ -692,10 +653,10 @@ void __init mem_init(void) |
8404 |
+ (unsigned long)&__init_begin, (unsigned long)&__init_end, |
8405 |
+ ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10, |
8406 |
+ |
8407 |
+- (unsigned long)&_etext, (unsigned long)&_edata, |
8408 |
+- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, |
8409 |
++ (unsigned long)&_data, (unsigned long)&_edata, |
8410 |
++ ((unsigned long)&_edata - (unsigned long)&_data) >> 10, |
8411 |
+ |
8412 |
+- (unsigned long)&_text, (unsigned long)&_etext, |
8413 |
++ (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET, |
8414 |
+ ((unsigned long)&_etext - (unsigned long)&_text) >> 10); |
8415 |
+ |
8416 |
+ #ifdef CONFIG_HIGHMEM |
8417 |
+@@ -706,10 +667,6 @@ void __init mem_init(void) |
8418 |
+ BUG_ON((unsigned long)high_memory > VMALLOC_START); |
8419 |
+ #endif /* double-sanity-check paranoia */ |
8420 |
+ |
8421 |
+-#ifdef CONFIG_X86_PAE |
8422 |
+- if (!cpu_has_pae) |
8423 |
+- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); |
8424 |
+-#endif |
8425 |
+ if (boot_cpu_data.wp_works_ok < 0) |
8426 |
+ test_wp_bit(); |
8427 |
+ |
8428 |
+@@ -844,6 +801,38 @@ void free_init_pages(char *what, unsigne |
8429 |
+ |
8430 |
+ void free_initmem(void) |
8431 |
+ { |
8432 |
++ |
8433 |
++#ifdef CONFIG_PAX_KERNEXEC |
8434 |
++ /* PaX: limit KERNEL_CS to actual size */ |
8435 |
++ unsigned long addr, limit; |
8436 |
++ __u32 a, b; |
8437 |
++ int cpu; |
8438 |
++ pgd_t *pgd; |
8439 |
++ pud_t *pud; |
8440 |
++ pmd_t *pmd; |
8441 |
++ |
8442 |
++#ifdef CONFIG_MODULES |
8443 |
++ limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET; |
8444 |
++#else |
8445 |
++ limit = (unsigned long)&_etext; |
8446 |
++#endif |
8447 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
8448 |
++ |
8449 |
++ for (cpu = 0; cpu < NR_CPUS; cpu++) { |
8450 |
++ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC); |
8451 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b); |
8452 |
++ } |
8453 |
++ |
8454 |
++ /* PaX: make KERNEL_CS read-only */ |
8455 |
++ for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) { |
8456 |
++ pgd = pgd_offset_k(addr); |
8457 |
++ pud = pud_offset(pgd, addr); |
8458 |
++ pmd = pmd_offset(pud, addr); |
8459 |
++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); |
8460 |
++ } |
8461 |
++ flush_tlb_all(); |
8462 |
++#endif |
8463 |
++ |
8464 |
+ free_init_pages("unused kernel memory", |
8465 |
+ (unsigned long)(&__init_begin), |
8466 |
+ (unsigned long)(&__init_end)); |
8467 |
+diff -Nurp linux-2.6.23.15/arch/i386/mm/mmap.c linux-2.6.23.15-grsec/arch/i386/mm/mmap.c |
8468 |
+--- linux-2.6.23.15/arch/i386/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100 |
8469 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000 |
8470 |
+@@ -35,12 +35,18 @@ |
8471 |
+ * Leave an at least ~128 MB hole. |
8472 |
+ */ |
8473 |
+ #define MIN_GAP (128*1024*1024) |
8474 |
+-#define MAX_GAP (TASK_SIZE/6*5) |
8475 |
++#define MAX_GAP (task_size/6*5) |
8476 |
+ |
8477 |
+ static inline unsigned long mmap_base(struct mm_struct *mm) |
8478 |
+ { |
8479 |
+ unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; |
8480 |
+ unsigned long random_factor = 0; |
8481 |
++ unsigned long task_size = TASK_SIZE; |
8482 |
++ |
8483 |
++#ifdef CONFIG_PAX_SEGMEXEC |
8484 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
8485 |
++ task_size = SEGMEXEC_TASK_SIZE; |
8486 |
++#endif |
8487 |
+ |
8488 |
+ if (current->flags & PF_RANDOMIZE) |
8489 |
+ random_factor = get_random_int() % (1024*1024); |
8490 |
+@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st |
8491 |
+ else if (gap > MAX_GAP) |
8492 |
+ gap = MAX_GAP; |
8493 |
+ |
8494 |
+- return PAGE_ALIGN(TASK_SIZE - gap - random_factor); |
8495 |
++ return PAGE_ALIGN(task_size - gap - random_factor); |
8496 |
+ } |
8497 |
+ |
8498 |
+ /* |
8499 |
+@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str |
8500 |
+ if (sysctl_legacy_va_layout || |
8501 |
+ (current->personality & ADDR_COMPAT_LAYOUT) || |
8502 |
+ current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) { |
8503 |
++ |
8504 |
++#ifdef CONFIG_PAX_SEGMEXEC |
8505 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) |
8506 |
++ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE; |
8507 |
++ else |
8508 |
++#endif |
8509 |
++ |
8510 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
8511 |
++ |
8512 |
++#ifdef CONFIG_PAX_RANDMMAP |
8513 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
8514 |
++ mm->mmap_base += mm->delta_mmap; |
8515 |
++#endif |
8516 |
++ |
8517 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
8518 |
+ mm->unmap_area = arch_unmap_area; |
8519 |
+ } else { |
8520 |
+ mm->mmap_base = mmap_base(mm); |
8521 |
++ |
8522 |
++#ifdef CONFIG_PAX_RANDMMAP |
8523 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
8524 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
8525 |
++#endif |
8526 |
++ |
8527 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
8528 |
+ mm->unmap_area = arch_unmap_area_topdown; |
8529 |
+ } |
8530 |
+diff -Nurp linux-2.6.23.15/arch/i386/mm/pageattr.c linux-2.6.23.15-grsec/arch/i386/mm/pageattr.c |
8531 |
+--- linux-2.6.23.15/arch/i386/mm/pageattr.c 2007-10-09 21:31:38.000000000 +0100 |
8532 |
++++ linux-2.6.23.15-grsec/arch/i386/mm/pageattr.c 2008-02-11 10:37:44.000000000 +0000 |
8533 |
+@@ -13,6 +13,7 @@ |
8534 |
+ #include <asm/tlbflush.h> |
8535 |
+ #include <asm/pgalloc.h> |
8536 |
+ #include <asm/sections.h> |
8537 |
++#include <asm/desc.h> |
8538 |
+ |
8539 |
+ static DEFINE_SPINLOCK(cpa_lock); |
8540 |
+ static struct list_head df_list = LIST_HEAD_INIT(df_list); |
8541 |
+@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr |
8542 |
+ } |
8543 |
+ |
8544 |
+ static struct page *split_large_page(unsigned long address, pgprot_t prot, |
8545 |
+- pgprot_t ref_prot) |
8546 |
++ pgprot_t ref_prot, unsigned long flags) |
8547 |
+ { |
8548 |
+ int i; |
8549 |
+ unsigned long addr; |
8550 |
+ struct page *base; |
8551 |
+ pte_t *pbase; |
8552 |
+ |
8553 |
+- spin_unlock_irq(&cpa_lock); |
8554 |
++ spin_unlock_irqrestore(&cpa_lock, flags); |
8555 |
+ base = alloc_pages(GFP_KERNEL, 0); |
8556 |
+- spin_lock_irq(&cpa_lock); |
8557 |
++ spin_lock_irqsave(&cpa_lock, flags); |
8558 |
+ if (!base) |
8559 |
+ return NULL; |
8560 |
+ |
8561 |
+@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns |
8562 |
+ struct page *page; |
8563 |
+ unsigned long flags; |
8564 |
+ |
8565 |
++#ifdef CONFIG_PAX_KERNEXEC |
8566 |
++ unsigned long cr0; |
8567 |
++ |
8568 |
++ pax_open_kernel(cr0); |
8569 |
++#endif |
8570 |
++ |
8571 |
+ set_pte_atomic(kpte, pte); /* change init_mm */ |
8572 |
++ |
8573 |
++#ifdef CONFIG_PAX_KERNEXEC |
8574 |
++ pax_close_kernel(cr0); |
8575 |
++#endif |
8576 |
++ |
8577 |
+ if (SHARED_KERNEL_PMD) |
8578 |
+ return; |
8579 |
+ |
8580 |
+@@ -126,7 +138,7 @@ static inline void revert_page(struct pa |
8581 |
+ pte_t *linear; |
8582 |
+ |
8583 |
+ ref_prot = |
8584 |
+- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext) |
8585 |
++ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET) |
8586 |
+ ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE; |
8587 |
+ |
8588 |
+ linear = (pte_t *) |
8589 |
+@@ -143,7 +155,7 @@ static inline void save_page(struct page |
8590 |
+ } |
8591 |
+ |
8592 |
+ static int |
8593 |
+-__change_page_attr(struct page *page, pgprot_t prot) |
8594 |
++__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags) |
8595 |
+ { |
8596 |
+ pte_t *kpte; |
8597 |
+ unsigned long address; |
8598 |
+@@ -167,13 +179,20 @@ __change_page_attr(struct page *page, pg |
8599 |
+ struct page *split; |
8600 |
+ |
8601 |
+ ref_prot = |
8602 |
+- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext) |
8603 |
++ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET) |
8604 |
+ ? PAGE_KERNEL_EXEC : PAGE_KERNEL; |
8605 |
+- split = split_large_page(address, prot, ref_prot); |
8606 |
++ split = split_large_page(address, prot, ref_prot, flags); |
8607 |
+ if (!split) |
8608 |
+ return -ENOMEM; |
8609 |
+- set_pmd_pte(kpte,address,mk_pte(split, ref_prot)); |
8610 |
+- kpte_page = split; |
8611 |
++ if (pte_huge(*kpte)) { |
8612 |
++ set_pmd_pte(kpte,address,mk_pte(split, ref_prot)); |
8613 |
++ kpte_page = split; |
8614 |
++ } else { |
8615 |
++ __free_pages(split, 0); |
8616 |
++ kpte = lookup_address(address); |
8617 |
++ kpte_page = virt_to_page(kpte); |
8618 |
++ set_pte_atomic(kpte, mk_pte(page, prot)); |
8619 |
++ } |
8620 |
+ } |
8621 |
+ page_private(kpte_page)++; |
8622 |
+ } else if (!pte_huge(*kpte)) { |
8623 |
+@@ -225,7 +244,7 @@ int change_page_attr(struct page *page, |
8624 |
+ |
8625 |
+ spin_lock_irqsave(&cpa_lock, flags); |
8626 |
+ for (i = 0; i < numpages; i++, page++) { |
8627 |
+- err = __change_page_attr(page, prot); |
8628 |
++ err = __change_page_attr(page, prot, flags); |
8629 |
+ if (err) |
8630 |
+ break; |
8631 |
+ } |
8632 |
+diff -Nurp linux-2.6.23.15/arch/i386/oprofile/backtrace.c linux-2.6.23.15-grsec/arch/i386/oprofile/backtrace.c |
8633 |
+--- linux-2.6.23.15/arch/i386/oprofile/backtrace.c 2007-10-09 21:31:38.000000000 +0100 |
8634 |
++++ linux-2.6.23.15-grsec/arch/i386/oprofile/backtrace.c 2008-02-11 10:37:44.000000000 +0000 |
8635 |
+@@ -22,7 +22,7 @@ struct frame_head { |
8636 |
+ static struct frame_head * |
8637 |
+ dump_kernel_backtrace(struct frame_head * head) |
8638 |
+ { |
8639 |
+- oprofile_add_trace(head->ret); |
8640 |
++ oprofile_add_trace(head->ret + __KERNEL_TEXT_OFFSET); |
8641 |
+ |
8642 |
+ /* frame pointers should strictly progress back up the stack |
8643 |
+ * (towards higher addresses) */ |
8644 |
+@@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg |
8645 |
+ head = (struct frame_head *)regs->ebp; |
8646 |
+ #endif |
8647 |
+ |
8648 |
+- if (!user_mode_vm(regs)) { |
8649 |
++ if (!user_mode(regs)) { |
8650 |
+ while (depth-- && valid_kernel_stack(head, regs)) |
8651 |
+ head = dump_kernel_backtrace(head); |
8652 |
+ return; |
8653 |
+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 |
8654 |
+--- linux-2.6.23.15/arch/i386/oprofile/op_model_p4.c 2007-10-09 21:31:38.000000000 +0100 |
8655 |
++++ linux-2.6.23.15-grsec/arch/i386/oprofile/op_model_p4.c 2008-02-11 10:37:44.000000000 +0000 |
8656 |
+@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo |
8657 |
+ #endif |
8658 |
+ } |
8659 |
+ |
8660 |
+-static int inline addr_increment(void) |
8661 |
++static inline int addr_increment(void) |
8662 |
+ { |
8663 |
+ #ifdef CONFIG_SMP |
8664 |
+ return smp_num_siblings == 2 ? 2 : 1; |
8665 |
+diff -Nurp linux-2.6.23.15/arch/i386/pci/common.c linux-2.6.23.15-grsec/arch/i386/pci/common.c |
8666 |
+--- linux-2.6.23.15/arch/i386/pci/common.c 2007-10-09 21:31:38.000000000 +0100 |
8667 |
++++ linux-2.6.23.15-grsec/arch/i386/pci/common.c 2008-02-11 10:37:44.000000000 +0000 |
8668 |
+@@ -287,7 +287,7 @@ static struct dmi_system_id __devinitdat |
8669 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"), |
8670 |
+ }, |
8671 |
+ }, |
8672 |
+- {} |
8673 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL} |
8674 |
+ }; |
8675 |
+ |
8676 |
+ struct pci_bus * __devinit pcibios_scan_root(int busnum) |
8677 |
+diff -Nurp linux-2.6.23.15/arch/i386/pci/early.c linux-2.6.23.15-grsec/arch/i386/pci/early.c |
8678 |
+--- linux-2.6.23.15/arch/i386/pci/early.c 2007-10-09 21:31:38.000000000 +0100 |
8679 |
++++ linux-2.6.23.15-grsec/arch/i386/pci/early.c 2008-02-11 10:37:44.000000000 +0000 |
8680 |
+@@ -7,7 +7,7 @@ |
8681 |
+ /* Direct PCI access. This is used for PCI accesses in early boot before |
8682 |
+ the PCI subsystem works. */ |
8683 |
+ |
8684 |
+-#define PDprintk(x...) |
8685 |
++#define PDprintk(x...) do {} while (0) |
8686 |
+ |
8687 |
+ u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) |
8688 |
+ { |
8689 |
+diff -Nurp linux-2.6.23.15/arch/i386/pci/fixup.c linux-2.6.23.15-grsec/arch/i386/pci/fixup.c |
8690 |
+--- linux-2.6.23.15/arch/i386/pci/fixup.c 2007-10-09 21:31:38.000000000 +0100 |
8691 |
++++ linux-2.6.23.15-grsec/arch/i386/pci/fixup.c 2008-02-11 10:37:44.000000000 +0000 |
8692 |
+@@ -386,7 +386,7 @@ static struct dmi_system_id __devinitdat |
8693 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"), |
8694 |
+ }, |
8695 |
+ }, |
8696 |
+- { } |
8697 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
8698 |
+ }; |
8699 |
+ |
8700 |
+ static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev) |
8701 |
+diff -Nurp linux-2.6.23.15/arch/i386/pci/irq.c linux-2.6.23.15-grsec/arch/i386/pci/irq.c |
8702 |
+--- linux-2.6.23.15/arch/i386/pci/irq.c 2007-10-09 21:31:38.000000000 +0100 |
8703 |
++++ linux-2.6.23.15-grsec/arch/i386/pci/irq.c 2008-02-11 10:37:44.000000000 +0000 |
8704 |
+@@ -508,7 +508,7 @@ static __init int intel_router_probe(str |
8705 |
+ static struct pci_device_id __initdata pirq_440gx[] = { |
8706 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) }, |
8707 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) }, |
8708 |
+- { }, |
8709 |
++ { PCI_DEVICE(0, 0) } |
8710 |
+ }; |
8711 |
+ |
8712 |
+ /* 440GX has a proprietary PIRQ router -- don't use it */ |
8713 |
+@@ -1051,7 +1051,7 @@ static struct dmi_system_id __initdata p |
8714 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), |
8715 |
+ }, |
8716 |
+ }, |
8717 |
+- { } |
8718 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
8719 |
+ }; |
8720 |
+ |
8721 |
+ static int __init pcibios_irq_init(void) |
8722 |
+diff -Nurp linux-2.6.23.15/arch/i386/pci/pcbios.c linux-2.6.23.15-grsec/arch/i386/pci/pcbios.c |
8723 |
+--- linux-2.6.23.15/arch/i386/pci/pcbios.c 2007-10-09 21:31:38.000000000 +0100 |
8724 |
++++ linux-2.6.23.15-grsec/arch/i386/pci/pcbios.c 2008-02-11 10:37:44.000000000 +0000 |
8725 |
+@@ -57,50 +57,124 @@ union bios32 { |
8726 |
+ static struct { |
8727 |
+ unsigned long address; |
8728 |
+ unsigned short segment; |
8729 |
+-} bios32_indirect = { 0, __KERNEL_CS }; |
8730 |
++} bios32_indirect __read_only = { 0, __PCIBIOS_CS }; |
8731 |
+ |
8732 |
+ /* |
8733 |
+ * Returns the entry point for the given service, NULL on error |
8734 |
+ */ |
8735 |
+ |
8736 |
+-static unsigned long bios32_service(unsigned long service) |
8737 |
++static unsigned long __devinit bios32_service(unsigned long service) |
8738 |
+ { |
8739 |
+ unsigned char return_code; /* %al */ |
8740 |
+ unsigned long address; /* %ebx */ |
8741 |
+ unsigned long length; /* %ecx */ |
8742 |
+ unsigned long entry; /* %edx */ |
8743 |
+ unsigned long flags; |
8744 |
++ struct desc_struct *gdt; |
8745 |
++ |
8746 |
++#ifdef CONFIG_PAX_KERNEXEC |
8747 |
++ unsigned long cr0; |
8748 |
++#endif |
8749 |
+ |
8750 |
+ local_irq_save(flags); |
8751 |
+- __asm__("lcall *(%%edi); cld" |
8752 |
++ |
8753 |
++ gdt = get_cpu_gdt_table(smp_processor_id()); |
8754 |
++ |
8755 |
++#ifdef CONFIG_PAX_KERNEXEC |
8756 |
++ pax_open_kernel(cr0); |
8757 |
++#endif |
8758 |
++ |
8759 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a, |
8760 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b, |
8761 |
++ 0UL, 0xFFFFFUL, 0x9B, 0xC); |
8762 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a, |
8763 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b, |
8764 |
++ 0UL, 0xFFFFFUL, 0x93, 0xC); |
8765 |
++ |
8766 |
++#ifdef CONFIG_PAX_KERNEXEC |
8767 |
++ pax_close_kernel(cr0); |
8768 |
++#endif |
8769 |
++ |
8770 |
++ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld" |
8771 |
+ : "=a" (return_code), |
8772 |
+ "=b" (address), |
8773 |
+ "=c" (length), |
8774 |
+ "=d" (entry) |
8775 |
+ : "0" (service), |
8776 |
+ "1" (0), |
8777 |
+- "D" (&bios32_indirect)); |
8778 |
++ "D" (&bios32_indirect), |
8779 |
++ "r"(__PCIBIOS_DS) |
8780 |
++ : "memory"); |
8781 |
++ |
8782 |
++#ifdef CONFIG_PAX_KERNEXEC |
8783 |
++ pax_open_kernel(cr0); |
8784 |
++#endif |
8785 |
++ |
8786 |
++ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0; |
8787 |
++ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0; |
8788 |
++ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0; |
8789 |
++ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0; |
8790 |
++ |
8791 |
++#ifdef CONFIG_PAX_KERNEXEC |
8792 |
++ pax_close_kernel(cr0); |
8793 |
++#endif |
8794 |
++ |
8795 |
+ local_irq_restore(flags); |
8796 |
+ |
8797 |
+ switch (return_code) { |
8798 |
+- case 0: |
8799 |
+- return address + entry; |
8800 |
+- case 0x80: /* Not present */ |
8801 |
+- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); |
8802 |
+- return 0; |
8803 |
+- default: /* Shouldn't happen */ |
8804 |
+- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", |
8805 |
+- service, return_code); |
8806 |
++ case 0: { |
8807 |
++ int cpu; |
8808 |
++ unsigned char flags; |
8809 |
++ |
8810 |
++ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry); |
8811 |
++ if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) { |
8812 |
++ printk(KERN_WARNING "bios32_service: not valid\n"); |
8813 |
+ return 0; |
8814 |
++ } |
8815 |
++ address = address + PAGE_OFFSET; |
8816 |
++ length += 16UL; /* some BIOSs underreport this... */ |
8817 |
++ flags = 4; |
8818 |
++ if (length >= 64*1024*1024) { |
8819 |
++ length >>= PAGE_SHIFT; |
8820 |
++ flags |= 8; |
8821 |
++ } |
8822 |
++ |
8823 |
++#ifdef CONFIG_PAX_KERNEXEC |
8824 |
++ pax_open_kernel(cr0); |
8825 |
++#endif |
8826 |
++ |
8827 |
++ for (cpu = 0; cpu < NR_CPUS; cpu++) { |
8828 |
++ gdt = get_cpu_gdt_table(cpu); |
8829 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a, |
8830 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b, |
8831 |
++ address, length, 0x9b, flags); |
8832 |
++ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a, |
8833 |
++ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b, |
8834 |
++ address, length, 0x93, flags); |
8835 |
++ } |
8836 |
++ |
8837 |
++#ifdef CONFIG_PAX_KERNEXEC |
8838 |
++ pax_close_kernel(cr0); |
8839 |
++#endif |
8840 |
++ |
8841 |
++ return entry; |
8842 |
++ } |
8843 |
++ case 0x80: /* Not present */ |
8844 |
++ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); |
8845 |
++ return 0; |
8846 |
++ default: /* Shouldn't happen */ |
8847 |
++ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", |
8848 |
++ service, return_code); |
8849 |
++ return 0; |
8850 |
+ } |
8851 |
+ } |
8852 |
+ |
8853 |
+ static struct { |
8854 |
+ unsigned long address; |
8855 |
+ unsigned short segment; |
8856 |
+-} pci_indirect = { 0, __KERNEL_CS }; |
8857 |
++} pci_indirect __read_only = { 0, __PCIBIOS_CS }; |
8858 |
+ |
8859 |
+-static int pci_bios_present; |
8860 |
++static int pci_bios_present __read_only; |
8861 |
+ |
8862 |
+ static int __devinit check_pcibios(void) |
8863 |
+ { |
8864 |
+@@ -109,11 +183,13 @@ static int __devinit check_pcibios(void) |
8865 |
+ unsigned long flags, pcibios_entry; |
8866 |
+ |
8867 |
+ if ((pcibios_entry = bios32_service(PCI_SERVICE))) { |
8868 |
+- pci_indirect.address = pcibios_entry + PAGE_OFFSET; |
8869 |
++ pci_indirect.address = pcibios_entry; |
8870 |
+ |
8871 |
+ local_irq_save(flags); |
8872 |
+- __asm__( |
8873 |
+- "lcall *(%%edi); cld\n\t" |
8874 |
++ __asm__("movw %w6, %%ds\n\t" |
8875 |
++ "lcall *%%ss:(%%edi); cld\n\t" |
8876 |
++ "push %%ss\n\t" |
8877 |
++ "pop %%ds\n\t" |
8878 |
+ "jc 1f\n\t" |
8879 |
+ "xor %%ah, %%ah\n" |
8880 |
+ "1:" |
8881 |
+@@ -122,7 +198,8 @@ static int __devinit check_pcibios(void) |
8882 |
+ "=b" (ebx), |
8883 |
+ "=c" (ecx) |
8884 |
+ : "1" (PCIBIOS_PCI_BIOS_PRESENT), |
8885 |
+- "D" (&pci_indirect) |
8886 |
++ "D" (&pci_indirect), |
8887 |
++ "r" (__PCIBIOS_DS) |
8888 |
+ : "memory"); |
8889 |
+ local_irq_restore(flags); |
8890 |
+ |
8891 |
+@@ -158,7 +235,10 @@ static int __devinit pci_bios_find_devic |
8892 |
+ unsigned short bx; |
8893 |
+ unsigned short ret; |
8894 |
+ |
8895 |
+- __asm__("lcall *(%%edi); cld\n\t" |
8896 |
++ __asm__("movw %w7, %%ds\n\t" |
8897 |
++ "lcall *%%ss:(%%edi); cld\n\t" |
8898 |
++ "push %%ss\n\t" |
8899 |
++ "pop %%ds\n\t" |
8900 |
+ "jc 1f\n\t" |
8901 |
+ "xor %%ah, %%ah\n" |
8902 |
+ "1:" |
8903 |
+@@ -168,7 +248,8 @@ static int __devinit pci_bios_find_devic |
8904 |
+ "c" (device_id), |
8905 |
+ "d" (vendor), |
8906 |
+ "S" ((int) index), |
8907 |
+- "D" (&pci_indirect)); |
8908 |
++ "D" (&pci_indirect), |
8909 |
++ "r" (__PCIBIOS_DS)); |
8910 |
+ *bus = (bx >> 8) & 0xff; |
8911 |
+ *device_fn = bx & 0xff; |
8912 |
+ return (int) (ret & 0xff00) >> 8; |
8913 |
+@@ -188,7 +269,10 @@ static int pci_bios_read(unsigned int se |
8914 |
+ |
8915 |
+ switch (len) { |
8916 |
+ case 1: |
8917 |
+- __asm__("lcall *(%%esi); cld\n\t" |
8918 |
++ __asm__("movw %w6, %%ds\n\t" |
8919 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
8920 |
++ "push %%ss\n\t" |
8921 |
++ "pop %%ds\n\t" |
8922 |
+ "jc 1f\n\t" |
8923 |
+ "xor %%ah, %%ah\n" |
8924 |
+ "1:" |
8925 |
+@@ -197,10 +281,14 @@ static int pci_bios_read(unsigned int se |
8926 |
+ : "1" (PCIBIOS_READ_CONFIG_BYTE), |
8927 |
+ "b" (bx), |
8928 |
+ "D" ((long)reg), |
8929 |
+- "S" (&pci_indirect)); |
8930 |
++ "S" (&pci_indirect), |
8931 |
++ "r" (__PCIBIOS_DS)); |
8932 |
+ break; |
8933 |
+ case 2: |
8934 |
+- __asm__("lcall *(%%esi); cld\n\t" |
8935 |
++ __asm__("movw %w6, %%ds\n\t" |
8936 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
8937 |
++ "push %%ss\n\t" |
8938 |
++ "pop %%ds\n\t" |
8939 |
+ "jc 1f\n\t" |
8940 |
+ "xor %%ah, %%ah\n" |
8941 |
+ "1:" |
8942 |
+@@ -209,10 +297,14 @@ static int pci_bios_read(unsigned int se |
8943 |
+ : "1" (PCIBIOS_READ_CONFIG_WORD), |
8944 |
+ "b" (bx), |
8945 |
+ "D" ((long)reg), |
8946 |
+- "S" (&pci_indirect)); |
8947 |
++ "S" (&pci_indirect), |
8948 |
++ "r" (__PCIBIOS_DS)); |
8949 |
+ break; |
8950 |
+ case 4: |
8951 |
+- __asm__("lcall *(%%esi); cld\n\t" |
8952 |
++ __asm__("movw %w6, %%ds\n\t" |
8953 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
8954 |
++ "push %%ss\n\t" |
8955 |
++ "pop %%ds\n\t" |
8956 |
+ "jc 1f\n\t" |
8957 |
+ "xor %%ah, %%ah\n" |
8958 |
+ "1:" |
8959 |
+@@ -221,7 +313,8 @@ static int pci_bios_read(unsigned int se |
8960 |
+ : "1" (PCIBIOS_READ_CONFIG_DWORD), |
8961 |
+ "b" (bx), |
8962 |
+ "D" ((long)reg), |
8963 |
+- "S" (&pci_indirect)); |
8964 |
++ "S" (&pci_indirect), |
8965 |
++ "r" (__PCIBIOS_DS)); |
8966 |
+ break; |
8967 |
+ } |
8968 |
+ |
8969 |
+@@ -244,7 +337,10 @@ static int pci_bios_write(unsigned int s |
8970 |
+ |
8971 |
+ switch (len) { |
8972 |
+ case 1: |
8973 |
+- __asm__("lcall *(%%esi); cld\n\t" |
8974 |
++ __asm__("movw %w6, %%ds\n\t" |
8975 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
8976 |
++ "push %%ss\n\t" |
8977 |
++ "pop %%ds\n\t" |
8978 |
+ "jc 1f\n\t" |
8979 |
+ "xor %%ah, %%ah\n" |
8980 |
+ "1:" |
8981 |
+@@ -253,10 +349,14 @@ static int pci_bios_write(unsigned int s |
8982 |
+ "c" (value), |
8983 |
+ "b" (bx), |
8984 |
+ "D" ((long)reg), |
8985 |
+- "S" (&pci_indirect)); |
8986 |
++ "S" (&pci_indirect), |
8987 |
++ "r" (__PCIBIOS_DS)); |
8988 |
+ break; |
8989 |
+ case 2: |
8990 |
+- __asm__("lcall *(%%esi); cld\n\t" |
8991 |
++ __asm__("movw %w6, %%ds\n\t" |
8992 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
8993 |
++ "push %%ss\n\t" |
8994 |
++ "pop %%ds\n\t" |
8995 |
+ "jc 1f\n\t" |
8996 |
+ "xor %%ah, %%ah\n" |
8997 |
+ "1:" |
8998 |
+@@ -265,10 +365,14 @@ static int pci_bios_write(unsigned int s |
8999 |
+ "c" (value), |
9000 |
+ "b" (bx), |
9001 |
+ "D" ((long)reg), |
9002 |
+- "S" (&pci_indirect)); |
9003 |
++ "S" (&pci_indirect), |
9004 |
++ "r" (__PCIBIOS_DS)); |
9005 |
+ break; |
9006 |
+ case 4: |
9007 |
+- __asm__("lcall *(%%esi); cld\n\t" |
9008 |
++ __asm__("movw %w6, %%ds\n\t" |
9009 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
9010 |
++ "push %%ss\n\t" |
9011 |
++ "pop %%ds\n\t" |
9012 |
+ "jc 1f\n\t" |
9013 |
+ "xor %%ah, %%ah\n" |
9014 |
+ "1:" |
9015 |
+@@ -277,7 +381,8 @@ static int pci_bios_write(unsigned int s |
9016 |
+ "c" (value), |
9017 |
+ "b" (bx), |
9018 |
+ "D" ((long)reg), |
9019 |
+- "S" (&pci_indirect)); |
9020 |
++ "S" (&pci_indirect), |
9021 |
++ "r" (__PCIBIOS_DS)); |
9022 |
+ break; |
9023 |
+ } |
9024 |
+ |
9025 |
+@@ -430,10 +535,13 @@ struct irq_routing_table * pcibios_get_i |
9026 |
+ |
9027 |
+ DBG("PCI: Fetching IRQ routing table... "); |
9028 |
+ __asm__("push %%es\n\t" |
9029 |
++ "movw %w8, %%ds\n\t" |
9030 |
+ "push %%ds\n\t" |
9031 |
+ "pop %%es\n\t" |
9032 |
+- "lcall *(%%esi); cld\n\t" |
9033 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
9034 |
+ "pop %%es\n\t" |
9035 |
++ "push %%ss\n\t" |
9036 |
++ "pop %%ds\n" |
9037 |
+ "jc 1f\n\t" |
9038 |
+ "xor %%ah, %%ah\n" |
9039 |
+ "1:" |
9040 |
+@@ -444,7 +552,8 @@ struct irq_routing_table * pcibios_get_i |
9041 |
+ "1" (0), |
9042 |
+ "D" ((long) &opt), |
9043 |
+ "S" (&pci_indirect), |
9044 |
+- "m" (opt) |
9045 |
++ "m" (opt), |
9046 |
++ "r" (__PCIBIOS_DS) |
9047 |
+ : "memory"); |
9048 |
+ DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map); |
9049 |
+ if (ret & 0xff00) |
9050 |
+@@ -468,7 +577,10 @@ int pcibios_set_irq_routing(struct pci_d |
9051 |
+ { |
9052 |
+ int ret; |
9053 |
+ |
9054 |
+- __asm__("lcall *(%%esi); cld\n\t" |
9055 |
++ __asm__("movw %w5, %%ds\n\t" |
9056 |
++ "lcall *%%ss:(%%esi); cld\n\t" |
9057 |
++ "push %%ss\n\t" |
9058 |
++ "pop %%ds\n" |
9059 |
+ "jc 1f\n\t" |
9060 |
+ "xor %%ah, %%ah\n" |
9061 |
+ "1:" |
9062 |
+@@ -476,7 +588,8 @@ int pcibios_set_irq_routing(struct pci_d |
9063 |
+ : "0" (PCIBIOS_SET_PCI_HW_INT), |
9064 |
+ "b" ((dev->bus->number << 8) | dev->devfn), |
9065 |
+ "c" ((irq << 8) | (pin + 10)), |
9066 |
+- "S" (&pci_indirect)); |
9067 |
++ "S" (&pci_indirect), |
9068 |
++ "r" (__PCIBIOS_DS)); |
9069 |
+ return !(ret & 0xff00); |
9070 |
+ } |
9071 |
+ EXPORT_SYMBOL(pcibios_set_irq_routing); |
9072 |
+diff -Nurp linux-2.6.23.15/arch/i386/power/cpu.c linux-2.6.23.15-grsec/arch/i386/power/cpu.c |
9073 |
+--- linux-2.6.23.15/arch/i386/power/cpu.c 2007-10-09 21:31:38.000000000 +0100 |
9074 |
++++ linux-2.6.23.15-grsec/arch/i386/power/cpu.c 2008-02-11 10:37:44.000000000 +0000 |
9075 |
+@@ -64,7 +64,7 @@ static void do_fpu_end(void) |
9076 |
+ static void fix_processor_context(void) |
9077 |
+ { |
9078 |
+ int cpu = smp_processor_id(); |
9079 |
+- struct tss_struct * t = &per_cpu(init_tss, cpu); |
9080 |
++ struct tss_struct *t = init_tss + cpu; |
9081 |
+ |
9082 |
+ 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. */ |
9083 |
+ |
9084 |
+diff -Nurp linux-2.6.23.15/arch/i386/xen/enlighten.c linux-2.6.23.15-grsec/arch/i386/xen/enlighten.c |
9085 |
+--- linux-2.6.23.15/arch/i386/xen/enlighten.c 2008-02-11 10:36:03.000000000 +0000 |
9086 |
++++ linux-2.6.23.15-grsec/arch/i386/xen/enlighten.c 2008-02-11 10:37:44.000000000 +0000 |
9087 |
+@@ -320,7 +320,7 @@ static void xen_set_ldt(const void *addr |
9088 |
+ static void xen_load_gdt(const struct Xgt_desc_struct *dtr) |
9089 |
+ { |
9090 |
+ unsigned long *frames; |
9091 |
+- unsigned long va = dtr->address; |
9092 |
++ unsigned long va = (unsigned long)dtr->address; |
9093 |
+ unsigned int size = dtr->size + 1; |
9094 |
+ unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; |
9095 |
+ int f; |
9096 |
+@@ -335,7 +335,7 @@ static void xen_load_gdt(const struct Xg |
9097 |
+ mcs = xen_mc_entry(sizeof(*frames) * pages); |
9098 |
+ frames = mcs.args; |
9099 |
+ |
9100 |
+- for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { |
9101 |
++ for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) { |
9102 |
+ frames[f] = virt_to_mfn(va); |
9103 |
+ make_lowmem_page_readonly((void *)va); |
9104 |
+ } |
9105 |
+@@ -429,7 +429,7 @@ static void xen_write_idt_entry(struct d |
9106 |
+ |
9107 |
+ preempt_disable(); |
9108 |
+ |
9109 |
+- start = __get_cpu_var(idt_desc).address; |
9110 |
++ start = (unsigned long)__get_cpu_var(idt_desc).address; |
9111 |
+ end = start + __get_cpu_var(idt_desc).size + 1; |
9112 |
+ |
9113 |
+ xen_mc_flush(); |
9114 |
+diff -Nurp linux-2.6.23.15/arch/i386/xen/smp.c linux-2.6.23.15-grsec/arch/i386/xen/smp.c |
9115 |
+--- linux-2.6.23.15/arch/i386/xen/smp.c 2007-10-09 21:31:38.000000000 +0100 |
9116 |
++++ linux-2.6.23.15-grsec/arch/i386/xen/smp.c 2008-02-11 10:37:44.000000000 +0000 |
9117 |
+@@ -144,7 +144,7 @@ void __init xen_smp_prepare_boot_cpu(voi |
9118 |
+ |
9119 |
+ /* We've switched to the "real" per-cpu gdt, so make sure the |
9120 |
+ old memory can be recycled */ |
9121 |
+- make_lowmem_page_readwrite(&per_cpu__gdt_page); |
9122 |
++ make_lowmem_page_readwrite(get_cpu_gdt_table(smp_processor_id())); |
9123 |
+ |
9124 |
+ for (cpu = 0; cpu < NR_CPUS; cpu++) { |
9125 |
+ cpus_clear(cpu_sibling_map[cpu]); |
9126 |
+@@ -198,7 +198,7 @@ static __cpuinit int |
9127 |
+ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) |
9128 |
+ { |
9129 |
+ struct vcpu_guest_context *ctxt; |
9130 |
+- struct gdt_page *gdt = &per_cpu(gdt_page, cpu); |
9131 |
++ struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
9132 |
+ |
9133 |
+ if (cpu_test_and_set(cpu, cpu_initialized_map)) |
9134 |
+ return 0; |
9135 |
+@@ -222,11 +222,11 @@ cpu_initialize_context(unsigned int cpu, |
9136 |
+ |
9137 |
+ ctxt->ldt_ents = 0; |
9138 |
+ |
9139 |
+- BUG_ON((unsigned long)gdt->gdt & ~PAGE_MASK); |
9140 |
+- make_lowmem_page_readonly(gdt->gdt); |
9141 |
++ BUG_ON((unsigned long)gdt & ~PAGE_MASK); |
9142 |
++ make_lowmem_page_readonly(gdt); |
9143 |
+ |
9144 |
+- ctxt->gdt_frames[0] = virt_to_mfn(gdt->gdt); |
9145 |
+- ctxt->gdt_ents = ARRAY_SIZE(gdt->gdt); |
9146 |
++ ctxt->gdt_frames[0] = virt_to_mfn(gdt); |
9147 |
++ ctxt->gdt_ents = GDT_ENTRIES; |
9148 |
+ |
9149 |
+ ctxt->user_regs.cs = __KERNEL_CS; |
9150 |
+ ctxt->user_regs.esp = idle->thread.esp0 - sizeof(struct pt_regs); |
9151 |
+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 |
9152 |
+--- linux-2.6.23.15/arch/ia64/ia32/binfmt_elf32.c 2007-10-09 21:31:38.000000000 +0100 |
9153 |
++++ linux-2.6.23.15-grsec/arch/ia64/ia32/binfmt_elf32.c 2008-02-11 10:37:44.000000000 +0000 |
9154 |
+@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_ |
9155 |
+ |
9156 |
+ #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack)) |
9157 |
+ |
9158 |
++#ifdef CONFIG_PAX_ASLR |
9159 |
++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) |
9160 |
++ |
9161 |
++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
9162 |
++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
9163 |
++#endif |
9164 |
++ |
9165 |
+ /* Ugly but avoids duplication */ |
9166 |
+ #include "../../../fs/binfmt_elf.c" |
9167 |
+ |
9168 |
+diff -Nurp linux-2.6.23.15/arch/ia64/ia32/ia32priv.h linux-2.6.23.15-grsec/arch/ia64/ia32/ia32priv.h |
9169 |
+--- linux-2.6.23.15/arch/ia64/ia32/ia32priv.h 2007-10-09 21:31:38.000000000 +0100 |
9170 |
++++ linux-2.6.23.15-grsec/arch/ia64/ia32/ia32priv.h 2008-02-11 10:37:44.000000000 +0000 |
9171 |
+@@ -304,7 +304,14 @@ struct old_linux32_dirent { |
9172 |
+ #define ELF_DATA ELFDATA2LSB |
9173 |
+ #define ELF_ARCH EM_386 |
9174 |
+ |
9175 |
+-#define IA32_STACK_TOP IA32_PAGE_OFFSET |
9176 |
++#ifdef CONFIG_PAX_RANDUSTACK |
9177 |
++#define __IA32_DELTA_STACK (current->mm->delta_stack) |
9178 |
++#else |
9179 |
++#define __IA32_DELTA_STACK 0UL |
9180 |
++#endif |
9181 |
++ |
9182 |
++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK) |
9183 |
++ |
9184 |
+ #define IA32_GATE_OFFSET IA32_PAGE_OFFSET |
9185 |
+ #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE |
9186 |
+ |
9187 |
+diff -Nurp linux-2.6.23.15/arch/ia64/kernel/module.c linux-2.6.23.15-grsec/arch/ia64/kernel/module.c |
9188 |
+--- linux-2.6.23.15/arch/ia64/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
9189 |
++++ linux-2.6.23.15-grsec/arch/ia64/kernel/module.c 2008-02-11 10:37:44.000000000 +0000 |
9190 |
+@@ -321,7 +321,7 @@ module_alloc (unsigned long size) |
9191 |
+ void |
9192 |
+ module_free (struct module *mod, void *module_region) |
9193 |
+ { |
9194 |
+- if (mod->arch.init_unw_table && module_region == mod->module_init) { |
9195 |
++ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) { |
9196 |
+ unw_remove_unwind_table(mod->arch.init_unw_table); |
9197 |
+ mod->arch.init_unw_table = NULL; |
9198 |
+ } |
9199 |
+@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd |
9200 |
+ } |
9201 |
+ |
9202 |
+ static inline int |
9203 |
++in_init_rx (const struct module *mod, uint64_t addr) |
9204 |
++{ |
9205 |
++ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx; |
9206 |
++} |
9207 |
++ |
9208 |
++static inline int |
9209 |
++in_init_rw (const struct module *mod, uint64_t addr) |
9210 |
++{ |
9211 |
++ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw; |
9212 |
++} |
9213 |
++ |
9214 |
++static inline int |
9215 |
+ in_init (const struct module *mod, uint64_t addr) |
9216 |
+ { |
9217 |
+- return addr - (uint64_t) mod->module_init < mod->init_size; |
9218 |
++ return in_init_rx(mod, value) || in_init_rw(mod, value); |
9219 |
++} |
9220 |
++ |
9221 |
++static inline int |
9222 |
++in_core_rx (const struct module *mod, uint64_t addr) |
9223 |
++{ |
9224 |
++ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx; |
9225 |
++} |
9226 |
++ |
9227 |
++static inline int |
9228 |
++in_core_rw (const struct module *mod, uint64_t addr) |
9229 |
++{ |
9230 |
++ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw; |
9231 |
+ } |
9232 |
+ |
9233 |
+ static inline int |
9234 |
+ in_core (const struct module *mod, uint64_t addr) |
9235 |
+ { |
9236 |
+- return addr - (uint64_t) mod->module_core < mod->core_size; |
9237 |
++ return in_core_rx(mod, value) || in_core_rw(mod, value); |
9238 |
+ } |
9239 |
+ |
9240 |
+ static inline int |
9241 |
+@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_ |
9242 |
+ break; |
9243 |
+ |
9244 |
+ case RV_BDREL: |
9245 |
+- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core); |
9246 |
++ if (in_init_rx(mod, val)) |
9247 |
++ val -= (uint64_t) mod->module_init_rx; |
9248 |
++ else if (in_init_rw(mod, val)) |
9249 |
++ val -= (uint64_t) mod->module_init_rw; |
9250 |
++ else if (in_core_rx(mod, val)) |
9251 |
++ val -= (uint64_t) mod->module_core_rx; |
9252 |
++ else if (in_core_rw(mod, val)) |
9253 |
++ val -= (uint64_t) mod->module_core_rw; |
9254 |
+ break; |
9255 |
+ |
9256 |
+ case RV_LTV: |
9257 |
+@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs, |
9258 |
+ * addresses have been selected... |
9259 |
+ */ |
9260 |
+ uint64_t gp; |
9261 |
+- if (mod->core_size > MAX_LTOFF) |
9262 |
++ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF) |
9263 |
+ /* |
9264 |
+ * This takes advantage of fact that SHF_ARCH_SMALL gets allocated |
9265 |
+ * at the end of the module. |
9266 |
+ */ |
9267 |
+- gp = mod->core_size - MAX_LTOFF / 2; |
9268 |
++ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2; |
9269 |
+ else |
9270 |
+- gp = mod->core_size / 2; |
9271 |
+- gp = (uint64_t) mod->module_core + ((gp + 7) & -8); |
9272 |
++ gp = (mod->core_size_rx + mod->core_size_rw) / 2; |
9273 |
++ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8); |
9274 |
+ mod->arch.gp = gp; |
9275 |
+ DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); |
9276 |
+ } |
9277 |
+diff -Nurp linux-2.6.23.15/arch/ia64/kernel/ptrace.c linux-2.6.23.15-grsec/arch/ia64/kernel/ptrace.c |
9278 |
+--- linux-2.6.23.15/arch/ia64/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100 |
9279 |
++++ linux-2.6.23.15-grsec/arch/ia64/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000 |
9280 |
+@@ -17,6 +17,7 @@ |
9281 |
+ #include <linux/security.h> |
9282 |
+ #include <linux/audit.h> |
9283 |
+ #include <linux/signal.h> |
9284 |
++#include <linux/grsecurity.h> |
9285 |
+ |
9286 |
+ #include <asm/pgtable.h> |
9287 |
+ #include <asm/processor.h> |
9288 |
+@@ -1451,6 +1452,9 @@ sys_ptrace (long request, pid_t pid, uns |
9289 |
+ if (pid == 1) /* no messing around with init! */ |
9290 |
+ goto out_tsk; |
9291 |
+ |
9292 |
++ if (gr_handle_ptrace(child, request)) |
9293 |
++ goto out_tsk; |
9294 |
++ |
9295 |
+ if (request == PTRACE_ATTACH) { |
9296 |
+ ret = ptrace_attach(child); |
9297 |
+ goto out_tsk; |
9298 |
+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 |
9299 |
+--- linux-2.6.23.15/arch/ia64/kernel/sys_ia64.c 2007-10-09 21:31:38.000000000 +0100 |
9300 |
++++ linux-2.6.23.15-grsec/arch/ia64/kernel/sys_ia64.c 2008-02-11 10:37:44.000000000 +0000 |
9301 |
+@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil |
9302 |
+ if (REGION_NUMBER(addr) == RGN_HPAGE) |
9303 |
+ addr = 0; |
9304 |
+ #endif |
9305 |
++ |
9306 |
++#ifdef CONFIG_PAX_RANDMMAP |
9307 |
++ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp) |
9308 |
++ addr = mm->free_area_cache; |
9309 |
++ else |
9310 |
++#endif |
9311 |
++ |
9312 |
+ if (!addr) |
9313 |
+ addr = mm->free_area_cache; |
9314 |
+ |
9315 |
+@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil |
9316 |
+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { |
9317 |
+ /* At this point: (!vma || addr < vma->vm_end). */ |
9318 |
+ if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) { |
9319 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
9320 |
++ if (start_addr != mm->mmap_base) { |
9321 |
+ /* Start a new search --- just in case we missed some holes. */ |
9322 |
+- addr = TASK_UNMAPPED_BASE; |
9323 |
++ addr = mm->mmap_base; |
9324 |
+ goto full_search; |
9325 |
+ } |
9326 |
+ return -ENOMEM; |
9327 |
+diff -Nurp linux-2.6.23.15/arch/ia64/mm/fault.c linux-2.6.23.15-grsec/arch/ia64/mm/fault.c |
9328 |
+--- linux-2.6.23.15/arch/ia64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
9329 |
++++ linux-2.6.23.15-grsec/arch/ia64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
9330 |
+@@ -10,6 +10,7 @@ |
9331 |
+ #include <linux/interrupt.h> |
9332 |
+ #include <linux/kprobes.h> |
9333 |
+ #include <linux/kdebug.h> |
9334 |
++#include <linux/binfmts.h> |
9335 |
+ |
9336 |
+ #include <asm/pgtable.h> |
9337 |
+ #include <asm/processor.h> |
9338 |
+@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned |
9339 |
+ return pte_present(pte); |
9340 |
+ } |
9341 |
+ |
9342 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9343 |
++void pax_report_insns(void *pc, void *sp) |
9344 |
++{ |
9345 |
++ unsigned long i; |
9346 |
++ |
9347 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
9348 |
++ for (i = 0; i < 8; i++) { |
9349 |
++ unsigned int c; |
9350 |
++ if (get_user(c, (unsigned int *)pc+i)) |
9351 |
++ printk("???????? "); |
9352 |
++ else |
9353 |
++ printk("%08x ", c); |
9354 |
++ } |
9355 |
++ printk("\n"); |
9356 |
++} |
9357 |
++#endif |
9358 |
++ |
9359 |
+ void __kprobes |
9360 |
+ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs) |
9361 |
+ { |
9362 |
+@@ -145,9 +163,23 @@ ia64_do_page_fault (unsigned long addres |
9363 |
+ mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT) |
9364 |
+ | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); |
9365 |
+ |
9366 |
+- if ((vma->vm_flags & mask) != mask) |
9367 |
++ if ((vma->vm_flags & mask) != mask) { |
9368 |
++ |
9369 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9370 |
++ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) { |
9371 |
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip) |
9372 |
++ goto bad_area; |
9373 |
++ |
9374 |
++ up_read(&mm->mmap_sem); |
9375 |
++ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12); |
9376 |
++ do_exit(SIGKILL); |
9377 |
++ } |
9378 |
++#endif |
9379 |
++ |
9380 |
+ goto bad_area; |
9381 |
+ |
9382 |
++ } |
9383 |
++ |
9384 |
+ survive: |
9385 |
+ /* |
9386 |
+ * If for any reason at all we couldn't handle the fault, make |
9387 |
+diff -Nurp linux-2.6.23.15/arch/ia64/mm/init.c linux-2.6.23.15-grsec/arch/ia64/mm/init.c |
9388 |
+--- linux-2.6.23.15/arch/ia64/mm/init.c 2007-10-09 21:31:38.000000000 +0100 |
9389 |
++++ linux-2.6.23.15-grsec/arch/ia64/mm/init.c 2008-02-11 10:37:44.000000000 +0000 |
9390 |
+@@ -20,8 +20,8 @@ |
9391 |
+ #include <linux/proc_fs.h> |
9392 |
+ #include <linux/bitops.h> |
9393 |
+ #include <linux/kexec.h> |
9394 |
++#include <linux/a.out.h> |
9395 |
+ |
9396 |
+-#include <asm/a.out.h> |
9397 |
+ #include <asm/dma.h> |
9398 |
+ #include <asm/ia32.h> |
9399 |
+ #include <asm/io.h> |
9400 |
+@@ -130,8 +130,21 @@ ia64_init_addr_space (void) |
9401 |
+ vma->vm_mm = current->mm; |
9402 |
+ vma->vm_start = current->thread.rbs_bot & PAGE_MASK; |
9403 |
+ vma->vm_end = vma->vm_start + PAGE_SIZE; |
9404 |
+- vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7]; |
9405 |
+ vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT; |
9406 |
++ |
9407 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9408 |
++ if (current->mm->pax_flags & MF_PAX_PAGEEXEC) { |
9409 |
++ vm->vm_flags &= ~VM_EXEC; |
9410 |
++ |
9411 |
++#ifdef CONFIG_PAX_MPROTECT |
9412 |
++ if (current->mm->pax_flags & MF_PAX_MPROTECT) |
9413 |
++ vma->vm_flags &= ~VM_MAYEXEC; |
9414 |
++#endif |
9415 |
++ |
9416 |
++ } |
9417 |
++#endif |
9418 |
++ |
9419 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
9420 |
+ down_write(¤t->mm->mmap_sem); |
9421 |
+ if (insert_vm_struct(current->mm, vma)) { |
9422 |
+ up_write(¤t->mm->mmap_sem); |
9423 |
+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 |
9424 |
+--- linux-2.6.23.15/arch/mips/kernel/binfmt_elfn32.c 2007-10-09 21:31:38.000000000 +0100 |
9425 |
++++ linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfn32.c 2008-02-11 10:37:44.000000000 +0000 |
9426 |
+@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N |
9427 |
+ #undef ELF_ET_DYN_BASE |
9428 |
+ #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) |
9429 |
+ |
9430 |
++#ifdef CONFIG_PAX_ASLR |
9431 |
++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) |
9432 |
++ |
9433 |
++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
9434 |
++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
9435 |
++#endif |
9436 |
++ |
9437 |
+ #include <asm/processor.h> |
9438 |
+ #include <linux/module.h> |
9439 |
+ #include <linux/elfcore.h> |
9440 |
+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 |
9441 |
+--- linux-2.6.23.15/arch/mips/kernel/binfmt_elfo32.c 2007-10-09 21:31:38.000000000 +0100 |
9442 |
++++ linux-2.6.23.15-grsec/arch/mips/kernel/binfmt_elfo32.c 2008-02-11 10:37:44.000000000 +0000 |
9443 |
+@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N |
9444 |
+ #undef ELF_ET_DYN_BASE |
9445 |
+ #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) |
9446 |
+ |
9447 |
++#ifdef CONFIG_PAX_ASLR |
9448 |
++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) |
9449 |
++ |
9450 |
++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
9451 |
++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
9452 |
++#endif |
9453 |
++ |
9454 |
+ #include <asm/processor.h> |
9455 |
+ #include <linux/module.h> |
9456 |
+ #include <linux/elfcore.h> |
9457 |
+diff -Nurp linux-2.6.23.15/arch/mips/kernel/syscall.c linux-2.6.23.15-grsec/arch/mips/kernel/syscall.c |
9458 |
+--- linux-2.6.23.15/arch/mips/kernel/syscall.c 2007-10-09 21:31:38.000000000 +0100 |
9459 |
++++ linux-2.6.23.15-grsec/arch/mips/kernel/syscall.c 2008-02-11 10:37:44.000000000 +0000 |
9460 |
+@@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str |
9461 |
+ do_color_align = 0; |
9462 |
+ if (filp || (flags & MAP_SHARED)) |
9463 |
+ do_color_align = 1; |
9464 |
++ |
9465 |
++#ifdef CONFIG_PAX_RANDMMAP |
9466 |
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
9467 |
++#endif |
9468 |
++ |
9469 |
+ if (addr) { |
9470 |
+ if (do_color_align) |
9471 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
9472 |
+@@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str |
9473 |
+ (!vmm || addr + len <= vmm->vm_start)) |
9474 |
+ return addr; |
9475 |
+ } |
9476 |
+- addr = TASK_UNMAPPED_BASE; |
9477 |
++ addr = current->mm->mmap_base; |
9478 |
+ if (do_color_align) |
9479 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
9480 |
+ else |
9481 |
+diff -Nurp linux-2.6.23.15/arch/mips/mm/fault.c linux-2.6.23.15-grsec/arch/mips/mm/fault.c |
9482 |
+--- linux-2.6.23.15/arch/mips/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
9483 |
++++ linux-2.6.23.15-grsec/arch/mips/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
9484 |
+@@ -26,6 +26,23 @@ |
9485 |
+ #include <asm/ptrace.h> |
9486 |
+ #include <asm/highmem.h> /* For VMALLOC_END */ |
9487 |
+ |
9488 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9489 |
++void pax_report_insns(void *pc) |
9490 |
++{ |
9491 |
++ unsigned long i; |
9492 |
++ |
9493 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
9494 |
++ for (i = 0; i < 5; i++) { |
9495 |
++ unsigned int c; |
9496 |
++ if (get_user(c, (unsigned int *)pc+i)) |
9497 |
++ printk("???????? "); |
9498 |
++ else |
9499 |
++ printk("%08x ", c); |
9500 |
++ } |
9501 |
++ printk("\n"); |
9502 |
++} |
9503 |
++#endif |
9504 |
++ |
9505 |
+ /* |
9506 |
+ * This routine handles page faults. It determines the address, |
9507 |
+ * and the problem, and then passes it off to one of the appropriate |
9508 |
+diff -Nurp linux-2.6.23.15/arch/parisc/kernel/module.c linux-2.6.23.15-grsec/arch/parisc/kernel/module.c |
9509 |
+--- linux-2.6.23.15/arch/parisc/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
9510 |
++++ linux-2.6.23.15-grsec/arch/parisc/kernel/module.c 2008-02-11 10:37:44.000000000 +0000 |
9511 |
+@@ -73,16 +73,38 @@ |
9512 |
+ |
9513 |
+ /* three functions to determine where in the module core |
9514 |
+ * or init pieces the location is */ |
9515 |
++static inline int in_init_rx(struct module *me, void *loc) |
9516 |
++{ |
9517 |
++ return (loc >= me->module_init_rx && |
9518 |
++ loc < (me->module_init_rx + me->init_size_rx)); |
9519 |
++} |
9520 |
++ |
9521 |
++static inline int in_init_rw(struct module *me, void *loc) |
9522 |
++{ |
9523 |
++ return (loc >= me->module_init_rw && |
9524 |
++ loc < (me->module_init_rw + me->init_size_rw)); |
9525 |
++} |
9526 |
++ |
9527 |
+ static inline int in_init(struct module *me, void *loc) |
9528 |
+ { |
9529 |
+- return (loc >= me->module_init && |
9530 |
+- loc <= (me->module_init + me->init_size)); |
9531 |
++ return in_init_rx(me, loc) || in_init_rw(me, loc); |
9532 |
++} |
9533 |
++ |
9534 |
++static inline int in_core_rx(struct module *me, void *loc) |
9535 |
++{ |
9536 |
++ return (loc >= me->module_core_rx && |
9537 |
++ loc < (me->module_core_rx + me->core_size_rx)); |
9538 |
++} |
9539 |
++ |
9540 |
++static inline int in_core_rw(struct module *me, void *loc) |
9541 |
++{ |
9542 |
++ return (loc >= me->module_core_rw && |
9543 |
++ loc < (me->module_core_rw + me->core_size_rw)); |
9544 |
+ } |
9545 |
+ |
9546 |
+ static inline int in_core(struct module *me, void *loc) |
9547 |
+ { |
9548 |
+- return (loc >= me->module_core && |
9549 |
+- loc <= (me->module_core + me->core_size)); |
9550 |
++ return in_core_rx(me, loc) || in_core_rw(me, loc); |
9551 |
+ } |
9552 |
+ |
9553 |
+ static inline int in_local(struct module *me, void *loc) |
9554 |
+@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_ |
9555 |
+ } |
9556 |
+ |
9557 |
+ /* align things a bit */ |
9558 |
+- me->core_size = ALIGN(me->core_size, 16); |
9559 |
+- me->arch.got_offset = me->core_size; |
9560 |
+- me->core_size += gots * sizeof(struct got_entry); |
9561 |
+- |
9562 |
+- me->core_size = ALIGN(me->core_size, 16); |
9563 |
+- me->arch.fdesc_offset = me->core_size; |
9564 |
+- me->core_size += fdescs * sizeof(Elf_Fdesc); |
9565 |
+- |
9566 |
+- me->core_size = ALIGN(me->core_size, 16); |
9567 |
+- me->arch.stub_offset = me->core_size; |
9568 |
+- me->core_size += stubs * sizeof(struct stub_entry); |
9569 |
+- |
9570 |
+- me->init_size = ALIGN(me->init_size, 16); |
9571 |
+- me->arch.init_stub_offset = me->init_size; |
9572 |
+- me->init_size += init_stubs * sizeof(struct stub_entry); |
9573 |
++ me->core_size_rw = ALIGN(me->core_size_rw, 16); |
9574 |
++ me->arch.got_offset = me->core_size_rw; |
9575 |
++ me->core_size_rw += gots * sizeof(struct got_entry); |
9576 |
++ |
9577 |
++ me->core_size_rw = ALIGN(me->core_size_rw, 16); |
9578 |
++ me->arch.fdesc_offset = me->core_size_rw; |
9579 |
++ me->core_size_rw += fdescs * sizeof(Elf_Fdesc); |
9580 |
++ |
9581 |
++ me->core_size_rx = ALIGN(me->core_size_rx, 16); |
9582 |
++ me->arch.stub_offset = me->core_size_rx; |
9583 |
++ me->core_size_rx += stubs * sizeof(struct stub_entry); |
9584 |
++ |
9585 |
++ me->init_size_rx = ALIGN(me->init_size_rx, 16); |
9586 |
++ me->arch.init_stub_offset = me->init_size_rx; |
9587 |
++ me->init_size_rx += init_stubs * sizeof(struct stub_entry); |
9588 |
+ |
9589 |
+ me->arch.got_max = gots; |
9590 |
+ me->arch.fdesc_max = fdescs; |
9591 |
+@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module |
9592 |
+ |
9593 |
+ BUG_ON(value == 0); |
9594 |
+ |
9595 |
+- got = me->module_core + me->arch.got_offset; |
9596 |
++ got = me->module_core_rw + me->arch.got_offset; |
9597 |
+ for (i = 0; got[i].addr; i++) |
9598 |
+ if (got[i].addr == value) |
9599 |
+ goto out; |
9600 |
+@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module |
9601 |
+ #ifdef CONFIG_64BIT |
9602 |
+ static Elf_Addr get_fdesc(struct module *me, unsigned long value) |
9603 |
+ { |
9604 |
+- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset; |
9605 |
++ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset; |
9606 |
+ |
9607 |
+ if (!value) { |
9608 |
+ printk(KERN_ERR "%s: zero OPD requested!\n", me->name); |
9609 |
+@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module |
9610 |
+ |
9611 |
+ /* Create new one */ |
9612 |
+ fdesc->addr = value; |
9613 |
+- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset; |
9614 |
++ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset; |
9615 |
+ return (Elf_Addr)fdesc; |
9616 |
+ } |
9617 |
+ #endif /* CONFIG_64BIT */ |
9618 |
+@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module * |
9619 |
+ if(init_section) { |
9620 |
+ i = me->arch.init_stub_count++; |
9621 |
+ BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max); |
9622 |
+- stub = me->module_init + me->arch.init_stub_offset + |
9623 |
++ stub = me->module_init_rx + me->arch.init_stub_offset + |
9624 |
+ i * sizeof(struct stub_entry); |
9625 |
+ } else { |
9626 |
+ i = me->arch.stub_count++; |
9627 |
+ BUG_ON(me->arch.stub_count > me->arch.stub_max); |
9628 |
+- stub = me->module_core + me->arch.stub_offset + |
9629 |
++ stub = me->module_core_rx + me->arch.stub_offset + |
9630 |
+ i * sizeof(struct stub_entry); |
9631 |
+ } |
9632 |
+ |
9633 |
+@@ -759,7 +781,7 @@ register_unwind_table(struct module *me, |
9634 |
+ |
9635 |
+ table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr; |
9636 |
+ end = table + sechdrs[me->arch.unwind_section].sh_size; |
9637 |
+- gp = (Elf_Addr)me->module_core + me->arch.got_offset; |
9638 |
++ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset; |
9639 |
+ |
9640 |
+ DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", |
9641 |
+ me->arch.unwind_section, table, end, gp); |
9642 |
+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 |
9643 |
+--- linux-2.6.23.15/arch/parisc/kernel/sys_parisc.c 2007-10-09 21:31:38.000000000 +0100 |
9644 |
++++ linux-2.6.23.15-grsec/arch/parisc/kernel/sys_parisc.c 2008-02-11 10:37:44.000000000 +0000 |
9645 |
+@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str |
9646 |
+ if (flags & MAP_FIXED) |
9647 |
+ return addr; |
9648 |
+ if (!addr) |
9649 |
+- addr = TASK_UNMAPPED_BASE; |
9650 |
++ addr = current->mm->mmap_base; |
9651 |
+ |
9652 |
+ if (filp) { |
9653 |
+ addr = get_shared_area(filp->f_mapping, addr, len, pgoff); |
9654 |
+diff -Nurp linux-2.6.23.15/arch/parisc/kernel/traps.c linux-2.6.23.15-grsec/arch/parisc/kernel/traps.c |
9655 |
+--- linux-2.6.23.15/arch/parisc/kernel/traps.c 2007-10-09 21:31:38.000000000 +0100 |
9656 |
++++ linux-2.6.23.15-grsec/arch/parisc/kernel/traps.c 2008-02-11 10:37:44.000000000 +0000 |
9657 |
+@@ -713,9 +713,7 @@ void handle_interruption(int code, struc |
9658 |
+ |
9659 |
+ down_read(¤t->mm->mmap_sem); |
9660 |
+ vma = find_vma(current->mm,regs->iaoq[0]); |
9661 |
+- if (vma && (regs->iaoq[0] >= vma->vm_start) |
9662 |
+- && (vma->vm_flags & VM_EXEC)) { |
9663 |
+- |
9664 |
++ if (vma && (regs->iaoq[0] >= vma->vm_start)) { |
9665 |
+ fault_address = regs->iaoq[0]; |
9666 |
+ fault_space = regs->iasq[0]; |
9667 |
+ |
9668 |
+diff -Nurp linux-2.6.23.15/arch/parisc/mm/fault.c linux-2.6.23.15-grsec/arch/parisc/mm/fault.c |
9669 |
+--- linux-2.6.23.15/arch/parisc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
9670 |
++++ linux-2.6.23.15-grsec/arch/parisc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
9671 |
+@@ -16,6 +16,8 @@ |
9672 |
+ #include <linux/sched.h> |
9673 |
+ #include <linux/interrupt.h> |
9674 |
+ #include <linux/module.h> |
9675 |
++#include <linux/unistd.h> |
9676 |
++#include <linux/binfmts.h> |
9677 |
+ |
9678 |
+ #include <asm/uaccess.h> |
9679 |
+ #include <asm/traps.h> |
9680 |
+@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex |
9681 |
+ static unsigned long |
9682 |
+ parisc_acctyp(unsigned long code, unsigned int inst) |
9683 |
+ { |
9684 |
+- if (code == 6 || code == 16) |
9685 |
++ if (code == 6 || code == 7 || code == 16) |
9686 |
+ return VM_EXEC; |
9687 |
+ |
9688 |
+ switch (inst & 0xf0000000) { |
9689 |
+@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign |
9690 |
+ } |
9691 |
+ #endif |
9692 |
+ |
9693 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9694 |
++/* |
9695 |
++ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address) |
9696 |
++ * |
9697 |
++ * returns 1 when task should be killed |
9698 |
++ * 2 when rt_sigreturn trampoline was detected |
9699 |
++ * 3 when unpatched PLT trampoline was detected |
9700 |
++ */ |
9701 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
9702 |
++{ |
9703 |
++ |
9704 |
++#ifdef CONFIG_PAX_EMUPLT |
9705 |
++ int err; |
9706 |
++ |
9707 |
++ do { /* PaX: unpatched PLT emulation */ |
9708 |
++ unsigned int bl, depwi; |
9709 |
++ |
9710 |
++ err = get_user(bl, (unsigned int *)instruction_pointer(regs)); |
9711 |
++ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4)); |
9712 |
++ |
9713 |
++ if (err) |
9714 |
++ break; |
9715 |
++ |
9716 |
++ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) { |
9717 |
++ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12; |
9718 |
++ |
9719 |
++ err = get_user(ldw, (unsigned int *)addr); |
9720 |
++ err |= get_user(bv, (unsigned int *)(addr+4)); |
9721 |
++ err |= get_user(ldw2, (unsigned int *)(addr+8)); |
9722 |
++ |
9723 |
++ if (err) |
9724 |
++ break; |
9725 |
++ |
9726 |
++ if (ldw == 0x0E801096U && |
9727 |
++ bv == 0xEAC0C000U && |
9728 |
++ ldw2 == 0x0E881095U) |
9729 |
++ { |
9730 |
++ unsigned int resolver, map; |
9731 |
++ |
9732 |
++ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8)); |
9733 |
++ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12)); |
9734 |
++ if (err) |
9735 |
++ break; |
9736 |
++ |
9737 |
++ regs->gr[20] = instruction_pointer(regs)+8; |
9738 |
++ regs->gr[21] = map; |
9739 |
++ regs->gr[22] = resolver; |
9740 |
++ regs->iaoq[0] = resolver | 3UL; |
9741 |
++ regs->iaoq[1] = regs->iaoq[0] + 4; |
9742 |
++ return 3; |
9743 |
++ } |
9744 |
++ } |
9745 |
++ } while (0); |
9746 |
++#endif |
9747 |
++ |
9748 |
++#ifdef CONFIG_PAX_EMUTRAMP |
9749 |
++ |
9750 |
++#ifndef CONFIG_PAX_EMUSIGRT |
9751 |
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) |
9752 |
++ return 1; |
9753 |
++#endif |
9754 |
++ |
9755 |
++ do { /* PaX: rt_sigreturn emulation */ |
9756 |
++ unsigned int ldi1, ldi2, bel, nop; |
9757 |
++ |
9758 |
++ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs)); |
9759 |
++ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4)); |
9760 |
++ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8)); |
9761 |
++ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12)); |
9762 |
++ |
9763 |
++ if (err) |
9764 |
++ break; |
9765 |
++ |
9766 |
++ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) && |
9767 |
++ ldi2 == 0x3414015AU && |
9768 |
++ bel == 0xE4008200U && |
9769 |
++ nop == 0x08000240U) |
9770 |
++ { |
9771 |
++ regs->gr[25] = (ldi1 & 2) >> 1; |
9772 |
++ regs->gr[20] = __NR_rt_sigreturn; |
9773 |
++ regs->gr[31] = regs->iaoq[1] + 16; |
9774 |
++ regs->sr[0] = regs->iasq[1]; |
9775 |
++ regs->iaoq[0] = 0x100UL; |
9776 |
++ regs->iaoq[1] = regs->iaoq[0] + 4; |
9777 |
++ regs->iasq[0] = regs->sr[2]; |
9778 |
++ regs->iasq[1] = regs->sr[2]; |
9779 |
++ return 2; |
9780 |
++ } |
9781 |
++ } while (0); |
9782 |
++#endif |
9783 |
++ |
9784 |
++ return 1; |
9785 |
++} |
9786 |
++ |
9787 |
++void pax_report_insns(void *pc, void *sp) |
9788 |
++{ |
9789 |
++ unsigned long i; |
9790 |
++ |
9791 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
9792 |
++ for (i = 0; i < 5; i++) { |
9793 |
++ unsigned int c; |
9794 |
++ if (get_user(c, (unsigned int *)pc+i)) |
9795 |
++ printk("???????? "); |
9796 |
++ else |
9797 |
++ printk("%08x ", c); |
9798 |
++ } |
9799 |
++ printk("\n"); |
9800 |
++} |
9801 |
++#endif |
9802 |
++ |
9803 |
+ void do_page_fault(struct pt_regs *regs, unsigned long code, |
9804 |
+ unsigned long address) |
9805 |
+ { |
9806 |
+@@ -165,8 +277,33 @@ good_area: |
9807 |
+ |
9808 |
+ acc_type = parisc_acctyp(code,regs->iir); |
9809 |
+ |
9810 |
+- if ((vma->vm_flags & acc_type) != acc_type) |
9811 |
++ if ((vma->vm_flags & acc_type) != acc_type) { |
9812 |
++ |
9813 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9814 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) && |
9815 |
++ (address & ~3UL) == instruction_pointer(regs)) |
9816 |
++ { |
9817 |
++ up_read(&mm->mmap_sem); |
9818 |
++ switch (pax_handle_fetch_fault(regs)) { |
9819 |
++ |
9820 |
++#ifdef CONFIG_PAX_EMUPLT |
9821 |
++ case 3: |
9822 |
++ return; |
9823 |
++#endif |
9824 |
++ |
9825 |
++#ifdef CONFIG_PAX_EMUTRAMP |
9826 |
++ case 2: |
9827 |
++ return; |
9828 |
++#endif |
9829 |
++ |
9830 |
++ } |
9831 |
++ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]); |
9832 |
++ do_exit(SIGKILL); |
9833 |
++ } |
9834 |
++#endif |
9835 |
++ |
9836 |
+ goto bad_area; |
9837 |
++ } |
9838 |
+ |
9839 |
+ /* |
9840 |
+ * If for any reason at all we couldn't handle the fault, make |
9841 |
+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 |
9842 |
+--- linux-2.6.23.15/arch/powerpc/kernel/module_32.c 2007-10-09 21:31:38.000000000 +0100 |
9843 |
++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/module_32.c 2008-02-11 10:37:44.000000000 +0000 |
9844 |
+@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr |
9845 |
+ me->arch.core_plt_section = i; |
9846 |
+ } |
9847 |
+ if (!me->arch.core_plt_section || !me->arch.init_plt_section) { |
9848 |
+- printk("Module doesn't contain .plt or .init.plt sections.\n"); |
9849 |
++ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name); |
9850 |
+ return -ENOEXEC; |
9851 |
+ } |
9852 |
+ |
9853 |
+@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati |
9854 |
+ |
9855 |
+ DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location); |
9856 |
+ /* Init, or core PLT? */ |
9857 |
+- if (location >= mod->module_core |
9858 |
+- && location < mod->module_core + mod->core_size) |
9859 |
++ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) || |
9860 |
++ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw)) |
9861 |
+ entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; |
9862 |
+- else |
9863 |
++ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) || |
9864 |
++ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw)) |
9865 |
+ entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; |
9866 |
++ else { |
9867 |
++ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name); |
9868 |
++ return ~0UL; |
9869 |
++ } |
9870 |
+ |
9871 |
+ /* Find this entry, or if that fails, the next avail. entry */ |
9872 |
+ while (entry->jump[0]) { |
9873 |
+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 |
9874 |
+--- linux-2.6.23.15/arch/powerpc/kernel/signal_32.c 2007-10-09 21:31:38.000000000 +0100 |
9875 |
++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_32.c 2008-02-11 10:37:44.000000000 +0000 |
9876 |
+@@ -728,7 +728,7 @@ int handle_rt_signal32(unsigned long sig |
9877 |
+ |
9878 |
+ /* Save user registers on the stack */ |
9879 |
+ frame = &rt_sf->uc.uc_mcontext; |
9880 |
+- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) { |
9881 |
++ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) { |
9882 |
+ if (save_user_regs(regs, frame, 0)) |
9883 |
+ goto badframe; |
9884 |
+ regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp; |
9885 |
+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 |
9886 |
+--- linux-2.6.23.15/arch/powerpc/kernel/signal_64.c 2007-10-09 21:31:38.000000000 +0100 |
9887 |
++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/signal_64.c 2008-02-11 10:37:44.000000000 +0000 |
9888 |
+@@ -359,7 +359,7 @@ int handle_rt_signal64(int signr, struct |
9889 |
+ current->thread.fpscr.val = 0; |
9890 |
+ |
9891 |
+ /* Set up to return from userspace. */ |
9892 |
+- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) { |
9893 |
++ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) { |
9894 |
+ regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp; |
9895 |
+ } else { |
9896 |
+ err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]); |
9897 |
+diff -Nurp linux-2.6.23.15/arch/powerpc/kernel/vdso.c linux-2.6.23.15-grsec/arch/powerpc/kernel/vdso.c |
9898 |
+--- linux-2.6.23.15/arch/powerpc/kernel/vdso.c 2007-10-09 21:31:38.000000000 +0100 |
9899 |
++++ linux-2.6.23.15-grsec/arch/powerpc/kernel/vdso.c 2008-02-11 10:37:44.000000000 +0000 |
9900 |
+@@ -211,7 +211,7 @@ int arch_setup_additional_pages(struct l |
9901 |
+ vdso_base = VDSO32_MBASE; |
9902 |
+ #endif |
9903 |
+ |
9904 |
+- current->mm->context.vdso_base = 0; |
9905 |
++ current->mm->context.vdso_base = ~0UL; |
9906 |
+ |
9907 |
+ /* vDSO has a problem and was disabled, just don't "enable" it for the |
9908 |
+ * process |
9909 |
+@@ -228,7 +228,7 @@ int arch_setup_additional_pages(struct l |
9910 |
+ */ |
9911 |
+ down_write(&mm->mmap_sem); |
9912 |
+ vdso_base = get_unmapped_area(NULL, vdso_base, |
9913 |
+- vdso_pages << PAGE_SHIFT, 0, 0); |
9914 |
++ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE); |
9915 |
+ if (IS_ERR_VALUE(vdso_base)) { |
9916 |
+ rc = vdso_base; |
9917 |
+ goto fail_mmapsem; |
9918 |
+diff -Nurp linux-2.6.23.15/arch/powerpc/mm/fault.c linux-2.6.23.15-grsec/arch/powerpc/mm/fault.c |
9919 |
+--- linux-2.6.23.15/arch/powerpc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
9920 |
++++ linux-2.6.23.15-grsec/arch/powerpc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
9921 |
+@@ -29,6 +29,12 @@ |
9922 |
+ #include <linux/module.h> |
9923 |
+ #include <linux/kprobes.h> |
9924 |
+ #include <linux/kdebug.h> |
9925 |
++#include <linux/binfmts.h> |
9926 |
++#include <linux/slab.h> |
9927 |
++#include <linux/pagemap.h> |
9928 |
++#include <linux/compiler.h> |
9929 |
++#include <linux/binfmts.h> |
9930 |
++#include <linux/unistd.h> |
9931 |
+ |
9932 |
+ #include <asm/page.h> |
9933 |
+ #include <asm/pgtable.h> |
9934 |
+@@ -62,6 +68,364 @@ static inline int notify_page_fault(stru |
9935 |
+ } |
9936 |
+ #endif |
9937 |
+ |
9938 |
++#ifdef CONFIG_PAX_EMUSIGRT |
9939 |
++void pax_syscall_close(struct vm_area_struct *vma) |
9940 |
++{ |
9941 |
++ vma->vm_mm->call_syscall = 0UL; |
9942 |
++} |
9943 |
++ |
9944 |
++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
9945 |
++{ |
9946 |
++ struct page *page; |
9947 |
++ unsigned int *kaddr; |
9948 |
++ |
9949 |
++ page = alloc_page(GFP_HIGHUSER); |
9950 |
++ if (!page) |
9951 |
++ return NOPAGE_OOM; |
9952 |
++ |
9953 |
++ kaddr = kmap(page); |
9954 |
++ memset(kaddr, 0, PAGE_SIZE); |
9955 |
++ kaddr[0] = 0x44000002U; /* sc */ |
9956 |
++ __flush_dcache_icache(kaddr); |
9957 |
++ kunmap(page); |
9958 |
++ if (type) |
9959 |
++ *type = VM_FAULT_MAJOR; |
9960 |
++ return page; |
9961 |
++} |
9962 |
++ |
9963 |
++static struct vm_operations_struct pax_vm_ops = { |
9964 |
++ .close = pax_syscall_close, |
9965 |
++ .nopage = pax_syscall_nopage, |
9966 |
++}; |
9967 |
++ |
9968 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
9969 |
++{ |
9970 |
++ int ret; |
9971 |
++ |
9972 |
++ memset(vma, 0, sizeof(*vma)); |
9973 |
++ vma->vm_mm = current->mm; |
9974 |
++ vma->vm_start = addr; |
9975 |
++ vma->vm_end = addr + PAGE_SIZE; |
9976 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
9977 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
9978 |
++ vma->vm_ops = &pax_vm_ops; |
9979 |
++ |
9980 |
++ ret = insert_vm_struct(current->mm, vma); |
9981 |
++ if (ret) |
9982 |
++ return ret; |
9983 |
++ |
9984 |
++ ++current->mm->total_vm; |
9985 |
++ return 0; |
9986 |
++} |
9987 |
++#endif |
9988 |
++ |
9989 |
++#ifdef CONFIG_PAX_PAGEEXEC |
9990 |
++/* |
9991 |
++ * PaX: decide what to do with offenders (regs->nip = fault address) |
9992 |
++ * |
9993 |
++ * returns 1 when task should be killed |
9994 |
++ * 2 when patched GOT trampoline was detected |
9995 |
++ * 3 when patched PLT trampoline was detected |
9996 |
++ * 4 when unpatched PLT trampoline was detected |
9997 |
++ * 5 when sigreturn trampoline was detected |
9998 |
++ * 6 when rt_sigreturn trampoline was detected |
9999 |
++ */ |
10000 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
10001 |
++{ |
10002 |
++ |
10003 |
++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT) |
10004 |
++ int err; |
10005 |
++#endif |
10006 |
++ |
10007 |
++#ifdef CONFIG_PAX_EMUPLT |
10008 |
++ do { /* PaX: patched GOT emulation */ |
10009 |
++ unsigned int blrl; |
10010 |
++ |
10011 |
++ err = get_user(blrl, (unsigned int *)regs->nip); |
10012 |
++ |
10013 |
++ if (!err && blrl == 0x4E800021U) { |
10014 |
++ unsigned long temp = regs->nip; |
10015 |
++ |
10016 |
++ regs->nip = regs->link & 0xFFFFFFFCUL; |
10017 |
++ regs->link = temp + 4UL; |
10018 |
++ return 2; |
10019 |
++ } |
10020 |
++ } while (0); |
10021 |
++ |
10022 |
++ do { /* PaX: patched PLT emulation #1 */ |
10023 |
++ unsigned int b; |
10024 |
++ |
10025 |
++ err = get_user(b, (unsigned int *)regs->nip); |
10026 |
++ |
10027 |
++ if (!err && (b & 0xFC000003U) == 0x48000000U) { |
10028 |
++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL); |
10029 |
++ return 3; |
10030 |
++ } |
10031 |
++ } while (0); |
10032 |
++ |
10033 |
++ do { /* PaX: unpatched PLT emulation #1 */ |
10034 |
++ unsigned int li, b; |
10035 |
++ |
10036 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10037 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
10038 |
++ |
10039 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
10040 |
++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
10041 |
++ unsigned long addr = b | 0xFC000000UL; |
10042 |
++ |
10043 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
10044 |
++ err = get_user(rlwinm, (unsigned int *)addr); |
10045 |
++ err |= get_user(add, (unsigned int *)(addr+4)); |
10046 |
++ err |= get_user(li2, (unsigned int *)(addr+8)); |
10047 |
++ err |= get_user(addis2, (unsigned int *)(addr+12)); |
10048 |
++ err |= get_user(mtctr, (unsigned int *)(addr+16)); |
10049 |
++ err |= get_user(li3, (unsigned int *)(addr+20)); |
10050 |
++ err |= get_user(addis3, (unsigned int *)(addr+24)); |
10051 |
++ err |= get_user(bctr, (unsigned int *)(addr+28)); |
10052 |
++ |
10053 |
++ if (err) |
10054 |
++ break; |
10055 |
++ |
10056 |
++ if (rlwinm == 0x556C083CU && |
10057 |
++ add == 0x7D6C5A14U && |
10058 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
10059 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
10060 |
++ mtctr == 0x7D8903A6U && |
10061 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
10062 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
10063 |
++ bctr == 0x4E800420U) |
10064 |
++ { |
10065 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10066 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10067 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
10068 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10069 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
10070 |
++ regs->nip = regs->ctr; |
10071 |
++ return 4; |
10072 |
++ } |
10073 |
++ } |
10074 |
++ } while (0); |
10075 |
++ |
10076 |
++#if 0 |
10077 |
++ do { /* PaX: unpatched PLT emulation #2 */ |
10078 |
++ unsigned int lis, lwzu, b, bctr; |
10079 |
++ |
10080 |
++ err = get_user(lis, (unsigned int *)regs->nip); |
10081 |
++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4)); |
10082 |
++ err |= get_user(b, (unsigned int *)(regs->nip+8)); |
10083 |
++ err |= get_user(bctr, (unsigned int *)(regs->nip+12)); |
10084 |
++ |
10085 |
++ if (err) |
10086 |
++ break; |
10087 |
++ |
10088 |
++ if ((lis & 0xFFFF0000U) == 0x39600000U && |
10089 |
++ (lwzu & 0xU) == 0xU && |
10090 |
++ (b & 0xFC000003U) == 0x48000000U && |
10091 |
++ bctr == 0x4E800420U) |
10092 |
++ { |
10093 |
++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
10094 |
++ unsigned long addr = b | 0xFC000000UL; |
10095 |
++ |
10096 |
++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
10097 |
++ err = get_user(addis, (unsigned int*)addr); |
10098 |
++ err |= get_user(addi, (unsigned int*)(addr+4)); |
10099 |
++ err |= get_user(rlwinm, (unsigned int*)(addr+8)); |
10100 |
++ err |= get_user(add, (unsigned int*)(addr+12)); |
10101 |
++ err |= get_user(li2, (unsigned int*)(addr+16)); |
10102 |
++ err |= get_user(addis2, (unsigned int*)(addr+20)); |
10103 |
++ err |= get_user(mtctr, (unsigned int*)(addr+24)); |
10104 |
++ err |= get_user(li3, (unsigned int*)(addr+28)); |
10105 |
++ err |= get_user(addis3, (unsigned int*)(addr+32)); |
10106 |
++ err |= get_user(bctr, (unsigned int*)(addr+36)); |
10107 |
++ |
10108 |
++ if (err) |
10109 |
++ break; |
10110 |
++ |
10111 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
10112 |
++ (addi & 0xFFFF0000U) == 0x396B0000U && |
10113 |
++ rlwinm == 0x556C083CU && |
10114 |
++ add == 0x7D6C5A14U && |
10115 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
10116 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
10117 |
++ mtctr == 0x7D8903A6U && |
10118 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
10119 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
10120 |
++ bctr == 0x4E800420U) |
10121 |
++ { |
10122 |
++ regs->gpr[PT_R11] = |
10123 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10124 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10125 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
10126 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10127 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
10128 |
++ regs->nip = regs->ctr; |
10129 |
++ return 4; |
10130 |
++ } |
10131 |
++ } |
10132 |
++ } while (0); |
10133 |
++#endif |
10134 |
++ |
10135 |
++ do { /* PaX: unpatched PLT emulation #3 */ |
10136 |
++ unsigned int li, b; |
10137 |
++ |
10138 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10139 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
10140 |
++ |
10141 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
10142 |
++ unsigned int addis, lwz, mtctr, bctr; |
10143 |
++ unsigned long addr = b | 0xFC000000UL; |
10144 |
++ |
10145 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
10146 |
++ err = get_user(addis, (unsigned int *)addr); |
10147 |
++ err |= get_user(lwz, (unsigned int *)(addr+4)); |
10148 |
++ err |= get_user(mtctr, (unsigned int *)(addr+8)); |
10149 |
++ err |= get_user(bctr, (unsigned int *)(addr+12)); |
10150 |
++ |
10151 |
++ if (err) |
10152 |
++ break; |
10153 |
++ |
10154 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
10155 |
++ (lwz & 0xFFFF0000U) == 0x816B0000U && |
10156 |
++ mtctr == 0x7D6903A6U && |
10157 |
++ bctr == 0x4E800420U) |
10158 |
++ { |
10159 |
++ unsigned int r11; |
10160 |
++ |
10161 |
++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10162 |
++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10163 |
++ |
10164 |
++ err = get_user(r11, (unsigned int *)addr); |
10165 |
++ if (err) |
10166 |
++ break; |
10167 |
++ |
10168 |
++ regs->gpr[PT_R11] = r11; |
10169 |
++ regs->ctr = r11; |
10170 |
++ regs->nip = r11; |
10171 |
++ return 4; |
10172 |
++ } |
10173 |
++ } |
10174 |
++ } while (0); |
10175 |
++#endif |
10176 |
++ |
10177 |
++#ifdef CONFIG_PAX_EMUSIGRT |
10178 |
++ do { /* PaX: sigreturn emulation */ |
10179 |
++ unsigned int li, sc; |
10180 |
++ |
10181 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10182 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
10183 |
++ |
10184 |
++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) { |
10185 |
++ struct vm_area_struct *vma; |
10186 |
++ unsigned long call_syscall; |
10187 |
++ |
10188 |
++ down_read(¤t->mm->mmap_sem); |
10189 |
++ call_syscall = current->mm->call_syscall; |
10190 |
++ up_read(¤t->mm->mmap_sem); |
10191 |
++ if (likely(call_syscall)) |
10192 |
++ goto emulate; |
10193 |
++ |
10194 |
++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
10195 |
++ |
10196 |
++ down_write(¤t->mm->mmap_sem); |
10197 |
++ if (current->mm->call_syscall) { |
10198 |
++ call_syscall = current->mm->call_syscall; |
10199 |
++ up_write(¤t->mm->mmap_sem); |
10200 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10201 |
++ goto emulate; |
10202 |
++ } |
10203 |
++ |
10204 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
10205 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
10206 |
++ up_write(¤t->mm->mmap_sem); |
10207 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10208 |
++ return 1; |
10209 |
++ } |
10210 |
++ |
10211 |
++ if (pax_insert_vma(vma, call_syscall)) { |
10212 |
++ up_write(¤t->mm->mmap_sem); |
10213 |
++ kmem_cache_free(vm_area_cachep, vma); |
10214 |
++ return 1; |
10215 |
++ } |
10216 |
++ |
10217 |
++ current->mm->call_syscall = call_syscall; |
10218 |
++ up_write(¤t->mm->mmap_sem); |
10219 |
++ |
10220 |
++emulate: |
10221 |
++ regs->gpr[PT_R0] = __NR_sigreturn; |
10222 |
++ regs->nip = call_syscall; |
10223 |
++ return 5; |
10224 |
++ } |
10225 |
++ } while (0); |
10226 |
++ |
10227 |
++ do { /* PaX: rt_sigreturn emulation */ |
10228 |
++ unsigned int li, sc; |
10229 |
++ |
10230 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10231 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
10232 |
++ |
10233 |
++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) { |
10234 |
++ struct vm_area_struct *vma; |
10235 |
++ unsigned int call_syscall; |
10236 |
++ |
10237 |
++ down_read(¤t->mm->mmap_sem); |
10238 |
++ call_syscall = current->mm->call_syscall; |
10239 |
++ up_read(¤t->mm->mmap_sem); |
10240 |
++ if (likely(call_syscall)) |
10241 |
++ goto rt_emulate; |
10242 |
++ |
10243 |
++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
10244 |
++ |
10245 |
++ down_write(¤t->mm->mmap_sem); |
10246 |
++ if (current->mm->call_syscall) { |
10247 |
++ call_syscall = current->mm->call_syscall; |
10248 |
++ up_write(¤t->mm->mmap_sem); |
10249 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10250 |
++ goto rt_emulate; |
10251 |
++ } |
10252 |
++ |
10253 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
10254 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
10255 |
++ up_write(¤t->mm->mmap_sem); |
10256 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10257 |
++ return 1; |
10258 |
++ } |
10259 |
++ |
10260 |
++ if (pax_insert_vma(vma, call_syscall)) { |
10261 |
++ up_write(¤t->mm->mmap_sem); |
10262 |
++ kmem_cache_free(vm_area_cachep, vma); |
10263 |
++ return 1; |
10264 |
++ } |
10265 |
++ |
10266 |
++ current->mm->call_syscall = call_syscall; |
10267 |
++ up_write(¤t->mm->mmap_sem); |
10268 |
++ |
10269 |
++rt_emulate: |
10270 |
++ regs->gpr[PT_R0] = __NR_rt_sigreturn; |
10271 |
++ regs->nip = call_syscall; |
10272 |
++ return 6; |
10273 |
++ } |
10274 |
++ } while (0); |
10275 |
++#endif |
10276 |
++ |
10277 |
++ return 1; |
10278 |
++} |
10279 |
++ |
10280 |
++void pax_report_insns(void *pc, void *sp) |
10281 |
++{ |
10282 |
++ unsigned long i; |
10283 |
++ |
10284 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
10285 |
++ for (i = 0; i < 5; i++) { |
10286 |
++ unsigned int c; |
10287 |
++ if (get_user(c, (unsigned int *)pc+i)) |
10288 |
++ printk("???????? "); |
10289 |
++ else |
10290 |
++ printk("%08x ", c); |
10291 |
++ } |
10292 |
++ printk("\n"); |
10293 |
++} |
10294 |
++#endif |
10295 |
++ |
10296 |
+ /* |
10297 |
+ * Check whether the instruction at regs->nip is a store using |
10298 |
+ * an update addressing form which will update r1. |
10299 |
+@@ -157,7 +521,7 @@ int __kprobes do_page_fault(struct pt_re |
10300 |
+ * indicate errors in DSISR but can validly be set in SRR1. |
10301 |
+ */ |
10302 |
+ if (trap == 0x400) |
10303 |
+- error_code &= 0x48200000; |
10304 |
++ error_code &= 0x58200000; |
10305 |
+ else |
10306 |
+ is_write = error_code & DSISR_ISSTORE; |
10307 |
+ #else |
10308 |
+@@ -357,6 +721,37 @@ bad_area: |
10309 |
+ bad_area_nosemaphore: |
10310 |
+ /* User mode accesses cause a SIGSEGV */ |
10311 |
+ if (user_mode(regs)) { |
10312 |
++ |
10313 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10314 |
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { |
10315 |
++#ifdef CONFIG_PPC64 |
10316 |
++ if (is_exec && (error_code & DSISR_PROTFAULT)) { |
10317 |
++#else |
10318 |
++ if (is_exec && regs->nip == address) { |
10319 |
++#endif |
10320 |
++ switch (pax_handle_fetch_fault(regs)) { |
10321 |
++ |
10322 |
++#ifdef CONFIG_PAX_EMUPLT |
10323 |
++ case 2: |
10324 |
++ case 3: |
10325 |
++ case 4: |
10326 |
++ return 0; |
10327 |
++#endif |
10328 |
++ |
10329 |
++#ifdef CONFIG_PAX_EMUSIGRT |
10330 |
++ case 5: |
10331 |
++ case 6: |
10332 |
++ return 0; |
10333 |
++#endif |
10334 |
++ |
10335 |
++ } |
10336 |
++ |
10337 |
++ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]); |
10338 |
++ do_exit(SIGKILL); |
10339 |
++ } |
10340 |
++ } |
10341 |
++#endif |
10342 |
++ |
10343 |
+ _exception(SIGSEGV, regs, code, address); |
10344 |
+ return 0; |
10345 |
+ } |
10346 |
+diff -Nurp linux-2.6.23.15/arch/powerpc/mm/mmap.c linux-2.6.23.15-grsec/arch/powerpc/mm/mmap.c |
10347 |
+--- linux-2.6.23.15/arch/powerpc/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100 |
10348 |
++++ linux-2.6.23.15-grsec/arch/powerpc/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000 |
10349 |
+@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str |
10350 |
+ */ |
10351 |
+ if (mmap_is_legacy()) { |
10352 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
10353 |
++ |
10354 |
++#ifdef CONFIG_PAX_RANDMMAP |
10355 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
10356 |
++ mm->mmap_base += mm->delta_mmap; |
10357 |
++#endif |
10358 |
++ |
10359 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
10360 |
+ mm->unmap_area = arch_unmap_area; |
10361 |
+ } else { |
10362 |
+ mm->mmap_base = mmap_base(); |
10363 |
++ |
10364 |
++#ifdef CONFIG_PAX_RANDMMAP |
10365 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
10366 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
10367 |
++#endif |
10368 |
++ |
10369 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
10370 |
+ mm->unmap_area = arch_unmap_area_topdown; |
10371 |
+ } |
10372 |
+diff -Nurp linux-2.6.23.15/arch/ppc/mm/fault.c linux-2.6.23.15-grsec/arch/ppc/mm/fault.c |
10373 |
+--- linux-2.6.23.15/arch/ppc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
10374 |
++++ linux-2.6.23.15-grsec/arch/ppc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
10375 |
+@@ -25,6 +25,11 @@ |
10376 |
+ #include <linux/interrupt.h> |
10377 |
+ #include <linux/highmem.h> |
10378 |
+ #include <linux/module.h> |
10379 |
++#include <linux/slab.h> |
10380 |
++#include <linux/pagemap.h> |
10381 |
++#include <linux/compiler.h> |
10382 |
++#include <linux/binfmts.h> |
10383 |
++#include <linux/unistd.h> |
10384 |
+ |
10385 |
+ #include <asm/page.h> |
10386 |
+ #include <asm/pgtable.h> |
10387 |
+@@ -48,6 +53,364 @@ unsigned long pte_misses; /* updated by |
10388 |
+ unsigned long pte_errors; /* updated by do_page_fault() */ |
10389 |
+ unsigned int probingmem; |
10390 |
+ |
10391 |
++#ifdef CONFIG_PAX_EMUSIGRT |
10392 |
++void pax_syscall_close(struct vm_area_struct *vma) |
10393 |
++{ |
10394 |
++ vma->vm_mm->call_syscall = 0UL; |
10395 |
++} |
10396 |
++ |
10397 |
++static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
10398 |
++{ |
10399 |
++ struct page *page; |
10400 |
++ unsigned int *kaddr; |
10401 |
++ |
10402 |
++ page = alloc_page(GFP_HIGHUSER); |
10403 |
++ if (!page) |
10404 |
++ return NOPAGE_OOM; |
10405 |
++ |
10406 |
++ kaddr = kmap(page); |
10407 |
++ memset(kaddr, 0, PAGE_SIZE); |
10408 |
++ kaddr[0] = 0x44000002U; /* sc */ |
10409 |
++ __flush_dcache_icache(kaddr); |
10410 |
++ kunmap(page); |
10411 |
++ if (type) |
10412 |
++ *type = VM_FAULT_MAJOR; |
10413 |
++ return page; |
10414 |
++} |
10415 |
++ |
10416 |
++static struct vm_operations_struct pax_vm_ops = { |
10417 |
++ .close = pax_syscall_close, |
10418 |
++ .nopage = pax_syscall_nopage, |
10419 |
++}; |
10420 |
++ |
10421 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
10422 |
++{ |
10423 |
++ int ret; |
10424 |
++ |
10425 |
++ memset(vma, 0, sizeof(*vma)); |
10426 |
++ vma->vm_mm = current->mm; |
10427 |
++ vma->vm_start = addr; |
10428 |
++ vma->vm_end = addr + PAGE_SIZE; |
10429 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
10430 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
10431 |
++ vma->vm_ops = &pax_vm_ops; |
10432 |
++ |
10433 |
++ ret = insert_vm_struct(current->mm, vma); |
10434 |
++ if (ret) |
10435 |
++ return ret; |
10436 |
++ |
10437 |
++ ++current->mm->total_vm; |
10438 |
++ return 0; |
10439 |
++} |
10440 |
++#endif |
10441 |
++ |
10442 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10443 |
++/* |
10444 |
++ * PaX: decide what to do with offenders (regs->nip = fault address) |
10445 |
++ * |
10446 |
++ * returns 1 when task should be killed |
10447 |
++ * 2 when patched GOT trampoline was detected |
10448 |
++ * 3 when patched PLT trampoline was detected |
10449 |
++ * 4 when unpatched PLT trampoline was detected |
10450 |
++ * 5 when sigreturn trampoline was detected |
10451 |
++ * 6 when rt_sigreturn trampoline was detected |
10452 |
++ */ |
10453 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
10454 |
++{ |
10455 |
++ |
10456 |
++#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT) |
10457 |
++ int err; |
10458 |
++#endif |
10459 |
++ |
10460 |
++#ifdef CONFIG_PAX_EMUPLT |
10461 |
++ do { /* PaX: patched GOT emulation */ |
10462 |
++ unsigned int blrl; |
10463 |
++ |
10464 |
++ err = get_user(blrl, (unsigned int *)regs->nip); |
10465 |
++ |
10466 |
++ if (!err && blrl == 0x4E800021U) { |
10467 |
++ unsigned long temp = regs->nip; |
10468 |
++ |
10469 |
++ regs->nip = regs->link & 0xFFFFFFFCUL; |
10470 |
++ regs->link = temp + 4UL; |
10471 |
++ return 2; |
10472 |
++ } |
10473 |
++ } while (0); |
10474 |
++ |
10475 |
++ do { /* PaX: patched PLT emulation #1 */ |
10476 |
++ unsigned int b; |
10477 |
++ |
10478 |
++ err = get_user(b, (unsigned int *)regs->nip); |
10479 |
++ |
10480 |
++ if (!err && (b & 0xFC000003U) == 0x48000000U) { |
10481 |
++ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL); |
10482 |
++ return 3; |
10483 |
++ } |
10484 |
++ } while (0); |
10485 |
++ |
10486 |
++ do { /* PaX: unpatched PLT emulation #1 */ |
10487 |
++ unsigned int li, b; |
10488 |
++ |
10489 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10490 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
10491 |
++ |
10492 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
10493 |
++ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
10494 |
++ unsigned long addr = b | 0xFC000000UL; |
10495 |
++ |
10496 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
10497 |
++ err = get_user(rlwinm, (unsigned int *)addr); |
10498 |
++ err |= get_user(add, (unsigned int *)(addr+4)); |
10499 |
++ err |= get_user(li2, (unsigned int *)(addr+8)); |
10500 |
++ err |= get_user(addis2, (unsigned int *)(addr+12)); |
10501 |
++ err |= get_user(mtctr, (unsigned int *)(addr+16)); |
10502 |
++ err |= get_user(li3, (unsigned int *)(addr+20)); |
10503 |
++ err |= get_user(addis3, (unsigned int *)(addr+24)); |
10504 |
++ err |= get_user(bctr, (unsigned int *)(addr+28)); |
10505 |
++ |
10506 |
++ if (err) |
10507 |
++ break; |
10508 |
++ |
10509 |
++ if (rlwinm == 0x556C083CU && |
10510 |
++ add == 0x7D6C5A14U && |
10511 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
10512 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
10513 |
++ mtctr == 0x7D8903A6U && |
10514 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
10515 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
10516 |
++ bctr == 0x4E800420U) |
10517 |
++ { |
10518 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10519 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10520 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
10521 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10522 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
10523 |
++ regs->nip = regs->ctr; |
10524 |
++ return 4; |
10525 |
++ } |
10526 |
++ } |
10527 |
++ } while (0); |
10528 |
++ |
10529 |
++#if 0 |
10530 |
++ do { /* PaX: unpatched PLT emulation #2 */ |
10531 |
++ unsigned int lis, lwzu, b, bctr; |
10532 |
++ |
10533 |
++ err = get_user(lis, (unsigned int *)regs->nip); |
10534 |
++ err |= get_user(lwzu, (unsigned int *)(regs->nip+4)); |
10535 |
++ err |= get_user(b, (unsigned int *)(regs->nip+8)); |
10536 |
++ err |= get_user(bctr, (unsigned int *)(regs->nip+12)); |
10537 |
++ |
10538 |
++ if (err) |
10539 |
++ break; |
10540 |
++ |
10541 |
++ if ((lis & 0xFFFF0000U) == 0x39600000U && |
10542 |
++ (lwzu & 0xU) == 0xU && |
10543 |
++ (b & 0xFC000003U) == 0x48000000U && |
10544 |
++ bctr == 0x4E800420U) |
10545 |
++ { |
10546 |
++ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; |
10547 |
++ unsigned long addr = b | 0xFC000000UL; |
10548 |
++ |
10549 |
++ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
10550 |
++ err = get_user(addis, (unsigned int*)addr); |
10551 |
++ err |= get_user(addi, (unsigned int*)(addr+4)); |
10552 |
++ err |= get_user(rlwinm, (unsigned int*)(addr+8)); |
10553 |
++ err |= get_user(add, (unsigned int*)(addr+12)); |
10554 |
++ err |= get_user(li2, (unsigned int*)(addr+16)); |
10555 |
++ err |= get_user(addis2, (unsigned int*)(addr+20)); |
10556 |
++ err |= get_user(mtctr, (unsigned int*)(addr+24)); |
10557 |
++ err |= get_user(li3, (unsigned int*)(addr+28)); |
10558 |
++ err |= get_user(addis3, (unsigned int*)(addr+32)); |
10559 |
++ err |= get_user(bctr, (unsigned int*)(addr+36)); |
10560 |
++ |
10561 |
++ if (err) |
10562 |
++ break; |
10563 |
++ |
10564 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
10565 |
++ (addi & 0xFFFF0000U) == 0x396B0000U && |
10566 |
++ rlwinm == 0x556C083CU && |
10567 |
++ add == 0x7D6C5A14U && |
10568 |
++ (li2 & 0xFFFF0000U) == 0x39800000U && |
10569 |
++ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && |
10570 |
++ mtctr == 0x7D8903A6U && |
10571 |
++ (li3 & 0xFFFF0000U) == 0x39800000U && |
10572 |
++ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && |
10573 |
++ bctr == 0x4E800420U) |
10574 |
++ { |
10575 |
++ regs->gpr[PT_R11] = |
10576 |
++ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10577 |
++ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10578 |
++ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; |
10579 |
++ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10580 |
++ regs->ctr += (addis2 & 0xFFFFU) << 16; |
10581 |
++ regs->nip = regs->ctr; |
10582 |
++ return 4; |
10583 |
++ } |
10584 |
++ } |
10585 |
++ } while (0); |
10586 |
++#endif |
10587 |
++ |
10588 |
++ do { /* PaX: unpatched PLT emulation #3 */ |
10589 |
++ unsigned int li, b; |
10590 |
++ |
10591 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10592 |
++ err |= get_user(b, (unsigned int *)(regs->nip+4)); |
10593 |
++ |
10594 |
++ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { |
10595 |
++ unsigned int addis, lwz, mtctr, bctr; |
10596 |
++ unsigned long addr = b | 0xFC000000UL; |
10597 |
++ |
10598 |
++ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); |
10599 |
++ err = get_user(addis, (unsigned int *)addr); |
10600 |
++ err |= get_user(lwz, (unsigned int *)(addr+4)); |
10601 |
++ err |= get_user(mtctr, (unsigned int *)(addr+8)); |
10602 |
++ err |= get_user(bctr, (unsigned int *)(addr+12)); |
10603 |
++ |
10604 |
++ if (err) |
10605 |
++ break; |
10606 |
++ |
10607 |
++ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && |
10608 |
++ (lwz & 0xFFFF0000U) == 0x816B0000U && |
10609 |
++ mtctr == 0x7D6903A6U && |
10610 |
++ bctr == 0x4E800420U) |
10611 |
++ { |
10612 |
++ unsigned int r11; |
10613 |
++ |
10614 |
++ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10615 |
++ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); |
10616 |
++ |
10617 |
++ err = get_user(r11, (unsigned int *)addr); |
10618 |
++ if (err) |
10619 |
++ break; |
10620 |
++ |
10621 |
++ regs->gpr[PT_R11] = r11; |
10622 |
++ regs->ctr = r11; |
10623 |
++ regs->nip = r11; |
10624 |
++ return 4; |
10625 |
++ } |
10626 |
++ } |
10627 |
++ } while (0); |
10628 |
++#endif |
10629 |
++ |
10630 |
++#ifdef CONFIG_PAX_EMUSIGRT |
10631 |
++ do { /* PaX: sigreturn emulation */ |
10632 |
++ unsigned int li, sc; |
10633 |
++ |
10634 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10635 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
10636 |
++ |
10637 |
++ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) { |
10638 |
++ struct vm_area_struct *vma; |
10639 |
++ unsigned long call_syscall; |
10640 |
++ |
10641 |
++ down_read(¤t->mm->mmap_sem); |
10642 |
++ call_syscall = current->mm->call_syscall; |
10643 |
++ up_read(¤t->mm->mmap_sem); |
10644 |
++ if (likely(call_syscall)) |
10645 |
++ goto emulate; |
10646 |
++ |
10647 |
++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
10648 |
++ |
10649 |
++ down_write(¤t->mm->mmap_sem); |
10650 |
++ if (current->mm->call_syscall) { |
10651 |
++ call_syscall = current->mm->call_syscall; |
10652 |
++ up_write(¤t->mm->mmap_sem); |
10653 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10654 |
++ goto emulate; |
10655 |
++ } |
10656 |
++ |
10657 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
10658 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
10659 |
++ up_write(¤t->mm->mmap_sem); |
10660 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10661 |
++ return 1; |
10662 |
++ } |
10663 |
++ |
10664 |
++ if (pax_insert_vma(vma, call_syscall)) { |
10665 |
++ up_write(¤t->mm->mmap_sem); |
10666 |
++ kmem_cache_free(vm_area_cachep, vma); |
10667 |
++ return 1; |
10668 |
++ } |
10669 |
++ |
10670 |
++ current->mm->call_syscall = call_syscall; |
10671 |
++ up_write(¤t->mm->mmap_sem); |
10672 |
++ |
10673 |
++emulate: |
10674 |
++ regs->gpr[PT_R0] = __NR_sigreturn; |
10675 |
++ regs->nip = call_syscall; |
10676 |
++ return 5; |
10677 |
++ } |
10678 |
++ } while (0); |
10679 |
++ |
10680 |
++ do { /* PaX: rt_sigreturn emulation */ |
10681 |
++ unsigned int li, sc; |
10682 |
++ |
10683 |
++ err = get_user(li, (unsigned int *)regs->nip); |
10684 |
++ err |= get_user(sc, (unsigned int *)(regs->nip+4)); |
10685 |
++ |
10686 |
++ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) { |
10687 |
++ struct vm_area_struct *vma; |
10688 |
++ unsigned int call_syscall; |
10689 |
++ |
10690 |
++ down_read(¤t->mm->mmap_sem); |
10691 |
++ call_syscall = current->mm->call_syscall; |
10692 |
++ up_read(¤t->mm->mmap_sem); |
10693 |
++ if (likely(call_syscall)) |
10694 |
++ goto rt_emulate; |
10695 |
++ |
10696 |
++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
10697 |
++ |
10698 |
++ down_write(¤t->mm->mmap_sem); |
10699 |
++ if (current->mm->call_syscall) { |
10700 |
++ call_syscall = current->mm->call_syscall; |
10701 |
++ up_write(¤t->mm->mmap_sem); |
10702 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10703 |
++ goto rt_emulate; |
10704 |
++ } |
10705 |
++ |
10706 |
++ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
10707 |
++ if (!vma || (call_syscall & ~PAGE_MASK)) { |
10708 |
++ up_write(¤t->mm->mmap_sem); |
10709 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
10710 |
++ return 1; |
10711 |
++ } |
10712 |
++ |
10713 |
++ if (pax_insert_vma(vma, call_syscall)) { |
10714 |
++ up_write(¤t->mm->mmap_sem); |
10715 |
++ kmem_cache_free(vm_area_cachep, vma); |
10716 |
++ return 1; |
10717 |
++ } |
10718 |
++ |
10719 |
++ current->mm->call_syscall = call_syscall; |
10720 |
++ up_write(¤t->mm->mmap_sem); |
10721 |
++ |
10722 |
++rt_emulate: |
10723 |
++ regs->gpr[PT_R0] = __NR_rt_sigreturn; |
10724 |
++ regs->nip = call_syscall; |
10725 |
++ return 6; |
10726 |
++ } |
10727 |
++ } while (0); |
10728 |
++#endif |
10729 |
++ |
10730 |
++ return 1; |
10731 |
++} |
10732 |
++ |
10733 |
++void pax_report_insns(void *pc, void *sp) |
10734 |
++{ |
10735 |
++ unsigned long i; |
10736 |
++ |
10737 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
10738 |
++ for (i = 0; i < 5; i++) { |
10739 |
++ unsigned int c; |
10740 |
++ if (get_user(c, (unsigned int *)pc+i)) |
10741 |
++ printk("???????? "); |
10742 |
++ else |
10743 |
++ printk("%08x ", c); |
10744 |
++ } |
10745 |
++ printk("\n"); |
10746 |
++} |
10747 |
++#endif |
10748 |
++ |
10749 |
+ /* |
10750 |
+ * Check whether the instruction at regs->nip is a store using |
10751 |
+ * an update addressing form which will update r1. |
10752 |
+@@ -109,7 +472,7 @@ int do_page_fault(struct pt_regs *regs, |
10753 |
+ * indicate errors in DSISR but can validly be set in SRR1. |
10754 |
+ */ |
10755 |
+ if (TRAP(regs) == 0x400) |
10756 |
+- error_code &= 0x48200000; |
10757 |
++ error_code &= 0x58200000; |
10758 |
+ else |
10759 |
+ is_write = error_code & 0x02000000; |
10760 |
+ #endif /* CONFIG_4xx || CONFIG_BOOKE */ |
10761 |
+@@ -204,15 +567,14 @@ good_area: |
10762 |
+ pte_t *ptep; |
10763 |
+ pmd_t *pmdp; |
10764 |
+ |
10765 |
+-#if 0 |
10766 |
++#if 1 |
10767 |
+ /* It would be nice to actually enforce the VM execute |
10768 |
+ permission on CPUs which can do so, but far too |
10769 |
+ much stuff in userspace doesn't get the permissions |
10770 |
+ right, so we let any page be executed for now. */ |
10771 |
+ if (! (vma->vm_flags & VM_EXEC)) |
10772 |
+ goto bad_area; |
10773 |
+-#endif |
10774 |
+- |
10775 |
++#else |
10776 |
+ /* Since 4xx/Book-E supports per-page execute permission, |
10777 |
+ * we lazily flush dcache to icache. */ |
10778 |
+ ptep = NULL; |
10779 |
+@@ -235,6 +597,7 @@ good_area: |
10780 |
+ pte_unmap_unlock(ptep, ptl); |
10781 |
+ } |
10782 |
+ #endif |
10783 |
++#endif |
10784 |
+ /* a read */ |
10785 |
+ } else { |
10786 |
+ /* protection fault */ |
10787 |
+@@ -278,6 +641,33 @@ bad_area: |
10788 |
+ |
10789 |
+ /* User mode accesses cause a SIGSEGV */ |
10790 |
+ if (user_mode(regs)) { |
10791 |
++ |
10792 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10793 |
++ if (mm->pax_flags & MF_PAX_PAGEEXEC) { |
10794 |
++ if ((TRAP(regs) == 0x400) && (regs->nip == address)) { |
10795 |
++ switch (pax_handle_fetch_fault(regs)) { |
10796 |
++ |
10797 |
++#ifdef CONFIG_PAX_EMUPLT |
10798 |
++ case 2: |
10799 |
++ case 3: |
10800 |
++ case 4: |
10801 |
++ return 0; |
10802 |
++#endif |
10803 |
++ |
10804 |
++#ifdef CONFIG_PAX_EMUSIGRT |
10805 |
++ case 5: |
10806 |
++ case 6: |
10807 |
++ return 0; |
10808 |
++#endif |
10809 |
++ |
10810 |
++ } |
10811 |
++ |
10812 |
++ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]); |
10813 |
++ do_exit(SIGKILL); |
10814 |
++ } |
10815 |
++ } |
10816 |
++#endif |
10817 |
++ |
10818 |
+ _exception(SIGSEGV, regs, code, address); |
10819 |
+ return 0; |
10820 |
+ } |
10821 |
+diff -Nurp linux-2.6.23.15/arch/s390/kernel/module.c linux-2.6.23.15-grsec/arch/s390/kernel/module.c |
10822 |
+--- linux-2.6.23.15/arch/s390/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
10823 |
++++ linux-2.6.23.15-grsec/arch/s390/kernel/module.c 2008-02-11 10:37:44.000000000 +0000 |
10824 |
+@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr, |
10825 |
+ |
10826 |
+ /* Increase core size by size of got & plt and set start |
10827 |
+ offsets for got and plt. */ |
10828 |
+- me->core_size = ALIGN(me->core_size, 4); |
10829 |
+- me->arch.got_offset = me->core_size; |
10830 |
+- me->core_size += me->arch.got_size; |
10831 |
+- me->arch.plt_offset = me->core_size; |
10832 |
+- me->core_size += me->arch.plt_size; |
10833 |
++ me->core_size_rw = ALIGN(me->core_size_rw, 4); |
10834 |
++ me->arch.got_offset = me->core_size_rw; |
10835 |
++ me->core_size_rw += me->arch.got_size; |
10836 |
++ me->arch.plt_offset = me->core_size_rx; |
10837 |
++ me->core_size_rx += me->arch.plt_size; |
10838 |
+ return 0; |
10839 |
+ } |
10840 |
+ |
10841 |
+@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
10842 |
+ if (info->got_initialized == 0) { |
10843 |
+ Elf_Addr *gotent; |
10844 |
+ |
10845 |
+- gotent = me->module_core + me->arch.got_offset + |
10846 |
++ gotent = me->module_core_rw + me->arch.got_offset + |
10847 |
+ info->got_offset; |
10848 |
+ *gotent = val; |
10849 |
+ info->got_initialized = 1; |
10850 |
+@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
10851 |
+ else if (r_type == R_390_GOTENT || |
10852 |
+ r_type == R_390_GOTPLTENT) |
10853 |
+ *(unsigned int *) loc = |
10854 |
+- (val + (Elf_Addr) me->module_core - loc) >> 1; |
10855 |
++ (val + (Elf_Addr) me->module_core_rw - loc) >> 1; |
10856 |
+ else if (r_type == R_390_GOT64 || |
10857 |
+ r_type == R_390_GOTPLT64) |
10858 |
+ *(unsigned long *) loc = val; |
10859 |
+@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
10860 |
+ case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */ |
10861 |
+ if (info->plt_initialized == 0) { |
10862 |
+ unsigned int *ip; |
10863 |
+- ip = me->module_core + me->arch.plt_offset + |
10864 |
++ ip = me->module_core_rx + me->arch.plt_offset + |
10865 |
+ info->plt_offset; |
10866 |
+ #ifndef CONFIG_64BIT |
10867 |
+ ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */ |
10868 |
+@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
10869 |
+ val = me->arch.plt_offset - me->arch.got_offset + |
10870 |
+ info->plt_offset + rela->r_addend; |
10871 |
+ else |
10872 |
+- val = (Elf_Addr) me->module_core + |
10873 |
++ val = (Elf_Addr) me->module_core_rx + |
10874 |
+ me->arch.plt_offset + info->plt_offset + |
10875 |
+ rela->r_addend - loc; |
10876 |
+ if (r_type == R_390_PLT16DBL) |
10877 |
+@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
10878 |
+ case R_390_GOTOFF32: /* 32 bit offset to GOT. */ |
10879 |
+ case R_390_GOTOFF64: /* 64 bit offset to GOT. */ |
10880 |
+ val = val + rela->r_addend - |
10881 |
+- ((Elf_Addr) me->module_core + me->arch.got_offset); |
10882 |
++ ((Elf_Addr) me->module_core_rw + me->arch.got_offset); |
10883 |
+ if (r_type == R_390_GOTOFF16) |
10884 |
+ *(unsigned short *) loc = val; |
10885 |
+ else if (r_type == R_390_GOTOFF32) |
10886 |
+@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base |
10887 |
+ break; |
10888 |
+ case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */ |
10889 |
+ case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */ |
10890 |
+- val = (Elf_Addr) me->module_core + me->arch.got_offset + |
10891 |
++ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset + |
10892 |
+ rela->r_addend - loc; |
10893 |
+ if (r_type == R_390_GOTPC) |
10894 |
+ *(unsigned int *) loc = val; |
10895 |
+diff -Nurp linux-2.6.23.15/arch/sparc/Makefile linux-2.6.23.15-grsec/arch/sparc/Makefile |
10896 |
+--- linux-2.6.23.15/arch/sparc/Makefile 2007-10-09 21:31:38.000000000 +0100 |
10897 |
++++ linux-2.6.23.15-grsec/arch/sparc/Makefile 2008-02-11 10:37:44.000000000 +0000 |
10898 |
+@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc |
10899 |
+ # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-) |
10900 |
+ INIT_Y := $(patsubst %/, %/built-in.o, $(init-y)) |
10901 |
+ CORE_Y := $(core-y) |
10902 |
+-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ |
10903 |
++CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/ |
10904 |
+ CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y)) |
10905 |
+ DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y)) |
10906 |
+ NET_Y := $(patsubst %/, %/built-in.o, $(net-y)) |
10907 |
+diff -Nurp linux-2.6.23.15/arch/sparc/kernel/ptrace.c linux-2.6.23.15-grsec/arch/sparc/kernel/ptrace.c |
10908 |
+--- linux-2.6.23.15/arch/sparc/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100 |
10909 |
++++ linux-2.6.23.15-grsec/arch/sparc/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000 |
10910 |
+@@ -19,6 +19,7 @@ |
10911 |
+ #include <linux/smp_lock.h> |
10912 |
+ #include <linux/security.h> |
10913 |
+ #include <linux/signal.h> |
10914 |
++#include <linux/grsecurity.h> |
10915 |
+ |
10916 |
+ #include <asm/pgtable.h> |
10917 |
+ #include <asm/system.h> |
10918 |
+@@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs |
10919 |
+ goto out; |
10920 |
+ } |
10921 |
+ |
10922 |
++ if (gr_handle_ptrace(child, request)) { |
10923 |
++ pt_error_return(regs, EPERM); |
10924 |
++ goto out_tsk; |
10925 |
++ } |
10926 |
++ |
10927 |
+ if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) |
10928 |
+ || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { |
10929 |
+ if (ptrace_attach(child)) { |
10930 |
+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 |
10931 |
+--- linux-2.6.23.15/arch/sparc/kernel/sys_sparc.c 2007-10-09 21:31:38.000000000 +0100 |
10932 |
++++ linux-2.6.23.15-grsec/arch/sparc/kernel/sys_sparc.c 2008-02-11 10:37:44.000000000 +0000 |
10933 |
+@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str |
10934 |
+ if (ARCH_SUN4C_SUN4 && len > 0x20000000) |
10935 |
+ return -ENOMEM; |
10936 |
+ if (!addr) |
10937 |
+- addr = TASK_UNMAPPED_BASE; |
10938 |
++ addr = current->mm->mmap_base; |
10939 |
+ |
10940 |
+ if (flags & MAP_SHARED) |
10941 |
+ addr = COLOUR_ALIGN(addr); |
10942 |
+diff -Nurp linux-2.6.23.15/arch/sparc/mm/fault.c linux-2.6.23.15-grsec/arch/sparc/mm/fault.c |
10943 |
+--- linux-2.6.23.15/arch/sparc/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
10944 |
++++ linux-2.6.23.15-grsec/arch/sparc/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
10945 |
+@@ -21,6 +21,10 @@ |
10946 |
+ #include <linux/interrupt.h> |
10947 |
+ #include <linux/module.h> |
10948 |
+ #include <linux/kdebug.h> |
10949 |
++#include <linux/slab.h> |
10950 |
++#include <linux/pagemap.h> |
10951 |
++#include <linux/compiler.h> |
10952 |
++#include <linux/binfmts.h> |
10953 |
+ |
10954 |
+ #include <asm/system.h> |
10955 |
+ #include <asm/page.h> |
10956 |
+@@ -216,6 +220,252 @@ static unsigned long compute_si_addr(str |
10957 |
+ return safe_compute_effective_address(regs, insn); |
10958 |
+ } |
10959 |
+ |
10960 |
++#ifdef CONFIG_PAX_PAGEEXEC |
10961 |
++void pax_emuplt_close(struct vm_area_struct *vma) |
10962 |
++{ |
10963 |
++ vma->vm_mm->call_dl_resolve = 0UL; |
10964 |
++} |
10965 |
++ |
10966 |
++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
10967 |
++{ |
10968 |
++ struct page *page; |
10969 |
++ unsigned int *kaddr; |
10970 |
++ |
10971 |
++ page = alloc_page(GFP_HIGHUSER); |
10972 |
++ if (!page) |
10973 |
++ return NOPAGE_OOM; |
10974 |
++ |
10975 |
++ kaddr = kmap(page); |
10976 |
++ memset(kaddr, 0, PAGE_SIZE); |
10977 |
++ kaddr[0] = 0x9DE3BFA8U; /* save */ |
10978 |
++ flush_dcache_page(page); |
10979 |
++ kunmap(page); |
10980 |
++ if (type) |
10981 |
++ *type = VM_FAULT_MAJOR; |
10982 |
++ |
10983 |
++ return page; |
10984 |
++} |
10985 |
++ |
10986 |
++static struct vm_operations_struct pax_vm_ops = { |
10987 |
++ .close = pax_emuplt_close, |
10988 |
++ .nopage = pax_emuplt_nopage, |
10989 |
++}; |
10990 |
++ |
10991 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
10992 |
++{ |
10993 |
++ int ret; |
10994 |
++ |
10995 |
++ memset(vma, 0, sizeof(*vma)); |
10996 |
++ vma->vm_mm = current->mm; |
10997 |
++ vma->vm_start = addr; |
10998 |
++ vma->vm_end = addr + PAGE_SIZE; |
10999 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
11000 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
11001 |
++ vma->vm_ops = &pax_vm_ops; |
11002 |
++ |
11003 |
++ ret = insert_vm_struct(current->mm, vma); |
11004 |
++ if (ret) |
11005 |
++ return ret; |
11006 |
++ |
11007 |
++ ++current->mm->total_vm; |
11008 |
++ return 0; |
11009 |
++} |
11010 |
++ |
11011 |
++/* |
11012 |
++ * PaX: decide what to do with offenders (regs->pc = fault address) |
11013 |
++ * |
11014 |
++ * returns 1 when task should be killed |
11015 |
++ * 2 when patched PLT trampoline was detected |
11016 |
++ * 3 when unpatched PLT trampoline was detected |
11017 |
++ */ |
11018 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
11019 |
++{ |
11020 |
++ |
11021 |
++#ifdef CONFIG_PAX_EMUPLT |
11022 |
++ int err; |
11023 |
++ |
11024 |
++ do { /* PaX: patched PLT emulation #1 */ |
11025 |
++ unsigned int sethi1, sethi2, jmpl; |
11026 |
++ |
11027 |
++ err = get_user(sethi1, (unsigned int *)regs->pc); |
11028 |
++ err |= get_user(sethi2, (unsigned int *)(regs->pc+4)); |
11029 |
++ err |= get_user(jmpl, (unsigned int *)(regs->pc+8)); |
11030 |
++ |
11031 |
++ if (err) |
11032 |
++ break; |
11033 |
++ |
11034 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
11035 |
++ (sethi2 & 0xFFC00000U) == 0x03000000U && |
11036 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U) |
11037 |
++ { |
11038 |
++ unsigned int addr; |
11039 |
++ |
11040 |
++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; |
11041 |
++ addr = regs->u_regs[UREG_G1]; |
11042 |
++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); |
11043 |
++ regs->pc = addr; |
11044 |
++ regs->npc = addr+4; |
11045 |
++ return 2; |
11046 |
++ } |
11047 |
++ } while (0); |
11048 |
++ |
11049 |
++ { /* PaX: patched PLT emulation #2 */ |
11050 |
++ unsigned int ba; |
11051 |
++ |
11052 |
++ err = get_user(ba, (unsigned int *)regs->pc); |
11053 |
++ |
11054 |
++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { |
11055 |
++ unsigned int addr; |
11056 |
++ |
11057 |
++ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); |
11058 |
++ regs->pc = addr; |
11059 |
++ regs->npc = addr+4; |
11060 |
++ return 2; |
11061 |
++ } |
11062 |
++ } |
11063 |
++ |
11064 |
++ do { /* PaX: patched PLT emulation #3 */ |
11065 |
++ unsigned int sethi, jmpl, nop; |
11066 |
++ |
11067 |
++ err = get_user(sethi, (unsigned int *)regs->pc); |
11068 |
++ err |= get_user(jmpl, (unsigned int *)(regs->pc+4)); |
11069 |
++ err |= get_user(nop, (unsigned int *)(regs->pc+8)); |
11070 |
++ |
11071 |
++ if (err) |
11072 |
++ break; |
11073 |
++ |
11074 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
11075 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U && |
11076 |
++ nop == 0x01000000U) |
11077 |
++ { |
11078 |
++ unsigned int addr; |
11079 |
++ |
11080 |
++ addr = (sethi & 0x003FFFFFU) << 10; |
11081 |
++ regs->u_regs[UREG_G1] = addr; |
11082 |
++ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); |
11083 |
++ regs->pc = addr; |
11084 |
++ regs->npc = addr+4; |
11085 |
++ return 2; |
11086 |
++ } |
11087 |
++ } while (0); |
11088 |
++ |
11089 |
++ do { /* PaX: unpatched PLT emulation step 1 */ |
11090 |
++ unsigned int sethi, ba, nop; |
11091 |
++ |
11092 |
++ err = get_user(sethi, (unsigned int *)regs->pc); |
11093 |
++ err |= get_user(ba, (unsigned int *)(regs->pc+4)); |
11094 |
++ err |= get_user(nop, (unsigned int *)(regs->pc+8)); |
11095 |
++ |
11096 |
++ if (err) |
11097 |
++ break; |
11098 |
++ |
11099 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
11100 |
++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && |
11101 |
++ nop == 0x01000000U) |
11102 |
++ { |
11103 |
++ unsigned int addr, save, call; |
11104 |
++ |
11105 |
++ if ((ba & 0xFFC00000U) == 0x30800000U) |
11106 |
++ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); |
11107 |
++ else |
11108 |
++ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2); |
11109 |
++ |
11110 |
++ err = get_user(save, (unsigned int *)addr); |
11111 |
++ err |= get_user(call, (unsigned int *)(addr+4)); |
11112 |
++ err |= get_user(nop, (unsigned int *)(addr+8)); |
11113 |
++ if (err) |
11114 |
++ break; |
11115 |
++ |
11116 |
++ if (save == 0x9DE3BFA8U && |
11117 |
++ (call & 0xC0000000U) == 0x40000000U && |
11118 |
++ nop == 0x01000000U) |
11119 |
++ { |
11120 |
++ struct vm_area_struct *vma; |
11121 |
++ unsigned long call_dl_resolve; |
11122 |
++ |
11123 |
++ down_read(¤t->mm->mmap_sem); |
11124 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
11125 |
++ up_read(¤t->mm->mmap_sem); |
11126 |
++ if (likely(call_dl_resolve)) |
11127 |
++ goto emulate; |
11128 |
++ |
11129 |
++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
11130 |
++ |
11131 |
++ down_write(¤t->mm->mmap_sem); |
11132 |
++ if (current->mm->call_dl_resolve) { |
11133 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
11134 |
++ up_write(¤t->mm->mmap_sem); |
11135 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
11136 |
++ goto emulate; |
11137 |
++ } |
11138 |
++ |
11139 |
++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
11140 |
++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { |
11141 |
++ up_write(¤t->mm->mmap_sem); |
11142 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
11143 |
++ return 1; |
11144 |
++ } |
11145 |
++ |
11146 |
++ if (pax_insert_vma(vma, call_dl_resolve)) { |
11147 |
++ up_write(¤t->mm->mmap_sem); |
11148 |
++ kmem_cache_free(vm_area_cachep, vma); |
11149 |
++ return 1; |
11150 |
++ } |
11151 |
++ |
11152 |
++ current->mm->call_dl_resolve = call_dl_resolve; |
11153 |
++ up_write(¤t->mm->mmap_sem); |
11154 |
++ |
11155 |
++emulate: |
11156 |
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; |
11157 |
++ regs->pc = call_dl_resolve; |
11158 |
++ regs->npc = addr+4; |
11159 |
++ return 3; |
11160 |
++ } |
11161 |
++ } |
11162 |
++ } while (0); |
11163 |
++ |
11164 |
++ do { /* PaX: unpatched PLT emulation step 2 */ |
11165 |
++ unsigned int save, call, nop; |
11166 |
++ |
11167 |
++ err = get_user(save, (unsigned int *)(regs->pc-4)); |
11168 |
++ err |= get_user(call, (unsigned int *)regs->pc); |
11169 |
++ err |= get_user(nop, (unsigned int *)(regs->pc+4)); |
11170 |
++ if (err) |
11171 |
++ break; |
11172 |
++ |
11173 |
++ if (save == 0x9DE3BFA8U && |
11174 |
++ (call & 0xC0000000U) == 0x40000000U && |
11175 |
++ nop == 0x01000000U) |
11176 |
++ { |
11177 |
++ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2); |
11178 |
++ |
11179 |
++ regs->u_regs[UREG_RETPC] = regs->pc; |
11180 |
++ regs->pc = dl_resolve; |
11181 |
++ regs->npc = dl_resolve+4; |
11182 |
++ return 3; |
11183 |
++ } |
11184 |
++ } while (0); |
11185 |
++#endif |
11186 |
++ |
11187 |
++ return 1; |
11188 |
++} |
11189 |
++ |
11190 |
++void pax_report_insns(void *pc, void *sp) |
11191 |
++{ |
11192 |
++ unsigned long i; |
11193 |
++ |
11194 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
11195 |
++ for (i = 0; i < 5; i++) { |
11196 |
++ unsigned int c; |
11197 |
++ if (get_user(c, (unsigned int *)pc+i)) |
11198 |
++ printk("???????? "); |
11199 |
++ else |
11200 |
++ printk("%08x ", c); |
11201 |
++ } |
11202 |
++ printk("\n"); |
11203 |
++} |
11204 |
++#endif |
11205 |
++ |
11206 |
+ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, |
11207 |
+ unsigned long address) |
11208 |
+ { |
11209 |
+@@ -280,6 +530,24 @@ good_area: |
11210 |
+ if(!(vma->vm_flags & VM_WRITE)) |
11211 |
+ goto bad_area; |
11212 |
+ } else { |
11213 |
++ |
11214 |
++#ifdef CONFIG_PAX_PAGEEXEC |
11215 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) { |
11216 |
++ up_read(&mm->mmap_sem); |
11217 |
++ switch (pax_handle_fetch_fault(regs)) { |
11218 |
++ |
11219 |
++#ifdef CONFIG_PAX_EMUPLT |
11220 |
++ case 2: |
11221 |
++ case 3: |
11222 |
++ return; |
11223 |
++#endif |
11224 |
++ |
11225 |
++ } |
11226 |
++ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]); |
11227 |
++ do_exit(SIGKILL); |
11228 |
++ } |
11229 |
++#endif |
11230 |
++ |
11231 |
+ /* Allow reads even for write-only mappings */ |
11232 |
+ if(!(vma->vm_flags & (VM_READ | VM_EXEC))) |
11233 |
+ goto bad_area; |
11234 |
+diff -Nurp linux-2.6.23.15/arch/sparc/mm/init.c linux-2.6.23.15-grsec/arch/sparc/mm/init.c |
11235 |
+--- linux-2.6.23.15/arch/sparc/mm/init.c 2007-10-09 21:31:38.000000000 +0100 |
11236 |
++++ linux-2.6.23.15-grsec/arch/sparc/mm/init.c 2008-02-11 10:37:44.000000000 +0000 |
11237 |
+@@ -336,17 +336,17 @@ void __init paging_init(void) |
11238 |
+ |
11239 |
+ /* Initialize the protection map with non-constant, MMU dependent values. */ |
11240 |
+ protection_map[0] = PAGE_NONE; |
11241 |
+- protection_map[1] = PAGE_READONLY; |
11242 |
+- protection_map[2] = PAGE_COPY; |
11243 |
+- protection_map[3] = PAGE_COPY; |
11244 |
++ protection_map[1] = PAGE_READONLY_NOEXEC; |
11245 |
++ protection_map[2] = PAGE_COPY_NOEXEC; |
11246 |
++ protection_map[3] = PAGE_COPY_NOEXEC; |
11247 |
+ protection_map[4] = PAGE_READONLY; |
11248 |
+ protection_map[5] = PAGE_READONLY; |
11249 |
+ protection_map[6] = PAGE_COPY; |
11250 |
+ protection_map[7] = PAGE_COPY; |
11251 |
+ protection_map[8] = PAGE_NONE; |
11252 |
+- protection_map[9] = PAGE_READONLY; |
11253 |
+- protection_map[10] = PAGE_SHARED; |
11254 |
+- protection_map[11] = PAGE_SHARED; |
11255 |
++ protection_map[9] = PAGE_READONLY_NOEXEC; |
11256 |
++ protection_map[10] = PAGE_SHARED_NOEXEC; |
11257 |
++ protection_map[11] = PAGE_SHARED_NOEXEC; |
11258 |
+ protection_map[12] = PAGE_READONLY; |
11259 |
+ protection_map[13] = PAGE_READONLY; |
11260 |
+ protection_map[14] = PAGE_SHARED; |
11261 |
+diff -Nurp linux-2.6.23.15/arch/sparc/mm/srmmu.c linux-2.6.23.15-grsec/arch/sparc/mm/srmmu.c |
11262 |
+--- linux-2.6.23.15/arch/sparc/mm/srmmu.c 2007-10-09 21:31:38.000000000 +0100 |
11263 |
++++ linux-2.6.23.15-grsec/arch/sparc/mm/srmmu.c 2008-02-11 10:37:44.000000000 +0000 |
11264 |
+@@ -2157,6 +2157,13 @@ void __init ld_mmu_srmmu(void) |
11265 |
+ PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED); |
11266 |
+ BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); |
11267 |
+ BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); |
11268 |
++ |
11269 |
++#ifdef CONFIG_PAX_PAGEEXEC |
11270 |
++ PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC); |
11271 |
++ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC)); |
11272 |
++ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC)); |
11273 |
++#endif |
11274 |
++ |
11275 |
+ BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); |
11276 |
+ page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); |
11277 |
+ |
11278 |
+diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/Makefile linux-2.6.23.15-grsec/arch/sparc64/kernel/Makefile |
11279 |
+--- linux-2.6.23.15/arch/sparc64/kernel/Makefile 2007-10-09 21:31:38.000000000 +0100 |
11280 |
++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/Makefile 2008-02-11 10:37:44.000000000 +0000 |
11281 |
+@@ -3,7 +3,7 @@ |
11282 |
+ # |
11283 |
+ |
11284 |
+ EXTRA_AFLAGS := -ansi |
11285 |
+-EXTRA_CFLAGS := -Werror |
11286 |
++#EXTRA_CFLAGS := -Werror |
11287 |
+ |
11288 |
+ extra-y := head.o init_task.o vmlinux.lds |
11289 |
+ |
11290 |
+diff -Nurp linux-2.6.23.15/arch/sparc64/kernel/ptrace.c linux-2.6.23.15-grsec/arch/sparc64/kernel/ptrace.c |
11291 |
+--- linux-2.6.23.15/arch/sparc64/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100 |
11292 |
++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/ptrace.c 2008-02-11 10:37:44.000000000 +0000 |
11293 |
+@@ -22,6 +22,7 @@ |
11294 |
+ #include <linux/seccomp.h> |
11295 |
+ #include <linux/audit.h> |
11296 |
+ #include <linux/signal.h> |
11297 |
++#include <linux/grsecurity.h> |
11298 |
+ |
11299 |
+ #include <asm/asi.h> |
11300 |
+ #include <asm/pgtable.h> |
11301 |
+@@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs |
11302 |
+ goto out; |
11303 |
+ } |
11304 |
+ |
11305 |
++ if (gr_handle_ptrace(child, (long)request)) { |
11306 |
++ pt_error_return(regs, EPERM); |
11307 |
++ goto out_tsk; |
11308 |
++ } |
11309 |
++ |
11310 |
+ if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) |
11311 |
+ || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { |
11312 |
+ if (ptrace_attach(child)) { |
11313 |
+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 |
11314 |
+--- linux-2.6.23.15/arch/sparc64/kernel/sys_sparc.c 2008-02-11 10:36:03.000000000 +0000 |
11315 |
++++ linux-2.6.23.15-grsec/arch/sparc64/kernel/sys_sparc.c 2008-02-11 10:37:44.000000000 +0000 |
11316 |
+@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str |
11317 |
+ /* We do not accept a shared mapping if it would violate |
11318 |
+ * cache aliasing constraints. |
11319 |
+ */ |
11320 |
+- if ((flags & MAP_SHARED) && |
11321 |
++ if ((filp || (flags & MAP_SHARED)) && |
11322 |
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) |
11323 |
+ return -EINVAL; |
11324 |
+ return addr; |
11325 |
+@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str |
11326 |
+ if (filp || (flags & MAP_SHARED)) |
11327 |
+ do_color_align = 1; |
11328 |
+ |
11329 |
++#ifdef CONFIG_PAX_RANDMMAP |
11330 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
11331 |
++#endif |
11332 |
++ |
11333 |
+ if (addr) { |
11334 |
+ if (do_color_align) |
11335 |
+ addr = COLOUR_ALIGN(addr, pgoff); |
11336 |
+@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str |
11337 |
+ } |
11338 |
+ |
11339 |
+ if (len > mm->cached_hole_size) { |
11340 |
+- start_addr = addr = mm->free_area_cache; |
11341 |
++ start_addr = addr = mm->free_area_cache; |
11342 |
+ } else { |
11343 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
11344 |
++ start_addr = addr = mm->mmap_base; |
11345 |
+ mm->cached_hole_size = 0; |
11346 |
+ } |
11347 |
+ |
11348 |
+@@ -174,8 +178,8 @@ full_search: |
11349 |
+ vma = find_vma(mm, VA_EXCLUDE_END); |
11350 |
+ } |
11351 |
+ if (unlikely(task_size < addr)) { |
11352 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
11353 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
11354 |
++ if (start_addr != mm->mmap_base) { |
11355 |
++ start_addr = addr = mm->mmap_base; |
11356 |
+ mm->cached_hole_size = 0; |
11357 |
+ goto full_search; |
11358 |
+ } |
11359 |
+@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi |
11360 |
+ /* We do not accept a shared mapping if it would violate |
11361 |
+ * cache aliasing constraints. |
11362 |
+ */ |
11363 |
+- if ((flags & MAP_SHARED) && |
11364 |
++ if ((filp || (flags & MAP_SHARED)) && |
11365 |
+ ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))) |
11366 |
+ return -EINVAL; |
11367 |
+ return addr; |
11368 |
+@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str |
11369 |
+ current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY || |
11370 |
+ sysctl_legacy_va_layout) { |
11371 |
+ mm->mmap_base = TASK_UNMAPPED_BASE + random_factor; |
11372 |
++ |
11373 |
++#ifdef CONFIG_PAX_RANDMMAP |
11374 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11375 |
++ mm->mmap_base += mm->delta_mmap; |
11376 |
++#endif |
11377 |
++ |
11378 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
11379 |
+ mm->unmap_area = arch_unmap_area; |
11380 |
+ } else { |
11381 |
+@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str |
11382 |
+ gap = (task_size / 6 * 5); |
11383 |
+ |
11384 |
+ mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor); |
11385 |
++ |
11386 |
++#ifdef CONFIG_PAX_RANDMMAP |
11387 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11388 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
11389 |
++#endif |
11390 |
++ |
11391 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
11392 |
+ mm->unmap_area = arch_unmap_area_topdown; |
11393 |
+ } |
11394 |
+diff -Nurp linux-2.6.23.15/arch/sparc64/mm/Makefile linux-2.6.23.15-grsec/arch/sparc64/mm/Makefile |
11395 |
+--- linux-2.6.23.15/arch/sparc64/mm/Makefile 2007-10-09 21:31:38.000000000 +0100 |
11396 |
++++ linux-2.6.23.15-grsec/arch/sparc64/mm/Makefile 2008-02-11 10:37:44.000000000 +0000 |
11397 |
+@@ -3,7 +3,7 @@ |
11398 |
+ # |
11399 |
+ |
11400 |
+ EXTRA_AFLAGS := -ansi |
11401 |
+-EXTRA_CFLAGS := -Werror |
11402 |
++#EXTRA_CFLAGS := -Werror |
11403 |
+ |
11404 |
+ obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o |
11405 |
+ |
11406 |
+diff -Nurp linux-2.6.23.15/arch/sparc64/mm/fault.c linux-2.6.23.15-grsec/arch/sparc64/mm/fault.c |
11407 |
+--- linux-2.6.23.15/arch/sparc64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
11408 |
++++ linux-2.6.23.15-grsec/arch/sparc64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
11409 |
+@@ -20,6 +20,10 @@ |
11410 |
+ #include <linux/kprobes.h> |
11411 |
+ #include <linux/kallsyms.h> |
11412 |
+ #include <linux/kdebug.h> |
11413 |
++#include <linux/slab.h> |
11414 |
++#include <linux/pagemap.h> |
11415 |
++#include <linux/compiler.h> |
11416 |
++#include <linux/binfmts.h> |
11417 |
+ |
11418 |
+ #include <asm/page.h> |
11419 |
+ #include <asm/pgtable.h> |
11420 |
+@@ -270,6 +274,369 @@ cannot_handle: |
11421 |
+ unhandled_fault (address, current, regs); |
11422 |
+ } |
11423 |
+ |
11424 |
++#ifdef CONFIG_PAX_PAGEEXEC |
11425 |
++#ifdef CONFIG_PAX_EMUPLT |
11426 |
++static void pax_emuplt_close(struct vm_area_struct *vma) |
11427 |
++{ |
11428 |
++ vma->vm_mm->call_dl_resolve = 0UL; |
11429 |
++} |
11430 |
++ |
11431 |
++static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type) |
11432 |
++{ |
11433 |
++ struct page *page; |
11434 |
++ unsigned int *kaddr; |
11435 |
++ |
11436 |
++ page = alloc_page(GFP_HIGHUSER); |
11437 |
++ if (!page) |
11438 |
++ return NOPAGE_OOM; |
11439 |
++ |
11440 |
++ kaddr = kmap(page); |
11441 |
++ memset(kaddr, 0, PAGE_SIZE); |
11442 |
++ kaddr[0] = 0x9DE3BFA8U; /* save */ |
11443 |
++ flush_dcache_page(page); |
11444 |
++ kunmap(page); |
11445 |
++ if (type) |
11446 |
++ *type = VM_FAULT_MAJOR; |
11447 |
++ return page; |
11448 |
++} |
11449 |
++ |
11450 |
++static struct vm_operations_struct pax_vm_ops = { |
11451 |
++ .close = pax_emuplt_close, |
11452 |
++ .nopage = pax_emuplt_nopage, |
11453 |
++}; |
11454 |
++ |
11455 |
++static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) |
11456 |
++{ |
11457 |
++ int ret; |
11458 |
++ |
11459 |
++ memset(vma, 0, sizeof(*vma)); |
11460 |
++ vma->vm_mm = current->mm; |
11461 |
++ vma->vm_start = addr; |
11462 |
++ vma->vm_end = addr + PAGE_SIZE; |
11463 |
++ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; |
11464 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
11465 |
++ vma->vm_ops = &pax_vm_ops; |
11466 |
++ |
11467 |
++ ret = insert_vm_struct(current->mm, vma); |
11468 |
++ if (ret) |
11469 |
++ return ret; |
11470 |
++ |
11471 |
++ ++current->mm->total_vm; |
11472 |
++ return 0; |
11473 |
++} |
11474 |
++#endif |
11475 |
++ |
11476 |
++/* |
11477 |
++ * PaX: decide what to do with offenders (regs->tpc = fault address) |
11478 |
++ * |
11479 |
++ * returns 1 when task should be killed |
11480 |
++ * 2 when patched PLT trampoline was detected |
11481 |
++ * 3 when unpatched PLT trampoline was detected |
11482 |
++ */ |
11483 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
11484 |
++{ |
11485 |
++ |
11486 |
++#ifdef CONFIG_PAX_EMUPLT |
11487 |
++ int err; |
11488 |
++ |
11489 |
++ do { /* PaX: patched PLT emulation #1 */ |
11490 |
++ unsigned int sethi1, sethi2, jmpl; |
11491 |
++ |
11492 |
++ err = get_user(sethi1, (unsigned int *)regs->tpc); |
11493 |
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); |
11494 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8)); |
11495 |
++ |
11496 |
++ if (err) |
11497 |
++ break; |
11498 |
++ |
11499 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
11500 |
++ (sethi2 & 0xFFC00000U) == 0x03000000U && |
11501 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U) |
11502 |
++ { |
11503 |
++ unsigned long addr; |
11504 |
++ |
11505 |
++ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; |
11506 |
++ addr = regs->u_regs[UREG_G1]; |
11507 |
++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); |
11508 |
++ regs->tpc = addr; |
11509 |
++ regs->tnpc = addr+4; |
11510 |
++ return 2; |
11511 |
++ } |
11512 |
++ } while (0); |
11513 |
++ |
11514 |
++ { /* PaX: patched PLT emulation #2 */ |
11515 |
++ unsigned int ba; |
11516 |
++ |
11517 |
++ err = get_user(ba, (unsigned int *)regs->tpc); |
11518 |
++ |
11519 |
++ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { |
11520 |
++ unsigned long addr; |
11521 |
++ |
11522 |
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); |
11523 |
++ regs->tpc = addr; |
11524 |
++ regs->tnpc = addr+4; |
11525 |
++ return 2; |
11526 |
++ } |
11527 |
++ } |
11528 |
++ |
11529 |
++ do { /* PaX: patched PLT emulation #3 */ |
11530 |
++ unsigned int sethi, jmpl, nop; |
11531 |
++ |
11532 |
++ err = get_user(sethi, (unsigned int *)regs->tpc); |
11533 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4)); |
11534 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); |
11535 |
++ |
11536 |
++ if (err) |
11537 |
++ break; |
11538 |
++ |
11539 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
11540 |
++ (jmpl & 0xFFFFE000U) == 0x81C06000U && |
11541 |
++ nop == 0x01000000U) |
11542 |
++ { |
11543 |
++ unsigned long addr; |
11544 |
++ |
11545 |
++ addr = (sethi & 0x003FFFFFU) << 10; |
11546 |
++ regs->u_regs[UREG_G1] = addr; |
11547 |
++ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); |
11548 |
++ regs->tpc = addr; |
11549 |
++ regs->tnpc = addr+4; |
11550 |
++ return 2; |
11551 |
++ } |
11552 |
++ } while (0); |
11553 |
++ |
11554 |
++ do { /* PaX: patched PLT emulation #4 */ |
11555 |
++ unsigned int mov1, call, mov2; |
11556 |
++ |
11557 |
++ err = get_user(mov1, (unsigned int *)regs->tpc); |
11558 |
++ err |= get_user(call, (unsigned int *)(regs->tpc+4)); |
11559 |
++ err |= get_user(mov2, (unsigned int *)(regs->tpc+8)); |
11560 |
++ |
11561 |
++ if (err) |
11562 |
++ break; |
11563 |
++ |
11564 |
++ if (mov1 == 0x8210000FU && |
11565 |
++ (call & 0xC0000000U) == 0x40000000U && |
11566 |
++ mov2 == 0x9E100001U) |
11567 |
++ { |
11568 |
++ unsigned long addr; |
11569 |
++ |
11570 |
++ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC]; |
11571 |
++ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); |
11572 |
++ regs->tpc = addr; |
11573 |
++ regs->tnpc = addr+4; |
11574 |
++ return 2; |
11575 |
++ } |
11576 |
++ } while (0); |
11577 |
++ |
11578 |
++ do { /* PaX: patched PLT emulation #5 */ |
11579 |
++ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop; |
11580 |
++ |
11581 |
++ err = get_user(sethi1, (unsigned int *)regs->tpc); |
11582 |
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); |
11583 |
++ err |= get_user(or1, (unsigned int *)(regs->tpc+8)); |
11584 |
++ err |= get_user(or2, (unsigned int *)(regs->tpc+12)); |
11585 |
++ err |= get_user(sllx, (unsigned int *)(regs->tpc+16)); |
11586 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20)); |
11587 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+24)); |
11588 |
++ |
11589 |
++ if (err) |
11590 |
++ break; |
11591 |
++ |
11592 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
11593 |
++ (sethi2 & 0xFFC00000U) == 0x0B000000U && |
11594 |
++ (or1 & 0xFFFFE000U) == 0x82106000U && |
11595 |
++ (or2 & 0xFFFFE000U) == 0x8A116000U && |
11596 |
++ sllx == 0x83287020 && |
11597 |
++ jmpl == 0x81C04005U && |
11598 |
++ nop == 0x01000000U) |
11599 |
++ { |
11600 |
++ unsigned long addr; |
11601 |
++ |
11602 |
++ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU); |
11603 |
++ regs->u_regs[UREG_G1] <<= 32; |
11604 |
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU); |
11605 |
++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; |
11606 |
++ regs->tpc = addr; |
11607 |
++ regs->tnpc = addr+4; |
11608 |
++ return 2; |
11609 |
++ } |
11610 |
++ } while (0); |
11611 |
++ |
11612 |
++ do { /* PaX: patched PLT emulation #6 */ |
11613 |
++ unsigned int sethi1, sethi2, sllx, or, jmpl, nop; |
11614 |
++ |
11615 |
++ err = get_user(sethi1, (unsigned int *)regs->tpc); |
11616 |
++ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4)); |
11617 |
++ err |= get_user(sllx, (unsigned int *)(regs->tpc+8)); |
11618 |
++ err |= get_user(or, (unsigned int *)(regs->tpc+12)); |
11619 |
++ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16)); |
11620 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+20)); |
11621 |
++ |
11622 |
++ if (err) |
11623 |
++ break; |
11624 |
++ |
11625 |
++ if ((sethi1 & 0xFFC00000U) == 0x03000000U && |
11626 |
++ (sethi2 & 0xFFC00000U) == 0x0B000000U && |
11627 |
++ sllx == 0x83287020 && |
11628 |
++ (or & 0xFFFFE000U) == 0x8A116000U && |
11629 |
++ jmpl == 0x81C04005U && |
11630 |
++ nop == 0x01000000U) |
11631 |
++ { |
11632 |
++ unsigned long addr; |
11633 |
++ |
11634 |
++ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10; |
11635 |
++ regs->u_regs[UREG_G1] <<= 32; |
11636 |
++ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU); |
11637 |
++ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; |
11638 |
++ regs->tpc = addr; |
11639 |
++ regs->tnpc = addr+4; |
11640 |
++ return 2; |
11641 |
++ } |
11642 |
++ } while (0); |
11643 |
++ |
11644 |
++ do { /* PaX: patched PLT emulation #7 */ |
11645 |
++ unsigned int sethi, ba, nop; |
11646 |
++ |
11647 |
++ err = get_user(sethi, (unsigned int *)regs->tpc); |
11648 |
++ err |= get_user(ba, (unsigned int *)(regs->tpc+4)); |
11649 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); |
11650 |
++ |
11651 |
++ if (err) |
11652 |
++ break; |
11653 |
++ |
11654 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
11655 |
++ (ba & 0xFFF00000U) == 0x30600000U && |
11656 |
++ nop == 0x01000000U) |
11657 |
++ { |
11658 |
++ unsigned long addr; |
11659 |
++ |
11660 |
++ addr = (sethi & 0x003FFFFFU) << 10; |
11661 |
++ regs->u_regs[UREG_G1] = addr; |
11662 |
++ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); |
11663 |
++ regs->tpc = addr; |
11664 |
++ regs->tnpc = addr+4; |
11665 |
++ return 2; |
11666 |
++ } |
11667 |
++ } while (0); |
11668 |
++ |
11669 |
++ do { /* PaX: unpatched PLT emulation step 1 */ |
11670 |
++ unsigned int sethi, ba, nop; |
11671 |
++ |
11672 |
++ err = get_user(sethi, (unsigned int *)regs->tpc); |
11673 |
++ err |= get_user(ba, (unsigned int *)(regs->tpc+4)); |
11674 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+8)); |
11675 |
++ |
11676 |
++ if (err) |
11677 |
++ break; |
11678 |
++ |
11679 |
++ if ((sethi & 0xFFC00000U) == 0x03000000U && |
11680 |
++ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && |
11681 |
++ nop == 0x01000000U) |
11682 |
++ { |
11683 |
++ unsigned long addr; |
11684 |
++ unsigned int save, call; |
11685 |
++ |
11686 |
++ if ((ba & 0xFFC00000U) == 0x30800000U) |
11687 |
++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); |
11688 |
++ else |
11689 |
++ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); |
11690 |
++ |
11691 |
++ err = get_user(save, (unsigned int *)addr); |
11692 |
++ err |= get_user(call, (unsigned int *)(addr+4)); |
11693 |
++ err |= get_user(nop, (unsigned int *)(addr+8)); |
11694 |
++ if (err) |
11695 |
++ break; |
11696 |
++ |
11697 |
++ if (save == 0x9DE3BFA8U && |
11698 |
++ (call & 0xC0000000U) == 0x40000000U && |
11699 |
++ nop == 0x01000000U) |
11700 |
++ { |
11701 |
++ struct vm_area_struct *vma; |
11702 |
++ unsigned long call_dl_resolve; |
11703 |
++ |
11704 |
++ down_read(¤t->mm->mmap_sem); |
11705 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
11706 |
++ up_read(¤t->mm->mmap_sem); |
11707 |
++ if (likely(call_dl_resolve)) |
11708 |
++ goto emulate; |
11709 |
++ |
11710 |
++ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
11711 |
++ |
11712 |
++ down_write(¤t->mm->mmap_sem); |
11713 |
++ if (current->mm->call_dl_resolve) { |
11714 |
++ call_dl_resolve = current->mm->call_dl_resolve; |
11715 |
++ up_write(¤t->mm->mmap_sem); |
11716 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
11717 |
++ goto emulate; |
11718 |
++ } |
11719 |
++ |
11720 |
++ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); |
11721 |
++ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { |
11722 |
++ up_write(¤t->mm->mmap_sem); |
11723 |
++ if (vma) kmem_cache_free(vm_area_cachep, vma); |
11724 |
++ return 1; |
11725 |
++ } |
11726 |
++ |
11727 |
++ if (pax_insert_vma(vma, call_dl_resolve)) { |
11728 |
++ up_write(¤t->mm->mmap_sem); |
11729 |
++ kmem_cache_free(vm_area_cachep, vma); |
11730 |
++ return 1; |
11731 |
++ } |
11732 |
++ |
11733 |
++ current->mm->call_dl_resolve = call_dl_resolve; |
11734 |
++ up_write(¤t->mm->mmap_sem); |
11735 |
++ |
11736 |
++emulate: |
11737 |
++ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; |
11738 |
++ regs->tpc = call_dl_resolve; |
11739 |
++ regs->tnpc = addr+4; |
11740 |
++ return 3; |
11741 |
++ } |
11742 |
++ } |
11743 |
++ } while (0); |
11744 |
++ |
11745 |
++ do { /* PaX: unpatched PLT emulation step 2 */ |
11746 |
++ unsigned int save, call, nop; |
11747 |
++ |
11748 |
++ err = get_user(save, (unsigned int *)(regs->tpc-4)); |
11749 |
++ err |= get_user(call, (unsigned int *)regs->tpc); |
11750 |
++ err |= get_user(nop, (unsigned int *)(regs->tpc+4)); |
11751 |
++ if (err) |
11752 |
++ break; |
11753 |
++ |
11754 |
++ if (save == 0x9DE3BFA8U && |
11755 |
++ (call & 0xC0000000U) == 0x40000000U && |
11756 |
++ nop == 0x01000000U) |
11757 |
++ { |
11758 |
++ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); |
11759 |
++ |
11760 |
++ regs->u_regs[UREG_RETPC] = regs->tpc; |
11761 |
++ regs->tpc = dl_resolve; |
11762 |
++ regs->tnpc = dl_resolve+4; |
11763 |
++ return 3; |
11764 |
++ } |
11765 |
++ } while (0); |
11766 |
++#endif |
11767 |
++ |
11768 |
++ return 1; |
11769 |
++} |
11770 |
++ |
11771 |
++void pax_report_insns(void *pc, void *sp) |
11772 |
++{ |
11773 |
++ unsigned long i; |
11774 |
++ |
11775 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
11776 |
++ for (i = 0; i < 5; i++) { |
11777 |
++ unsigned int c; |
11778 |
++ if (get_user(c, (unsigned int *)pc+i)) |
11779 |
++ printk("???????? "); |
11780 |
++ else |
11781 |
++ printk("%08x ", c); |
11782 |
++ } |
11783 |
++ printk("\n"); |
11784 |
++} |
11785 |
++#endif |
11786 |
++ |
11787 |
+ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) |
11788 |
+ { |
11789 |
+ struct mm_struct *mm = current->mm; |
11790 |
+@@ -311,8 +678,10 @@ asmlinkage void __kprobes do_sparc64_fau |
11791 |
+ goto intr_or_no_mm; |
11792 |
+ |
11793 |
+ if (test_thread_flag(TIF_32BIT)) { |
11794 |
+- if (!(regs->tstate & TSTATE_PRIV)) |
11795 |
++ if (!(regs->tstate & TSTATE_PRIV)) { |
11796 |
+ regs->tpc &= 0xffffffff; |
11797 |
++ regs->tnpc &= 0xffffffff; |
11798 |
++ } |
11799 |
+ address &= 0xffffffff; |
11800 |
+ } |
11801 |
+ |
11802 |
+@@ -329,6 +698,29 @@ asmlinkage void __kprobes do_sparc64_fau |
11803 |
+ if (!vma) |
11804 |
+ goto bad_area; |
11805 |
+ |
11806 |
++#ifdef CONFIG_PAX_PAGEEXEC |
11807 |
++ /* PaX: detect ITLB misses on non-exec pages */ |
11808 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address && |
11809 |
++ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB)) |
11810 |
++ { |
11811 |
++ if (address != regs->tpc) |
11812 |
++ goto good_area; |
11813 |
++ |
11814 |
++ up_read(&mm->mmap_sem); |
11815 |
++ switch (pax_handle_fetch_fault(regs)) { |
11816 |
++ |
11817 |
++#ifdef CONFIG_PAX_EMUPLT |
11818 |
++ case 2: |
11819 |
++ case 3: |
11820 |
++ return; |
11821 |
++#endif |
11822 |
++ |
11823 |
++ } |
11824 |
++ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS)); |
11825 |
++ do_exit(SIGKILL); |
11826 |
++ } |
11827 |
++#endif |
11828 |
++ |
11829 |
+ /* Pure DTLB misses do not tell us whether the fault causing |
11830 |
+ * load/store/atomic was a write or not, it only says that there |
11831 |
+ * was no match. So in such a case we (carefully) read the |
11832 |
+diff -Nurp linux-2.6.23.15/arch/v850/kernel/module.c linux-2.6.23.15-grsec/arch/v850/kernel/module.c |
11833 |
+--- linux-2.6.23.15/arch/v850/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
11834 |
++++ linux-2.6.23.15-grsec/arch/v850/kernel/module.c 2008-02-11 10:37:44.000000000 +0000 |
11835 |
+@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat |
11836 |
+ tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */ |
11837 |
+ |
11838 |
+ /* Init, or core PLT? */ |
11839 |
+- if (location >= mod->module_core |
11840 |
+- && location < mod->module_core + mod->core_size) |
11841 |
++ if (location >= mod->module_core_rx |
11842 |
++ && location < mod->module_core_rx + mod->core_size_rx) |
11843 |
+ entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr; |
11844 |
+ else |
11845 |
+ entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr; |
11846 |
+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 |
11847 |
+--- linux-2.6.23.15/arch/x86_64/ia32/ia32_binfmt.c 2007-10-09 21:31:38.000000000 +0100 |
11848 |
++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_binfmt.c 2008-02-11 10:37:44.000000000 +0000 |
11849 |
+@@ -36,12 +36,12 @@ |
11850 |
+ #define AT_SYSINFO 32 |
11851 |
+ #define AT_SYSINFO_EHDR 33 |
11852 |
+ |
11853 |
+-int sysctl_vsyscall32 = 1; |
11854 |
++int sysctl_vsyscall32; |
11855 |
+ |
11856 |
+ #undef ARCH_DLINFO |
11857 |
+ #define ARCH_DLINFO do { \ |
11858 |
+ if (sysctl_vsyscall32) { \ |
11859 |
+- current->mm->context.vdso = (void *)VSYSCALL32_BASE; \ |
11860 |
++ current->mm->context.vdso = VSYSCALL32_BASE; \ |
11861 |
+ NEW_AUX_ENT(AT_SYSINFO, (u32)(u64)VSYSCALL32_VSYSCALL); \ |
11862 |
+ NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL32_BASE); \ |
11863 |
+ } \ |
11864 |
+@@ -145,6 +145,13 @@ struct elf_prpsinfo |
11865 |
+ //#include <asm/ia32.h> |
11866 |
+ #include <linux/elf.h> |
11867 |
+ |
11868 |
++#ifdef CONFIG_PAX_ASLR |
11869 |
++#define PAX_ELF_ET_DYN_BASE 0x08048000UL |
11870 |
++ |
11871 |
++#define PAX_DELTA_MMAP_LEN 16 |
11872 |
++#define PAX_DELTA_STACK_LEN 16 |
11873 |
++#endif |
11874 |
++ |
11875 |
+ typedef struct user_i387_ia32_struct elf_fpregset_t; |
11876 |
+ typedef struct user32_fxsr_struct elf_fpxregset_t; |
11877 |
+ |
11878 |
+@@ -298,7 +305,7 @@ static ctl_table abi_table2[] = { |
11879 |
+ .mode = 0644, |
11880 |
+ .proc_handler = proc_dointvec |
11881 |
+ }, |
11882 |
+- {} |
11883 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
11884 |
+ }; |
11885 |
+ |
11886 |
+ static ctl_table abi_root_table2[] = { |
11887 |
+@@ -308,7 +315,7 @@ static ctl_table abi_root_table2[] = { |
11888 |
+ .mode = 0555, |
11889 |
+ .child = abi_table2 |
11890 |
+ }, |
11891 |
+- {} |
11892 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
11893 |
+ }; |
11894 |
+ |
11895 |
+ static __init int ia32_binfmt_init(void) |
11896 |
+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 |
11897 |
+--- linux-2.6.23.15/arch/x86_64/ia32/ia32_signal.c 2007-10-09 21:31:38.000000000 +0100 |
11898 |
++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ia32_signal.c 2008-02-11 10:37:44.000000000 +0000 |
11899 |
+@@ -573,6 +573,7 @@ int ia32_setup_rt_frame(int sig, struct |
11900 |
+ __NR_ia32_rt_sigreturn, |
11901 |
+ 0x80cd, |
11902 |
+ 0, |
11903 |
++ 0 |
11904 |
+ }; |
11905 |
+ err |= __copy_to_user(frame->retcode, &code, 8); |
11906 |
+ } |
11907 |
+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 |
11908 |
+--- linux-2.6.23.15/arch/x86_64/ia32/mmap32.c 2007-10-09 21:31:38.000000000 +0100 |
11909 |
++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/mmap32.c 2008-02-11 10:37:44.000000000 +0000 |
11910 |
+@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str |
11911 |
+ (current->personality & ADDR_COMPAT_LAYOUT) || |
11912 |
+ current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) { |
11913 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
11914 |
++ |
11915 |
++#ifdef CONFIG_PAX_RANDMMAP |
11916 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11917 |
++ mm->mmap_base += mm->delta_mmap; |
11918 |
++#endif |
11919 |
++ |
11920 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
11921 |
+ mm->unmap_area = arch_unmap_area; |
11922 |
+ } else { |
11923 |
+ mm->mmap_base = mmap_base(mm); |
11924 |
++ |
11925 |
++#ifdef CONFIG_PAX_RANDMMAP |
11926 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
11927 |
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack; |
11928 |
++#endif |
11929 |
++ |
11930 |
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown; |
11931 |
+ mm->unmap_area = arch_unmap_area_topdown; |
11932 |
+ } |
11933 |
+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 |
11934 |
+--- linux-2.6.23.15/arch/x86_64/ia32/ptrace32.c 2007-10-09 21:31:38.000000000 +0100 |
11935 |
++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/ptrace32.c 2008-02-11 10:37:44.000000000 +0000 |
11936 |
+@@ -382,7 +382,7 @@ asmlinkage long sys32_ptrace(long reques |
11937 |
+ /* no checking to be bug-to-bug compatible with i386. */ |
11938 |
+ /* but silence warning */ |
11939 |
+ if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u))) |
11940 |
+- ; |
11941 |
++ {} |
11942 |
+ set_stopped_child_used_math(child); |
11943 |
+ child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; |
11944 |
+ ret = 0; |
11945 |
+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 |
11946 |
+--- linux-2.6.23.15/arch/x86_64/ia32/syscall32.c 2007-10-09 21:31:38.000000000 +0100 |
11947 |
++++ linux-2.6.23.15-grsec/arch/x86_64/ia32/syscall32.c 2008-02-11 10:37:44.000000000 +0000 |
11948 |
+@@ -30,6 +30,9 @@ int syscall32_setup_pages(struct linux_b |
11949 |
+ struct mm_struct *mm = current->mm; |
11950 |
+ int ret; |
11951 |
+ |
11952 |
++ if (!sysctl_vsyscall32) |
11953 |
++ return 0; |
11954 |
++ |
11955 |
+ down_write(&mm->mmap_sem); |
11956 |
+ /* |
11957 |
+ * MAYWRITE to allow gdb to COW and set breakpoints |
11958 |
+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 |
11959 |
+--- linux-2.6.23.15/arch/x86_64/kernel/hpet.c 2007-10-09 21:31:38.000000000 +0100 |
11960 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/hpet.c 2008-02-11 10:37:44.000000000 +0000 |
11961 |
+@@ -65,7 +65,7 @@ static __init int late_hpet_init(void) |
11962 |
+ hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE); |
11963 |
+ timer = &hpet->hpet_timers[2]; |
11964 |
+ for (i = 2; i < ntimer; timer++, i++) |
11965 |
+- hd.hd_irq[i] = (timer->hpet_config & |
11966 |
++ hd.hd_irq[i] = (readl(&timer->hpet_config) & |
11967 |
+ Tn_INT_ROUTE_CNF_MASK) >> |
11968 |
+ Tn_INT_ROUTE_CNF_SHIFT; |
11969 |
+ |
11970 |
+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 |
11971 |
+--- linux-2.6.23.15/arch/x86_64/kernel/i8259.c 2007-10-09 21:31:38.000000000 +0100 |
11972 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/i8259.c 2008-02-11 10:37:44.000000000 +0000 |
11973 |
+@@ -395,7 +395,7 @@ device_initcall(i8259A_init_sysfs); |
11974 |
+ * IRQ2 is cascade interrupt to second interrupt controller |
11975 |
+ */ |
11976 |
+ |
11977 |
+-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL}; |
11978 |
++static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL}; |
11979 |
+ DEFINE_PER_CPU(vector_irq_t, vector_irq) = { |
11980 |
+ [0 ... IRQ0_VECTOR - 1] = -1, |
11981 |
+ [IRQ0_VECTOR] = 0, |
11982 |
+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 |
11983 |
+--- linux-2.6.23.15/arch/x86_64/kernel/ioport.c 2007-10-09 21:31:38.000000000 +0100 |
11984 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/ioport.c 2008-02-11 10:37:44.000000000 +0000 |
11985 |
+@@ -16,6 +16,7 @@ |
11986 |
+ #include <linux/slab.h> |
11987 |
+ #include <linux/thread_info.h> |
11988 |
+ #include <linux/syscalls.h> |
11989 |
++#include <linux/grsecurity.h> |
11990 |
+ |
11991 |
+ /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ |
11992 |
+ static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value) |
11993 |
+@@ -41,8 +42,16 @@ asmlinkage long sys_ioperm(unsigned long |
11994 |
+ |
11995 |
+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) |
11996 |
+ return -EINVAL; |
11997 |
++ |
11998 |
++#ifdef CONFIG_GRKERNSEC_IO |
11999 |
++ if (turn_on) { |
12000 |
++ gr_handle_ioperm(); |
12001 |
++ return -EPERM; |
12002 |
++ } |
12003 |
++#else |
12004 |
+ if (turn_on && !capable(CAP_SYS_RAWIO)) |
12005 |
+ return -EPERM; |
12006 |
++#endif |
12007 |
+ |
12008 |
+ /* |
12009 |
+ * If it's the first ioperm() call in this thread's lifetime, set the |
12010 |
+@@ -111,8 +120,13 @@ asmlinkage long sys_iopl(unsigned int le |
12011 |
+ return -EINVAL; |
12012 |
+ /* Trying to gain more privileges? */ |
12013 |
+ if (level > old) { |
12014 |
++#ifdef CONFIG_GRKERNSEC_IO |
12015 |
++ gr_handle_iopl(); |
12016 |
++ return -EPERM; |
12017 |
++#else |
12018 |
+ if (!capable(CAP_SYS_RAWIO)) |
12019 |
+ return -EPERM; |
12020 |
++#endif |
12021 |
+ } |
12022 |
+ regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12); |
12023 |
+ return 0; |
12024 |
+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 |
12025 |
+--- linux-2.6.23.15/arch/x86_64/kernel/mce.c 2007-10-09 21:31:38.000000000 +0100 |
12026 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/mce.c 2008-02-11 10:37:44.000000000 +0000 |
12027 |
+@@ -665,6 +665,7 @@ static struct miscdevice mce_log_device |
12028 |
+ MISC_MCELOG_MINOR, |
12029 |
+ "mcelog", |
12030 |
+ &mce_chrdev_ops, |
12031 |
++ {NULL, NULL}, NULL, NULL |
12032 |
+ }; |
12033 |
+ |
12034 |
+ static unsigned long old_cr4 __initdata; |
12035 |
+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 |
12036 |
+--- linux-2.6.23.15/arch/x86_64/kernel/process.c 2007-10-09 21:31:38.000000000 +0100 |
12037 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/process.c 2008-02-11 10:37:44.000000000 +0000 |
12038 |
+@@ -894,10 +894,3 @@ int dump_task_regs(struct task_struct *t |
12039 |
+ |
12040 |
+ return 1; |
12041 |
+ } |
12042 |
+- |
12043 |
+-unsigned long arch_align_stack(unsigned long sp) |
12044 |
+-{ |
12045 |
+- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
12046 |
+- sp -= get_random_int() % 8192; |
12047 |
+- return sp & ~0xf; |
12048 |
+-} |
12049 |
+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 |
12050 |
+--- linux-2.6.23.15/arch/x86_64/kernel/setup64.c 2007-10-09 21:31:38.000000000 +0100 |
12051 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/setup64.c 2008-02-11 10:37:44.000000000 +0000 |
12052 |
+@@ -37,7 +37,7 @@ struct desc_ptr idt_descr = { 256 * 16 - |
12053 |
+ char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned"))); |
12054 |
+ |
12055 |
+ unsigned long __supported_pte_mask __read_mostly = ~0UL; |
12056 |
+-static int do_not_nx __cpuinitdata = 0; |
12057 |
++EXPORT_SYMBOL(__supported_pte_mask); |
12058 |
+ |
12059 |
+ /* noexec=on|off |
12060 |
+ Control non executable mappings for 64bit processes. |
12061 |
+@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str) |
12062 |
+ return -EINVAL; |
12063 |
+ if (!strncmp(str, "on", 2)) { |
12064 |
+ __supported_pte_mask |= _PAGE_NX; |
12065 |
+- do_not_nx = 0; |
12066 |
+ } else if (!strncmp(str, "off", 3)) { |
12067 |
+- do_not_nx = 1; |
12068 |
+ __supported_pte_mask &= ~_PAGE_NX; |
12069 |
+ } |
12070 |
+ return 0; |
12071 |
+ } |
12072 |
+ early_param("noexec", nonx_setup); |
12073 |
+ |
12074 |
+-int force_personality32 = 0; |
12075 |
++int force_personality32; |
12076 |
+ |
12077 |
+ /* noexec32=on|off |
12078 |
+ Control non executable heap for 32bit processes. |
12079 |
+@@ -177,7 +175,7 @@ void __cpuinit check_efer(void) |
12080 |
+ unsigned long efer; |
12081 |
+ |
12082 |
+ rdmsrl(MSR_EFER, efer); |
12083 |
+- if (!(efer & EFER_NX) || do_not_nx) { |
12084 |
++ if (!(efer & EFER_NX)) { |
12085 |
+ __supported_pte_mask &= ~_PAGE_NX; |
12086 |
+ } |
12087 |
+ } |
12088 |
+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 |
12089 |
+--- linux-2.6.23.15/arch/x86_64/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100 |
12090 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/signal.c 2008-02-11 10:37:44.000000000 +0000 |
12091 |
+@@ -254,8 +254,8 @@ static int setup_rt_frame(int sig, struc |
12092 |
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); |
12093 |
+ err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); |
12094 |
+ if (sizeof(*set) == 16) { |
12095 |
+- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); |
12096 |
+- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); |
12097 |
++ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); |
12098 |
++ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); |
12099 |
+ } else |
12100 |
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
12101 |
+ |
12102 |
+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 |
12103 |
+--- linux-2.6.23.15/arch/x86_64/kernel/sys_x86_64.c 2007-10-09 21:31:38.000000000 +0100 |
12104 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/sys_x86_64.c 2008-02-11 10:37:44.000000000 +0000 |
12105 |
+@@ -65,8 +65,8 @@ out: |
12106 |
+ return error; |
12107 |
+ } |
12108 |
+ |
12109 |
+-static void find_start_end(unsigned long flags, unsigned long *begin, |
12110 |
+- unsigned long *end) |
12111 |
++static void find_start_end(struct mm_struct *mm, unsigned long flags, |
12112 |
++ unsigned long *begin, unsigned long *end) |
12113 |
+ { |
12114 |
+ if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) { |
12115 |
+ /* This is usually used needed to map code in small |
12116 |
+@@ -79,7 +79,7 @@ static void find_start_end(unsigned long |
12117 |
+ *begin = 0x40000000; |
12118 |
+ *end = 0x80000000; |
12119 |
+ } else { |
12120 |
+- *begin = TASK_UNMAPPED_BASE; |
12121 |
++ *begin = mm->mmap_base; |
12122 |
+ *end = TASK_SIZE; |
12123 |
+ } |
12124 |
+ } |
12125 |
+@@ -96,11 +96,15 @@ arch_get_unmapped_area(struct file *filp |
12126 |
+ if (flags & MAP_FIXED) |
12127 |
+ return addr; |
12128 |
+ |
12129 |
+- find_start_end(flags, &begin, &end); |
12130 |
++ find_start_end(mm, flags, &begin, &end); |
12131 |
+ |
12132 |
+ if (len > end) |
12133 |
+ return -ENOMEM; |
12134 |
+ |
12135 |
++#ifdef CONFIG_PAX_RANDMMAP |
12136 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp) |
12137 |
++#endif |
12138 |
++ |
12139 |
+ if (addr) { |
12140 |
+ addr = PAGE_ALIGN(addr); |
12141 |
+ vma = find_vma(mm, addr); |
12142 |
+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 |
12143 |
+--- linux-2.6.23.15/arch/x86_64/kernel/vsyscall.c 2007-10-09 21:31:38.000000000 +0100 |
12144 |
++++ linux-2.6.23.15-grsec/arch/x86_64/kernel/vsyscall.c 2008-02-11 10:37:44.000000000 +0000 |
12145 |
+@@ -273,13 +273,13 @@ static ctl_table kernel_table2[] = { |
12146 |
+ .mode = 0644, |
12147 |
+ .strategy = vsyscall_sysctl_nostrat, |
12148 |
+ .proc_handler = vsyscall_sysctl_change }, |
12149 |
+- {} |
12150 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
12151 |
+ }; |
12152 |
+ |
12153 |
+ static ctl_table kernel_root_table2[] = { |
12154 |
+ { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555, |
12155 |
+ .child = kernel_table2 }, |
12156 |
+- {} |
12157 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
12158 |
+ }; |
12159 |
+ |
12160 |
+ #endif |
12161 |
+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 |
12162 |
+--- linux-2.6.23.15/arch/x86_64/mm/fault.c 2007-10-09 21:31:38.000000000 +0100 |
12163 |
++++ linux-2.6.23.15-grsec/arch/x86_64/mm/fault.c 2008-02-11 10:37:44.000000000 +0000 |
12164 |
+@@ -25,6 +25,7 @@ |
12165 |
+ #include <linux/kprobes.h> |
12166 |
+ #include <linux/uaccess.h> |
12167 |
+ #include <linux/kdebug.h> |
12168 |
++#include <linux/binfmts.h> |
12169 |
+ |
12170 |
+ #include <asm/system.h> |
12171 |
+ #include <asm/pgalloc.h> |
12172 |
+@@ -291,6 +292,163 @@ static int vmalloc_fault(unsigned long a |
12173 |
+ return 0; |
12174 |
+ } |
12175 |
+ |
12176 |
++#ifdef CONFIG_PAX_EMUTRAMP |
12177 |
++static int pax_handle_fetch_fault_32(struct pt_regs *regs) |
12178 |
++{ |
12179 |
++ int err; |
12180 |
++ |
12181 |
++ do { /* PaX: gcc trampoline emulation #1 */ |
12182 |
++ unsigned char mov1, mov2; |
12183 |
++ unsigned short jmp; |
12184 |
++ unsigned int addr1, addr2; |
12185 |
++ |
12186 |
++ if ((regs->rip + 11) >> 32) |
12187 |
++ break; |
12188 |
++ |
12189 |
++ err = get_user(mov1, (unsigned char __user *)regs->rip); |
12190 |
++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1)); |
12191 |
++ err |= get_user(mov2, (unsigned char __user *)(regs->rip + 5)); |
12192 |
++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6)); |
12193 |
++ err |= get_user(jmp, (unsigned short __user *)(regs->rip + 10)); |
12194 |
++ |
12195 |
++ if (err) |
12196 |
++ break; |
12197 |
++ |
12198 |
++ if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) { |
12199 |
++ regs->rcx = addr1; |
12200 |
++ regs->rax = addr2; |
12201 |
++ regs->rip = addr2; |
12202 |
++ return 2; |
12203 |
++ } |
12204 |
++ } while (0); |
12205 |
++ |
12206 |
++ do { /* PaX: gcc trampoline emulation #2 */ |
12207 |
++ unsigned char mov, jmp; |
12208 |
++ unsigned int addr1, addr2; |
12209 |
++ |
12210 |
++ if ((regs->rip + 9) >> 32) |
12211 |
++ break; |
12212 |
++ |
12213 |
++ err = get_user(mov, (unsigned char __user *)regs->rip); |
12214 |
++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 1)); |
12215 |
++ err |= get_user(jmp, (unsigned char __user *)(regs->rip + 5)); |
12216 |
++ err |= get_user(addr2, (unsigned int __user *)(regs->rip + 6)); |
12217 |
++ |
12218 |
++ if (err) |
12219 |
++ break; |
12220 |
++ |
12221 |
++ if (mov == 0xB9 && jmp == 0xE9) { |
12222 |
++ regs->rcx = addr1; |
12223 |
++ regs->rip = (unsigned int)(regs->rip + addr2 + 10); |
12224 |
++ return 2; |
12225 |
++ } |
12226 |
++ } while (0); |
12227 |
++ |
12228 |
++ return 1; /* PaX in action */ |
12229 |
++} |
12230 |
++ |
12231 |
++static int pax_handle_fetch_fault_64(struct pt_regs *regs) |
12232 |
++{ |
12233 |
++ int err; |
12234 |
++ |
12235 |
++ do { /* PaX: gcc trampoline emulation #1 */ |
12236 |
++ unsigned short mov1, mov2, jmp1; |
12237 |
++ unsigned char jmp2; |
12238 |
++ unsigned int addr1; |
12239 |
++ unsigned long addr2; |
12240 |
++ |
12241 |
++ err = get_user(mov1, (unsigned short __user *)regs->rip); |
12242 |
++ err |= get_user(addr1, (unsigned int __user *)(regs->rip + 2)); |
12243 |
++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 6)); |
12244 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 8)); |
12245 |
++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 16)); |
12246 |
++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 18)); |
12247 |
++ |
12248 |
++ if (err) |
12249 |
++ break; |
12250 |
++ |
12251 |
++ if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) { |
12252 |
++ regs->r11 = addr1; |
12253 |
++ regs->r10 = addr2; |
12254 |
++ regs->rip = addr1; |
12255 |
++ return 2; |
12256 |
++ } |
12257 |
++ } while (0); |
12258 |
++ |
12259 |
++ do { /* PaX: gcc trampoline emulation #2 */ |
12260 |
++ unsigned short mov1, mov2, jmp1; |
12261 |
++ unsigned char jmp2; |
12262 |
++ unsigned long addr1, addr2; |
12263 |
++ |
12264 |
++ err = get_user(mov1, (unsigned short __user *)regs->rip); |
12265 |
++ err |= get_user(addr1, (unsigned long __user *)(regs->rip + 2)); |
12266 |
++ err |= get_user(mov2, (unsigned short __user *)(regs->rip + 10)); |
12267 |
++ err |= get_user(addr2, (unsigned long __user *)(regs->rip + 12)); |
12268 |
++ err |= get_user(jmp1, (unsigned short __user *)(regs->rip + 20)); |
12269 |
++ err |= get_user(jmp2, (unsigned char __user *)(regs->rip + 22)); |
12270 |
++ |
12271 |
++ if (err) |
12272 |
++ break; |
12273 |
++ |
12274 |
++ if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) { |
12275 |
++ regs->r11 = addr1; |
12276 |
++ regs->r10 = addr2; |
12277 |
++ regs->rip = addr1; |
12278 |
++ return 2; |
12279 |
++ } |
12280 |
++ } while (0); |
12281 |
++ |
12282 |
++ return 1; /* PaX in action */ |
12283 |
++} |
12284 |
++ |
12285 |
++/* |
12286 |
++ * PaX: decide what to do with offenders (regs->rip = fault address) |
12287 |
++ * |
12288 |
++ * returns 1 when task should be killed |
12289 |
++ * 2 when gcc trampoline was detected |
12290 |
++ */ |
12291 |
++static int pax_handle_fetch_fault(struct pt_regs *regs) |
12292 |
++{ |
12293 |
++ if (regs->eflags & X86_EFLAGS_VM) |
12294 |
++ return 1; |
12295 |
++ |
12296 |
++ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) |
12297 |
++ return 1; |
12298 |
++ |
12299 |
++ if (regs->cs == __USER32_CS || (regs->cs & (1<<2))) |
12300 |
++ return pax_handle_fetch_fault_32(regs); |
12301 |
++ else |
12302 |
++ return pax_handle_fetch_fault_64(regs); |
12303 |
++} |
12304 |
++#endif |
12305 |
++ |
12306 |
++#ifdef CONFIG_PAX_PAGEEXEC |
12307 |
++void pax_report_insns(void *pc, void *sp) |
12308 |
++{ |
12309 |
++ long i; |
12310 |
++ |
12311 |
++ printk(KERN_ERR "PAX: bytes at PC: "); |
12312 |
++ for (i = 0; i < 20; i++) { |
12313 |
++ unsigned char c; |
12314 |
++ if (get_user(c, (unsigned char __user *)pc+i)) |
12315 |
++ printk("?? "); |
12316 |
++ else |
12317 |
++ printk("%02x ", c); |
12318 |
++ } |
12319 |
++ printk("\n"); |
12320 |
++ |
12321 |
++ printk(KERN_ERR "PAX: bytes at SP-8: "); |
12322 |
++ for (i = -1; i < 10; i++) { |
12323 |
++ unsigned long c; |
12324 |
++ if (get_user(c, (unsigned long __user *)sp+i)) |
12325 |
++ printk("???????????????? "); |
12326 |
++ else |
12327 |
++ printk("%016lx ", c); |
12328 |
++ } |
12329 |
++ printk("\n"); |
12330 |
++} |
12331 |
++#endif |
12332 |
++ |
12333 |
+ static int page_fault_trace; |
12334 |
+ int show_unhandled_signals = 1; |
12335 |
+ |
12336 |
+@@ -427,6 +585,8 @@ asmlinkage void __kprobes do_page_fault( |
12337 |
+ good_area: |
12338 |
+ info.si_code = SEGV_ACCERR; |
12339 |
+ write = 0; |
12340 |
++ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC)) |
12341 |
++ goto bad_area; |
12342 |
+ switch (error_code & (PF_PROT|PF_WRITE)) { |
12343 |
+ default: /* 3: write, present */ |
12344 |
+ /* fall through */ |
12345 |
+@@ -478,6 +638,21 @@ bad_area_nosemaphore: |
12346 |
+ */ |
12347 |
+ local_irq_enable(); |
12348 |
+ |
12349 |
++#ifdef CONFIG_PAX_PAGEEXEC |
12350 |
++ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) { |
12351 |
++ |
12352 |
++#ifdef CONFIG_PAX_EMUTRAMP |
12353 |
++ switch (pax_handle_fetch_fault(regs)) { |
12354 |
++ case 2: |
12355 |
++ return; |
12356 |
++ } |
12357 |
++#endif |
12358 |
++ |
12359 |
++ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp); |
12360 |
++ do_exit(SIGKILL); |
12361 |
++ } |
12362 |
++#endif |
12363 |
++ |
12364 |
+ if (is_prefetch(regs, address, error_code)) |
12365 |
+ return; |
12366 |
+ |
12367 |
+@@ -499,7 +674,7 @@ bad_area_nosemaphore: |
12368 |
+ tsk->comm, tsk->pid, address, regs->rip, |
12369 |
+ regs->rsp, error_code); |
12370 |
+ } |
12371 |
+- |
12372 |
++ |
12373 |
+ tsk->thread.cr2 = address; |
12374 |
+ /* Kernel addresses are always protection faults */ |
12375 |
+ tsk->thread.error_code = error_code | (address >= TASK_SIZE); |
12376 |
+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 |
12377 |
+--- linux-2.6.23.15/arch/x86_64/mm/init.c 2008-02-11 10:36:03.000000000 +0000 |
12378 |
++++ linux-2.6.23.15-grsec/arch/x86_64/mm/init.c 2008-02-11 10:37:44.000000000 +0000 |
12379 |
+@@ -45,7 +45,7 @@ |
12380 |
+ #include <asm/sections.h> |
12381 |
+ |
12382 |
+ #ifndef Dprintk |
12383 |
+-#define Dprintk(x...) |
12384 |
++#define Dprintk(x...) do {} while (0) |
12385 |
+ #endif |
12386 |
+ |
12387 |
+ const struct dma_mapping_ops* dma_ops; |
12388 |
+@@ -736,7 +736,7 @@ int in_gate_area_no_task(unsigned long a |
12389 |
+ |
12390 |
+ const char *arch_vma_name(struct vm_area_struct *vma) |
12391 |
+ { |
12392 |
+- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) |
12393 |
++ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso) |
12394 |
+ return "[vdso]"; |
12395 |
+ if (vma == &gate_vma) |
12396 |
+ return "[vsyscall]"; |
12397 |
+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 |
12398 |
+--- linux-2.6.23.15/arch/x86_64/mm/mmap.c 2007-10-09 21:31:38.000000000 +0100 |
12399 |
++++ linux-2.6.23.15-grsec/arch/x86_64/mm/mmap.c 2008-02-11 10:37:44.000000000 +0000 |
12400 |
+@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str |
12401 |
+ unsigned rnd = get_random_int() & 0xfffffff; |
12402 |
+ mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT; |
12403 |
+ } |
12404 |
++ |
12405 |
++#ifdef CONFIG_PAX_RANDMMAP |
12406 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
12407 |
++ mm->mmap_base += mm->delta_mmap; |
12408 |
++#endif |
12409 |
++ |
12410 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
12411 |
+ mm->unmap_area = arch_unmap_area; |
12412 |
+ } |
12413 |
+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 |
12414 |
+--- linux-2.6.23.15/arch/x86_64/mm/numa.c 2007-10-09 21:31:38.000000000 +0100 |
12415 |
++++ linux-2.6.23.15-grsec/arch/x86_64/mm/numa.c 2008-02-11 10:37:44.000000000 +0000 |
12416 |
+@@ -19,7 +19,7 @@ |
12417 |
+ #include <asm/acpi.h> |
12418 |
+ |
12419 |
+ #ifndef Dprintk |
12420 |
+-#define Dprintk(x...) |
12421 |
++#define Dprintk(x...) do {} while (0) |
12422 |
+ #endif |
12423 |
+ |
12424 |
+ struct pglist_data *node_data[MAX_NUMNODES] __read_mostly; |
12425 |
+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 |
12426 |
+--- linux-2.6.23.15/arch/x86_64/vdso/vma.c 2007-10-09 21:31:38.000000000 +0100 |
12427 |
++++ linux-2.6.23.15-grsec/arch/x86_64/vdso/vma.c 2008-02-11 10:37:44.000000000 +0000 |
12428 |
+@@ -126,7 +126,7 @@ int arch_setup_additional_pages(struct l |
12429 |
+ if (ret) |
12430 |
+ goto up_fail; |
12431 |
+ |
12432 |
+- current->mm->context.vdso = (void *)addr; |
12433 |
++ current->mm->context.vdso = addr; |
12434 |
+ up_fail: |
12435 |
+ up_write(&mm->mmap_sem); |
12436 |
+ return ret; |
12437 |
+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 |
12438 |
+--- linux-2.6.23.15/crypto/async_tx/async_tx.c 2007-10-09 21:31:38.000000000 +0100 |
12439 |
++++ linux-2.6.23.15-grsec/crypto/async_tx/async_tx.c 2008-02-11 10:37:44.000000000 +0000 |
12440 |
+@@ -342,8 +342,8 @@ async_tx_init(void) |
12441 |
+ err: |
12442 |
+ printk(KERN_ERR "async_tx: initialization failure\n"); |
12443 |
+ |
12444 |
+- while (--cap >= 0) |
12445 |
+- free_percpu(channel_table[cap]); |
12446 |
++ while (cap) |
12447 |
++ free_percpu(channel_table[--cap]); |
12448 |
+ |
12449 |
+ return 1; |
12450 |
+ } |
12451 |
+diff -Nurp linux-2.6.23.15/crypto/lrw.c linux-2.6.23.15-grsec/crypto/lrw.c |
12452 |
+--- linux-2.6.23.15/crypto/lrw.c 2007-10-09 21:31:38.000000000 +0100 |
12453 |
++++ linux-2.6.23.15-grsec/crypto/lrw.c 2008-02-11 10:37:44.000000000 +0000 |
12454 |
+@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par |
12455 |
+ struct priv *ctx = crypto_tfm_ctx(parent); |
12456 |
+ struct crypto_cipher *child = ctx->child; |
12457 |
+ int err, i; |
12458 |
+- be128 tmp = { 0 }; |
12459 |
++ be128 tmp = { 0, 0 }; |
12460 |
+ int bsize = crypto_cipher_blocksize(child); |
12461 |
+ |
12462 |
+ crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); |
12463 |
+diff -Nurp linux-2.6.23.15/drivers/acpi/blacklist.c linux-2.6.23.15-grsec/drivers/acpi/blacklist.c |
12464 |
+--- linux-2.6.23.15/drivers/acpi/blacklist.c 2008-02-11 10:36:03.000000000 +0000 |
12465 |
++++ linux-2.6.23.15-grsec/drivers/acpi/blacklist.c 2008-02-11 10:37:44.000000000 +0000 |
12466 |
+@@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b |
12467 |
+ {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, |
12468 |
+ "Incorrect _ADR", 1}, |
12469 |
+ |
12470 |
+- {""} |
12471 |
++ {"", "", 0, 0, 0, all_versions, 0} |
12472 |
+ }; |
12473 |
+ |
12474 |
+ #if CONFIG_ACPI_BLACKLIST_YEAR |
12475 |
+diff -Nurp linux-2.6.23.15/drivers/acpi/processor_core.c linux-2.6.23.15-grsec/drivers/acpi/processor_core.c |
12476 |
+--- linux-2.6.23.15/drivers/acpi/processor_core.c 2007-10-09 21:31:38.000000000 +0100 |
12477 |
++++ linux-2.6.23.15-grsec/drivers/acpi/processor_core.c 2008-02-11 10:37:44.000000000 +0000 |
12478 |
+@@ -643,7 +643,7 @@ static int __cpuinit acpi_processor_star |
12479 |
+ return 0; |
12480 |
+ } |
12481 |
+ |
12482 |
+- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0)); |
12483 |
++ BUG_ON(pr->id >= NR_CPUS); |
12484 |
+ |
12485 |
+ /* |
12486 |
+ * Buggy BIOS check |
12487 |
+diff -Nurp linux-2.6.23.15/drivers/acpi/processor_idle.c linux-2.6.23.15-grsec/drivers/acpi/processor_idle.c |
12488 |
+--- linux-2.6.23.15/drivers/acpi/processor_idle.c 2007-10-09 21:31:38.000000000 +0100 |
12489 |
++++ linux-2.6.23.15-grsec/drivers/acpi/processor_idle.c 2008-02-11 10:37:44.000000000 +0000 |
12490 |
+@@ -164,7 +164,7 @@ static struct dmi_system_id __cpuinitdat |
12491 |
+ DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), |
12492 |
+ DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, |
12493 |
+ (void *)2}, |
12494 |
+- {}, |
12495 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}, |
12496 |
+ }; |
12497 |
+ |
12498 |
+ static inline u32 ticks_elapsed(u32 t1, u32 t2) |
12499 |
+diff -Nurp linux-2.6.23.15/drivers/acpi/sleep/main.c linux-2.6.23.15-grsec/drivers/acpi/sleep/main.c |
12500 |
+--- linux-2.6.23.15/drivers/acpi/sleep/main.c 2008-02-11 10:36:03.000000000 +0000 |
12501 |
++++ linux-2.6.23.15-grsec/drivers/acpi/sleep/main.c 2008-02-11 10:37:44.000000000 +0000 |
12502 |
+@@ -228,7 +228,7 @@ static struct dmi_system_id __initdata a |
12503 |
+ .ident = "Toshiba Satellite 4030cdt", |
12504 |
+ .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),}, |
12505 |
+ }, |
12506 |
+- {}, |
12507 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}, |
12508 |
+ }; |
12509 |
+ #endif /* CONFIG_SUSPEND */ |
12510 |
+ |
12511 |
+diff -Nurp linux-2.6.23.15/drivers/acpi/tables/tbfadt.c linux-2.6.23.15-grsec/drivers/acpi/tables/tbfadt.c |
12512 |
+--- linux-2.6.23.15/drivers/acpi/tables/tbfadt.c 2007-10-09 21:31:38.000000000 +0100 |
12513 |
++++ linux-2.6.23.15-grsec/drivers/acpi/tables/tbfadt.c 2008-02-11 10:37:44.000000000 +0000 |
12514 |
+@@ -48,7 +48,7 @@ |
12515 |
+ ACPI_MODULE_NAME("tbfadt") |
12516 |
+ |
12517 |
+ /* Local prototypes */ |
12518 |
+-static void inline |
12519 |
++static inline void |
12520 |
+ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
12521 |
+ u8 bit_width, u64 address); |
12522 |
+ |
12523 |
+@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t |
12524 |
+ * |
12525 |
+ ******************************************************************************/ |
12526 |
+ |
12527 |
+-static void inline |
12528 |
++static inline void |
12529 |
+ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address, |
12530 |
+ u8 bit_width, u64 address) |
12531 |
+ { |
12532 |
+diff -Nurp linux-2.6.23.15/drivers/ata/ahci.c linux-2.6.23.15-grsec/drivers/ata/ahci.c |
12533 |
+--- linux-2.6.23.15/drivers/ata/ahci.c 2008-02-11 10:36:03.000000000 +0000 |
12534 |
++++ linux-2.6.23.15-grsec/drivers/ata/ahci.c 2008-02-11 10:37:44.000000000 +0000 |
12535 |
+@@ -523,7 +523,7 @@ static const struct pci_device_id ahci_p |
12536 |
+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
12537 |
+ PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci }, |
12538 |
+ |
12539 |
+- { } /* terminate list */ |
12540 |
++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ |
12541 |
+ }; |
12542 |
+ |
12543 |
+ |
12544 |
+diff -Nurp linux-2.6.23.15/drivers/ata/ata_piix.c linux-2.6.23.15-grsec/drivers/ata/ata_piix.c |
12545 |
+--- linux-2.6.23.15/drivers/ata/ata_piix.c 2007-10-09 21:31:38.000000000 +0100 |
12546 |
++++ linux-2.6.23.15-grsec/drivers/ata/ata_piix.c 2008-02-11 10:37:44.000000000 +0000 |
12547 |
+@@ -257,7 +257,7 @@ static const struct pci_device_id piix_p |
12548 |
+ /* SATA Controller IDE (Tolapai) */ |
12549 |
+ { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci }, |
12550 |
+ |
12551 |
+- { } /* terminate list */ |
12552 |
++ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ |
12553 |
+ }; |
12554 |
+ |
12555 |
+ static struct pci_driver piix_pci_driver = { |
12556 |
+@@ -617,7 +617,7 @@ static const struct ich_laptop ich_lapto |
12557 |
+ { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ |
12558 |
+ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ |
12559 |
+ /* end marker */ |
12560 |
+- { 0, } |
12561 |
++ { 0, 0, 0 } |
12562 |
+ }; |
12563 |
+ |
12564 |
+ /** |
12565 |
+@@ -963,7 +963,7 @@ static int piix_broken_suspend(void) |
12566 |
+ }, |
12567 |
+ }, |
12568 |
+ |
12569 |
+- { } /* terminate list */ |
12570 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } /* terminate list */ |
12571 |
+ }; |
12572 |
+ static const char *oemstrs[] = { |
12573 |
+ "Tecra M3,", |
12574 |
+diff -Nurp linux-2.6.23.15/drivers/ata/libata-core.c linux-2.6.23.15-grsec/drivers/ata/libata-core.c |
12575 |
+--- linux-2.6.23.15/drivers/ata/libata-core.c 2008-02-11 10:36:03.000000000 +0000 |
12576 |
++++ linux-2.6.23.15-grsec/drivers/ata/libata-core.c 2008-02-11 10:37:44.000000000 +0000 |
12577 |
+@@ -472,7 +472,7 @@ static const struct ata_xfer_ent { |
12578 |
+ { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 }, |
12579 |
+ { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 }, |
12580 |
+ { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 }, |
12581 |
+- { -1, }, |
12582 |
++ { -1, 0, 0 }, |
12583 |
+ }; |
12584 |
+ |
12585 |
+ /** |
12586 |
+@@ -2546,7 +2546,7 @@ static const struct ata_timing ata_timin |
12587 |
+ |
12588 |
+ /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */ |
12589 |
+ |
12590 |
+- { 0xFF } |
12591 |
++ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 } |
12592 |
+ }; |
12593 |
+ |
12594 |
+ #define ENOUGH(v,unit) (((v)-1)/(unit)+1) |
12595 |
+@@ -3799,7 +3799,7 @@ static const struct ata_blacklist_entry |
12596 |
+ { "MAXTOR 6L080L4", "A93.0500", ATA_HORKAGE_BROKEN_HPA }, |
12597 |
+ |
12598 |
+ /* End Marker */ |
12599 |
+- { } |
12600 |
++ { NULL, NULL, 0 } |
12601 |
+ }; |
12602 |
+ |
12603 |
+ static unsigned long ata_dev_blacklisted(const struct ata_device *dev) |
12604 |
+diff -Nurp linux-2.6.23.15/drivers/char/agp/frontend.c linux-2.6.23.15-grsec/drivers/char/agp/frontend.c |
12605 |
+--- linux-2.6.23.15/drivers/char/agp/frontend.c 2007-10-09 21:31:38.000000000 +0100 |
12606 |
++++ linux-2.6.23.15-grsec/drivers/char/agp/frontend.c 2008-02-11 10:37:44.000000000 +0000 |
12607 |
+@@ -820,7 +820,7 @@ static int agpioc_reserve_wrap(struct ag |
12608 |
+ if (copy_from_user(&reserve, arg, sizeof(struct agp_region))) |
12609 |
+ return -EFAULT; |
12610 |
+ |
12611 |
+- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment)) |
12612 |
++ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv)) |
12613 |
+ return -EFAULT; |
12614 |
+ |
12615 |
+ client = agp_find_client_by_pid(reserve.pid); |
12616 |
+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 |
12617 |
+--- linux-2.6.23.15/drivers/char/agp/intel-agp.c 2007-10-09 21:31:38.000000000 +0100 |
12618 |
++++ linux-2.6.23.15-grsec/drivers/char/agp/intel-agp.c 2008-02-11 10:37:44.000000000 +0000 |
12619 |
+@@ -2071,7 +2071,7 @@ static struct pci_device_id agp_intel_pc |
12620 |
+ ID(PCI_DEVICE_ID_INTEL_G33_HB), |
12621 |
+ ID(PCI_DEVICE_ID_INTEL_Q35_HB), |
12622 |
+ ID(PCI_DEVICE_ID_INTEL_Q33_HB), |
12623 |
+- { } |
12624 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
12625 |
+ }; |
12626 |
+ |
12627 |
+ MODULE_DEVICE_TABLE(pci, agp_intel_pci_table); |
12628 |
+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 |
12629 |
+--- linux-2.6.23.15/drivers/char/drm/drm_pciids.h 2007-10-09 21:31:38.000000000 +0100 |
12630 |
++++ linux-2.6.23.15-grsec/drivers/char/drm/drm_pciids.h 2008-02-11 10:37:44.000000000 +0000 |
12631 |
+@@ -251,7 +251,7 @@ |
12632 |
+ {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12633 |
+ {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12634 |
+ {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12635 |
+- {0, 0, 0} |
12636 |
++ {0, 0, 0, 0, 0, 0, 0 } |
12637 |
+ |
12638 |
+ #define i830_PCI_IDS \ |
12639 |
+ {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
12640 |
+diff -Nurp linux-2.6.23.15/drivers/char/hpet.c linux-2.6.23.15-grsec/drivers/char/hpet.c |
12641 |
+--- linux-2.6.23.15/drivers/char/hpet.c 2007-10-09 21:31:38.000000000 +0100 |
12642 |
++++ linux-2.6.23.15-grsec/drivers/char/hpet.c 2008-02-11 10:37:44.000000000 +0000 |
12643 |
+@@ -1028,7 +1028,7 @@ static struct acpi_driver hpet_acpi_driv |
12644 |
+ }, |
12645 |
+ }; |
12646 |
+ |
12647 |
+-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops }; |
12648 |
++static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL }; |
12649 |
+ |
12650 |
+ static int __init hpet_init(void) |
12651 |
+ { |
12652 |
+diff -Nurp linux-2.6.23.15/drivers/char/keyboard.c linux-2.6.23.15-grsec/drivers/char/keyboard.c |
12653 |
+--- linux-2.6.23.15/drivers/char/keyboard.c 2007-10-09 21:31:38.000000000 +0100 |
12654 |
++++ linux-2.6.23.15-grsec/drivers/char/keyboard.c 2008-02-11 10:37:44.000000000 +0000 |
12655 |
+@@ -605,6 +605,16 @@ static void k_spec(struct vc_data *vc, u |
12656 |
+ kbd->kbdmode == VC_MEDIUMRAW) && |
12657 |
+ value != KVAL(K_SAK)) |
12658 |
+ return; /* SAK is allowed even in raw mode */ |
12659 |
++ |
12660 |
++#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP) |
12661 |
++ { |
12662 |
++ void *func = fn_handler[value]; |
12663 |
++ if (func == fn_show_state || func == fn_show_ptregs || |
12664 |
++ func == fn_show_mem) |
12665 |
++ return; |
12666 |
++ } |
12667 |
++#endif |
12668 |
++ |
12669 |
+ fn_handler[value](vc); |
12670 |
+ } |
12671 |
+ |
12672 |
+@@ -1340,7 +1350,7 @@ static const struct input_device_id kbd_ |
12673 |
+ .evbit = { BIT(EV_SND) }, |
12674 |
+ }, |
12675 |
+ |
12676 |
+- { }, /* Terminating entry */ |
12677 |
++ { 0 }, /* Terminating entry */ |
12678 |
+ }; |
12679 |
+ |
12680 |
+ MODULE_DEVICE_TABLE(input, kbd_ids); |
12681 |
+diff -Nurp linux-2.6.23.15/drivers/char/mem.c linux-2.6.23.15-grsec/drivers/char/mem.c |
12682 |
+--- linux-2.6.23.15/drivers/char/mem.c 2007-10-09 21:31:38.000000000 +0100 |
12683 |
++++ linux-2.6.23.15-grsec/drivers/char/mem.c 2008-02-11 10:37:44.000000000 +0000 |
12684 |
+@@ -26,6 +26,7 @@ |
12685 |
+ #include <linux/bootmem.h> |
12686 |
+ #include <linux/splice.h> |
12687 |
+ #include <linux/pfn.h> |
12688 |
++#include <linux/grsecurity.h> |
12689 |
+ |
12690 |
+ #include <asm/uaccess.h> |
12691 |
+ #include <asm/io.h> |
12692 |
+@@ -34,6 +35,10 @@ |
12693 |
+ # include <linux/efi.h> |
12694 |
+ #endif |
12695 |
+ |
12696 |
++#ifdef CONFIG_GRKERNSEC |
12697 |
++extern struct file_operations grsec_fops; |
12698 |
++#endif |
12699 |
++ |
12700 |
+ /* |
12701 |
+ * Architectures vary in how they handle caching for addresses |
12702 |
+ * outside of main memory. |
12703 |
+@@ -180,6 +185,11 @@ static ssize_t write_mem(struct file * f |
12704 |
+ if (!valid_phys_addr_range(p, count)) |
12705 |
+ return -EFAULT; |
12706 |
+ |
12707 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12708 |
++ gr_handle_mem_write(); |
12709 |
++ return -EPERM; |
12710 |
++#endif |
12711 |
++ |
12712 |
+ written = 0; |
12713 |
+ |
12714 |
+ #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED |
12715 |
+@@ -281,6 +291,11 @@ static int mmap_mem(struct file * file, |
12716 |
+ if (!private_mapping_ok(vma)) |
12717 |
+ return -ENOSYS; |
12718 |
+ |
12719 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12720 |
++ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma)) |
12721 |
++ return -EPERM; |
12722 |
++#endif |
12723 |
++ |
12724 |
+ vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, |
12725 |
+ size, |
12726 |
+ vma->vm_page_prot); |
12727 |
+@@ -512,6 +527,11 @@ static ssize_t write_kmem(struct file * |
12728 |
+ ssize_t written; |
12729 |
+ char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ |
12730 |
+ |
12731 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12732 |
++ gr_handle_kmem_write(); |
12733 |
++ return -EPERM; |
12734 |
++#endif |
12735 |
++ |
12736 |
+ if (p < (unsigned long) high_memory) { |
12737 |
+ |
12738 |
+ wrote = count; |
12739 |
+@@ -635,6 +655,10 @@ static inline size_t read_zero_pagealign |
12740 |
+ struct vm_area_struct * vma; |
12741 |
+ unsigned long addr=(unsigned long)buf; |
12742 |
+ |
12743 |
++#ifdef CONFIG_PAX_SEGMEXEC |
12744 |
++ struct vm_area_struct *vma_m; |
12745 |
++#endif |
12746 |
++ |
12747 |
+ mm = current->mm; |
12748 |
+ /* Oops, this was forgotten before. -ben */ |
12749 |
+ down_read(&mm->mmap_sem); |
12750 |
+@@ -651,8 +675,14 @@ static inline size_t read_zero_pagealign |
12751 |
+ if (count > size) |
12752 |
+ count = size; |
12753 |
+ |
12754 |
++#ifdef CONFIG_PAX_SEGMEXEC |
12755 |
++ vma_m = pax_find_mirror_vma(vma); |
12756 |
++ if (vma_m) |
12757 |
++ zap_page_range(vma_m, addr + SEGMEXEC_TASK_SIZE, count, NULL); |
12758 |
++#endif |
12759 |
++ |
12760 |
+ zap_page_range(vma, addr, count, NULL); |
12761 |
+- if (zeromap_page_range(vma, addr, count, PAGE_COPY)) |
12762 |
++ if (zeromap_page_range(vma, addr, count, vma->vm_page_prot)) |
12763 |
+ break; |
12764 |
+ |
12765 |
+ size -= count; |
12766 |
+@@ -805,6 +835,16 @@ static loff_t memory_lseek(struct file * |
12767 |
+ |
12768 |
+ static int open_port(struct inode * inode, struct file * filp) |
12769 |
+ { |
12770 |
++#ifdef CONFIG_GRKERNSEC_KMEM |
12771 |
++ gr_handle_open_port(); |
12772 |
++ return -EPERM; |
12773 |
++#endif |
12774 |
++ |
12775 |
++ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; |
12776 |
++} |
12777 |
++ |
12778 |
++static int open_mem(struct inode * inode, struct file * filp) |
12779 |
++{ |
12780 |
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; |
12781 |
+ } |
12782 |
+ |
12783 |
+@@ -812,7 +852,6 @@ static int open_port(struct inode * inod |
12784 |
+ #define full_lseek null_lseek |
12785 |
+ #define write_zero write_null |
12786 |
+ #define read_full read_zero |
12787 |
+-#define open_mem open_port |
12788 |
+ #define open_kmem open_mem |
12789 |
+ #define open_oldmem open_mem |
12790 |
+ |
12791 |
+@@ -945,6 +984,11 @@ static int memory_open(struct inode * in |
12792 |
+ filp->f_op = &oldmem_fops; |
12793 |
+ break; |
12794 |
+ #endif |
12795 |
++#ifdef CONFIG_GRKERNSEC |
12796 |
++ case 13: |
12797 |
++ filp->f_op = &grsec_fops; |
12798 |
++ break; |
12799 |
++#endif |
12800 |
+ default: |
12801 |
+ return -ENXIO; |
12802 |
+ } |
12803 |
+@@ -977,6 +1021,9 @@ static const struct { |
12804 |
+ #ifdef CONFIG_CRASH_DUMP |
12805 |
+ {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops}, |
12806 |
+ #endif |
12807 |
++#ifdef CONFIG_GRKERNSEC |
12808 |
++ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops}, |
12809 |
++#endif |
12810 |
+ }; |
12811 |
+ |
12812 |
+ static struct class *mem_class; |
12813 |
+diff -Nurp linux-2.6.23.15/drivers/char/nvram.c linux-2.6.23.15-grsec/drivers/char/nvram.c |
12814 |
+--- linux-2.6.23.15/drivers/char/nvram.c 2007-10-09 21:31:38.000000000 +0100 |
12815 |
++++ linux-2.6.23.15-grsec/drivers/char/nvram.c 2008-02-11 10:37:44.000000000 +0000 |
12816 |
+@@ -430,7 +430,10 @@ static const struct file_operations nvra |
12817 |
+ static struct miscdevice nvram_dev = { |
12818 |
+ NVRAM_MINOR, |
12819 |
+ "nvram", |
12820 |
+- &nvram_fops |
12821 |
++ &nvram_fops, |
12822 |
++ {NULL, NULL}, |
12823 |
++ NULL, |
12824 |
++ NULL |
12825 |
+ }; |
12826 |
+ |
12827 |
+ static int __init |
12828 |
+diff -Nurp linux-2.6.23.15/drivers/char/random.c linux-2.6.23.15-grsec/drivers/char/random.c |
12829 |
+--- linux-2.6.23.15/drivers/char/random.c 2008-02-11 10:36:03.000000000 +0000 |
12830 |
++++ linux-2.6.23.15-grsec/drivers/char/random.c 2008-02-11 10:37:44.000000000 +0000 |
12831 |
+@@ -248,8 +248,13 @@ |
12832 |
+ /* |
12833 |
+ * Configuration information |
12834 |
+ */ |
12835 |
++#ifdef CONFIG_GRKERNSEC_RANDNET |
12836 |
++#define INPUT_POOL_WORDS 512 |
12837 |
++#define OUTPUT_POOL_WORDS 128 |
12838 |
++#else |
12839 |
+ #define INPUT_POOL_WORDS 128 |
12840 |
+ #define OUTPUT_POOL_WORDS 32 |
12841 |
++#endif |
12842 |
+ #define SEC_XFER_SIZE 512 |
12843 |
+ |
12844 |
+ /* |
12845 |
+@@ -286,10 +291,17 @@ static struct poolinfo { |
12846 |
+ int poolwords; |
12847 |
+ int tap1, tap2, tap3, tap4, tap5; |
12848 |
+ } poolinfo_table[] = { |
12849 |
++#ifdef CONFIG_GRKERNSEC_RANDNET |
12850 |
++ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */ |
12851 |
++ { 512, 411, 308, 208, 104, 1 }, |
12852 |
++ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */ |
12853 |
++ { 128, 103, 76, 51, 25, 1 }, |
12854 |
++#else |
12855 |
+ /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */ |
12856 |
+ { 128, 103, 76, 51, 25, 1 }, |
12857 |
+ /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */ |
12858 |
+ { 32, 26, 20, 14, 7, 1 }, |
12859 |
++#endif |
12860 |
+ #if 0 |
12861 |
+ /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */ |
12862 |
+ { 2048, 1638, 1231, 819, 411, 1 }, |
12863 |
+@@ -1172,7 +1184,7 @@ EXPORT_SYMBOL(generate_random_uuid); |
12864 |
+ #include <linux/sysctl.h> |
12865 |
+ |
12866 |
+ static int min_read_thresh = 8, min_write_thresh; |
12867 |
+-static int max_read_thresh = INPUT_POOL_WORDS * 32; |
12868 |
++static int max_read_thresh = OUTPUT_POOL_WORDS * 32; |
12869 |
+ static int max_write_thresh = INPUT_POOL_WORDS * 32; |
12870 |
+ static char sysctl_bootid[16]; |
12871 |
+ |
12872 |
+diff -Nurp linux-2.6.23.15/drivers/char/vt_ioctl.c linux-2.6.23.15-grsec/drivers/char/vt_ioctl.c |
12873 |
+--- linux-2.6.23.15/drivers/char/vt_ioctl.c 2007-10-09 21:31:38.000000000 +0100 |
12874 |
++++ linux-2.6.23.15-grsec/drivers/char/vt_ioctl.c 2008-02-11 10:37:44.000000000 +0000 |
12875 |
+@@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __ |
12876 |
+ case KDSKBENT: |
12877 |
+ if (!perm) |
12878 |
+ return -EPERM; |
12879 |
++ |
12880 |
++#ifdef CONFIG_GRKERNSEC |
12881 |
++ if (!capable(CAP_SYS_TTY_CONFIG)) |
12882 |
++ return -EPERM; |
12883 |
++#endif |
12884 |
++ |
12885 |
+ if (!i && v == K_NOSUCHMAP) { |
12886 |
+ /* deallocate map */ |
12887 |
+ key_map = key_maps[s]; |
12888 |
+@@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry |
12889 |
+ goto reterr; |
12890 |
+ } |
12891 |
+ |
12892 |
++#ifdef CONFIG_GRKERNSEC |
12893 |
++ if (!capable(CAP_SYS_TTY_CONFIG)) { |
12894 |
++ ret = -EPERM; |
12895 |
++ goto reterr; |
12896 |
++ } |
12897 |
++#endif |
12898 |
++ |
12899 |
+ q = func_table[i]; |
12900 |
+ first_free = funcbufptr + (funcbufsize - funcbufleft); |
12901 |
+ for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) |
12902 |
+diff -Nurp linux-2.6.23.15/drivers/dma/ioatdma.c linux-2.6.23.15-grsec/drivers/dma/ioatdma.c |
12903 |
+--- linux-2.6.23.15/drivers/dma/ioatdma.c 2007-10-09 21:31:38.000000000 +0100 |
12904 |
++++ linux-2.6.23.15-grsec/drivers/dma/ioatdma.c 2008-02-11 10:37:44.000000000 +0000 |
12905 |
+@@ -244,7 +244,6 @@ static void ioat_dma_free_chan_resources |
12906 |
+ struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); |
12907 |
+ struct ioat_device *ioat_device = to_ioat_device(chan->device); |
12908 |
+ struct ioat_desc_sw *desc, *_desc; |
12909 |
+- u16 chanctrl; |
12910 |
+ int in_use_descs = 0; |
12911 |
+ |
12912 |
+ ioat_dma_memcpy_cleanup(ioat_chan); |
12913 |
+diff -Nurp linux-2.6.23.15/drivers/edac/edac_core.h linux-2.6.23.15-grsec/drivers/edac/edac_core.h |
12914 |
+--- linux-2.6.23.15/drivers/edac/edac_core.h 2007-10-09 21:31:38.000000000 +0100 |
12915 |
++++ linux-2.6.23.15-grsec/drivers/edac/edac_core.h 2008-02-11 10:37:44.000000000 +0000 |
12916 |
+@@ -86,11 +86,11 @@ extern int edac_debug_level; |
12917 |
+ |
12918 |
+ #else /* !CONFIG_EDAC_DEBUG */ |
12919 |
+ |
12920 |
+-#define debugf0( ... ) |
12921 |
+-#define debugf1( ... ) |
12922 |
+-#define debugf2( ... ) |
12923 |
+-#define debugf3( ... ) |
12924 |
+-#define debugf4( ... ) |
12925 |
++#define debugf0( ... ) do {} while (0) |
12926 |
++#define debugf1( ... ) do {} while (0) |
12927 |
++#define debugf2( ... ) do {} while (0) |
12928 |
++#define debugf3( ... ) do {} while (0) |
12929 |
++#define debugf4( ... ) do {} while (0) |
12930 |
+ |
12931 |
+ #endif /* !CONFIG_EDAC_DEBUG */ |
12932 |
+ |
12933 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/fscpos.c linux-2.6.23.15-grsec/drivers/hwmon/fscpos.c |
12934 |
+--- linux-2.6.23.15/drivers/hwmon/fscpos.c 2007-10-09 21:31:38.000000000 +0100 |
12935 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/fscpos.c 2008-02-11 10:37:44.000000000 +0000 |
12936 |
+@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client |
12937 |
+ unsigned long v = simple_strtoul(buf, NULL, 10); |
12938 |
+ |
12939 |
+ /* Range: 0..255 */ |
12940 |
+- if (v < 0) v = 0; |
12941 |
+ if (v > 255) v = 255; |
12942 |
+ |
12943 |
+ mutex_lock(&data->update_lock); |
12944 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/k8temp.c linux-2.6.23.15-grsec/drivers/hwmon/k8temp.c |
12945 |
+--- linux-2.6.23.15/drivers/hwmon/k8temp.c 2007-10-09 21:31:38.000000000 +0100 |
12946 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/k8temp.c 2008-02-11 10:37:44.000000000 +0000 |
12947 |
+@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n |
12948 |
+ |
12949 |
+ static struct pci_device_id k8temp_ids[] = { |
12950 |
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, |
12951 |
+- { 0 }, |
12952 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
12953 |
+ }; |
12954 |
+ |
12955 |
+ MODULE_DEVICE_TABLE(pci, k8temp_ids); |
12956 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/sis5595.c linux-2.6.23.15-grsec/drivers/hwmon/sis5595.c |
12957 |
+--- linux-2.6.23.15/drivers/hwmon/sis5595.c 2007-10-09 21:31:38.000000000 +0100 |
12958 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/sis5595.c 2008-02-11 10:37:44.000000000 +0000 |
12959 |
+@@ -673,7 +673,7 @@ static struct sis5595_data *sis5595_upda |
12960 |
+ |
12961 |
+ static struct pci_device_id sis5595_pci_ids[] = { |
12962 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
12963 |
+- { 0, } |
12964 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
12965 |
+ }; |
12966 |
+ |
12967 |
+ MODULE_DEVICE_TABLE(pci, sis5595_pci_ids); |
12968 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/thmc50.c linux-2.6.23.15-grsec/drivers/hwmon/thmc50.c |
12969 |
+--- linux-2.6.23.15/drivers/hwmon/thmc50.c 2007-10-09 21:31:38.000000000 +0100 |
12970 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/thmc50.c 2008-02-11 10:37:44.000000000 +0000 |
12971 |
+@@ -47,9 +47,9 @@ I2C_CLIENT_MODULE_PARM(adm1022_temp3, "L |
12972 |
+ #define THMC50_REG_DIE_CODE 0x3F |
12973 |
+ #define THMC50_REG_ANALOG_OUT 0x19 |
12974 |
+ |
12975 |
+-const static u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
12976 |
+-const static u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
12977 |
+-const static u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; |
12978 |
++static const u8 THMC50_REG_TEMP[] = { 0x27, 0x26, 0x20 }; |
12979 |
++static const u8 THMC50_REG_TEMP_MIN[] = { 0x3A, 0x38, 0x2C }; |
12980 |
++static const u8 THMC50_REG_TEMP_MAX[] = { 0x39, 0x37, 0x2B }; |
12981 |
+ |
12982 |
+ #define THMC50_REG_CONF_nFANOFF 0x20 |
12983 |
+ |
12984 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/via686a.c linux-2.6.23.15-grsec/drivers/hwmon/via686a.c |
12985 |
+--- linux-2.6.23.15/drivers/hwmon/via686a.c 2007-10-09 21:31:38.000000000 +0100 |
12986 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/via686a.c 2008-02-11 10:37:44.000000000 +0000 |
12987 |
+@@ -740,7 +740,7 @@ static struct via686a_data *via686a_upda |
12988 |
+ |
12989 |
+ static struct pci_device_id via686a_pci_ids[] = { |
12990 |
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) }, |
12991 |
+- { 0, } |
12992 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
12993 |
+ }; |
12994 |
+ |
12995 |
+ MODULE_DEVICE_TABLE(pci, via686a_pci_ids); |
12996 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/vt8231.c linux-2.6.23.15-grsec/drivers/hwmon/vt8231.c |
12997 |
+--- linux-2.6.23.15/drivers/hwmon/vt8231.c 2007-10-09 21:31:38.000000000 +0100 |
12998 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/vt8231.c 2008-02-11 10:37:44.000000000 +0000 |
12999 |
+@@ -662,7 +662,7 @@ static struct platform_driver vt8231_dri |
13000 |
+ |
13001 |
+ static struct pci_device_id vt8231_pci_ids[] = { |
13002 |
+ { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) }, |
13003 |
+- { 0, } |
13004 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13005 |
+ }; |
13006 |
+ |
13007 |
+ MODULE_DEVICE_TABLE(pci, vt8231_pci_ids); |
13008 |
+diff -Nurp linux-2.6.23.15/drivers/hwmon/w83791d.c linux-2.6.23.15-grsec/drivers/hwmon/w83791d.c |
13009 |
+--- linux-2.6.23.15/drivers/hwmon/w83791d.c 2007-10-09 21:31:38.000000000 +0100 |
13010 |
++++ linux-2.6.23.15-grsec/drivers/hwmon/w83791d.c 2008-02-11 10:37:44.000000000 +0000 |
13011 |
+@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct |
13012 |
+ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind); |
13013 |
+ static int w83791d_detach_client(struct i2c_client *client); |
13014 |
+ |
13015 |
+-static int w83791d_read(struct i2c_client *client, u8 register); |
13016 |
+-static int w83791d_write(struct i2c_client *client, u8 register, u8 value); |
13017 |
++static int w83791d_read(struct i2c_client *client, u8 reg); |
13018 |
++static int w83791d_write(struct i2c_client *client, u8 reg, u8 value); |
13019 |
+ static struct w83791d_data *w83791d_update_device(struct device *dev); |
13020 |
+ |
13021 |
+ #ifdef DEBUG |
13022 |
+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 |
13023 |
+--- linux-2.6.23.15/drivers/i2c/busses/i2c-i801.c 2007-10-09 21:31:38.000000000 +0100 |
13024 |
++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i801.c 2008-02-11 10:37:44.000000000 +0000 |
13025 |
+@@ -543,7 +543,7 @@ static struct pci_device_id i801_ids[] = |
13026 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, |
13027 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, |
13028 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) }, |
13029 |
+- { 0, } |
13030 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13031 |
+ }; |
13032 |
+ |
13033 |
+ MODULE_DEVICE_TABLE (pci, i801_ids); |
13034 |
+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 |
13035 |
+--- linux-2.6.23.15/drivers/i2c/busses/i2c-i810.c 2007-10-09 21:31:38.000000000 +0100 |
13036 |
++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-i810.c 2008-02-11 10:37:44.000000000 +0000 |
13037 |
+@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _ |
13038 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) }, |
13039 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) }, |
13040 |
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) }, |
13041 |
+- { 0, }, |
13042 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
13043 |
+ }; |
13044 |
+ |
13045 |
+ MODULE_DEVICE_TABLE (pci, i810_ids); |
13046 |
+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 |
13047 |
+--- linux-2.6.23.15/drivers/i2c/busses/i2c-piix4.c 2007-10-09 21:31:38.000000000 +0100 |
13048 |
++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-piix4.c 2008-02-11 10:37:44.000000000 +0000 |
13049 |
+@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat |
13050 |
+ .ident = "IBM", |
13051 |
+ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, |
13052 |
+ }, |
13053 |
+- { }, |
13054 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }, |
13055 |
+ }; |
13056 |
+ |
13057 |
+ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, |
13058 |
+@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[] |
13059 |
+ .driver_data = 3 }, |
13060 |
+ { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3), |
13061 |
+ .driver_data = 0 }, |
13062 |
+- { 0, } |
13063 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13064 |
+ }; |
13065 |
+ |
13066 |
+ MODULE_DEVICE_TABLE (pci, piix4_ids); |
13067 |
+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 |
13068 |
+--- linux-2.6.23.15/drivers/i2c/busses/i2c-sis630.c 2007-10-09 21:31:38.000000000 +0100 |
13069 |
++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis630.c 2008-02-11 10:37:44.000000000 +0000 |
13070 |
+@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter |
13071 |
+ static struct pci_device_id sis630_ids[] __devinitdata = { |
13072 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
13073 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, |
13074 |
+- { 0, } |
13075 |
++ { PCI_DEVICE(0, 0) } |
13076 |
+ }; |
13077 |
+ |
13078 |
+ MODULE_DEVICE_TABLE (pci, sis630_ids); |
13079 |
+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 |
13080 |
+--- linux-2.6.23.15/drivers/i2c/busses/i2c-sis96x.c 2007-10-09 21:31:38.000000000 +0100 |
13081 |
++++ linux-2.6.23.15-grsec/drivers/i2c/busses/i2c-sis96x.c 2008-02-11 10:37:44.000000000 +0000 |
13082 |
+@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter |
13083 |
+ |
13084 |
+ static struct pci_device_id sis96x_ids[] = { |
13085 |
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) }, |
13086 |
+- { 0, } |
13087 |
++ { PCI_DEVICE(0, 0) } |
13088 |
+ }; |
13089 |
+ |
13090 |
+ MODULE_DEVICE_TABLE (pci, sis96x_ids); |
13091 |
+diff -Nurp linux-2.6.23.15/drivers/ide/ide-cd.c linux-2.6.23.15-grsec/drivers/ide/ide-cd.c |
13092 |
+--- linux-2.6.23.15/drivers/ide/ide-cd.c 2007-10-09 21:31:38.000000000 +0100 |
13093 |
++++ linux-2.6.23.15-grsec/drivers/ide/ide-cd.c 2008-02-11 10:37:44.000000000 +0000 |
13094 |
+@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_ |
13095 |
+ sector &= ~(bio_sectors -1); |
13096 |
+ valid = (sector - failed_command->sector) << 9; |
13097 |
+ |
13098 |
+- if (valid < 0) |
13099 |
+- valid = 0; |
13100 |
+ if (sector < get_capacity(info->disk) && |
13101 |
+ drive->probed_capacity - sector < 4 * 75) { |
13102 |
+ set_capacity(info->disk, sector); |
13103 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/dv1394.c linux-2.6.23.15-grsec/drivers/ieee1394/dv1394.c |
13104 |
+--- linux-2.6.23.15/drivers/ieee1394/dv1394.c 2007-10-09 21:31:38.000000000 +0100 |
13105 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/dv1394.c 2008-02-11 10:37:44.000000000 +0000 |
13106 |
+@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c |
13107 |
+ based upon DIF section and sequence |
13108 |
+ */ |
13109 |
+ |
13110 |
+-static void inline |
13111 |
++static inline void |
13112 |
+ frame_put_packet (struct frame *f, struct packet *p) |
13113 |
+ { |
13114 |
+ int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */ |
13115 |
+@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c |
13116 |
+ /* default SYT offset is 3 cycles */ |
13117 |
+ init->syt_offset = 3; |
13118 |
+ |
13119 |
+- if ( (init->channel > 63) || (init->channel < 0) ) |
13120 |
++ if (init->channel > 63) |
13121 |
+ init->channel = 63; |
13122 |
+ |
13123 |
+ chan_mask = (u64)1 << init->channel; |
13124 |
+@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_ |
13125 |
+ .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13126 |
+ .version = AVC_SW_VERSION_ENTRY & 0xffffff |
13127 |
+ }, |
13128 |
+- { } |
13129 |
++ { 0, 0, 0, 0, 0, 0 } |
13130 |
+ }; |
13131 |
+ |
13132 |
+ MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table); |
13133 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/eth1394.c linux-2.6.23.15-grsec/drivers/ieee1394/eth1394.c |
13134 |
+--- linux-2.6.23.15/drivers/ieee1394/eth1394.c 2007-10-09 21:31:38.000000000 +0100 |
13135 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/eth1394.c 2008-02-11 10:37:44.000000000 +0000 |
13136 |
+@@ -449,7 +449,7 @@ static struct ieee1394_device_id eth1394 |
13137 |
+ .specifier_id = ETHER1394_GASP_SPECIFIER_ID, |
13138 |
+ .version = ETHER1394_GASP_VERSION, |
13139 |
+ }, |
13140 |
+- {} |
13141 |
++ { 0, 0, 0, 0, 0, 0 } |
13142 |
+ }; |
13143 |
+ |
13144 |
+ MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table); |
13145 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/hosts.c linux-2.6.23.15-grsec/drivers/ieee1394/hosts.c |
13146 |
+--- linux-2.6.23.15/drivers/ieee1394/hosts.c 2007-10-09 21:31:38.000000000 +0100 |
13147 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/hosts.c 2008-02-11 10:37:44.000000000 +0000 |
13148 |
+@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso |
13149 |
+ } |
13150 |
+ |
13151 |
+ static struct hpsb_host_driver dummy_driver = { |
13152 |
++ .name = "dummy", |
13153 |
+ .transmit_packet = dummy_transmit_packet, |
13154 |
+ .devctl = dummy_devctl, |
13155 |
+ .isoctl = dummy_isoctl |
13156 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/ohci1394.c linux-2.6.23.15-grsec/drivers/ieee1394/ohci1394.c |
13157 |
+--- linux-2.6.23.15/drivers/ieee1394/ohci1394.c 2007-10-09 21:31:38.000000000 +0100 |
13158 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/ohci1394.c 2008-02-11 10:37:44.000000000 +0000 |
13159 |
+@@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_ |
13160 |
+ printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args) |
13161 |
+ |
13162 |
+ /* Module Parameters */ |
13163 |
+-static int phys_dma = 1; |
13164 |
++static int phys_dma; |
13165 |
+ module_param(phys_dma, int, 0444); |
13166 |
+-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1)."); |
13167 |
++MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0)."); |
13168 |
+ |
13169 |
+ static void dma_trm_tasklet(unsigned long data); |
13170 |
+ static void dma_trm_reset(struct dma_trm_ctx *d); |
13171 |
+@@ -3396,7 +3396,7 @@ static struct pci_device_id ohci1394_pci |
13172 |
+ .subvendor = PCI_ANY_ID, |
13173 |
+ .subdevice = PCI_ANY_ID, |
13174 |
+ }, |
13175 |
+- { 0, }, |
13176 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
13177 |
+ }; |
13178 |
+ |
13179 |
+ MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl); |
13180 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/raw1394.c linux-2.6.23.15-grsec/drivers/ieee1394/raw1394.c |
13181 |
+--- linux-2.6.23.15/drivers/ieee1394/raw1394.c 2007-10-09 21:31:38.000000000 +0100 |
13182 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/raw1394.c 2008-02-11 10:37:44.000000000 +0000 |
13183 |
+@@ -2952,7 +2952,7 @@ static struct ieee1394_device_id raw1394 |
13184 |
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, |
13185 |
+ .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13186 |
+ .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff}, |
13187 |
+- {} |
13188 |
++ { 0, 0, 0, 0, 0, 0 } |
13189 |
+ }; |
13190 |
+ |
13191 |
+ MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table); |
13192 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/sbp2.c linux-2.6.23.15-grsec/drivers/ieee1394/sbp2.c |
13193 |
+--- linux-2.6.23.15/drivers/ieee1394/sbp2.c 2007-10-09 21:31:38.000000000 +0100 |
13194 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/sbp2.c 2008-02-11 10:37:44.000000000 +0000 |
13195 |
+@@ -272,7 +272,7 @@ static struct ieee1394_device_id sbp2_id |
13196 |
+ .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION, |
13197 |
+ .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13198 |
+ .version = SBP2_SW_VERSION_ENTRY & 0xffffff}, |
13199 |
+- {} |
13200 |
++ { 0, 0, 0, 0, 0, 0 } |
13201 |
+ }; |
13202 |
+ MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table); |
13203 |
+ |
13204 |
+@@ -2063,7 +2063,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot |
13205 |
+ MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME); |
13206 |
+ MODULE_LICENSE("GPL"); |
13207 |
+ |
13208 |
+-static int sbp2_module_init(void) |
13209 |
++static int __init sbp2_module_init(void) |
13210 |
+ { |
13211 |
+ int ret; |
13212 |
+ |
13213 |
+diff -Nurp linux-2.6.23.15/drivers/ieee1394/video1394.c linux-2.6.23.15-grsec/drivers/ieee1394/video1394.c |
13214 |
+--- linux-2.6.23.15/drivers/ieee1394/video1394.c 2007-10-09 21:31:38.000000000 +0100 |
13215 |
++++ linux-2.6.23.15-grsec/drivers/ieee1394/video1394.c 2008-02-11 10:37:44.000000000 +0000 |
13216 |
+@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file |
13217 |
+ if (unlikely(d == NULL)) |
13218 |
+ return -EFAULT; |
13219 |
+ |
13220 |
+- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) { |
13221 |
++ if (unlikely(v.buffer>=d->num_desc - 1)) { |
13222 |
+ PRINT(KERN_ERR, ohci->host->id, |
13223 |
+ "Buffer %d out of range",v.buffer); |
13224 |
+ return -EINVAL; |
13225 |
+@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file |
13226 |
+ if (unlikely(d == NULL)) |
13227 |
+ return -EFAULT; |
13228 |
+ |
13229 |
+- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) { |
13230 |
++ if (unlikely(v.buffer>d->num_desc - 1)) { |
13231 |
+ PRINT(KERN_ERR, ohci->host->id, |
13232 |
+ "Buffer %d out of range",v.buffer); |
13233 |
+ return -EINVAL; |
13234 |
+@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file |
13235 |
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
13236 |
+ if (d == NULL) return -EFAULT; |
13237 |
+ |
13238 |
+- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { |
13239 |
++ if (v.buffer>=d->num_desc - 1) { |
13240 |
+ PRINT(KERN_ERR, ohci->host->id, |
13241 |
+ "Buffer %d out of range",v.buffer); |
13242 |
+ return -EINVAL; |
13243 |
+@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file |
13244 |
+ d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
13245 |
+ if (d == NULL) return -EFAULT; |
13246 |
+ |
13247 |
+- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) { |
13248 |
++ if (v.buffer>=d->num_desc-1) { |
13249 |
+ PRINT(KERN_ERR, ohci->host->id, |
13250 |
+ "Buffer %d out of range",v.buffer); |
13251 |
+ return -EINVAL; |
13252 |
+@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13 |
13253 |
+ .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff, |
13254 |
+ .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff |
13255 |
+ }, |
13256 |
+- { } |
13257 |
++ { 0, 0, 0, 0, 0, 0 } |
13258 |
+ }; |
13259 |
+ |
13260 |
+ MODULE_DEVICE_TABLE(ieee1394, video1394_id_table); |
13261 |
+diff -Nurp linux-2.6.23.15/drivers/input/keyboard/atkbd.c linux-2.6.23.15-grsec/drivers/input/keyboard/atkbd.c |
13262 |
+--- linux-2.6.23.15/drivers/input/keyboard/atkbd.c 2007-10-09 21:31:38.000000000 +0100 |
13263 |
++++ linux-2.6.23.15-grsec/drivers/input/keyboard/atkbd.c 2008-02-11 10:37:44.000000000 +0000 |
13264 |
+@@ -1075,7 +1075,7 @@ static struct serio_device_id atkbd_seri |
13265 |
+ .id = SERIO_ANY, |
13266 |
+ .extra = SERIO_ANY, |
13267 |
+ }, |
13268 |
+- { 0 } |
13269 |
++ { 0, 0, 0, 0 } |
13270 |
+ }; |
13271 |
+ |
13272 |
+ MODULE_DEVICE_TABLE(serio, atkbd_serio_ids); |
13273 |
+diff -Nurp linux-2.6.23.15/drivers/input/mouse/lifebook.c linux-2.6.23.15-grsec/drivers/input/mouse/lifebook.c |
13274 |
+--- linux-2.6.23.15/drivers/input/mouse/lifebook.c 2007-10-09 21:31:38.000000000 +0100 |
13275 |
++++ linux-2.6.23.15-grsec/drivers/input/mouse/lifebook.c 2008-02-11 10:37:44.000000000 +0000 |
13276 |
+@@ -102,7 +102,7 @@ static struct dmi_system_id lifebook_dmi |
13277 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"), |
13278 |
+ }, |
13279 |
+ }, |
13280 |
+- { } |
13281 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL} |
13282 |
+ }; |
13283 |
+ |
13284 |
+ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
13285 |
+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 |
13286 |
+--- linux-2.6.23.15/drivers/input/mouse/psmouse-base.c 2007-10-09 21:31:38.000000000 +0100 |
13287 |
++++ linux-2.6.23.15-grsec/drivers/input/mouse/psmouse-base.c 2008-02-11 10:37:44.000000000 +0000 |
13288 |
+@@ -1325,7 +1325,7 @@ static struct serio_device_id psmouse_se |
13289 |
+ .id = SERIO_ANY, |
13290 |
+ .extra = SERIO_ANY, |
13291 |
+ }, |
13292 |
+- { 0 } |
13293 |
++ { 0, 0, 0, 0 } |
13294 |
+ }; |
13295 |
+ |
13296 |
+ MODULE_DEVICE_TABLE(serio, psmouse_serio_ids); |
13297 |
+diff -Nurp linux-2.6.23.15/drivers/input/mouse/synaptics.c linux-2.6.23.15-grsec/drivers/input/mouse/synaptics.c |
13298 |
+--- linux-2.6.23.15/drivers/input/mouse/synaptics.c 2007-10-09 21:31:38.000000000 +0100 |
13299 |
++++ linux-2.6.23.15-grsec/drivers/input/mouse/synaptics.c 2008-02-11 10:37:44.000000000 +0000 |
13300 |
+@@ -417,7 +417,7 @@ static void synaptics_process_packet(str |
13301 |
+ break; |
13302 |
+ case 2: |
13303 |
+ if (SYN_MODEL_PEN(priv->model_id)) |
13304 |
+- ; /* Nothing, treat a pen as a single finger */ |
13305 |
++ break; /* Nothing, treat a pen as a single finger */ |
13306 |
+ break; |
13307 |
+ case 4 ... 15: |
13308 |
+ if (SYN_CAP_PALMDETECT(priv->capabilities)) |
13309 |
+@@ -624,7 +624,7 @@ static struct dmi_system_id toshiba_dmi_ |
13310 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"), |
13311 |
+ }, |
13312 |
+ }, |
13313 |
+- { } |
13314 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
13315 |
+ }; |
13316 |
+ #endif |
13317 |
+ |
13318 |
+diff -Nurp linux-2.6.23.15/drivers/input/mousedev.c linux-2.6.23.15-grsec/drivers/input/mousedev.c |
13319 |
+--- linux-2.6.23.15/drivers/input/mousedev.c 2008-02-11 10:36:03.000000000 +0000 |
13320 |
++++ linux-2.6.23.15-grsec/drivers/input/mousedev.c 2008-02-11 10:37:44.000000000 +0000 |
13321 |
+@@ -1048,7 +1048,7 @@ static struct input_handler mousedev_han |
13322 |
+ |
13323 |
+ #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX |
13324 |
+ static struct miscdevice psaux_mouse = { |
13325 |
+- PSMOUSE_MINOR, "psaux", &mousedev_fops |
13326 |
++ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL |
13327 |
+ }; |
13328 |
+ static int psaux_registered; |
13329 |
+ #endif |
13330 |
+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 |
13331 |
+--- linux-2.6.23.15/drivers/input/serio/i8042-x86ia64io.h 2007-10-09 21:31:38.000000000 +0100 |
13332 |
++++ linux-2.6.23.15-grsec/drivers/input/serio/i8042-x86ia64io.h 2008-02-11 10:37:44.000000000 +0000 |
13333 |
+@@ -110,7 +110,7 @@ static struct dmi_system_id __initdata i |
13334 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "5a"), |
13335 |
+ }, |
13336 |
+ }, |
13337 |
+- { } |
13338 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
13339 |
+ }; |
13340 |
+ |
13341 |
+ /* |
13342 |
+@@ -262,7 +262,7 @@ static struct dmi_system_id __initdata i |
13343 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"), |
13344 |
+ }, |
13345 |
+ }, |
13346 |
+- { } |
13347 |
++ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL } |
13348 |
+ }; |
13349 |
+ |
13350 |
+ |
13351 |
+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 |
13352 |
+--- linux-2.6.23.15/drivers/input/serio/serio_raw.c 2007-10-09 21:31:38.000000000 +0100 |
13353 |
++++ linux-2.6.23.15-grsec/drivers/input/serio/serio_raw.c 2008-02-11 10:37:44.000000000 +0000 |
13354 |
+@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_ |
13355 |
+ .id = SERIO_ANY, |
13356 |
+ .extra = SERIO_ANY, |
13357 |
+ }, |
13358 |
+- { 0 } |
13359 |
++ { 0, 0, 0, 0 } |
13360 |
+ }; |
13361 |
+ |
13362 |
+ MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids); |
13363 |
+diff -Nurp linux-2.6.23.15/drivers/kvm/kvm_main.c linux-2.6.23.15-grsec/drivers/kvm/kvm_main.c |
13364 |
+--- linux-2.6.23.15/drivers/kvm/kvm_main.c 2008-02-11 10:36:03.000000000 +0000 |
13365 |
++++ linux-2.6.23.15-grsec/drivers/kvm/kvm_main.c 2008-02-11 10:37:44.000000000 +0000 |
13366 |
+@@ -63,21 +63,21 @@ static struct kvm_stats_debugfs_item { |
13367 |
+ int offset; |
13368 |
+ struct dentry *dentry; |
13369 |
+ } debugfs_entries[] = { |
13370 |
+- { "pf_fixed", STAT_OFFSET(pf_fixed) }, |
13371 |
+- { "pf_guest", STAT_OFFSET(pf_guest) }, |
13372 |
+- { "tlb_flush", STAT_OFFSET(tlb_flush) }, |
13373 |
+- { "invlpg", STAT_OFFSET(invlpg) }, |
13374 |
+- { "exits", STAT_OFFSET(exits) }, |
13375 |
+- { "io_exits", STAT_OFFSET(io_exits) }, |
13376 |
+- { "mmio_exits", STAT_OFFSET(mmio_exits) }, |
13377 |
+- { "signal_exits", STAT_OFFSET(signal_exits) }, |
13378 |
+- { "irq_window", STAT_OFFSET(irq_window_exits) }, |
13379 |
+- { "halt_exits", STAT_OFFSET(halt_exits) }, |
13380 |
+- { "request_irq", STAT_OFFSET(request_irq_exits) }, |
13381 |
+- { "irq_exits", STAT_OFFSET(irq_exits) }, |
13382 |
+- { "light_exits", STAT_OFFSET(light_exits) }, |
13383 |
+- { "efer_reload", STAT_OFFSET(efer_reload) }, |
13384 |
+- { NULL } |
13385 |
++ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL }, |
13386 |
++ { "pf_guest", STAT_OFFSET(pf_guest), NULL }, |
13387 |
++ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL }, |
13388 |
++ { "invlpg", STAT_OFFSET(invlpg), NULL }, |
13389 |
++ { "exits", STAT_OFFSET(exits), NULL }, |
13390 |
++ { "io_exits", STAT_OFFSET(io_exits), NULL }, |
13391 |
++ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL }, |
13392 |
++ { "signal_exits", STAT_OFFSET(signal_exits), NULL }, |
13393 |
++ { "irq_window", STAT_OFFSET(irq_window_exits), NULL }, |
13394 |
++ { "halt_exits", STAT_OFFSET(halt_exits), NULL }, |
13395 |
++ { "request_irq", STAT_OFFSET(request_irq_exits), NULL }, |
13396 |
++ { "irq_exits", STAT_OFFSET(irq_exits), NULL }, |
13397 |
++ { "light_exits", STAT_OFFSET(light_exits), NULL }, |
13398 |
++ { "efer_reload", STAT_OFFSET(efer_reload), NULL }, |
13399 |
++ { NULL, 0, NULL } |
13400 |
+ }; |
13401 |
+ |
13402 |
+ static struct dentry *debugfs_dir; |
13403 |
+@@ -2255,7 +2255,7 @@ static int kvm_vcpu_ioctl_translate(stru |
13404 |
+ static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, |
13405 |
+ struct kvm_interrupt *irq) |
13406 |
+ { |
13407 |
+- if (irq->irq < 0 || irq->irq >= 256) |
13408 |
++ if (irq->irq >= 256) |
13409 |
+ return -EINVAL; |
13410 |
+ vcpu_load(vcpu); |
13411 |
+ |
13412 |
+@@ -2895,6 +2895,9 @@ static struct miscdevice kvm_dev = { |
13413 |
+ KVM_MINOR, |
13414 |
+ "kvm", |
13415 |
+ &kvm_chardev_ops, |
13416 |
++ {NULL, NULL}, |
13417 |
++ NULL, |
13418 |
++ NULL |
13419 |
+ }; |
13420 |
+ |
13421 |
+ static int kvm_reboot(struct notifier_block *notifier, unsigned long val, |
13422 |
+diff -Nurp linux-2.6.23.15/drivers/kvm/vmx.c linux-2.6.23.15-grsec/drivers/kvm/vmx.c |
13423 |
+--- linux-2.6.23.15/drivers/kvm/vmx.c 2008-02-11 10:36:03.000000000 +0000 |
13424 |
++++ linux-2.6.23.15-grsec/drivers/kvm/vmx.c 2008-02-11 10:37:44.000000000 +0000 |
13425 |
+@@ -2148,7 +2148,7 @@ again: |
13426 |
+ |
13427 |
+ vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; |
13428 |
+ |
13429 |
+- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); |
13430 |
++ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS)); |
13431 |
+ |
13432 |
+ if (unlikely(fail)) { |
13433 |
+ kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
13434 |
+diff -Nurp linux-2.6.23.15/drivers/kvm/x86_emulate.c linux-2.6.23.15-grsec/drivers/kvm/x86_emulate.c |
13435 |
+--- linux-2.6.23.15/drivers/kvm/x86_emulate.c 2008-02-11 10:36:03.000000000 +0000 |
13436 |
++++ linux-2.6.23.15-grsec/drivers/kvm/x86_emulate.c 2008-02-11 10:37:44.000000000 +0000 |
13437 |
+@@ -823,7 +823,7 @@ done_prefixes: |
13438 |
+ case DstReg: |
13439 |
+ dst.type = OP_REG; |
13440 |
+ if ((d & ByteOp) |
13441 |
+- && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { |
13442 |
++ && !(twobyte && (b == 0xb6 || b == 0xb7))) { |
13443 |
+ dst.ptr = decode_register(modrm_reg, _regs, |
13444 |
+ (rex_prefix == 0)); |
13445 |
+ dst.val = *(u8 *) dst.ptr; |
13446 |
+diff -Nurp linux-2.6.23.15/drivers/md/bitmap.c linux-2.6.23.15-grsec/drivers/md/bitmap.c |
13447 |
+--- linux-2.6.23.15/drivers/md/bitmap.c 2008-02-11 10:36:03.000000000 +0000 |
13448 |
++++ linux-2.6.23.15-grsec/drivers/md/bitmap.c 2008-02-11 10:37:44.000000000 +0000 |
13449 |
+@@ -57,7 +57,7 @@ |
13450 |
+ # if DEBUG > 0 |
13451 |
+ # define PRINTK(x...) printk(KERN_DEBUG x) |
13452 |
+ # else |
13453 |
+-# define PRINTK(x...) |
13454 |
++# define PRINTK(x...) do {} while (0) |
13455 |
+ # endif |
13456 |
+ #endif |
13457 |
+ |
13458 |
+diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2000.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2000.c |
13459 |
+--- linux-2.6.23.15/drivers/mtd/devices/doc2000.c 2007-10-09 21:31:38.000000000 +0100 |
13460 |
++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2000.c 2008-02-11 10:37:44.000000000 +0000 |
13461 |
+@@ -632,7 +632,7 @@ static int doc_read(struct mtd_info *mtd |
13462 |
+ len = ((from | 0x1ff) + 1) - from; |
13463 |
+ |
13464 |
+ /* The ECC will not be calculated correctly if less than 512 is read */ |
13465 |
+- if (len != 0x200 && eccbuf) |
13466 |
++ if (len != 0x200) |
13467 |
+ printk(KERN_WARNING |
13468 |
+ "ECC needs a full sector read (adr: %lx size %lx)\n", |
13469 |
+ (long) from, (long) len); |
13470 |
+diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2001.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001.c |
13471 |
+--- linux-2.6.23.15/drivers/mtd/devices/doc2001.c 2007-10-09 21:31:38.000000000 +0100 |
13472 |
++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001.c 2008-02-11 10:37:44.000000000 +0000 |
13473 |
+@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt |
13474 |
+ /* Don't allow read past end of device */ |
13475 |
+ if (from >= this->totlen) |
13476 |
+ return -EINVAL; |
13477 |
++ if (!len) |
13478 |
++ return -EINVAL; |
13479 |
+ |
13480 |
+ /* Don't allow a single read to cross a 512-byte block boundary */ |
13481 |
+ if (from + len > ((from | 0x1ff) + 1)) |
13482 |
+diff -Nurp linux-2.6.23.15/drivers/mtd/devices/doc2001plus.c linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001plus.c |
13483 |
+--- linux-2.6.23.15/drivers/mtd/devices/doc2001plus.c 2007-10-09 21:31:38.000000000 +0100 |
13484 |
++++ linux-2.6.23.15-grsec/drivers/mtd/devices/doc2001plus.c 2008-02-11 10:37:44.000000000 +0000 |
13485 |
+@@ -748,7 +748,7 @@ static int doc_write(struct mtd_info *mt |
13486 |
+ WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd); |
13487 |
+ |
13488 |
+ /* On interleaved devices the flags for 2nd half 512 are before data */ |
13489 |
+- if (eccbuf && before) |
13490 |
++ if (before) |
13491 |
+ fto -= 2; |
13492 |
+ |
13493 |
+ /* issue the Serial Data In command to initial the Page Program process */ |
13494 |
+diff -Nurp linux-2.6.23.15/drivers/mtd/devices/slram.c linux-2.6.23.15-grsec/drivers/mtd/devices/slram.c |
13495 |
+--- linux-2.6.23.15/drivers/mtd/devices/slram.c 2007-10-09 21:31:38.000000000 +0100 |
13496 |
++++ linux-2.6.23.15-grsec/drivers/mtd/devices/slram.c 2008-02-11 10:37:44.000000000 +0000 |
13497 |
+@@ -270,7 +270,7 @@ static int parse_cmdline(char *devname, |
13498 |
+ } |
13499 |
+ T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n", |
13500 |
+ devname, devstart, devlength); |
13501 |
+- if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) { |
13502 |
++ if (devlength % SLRAM_BLK_SZ != 0) { |
13503 |
+ E("slram: Illegal start / length parameter.\n"); |
13504 |
+ return(-EINVAL); |
13505 |
+ } |
13506 |
+diff -Nurp linux-2.6.23.15/drivers/mtd/ubi/build.c linux-2.6.23.15-grsec/drivers/mtd/ubi/build.c |
13507 |
+--- linux-2.6.23.15/drivers/mtd/ubi/build.c 2007-10-09 21:31:38.000000000 +0100 |
13508 |
++++ linux-2.6.23.15-grsec/drivers/mtd/ubi/build.c 2008-02-11 10:37:44.000000000 +0000 |
13509 |
+@@ -727,7 +727,7 @@ static int __init bytes_str_to_int(const |
13510 |
+ unsigned long result; |
13511 |
+ |
13512 |
+ result = simple_strtoul(str, &endp, 0); |
13513 |
+- if (str == endp || result < 0) { |
13514 |
++ if (str == endp) { |
13515 |
+ printk("UBI error: incorrect bytes count: \"%s\"\n", str); |
13516 |
+ return -EINVAL; |
13517 |
+ } |
13518 |
+diff -Nurp linux-2.6.23.15/drivers/net/eepro100.c linux-2.6.23.15-grsec/drivers/net/eepro100.c |
13519 |
+--- linux-2.6.23.15/drivers/net/eepro100.c 2007-10-09 21:31:38.000000000 +0100 |
13520 |
++++ linux-2.6.23.15-grsec/drivers/net/eepro100.c 2008-02-11 10:37:44.000000000 +0000 |
13521 |
+@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */; |
13522 |
+ # define rx_align(skb) skb_reserve((skb), 2) |
13523 |
+ # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed)) |
13524 |
+ #else |
13525 |
+-# define rx_align(skb) |
13526 |
++# define rx_align(skb) do {} while (0) |
13527 |
+ # define RxFD_ALIGNMENT |
13528 |
+ #endif |
13529 |
+ |
13530 |
+@@ -2344,33 +2344,33 @@ static void __devexit eepro100_remove_on |
13531 |
+ } |
13532 |
+ |
13533 |
+ static struct pci_device_id eepro100_pci_tbl[] = { |
13534 |
+- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, }, |
13535 |
+- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, }, |
13536 |
+- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, }, |
13537 |
+- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, }, |
13538 |
+- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, }, |
13539 |
+- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, }, |
13540 |
+- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, }, |
13541 |
+- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, }, |
13542 |
+- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, }, |
13543 |
+- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, }, |
13544 |
+- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, }, |
13545 |
+- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, }, |
13546 |
+- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, }, |
13547 |
+- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, }, |
13548 |
+- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, }, |
13549 |
+- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, }, |
13550 |
+- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, }, |
13551 |
+- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, }, |
13552 |
+- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, }, |
13553 |
+- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, }, |
13554 |
+- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, }, |
13555 |
+- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, }, |
13556 |
+- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, }, |
13557 |
+- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, }, |
13558 |
+- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, }, |
13559 |
+- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, }, |
13560 |
+- { 0,} |
13561 |
++ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13562 |
++ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13563 |
++ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13564 |
++ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13565 |
++ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13566 |
++ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13567 |
++ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13568 |
++ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13569 |
++ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13570 |
++ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13571 |
++ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13572 |
++ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13573 |
++ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13574 |
++ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13575 |
++ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13576 |
++ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13577 |
++ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13578 |
++ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13579 |
++ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13580 |
++ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13581 |
++ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13582 |
++ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13583 |
++ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13584 |
++ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13585 |
++ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13586 |
++ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
13587 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13588 |
+ }; |
13589 |
+ MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl); |
13590 |
+ |
13591 |
+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 |
13592 |
+--- linux-2.6.23.15/drivers/net/irda/vlsi_ir.c 2007-10-09 21:31:38.000000000 +0100 |
13593 |
++++ linux-2.6.23.15-grsec/drivers/net/irda/vlsi_ir.c 2008-02-11 10:37:44.000000000 +0000 |
13594 |
+@@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s |
13595 |
+ /* no race - tx-ring already empty */ |
13596 |
+ vlsi_set_baud(idev, iobase); |
13597 |
+ netif_wake_queue(ndev); |
13598 |
+- } |
13599 |
+- else |
13600 |
+- ; |
13601 |
++ } else { |
13602 |
+ /* keep the speed change pending like it would |
13603 |
+ * for any len>0 packet. tx completion interrupt |
13604 |
+ * will apply it when the tx ring becomes empty. |
13605 |
+ */ |
13606 |
++ } |
13607 |
+ spin_unlock_irqrestore(&idev->lock, flags); |
13608 |
+ dev_kfree_skb_any(skb); |
13609 |
+ return 0; |
13610 |
+diff -Nurp linux-2.6.23.15/drivers/net/pcnet32.c linux-2.6.23.15-grsec/drivers/net/pcnet32.c |
13611 |
+--- linux-2.6.23.15/drivers/net/pcnet32.c 2007-10-09 21:31:38.000000000 +0100 |
13612 |
++++ linux-2.6.23.15-grsec/drivers/net/pcnet32.c 2008-02-11 10:37:44.000000000 +0000 |
13613 |
+@@ -82,7 +82,7 @@ static int cards_found; |
13614 |
+ /* |
13615 |
+ * VLB I/O addresses |
13616 |
+ */ |
13617 |
+-static unsigned int pcnet32_portlist[] __initdata = |
13618 |
++static unsigned int pcnet32_portlist[] __devinitdata = |
13619 |
+ { 0x300, 0x320, 0x340, 0x360, 0 }; |
13620 |
+ |
13621 |
+ static int pcnet32_debug = 0; |
13622 |
+diff -Nurp linux-2.6.23.15/drivers/net/tg3.h linux-2.6.23.15-grsec/drivers/net/tg3.h |
13623 |
+--- linux-2.6.23.15/drivers/net/tg3.h 2007-10-09 21:31:38.000000000 +0100 |
13624 |
++++ linux-2.6.23.15-grsec/drivers/net/tg3.h 2008-02-11 10:37:44.000000000 +0000 |
13625 |
+@@ -127,6 +127,7 @@ |
13626 |
+ #define CHIPREV_ID_5750_A0 0x4000 |
13627 |
+ #define CHIPREV_ID_5750_A1 0x4001 |
13628 |
+ #define CHIPREV_ID_5750_A3 0x4003 |
13629 |
++#define CHIPREV_ID_5750_C1 0x4201 |
13630 |
+ #define CHIPREV_ID_5750_C2 0x4202 |
13631 |
+ #define CHIPREV_ID_5752_A0_HW 0x5000 |
13632 |
+ #define CHIPREV_ID_5752_A0 0x6000 |
13633 |
+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 |
13634 |
+--- linux-2.6.23.15/drivers/pci/hotplug/cpqphp_nvram.c 2007-10-09 21:31:38.000000000 +0100 |
13635 |
++++ linux-2.6.23.15-grsec/drivers/pci/hotplug/cpqphp_nvram.c 2008-02-11 10:37:44.000000000 +0000 |
13636 |
+@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_ |
13637 |
+ |
13638 |
+ void compaq_nvram_init (void __iomem *rom_start) |
13639 |
+ { |
13640 |
++ |
13641 |
++#ifndef CONFIG_PAX_KERNEXEC |
13642 |
+ if (rom_start) { |
13643 |
+ compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); |
13644 |
+ } |
13645 |
++#endif |
13646 |
++ |
13647 |
+ dbg("int15 entry = %p\n", compaq_int15_entry_point); |
13648 |
+ |
13649 |
+ /* initialize our int15 lock */ |
13650 |
+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 |
13651 |
+--- linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv.c 2007-10-09 21:31:38.000000000 +0100 |
13652 |
++++ linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv.c 2008-02-11 10:37:44.000000000 +0000 |
13653 |
+@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i |
13654 |
+ .port_type = PCIE_RC_PORT, |
13655 |
+ .service_type = PCIE_PORT_SERVICE_AER, |
13656 |
+ }, |
13657 |
+- { /* end: all zeroes */ } |
13658 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
13659 |
+ }; |
13660 |
+ |
13661 |
+ static struct pci_error_handlers aer_error_handlers = { |
13662 |
+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 |
13663 |
+--- linux-2.6.23.15/drivers/pci/pcie/aer/aerdrv_core.c 2007-10-09 21:31:38.000000000 +0100 |
13664 |
++++ linux-2.6.23.15-grsec/drivers/pci/pcie/aer/aerdrv_core.c 2008-02-11 10:37:44.000000000 +0000 |
13665 |
+@@ -660,7 +660,7 @@ static void aer_isr_one_error(struct pci |
13666 |
+ struct aer_err_source *e_src) |
13667 |
+ { |
13668 |
+ struct device *s_device; |
13669 |
+- struct aer_err_info e_info = {0, 0, 0,}; |
13670 |
++ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}}; |
13671 |
+ int i; |
13672 |
+ u16 id; |
13673 |
+ |
13674 |
+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 |
13675 |
+--- linux-2.6.23.15/drivers/pci/pcie/portdrv_pci.c 2007-10-09 21:31:38.000000000 +0100 |
13676 |
++++ linux-2.6.23.15-grsec/drivers/pci/pcie/portdrv_pci.c 2008-02-11 10:37:44.000000000 +0000 |
13677 |
+@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru |
13678 |
+ static const struct pci_device_id port_pci_ids[] = { { |
13679 |
+ /* handle any PCI-Express port */ |
13680 |
+ PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), |
13681 |
+- }, { /* end: all zeroes */ } |
13682 |
++ }, { 0, 0, 0, 0, 0, 0, 0 } |
13683 |
+ }; |
13684 |
+ MODULE_DEVICE_TABLE(pci, port_pci_ids); |
13685 |
+ |
13686 |
+diff -Nurp linux-2.6.23.15/drivers/pci/proc.c linux-2.6.23.15-grsec/drivers/pci/proc.c |
13687 |
+--- linux-2.6.23.15/drivers/pci/proc.c 2007-10-09 21:31:38.000000000 +0100 |
13688 |
++++ linux-2.6.23.15-grsec/drivers/pci/proc.c 2008-02-11 10:37:44.000000000 +0000 |
13689 |
+@@ -466,7 +466,15 @@ static int __init pci_proc_init(void) |
13690 |
+ { |
13691 |
+ struct proc_dir_entry *entry; |
13692 |
+ struct pci_dev *dev = NULL; |
13693 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
13694 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
13695 |
++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus); |
13696 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
13697 |
++ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus); |
13698 |
++#endif |
13699 |
++#else |
13700 |
+ proc_bus_pci_dir = proc_mkdir("pci", proc_bus); |
13701 |
++#endif |
13702 |
+ entry = create_proc_entry("devices", 0, proc_bus_pci_dir); |
13703 |
+ if (entry) |
13704 |
+ entry->proc_fops = &proc_bus_pci_dev_operations; |
13705 |
+diff -Nurp linux-2.6.23.15/drivers/pcmcia/ti113x.h linux-2.6.23.15-grsec/drivers/pcmcia/ti113x.h |
13706 |
+--- linux-2.6.23.15/drivers/pcmcia/ti113x.h 2007-10-09 21:31:38.000000000 +0100 |
13707 |
++++ linux-2.6.23.15-grsec/drivers/pcmcia/ti113x.h 2008-02-11 10:37:44.000000000 +0000 |
13708 |
+@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl |
13709 |
+ DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID, |
13710 |
+ ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE), |
13711 |
+ |
13712 |
+- {} |
13713 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13714 |
+ }; |
13715 |
+ |
13716 |
+ static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus) |
13717 |
+diff -Nurp linux-2.6.23.15/drivers/pcmcia/yenta_socket.c linux-2.6.23.15-grsec/drivers/pcmcia/yenta_socket.c |
13718 |
+--- linux-2.6.23.15/drivers/pcmcia/yenta_socket.c 2007-10-09 21:31:38.000000000 +0100 |
13719 |
++++ linux-2.6.23.15-grsec/drivers/pcmcia/yenta_socket.c 2008-02-11 10:37:44.000000000 +0000 |
13720 |
+@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table |
13721 |
+ |
13722 |
+ /* match any cardbus bridge */ |
13723 |
+ CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), |
13724 |
+- { /* all zeroes */ } |
13725 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13726 |
+ }; |
13727 |
+ MODULE_DEVICE_TABLE(pci, yenta_table); |
13728 |
+ |
13729 |
+diff -Nurp linux-2.6.23.15/drivers/pnp/pnpbios/bioscalls.c linux-2.6.23.15-grsec/drivers/pnp/pnpbios/bioscalls.c |
13730 |
+--- linux-2.6.23.15/drivers/pnp/pnpbios/bioscalls.c 2007-10-09 21:31:38.000000000 +0100 |
13731 |
++++ linux-2.6.23.15-grsec/drivers/pnp/pnpbios/bioscalls.c 2008-02-11 10:37:44.000000000 +0000 |
13732 |
+@@ -61,7 +61,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr |
13733 |
+ set_limit(gdt[(selname) >> 3], size); \ |
13734 |
+ } while(0) |
13735 |
+ |
13736 |
+-static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; |
13737 |
++static struct desc_struct bad_bios_desc __read_only = { 0, 0x00409300 }; |
13738 |
+ |
13739 |
+ /* |
13740 |
+ * At some point we want to use this stack frame pointer to unwind |
13741 |
+@@ -88,6 +88,10 @@ static inline u16 call_pnp_bios(u16 func |
13742 |
+ struct desc_struct save_desc_40; |
13743 |
+ int cpu; |
13744 |
+ |
13745 |
++#ifdef CONFIG_PAX_KERNEXEC |
13746 |
++ unsigned long cr0; |
13747 |
++#endif |
13748 |
++ |
13749 |
+ /* |
13750 |
+ * PnP BIOSes are generally not terribly re-entrant. |
13751 |
+ * Also, don't rely on them to save everything correctly. |
13752 |
+@@ -97,8 +101,17 @@ static inline u16 call_pnp_bios(u16 func |
13753 |
+ |
13754 |
+ cpu = get_cpu(); |
13755 |
+ save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8]; |
13756 |
++ |
13757 |
++#ifdef CONFIG_PAX_KERNEXEC |
13758 |
++ pax_open_kernel(cr0); |
13759 |
++#endif |
13760 |
++ |
13761 |
+ get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; |
13762 |
+ |
13763 |
++#ifdef CONFIG_PAX_KERNEXEC |
13764 |
++ pax_close_kernel(cr0); |
13765 |
++#endif |
13766 |
++ |
13767 |
+ /* On some boxes IRQ's during PnP BIOS calls are deadly. */ |
13768 |
+ spin_lock_irqsave(&pnp_bios_lock, flags); |
13769 |
+ |
13770 |
+@@ -135,7 +148,16 @@ static inline u16 call_pnp_bios(u16 func |
13771 |
+ :"memory"); |
13772 |
+ spin_unlock_irqrestore(&pnp_bios_lock, flags); |
13773 |
+ |
13774 |
++#ifdef CONFIG_PAX_KERNEXEC |
13775 |
++ pax_open_kernel(cr0); |
13776 |
++#endif |
13777 |
++ |
13778 |
+ get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40; |
13779 |
++ |
13780 |
++#ifdef CONFIG_PAX_KERNEXEC |
13781 |
++ pax_close_kernel(cr0); |
13782 |
++#endif |
13783 |
++ |
13784 |
+ put_cpu(); |
13785 |
+ |
13786 |
+ /* If we get here and this is set then the PnP BIOS faulted on us. */ |
13787 |
+@@ -469,16 +491,25 @@ int pnp_bios_read_escd(char *data, u32 n |
13788 |
+ return status; |
13789 |
+ } |
13790 |
+ |
13791 |
+-void pnpbios_calls_init(union pnp_bios_install_struct *header) |
13792 |
++void __init pnpbios_calls_init(union pnp_bios_install_struct *header) |
13793 |
+ { |
13794 |
+ int i; |
13795 |
+ |
13796 |
++#ifdef CONFIG_PAX_KERNEXEC |
13797 |
++ unsigned long cr0; |
13798 |
++#endif |
13799 |
++ |
13800 |
+ spin_lock_init(&pnp_bios_lock); |
13801 |
+ pnp_bios_callpoint.offset = header->fields.pm16offset; |
13802 |
+ pnp_bios_callpoint.segment = PNP_CS16; |
13803 |
+ |
13804 |
+ set_base(bad_bios_desc, __va((unsigned long)0x40 << 4)); |
13805 |
+ _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4)); |
13806 |
++ |
13807 |
++#ifdef CONFIG_PAX_KERNEXEC |
13808 |
++ pax_open_kernel(cr0); |
13809 |
++#endif |
13810 |
++ |
13811 |
+ for (i = 0; i < NR_CPUS; i++) { |
13812 |
+ struct desc_struct *gdt = get_cpu_gdt_table(i); |
13813 |
+ if (!gdt) |
13814 |
+@@ -489,4 +520,9 @@ void pnpbios_calls_init(union pnp_bios_i |
13815 |
+ set_base(gdt[GDT_ENTRY_PNPBIOS_DS], |
13816 |
+ __va(header->fields.pm16dseg)); |
13817 |
+ } |
13818 |
++ |
13819 |
++#ifdef CONFIG_PAX_KERNEXEC |
13820 |
++ pax_close_kernel(cr0); |
13821 |
++#endif |
13822 |
++ |
13823 |
+ } |
13824 |
+diff -Nurp linux-2.6.23.15/drivers/pnp/quirks.c linux-2.6.23.15-grsec/drivers/pnp/quirks.c |
13825 |
+--- linux-2.6.23.15/drivers/pnp/quirks.c 2007-10-09 21:31:38.000000000 +0100 |
13826 |
++++ linux-2.6.23.15-grsec/drivers/pnp/quirks.c 2008-02-11 10:37:44.000000000 +0000 |
13827 |
+@@ -127,7 +127,7 @@ static struct pnp_fixup pnp_fixups[] = { |
13828 |
+ {"CTL0043", quirk_sb16audio_resources}, |
13829 |
+ {"CTL0044", quirk_sb16audio_resources}, |
13830 |
+ {"CTL0045", quirk_sb16audio_resources}, |
13831 |
+- {""} |
13832 |
++ {"", NULL} |
13833 |
+ }; |
13834 |
+ |
13835 |
+ void pnp_fixup_device(struct pnp_dev *dev) |
13836 |
+diff -Nurp linux-2.6.23.15/drivers/pnp/resource.c linux-2.6.23.15-grsec/drivers/pnp/resource.c |
13837 |
+--- linux-2.6.23.15/drivers/pnp/resource.c 2007-10-09 21:31:38.000000000 +0100 |
13838 |
++++ linux-2.6.23.15-grsec/drivers/pnp/resource.c 2008-02-11 10:37:44.000000000 +0000 |
13839 |
+@@ -345,7 +345,7 @@ int pnp_check_irq(struct pnp_dev *dev, i |
13840 |
+ return 1; |
13841 |
+ |
13842 |
+ /* check if the resource is valid */ |
13843 |
+- if (*irq < 0 || *irq > 15) |
13844 |
++ if (*irq > 15) |
13845 |
+ return 0; |
13846 |
+ |
13847 |
+ /* check if the resource is reserved */ |
13848 |
+@@ -412,7 +412,7 @@ int pnp_check_dma(struct pnp_dev *dev, i |
13849 |
+ return 1; |
13850 |
+ |
13851 |
+ /* check if the resource is valid */ |
13852 |
+- if (*dma < 0 || *dma == 4 || *dma > 7) |
13853 |
++ if (*dma == 4 || *dma > 7) |
13854 |
+ return 0; |
13855 |
+ |
13856 |
+ /* check if the resource is reserved */ |
13857 |
+diff -Nurp linux-2.6.23.15/drivers/scsi/scsi_lib.c linux-2.6.23.15-grsec/drivers/scsi/scsi_lib.c |
13858 |
+--- linux-2.6.23.15/drivers/scsi/scsi_lib.c 2007-10-09 21:31:38.000000000 +0100 |
13859 |
++++ linux-2.6.23.15-grsec/drivers/scsi/scsi_lib.c 2008-02-11 10:37:44.000000000 +0000 |
13860 |
+@@ -44,7 +44,7 @@ struct scsi_host_sg_pool { |
13861 |
+ #error SCSI_MAX_PHYS_SEGMENTS is too small |
13862 |
+ #endif |
13863 |
+ |
13864 |
+-#define SP(x) { x, "sgpool-" #x } |
13865 |
++#define SP(x) { x, "sgpool-" #x, NULL, NULL } |
13866 |
+ static struct scsi_host_sg_pool scsi_sg_pools[] = { |
13867 |
+ SP(8), |
13868 |
+ SP(16), |
13869 |
+diff -Nurp linux-2.6.23.15/drivers/scsi/scsi_logging.h linux-2.6.23.15-grsec/drivers/scsi/scsi_logging.h |
13870 |
+--- linux-2.6.23.15/drivers/scsi/scsi_logging.h 2007-10-09 21:31:38.000000000 +0100 |
13871 |
++++ linux-2.6.23.15-grsec/drivers/scsi/scsi_logging.h 2008-02-11 10:37:44.000000000 +0000 |
13872 |
+@@ -51,7 +51,7 @@ do { \ |
13873 |
+ } while (0); \ |
13874 |
+ } while (0) |
13875 |
+ #else |
13876 |
+-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) |
13877 |
++#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0) |
13878 |
+ #endif /* CONFIG_SCSI_LOGGING */ |
13879 |
+ |
13880 |
+ /* |
13881 |
+diff -Nurp linux-2.6.23.15/drivers/serial/8250_pci.c linux-2.6.23.15-grsec/drivers/serial/8250_pci.c |
13882 |
+--- linux-2.6.23.15/drivers/serial/8250_pci.c 2007-10-09 21:31:38.000000000 +0100 |
13883 |
++++ linux-2.6.23.15-grsec/drivers/serial/8250_pci.c 2008-02-11 10:37:44.000000000 +0000 |
13884 |
+@@ -2589,7 +2589,7 @@ static struct pci_device_id serial_pci_t |
13885 |
+ PCI_ANY_ID, PCI_ANY_ID, |
13886 |
+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, |
13887 |
+ 0xffff00, pbn_default }, |
13888 |
+- { 0, } |
13889 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13890 |
+ }; |
13891 |
+ |
13892 |
+ static struct pci_driver serial_pci_driver = { |
13893 |
+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 |
13894 |
+--- linux-2.6.23.15/drivers/usb/class/cdc-acm.c 2007-10-09 21:31:38.000000000 +0100 |
13895 |
++++ linux-2.6.23.15-grsec/drivers/usb/class/cdc-acm.c 2008-02-11 10:37:44.000000000 +0000 |
13896 |
+@@ -1199,7 +1199,7 @@ static struct usb_device_id acm_ids[] = |
13897 |
+ USB_CDC_ACM_PROTO_AT_CDMA) }, |
13898 |
+ |
13899 |
+ /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */ |
13900 |
+- { } |
13901 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
13902 |
+ }; |
13903 |
+ |
13904 |
+ MODULE_DEVICE_TABLE (usb, acm_ids); |
13905 |
+diff -Nurp linux-2.6.23.15/drivers/usb/class/usblp.c linux-2.6.23.15-grsec/drivers/usb/class/usblp.c |
13906 |
+--- linux-2.6.23.15/drivers/usb/class/usblp.c 2007-10-09 21:31:38.000000000 +0100 |
13907 |
++++ linux-2.6.23.15-grsec/drivers/usb/class/usblp.c 2008-02-11 10:37:44.000000000 +0000 |
13908 |
+@@ -225,7 +225,7 @@ static const struct quirk_printer_struct |
13909 |
+ { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ |
13910 |
+ { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@×××.de> */ |
13911 |
+ { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */ |
13912 |
+- { 0, 0 } |
13913 |
++ { 0, 0, 0 } |
13914 |
+ }; |
13915 |
+ |
13916 |
+ static int usblp_wwait(struct usblp *usblp, int nonblock); |
13917 |
+@@ -1376,7 +1376,7 @@ static struct usb_device_id usblp_ids [] |
13918 |
+ { USB_INTERFACE_INFO(7, 1, 2) }, |
13919 |
+ { USB_INTERFACE_INFO(7, 1, 3) }, |
13920 |
+ { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */ |
13921 |
+- { } /* Terminating entry */ |
13922 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ |
13923 |
+ }; |
13924 |
+ |
13925 |
+ MODULE_DEVICE_TABLE (usb, usblp_ids); |
13926 |
+diff -Nurp linux-2.6.23.15/drivers/usb/core/hub.c linux-2.6.23.15-grsec/drivers/usb/core/hub.c |
13927 |
+--- linux-2.6.23.15/drivers/usb/core/hub.c 2008-02-11 10:36:03.000000000 +0000 |
13928 |
++++ linux-2.6.23.15-grsec/drivers/usb/core/hub.c 2008-02-11 10:37:44.000000000 +0000 |
13929 |
+@@ -2762,7 +2762,7 @@ static struct usb_device_id hub_id_table |
13930 |
+ .bDeviceClass = USB_CLASS_HUB}, |
13931 |
+ { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, |
13932 |
+ .bInterfaceClass = USB_CLASS_HUB}, |
13933 |
+- { } /* Terminating entry */ |
13934 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */ |
13935 |
+ }; |
13936 |
+ |
13937 |
+ MODULE_DEVICE_TABLE (usb, hub_id_table); |
13938 |
+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 |
13939 |
+--- linux-2.6.23.15/drivers/usb/host/ehci-pci.c 2007-10-09 21:31:38.000000000 +0100 |
13940 |
++++ linux-2.6.23.15-grsec/drivers/usb/host/ehci-pci.c 2008-02-11 10:37:44.000000000 +0000 |
13941 |
+@@ -377,7 +377,7 @@ static const struct pci_device_id pci_id |
13942 |
+ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0), |
13943 |
+ .driver_data = (unsigned long) &ehci_pci_hc_driver, |
13944 |
+ }, |
13945 |
+- { /* end: all zeroes */ } |
13946 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
13947 |
+ }; |
13948 |
+ MODULE_DEVICE_TABLE(pci, pci_ids); |
13949 |
+ |
13950 |
+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 |
13951 |
+--- linux-2.6.23.15/drivers/usb/host/uhci-hcd.c 2007-10-09 21:31:38.000000000 +0100 |
13952 |
++++ linux-2.6.23.15-grsec/drivers/usb/host/uhci-hcd.c 2008-02-11 10:37:44.000000000 +0000 |
13953 |
+@@ -894,7 +894,7 @@ static const struct pci_device_id uhci_p |
13954 |
+ /* handle any USB UHCI controller */ |
13955 |
+ PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0), |
13956 |
+ .driver_data = (unsigned long) &uhci_driver, |
13957 |
+- }, { /* end: all zeroes */ } |
13958 |
++ }, { 0, 0, 0, 0, 0, 0, 0 } |
13959 |
+ }; |
13960 |
+ |
13961 |
+ MODULE_DEVICE_TABLE(pci, uhci_pci_ids); |
13962 |
+diff -Nurp linux-2.6.23.15/drivers/usb/storage/debug.h linux-2.6.23.15-grsec/drivers/usb/storage/debug.h |
13963 |
+--- linux-2.6.23.15/drivers/usb/storage/debug.h 2007-10-09 21:31:38.000000000 +0100 |
13964 |
++++ linux-2.6.23.15-grsec/drivers/usb/storage/debug.h 2008-02-11 10:37:44.000000000 +0000 |
13965 |
+@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char |
13966 |
+ #define US_DEBUGPX(x...) printk( x ) |
13967 |
+ #define US_DEBUG(x) x |
13968 |
+ #else |
13969 |
+-#define US_DEBUGP(x...) |
13970 |
+-#define US_DEBUGPX(x...) |
13971 |
+-#define US_DEBUG(x) |
13972 |
++#define US_DEBUGP(x...) do {} while (0) |
13973 |
++#define US_DEBUGPX(x...) do {} while (0) |
13974 |
++#define US_DEBUG(x) do {} while (0) |
13975 |
+ #endif |
13976 |
+ |
13977 |
+ #endif |
13978 |
+diff -Nurp linux-2.6.23.15/drivers/usb/storage/usb.c linux-2.6.23.15-grsec/drivers/usb/storage/usb.c |
13979 |
+--- linux-2.6.23.15/drivers/usb/storage/usb.c 2007-10-09 21:31:38.000000000 +0100 |
13980 |
++++ linux-2.6.23.15-grsec/drivers/usb/storage/usb.c 2008-02-11 10:37:44.000000000 +0000 |
13981 |
+@@ -134,7 +134,7 @@ static struct usb_device_id storage_usb_ |
13982 |
+ #undef UNUSUAL_DEV |
13983 |
+ #undef USUAL_DEV |
13984 |
+ /* Terminating entry */ |
13985 |
+- { } |
13986 |
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } |
13987 |
+ }; |
13988 |
+ |
13989 |
+ MODULE_DEVICE_TABLE (usb, storage_usb_ids); |
13990 |
+@@ -174,7 +174,7 @@ static struct us_unusual_dev us_unusual_ |
13991 |
+ # undef USUAL_DEV |
13992 |
+ |
13993 |
+ /* Terminating entry */ |
13994 |
+- { NULL } |
13995 |
++ { NULL, NULL, 0, 0, NULL } |
13996 |
+ }; |
13997 |
+ |
13998 |
+ |
13999 |
+diff -Nurp linux-2.6.23.15/drivers/video/fbcmap.c linux-2.6.23.15-grsec/drivers/video/fbcmap.c |
14000 |
+--- linux-2.6.23.15/drivers/video/fbcmap.c 2007-10-09 21:31:38.000000000 +0100 |
14001 |
++++ linux-2.6.23.15-grsec/drivers/video/fbcmap.c 2008-02-11 10:37:44.000000000 +0000 |
14002 |
+@@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user |
14003 |
+ int rc, size = cmap->len * sizeof(u16); |
14004 |
+ struct fb_cmap umap; |
14005 |
+ |
14006 |
+- if (cmap->start < 0 || (!info->fbops->fb_setcolreg && |
14007 |
+- !info->fbops->fb_setcmap)) |
14008 |
++ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap) |
14009 |
+ return -EINVAL; |
14010 |
+ |
14011 |
+ memset(&umap, 0, sizeof(struct fb_cmap)); |
14012 |
+diff -Nurp linux-2.6.23.15/drivers/video/fbmem.c linux-2.6.23.15-grsec/drivers/video/fbmem.c |
14013 |
+--- linux-2.6.23.15/drivers/video/fbmem.c 2007-10-09 21:31:38.000000000 +0100 |
14014 |
++++ linux-2.6.23.15-grsec/drivers/video/fbmem.c 2008-02-11 10:37:44.000000000 +0000 |
14015 |
+@@ -394,7 +394,7 @@ static void fb_do_show_logo(struct fb_in |
14016 |
+ image->dx += image->width + 8; |
14017 |
+ } |
14018 |
+ } else if (rotate == FB_ROTATE_UD) { |
14019 |
+- for (x = 0; x < num && image->dx >= 0; x++) { |
14020 |
++ for (x = 0; x < num && (__s32)image->dx >= 0; x++) { |
14021 |
+ info->fbops->fb_imageblit(info, image); |
14022 |
+ image->dx -= image->width + 8; |
14023 |
+ } |
14024 |
+@@ -406,7 +406,7 @@ static void fb_do_show_logo(struct fb_in |
14025 |
+ image->dy += image->height + 8; |
14026 |
+ } |
14027 |
+ } else if (rotate == FB_ROTATE_CCW) { |
14028 |
+- for (x = 0; x < num && image->dy >= 0; x++) { |
14029 |
++ for (x = 0; x < num && (__s32)image->dy >= 0; x++) { |
14030 |
+ info->fbops->fb_imageblit(info, image); |
14031 |
+ image->dy -= image->height + 8; |
14032 |
+ } |
14033 |
+@@ -1057,9 +1057,9 @@ fb_ioctl(struct inode *inode, struct fil |
14034 |
+ case FBIOPUT_CON2FBMAP: |
14035 |
+ if (copy_from_user(&con2fb, argp, sizeof(con2fb))) |
14036 |
+ return - EFAULT; |
14037 |
+- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES) |
14038 |
++ if (con2fb.console > MAX_NR_CONSOLES) |
14039 |
+ return -EINVAL; |
14040 |
+- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) |
14041 |
++ if (con2fb.framebuffer >= FB_MAX) |
14042 |
+ return -EINVAL; |
14043 |
+ #ifdef CONFIG_KMOD |
14044 |
+ if (!registered_fb[con2fb.framebuffer]) |
14045 |
+diff -Nurp linux-2.6.23.15/drivers/video/fbmon.c linux-2.6.23.15-grsec/drivers/video/fbmon.c |
14046 |
+--- linux-2.6.23.15/drivers/video/fbmon.c 2007-10-09 21:31:38.000000000 +0100 |
14047 |
++++ linux-2.6.23.15-grsec/drivers/video/fbmon.c 2008-02-11 10:37:44.000000000 +0000 |
14048 |
+@@ -45,7 +45,7 @@ |
14049 |
+ #ifdef DEBUG |
14050 |
+ #define DPRINTK(fmt, args...) printk(fmt,## args) |
14051 |
+ #else |
14052 |
+-#define DPRINTK(fmt, args...) |
14053 |
++#define DPRINTK(fmt, args...) do {} while (0) |
14054 |
+ #endif |
14055 |
+ |
14056 |
+ #define FBMON_FIX_HEADER 1 |
14057 |
+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 |
14058 |
+--- linux-2.6.23.15/drivers/video/i810/i810_accel.c 2007-10-09 21:31:38.000000000 +0100 |
14059 |
++++ linux-2.6.23.15-grsec/drivers/video/i810/i810_accel.c 2008-02-11 10:37:44.000000000 +0000 |
14060 |
+@@ -73,6 +73,7 @@ static inline int wait_for_space(struct |
14061 |
+ } |
14062 |
+ } |
14063 |
+ printk("ringbuffer lockup!!!\n"); |
14064 |
++ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space); |
14065 |
+ i810_report_error(mmio); |
14066 |
+ par->dev_flags |= LOCKUP; |
14067 |
+ info->pixmap.scan_align = 1; |
14068 |
+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 |
14069 |
+--- linux-2.6.23.15/drivers/video/i810/i810_main.c 2007-10-09 21:31:38.000000000 +0100 |
14070 |
++++ linux-2.6.23.15-grsec/drivers/video/i810/i810_main.c 2008-02-11 10:37:44.000000000 +0000 |
14071 |
+@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t |
14072 |
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, |
14073 |
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, |
14074 |
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 }, |
14075 |
+- { 0 }, |
14076 |
++ { 0, 0, 0, 0, 0, 0, 0 }, |
14077 |
+ }; |
14078 |
+ |
14079 |
+ static struct pci_driver i810fb_driver = { |
14080 |
+@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info |
14081 |
+ int size = ((cursor->image.width + 7) >> 3) * |
14082 |
+ cursor->image.height; |
14083 |
+ int i; |
14084 |
+- u8 *data = kmalloc(64 * 8, GFP_ATOMIC); |
14085 |
++ u8 *data = kmalloc(64 * 8, GFP_KERNEL); |
14086 |
+ |
14087 |
+ if (data == NULL) |
14088 |
+ return -ENOMEM; |
14089 |
+diff -Nurp linux-2.6.23.15/drivers/video/modedb.c linux-2.6.23.15-grsec/drivers/video/modedb.c |
14090 |
+--- linux-2.6.23.15/drivers/video/modedb.c 2007-10-09 21:31:38.000000000 +0100 |
14091 |
++++ linux-2.6.23.15-grsec/drivers/video/modedb.c 2008-02-11 10:37:44.000000000 +0000 |
14092 |
+@@ -37,228 +37,228 @@ static const struct fb_videomode modedb[ |
14093 |
+ { |
14094 |
+ /* 640x400 @ 70 Hz, 31.5 kHz hsync */ |
14095 |
+ NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2, |
14096 |
+- 0, FB_VMODE_NONINTERLACED |
14097 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14098 |
+ }, { |
14099 |
+ /* 640x480 @ 60 Hz, 31.5 kHz hsync */ |
14100 |
+ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, |
14101 |
+- 0, FB_VMODE_NONINTERLACED |
14102 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14103 |
+ }, { |
14104 |
+ /* 800x600 @ 56 Hz, 35.15 kHz hsync */ |
14105 |
+ NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2, |
14106 |
+- 0, FB_VMODE_NONINTERLACED |
14107 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14108 |
+ }, { |
14109 |
+ /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */ |
14110 |
+ NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8, |
14111 |
+- 0, FB_VMODE_INTERLACED |
14112 |
++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN |
14113 |
+ }, { |
14114 |
+ /* 640x400 @ 85 Hz, 37.86 kHz hsync */ |
14115 |
+ NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, |
14116 |
+- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14117 |
++ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14118 |
+ }, { |
14119 |
+ /* 640x480 @ 72 Hz, 36.5 kHz hsync */ |
14120 |
+ NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3, |
14121 |
+- 0, FB_VMODE_NONINTERLACED |
14122 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14123 |
+ }, { |
14124 |
+ /* 640x480 @ 75 Hz, 37.50 kHz hsync */ |
14125 |
+ NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, |
14126 |
+- 0, FB_VMODE_NONINTERLACED |
14127 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14128 |
+ }, { |
14129 |
+ /* 800x600 @ 60 Hz, 37.8 kHz hsync */ |
14130 |
+ NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, |
14131 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14132 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14133 |
+ }, { |
14134 |
+ /* 640x480 @ 85 Hz, 43.27 kHz hsync */ |
14135 |
+ NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3, |
14136 |
+- 0, FB_VMODE_NONINTERLACED |
14137 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14138 |
+ }, { |
14139 |
+ /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ |
14140 |
+ NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, |
14141 |
+- 0, FB_VMODE_INTERLACED |
14142 |
++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN |
14143 |
+ }, { |
14144 |
+ /* 800x600 @ 72 Hz, 48.0 kHz hsync */ |
14145 |
+ NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, |
14146 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14147 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14148 |
+ }, { |
14149 |
+ /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ |
14150 |
+ NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6, |
14151 |
+- 0, FB_VMODE_NONINTERLACED |
14152 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14153 |
+ }, { |
14154 |
+ /* 640x480 @ 100 Hz, 53.01 kHz hsync */ |
14155 |
+ NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6, |
14156 |
+- 0, FB_VMODE_NONINTERLACED |
14157 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14158 |
+ }, { |
14159 |
+ /* 1152x864 @ 60 Hz, 53.5 kHz hsync */ |
14160 |
+ NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8, |
14161 |
+- 0, FB_VMODE_NONINTERLACED |
14162 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14163 |
+ }, { |
14164 |
+ /* 800x600 @ 85 Hz, 55.84 kHz hsync */ |
14165 |
+ NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5, |
14166 |
+- 0, FB_VMODE_NONINTERLACED |
14167 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14168 |
+ }, { |
14169 |
+ /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ |
14170 |
+ NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, |
14171 |
+- 0, FB_VMODE_NONINTERLACED |
14172 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14173 |
+ }, { |
14174 |
+ /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */ |
14175 |
+ NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12, |
14176 |
+- 0, FB_VMODE_INTERLACED |
14177 |
++ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN |
14178 |
+ }, { |
14179 |
+ /* 800x600 @ 100 Hz, 64.02 kHz hsync */ |
14180 |
+ NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6, |
14181 |
+- 0, FB_VMODE_NONINTERLACED |
14182 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14183 |
+ }, { |
14184 |
+ /* 1024x768 @ 76 Hz, 62.5 kHz hsync */ |
14185 |
+ NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3, |
14186 |
+- 0, FB_VMODE_NONINTERLACED |
14187 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14188 |
+ }, { |
14189 |
+ /* 1152x864 @ 70 Hz, 62.4 kHz hsync */ |
14190 |
+ NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10, |
14191 |
+- 0, FB_VMODE_NONINTERLACED |
14192 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14193 |
+ }, { |
14194 |
+ /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */ |
14195 |
+ NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3, |
14196 |
+- 0, FB_VMODE_NONINTERLACED |
14197 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14198 |
+ }, { |
14199 |
+ /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ |
14200 |
+ NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, |
14201 |
+- 0, FB_VMODE_NONINTERLACED |
14202 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14203 |
+ }, { |
14204 |
+ /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ |
14205 |
+ NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, |
14206 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14207 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14208 |
+ }, { |
14209 |
+ /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ |
14210 |
+ NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3, |
14211 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14212 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14213 |
+ }, { |
14214 |
+ /* 1024x768 @ 85 Hz, 70.24 kHz hsync */ |
14215 |
+ NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6, |
14216 |
+- 0, FB_VMODE_NONINTERLACED |
14217 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14218 |
+ }, { |
14219 |
+ /* 1152x864 @ 78 Hz, 70.8 kHz hsync */ |
14220 |
+ NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12, |
14221 |
+- 0, FB_VMODE_NONINTERLACED |
14222 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14223 |
+ }, { |
14224 |
+ /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */ |
14225 |
+ NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8, |
14226 |
+- 0, FB_VMODE_NONINTERLACED |
14227 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14228 |
+ }, { |
14229 |
+ /* 1600x1200 @ 60Hz, 75.00 kHz hsync */ |
14230 |
+ NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3, |
14231 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14232 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14233 |
+ }, { |
14234 |
+ /* 1152x864 @ 84 Hz, 76.0 kHz hsync */ |
14235 |
+ NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12, |
14236 |
+- 0, FB_VMODE_NONINTERLACED |
14237 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14238 |
+ }, { |
14239 |
+ /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */ |
14240 |
+ NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3, |
14241 |
+- 0, FB_VMODE_NONINTERLACED |
14242 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14243 |
+ }, { |
14244 |
+ /* 1024x768 @ 100Hz, 80.21 kHz hsync */ |
14245 |
+ NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10, |
14246 |
+- 0, FB_VMODE_NONINTERLACED |
14247 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14248 |
+ }, { |
14249 |
+ /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */ |
14250 |
+ NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3, |
14251 |
+- 0, FB_VMODE_NONINTERLACED |
14252 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14253 |
+ }, { |
14254 |
+ /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */ |
14255 |
+ NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, |
14256 |
+- 0, FB_VMODE_NONINTERLACED |
14257 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14258 |
+ }, { |
14259 |
+ /* 1152x864 @ 100 Hz, 89.62 kHz hsync */ |
14260 |
+ NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19, |
14261 |
+- 0, FB_VMODE_NONINTERLACED |
14262 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14263 |
+ }, { |
14264 |
+ /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */ |
14265 |
+ NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, |
14266 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14267 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14268 |
+ }, { |
14269 |
+ /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */ |
14270 |
+ NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, |
14271 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14272 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14273 |
+ }, { |
14274 |
+ /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */ |
14275 |
+ NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6, |
14276 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14277 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14278 |
+ }, { |
14279 |
+ /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */ |
14280 |
+ NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3, |
14281 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14282 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14283 |
+ }, { |
14284 |
+ /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */ |
14285 |
+ NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15, |
14286 |
+- 0, FB_VMODE_NONINTERLACED |
14287 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14288 |
+ }, { |
14289 |
+ /* 1800x1440 @ 64Hz, 96.15 kHz hsync */ |
14290 |
+ NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3, |
14291 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14292 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14293 |
+ }, { |
14294 |
+ /* 1800x1440 @ 70Hz, 104.52 kHz hsync */ |
14295 |
+ NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3, |
14296 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14297 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14298 |
+ }, { |
14299 |
+ /* 512x384 @ 78 Hz, 31.50 kHz hsync */ |
14300 |
+ NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3, |
14301 |
+- 0, FB_VMODE_NONINTERLACED |
14302 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14303 |
+ }, { |
14304 |
+ /* 512x384 @ 85 Hz, 34.38 kHz hsync */ |
14305 |
+ NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3, |
14306 |
+- 0, FB_VMODE_NONINTERLACED |
14307 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14308 |
+ }, { |
14309 |
+ /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */ |
14310 |
+ NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1, |
14311 |
+- 0, FB_VMODE_DOUBLE |
14312 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14313 |
+ }, { |
14314 |
+ /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */ |
14315 |
+ NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1, |
14316 |
+- 0, FB_VMODE_DOUBLE |
14317 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14318 |
+ }, { |
14319 |
+ /* 320x240 @ 72 Hz, 36.5 kHz hsync */ |
14320 |
+ NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2, |
14321 |
+- 0, FB_VMODE_DOUBLE |
14322 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14323 |
+ }, { |
14324 |
+ /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */ |
14325 |
+ NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1, |
14326 |
+- 0, FB_VMODE_DOUBLE |
14327 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14328 |
+ }, { |
14329 |
+ /* 400x300 @ 60 Hz, 37.8 kHz hsync */ |
14330 |
+ NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2, |
14331 |
+- 0, FB_VMODE_DOUBLE |
14332 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14333 |
+ }, { |
14334 |
+ /* 400x300 @ 72 Hz, 48.0 kHz hsync */ |
14335 |
+ NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3, |
14336 |
+- 0, FB_VMODE_DOUBLE |
14337 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14338 |
+ }, { |
14339 |
+ /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */ |
14340 |
+ NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1, |
14341 |
+- 0, FB_VMODE_DOUBLE |
14342 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14343 |
+ }, { |
14344 |
+ /* 480x300 @ 60 Hz, 37.8 kHz hsync */ |
14345 |
+ NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2, |
14346 |
+- 0, FB_VMODE_DOUBLE |
14347 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14348 |
+ }, { |
14349 |
+ /* 480x300 @ 63 Hz, 39.6 kHz hsync */ |
14350 |
+ NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2, |
14351 |
+- 0, FB_VMODE_DOUBLE |
14352 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14353 |
+ }, { |
14354 |
+ /* 480x300 @ 72 Hz, 48.0 kHz hsync */ |
14355 |
+ NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, |
14356 |
+- 0, FB_VMODE_DOUBLE |
14357 |
++ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN |
14358 |
+ }, { |
14359 |
+ /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ |
14360 |
+ NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, |
14361 |
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
14362 |
+- FB_VMODE_NONINTERLACED |
14363 |
++ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14364 |
+ }, { |
14365 |
+ /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ |
14366 |
+ NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, |
14367 |
+- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED |
14368 |
++ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14369 |
+ }, { |
14370 |
+ /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ |
14371 |
+ NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5, |
14372 |
+- 0, FB_VMODE_NONINTERLACED |
14373 |
++ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN |
14374 |
+ }, |
14375 |
+ }; |
14376 |
+ |
14377 |
+diff -Nurp linux-2.6.23.15/drivers/video/vesafb.c linux-2.6.23.15-grsec/drivers/video/vesafb.c |
14378 |
+--- linux-2.6.23.15/drivers/video/vesafb.c 2007-10-09 21:31:38.000000000 +0100 |
14379 |
++++ linux-2.6.23.15-grsec/drivers/video/vesafb.c 2008-02-11 10:37:44.000000000 +0000 |
14380 |
+@@ -9,6 +9,7 @@ |
14381 |
+ */ |
14382 |
+ |
14383 |
+ #include <linux/module.h> |
14384 |
++#include <linux/moduleloader.h> |
14385 |
+ #include <linux/kernel.h> |
14386 |
+ #include <linux/errno.h> |
14387 |
+ #include <linux/string.h> |
14388 |
+@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl |
14389 |
+ unsigned int size_vmode; |
14390 |
+ unsigned int size_remap; |
14391 |
+ unsigned int size_total; |
14392 |
++ void *pmi_code = NULL; |
14393 |
+ |
14394 |
+ if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB) |
14395 |
+ return -ENODEV; |
14396 |
+@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl |
14397 |
+ size_remap = size_total; |
14398 |
+ vesafb_fix.smem_len = size_remap; |
14399 |
+ |
14400 |
+-#ifndef __i386__ |
14401 |
+- screen_info.vesapm_seg = 0; |
14402 |
+-#endif |
14403 |
+- |
14404 |
+ if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) { |
14405 |
+ printk(KERN_WARNING |
14406 |
+ "vesafb: cannot reserve video memory at 0x%lx\n", |
14407 |
+@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl |
14408 |
+ printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n", |
14409 |
+ vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages); |
14410 |
+ |
14411 |
++#ifdef __i386__ |
14412 |
++ |
14413 |
++#ifdef CONFIG_PAX_KERNEXEC |
14414 |
++ pmi_code = module_alloc_exec(screen_info.vesapm_size); |
14415 |
++ if (!pmi_code) |
14416 |
++#else |
14417 |
++ if (0) |
14418 |
++#endif |
14419 |
++ |
14420 |
++#endif |
14421 |
++ screen_info.vesapm_seg = 0; |
14422 |
++ |
14423 |
+ if (screen_info.vesapm_seg) { |
14424 |
+- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n", |
14425 |
+- screen_info.vesapm_seg,screen_info.vesapm_off); |
14426 |
++ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n", |
14427 |
++ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size); |
14428 |
+ } |
14429 |
+ |
14430 |
+ if (screen_info.vesapm_seg < 0xc000) |
14431 |
+@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl |
14432 |
+ |
14433 |
+ if (ypan || pmi_setpal) { |
14434 |
+ unsigned short *pmi_base; |
14435 |
+- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); |
14436 |
+- pmi_start = (void*)((char*)pmi_base + pmi_base[1]); |
14437 |
+- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]); |
14438 |
++ |
14439 |
++#ifdef CONFIG_PAX_KERNEXEC |
14440 |
++ unsigned long cr0; |
14441 |
++#endif |
14442 |
++ |
14443 |
++ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); |
14444 |
++ |
14445 |
++#ifdef CONFIG_PAX_KERNEXEC |
14446 |
++ pax_open_kernel(cr0); |
14447 |
++ memcpy(pmi_code, pmi_base, screen_info.vesapm_size); |
14448 |
++ pax_close_kernel(cr0); |
14449 |
++#else |
14450 |
++ pmi_code = pmi_base; |
14451 |
++#endif |
14452 |
++ |
14453 |
++ pmi_start = (void*)((char*)pmi_code + pmi_base[1]); |
14454 |
++ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]); |
14455 |
++ |
14456 |
++#ifdef CONFIG_PAX_KERNEXEC |
14457 |
++ pmi_start -= __KERNEL_TEXT_OFFSET; |
14458 |
++ pmi_pal -= __KERNEL_TEXT_OFFSET; |
14459 |
++#endif |
14460 |
++ |
14461 |
+ printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); |
14462 |
+ if (pmi_base[3]) { |
14463 |
+ printk(KERN_INFO "vesafb: pmi: ports = "); |
14464 |
+@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl |
14465 |
+ info->node, info->fix.id); |
14466 |
+ return 0; |
14467 |
+ err: |
14468 |
++ |
14469 |
++#ifdef CONFIG_PAX_KERNEXEC |
14470 |
++ module_free_exec(NULL, pmi_code); |
14471 |
++#endif |
14472 |
++ |
14473 |
+ if (info->screen_base) |
14474 |
+ iounmap(info->screen_base); |
14475 |
+ framebuffer_release(info); |
14476 |
+diff -Nurp linux-2.6.23.15/fs/Kconfig linux-2.6.23.15-grsec/fs/Kconfig |
14477 |
+--- linux-2.6.23.15/fs/Kconfig 2007-10-09 21:31:38.000000000 +0100 |
14478 |
++++ linux-2.6.23.15-grsec/fs/Kconfig 2008-02-11 10:37:44.000000000 +0000 |
14479 |
+@@ -909,7 +909,7 @@ config PROC_FS |
14480 |
+ |
14481 |
+ config PROC_KCORE |
14482 |
+ bool "/proc/kcore support" if !ARM |
14483 |
+- depends on PROC_FS && MMU |
14484 |
++ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD |
14485 |
+ |
14486 |
+ config PROC_VMCORE |
14487 |
+ bool "/proc/vmcore support (EXPERIMENTAL)" |
14488 |
+diff -Nurp linux-2.6.23.15/fs/binfmt_aout.c linux-2.6.23.15-grsec/fs/binfmt_aout.c |
14489 |
+--- linux-2.6.23.15/fs/binfmt_aout.c 2007-10-09 21:31:38.000000000 +0100 |
14490 |
++++ linux-2.6.23.15-grsec/fs/binfmt_aout.c 2008-02-11 10:37:44.000000000 +0000 |
14491 |
+@@ -24,6 +24,7 @@ |
14492 |
+ #include <linux/binfmts.h> |
14493 |
+ #include <linux/personality.h> |
14494 |
+ #include <linux/init.h> |
14495 |
++#include <linux/grsecurity.h> |
14496 |
+ |
14497 |
+ #include <asm/system.h> |
14498 |
+ #include <asm/uaccess.h> |
14499 |
+@@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st |
14500 |
+ /* If the size of the dump file exceeds the rlimit, then see what would happen |
14501 |
+ if we wrote the stack, but not the data area. */ |
14502 |
+ #ifdef __sparc__ |
14503 |
++ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1); |
14504 |
+ if ((dump.u_dsize+dump.u_ssize) > |
14505 |
+ current->signal->rlim[RLIMIT_CORE].rlim_cur) |
14506 |
+ dump.u_dsize = 0; |
14507 |
+ #else |
14508 |
++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1); |
14509 |
+ if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE > |
14510 |
+ current->signal->rlim[RLIMIT_CORE].rlim_cur) |
14511 |
+ dump.u_dsize = 0; |
14512 |
+@@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st |
14513 |
+ |
14514 |
+ /* Make sure we have enough room to write the stack and data areas. */ |
14515 |
+ #ifdef __sparc__ |
14516 |
++ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1); |
14517 |
+ if ((dump.u_ssize) > |
14518 |
+ current->signal->rlim[RLIMIT_CORE].rlim_cur) |
14519 |
+ dump.u_ssize = 0; |
14520 |
+ #else |
14521 |
++ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1); |
14522 |
+ if ((dump.u_ssize+1) * PAGE_SIZE > |
14523 |
+ current->signal->rlim[RLIMIT_CORE].rlim_cur) |
14524 |
+ dump.u_ssize = 0; |
14525 |
+@@ -294,6 +299,8 @@ static int load_aout_binary(struct linux |
14526 |
+ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; |
14527 |
+ if (rlim >= RLIM_INFINITY) |
14528 |
+ rlim = ~0; |
14529 |
++ |
14530 |
++ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1); |
14531 |
+ if (ex.a_data + ex.a_bss > rlim) |
14532 |
+ return -ENOMEM; |
14533 |
+ |
14534 |
+@@ -326,6 +333,28 @@ static int load_aout_binary(struct linux |
14535 |
+ current->mm->mmap = NULL; |
14536 |
+ compute_creds(bprm); |
14537 |
+ current->flags &= ~PF_FORKNOEXEC; |
14538 |
++ |
14539 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
14540 |
++ current->mm->pax_flags = 0UL; |
14541 |
++#endif |
14542 |
++ |
14543 |
++#ifdef CONFIG_PAX_PAGEEXEC |
14544 |
++ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) { |
14545 |
++ current->mm->pax_flags |= MF_PAX_PAGEEXEC; |
14546 |
++ |
14547 |
++#ifdef CONFIG_PAX_EMUTRAMP |
14548 |
++ if (N_FLAGS(ex) & F_PAX_EMUTRAMP) |
14549 |
++ current->mm->pax_flags |= MF_PAX_EMUTRAMP; |
14550 |
++#endif |
14551 |
++ |
14552 |
++#ifdef CONFIG_PAX_MPROTECT |
14553 |
++ if (!(N_FLAGS(ex) & F_PAX_MPROTECT)) |
14554 |
++ current->mm->pax_flags |= MF_PAX_MPROTECT; |
14555 |
++#endif |
14556 |
++ |
14557 |
++ } |
14558 |
++#endif |
14559 |
++ |
14560 |
+ #ifdef __sparc__ |
14561 |
+ if (N_MAGIC(ex) == NMAGIC) { |
14562 |
+ loff_t pos = fd_offset; |
14563 |
+@@ -421,7 +450,7 @@ static int load_aout_binary(struct linux |
14564 |
+ |
14565 |
+ down_write(¤t->mm->mmap_sem); |
14566 |
+ error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, |
14567 |
+- PROT_READ | PROT_WRITE | PROT_EXEC, |
14568 |
++ PROT_READ | PROT_WRITE, |
14569 |
+ MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, |
14570 |
+ fd_offset + ex.a_text); |
14571 |
+ up_write(¤t->mm->mmap_sem); |
14572 |
+diff -Nurp linux-2.6.23.15/fs/binfmt_elf.c linux-2.6.23.15-grsec/fs/binfmt_elf.c |
14573 |
+--- linux-2.6.23.15/fs/binfmt_elf.c 2007-10-09 21:31:38.000000000 +0100 |
14574 |
++++ linux-2.6.23.15-grsec/fs/binfmt_elf.c 2008-02-11 10:37:44.000000000 +0000 |
14575 |
+@@ -39,10 +39,21 @@ |
14576 |
+ #include <linux/random.h> |
14577 |
+ #include <linux/elf.h> |
14578 |
+ #include <linux/utsname.h> |
14579 |
++#include <linux/grsecurity.h> |
14580 |
++ |
14581 |
+ #include <asm/uaccess.h> |
14582 |
+ #include <asm/param.h> |
14583 |
+ #include <asm/page.h> |
14584 |
+ |
14585 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14586 |
++#include <asm/desc.h> |
14587 |
++#endif |
14588 |
++ |
14589 |
++#ifdef CONFIG_PAX_HOOK_ACL_FLAGS |
14590 |
++void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); |
14591 |
++EXPORT_SYMBOL(pax_set_initial_flags_func); |
14592 |
++#endif |
14593 |
++ |
14594 |
+ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); |
14595 |
+ static int load_elf_library(struct file *); |
14596 |
+ static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); |
14597 |
+@@ -84,6 +95,8 @@ static struct linux_binfmt elf_format = |
14598 |
+ |
14599 |
+ static int set_brk(unsigned long start, unsigned long end) |
14600 |
+ { |
14601 |
++ unsigned long e = end; |
14602 |
++ |
14603 |
+ start = ELF_PAGEALIGN(start); |
14604 |
+ end = ELF_PAGEALIGN(end); |
14605 |
+ if (end > start) { |
14606 |
+@@ -94,7 +107,7 @@ static int set_brk(unsigned long start, |
14607 |
+ if (BAD_ADDR(addr)) |
14608 |
+ return addr; |
14609 |
+ } |
14610 |
+- current->mm->start_brk = current->mm->brk = end; |
14611 |
++ current->mm->start_brk = current->mm->brk = e; |
14612 |
+ return 0; |
14613 |
+ } |
14614 |
+ |
14615 |
+@@ -325,10 +338,9 @@ static unsigned long load_elf_interp(str |
14616 |
+ { |
14617 |
+ struct elf_phdr *elf_phdata; |
14618 |
+ struct elf_phdr *eppnt; |
14619 |
+- unsigned long load_addr = 0; |
14620 |
+- int load_addr_set = 0; |
14621 |
++ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE; |
14622 |
+ unsigned long last_bss = 0, elf_bss = 0; |
14623 |
+- unsigned long error = ~0UL; |
14624 |
++ unsigned long error = -EINVAL; |
14625 |
+ int retval, i, size; |
14626 |
+ |
14627 |
+ /* First of all, some simple consistency checks */ |
14628 |
+@@ -367,66 +379,86 @@ static unsigned long load_elf_interp(str |
14629 |
+ goto out_close; |
14630 |
+ } |
14631 |
+ |
14632 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14633 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) |
14634 |
++ task_size = SEGMEXEC_TASK_SIZE; |
14635 |
++#endif |
14636 |
++ |
14637 |
+ eppnt = elf_phdata; |
14638 |
++ min_addr = task_size; |
14639 |
++ max_addr = 0; |
14640 |
++ error = -ENOMEM; |
14641 |
++ |
14642 |
+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { |
14643 |
+- if (eppnt->p_type == PT_LOAD) { |
14644 |
+- int elf_type = MAP_PRIVATE | MAP_DENYWRITE; |
14645 |
+- int elf_prot = 0; |
14646 |
+- unsigned long vaddr = 0; |
14647 |
+- unsigned long k, map_addr; |
14648 |
+- |
14649 |
+- if (eppnt->p_flags & PF_R) |
14650 |
+- elf_prot = PROT_READ; |
14651 |
+- if (eppnt->p_flags & PF_W) |
14652 |
+- elf_prot |= PROT_WRITE; |
14653 |
+- if (eppnt->p_flags & PF_X) |
14654 |
+- elf_prot |= PROT_EXEC; |
14655 |
+- vaddr = eppnt->p_vaddr; |
14656 |
+- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) |
14657 |
+- elf_type |= MAP_FIXED; |
14658 |
+- |
14659 |
+- map_addr = elf_map(interpreter, load_addr + vaddr, |
14660 |
+- eppnt, elf_prot, elf_type); |
14661 |
+- error = map_addr; |
14662 |
+- if (BAD_ADDR(map_addr)) |
14663 |
+- goto out_close; |
14664 |
+- |
14665 |
+- if (!load_addr_set && |
14666 |
+- interp_elf_ex->e_type == ET_DYN) { |
14667 |
+- load_addr = map_addr - ELF_PAGESTART(vaddr); |
14668 |
+- load_addr_set = 1; |
14669 |
+- } |
14670 |
++ if (eppnt->p_type != PT_LOAD) |
14671 |
++ continue; |
14672 |
+ |
14673 |
+- /* |
14674 |
+- * Check to see if the section's size will overflow the |
14675 |
+- * allowed task size. Note that p_filesz must always be |
14676 |
+- * <= p_memsize so it's only necessary to check p_memsz. |
14677 |
+- */ |
14678 |
+- k = load_addr + eppnt->p_vaddr; |
14679 |
+- if (BAD_ADDR(k) || |
14680 |
+- eppnt->p_filesz > eppnt->p_memsz || |
14681 |
+- eppnt->p_memsz > TASK_SIZE || |
14682 |
+- TASK_SIZE - eppnt->p_memsz < k) { |
14683 |
+- error = -ENOMEM; |
14684 |
+- goto out_close; |
14685 |
+- } |
14686 |
++ /* |
14687 |
++ * Check to see if the section's size will overflow the |
14688 |
++ * allowed task size. Note that p_filesz must always be |
14689 |
++ * <= p_memsize so it is only necessary to check p_memsz. |
14690 |
++ */ |
14691 |
++ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz) |
14692 |
++ goto out_close; |
14693 |
+ |
14694 |
+- /* |
14695 |
+- * Find the end of the file mapping for this phdr, and |
14696 |
+- * keep track of the largest address we see for this. |
14697 |
+- */ |
14698 |
+- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; |
14699 |
+- if (k > elf_bss) |
14700 |
+- elf_bss = k; |
14701 |
++ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr)) |
14702 |
++ min_addr = ELF_PAGESTART(eppnt->p_vaddr); |
14703 |
++ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz)) |
14704 |
++ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz); |
14705 |
++ } |
14706 |
++ if (min_addr >= max_addr || max_addr > task_size) |
14707 |
++ goto out_close; |
14708 |
+ |
14709 |
+- /* |
14710 |
+- * Do the same thing for the memory mapping - between |
14711 |
+- * elf_bss and last_bss is the bss section. |
14712 |
+- */ |
14713 |
+- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; |
14714 |
+- if (k > last_bss) |
14715 |
+- last_bss = k; |
14716 |
+- } |
14717 |
++ if (interp_elf_ex->e_type == ET_DYN) { |
14718 |
++ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE); |
14719 |
++ |
14720 |
++ if (load_addr >= task_size) |
14721 |
++ goto out_close; |
14722 |
++ |
14723 |
++ load_addr -= min_addr; |
14724 |
++ } |
14725 |
++ |
14726 |
++ eppnt = elf_phdata; |
14727 |
++ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { |
14728 |
++ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED; |
14729 |
++ int elf_prot = 0; |
14730 |
++ unsigned long vaddr = 0; |
14731 |
++ unsigned long k, map_addr; |
14732 |
++ |
14733 |
++ if (eppnt->p_type != PT_LOAD) |
14734 |
++ continue; |
14735 |
++ |
14736 |
++ if (eppnt->p_flags & PF_R) |
14737 |
++ elf_prot = PROT_READ; |
14738 |
++ if (eppnt->p_flags & PF_W) |
14739 |
++ elf_prot |= PROT_WRITE; |
14740 |
++ if (eppnt->p_flags & PF_X) |
14741 |
++ elf_prot |= PROT_EXEC; |
14742 |
++ vaddr = eppnt->p_vaddr; |
14743 |
++ |
14744 |
++ map_addr = elf_map(interpreter, load_addr + vaddr, |
14745 |
++ eppnt, elf_prot, elf_type); |
14746 |
++ error = map_addr; |
14747 |
++ if (BAD_ADDR(map_addr)) |
14748 |
++ goto out_close; |
14749 |
++ |
14750 |
++ k = load_addr + eppnt->p_vaddr; |
14751 |
++ |
14752 |
++ /* |
14753 |
++ * Find the end of the file mapping for this phdr, and |
14754 |
++ * keep track of the largest address we see for this. |
14755 |
++ */ |
14756 |
++ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; |
14757 |
++ if (k > elf_bss) |
14758 |
++ elf_bss = k; |
14759 |
++ |
14760 |
++ /* |
14761 |
++ * Do the same thing for the memory mapping - between |
14762 |
++ * elf_bss and last_bss is the bss section. |
14763 |
++ */ |
14764 |
++ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; |
14765 |
++ if (k > last_bss) |
14766 |
++ last_bss = k; |
14767 |
+ } |
14768 |
+ |
14769 |
+ /* |
14770 |
+@@ -454,6 +486,8 @@ static unsigned long load_elf_interp(str |
14771 |
+ |
14772 |
+ *interp_load_addr = load_addr; |
14773 |
+ error = ((unsigned long)interp_elf_ex->e_entry) + load_addr; |
14774 |
++ if (BAD_ADDR(error)) |
14775 |
++ error = -EFAULT; |
14776 |
+ |
14777 |
+ out_close: |
14778 |
+ kfree(elf_phdata); |
14779 |
+@@ -464,7 +498,7 @@ out: |
14780 |
+ static unsigned long load_aout_interp(struct exec *interp_ex, |
14781 |
+ struct file *interpreter) |
14782 |
+ { |
14783 |
+- unsigned long text_data, elf_entry = ~0UL; |
14784 |
++ unsigned long text_data, elf_entry = -EINVAL; |
14785 |
+ char __user * addr; |
14786 |
+ loff_t offset; |
14787 |
+ |
14788 |
+@@ -507,6 +541,177 @@ out: |
14789 |
+ return elf_entry; |
14790 |
+ } |
14791 |
+ |
14792 |
++#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE) |
14793 |
++static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata) |
14794 |
++{ |
14795 |
++ unsigned long pax_flags = 0UL; |
14796 |
++ |
14797 |
++#ifdef CONFIG_PAX_PAGEEXEC |
14798 |
++ if (elf_phdata->p_flags & PF_PAGEEXEC) |
14799 |
++ pax_flags |= MF_PAX_PAGEEXEC; |
14800 |
++#endif |
14801 |
++ |
14802 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14803 |
++ if (elf_phdata->p_flags & PF_SEGMEXEC) |
14804 |
++ pax_flags |= MF_PAX_SEGMEXEC; |
14805 |
++#endif |
14806 |
++ |
14807 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) |
14808 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
14809 |
++ if (nx_enabled) |
14810 |
++ pax_flags &= ~MF_PAX_SEGMEXEC; |
14811 |
++ else |
14812 |
++ pax_flags &= ~MF_PAX_PAGEEXEC; |
14813 |
++ } |
14814 |
++#endif |
14815 |
++ |
14816 |
++#ifdef CONFIG_PAX_EMUTRAMP |
14817 |
++ if (elf_phdata->p_flags & PF_EMUTRAMP) |
14818 |
++ pax_flags |= MF_PAX_EMUTRAMP; |
14819 |
++#endif |
14820 |
++ |
14821 |
++#ifdef CONFIG_PAX_MPROTECT |
14822 |
++ if (elf_phdata->p_flags & PF_MPROTECT) |
14823 |
++ pax_flags |= MF_PAX_MPROTECT; |
14824 |
++#endif |
14825 |
++ |
14826 |
++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) |
14827 |
++ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP)) |
14828 |
++ pax_flags |= MF_PAX_RANDMMAP; |
14829 |
++#endif |
14830 |
++ |
14831 |
++ return pax_flags; |
14832 |
++} |
14833 |
++#endif |
14834 |
++ |
14835 |
++#ifdef CONFIG_PAX_PT_PAX_FLAGS |
14836 |
++static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata) |
14837 |
++{ |
14838 |
++ unsigned long pax_flags = 0UL; |
14839 |
++ |
14840 |
++#ifdef CONFIG_PAX_PAGEEXEC |
14841 |
++ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC)) |
14842 |
++ pax_flags |= MF_PAX_PAGEEXEC; |
14843 |
++#endif |
14844 |
++ |
14845 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14846 |
++ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) |
14847 |
++ pax_flags |= MF_PAX_SEGMEXEC; |
14848 |
++#endif |
14849 |
++ |
14850 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) |
14851 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
14852 |
++ if (nx_enabled) |
14853 |
++ pax_flags &= ~MF_PAX_SEGMEXEC; |
14854 |
++ else |
14855 |
++ pax_flags &= ~MF_PAX_PAGEEXEC; |
14856 |
++ } |
14857 |
++#endif |
14858 |
++ |
14859 |
++#ifdef CONFIG_PAX_EMUTRAMP |
14860 |
++ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP)) |
14861 |
++ pax_flags |= MF_PAX_EMUTRAMP; |
14862 |
++#endif |
14863 |
++ |
14864 |
++#ifdef CONFIG_PAX_MPROTECT |
14865 |
++ if (!(elf_phdata->p_flags & PF_NOMPROTECT)) |
14866 |
++ pax_flags |= MF_PAX_MPROTECT; |
14867 |
++#endif |
14868 |
++ |
14869 |
++#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) |
14870 |
++ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP)) |
14871 |
++ pax_flags |= MF_PAX_RANDMMAP; |
14872 |
++#endif |
14873 |
++ |
14874 |
++ return pax_flags; |
14875 |
++} |
14876 |
++#endif |
14877 |
++ |
14878 |
++#ifdef CONFIG_PAX_EI_PAX |
14879 |
++static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex) |
14880 |
++{ |
14881 |
++ unsigned long pax_flags = 0UL; |
14882 |
++ |
14883 |
++#ifdef CONFIG_PAX_PAGEEXEC |
14884 |
++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) |
14885 |
++ pax_flags |= MF_PAX_PAGEEXEC; |
14886 |
++#endif |
14887 |
++ |
14888 |
++#ifdef CONFIG_PAX_SEGMEXEC |
14889 |
++ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) |
14890 |
++ pax_flags |= MF_PAX_SEGMEXEC; |
14891 |
++#endif |
14892 |
++ |
14893 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC) |
14894 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
14895 |
++ if (nx_enabled) |
14896 |
++ pax_flags &= ~MF_PAX_SEGMEXEC; |
14897 |
++ else |
14898 |
++ pax_flags &= ~MF_PAX_PAGEEXEC; |
14899 |
++ } |
14900 |
++#endif |
14901 |
++ |
14902 |
++#ifdef CONFIG_PAX_EMUTRAMP |
14903 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP)) |
14904 |
++ pax_flags |= MF_PAX_EMUTRAMP; |
14905 |
++#endif |
14906 |
++ |
14907 |
++#ifdef CONFIG_PAX_MPROTECT |
14908 |
++ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT)) |
14909 |
++ pax_flags |= MF_PAX_MPROTECT; |
14910 |
++#endif |
14911 |
++ |
14912 |
++#ifdef CONFIG_PAX_ASLR |
14913 |
++ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP)) |
14914 |
++ pax_flags |= MF_PAX_RANDMMAP; |
14915 |
++#endif |
14916 |
++ |
14917 |
++ return pax_flags; |
14918 |
++} |
14919 |
++#endif |
14920 |
++ |
14921 |
++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) |
14922 |
++static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata) |
14923 |
++{ |
14924 |
++ unsigned long pax_flags = 0UL; |
14925 |
++ |
14926 |
++#ifdef CONFIG_PAX_PT_PAX_FLAGS |
14927 |
++ unsigned long i; |
14928 |
++#endif |
14929 |
++ |
14930 |
++#ifdef CONFIG_PAX_EI_PAX |
14931 |
++ pax_flags = pax_parse_ei_pax(elf_ex); |
14932 |
++#endif |
14933 |
++ |
14934 |
++#ifdef CONFIG_PAX_PT_PAX_FLAGS |
14935 |
++ for (i = 0UL; i < elf_ex->e_phnum; i++) |
14936 |
++ if (elf_phdata[i].p_type == PT_PAX_FLAGS) { |
14937 |
++ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) || |
14938 |
++ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) || |
14939 |
++ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) || |
14940 |
++ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) || |
14941 |
++ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP))) |
14942 |
++ return -EINVAL; |
14943 |
++ |
14944 |
++#ifdef CONFIG_PAX_SOFTMODE |
14945 |
++ if (pax_softmode) |
14946 |
++ pax_flags = pax_parse_softmode(&elf_phdata[i]); |
14947 |
++ else |
14948 |
++#endif |
14949 |
++ |
14950 |
++ pax_flags = pax_parse_hardmode(&elf_phdata[i]); |
14951 |
++ break; |
14952 |
++ } |
14953 |
++#endif |
14954 |
++ |
14955 |
++ if (0 > pax_check_flags(&pax_flags)) |
14956 |
++ return -EINVAL; |
14957 |
++ |
14958 |
++ current->mm->pax_flags = pax_flags; |
14959 |
++ return 0; |
14960 |
++} |
14961 |
++#endif |
14962 |
++ |
14963 |
+ /* |
14964 |
+ * These are the functions used to load ELF style executables and shared |
14965 |
+ * libraries. There is no binary dependent code anywhere else. |
14966 |
+@@ -544,7 +749,7 @@ static int load_elf_binary(struct linux_ |
14967 |
+ char * elf_interpreter = NULL; |
14968 |
+ unsigned int interpreter_type = INTERPRETER_NONE; |
14969 |
+ unsigned char ibcs2_interpreter = 0; |
14970 |
+- unsigned long error; |
14971 |
++ unsigned long error = 0; |
14972 |
+ struct elf_phdr *elf_ppnt, *elf_phdata; |
14973 |
+ unsigned long elf_bss, elf_brk; |
14974 |
+ int elf_exec_fileno; |
14975 |
+@@ -556,12 +761,12 @@ static int load_elf_binary(struct linux_ |
14976 |
+ char passed_fileno[6]; |
14977 |
+ struct files_struct *files; |
14978 |
+ int executable_stack = EXSTACK_DEFAULT; |
14979 |
+- unsigned long def_flags = 0; |
14980 |
+ struct { |
14981 |
+ struct elfhdr elf_ex; |
14982 |
+ struct elfhdr interp_elf_ex; |
14983 |
+ struct exec interp_ex; |
14984 |
+ } *loc; |
14985 |
++ unsigned long task_size = TASK_SIZE; |
14986 |
+ |
14987 |
+ loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
14988 |
+ if (!loc) { |
14989 |
+@@ -788,14 +993,89 @@ static int load_elf_binary(struct linux_ |
14990 |
+ |
14991 |
+ /* OK, This is the point of no return */ |
14992 |
+ current->flags &= ~PF_FORKNOEXEC; |
14993 |
+- current->mm->def_flags = def_flags; |
14994 |
++ |
14995 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
14996 |
++ current->mm->pax_flags = 0UL; |
14997 |
++#endif |
14998 |
++ |
14999 |
++#ifdef CONFIG_PAX_DLRESOLVE |
15000 |
++ current->mm->call_dl_resolve = 0UL; |
15001 |
++#endif |
15002 |
++ |
15003 |
++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) |
15004 |
++ current->mm->call_syscall = 0UL; |
15005 |
++#endif |
15006 |
++ |
15007 |
++#ifdef CONFIG_PAX_ASLR |
15008 |
++ current->mm->delta_mmap = 0UL; |
15009 |
++ current->mm->delta_stack = 0UL; |
15010 |
++#endif |
15011 |
++ |
15012 |
++ current->mm->def_flags = 0; |
15013 |
++ |
15014 |
++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) |
15015 |
++ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) { |
15016 |
++ send_sig(SIGKILL, current, 0); |
15017 |
++ goto out_free_dentry; |
15018 |
++ } |
15019 |
++#endif |
15020 |
++ |
15021 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
15022 |
++ pax_set_initial_flags(bprm); |
15023 |
++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) |
15024 |
++ if (pax_set_initial_flags_func) |
15025 |
++ (pax_set_initial_flags_func)(bprm); |
15026 |
++#endif |
15027 |
++ |
15028 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
15029 |
++ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) { |
15030 |
++ current->mm->context.user_cs_limit = PAGE_SIZE; |
15031 |
++ current->mm->def_flags |= VM_PAGEEXEC; |
15032 |
++ } |
15033 |
++#endif |
15034 |
++ |
15035 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15036 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
15037 |
++ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE; |
15038 |
++ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE; |
15039 |
++ task_size = SEGMEXEC_TASK_SIZE; |
15040 |
++ } |
15041 |
++#endif |
15042 |
++ |
15043 |
++#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC) |
15044 |
++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15045 |
++ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu()); |
15046 |
++ put_cpu_no_resched(); |
15047 |
++ } |
15048 |
++#endif |
15049 |
++ |
15050 |
++#ifdef CONFIG_PAX_ASLR |
15051 |
++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) { |
15052 |
++ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT; |
15053 |
++ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT; |
15054 |
++ } |
15055 |
++#endif |
15056 |
++ |
15057 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15058 |
++ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) |
15059 |
++ executable_stack = EXSTACK_DEFAULT; |
15060 |
++#endif |
15061 |
+ |
15062 |
+ /* Do this immediately, since STACK_TOP as used in setup_arg_pages |
15063 |
+ may depend on the personality. */ |
15064 |
+ SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter); |
15065 |
++ |
15066 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15067 |
++ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))) |
15068 |
++#endif |
15069 |
++ |
15070 |
+ if (elf_read_implies_exec(loc->elf_ex, executable_stack)) |
15071 |
+ current->personality |= READ_IMPLIES_EXEC; |
15072 |
+ |
15073 |
++#ifdef CONFIG_PAX_ASLR |
15074 |
++ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP)) |
15075 |
++#endif |
15076 |
++ |
15077 |
+ if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
15078 |
+ current->flags |= PF_RANDOMIZE; |
15079 |
+ arch_pick_mmap_layout(current->mm); |
15080 |
+@@ -871,6 +1151,20 @@ static int load_elf_binary(struct linux_ |
15081 |
+ * might try to exec. This is because the brk will |
15082 |
+ * follow the loader, and is not movable. */ |
15083 |
+ load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); |
15084 |
++ |
15085 |
++#ifdef CONFIG_PAX_RANDMMAP |
15086 |
++ /* PaX: randomize base address at the default exe base if requested */ |
15087 |
++ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) { |
15088 |
++#ifdef CONFIG_SPARC64 |
15089 |
++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1); |
15090 |
++#else |
15091 |
++ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT; |
15092 |
++#endif |
15093 |
++ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias); |
15094 |
++ elf_flags |= MAP_FIXED; |
15095 |
++ } |
15096 |
++#endif |
15097 |
++ |
15098 |
+ } |
15099 |
+ |
15100 |
+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, |
15101 |
+@@ -903,9 +1197,9 @@ static int load_elf_binary(struct linux_ |
15102 |
+ * allowed task size. Note that p_filesz must always be |
15103 |
+ * <= p_memsz so it is only necessary to check p_memsz. |
15104 |
+ */ |
15105 |
+- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || |
15106 |
+- elf_ppnt->p_memsz > TASK_SIZE || |
15107 |
+- TASK_SIZE - elf_ppnt->p_memsz < k) { |
15108 |
++ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz || |
15109 |
++ elf_ppnt->p_memsz > task_size || |
15110 |
++ task_size - elf_ppnt->p_memsz < k) { |
15111 |
+ /* set_brk can never work. Avoid overflows. */ |
15112 |
+ send_sig(SIGKILL, current, 0); |
15113 |
+ retval = -EINVAL; |
15114 |
+@@ -933,6 +1227,11 @@ static int load_elf_binary(struct linux_ |
15115 |
+ start_data += load_bias; |
15116 |
+ end_data += load_bias; |
15117 |
+ |
15118 |
++#ifdef CONFIG_PAX_RANDMMAP |
15119 |
++ if (current->mm->pax_flags & MF_PAX_RANDMMAP) |
15120 |
++ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4); |
15121 |
++#endif |
15122 |
++ |
15123 |
+ /* Calling set_brk effectively mmaps the pages that we need |
15124 |
+ * for the bss and break sections. We must do this before |
15125 |
+ * mapping in the interpreter, to make sure it doesn't wind |
15126 |
+@@ -944,9 +1243,11 @@ static int load_elf_binary(struct linux_ |
15127 |
+ goto out_free_dentry; |
15128 |
+ } |
15129 |
+ if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) { |
15130 |
+- send_sig(SIGSEGV, current, 0); |
15131 |
+- retval = -EFAULT; /* Nobody gets to see this, but.. */ |
15132 |
+- goto out_free_dentry; |
15133 |
++ /* |
15134 |
++ * This bss-zeroing can fail if the ELF |
15135 |
++ * file specifies odd protections. So |
15136 |
++ * we don't check the return value |
15137 |
++ */ |
15138 |
+ } |
15139 |
+ |
15140 |
+ if (elf_interpreter) { |
15141 |
+@@ -1183,8 +1484,10 @@ static int dump_seek(struct file *file, |
15142 |
+ unsigned long n = off; |
15143 |
+ if (n > PAGE_SIZE) |
15144 |
+ n = PAGE_SIZE; |
15145 |
+- if (!dump_write(file, buf, n)) |
15146 |
++ if (!dump_write(file, buf, n)) { |
15147 |
++ free_page((unsigned long)buf); |
15148 |
+ return 0; |
15149 |
++ } |
15150 |
+ off -= n; |
15151 |
+ } |
15152 |
+ free_page((unsigned long)buf); |
15153 |
+@@ -1199,7 +1502,7 @@ static int dump_seek(struct file *file, |
15154 |
+ * |
15155 |
+ * I think we should skip something. But I am not sure how. H.J. |
15156 |
+ */ |
15157 |
+-static int maydump(struct vm_area_struct *vma, unsigned long mm_flags) |
15158 |
++static int maydump(struct vm_area_struct *vma, unsigned long mm_flags, long signr) |
15159 |
+ { |
15160 |
+ /* The vma can be set up to tell us the answer directly. */ |
15161 |
+ if (vma->vm_flags & VM_ALWAYSDUMP) |
15162 |
+@@ -1218,7 +1521,7 @@ static int maydump(struct vm_area_struct |
15163 |
+ } |
15164 |
+ |
15165 |
+ /* By default, if it hasn't been written to, don't write it out. */ |
15166 |
+- if (!vma->anon_vma) |
15167 |
++ if (signr != SIGKILL && !vma->anon_vma) |
15168 |
+ return test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags); |
15169 |
+ |
15170 |
+ return test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags); |
15171 |
+@@ -1275,8 +1578,11 @@ static int writenote(struct memelfnote * |
15172 |
+ #undef DUMP_WRITE |
15173 |
+ |
15174 |
+ #define DUMP_WRITE(addr, nr) \ |
15175 |
++ do { \ |
15176 |
++ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \ |
15177 |
+ if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ |
15178 |
+- goto end_coredump; |
15179 |
++ goto end_coredump; \ |
15180 |
++ } while (0); |
15181 |
+ #define DUMP_SEEK(off) \ |
15182 |
+ if (!dump_seek(file, (off))) \ |
15183 |
+ goto end_coredump; |
15184 |
+@@ -1676,7 +1982,7 @@ static int elf_core_dump(long signr, str |
15185 |
+ phdr.p_offset = offset; |
15186 |
+ phdr.p_vaddr = vma->vm_start; |
15187 |
+ phdr.p_paddr = 0; |
15188 |
+- phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0; |
15189 |
++ phdr.p_filesz = maydump(vma, mm_flags, signr) ? sz : 0; |
15190 |
+ phdr.p_memsz = sz; |
15191 |
+ offset += phdr.p_filesz; |
15192 |
+ phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; |
15193 |
+@@ -1720,7 +2026,7 @@ static int elf_core_dump(long signr, str |
15194 |
+ vma = next_vma(vma, gate_vma)) { |
15195 |
+ unsigned long addr; |
15196 |
+ |
15197 |
+- if (!maydump(vma, mm_flags)) |
15198 |
++ if (!maydump(vma, mm_flags, signr)) |
15199 |
+ continue; |
15200 |
+ |
15201 |
+ for (addr = vma->vm_start; |
15202 |
+@@ -1743,6 +2049,7 @@ static int elf_core_dump(long signr, str |
15203 |
+ flush_cache_page(vma, addr, |
15204 |
+ page_to_pfn(page)); |
15205 |
+ kaddr = kmap(page); |
15206 |
++ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1); |
15207 |
+ if ((size += PAGE_SIZE) > limit || |
15208 |
+ !dump_write(file, kaddr, |
15209 |
+ PAGE_SIZE)) { |
15210 |
+diff -Nurp linux-2.6.23.15/fs/binfmt_flat.c linux-2.6.23.15-grsec/fs/binfmt_flat.c |
15211 |
+--- linux-2.6.23.15/fs/binfmt_flat.c 2007-10-09 21:31:38.000000000 +0100 |
15212 |
++++ linux-2.6.23.15-grsec/fs/binfmt_flat.c 2008-02-11 10:37:44.000000000 +0000 |
15213 |
+@@ -559,7 +559,9 @@ static int load_flat_file(struct linux_b |
15214 |
+ realdatastart = (unsigned long) -ENOMEM; |
15215 |
+ printk("Unable to allocate RAM for process data, errno %d\n", |
15216 |
+ (int)-realdatastart); |
15217 |
++ down_write(¤t->mm->mmap_sem); |
15218 |
+ do_munmap(current->mm, textpos, text_len); |
15219 |
++ up_write(¤t->mm->mmap_sem); |
15220 |
+ ret = realdatastart; |
15221 |
+ goto err; |
15222 |
+ } |
15223 |
+@@ -581,8 +583,10 @@ static int load_flat_file(struct linux_b |
15224 |
+ } |
15225 |
+ if (result >= (unsigned long)-4096) { |
15226 |
+ printk("Unable to read data+bss, errno %d\n", (int)-result); |
15227 |
++ down_write(¤t->mm->mmap_sem); |
15228 |
+ do_munmap(current->mm, textpos, text_len); |
15229 |
+ do_munmap(current->mm, realdatastart, data_len + extra); |
15230 |
++ up_write(¤t->mm->mmap_sem); |
15231 |
+ ret = result; |
15232 |
+ goto err; |
15233 |
+ } |
15234 |
+@@ -655,8 +659,10 @@ static int load_flat_file(struct linux_b |
15235 |
+ } |
15236 |
+ if (result >= (unsigned long)-4096) { |
15237 |
+ printk("Unable to read code+data+bss, errno %d\n",(int)-result); |
15238 |
++ down_write(¤t->mm->mmap_sem); |
15239 |
+ do_munmap(current->mm, textpos, text_len + data_len + extra + |
15240 |
+ MAX_SHARED_LIBS * sizeof(unsigned long)); |
15241 |
++ up_write(¤t->mm->mmap_sem); |
15242 |
+ ret = result; |
15243 |
+ goto err; |
15244 |
+ } |
15245 |
+diff -Nurp linux-2.6.23.15/fs/binfmt_misc.c linux-2.6.23.15-grsec/fs/binfmt_misc.c |
15246 |
+--- linux-2.6.23.15/fs/binfmt_misc.c 2007-10-09 21:31:38.000000000 +0100 |
15247 |
++++ linux-2.6.23.15-grsec/fs/binfmt_misc.c 2008-02-11 10:37:44.000000000 +0000 |
15248 |
+@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux |
15249 |
+ struct files_struct *files = NULL; |
15250 |
+ |
15251 |
+ retval = -ENOEXEC; |
15252 |
+- if (!enabled) |
15253 |
++ if (!enabled || bprm->misc) |
15254 |
+ goto _ret; |
15255 |
+ |
15256 |
++ bprm->misc++; |
15257 |
++ |
15258 |
+ /* to keep locking time low, we copy the interpreter string */ |
15259 |
+ read_lock(&entries_lock); |
15260 |
+ fmt = check_file(bprm); |
15261 |
+@@ -720,7 +722,7 @@ static int bm_fill_super(struct super_bl |
15262 |
+ static struct tree_descr bm_files[] = { |
15263 |
+ [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO}, |
15264 |
+ [3] = {"register", &bm_register_operations, S_IWUSR}, |
15265 |
+- /* last one */ {""} |
15266 |
++ /* last one */ {"", NULL, 0} |
15267 |
+ }; |
15268 |
+ int err = simple_fill_super(sb, 0x42494e4d, bm_files); |
15269 |
+ if (!err) |
15270 |
+diff -Nurp linux-2.6.23.15/fs/buffer.c linux-2.6.23.15-grsec/fs/buffer.c |
15271 |
+--- linux-2.6.23.15/fs/buffer.c 2007-10-09 21:31:38.000000000 +0100 |
15272 |
++++ linux-2.6.23.15-grsec/fs/buffer.c 2008-02-11 10:37:44.000000000 +0000 |
15273 |
+@@ -41,6 +41,7 @@ |
15274 |
+ #include <linux/bitops.h> |
15275 |
+ #include <linux/mpage.h> |
15276 |
+ #include <linux/bit_spinlock.h> |
15277 |
++#include <linux/grsecurity.h> |
15278 |
+ |
15279 |
+ static int fsync_buffers_list(spinlock_t *lock, struct list_head *list); |
15280 |
+ |
15281 |
+@@ -2017,6 +2018,7 @@ static int __generic_cont_expand(struct |
15282 |
+ |
15283 |
+ err = -EFBIG; |
15284 |
+ limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
15285 |
++ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1); |
15286 |
+ if (limit != RLIM_INFINITY && size > (loff_t)limit) { |
15287 |
+ send_sig(SIGXFSZ, current, 0); |
15288 |
+ goto out; |
15289 |
+diff -Nurp linux-2.6.23.15/fs/cifs/cifs_uniupr.h linux-2.6.23.15-grsec/fs/cifs/cifs_uniupr.h |
15290 |
+--- linux-2.6.23.15/fs/cifs/cifs_uniupr.h 2007-10-09 21:31:38.000000000 +0100 |
15291 |
++++ linux-2.6.23.15-grsec/fs/cifs/cifs_uniupr.h 2008-02-11 10:37:44.000000000 +0000 |
15292 |
+@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa |
15293 |
+ {0x0490, 0x04cc, UniCaseRangeU0490}, |
15294 |
+ {0x1e00, 0x1ffc, UniCaseRangeU1e00}, |
15295 |
+ {0xff40, 0xff5a, UniCaseRangeUff40}, |
15296 |
+- {0} |
15297 |
++ {0, 0, NULL} |
15298 |
+ }; |
15299 |
+ #endif |
15300 |
+ |
15301 |
+diff -Nurp linux-2.6.23.15/fs/cifs/dir.c linux-2.6.23.15-grsec/fs/cifs/dir.c |
15302 |
+--- linux-2.6.23.15/fs/cifs/dir.c 2007-10-09 21:31:38.000000000 +0100 |
15303 |
++++ linux-2.6.23.15-grsec/fs/cifs/dir.c 2008-02-11 10:37:44.000000000 +0000 |
15304 |
+@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, stru |
15305 |
+ /* BB Do not bother to decode buf since no |
15306 |
+ local inode yet to put timestamps in, |
15307 |
+ but we can reuse it safely */ |
15308 |
+- int bytes_written; |
15309 |
++ unsigned int bytes_written; |
15310 |
+ struct win_dev *pdev; |
15311 |
+ pdev = (struct win_dev *)buf; |
15312 |
+ if (S_ISCHR(mode)) { |
15313 |
+diff -Nurp linux-2.6.23.15/fs/cifs/inode.c linux-2.6.23.15-grsec/fs/cifs/inode.c |
15314 |
+--- linux-2.6.23.15/fs/cifs/inode.c 2008-02-11 10:36:03.000000000 +0000 |
15315 |
++++ linux-2.6.23.15-grsec/fs/cifs/inode.c 2008-02-11 10:37:44.000000000 +0000 |
15316 |
+@@ -1470,7 +1470,7 @@ int cifs_setattr(struct dentry *direntry |
15317 |
+ atomic_dec(&open_file->wrtPending); |
15318 |
+ cFYI(1, ("SetFSize for attrs rc = %d", rc)); |
15319 |
+ if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
15320 |
+- int bytes_written; |
15321 |
++ unsigned int bytes_written; |
15322 |
+ rc = CIFSSMBWrite(xid, pTcon, |
15323 |
+ nfid, 0, attrs->ia_size, |
15324 |
+ &bytes_written, NULL, NULL, |
15325 |
+@@ -1503,7 +1503,7 @@ int cifs_setattr(struct dentry *direntry |
15326 |
+ cifs_sb->mnt_cifs_flags & |
15327 |
+ CIFS_MOUNT_MAP_SPECIAL_CHR); |
15328 |
+ if (rc == 0) { |
15329 |
+- int bytes_written; |
15330 |
++ unsigned int bytes_written; |
15331 |
+ rc = CIFSSMBWrite(xid, pTcon, |
15332 |
+ netfid, 0, |
15333 |
+ attrs->ia_size, |
15334 |
+diff -Nurp linux-2.6.23.15/fs/compat.c linux-2.6.23.15-grsec/fs/compat.c |
15335 |
+--- linux-2.6.23.15/fs/compat.c 2007-10-09 21:31:38.000000000 +0100 |
15336 |
++++ linux-2.6.23.15-grsec/fs/compat.c 2008-02-11 10:37:44.000000000 +0000 |
15337 |
+@@ -50,6 +50,7 @@ |
15338 |
+ #include <linux/poll.h> |
15339 |
+ #include <linux/mm.h> |
15340 |
+ #include <linux/eventpoll.h> |
15341 |
++#include <linux/grsecurity.h> |
15342 |
+ |
15343 |
+ #include <asm/uaccess.h> |
15344 |
+ #include <asm/mmu_context.h> |
15345 |
+@@ -1300,14 +1301,12 @@ static int compat_copy_strings(int argc, |
15346 |
+ if (!kmapped_page || kpos != (pos & PAGE_MASK)) { |
15347 |
+ struct page *page; |
15348 |
+ |
15349 |
+-#ifdef CONFIG_STACK_GROWSUP |
15350 |
+ ret = expand_stack_downwards(bprm->vma, pos); |
15351 |
+ if (ret < 0) { |
15352 |
+ /* We've exceed the stack rlimit. */ |
15353 |
+ ret = -E2BIG; |
15354 |
+ goto out; |
15355 |
+ } |
15356 |
+-#endif |
15357 |
+ ret = get_user_pages(current, bprm->mm, pos, |
15358 |
+ 1, 1, 1, &page, NULL); |
15359 |
+ if (ret <= 0) { |
15360 |
+@@ -1353,6 +1352,11 @@ int compat_do_execve(char * filename, |
15361 |
+ compat_uptr_t __user *envp, |
15362 |
+ struct pt_regs * regs) |
15363 |
+ { |
15364 |
++#ifdef CONFIG_GRKERNSEC |
15365 |
++ struct file *old_exec_file; |
15366 |
++ struct acl_subject_label *old_acl; |
15367 |
++ struct rlimit old_rlim[RLIM_NLIMITS]; |
15368 |
++#endif |
15369 |
+ struct linux_binprm *bprm; |
15370 |
+ struct file *file; |
15371 |
+ int retval; |
15372 |
+@@ -1373,6 +1377,14 @@ int compat_do_execve(char * filename, |
15373 |
+ bprm->filename = filename; |
15374 |
+ bprm->interp = filename; |
15375 |
+ |
15376 |
++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1); |
15377 |
++ retval = -EAGAIN; |
15378 |
++ if (gr_handle_nproc()) |
15379 |
++ goto out_file; |
15380 |
++ retval = -EACCES; |
15381 |
++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) |
15382 |
++ goto out_file; |
15383 |
++ |
15384 |
+ retval = bprm_mm_init(bprm); |
15385 |
+ if (retval) |
15386 |
+ goto out_file; |
15387 |
+@@ -1406,8 +1418,36 @@ int compat_do_execve(char * filename, |
15388 |
+ if (retval < 0) |
15389 |
+ goto out; |
15390 |
+ |
15391 |
++ if (!gr_tpe_allow(file)) { |
15392 |
++ retval = -EACCES; |
15393 |
++ goto out; |
15394 |
++ } |
15395 |
++ |
15396 |
++ if (gr_check_crash_exec(file)) { |
15397 |
++ retval = -EACCES; |
15398 |
++ goto out; |
15399 |
++ } |
15400 |
++ |
15401 |
++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); |
15402 |
++ |
15403 |
++ gr_handle_exec_args(bprm, (char __user * __user *)argv); |
15404 |
++ |
15405 |
++#ifdef CONFIG_GRKERNSEC |
15406 |
++ old_acl = current->acl; |
15407 |
++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim)); |
15408 |
++ old_exec_file = current->exec_file; |
15409 |
++ get_file(file); |
15410 |
++ current->exec_file = file; |
15411 |
++#endif |
15412 |
++ |
15413 |
++ gr_set_proc_label(file->f_dentry, file->f_vfsmnt); |
15414 |
++ |
15415 |
+ retval = search_binary_handler(bprm, regs); |
15416 |
+ if (retval >= 0) { |
15417 |
++#ifdef CONFIG_GRKERNSEC |
15418 |
++ if (old_exec_file) |
15419 |
++ fput(old_exec_file); |
15420 |
++#endif |
15421 |
+ /* execve success */ |
15422 |
+ security_bprm_free(bprm); |
15423 |
+ acct_update_integrals(current); |
15424 |
+@@ -1415,6 +1455,13 @@ int compat_do_execve(char * filename, |
15425 |
+ return retval; |
15426 |
+ } |
15427 |
+ |
15428 |
++#ifdef CONFIG_GRKERNSEC |
15429 |
++ current->acl = old_acl; |
15430 |
++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim)); |
15431 |
++ fput(current->exec_file); |
15432 |
++ current->exec_file = old_exec_file; |
15433 |
++#endif |
15434 |
++ |
15435 |
+ out: |
15436 |
+ if (bprm->security) |
15437 |
+ security_bprm_free(bprm); |
15438 |
+diff -Nurp linux-2.6.23.15/fs/compat_ioctl.c linux-2.6.23.15-grsec/fs/compat_ioctl.c |
15439 |
+--- linux-2.6.23.15/fs/compat_ioctl.c 2007-10-09 21:31:38.000000000 +0100 |
15440 |
++++ linux-2.6.23.15-grsec/fs/compat_ioctl.c 2008-02-11 10:37:44.000000000 +0000 |
15441 |
+@@ -2431,15 +2431,15 @@ struct ioctl_trans { |
15442 |
+ }; |
15443 |
+ |
15444 |
+ #define HANDLE_IOCTL(cmd,handler) \ |
15445 |
+- { (cmd), (ioctl_trans_handler_t)(handler) }, |
15446 |
++ { (cmd), (ioctl_trans_handler_t)(handler), NULL }, |
15447 |
+ |
15448 |
+ /* pointer to compatible structure or no argument */ |
15449 |
+ #define COMPATIBLE_IOCTL(cmd) \ |
15450 |
+- { (cmd), do_ioctl32_pointer }, |
15451 |
++ { (cmd), do_ioctl32_pointer, NULL }, |
15452 |
+ |
15453 |
+ /* argument is an unsigned long integer, not a pointer */ |
15454 |
+ #define ULONG_IOCTL(cmd) \ |
15455 |
+- { (cmd), (ioctl_trans_handler_t)sys_ioctl }, |
15456 |
++ { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL }, |
15457 |
+ |
15458 |
+ /* ioctl should not be warned about even if it's not implemented. |
15459 |
+ Valid reasons to use this: |
15460 |
+diff -Nurp linux-2.6.23.15/fs/debugfs/inode.c linux-2.6.23.15-grsec/fs/debugfs/inode.c |
15461 |
+--- linux-2.6.23.15/fs/debugfs/inode.c 2007-10-09 21:31:38.000000000 +0100 |
15462 |
++++ linux-2.6.23.15-grsec/fs/debugfs/inode.c 2008-02-11 10:37:44.000000000 +0000 |
15463 |
+@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc |
15464 |
+ |
15465 |
+ static int debug_fill_super(struct super_block *sb, void *data, int silent) |
15466 |
+ { |
15467 |
+- static struct tree_descr debug_files[] = {{""}}; |
15468 |
++ static struct tree_descr debug_files[] = {{"", NULL, 0}}; |
15469 |
+ |
15470 |
+ return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files); |
15471 |
+ } |
15472 |
+diff -Nurp linux-2.6.23.15/fs/exec.c linux-2.6.23.15-grsec/fs/exec.c |
15473 |
+--- linux-2.6.23.15/fs/exec.c 2008-02-11 10:36:03.000000000 +0000 |
15474 |
++++ linux-2.6.23.15-grsec/fs/exec.c 2008-02-11 10:37:44.000000000 +0000 |
15475 |
+@@ -50,6 +50,8 @@ |
15476 |
+ #include <linux/tsacct_kern.h> |
15477 |
+ #include <linux/cn_proc.h> |
15478 |
+ #include <linux/audit.h> |
15479 |
++#include <linux/random.h> |
15480 |
++#include <linux/grsecurity.h> |
15481 |
+ |
15482 |
+ #include <asm/uaccess.h> |
15483 |
+ #include <asm/mmu_context.h> |
15484 |
+@@ -184,18 +186,10 @@ static struct page *get_arg_page(struct |
15485 |
+ int write) |
15486 |
+ { |
15487 |
+ struct page *page; |
15488 |
+- int ret; |
15489 |
+ |
15490 |
+-#ifdef CONFIG_STACK_GROWSUP |
15491 |
+- if (write) { |
15492 |
+- ret = expand_stack_downwards(bprm->vma, pos); |
15493 |
+- if (ret < 0) |
15494 |
+- return NULL; |
15495 |
+- } |
15496 |
+-#endif |
15497 |
+- ret = get_user_pages(current, bprm->mm, pos, |
15498 |
+- 1, write, 1, &page, NULL); |
15499 |
+- if (ret <= 0) |
15500 |
++ if (0 > expand_stack_downwards(bprm->vma, pos)) |
15501 |
++ return NULL; |
15502 |
++ if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL)) |
15503 |
+ return NULL; |
15504 |
+ |
15505 |
+ if (write) { |
15506 |
+@@ -260,7 +254,12 @@ static int __bprm_mm_init(struct linux_b |
15507 |
+ vma->vm_start = vma->vm_end - PAGE_SIZE; |
15508 |
+ |
15509 |
+ vma->vm_flags = VM_STACK_FLAGS; |
15510 |
+- vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; |
15511 |
++ |
15512 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15513 |
++ vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC); |
15514 |
++#endif |
15515 |
++ |
15516 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
15517 |
+ err = insert_vm_struct(mm, vma); |
15518 |
+ if (err) { |
15519 |
+ up_write(&mm->mmap_sem); |
15520 |
+@@ -272,6 +271,11 @@ static int __bprm_mm_init(struct linux_b |
15521 |
+ |
15522 |
+ bprm->p = vma->vm_end - sizeof(void *); |
15523 |
+ |
15524 |
++#ifdef CONFIG_PAX_RANDUSTACK |
15525 |
++ if (randomize_va_space) |
15526 |
++ bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK; |
15527 |
++#endif |
15528 |
++ |
15529 |
+ return 0; |
15530 |
+ |
15531 |
+ err: |
15532 |
+@@ -395,7 +399,7 @@ static int count(char __user * __user * |
15533 |
+ if (!p) |
15534 |
+ break; |
15535 |
+ argv++; |
15536 |
+- if(++i > max) |
15537 |
++ if (++i > max) |
15538 |
+ return -E2BIG; |
15539 |
+ cond_resched(); |
15540 |
+ } |
15541 |
+@@ -535,6 +539,10 @@ static int shift_arg_pages(struct vm_are |
15542 |
+ if (vma != find_vma(mm, new_start)) |
15543 |
+ return -EFAULT; |
15544 |
+ |
15545 |
++#ifdef CONFIG_PAX_SEGMEXEC |
15546 |
++ BUG_ON(pax_find_mirror_vma(vma)); |
15547 |
++#endif |
15548 |
++ |
15549 |
+ /* |
15550 |
+ * cover the whole range: [new_start, old_end) |
15551 |
+ */ |
15552 |
+@@ -623,6 +631,14 @@ int setup_arg_pages(struct linux_binprm |
15553 |
+ bprm->exec -= stack_shift; |
15554 |
+ |
15555 |
+ down_write(&mm->mmap_sem); |
15556 |
++ |
15557 |
++ /* Move stack pages down in memory. */ |
15558 |
++ if (stack_shift) { |
15559 |
++ ret = shift_arg_pages(vma, stack_shift); |
15560 |
++ if (ret) |
15561 |
++ goto out_unlock; |
15562 |
++ } |
15563 |
++ |
15564 |
+ vm_flags = vma->vm_flags; |
15565 |
+ |
15566 |
+ /* |
15567 |
+@@ -634,23 +650,28 @@ int setup_arg_pages(struct linux_binprm |
15568 |
+ vm_flags |= VM_EXEC; |
15569 |
+ else if (executable_stack == EXSTACK_DISABLE_X) |
15570 |
+ vm_flags &= ~VM_EXEC; |
15571 |
++ else |
15572 |
++ vm_flags = VM_STACK_FLAGS; |
15573 |
+ vm_flags |= mm->def_flags; |
15574 |
+ |
15575 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15576 |
++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
15577 |
++ vm_flags &= ~VM_EXEC; |
15578 |
++ |
15579 |
++#ifdef CONFIG_PAX_MPROTECT |
15580 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) |
15581 |
++ vm_flags &= ~VM_MAYEXEC; |
15582 |
++#endif |
15583 |
++ |
15584 |
++ } |
15585 |
++#endif |
15586 |
++ |
15587 |
+ ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end, |
15588 |
+ vm_flags); |
15589 |
+ if (ret) |
15590 |
+ goto out_unlock; |
15591 |
+ BUG_ON(prev != vma); |
15592 |
+ |
15593 |
+- /* Move stack pages down in memory. */ |
15594 |
+- if (stack_shift) { |
15595 |
+- ret = shift_arg_pages(vma, stack_shift); |
15596 |
+- if (ret) { |
15597 |
+- up_write(&mm->mmap_sem); |
15598 |
+- return ret; |
15599 |
+- } |
15600 |
+- } |
15601 |
+- |
15602 |
+ #ifdef CONFIG_STACK_GROWSUP |
15603 |
+ stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE; |
15604 |
+ #else |
15605 |
+@@ -662,7 +683,7 @@ int setup_arg_pages(struct linux_binprm |
15606 |
+ |
15607 |
+ out_unlock: |
15608 |
+ up_write(&mm->mmap_sem); |
15609 |
+- return 0; |
15610 |
++ return ret; |
15611 |
+ } |
15612 |
+ EXPORT_SYMBOL(setup_arg_pages); |
15613 |
+ |
15614 |
+@@ -682,7 +703,7 @@ struct file *open_exec(const char *name) |
15615 |
+ file = ERR_PTR(-EACCES); |
15616 |
+ if (!(nd.mnt->mnt_flags & MNT_NOEXEC) && |
15617 |
+ S_ISREG(inode->i_mode)) { |
15618 |
+- int err = vfs_permission(&nd, MAY_EXEC); |
15619 |
++ err = vfs_permission(&nd, MAY_EXEC); |
15620 |
+ file = ERR_PTR(err); |
15621 |
+ if (!err) { |
15622 |
+ file = nameidata_to_filp(&nd, O_RDONLY); |
15623 |
+@@ -1339,6 +1360,11 @@ int do_execve(char * filename, |
15624 |
+ char __user *__user *envp, |
15625 |
+ struct pt_regs * regs) |
15626 |
+ { |
15627 |
++#ifdef CONFIG_GRKERNSEC |
15628 |
++ struct file *old_exec_file; |
15629 |
++ struct acl_subject_label *old_acl; |
15630 |
++ struct rlimit old_rlim[RLIM_NLIMITS]; |
15631 |
++#endif |
15632 |
+ struct linux_binprm *bprm; |
15633 |
+ struct file *file; |
15634 |
+ unsigned long env_p; |
15635 |
+@@ -1354,6 +1380,20 @@ int do_execve(char * filename, |
15636 |
+ if (IS_ERR(file)) |
15637 |
+ goto out_kfree; |
15638 |
+ |
15639 |
++ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1); |
15640 |
++ |
15641 |
++ if (gr_handle_nproc()) { |
15642 |
++ allow_write_access(file); |
15643 |
++ fput(file); |
15644 |
++ return -EAGAIN; |
15645 |
++ } |
15646 |
++ |
15647 |
++ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { |
15648 |
++ allow_write_access(file); |
15649 |
++ fput(file); |
15650 |
++ return -EACCES; |
15651 |
++ } |
15652 |
++ |
15653 |
+ sched_exec(); |
15654 |
+ |
15655 |
+ bprm->file = file; |
15656 |
+@@ -1395,8 +1435,38 @@ int do_execve(char * filename, |
15657 |
+ goto out; |
15658 |
+ bprm->argv_len = env_p - bprm->p; |
15659 |
+ |
15660 |
++ if (!gr_tpe_allow(file)) { |
15661 |
++ retval = -EACCES; |
15662 |
++ goto out; |
15663 |
++ } |
15664 |
++ |
15665 |
++ if (gr_check_crash_exec(file)) { |
15666 |
++ retval = -EACCES; |
15667 |
++ goto out; |
15668 |
++ } |
15669 |
++ |
15670 |
++ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); |
15671 |
++ |
15672 |
++ gr_handle_exec_args(bprm, argv); |
15673 |
++ |
15674 |
++#ifdef CONFIG_GRKERNSEC |
15675 |
++ old_acl = current->acl; |
15676 |
++ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim)); |
15677 |
++ old_exec_file = current->exec_file; |
15678 |
++ get_file(file); |
15679 |
++ current->exec_file = file; |
15680 |
++#endif |
15681 |
++ |
15682 |
++ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt); |
15683 |
++ if (retval < 0) |
15684 |
++ goto out_fail; |
15685 |
++ |
15686 |
+ retval = search_binary_handler(bprm,regs); |
15687 |
+ if (retval >= 0) { |
15688 |
++#ifdef CONFIG_GRKERNSEC |
15689 |
++ if (old_exec_file) |
15690 |
++ fput(old_exec_file); |
15691 |
++#endif |
15692 |
+ /* execve success */ |
15693 |
+ free_arg_pages(bprm); |
15694 |
+ security_bprm_free(bprm); |
15695 |
+@@ -1405,6 +1475,14 @@ int do_execve(char * filename, |
15696 |
+ return retval; |
15697 |
+ } |
15698 |
+ |
15699 |
++out_fail: |
15700 |
++#ifdef CONFIG_GRKERNSEC |
15701 |
++ current->acl = old_acl; |
15702 |
++ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim)); |
15703 |
++ fput(current->exec_file); |
15704 |
++ current->exec_file = old_exec_file; |
15705 |
++#endif |
15706 |
++ |
15707 |
+ out: |
15708 |
+ free_arg_pages(bprm); |
15709 |
+ if (bprm->security) |
15710 |
+@@ -1561,6 +1639,114 @@ out: |
15711 |
+ return ispipe; |
15712 |
+ } |
15713 |
+ |
15714 |
++int pax_check_flags(unsigned long *flags) |
15715 |
++{ |
15716 |
++ int retval = 0; |
15717 |
++ |
15718 |
++#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC) |
15719 |
++ if (*flags & MF_PAX_SEGMEXEC) |
15720 |
++ { |
15721 |
++ *flags &= ~MF_PAX_SEGMEXEC; |
15722 |
++ retval = -EINVAL; |
15723 |
++ } |
15724 |
++#endif |
15725 |
++ |
15726 |
++ if ((*flags & MF_PAX_PAGEEXEC) |
15727 |
++ |
15728 |
++#ifdef CONFIG_PAX_PAGEEXEC |
15729 |
++ && (*flags & MF_PAX_SEGMEXEC) |
15730 |
++#endif |
15731 |
++ |
15732 |
++ ) |
15733 |
++ { |
15734 |
++ *flags &= ~MF_PAX_PAGEEXEC; |
15735 |
++ retval = -EINVAL; |
15736 |
++ } |
15737 |
++ |
15738 |
++ if ((*flags & MF_PAX_MPROTECT) |
15739 |
++ |
15740 |
++#ifdef CONFIG_PAX_MPROTECT |
15741 |
++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) |
15742 |
++#endif |
15743 |
++ |
15744 |
++ ) |
15745 |
++ { |
15746 |
++ *flags &= ~MF_PAX_MPROTECT; |
15747 |
++ retval = -EINVAL; |
15748 |
++ } |
15749 |
++ |
15750 |
++ if ((*flags & MF_PAX_EMUTRAMP) |
15751 |
++ |
15752 |
++#ifdef CONFIG_PAX_EMUTRAMP |
15753 |
++ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) |
15754 |
++#endif |
15755 |
++ |
15756 |
++ ) |
15757 |
++ { |
15758 |
++ *flags &= ~MF_PAX_EMUTRAMP; |
15759 |
++ retval = -EINVAL; |
15760 |
++ } |
15761 |
++ |
15762 |
++ return retval; |
15763 |
++} |
15764 |
++ |
15765 |
++EXPORT_SYMBOL(pax_check_flags); |
15766 |
++ |
15767 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
15768 |
++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp) |
15769 |
++{ |
15770 |
++ struct task_struct *tsk = current; |
15771 |
++ struct mm_struct *mm = current->mm; |
15772 |
++ char *buffer_exec = (char *)__get_free_page(GFP_ATOMIC); |
15773 |
++ char *buffer_fault = (char *)__get_free_page(GFP_ATOMIC); |
15774 |
++ char *path_exec = NULL; |
15775 |
++ char *path_fault = NULL; |
15776 |
++ unsigned long start = 0UL, end = 0UL, offset = 0UL; |
15777 |
++ |
15778 |
++ if (buffer_exec && buffer_fault) { |
15779 |
++ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL; |
15780 |
++ |
15781 |
++ down_read(&mm->mmap_sem); |
15782 |
++ vma = mm->mmap; |
15783 |
++ while (vma && (!vma_exec || !vma_fault)) { |
15784 |
++ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) |
15785 |
++ vma_exec = vma; |
15786 |
++ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end) |
15787 |
++ vma_fault = vma; |
15788 |
++ vma = vma->vm_next; |
15789 |
++ } |
15790 |
++ if (vma_exec) { |
15791 |
++ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE); |
15792 |
++ if (IS_ERR(path_exec)) |
15793 |
++ path_exec = "<path too long>"; |
15794 |
++ } |
15795 |
++ if (vma_fault) { |
15796 |
++ start = vma_fault->vm_start; |
15797 |
++ end = vma_fault->vm_end; |
15798 |
++ offset = vma_fault->vm_pgoff << PAGE_SHIFT; |
15799 |
++ if (vma_fault->vm_file) { |
15800 |
++ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE); |
15801 |
++ if (IS_ERR(path_fault)) |
15802 |
++ path_fault = "<path too long>"; |
15803 |
++ } else |
15804 |
++ path_fault = "<anonymous mapping>"; |
15805 |
++ } |
15806 |
++ up_read(&mm->mmap_sem); |
15807 |
++ } |
15808 |
++ if (tsk->signal->curr_ip) |
15809 |
++ 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); |
15810 |
++ else |
15811 |
++ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset); |
15812 |
++ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " |
15813 |
++ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid, |
15814 |
++ tsk->uid, tsk->euid, pc, sp); |
15815 |
++ free_page((unsigned long)buffer_exec); |
15816 |
++ free_page((unsigned long)buffer_fault); |
15817 |
++ pax_report_insns(pc, sp); |
15818 |
++ do_coredump(SIGKILL, SIGKILL, regs); |
15819 |
++} |
15820 |
++#endif |
15821 |
++ |
15822 |
+ static void zap_process(struct task_struct *start) |
15823 |
+ { |
15824 |
+ struct task_struct *t; |
15825 |
+@@ -1753,6 +1939,10 @@ int do_coredump(long signr, int exit_cod |
15826 |
+ */ |
15827 |
+ clear_thread_flag(TIF_SIGPENDING); |
15828 |
+ |
15829 |
++ if (signr == SIGKILL || signr == SIGILL) |
15830 |
++ gr_handle_brute_attach(current); |
15831 |
++ |
15832 |
++ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1); |
15833 |
+ if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) |
15834 |
+ goto fail_unlock; |
15835 |
+ |
15836 |
+diff -Nurp linux-2.6.23.15/fs/ext2/balloc.c linux-2.6.23.15-grsec/fs/ext2/balloc.c |
15837 |
+--- linux-2.6.23.15/fs/ext2/balloc.c 2007-10-09 21:31:38.000000000 +0100 |
15838 |
++++ linux-2.6.23.15-grsec/fs/ext2/balloc.c 2008-02-11 10:37:44.000000000 +0000 |
15839 |
+@@ -111,7 +111,7 @@ static int reserve_blocks(struct super_b |
15840 |
+ if (free_blocks < count) |
15841 |
+ count = free_blocks; |
15842 |
+ |
15843 |
+- if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) && |
15844 |
++ if (free_blocks < root_blocks + count && !capable_nolog(CAP_SYS_RESOURCE) && |
15845 |
+ sbi->s_resuid != current->fsuid && |
15846 |
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
15847 |
+ /* |
15848 |
+diff -Nurp linux-2.6.23.15/fs/ext3/balloc.c linux-2.6.23.15-grsec/fs/ext3/balloc.c |
15849 |
+--- linux-2.6.23.15/fs/ext3/balloc.c 2007-10-09 21:31:38.000000000 +0100 |
15850 |
++++ linux-2.6.23.15-grsec/fs/ext3/balloc.c 2008-02-11 10:37:44.000000000 +0000 |
15851 |
+@@ -1359,7 +1359,7 @@ static int ext3_has_free_blocks(struct e |
15852 |
+ |
15853 |
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
15854 |
+ root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
15855 |
+- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
15856 |
++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && |
15857 |
+ sbi->s_resuid != current->fsuid && |
15858 |
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
15859 |
+ return 0; |
15860 |
+diff -Nurp linux-2.6.23.15/fs/ext3/namei.c linux-2.6.23.15-grsec/fs/ext3/namei.c |
15861 |
+--- linux-2.6.23.15/fs/ext3/namei.c 2007-10-09 21:31:38.000000000 +0100 |
15862 |
++++ linux-2.6.23.15-grsec/fs/ext3/namei.c 2008-02-11 10:37:44.000000000 +0000 |
15863 |
+@@ -1188,9 +1188,9 @@ static struct ext3_dir_entry_2 *do_split |
15864 |
+ u32 hash2; |
15865 |
+ struct dx_map_entry *map; |
15866 |
+ char *data1 = (*bh)->b_data, *data2; |
15867 |
+- unsigned split, move, size, i; |
15868 |
++ unsigned split, move, size; |
15869 |
+ struct ext3_dir_entry_2 *de = NULL, *de2; |
15870 |
+- int err = 0; |
15871 |
++ int i, err = 0; |
15872 |
+ |
15873 |
+ bh2 = ext3_append (handle, dir, &newblock, &err); |
15874 |
+ if (!(bh2)) { |
15875 |
+diff -Nurp linux-2.6.23.15/fs/ext3/xattr.c linux-2.6.23.15-grsec/fs/ext3/xattr.c |
15876 |
+--- linux-2.6.23.15/fs/ext3/xattr.c 2007-10-09 21:31:38.000000000 +0100 |
15877 |
++++ linux-2.6.23.15-grsec/fs/ext3/xattr.c 2008-02-11 10:37:44.000000000 +0000 |
15878 |
+@@ -89,8 +89,8 @@ |
15879 |
+ printk("\n"); \ |
15880 |
+ } while (0) |
15881 |
+ #else |
15882 |
+-# define ea_idebug(f...) |
15883 |
+-# define ea_bdebug(f...) |
15884 |
++# define ea_idebug(f...) do {} while (0) |
15885 |
++# define ea_bdebug(f...) do {} while (0) |
15886 |
+ #endif |
15887 |
+ |
15888 |
+ static void ext3_xattr_cache_insert(struct buffer_head *); |
15889 |
+diff -Nurp linux-2.6.23.15/fs/ext4/balloc.c linux-2.6.23.15-grsec/fs/ext4/balloc.c |
15890 |
+--- linux-2.6.23.15/fs/ext4/balloc.c 2007-10-09 21:31:38.000000000 +0100 |
15891 |
++++ linux-2.6.23.15-grsec/fs/ext4/balloc.c 2008-02-11 10:37:44.000000000 +0000 |
15892 |
+@@ -1376,7 +1376,7 @@ static int ext4_has_free_blocks(struct e |
15893 |
+ |
15894 |
+ free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
15895 |
+ root_blocks = ext4_r_blocks_count(sbi->s_es); |
15896 |
+- if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
15897 |
++ if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) && |
15898 |
+ sbi->s_resuid != current->fsuid && |
15899 |
+ (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
15900 |
+ return 0; |
15901 |
+diff -Nurp linux-2.6.23.15/fs/ext4/namei.c linux-2.6.23.15-grsec/fs/ext4/namei.c |
15902 |
+--- linux-2.6.23.15/fs/ext4/namei.c 2007-10-09 21:31:38.000000000 +0100 |
15903 |
++++ linux-2.6.23.15-grsec/fs/ext4/namei.c 2008-02-11 10:37:44.000000000 +0000 |
15904 |
+@@ -1186,9 +1186,9 @@ static struct ext4_dir_entry_2 *do_split |
15905 |
+ u32 hash2; |
15906 |
+ struct dx_map_entry *map; |
15907 |
+ char *data1 = (*bh)->b_data, *data2; |
15908 |
+- unsigned split, move, size, i; |
15909 |
++ unsigned split, move, size; |
15910 |
+ struct ext4_dir_entry_2 *de = NULL, *de2; |
15911 |
+- int err = 0; |
15912 |
++ int i, err = 0; |
15913 |
+ |
15914 |
+ bh2 = ext4_append (handle, dir, &newblock, &err); |
15915 |
+ if (!(bh2)) { |
15916 |
+diff -Nurp linux-2.6.23.15/fs/fcntl.c linux-2.6.23.15-grsec/fs/fcntl.c |
15917 |
+--- linux-2.6.23.15/fs/fcntl.c 2007-10-09 21:31:38.000000000 +0100 |
15918 |
++++ linux-2.6.23.15-grsec/fs/fcntl.c 2008-02-11 10:37:44.000000000 +0000 |
15919 |
+@@ -18,6 +18,7 @@ |
15920 |
+ #include <linux/ptrace.h> |
15921 |
+ #include <linux/signal.h> |
15922 |
+ #include <linux/rcupdate.h> |
15923 |
++#include <linux/grsecurity.h> |
15924 |
+ |
15925 |
+ #include <asm/poll.h> |
15926 |
+ #include <asm/siginfo.h> |
15927 |
+@@ -63,6 +64,7 @@ static int locate_fd(struct files_struct |
15928 |
+ struct fdtable *fdt; |
15929 |
+ |
15930 |
+ error = -EINVAL; |
15931 |
++ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0); |
15932 |
+ if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
15933 |
+ goto out; |
15934 |
+ |
15935 |
+@@ -82,6 +84,7 @@ repeat: |
15936 |
+ fdt->max_fds, start); |
15937 |
+ |
15938 |
+ error = -EMFILE; |
15939 |
++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); |
15940 |
+ if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
15941 |
+ goto out; |
15942 |
+ |
15943 |
+@@ -140,6 +143,8 @@ asmlinkage long sys_dup2(unsigned int ol |
15944 |
+ struct files_struct * files = current->files; |
15945 |
+ struct fdtable *fdt; |
15946 |
+ |
15947 |
++ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0); |
15948 |
++ |
15949 |
+ spin_lock(&files->file_lock); |
15950 |
+ if (!(file = fcheck(oldfd))) |
15951 |
+ goto out_unlock; |
15952 |
+@@ -458,7 +463,8 @@ static inline int sigio_perm(struct task |
15953 |
+ return (((fown->euid == 0) || |
15954 |
+ (fown->euid == p->suid) || (fown->euid == p->uid) || |
15955 |
+ (fown->uid == p->suid) || (fown->uid == p->uid)) && |
15956 |
+- !security_file_send_sigiotask(p, fown, sig)); |
15957 |
++ !security_file_send_sigiotask(p, fown, sig) && |
15958 |
++ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p)); |
15959 |
+ } |
15960 |
+ |
15961 |
+ static void send_sigio_to_task(struct task_struct *p, |
15962 |
+diff -Nurp linux-2.6.23.15/fs/fuse/control.c linux-2.6.23.15-grsec/fs/fuse/control.c |
15963 |
+--- linux-2.6.23.15/fs/fuse/control.c 2007-10-09 21:31:38.000000000 +0100 |
15964 |
++++ linux-2.6.23.15-grsec/fs/fuse/control.c 2008-02-11 10:37:44.000000000 +0000 |
15965 |
+@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co |
15966 |
+ |
15967 |
+ static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent) |
15968 |
+ { |
15969 |
+- struct tree_descr empty_descr = {""}; |
15970 |
++ struct tree_descr empty_descr = {"", NULL, 0}; |
15971 |
+ struct fuse_conn *fc; |
15972 |
+ int err; |
15973 |
+ |
15974 |
+diff -Nurp linux-2.6.23.15/fs/hfs/inode.c linux-2.6.23.15-grsec/fs/hfs/inode.c |
15975 |
+--- linux-2.6.23.15/fs/hfs/inode.c 2007-10-09 21:31:38.000000000 +0100 |
15976 |
++++ linux-2.6.23.15-grsec/fs/hfs/inode.c 2008-02-11 10:37:44.000000000 +0000 |
15977 |
+@@ -415,7 +415,7 @@ int hfs_write_inode(struct inode *inode, |
15978 |
+ |
15979 |
+ if (S_ISDIR(main_inode->i_mode)) { |
15980 |
+ if (fd.entrylength < sizeof(struct hfs_cat_dir)) |
15981 |
+- /* panic? */; |
15982 |
++ {/* panic? */} |
15983 |
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, |
15984 |
+ sizeof(struct hfs_cat_dir)); |
15985 |
+ if (rec.type != HFS_CDR_DIR || |
15986 |
+@@ -436,7 +436,7 @@ int hfs_write_inode(struct inode *inode, |
15987 |
+ sizeof(struct hfs_cat_file)); |
15988 |
+ } else { |
15989 |
+ if (fd.entrylength < sizeof(struct hfs_cat_file)) |
15990 |
+- /* panic? */; |
15991 |
++ {/* panic? */} |
15992 |
+ hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, |
15993 |
+ sizeof(struct hfs_cat_file)); |
15994 |
+ if (rec.type != HFS_CDR_FIL || |
15995 |
+diff -Nurp linux-2.6.23.15/fs/hfsplus/inode.c linux-2.6.23.15-grsec/fs/hfsplus/inode.c |
15996 |
+--- linux-2.6.23.15/fs/hfsplus/inode.c 2007-10-09 21:31:38.000000000 +0100 |
15997 |
++++ linux-2.6.23.15-grsec/fs/hfsplus/inode.c 2008-02-11 10:37:44.000000000 +0000 |
15998 |
+@@ -418,7 +418,7 @@ int hfsplus_cat_read_inode(struct inode |
15999 |
+ struct hfsplus_cat_folder *folder = &entry.folder; |
16000 |
+ |
16001 |
+ if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) |
16002 |
+- /* panic? */; |
16003 |
++ {/* panic? */} |
16004 |
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
16005 |
+ sizeof(struct hfsplus_cat_folder)); |
16006 |
+ hfsplus_get_perms(inode, &folder->permissions, 1); |
16007 |
+@@ -435,7 +435,7 @@ int hfsplus_cat_read_inode(struct inode |
16008 |
+ struct hfsplus_cat_file *file = &entry.file; |
16009 |
+ |
16010 |
+ if (fd->entrylength < sizeof(struct hfsplus_cat_file)) |
16011 |
+- /* panic? */; |
16012 |
++ {/* panic? */} |
16013 |
+ hfs_bnode_read(fd->bnode, &entry, fd->entryoffset, |
16014 |
+ sizeof(struct hfsplus_cat_file)); |
16015 |
+ |
16016 |
+@@ -491,7 +491,7 @@ int hfsplus_cat_write_inode(struct inode |
16017 |
+ struct hfsplus_cat_folder *folder = &entry.folder; |
16018 |
+ |
16019 |
+ if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) |
16020 |
+- /* panic? */; |
16021 |
++ {/* panic? */} |
16022 |
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
16023 |
+ sizeof(struct hfsplus_cat_folder)); |
16024 |
+ /* simple node checks? */ |
16025 |
+@@ -513,7 +513,7 @@ int hfsplus_cat_write_inode(struct inode |
16026 |
+ struct hfsplus_cat_file *file = &entry.file; |
16027 |
+ |
16028 |
+ if (fd.entrylength < sizeof(struct hfsplus_cat_file)) |
16029 |
+- /* panic? */; |
16030 |
++ {/* panic? */} |
16031 |
+ hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, |
16032 |
+ sizeof(struct hfsplus_cat_file)); |
16033 |
+ hfsplus_inode_write_fork(inode, &file->data_fork); |
16034 |
+diff -Nurp linux-2.6.23.15/fs/jffs2/debug.h linux-2.6.23.15-grsec/fs/jffs2/debug.h |
16035 |
+--- linux-2.6.23.15/fs/jffs2/debug.h 2007-10-09 21:31:38.000000000 +0100 |
16036 |
++++ linux-2.6.23.15-grsec/fs/jffs2/debug.h 2008-02-11 10:37:44.000000000 +0000 |
16037 |
+@@ -51,13 +51,13 @@ |
16038 |
+ #if CONFIG_JFFS2_FS_DEBUG > 0 |
16039 |
+ #define D1(x) x |
16040 |
+ #else |
16041 |
+-#define D1(x) |
16042 |
++#define D1(x) do {} while (0); |
16043 |
+ #endif |
16044 |
+ |
16045 |
+ #if CONFIG_JFFS2_FS_DEBUG > 1 |
16046 |
+ #define D2(x) x |
16047 |
+ #else |
16048 |
+-#define D2(x) |
16049 |
++#define D2(x) do {} while (0); |
16050 |
+ #endif |
16051 |
+ |
16052 |
+ /* The prefixes of JFFS2 messages */ |
16053 |
+@@ -113,68 +113,68 @@ |
16054 |
+ #ifdef JFFS2_DBG_READINODE_MESSAGES |
16055 |
+ #define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16056 |
+ #else |
16057 |
+-#define dbg_readinode(fmt, ...) |
16058 |
++#define dbg_readinode(fmt, ...) do {} while (0) |
16059 |
+ #endif |
16060 |
+ |
16061 |
+ /* Fragtree build debugging messages */ |
16062 |
+ #ifdef JFFS2_DBG_FRAGTREE_MESSAGES |
16063 |
+ #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16064 |
+ #else |
16065 |
+-#define dbg_fragtree(fmt, ...) |
16066 |
++#define dbg_fragtree(fmt, ...) do {} while (0) |
16067 |
+ #endif |
16068 |
+ #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES |
16069 |
+ #define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16070 |
+ #else |
16071 |
+-#define dbg_fragtree2(fmt, ...) |
16072 |
++#define dbg_fragtree2(fmt, ...) do {} while (0) |
16073 |
+ #endif |
16074 |
+ |
16075 |
+ /* Directory entry list manilulation debugging messages */ |
16076 |
+ #ifdef JFFS2_DBG_DENTLIST_MESSAGES |
16077 |
+ #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16078 |
+ #else |
16079 |
+-#define dbg_dentlist(fmt, ...) |
16080 |
++#define dbg_dentlist(fmt, ...) do {} while (0) |
16081 |
+ #endif |
16082 |
+ |
16083 |
+ /* Print the messages about manipulating node_refs */ |
16084 |
+ #ifdef JFFS2_DBG_NODEREF_MESSAGES |
16085 |
+ #define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16086 |
+ #else |
16087 |
+-#define dbg_noderef(fmt, ...) |
16088 |
++#define dbg_noderef(fmt, ...) do {} while (0) |
16089 |
+ #endif |
16090 |
+ |
16091 |
+ /* Manipulations with the list of inodes (JFFS2 inocache) */ |
16092 |
+ #ifdef JFFS2_DBG_INOCACHE_MESSAGES |
16093 |
+ #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16094 |
+ #else |
16095 |
+-#define dbg_inocache(fmt, ...) |
16096 |
++#define dbg_inocache(fmt, ...) do {} while (0) |
16097 |
+ #endif |
16098 |
+ |
16099 |
+ /* Summary debugging messages */ |
16100 |
+ #ifdef JFFS2_DBG_SUMMARY_MESSAGES |
16101 |
+ #define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16102 |
+ #else |
16103 |
+-#define dbg_summary(fmt, ...) |
16104 |
++#define dbg_summary(fmt, ...) do {} while (0) |
16105 |
+ #endif |
16106 |
+ |
16107 |
+ /* File system build messages */ |
16108 |
+ #ifdef JFFS2_DBG_FSBUILD_MESSAGES |
16109 |
+ #define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16110 |
+ #else |
16111 |
+-#define dbg_fsbuild(fmt, ...) |
16112 |
++#define dbg_fsbuild(fmt, ...) do {} while (0) |
16113 |
+ #endif |
16114 |
+ |
16115 |
+ /* Watch the object allocations */ |
16116 |
+ #ifdef JFFS2_DBG_MEMALLOC_MESSAGES |
16117 |
+ #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16118 |
+ #else |
16119 |
+-#define dbg_memalloc(fmt, ...) |
16120 |
++#define dbg_memalloc(fmt, ...) do {} while (0) |
16121 |
+ #endif |
16122 |
+ |
16123 |
+ /* Watch the XATTR subsystem */ |
16124 |
+ #ifdef JFFS2_DBG_XATTR_MESSAGES |
16125 |
+ #define dbg_xattr(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) |
16126 |
+ #else |
16127 |
+-#define dbg_xattr(fmt, ...) |
16128 |
++#define dbg_xattr(fmt, ...) do {} while (0) |
16129 |
+ #endif |
16130 |
+ |
16131 |
+ /* "Sanity" checks */ |
16132 |
+diff -Nurp linux-2.6.23.15/fs/jffs2/erase.c linux-2.6.23.15-grsec/fs/jffs2/erase.c |
16133 |
+--- linux-2.6.23.15/fs/jffs2/erase.c 2007-10-09 21:31:38.000000000 +0100 |
16134 |
++++ linux-2.6.23.15-grsec/fs/jffs2/erase.c 2008-02-11 10:37:44.000000000 +0000 |
16135 |
+@@ -389,7 +389,8 @@ static void jffs2_mark_erased_block(stru |
16136 |
+ struct jffs2_unknown_node marker = { |
16137 |
+ .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), |
16138 |
+ .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), |
16139 |
+- .totlen = cpu_to_je32(c->cleanmarker_size) |
16140 |
++ .totlen = cpu_to_je32(c->cleanmarker_size), |
16141 |
++ .hdr_crc = cpu_to_je32(0) |
16142 |
+ }; |
16143 |
+ |
16144 |
+ jffs2_prealloc_raw_node_refs(c, jeb, 1); |
16145 |
+diff -Nurp linux-2.6.23.15/fs/jffs2/summary.h linux-2.6.23.15-grsec/fs/jffs2/summary.h |
16146 |
+--- linux-2.6.23.15/fs/jffs2/summary.h 2007-10-09 21:31:38.000000000 +0100 |
16147 |
++++ linux-2.6.23.15-grsec/fs/jffs2/summary.h 2008-02-11 10:37:44.000000000 +0000 |
16148 |
+@@ -188,18 +188,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_ |
16149 |
+ |
16150 |
+ #define jffs2_sum_active() (0) |
16151 |
+ #define jffs2_sum_init(a) (0) |
16152 |
+-#define jffs2_sum_exit(a) |
16153 |
+-#define jffs2_sum_disable_collecting(a) |
16154 |
++#define jffs2_sum_exit(a) do {} while (0) |
16155 |
++#define jffs2_sum_disable_collecting(a) do {} while (0) |
16156 |
+ #define jffs2_sum_is_disabled(a) (0) |
16157 |
+-#define jffs2_sum_reset_collected(a) |
16158 |
++#define jffs2_sum_reset_collected(a) do {} while (0) |
16159 |
+ #define jffs2_sum_add_kvec(a,b,c,d) (0) |
16160 |
+-#define jffs2_sum_move_collected(a,b) |
16161 |
++#define jffs2_sum_move_collected(a,b) do {} while (0) |
16162 |
+ #define jffs2_sum_write_sumnode(a) (0) |
16163 |
+-#define jffs2_sum_add_padding_mem(a,b) |
16164 |
+-#define jffs2_sum_add_inode_mem(a,b,c) |
16165 |
+-#define jffs2_sum_add_dirent_mem(a,b,c) |
16166 |
+-#define jffs2_sum_add_xattr_mem(a,b,c) |
16167 |
+-#define jffs2_sum_add_xref_mem(a,b,c) |
16168 |
++#define jffs2_sum_add_padding_mem(a,b) do {} while (0) |
16169 |
++#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0) |
16170 |
++#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0) |
16171 |
++#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0) |
16172 |
++#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0) |
16173 |
+ #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0) |
16174 |
+ |
16175 |
+ #endif /* CONFIG_JFFS2_SUMMARY */ |
16176 |
+diff -Nurp linux-2.6.23.15/fs/jffs2/wbuf.c linux-2.6.23.15-grsec/fs/jffs2/wbuf.c |
16177 |
+--- linux-2.6.23.15/fs/jffs2/wbuf.c 2007-10-09 21:31:38.000000000 +0100 |
16178 |
++++ linux-2.6.23.15-grsec/fs/jffs2/wbuf.c 2008-02-11 10:37:44.000000000 +0000 |
16179 |
+@@ -973,7 +973,8 @@ static const struct jffs2_unknown_node o |
16180 |
+ { |
16181 |
+ .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK), |
16182 |
+ .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), |
16183 |
+- .totlen = constant_cpu_to_je32(8) |
16184 |
++ .totlen = constant_cpu_to_je32(8), |
16185 |
++ .hdr_crc = constant_cpu_to_je32(0) |
16186 |
+ }; |
16187 |
+ |
16188 |
+ /* |
16189 |
+diff -Nurp linux-2.6.23.15/fs/namei.c linux-2.6.23.15-grsec/fs/namei.c |
16190 |
+--- linux-2.6.23.15/fs/namei.c 2008-02-11 10:36:03.000000000 +0000 |
16191 |
++++ linux-2.6.23.15-grsec/fs/namei.c 2008-02-11 10:37:44.000000000 +0000 |
16192 |
+@@ -31,6 +31,7 @@ |
16193 |
+ #include <linux/file.h> |
16194 |
+ #include <linux/fcntl.h> |
16195 |
+ #include <linux/namei.h> |
16196 |
++#include <linux/grsecurity.h> |
16197 |
+ #include <asm/namei.h> |
16198 |
+ #include <asm/uaccess.h> |
16199 |
+ |
16200 |
+@@ -638,6 +639,13 @@ static inline int do_follow_link(struct |
16201 |
+ err = security_inode_follow_link(path->dentry, nd); |
16202 |
+ if (err) |
16203 |
+ goto loop; |
16204 |
++ |
16205 |
++ if (gr_handle_follow_link(path->dentry->d_parent->d_inode, |
16206 |
++ path->dentry->d_inode, path->dentry, nd->mnt)) { |
16207 |
++ err = -EACCES; |
16208 |
++ goto loop; |
16209 |
++ } |
16210 |
++ |
16211 |
+ current->link_count++; |
16212 |
+ current->total_link_count++; |
16213 |
+ nd->depth++; |
16214 |
+@@ -983,11 +991,18 @@ return_reval: |
16215 |
+ break; |
16216 |
+ } |
16217 |
+ return_base: |
16218 |
++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) { |
16219 |
++ path_release(nd); |
16220 |
++ return -ENOENT; |
16221 |
++ } |
16222 |
+ return 0; |
16223 |
+ out_dput: |
16224 |
+ dput_path(&next, nd); |
16225 |
+ break; |
16226 |
+ } |
16227 |
++ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) |
16228 |
++ err = -ENOENT; |
16229 |
++ |
16230 |
+ path_release(nd); |
16231 |
+ return_err: |
16232 |
+ return err; |
16233 |
+@@ -1649,9 +1664,17 @@ static int open_namei_create(struct name |
16234 |
+ int error; |
16235 |
+ struct dentry *dir = nd->dentry; |
16236 |
+ |
16237 |
++ if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) { |
16238 |
++ error = -EACCES; |
16239 |
++ goto out_unlock_dput; |
16240 |
++ } |
16241 |
++ |
16242 |
+ if (!IS_POSIXACL(dir->d_inode)) |
16243 |
+ mode &= ~current->fs->umask; |
16244 |
+ error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
16245 |
++ if (!error) |
16246 |
++ gr_handle_create(path->dentry, nd->mnt); |
16247 |
++out_unlock_dput: |
16248 |
+ mutex_unlock(&dir->d_inode->i_mutex); |
16249 |
+ dput(nd->dentry); |
16250 |
+ nd->dentry = path->dentry; |
16251 |
+@@ -1702,6 +1725,17 @@ int open_namei(int dfd, const char *path |
16252 |
+ nd, flag); |
16253 |
+ if (error) |
16254 |
+ return error; |
16255 |
++ |
16256 |
++ if (gr_handle_rawio(nd->dentry->d_inode)) { |
16257 |
++ error = -EPERM; |
16258 |
++ goto exit; |
16259 |
++ } |
16260 |
++ |
16261 |
++ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) { |
16262 |
++ error = -EACCES; |
16263 |
++ goto exit; |
16264 |
++ } |
16265 |
++ |
16266 |
+ goto ok; |
16267 |
+ } |
16268 |
+ |
16269 |
+@@ -1751,6 +1785,23 @@ do_last: |
16270 |
+ /* |
16271 |
+ * It already exists. |
16272 |
+ */ |
16273 |
++ |
16274 |
++ if (gr_handle_rawio(path.dentry->d_inode)) { |
16275 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
16276 |
++ error = -EPERM; |
16277 |
++ goto exit_dput; |
16278 |
++ } |
16279 |
++ if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) { |
16280 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
16281 |
++ error = -EACCES; |
16282 |
++ goto exit_dput; |
16283 |
++ } |
16284 |
++ if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) { |
16285 |
++ mutex_unlock(&dir->d_inode->i_mutex); |
16286 |
++ error = -EACCES; |
16287 |
++ goto exit_dput; |
16288 |
++ } |
16289 |
++ |
16290 |
+ mutex_unlock(&dir->d_inode->i_mutex); |
16291 |
+ audit_inode(pathname, path.dentry->d_inode); |
16292 |
+ |
16293 |
+@@ -1806,6 +1857,13 @@ do_link: |
16294 |
+ error = security_inode_follow_link(path.dentry, nd); |
16295 |
+ if (error) |
16296 |
+ goto exit_dput; |
16297 |
++ |
16298 |
++ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode, |
16299 |
++ path.dentry, nd->mnt)) { |
16300 |
++ error = -EACCES; |
16301 |
++ goto exit_dput; |
16302 |
++ } |
16303 |
++ |
16304 |
+ error = __do_follow_link(&path, nd); |
16305 |
+ if (error) { |
16306 |
+ /* Does someone understand code flow here? Or it is only |
16307 |
+@@ -1934,6 +1992,22 @@ asmlinkage long sys_mknodat(int dfd, con |
16308 |
+ if (!IS_POSIXACL(nd.dentry->d_inode)) |
16309 |
+ mode &= ~current->fs->umask; |
16310 |
+ if (!IS_ERR(dentry)) { |
16311 |
++ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) { |
16312 |
++ error = -EPERM; |
16313 |
++ dput(dentry); |
16314 |
++ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16315 |
++ path_release(&nd); |
16316 |
++ goto out; |
16317 |
++ } |
16318 |
++ |
16319 |
++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { |
16320 |
++ error = -EACCES; |
16321 |
++ dput(dentry); |
16322 |
++ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16323 |
++ path_release(&nd); |
16324 |
++ goto out; |
16325 |
++ } |
16326 |
++ |
16327 |
+ switch (mode & S_IFMT) { |
16328 |
+ case 0: case S_IFREG: |
16329 |
+ error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); |
16330 |
+@@ -1951,6 +2025,10 @@ asmlinkage long sys_mknodat(int dfd, con |
16331 |
+ default: |
16332 |
+ error = -EINVAL; |
16333 |
+ } |
16334 |
++ |
16335 |
++ if (!error) |
16336 |
++ gr_handle_create(dentry, nd.mnt); |
16337 |
++ |
16338 |
+ dput(dentry); |
16339 |
+ } |
16340 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16341 |
+@@ -2008,9 +2086,18 @@ asmlinkage long sys_mkdirat(int dfd, con |
16342 |
+ if (IS_ERR(dentry)) |
16343 |
+ goto out_unlock; |
16344 |
+ |
16345 |
++ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) { |
16346 |
++ error = -EACCES; |
16347 |
++ goto out_unlock_dput; |
16348 |
++ } |
16349 |
++ |
16350 |
+ if (!IS_POSIXACL(nd.dentry->d_inode)) |
16351 |
+ mode &= ~current->fs->umask; |
16352 |
+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); |
16353 |
++ |
16354 |
++ if (!error) |
16355 |
++ gr_handle_create(dentry, nd.mnt); |
16356 |
++out_unlock_dput: |
16357 |
+ dput(dentry); |
16358 |
+ out_unlock: |
16359 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16360 |
+@@ -2092,6 +2179,8 @@ static long do_rmdir(int dfd, const char |
16361 |
+ char * name; |
16362 |
+ struct dentry *dentry; |
16363 |
+ struct nameidata nd; |
16364 |
++ ino_t saved_ino = 0; |
16365 |
++ dev_t saved_dev = 0; |
16366 |
+ |
16367 |
+ name = getname(pathname); |
16368 |
+ if(IS_ERR(name)) |
16369 |
+@@ -2117,7 +2206,22 @@ static long do_rmdir(int dfd, const char |
16370 |
+ error = PTR_ERR(dentry); |
16371 |
+ if (IS_ERR(dentry)) |
16372 |
+ goto exit2; |
16373 |
++ |
16374 |
++ if (dentry->d_inode != NULL) { |
16375 |
++ if (dentry->d_inode->i_nlink <= 1) { |
16376 |
++ saved_ino = dentry->d_inode->i_ino; |
16377 |
++ saved_dev = dentry->d_inode->i_sb->s_dev; |
16378 |
++ } |
16379 |
++ |
16380 |
++ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) { |
16381 |
++ error = -EACCES; |
16382 |
++ goto dput_exit2; |
16383 |
++ } |
16384 |
++ } |
16385 |
+ error = vfs_rmdir(nd.dentry->d_inode, dentry); |
16386 |
++ if (!error && (saved_dev || saved_ino)) |
16387 |
++ gr_handle_delete(saved_ino, saved_dev); |
16388 |
++dput_exit2: |
16389 |
+ dput(dentry); |
16390 |
+ exit2: |
16391 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16392 |
+@@ -2176,6 +2280,8 @@ static long do_unlinkat(int dfd, const c |
16393 |
+ struct dentry *dentry; |
16394 |
+ struct nameidata nd; |
16395 |
+ struct inode *inode = NULL; |
16396 |
++ ino_t saved_ino = 0; |
16397 |
++ dev_t saved_dev = 0; |
16398 |
+ |
16399 |
+ name = getname(pathname); |
16400 |
+ if(IS_ERR(name)) |
16401 |
+@@ -2191,13 +2297,26 @@ static long do_unlinkat(int dfd, const c |
16402 |
+ dentry = lookup_hash(&nd); |
16403 |
+ error = PTR_ERR(dentry); |
16404 |
+ if (!IS_ERR(dentry)) { |
16405 |
++ error = 0; |
16406 |
+ /* Why not before? Because we want correct error value */ |
16407 |
+ if (nd.last.name[nd.last.len]) |
16408 |
+ goto slashes; |
16409 |
+ inode = dentry->d_inode; |
16410 |
+- if (inode) |
16411 |
++ if (inode) { |
16412 |
++ if (inode->i_nlink <= 1) { |
16413 |
++ saved_ino = inode->i_ino; |
16414 |
++ saved_dev = inode->i_sb->s_dev; |
16415 |
++ } |
16416 |
++ |
16417 |
++ if (!gr_acl_handle_unlink(dentry, nd.mnt)) |
16418 |
++ error = -EACCES; |
16419 |
++ |
16420 |
+ atomic_inc(&inode->i_count); |
16421 |
+- error = vfs_unlink(nd.dentry->d_inode, dentry); |
16422 |
++ } |
16423 |
++ if (!error) |
16424 |
++ error = vfs_unlink(nd.dentry->d_inode, dentry); |
16425 |
++ if (!error && (saved_ino || saved_dev)) |
16426 |
++ gr_handle_delete(saved_ino, saved_dev); |
16427 |
+ exit2: |
16428 |
+ dput(dentry); |
16429 |
+ } |
16430 |
+@@ -2278,7 +2397,16 @@ asmlinkage long sys_symlinkat(const char |
16431 |
+ if (IS_ERR(dentry)) |
16432 |
+ goto out_unlock; |
16433 |
+ |
16434 |
++ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) { |
16435 |
++ error = -EACCES; |
16436 |
++ goto out_dput_unlock; |
16437 |
++ } |
16438 |
++ |
16439 |
+ error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); |
16440 |
++ |
16441 |
++ if (!error) |
16442 |
++ gr_handle_create(dentry, nd.mnt); |
16443 |
++out_dput_unlock: |
16444 |
+ dput(dentry); |
16445 |
+ out_unlock: |
16446 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16447 |
+@@ -2373,7 +2501,25 @@ asmlinkage long sys_linkat(int olddfd, c |
16448 |
+ error = PTR_ERR(new_dentry); |
16449 |
+ if (IS_ERR(new_dentry)) |
16450 |
+ goto out_unlock; |
16451 |
++ |
16452 |
++ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt, |
16453 |
++ old_nd.dentry->d_inode, |
16454 |
++ old_nd.dentry->d_inode->i_mode, to)) { |
16455 |
++ error = -EACCES; |
16456 |
++ goto out_unlock_dput; |
16457 |
++ } |
16458 |
++ |
16459 |
++ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt, |
16460 |
++ old_nd.dentry, old_nd.mnt, to)) { |
16461 |
++ error = -EACCES; |
16462 |
++ goto out_unlock_dput; |
16463 |
++ } |
16464 |
++ |
16465 |
+ error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); |
16466 |
++ |
16467 |
++ if (!error) |
16468 |
++ gr_handle_create(new_dentry, nd.mnt); |
16469 |
++out_unlock_dput: |
16470 |
+ dput(new_dentry); |
16471 |
+ out_unlock: |
16472 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
16473 |
+@@ -2599,8 +2745,16 @@ static int do_rename(int olddfd, const c |
16474 |
+ if (new_dentry == trap) |
16475 |
+ goto exit5; |
16476 |
+ |
16477 |
+- error = vfs_rename(old_dir->d_inode, old_dentry, |
16478 |
++ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt, |
16479 |
++ old_dentry, old_dir->d_inode, oldnd.mnt, |
16480 |
++ newname); |
16481 |
++ |
16482 |
++ if (!error) |
16483 |
++ error = vfs_rename(old_dir->d_inode, old_dentry, |
16484 |
+ new_dir->d_inode, new_dentry); |
16485 |
++ if (!error) |
16486 |
++ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, |
16487 |
++ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0); |
16488 |
+ exit5: |
16489 |
+ dput(new_dentry); |
16490 |
+ exit4: |
16491 |
+diff -Nurp linux-2.6.23.15/fs/namespace.c linux-2.6.23.15-grsec/fs/namespace.c |
16492 |
+--- linux-2.6.23.15/fs/namespace.c 2007-10-09 21:31:38.000000000 +0100 |
16493 |
++++ linux-2.6.23.15-grsec/fs/namespace.c 2008-02-11 10:37:44.000000000 +0000 |
16494 |
+@@ -25,6 +25,7 @@ |
16495 |
+ #include <linux/security.h> |
16496 |
+ #include <linux/mount.h> |
16497 |
+ #include <linux/ramfs.h> |
16498 |
++#include <linux/grsecurity.h> |
16499 |
+ #include <asm/uaccess.h> |
16500 |
+ #include <asm/unistd.h> |
16501 |
+ #include "pnode.h" |
16502 |
+@@ -597,6 +598,8 @@ static int do_umount(struct vfsmount *mn |
16503 |
+ DQUOT_OFF(sb); |
16504 |
+ retval = do_remount_sb(sb, MS_RDONLY, NULL, 0); |
16505 |
+ unlock_kernel(); |
16506 |
++ |
16507 |
++ gr_log_remount(mnt->mnt_devname, retval); |
16508 |
+ } |
16509 |
+ up_write(&sb->s_umount); |
16510 |
+ return retval; |
16511 |
+@@ -617,6 +620,9 @@ static int do_umount(struct vfsmount *mn |
16512 |
+ security_sb_umount_busy(mnt); |
16513 |
+ up_write(&namespace_sem); |
16514 |
+ release_mounts(&umount_list); |
16515 |
++ |
16516 |
++ gr_log_unmount(mnt->mnt_devname, retval); |
16517 |
++ |
16518 |
+ return retval; |
16519 |
+ } |
16520 |
+ |
16521 |
+@@ -1422,6 +1428,11 @@ long do_mount(char *dev_name, char *dir_ |
16522 |
+ if (retval) |
16523 |
+ goto dput_out; |
16524 |
+ |
16525 |
++ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) { |
16526 |
++ retval = -EPERM; |
16527 |
++ goto dput_out; |
16528 |
++ } |
16529 |
++ |
16530 |
+ if (flags & MS_REMOUNT) |
16531 |
+ retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, |
16532 |
+ data_page); |
16533 |
+@@ -1436,6 +1447,9 @@ long do_mount(char *dev_name, char *dir_ |
16534 |
+ dev_name, data_page); |
16535 |
+ dput_out: |
16536 |
+ path_release(&nd); |
16537 |
++ |
16538 |
++ gr_log_mount(dev_name, dir_name, retval); |
16539 |
++ |
16540 |
+ return retval; |
16541 |
+ } |
16542 |
+ |
16543 |
+@@ -1673,6 +1687,9 @@ asmlinkage long sys_pivot_root(const cha |
16544 |
+ if (!capable(CAP_SYS_ADMIN)) |
16545 |
+ return -EPERM; |
16546 |
+ |
16547 |
++ if (gr_handle_chroot_pivot()) |
16548 |
++ return -EPERM; |
16549 |
++ |
16550 |
+ lock_kernel(); |
16551 |
+ |
16552 |
+ error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, |
16553 |
+diff -Nurp linux-2.6.23.15/fs/nfs/callback_xdr.c linux-2.6.23.15-grsec/fs/nfs/callback_xdr.c |
16554 |
+--- linux-2.6.23.15/fs/nfs/callback_xdr.c 2007-10-09 21:31:38.000000000 +0100 |
16555 |
++++ linux-2.6.23.15-grsec/fs/nfs/callback_xdr.c 2008-02-11 10:37:44.000000000 +0000 |
16556 |
+@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st |
16557 |
+ if (unlikely(status != 0)) |
16558 |
+ return status; |
16559 |
+ /* We do not like overly long tags! */ |
16560 |
+- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) { |
16561 |
++ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) { |
16562 |
+ printk("NFSv4 CALLBACK %s: client sent tag of length %u\n", |
16563 |
+ __FUNCTION__, hdr->taglen); |
16564 |
+ return htonl(NFS4ERR_RESOURCE); |
16565 |
+diff -Nurp linux-2.6.23.15/fs/nfs/nfs4proc.c linux-2.6.23.15-grsec/fs/nfs/nfs4proc.c |
16566 |
+--- linux-2.6.23.15/fs/nfs/nfs4proc.c 2007-10-09 21:31:38.000000000 +0100 |
16567 |
++++ linux-2.6.23.15-grsec/fs/nfs/nfs4proc.c 2008-02-11 10:37:44.000000000 +0000 |
16568 |
+@@ -657,7 +657,7 @@ static int _nfs4_do_open_reclaim(struct |
16569 |
+ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state) |
16570 |
+ { |
16571 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16572 |
+- struct nfs4_exception exception = { }; |
16573 |
++ struct nfs4_exception exception = {0, 0}; |
16574 |
+ int err; |
16575 |
+ do { |
16576 |
+ err = _nfs4_do_open_reclaim(ctx, state); |
16577 |
+@@ -699,7 +699,7 @@ static int _nfs4_open_delegation_recall( |
16578 |
+ |
16579 |
+ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) |
16580 |
+ { |
16581 |
+- struct nfs4_exception exception = { }; |
16582 |
++ struct nfs4_exception exception = {0, 0}; |
16583 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16584 |
+ int err; |
16585 |
+ do { |
16586 |
+@@ -1020,7 +1020,7 @@ static int _nfs4_open_expired(struct nfs |
16587 |
+ static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state) |
16588 |
+ { |
16589 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16590 |
+- struct nfs4_exception exception = { }; |
16591 |
++ struct nfs4_exception exception = {0, 0}; |
16592 |
+ int err; |
16593 |
+ |
16594 |
+ do { |
16595 |
+@@ -1122,7 +1122,7 @@ out_err: |
16596 |
+ |
16597 |
+ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred) |
16598 |
+ { |
16599 |
+- struct nfs4_exception exception = { }; |
16600 |
++ struct nfs4_exception exception = {0, 0}; |
16601 |
+ struct nfs4_state *res; |
16602 |
+ int status; |
16603 |
+ |
16604 |
+@@ -1211,7 +1211,7 @@ static int nfs4_do_setattr(struct inode |
16605 |
+ struct iattr *sattr, struct nfs4_state *state) |
16606 |
+ { |
16607 |
+ struct nfs_server *server = NFS_SERVER(inode); |
16608 |
+- struct nfs4_exception exception = { }; |
16609 |
++ struct nfs4_exception exception = {0, 0}; |
16610 |
+ int err; |
16611 |
+ do { |
16612 |
+ err = nfs4_handle_exception(server, |
16613 |
+@@ -1504,7 +1504,7 @@ static int _nfs4_server_capabilities(str |
16614 |
+ |
16615 |
+ int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle) |
16616 |
+ { |
16617 |
+- struct nfs4_exception exception = { }; |
16618 |
++ struct nfs4_exception exception = {0, 0}; |
16619 |
+ int err; |
16620 |
+ do { |
16621 |
+ err = nfs4_handle_exception(server, |
16622 |
+@@ -1537,7 +1537,7 @@ static int _nfs4_lookup_root(struct nfs_ |
16623 |
+ static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, |
16624 |
+ struct nfs_fsinfo *info) |
16625 |
+ { |
16626 |
+- struct nfs4_exception exception = { }; |
16627 |
++ struct nfs4_exception exception = {0, 0}; |
16628 |
+ int err; |
16629 |
+ do { |
16630 |
+ err = nfs4_handle_exception(server, |
16631 |
+@@ -1626,7 +1626,7 @@ static int _nfs4_proc_getattr(struct nfs |
16632 |
+ |
16633 |
+ static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
16634 |
+ { |
16635 |
+- struct nfs4_exception exception = { }; |
16636 |
++ struct nfs4_exception exception = {0, 0}; |
16637 |
+ int err; |
16638 |
+ do { |
16639 |
+ err = nfs4_handle_exception(server, |
16640 |
+@@ -1716,7 +1716,7 @@ static int nfs4_proc_lookupfh(struct nfs |
16641 |
+ struct qstr *name, struct nfs_fh *fhandle, |
16642 |
+ struct nfs_fattr *fattr) |
16643 |
+ { |
16644 |
+- struct nfs4_exception exception = { }; |
16645 |
++ struct nfs4_exception exception = {0, 0}; |
16646 |
+ int err; |
16647 |
+ do { |
16648 |
+ err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr); |
16649 |
+@@ -1745,7 +1745,7 @@ static int _nfs4_proc_lookup(struct inod |
16650 |
+ |
16651 |
+ static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
16652 |
+ { |
16653 |
+- struct nfs4_exception exception = { }; |
16654 |
++ struct nfs4_exception exception = {0, 0}; |
16655 |
+ int err; |
16656 |
+ do { |
16657 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
16658 |
+@@ -1801,7 +1801,7 @@ static int _nfs4_proc_access(struct inod |
16659 |
+ |
16660 |
+ static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) |
16661 |
+ { |
16662 |
+- struct nfs4_exception exception = { }; |
16663 |
++ struct nfs4_exception exception = {0, 0}; |
16664 |
+ int err; |
16665 |
+ do { |
16666 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
16667 |
+@@ -1856,7 +1856,7 @@ static int _nfs4_proc_readlink(struct in |
16668 |
+ static int nfs4_proc_readlink(struct inode *inode, struct page *page, |
16669 |
+ unsigned int pgbase, unsigned int pglen) |
16670 |
+ { |
16671 |
+- struct nfs4_exception exception = { }; |
16672 |
++ struct nfs4_exception exception = {0, 0}; |
16673 |
+ int err; |
16674 |
+ do { |
16675 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
16676 |
+@@ -1950,7 +1950,7 @@ static int _nfs4_proc_remove(struct inod |
16677 |
+ |
16678 |
+ static int nfs4_proc_remove(struct inode *dir, struct qstr *name) |
16679 |
+ { |
16680 |
+- struct nfs4_exception exception = { }; |
16681 |
++ struct nfs4_exception exception = {0, 0}; |
16682 |
+ int err; |
16683 |
+ do { |
16684 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
16685 |
+@@ -2022,7 +2022,7 @@ static int _nfs4_proc_rename(struct inod |
16686 |
+ static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name, |
16687 |
+ struct inode *new_dir, struct qstr *new_name) |
16688 |
+ { |
16689 |
+- struct nfs4_exception exception = { }; |
16690 |
++ struct nfs4_exception exception = {0, 0}; |
16691 |
+ int err; |
16692 |
+ do { |
16693 |
+ err = nfs4_handle_exception(NFS_SERVER(old_dir), |
16694 |
+@@ -2069,7 +2069,7 @@ static int _nfs4_proc_link(struct inode |
16695 |
+ |
16696 |
+ static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) |
16697 |
+ { |
16698 |
+- struct nfs4_exception exception = { }; |
16699 |
++ struct nfs4_exception exception = {0, 0}; |
16700 |
+ int err; |
16701 |
+ do { |
16702 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
16703 |
+@@ -2126,7 +2126,7 @@ static int _nfs4_proc_symlink(struct ino |
16704 |
+ static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry, |
16705 |
+ struct page *page, unsigned int len, struct iattr *sattr) |
16706 |
+ { |
16707 |
+- struct nfs4_exception exception = { }; |
16708 |
++ struct nfs4_exception exception = {0, 0}; |
16709 |
+ int err; |
16710 |
+ do { |
16711 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
16712 |
+@@ -2179,7 +2179,7 @@ static int _nfs4_proc_mkdir(struct inode |
16713 |
+ static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry, |
16714 |
+ struct iattr *sattr) |
16715 |
+ { |
16716 |
+- struct nfs4_exception exception = { }; |
16717 |
++ struct nfs4_exception exception = {0, 0}; |
16718 |
+ int err; |
16719 |
+ do { |
16720 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
16721 |
+@@ -2225,7 +2225,7 @@ static int _nfs4_proc_readdir(struct den |
16722 |
+ static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, |
16723 |
+ u64 cookie, struct page *page, unsigned int count, int plus) |
16724 |
+ { |
16725 |
+- struct nfs4_exception exception = { }; |
16726 |
++ struct nfs4_exception exception = {0, 0}; |
16727 |
+ int err; |
16728 |
+ do { |
16729 |
+ err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode), |
16730 |
+@@ -2295,7 +2295,7 @@ static int _nfs4_proc_mknod(struct inode |
16731 |
+ static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry, |
16732 |
+ struct iattr *sattr, dev_t rdev) |
16733 |
+ { |
16734 |
+- struct nfs4_exception exception = { }; |
16735 |
++ struct nfs4_exception exception = {0, 0}; |
16736 |
+ int err; |
16737 |
+ do { |
16738 |
+ err = nfs4_handle_exception(NFS_SERVER(dir), |
16739 |
+@@ -2324,7 +2324,7 @@ static int _nfs4_proc_statfs(struct nfs_ |
16740 |
+ |
16741 |
+ static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat) |
16742 |
+ { |
16743 |
+- struct nfs4_exception exception = { }; |
16744 |
++ struct nfs4_exception exception = {0, 0}; |
16745 |
+ int err; |
16746 |
+ do { |
16747 |
+ err = nfs4_handle_exception(server, |
16748 |
+@@ -2352,7 +2352,7 @@ static int _nfs4_do_fsinfo(struct nfs_se |
16749 |
+ |
16750 |
+ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo) |
16751 |
+ { |
16752 |
+- struct nfs4_exception exception = { }; |
16753 |
++ struct nfs4_exception exception = {0, 0}; |
16754 |
+ int err; |
16755 |
+ |
16756 |
+ do { |
16757 |
+@@ -2395,7 +2395,7 @@ static int _nfs4_proc_pathconf(struct nf |
16758 |
+ static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, |
16759 |
+ struct nfs_pathconf *pathconf) |
16760 |
+ { |
16761 |
+- struct nfs4_exception exception = { }; |
16762 |
++ struct nfs4_exception exception = {0, 0}; |
16763 |
+ int err; |
16764 |
+ |
16765 |
+ do { |
16766 |
+@@ -2714,7 +2714,7 @@ out_free: |
16767 |
+ |
16768 |
+ static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) |
16769 |
+ { |
16770 |
+- struct nfs4_exception exception = { }; |
16771 |
++ struct nfs4_exception exception = {0, 0}; |
16772 |
+ ssize_t ret; |
16773 |
+ do { |
16774 |
+ ret = __nfs4_get_acl_uncached(inode, buf, buflen); |
16775 |
+@@ -2768,7 +2768,7 @@ static int __nfs4_proc_set_acl(struct in |
16776 |
+ |
16777 |
+ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) |
16778 |
+ { |
16779 |
+- struct nfs4_exception exception = { }; |
16780 |
++ struct nfs4_exception exception = {0, 0}; |
16781 |
+ int err; |
16782 |
+ do { |
16783 |
+ err = nfs4_handle_exception(NFS_SERVER(inode), |
16784 |
+@@ -3065,7 +3065,7 @@ static int _nfs4_proc_delegreturn(struct |
16785 |
+ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid) |
16786 |
+ { |
16787 |
+ struct nfs_server *server = NFS_SERVER(inode); |
16788 |
+- struct nfs4_exception exception = { }; |
16789 |
++ struct nfs4_exception exception = {0, 0}; |
16790 |
+ int err; |
16791 |
+ do { |
16792 |
+ err = _nfs4_proc_delegreturn(inode, cred, stateid); |
16793 |
+@@ -3140,7 +3140,7 @@ out: |
16794 |
+ |
16795 |
+ static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
16796 |
+ { |
16797 |
+- struct nfs4_exception exception = { }; |
16798 |
++ struct nfs4_exception exception = {0, 0}; |
16799 |
+ int err; |
16800 |
+ |
16801 |
+ do { |
16802 |
+@@ -3474,7 +3474,7 @@ static int _nfs4_do_setlk(struct nfs4_st |
16803 |
+ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) |
16804 |
+ { |
16805 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16806 |
+- struct nfs4_exception exception = { }; |
16807 |
++ struct nfs4_exception exception = {0, 0}; |
16808 |
+ int err; |
16809 |
+ |
16810 |
+ do { |
16811 |
+@@ -3492,7 +3492,7 @@ static int nfs4_lock_reclaim(struct nfs4 |
16812 |
+ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request) |
16813 |
+ { |
16814 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16815 |
+- struct nfs4_exception exception = { }; |
16816 |
++ struct nfs4_exception exception = {0, 0}; |
16817 |
+ int err; |
16818 |
+ |
16819 |
+ err = nfs4_set_lock_state(state, request); |
16820 |
+@@ -3553,7 +3553,7 @@ out: |
16821 |
+ |
16822 |
+ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) |
16823 |
+ { |
16824 |
+- struct nfs4_exception exception = { }; |
16825 |
++ struct nfs4_exception exception = {0, 0}; |
16826 |
+ int err; |
16827 |
+ |
16828 |
+ do { |
16829 |
+@@ -3603,7 +3603,7 @@ nfs4_proc_lock(struct file *filp, int cm |
16830 |
+ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) |
16831 |
+ { |
16832 |
+ struct nfs_server *server = NFS_SERVER(state->inode); |
16833 |
+- struct nfs4_exception exception = { }; |
16834 |
++ struct nfs4_exception exception = {0, 0}; |
16835 |
+ int err; |
16836 |
+ |
16837 |
+ err = nfs4_set_lock_state(state, fl); |
16838 |
+diff -Nurp linux-2.6.23.15/fs/nfsd/export.c linux-2.6.23.15-grsec/fs/nfsd/export.c |
16839 |
+--- linux-2.6.23.15/fs/nfsd/export.c 2007-10-09 21:31:38.000000000 +0100 |
16840 |
++++ linux-2.6.23.15-grsec/fs/nfsd/export.c 2008-02-11 10:37:44.000000000 +0000 |
16841 |
+@@ -478,7 +478,7 @@ static int secinfo_parse(char **mesg, ch |
16842 |
+ * probably discover the problem when someone fails to |
16843 |
+ * authenticate. |
16844 |
+ */ |
16845 |
+- if (f->pseudoflavor < 0) |
16846 |
++ if ((s32)f->pseudoflavor < 0) |
16847 |
+ return -EINVAL; |
16848 |
+ err = get_int(mesg, &f->flags); |
16849 |
+ if (err) |
16850 |
+diff -Nurp linux-2.6.23.15/fs/nfsd/nfs4state.c linux-2.6.23.15-grsec/fs/nfsd/nfs4state.c |
16851 |
+--- linux-2.6.23.15/fs/nfsd/nfs4state.c 2007-10-09 21:31:38.000000000 +0100 |
16852 |
++++ linux-2.6.23.15-grsec/fs/nfsd/nfs4state.c 2008-02-11 10:37:44.000000000 +0000 |
16853 |
+@@ -1248,7 +1248,7 @@ static int access_valid(u32 x) |
16854 |
+ |
16855 |
+ static int deny_valid(u32 x) |
16856 |
+ { |
16857 |
+- return (x >= 0 && x < 5); |
16858 |
++ return (x < 5); |
16859 |
+ } |
16860 |
+ |
16861 |
+ static void |
16862 |
+diff -Nurp linux-2.6.23.15/fs/nls/nls_base.c linux-2.6.23.15-grsec/fs/nls/nls_base.c |
16863 |
+--- linux-2.6.23.15/fs/nls/nls_base.c 2007-10-09 21:31:38.000000000 +0100 |
16864 |
++++ linux-2.6.23.15-grsec/fs/nls/nls_base.c 2008-02-11 10:37:44.000000000 +0000 |
16865 |
+@@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] = |
16866 |
+ {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */}, |
16867 |
+ {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */}, |
16868 |
+ {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */}, |
16869 |
+- {0, /* end of table */} |
16870 |
++ {0, 0, 0, 0, 0, /* end of table */} |
16871 |
+ }; |
16872 |
+ |
16873 |
+ int |
16874 |
+diff -Nurp linux-2.6.23.15/fs/ntfs/file.c linux-2.6.23.15-grsec/fs/ntfs/file.c |
16875 |
+--- linux-2.6.23.15/fs/ntfs/file.c 2007-10-09 21:31:38.000000000 +0100 |
16876 |
++++ linux-2.6.23.15-grsec/fs/ntfs/file.c 2008-02-11 10:37:44.000000000 +0000 |
16877 |
+@@ -2295,6 +2295,6 @@ const struct inode_operations ntfs_file_ |
16878 |
+ #endif /* NTFS_RW */ |
16879 |
+ }; |
16880 |
+ |
16881 |
+-const struct file_operations ntfs_empty_file_ops = {}; |
16882 |
++const struct file_operations ntfs_empty_file_ops; |
16883 |
+ |
16884 |
+-const struct inode_operations ntfs_empty_inode_ops = {}; |
16885 |
++const struct inode_operations ntfs_empty_inode_ops; |
16886 |
+diff -Nurp linux-2.6.23.15/fs/open.c linux-2.6.23.15-grsec/fs/open.c |
16887 |
+--- linux-2.6.23.15/fs/open.c 2007-10-09 21:31:38.000000000 +0100 |
16888 |
++++ linux-2.6.23.15-grsec/fs/open.c 2008-02-11 10:37:44.000000000 +0000 |
16889 |
+@@ -27,6 +27,7 @@ |
16890 |
+ #include <linux/rcupdate.h> |
16891 |
+ #include <linux/audit.h> |
16892 |
+ #include <linux/falloc.h> |
16893 |
++#include <linux/grsecurity.h> |
16894 |
+ |
16895 |
+ int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
16896 |
+ { |
16897 |
+@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l |
16898 |
+ if (length < 0) |
16899 |
+ return -EINVAL; |
16900 |
+ |
16901 |
++ if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt)) |
16902 |
++ return -EACCES; |
16903 |
++ |
16904 |
+ newattrs.ia_size = length; |
16905 |
+ newattrs.ia_valid = ATTR_SIZE | time_attrs; |
16906 |
+ if (filp) { |
16907 |
+@@ -461,6 +465,9 @@ asmlinkage long sys_faccessat(int dfd, c |
16908 |
+ if(IS_RDONLY(nd.dentry->d_inode)) |
16909 |
+ res = -EROFS; |
16910 |
+ |
16911 |
++ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode)) |
16912 |
++ res = -EACCES; |
16913 |
++ |
16914 |
+ out_path_release: |
16915 |
+ path_release(&nd); |
16916 |
+ out: |
16917 |
+@@ -490,6 +497,8 @@ asmlinkage long sys_chdir(const char __u |
16918 |
+ if (error) |
16919 |
+ goto dput_and_out; |
16920 |
+ |
16921 |
++ gr_log_chdir(nd.dentry, nd.mnt); |
16922 |
++ |
16923 |
+ set_fs_pwd(current->fs, nd.mnt, nd.dentry); |
16924 |
+ |
16925 |
+ dput_and_out: |
16926 |
+@@ -520,6 +529,13 @@ asmlinkage long sys_fchdir(unsigned int |
16927 |
+ goto out_putf; |
16928 |
+ |
16929 |
+ error = file_permission(file, MAY_EXEC); |
16930 |
++ |
16931 |
++ if (!error && !gr_chroot_fchdir(dentry, mnt)) |
16932 |
++ error = -EPERM; |
16933 |
++ |
16934 |
++ if (!error) |
16935 |
++ gr_log_chdir(dentry, mnt); |
16936 |
++ |
16937 |
+ if (!error) |
16938 |
+ set_fs_pwd(current->fs, mnt, dentry); |
16939 |
+ out_putf: |
16940 |
+@@ -545,8 +561,16 @@ asmlinkage long sys_chroot(const char __ |
16941 |
+ if (!capable(CAP_SYS_CHROOT)) |
16942 |
+ goto dput_and_out; |
16943 |
+ |
16944 |
++ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt)) |
16945 |
++ goto dput_and_out; |
16946 |
++ |
16947 |
+ set_fs_root(current->fs, nd.mnt, nd.dentry); |
16948 |
+ set_fs_altroot(); |
16949 |
++ |
16950 |
++ gr_handle_chroot_caps(current); |
16951 |
++ |
16952 |
++ gr_handle_chroot_chdir(nd.dentry, nd.mnt); |
16953 |
++ |
16954 |
+ error = 0; |
16955 |
+ dput_and_out: |
16956 |
+ path_release(&nd); |
16957 |
+@@ -577,9 +601,22 @@ asmlinkage long sys_fchmod(unsigned int |
16958 |
+ err = -EPERM; |
16959 |
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
16960 |
+ goto out_putf; |
16961 |
++ |
16962 |
++ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) { |
16963 |
++ err = -EACCES; |
16964 |
++ goto out_putf; |
16965 |
++ } |
16966 |
++ |
16967 |
+ mutex_lock(&inode->i_mutex); |
16968 |
+ if (mode == (mode_t) -1) |
16969 |
+ mode = inode->i_mode; |
16970 |
++ |
16971 |
++ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) { |
16972 |
++ err = -EPERM; |
16973 |
++ mutex_unlock(&inode->i_mutex); |
16974 |
++ goto out_putf; |
16975 |
++ } |
16976 |
++ |
16977 |
+ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
16978 |
+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
16979 |
+ err = notify_change(dentry, &newattrs); |
16980 |
+@@ -612,9 +649,21 @@ asmlinkage long sys_fchmodat(int dfd, co |
16981 |
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
16982 |
+ goto dput_and_out; |
16983 |
+ |
16984 |
++ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) { |
16985 |
++ error = -EACCES; |
16986 |
++ goto dput_and_out; |
16987 |
++ }; |
16988 |
++ |
16989 |
+ mutex_lock(&inode->i_mutex); |
16990 |
+ if (mode == (mode_t) -1) |
16991 |
+ mode = inode->i_mode; |
16992 |
++ |
16993 |
++ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) { |
16994 |
++ error = -EACCES; |
16995 |
++ mutex_unlock(&inode->i_mutex); |
16996 |
++ goto dput_and_out; |
16997 |
++ } |
16998 |
++ |
16999 |
+ newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
17000 |
+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
17001 |
+ error = notify_change(nd.dentry, &newattrs); |
17002 |
+@@ -631,7 +680,7 @@ asmlinkage long sys_chmod(const char __u |
17003 |
+ return sys_fchmodat(AT_FDCWD, filename, mode); |
17004 |
+ } |
17005 |
+ |
17006 |
+-static int chown_common(struct dentry * dentry, uid_t user, gid_t group) |
17007 |
++static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt) |
17008 |
+ { |
17009 |
+ struct inode * inode; |
17010 |
+ int error; |
17011 |
+@@ -648,6 +697,12 @@ static int chown_common(struct dentry * |
17012 |
+ error = -EPERM; |
17013 |
+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
17014 |
+ goto out; |
17015 |
++ |
17016 |
++ if (!gr_acl_handle_chown(dentry, mnt)) { |
17017 |
++ error = -EACCES; |
17018 |
++ goto out; |
17019 |
++ } |
17020 |
++ |
17021 |
+ newattrs.ia_valid = ATTR_CTIME; |
17022 |
+ if (user != (uid_t) -1) { |
17023 |
+ newattrs.ia_valid |= ATTR_UID; |
17024 |
+@@ -674,7 +729,7 @@ asmlinkage long sys_chown(const char __u |
17025 |
+ error = user_path_walk(filename, &nd); |
17026 |
+ if (error) |
17027 |
+ goto out; |
17028 |
+- error = chown_common(nd.dentry, user, group); |
17029 |
++ error = chown_common(nd.dentry, user, group, nd.mnt); |
17030 |
+ path_release(&nd); |
17031 |
+ out: |
17032 |
+ return error; |
17033 |
+@@ -694,7 +749,7 @@ asmlinkage long sys_fchownat(int dfd, co |
17034 |
+ error = __user_walk_fd(dfd, filename, follow, &nd); |
17035 |
+ if (error) |
17036 |
+ goto out; |
17037 |
+- error = chown_common(nd.dentry, user, group); |
17038 |
++ error = chown_common(nd.dentry, user, group, nd.mnt); |
17039 |
+ path_release(&nd); |
17040 |
+ out: |
17041 |
+ return error; |
17042 |
+@@ -708,7 +763,7 @@ asmlinkage long sys_lchown(const char __ |
17043 |
+ error = user_path_walk_link(filename, &nd); |
17044 |
+ if (error) |
17045 |
+ goto out; |
17046 |
+- error = chown_common(nd.dentry, user, group); |
17047 |
++ error = chown_common(nd.dentry, user, group, nd.mnt); |
17048 |
+ path_release(&nd); |
17049 |
+ out: |
17050 |
+ return error; |
17051 |
+@@ -727,7 +782,7 @@ asmlinkage long sys_fchown(unsigned int |
17052 |
+ |
17053 |
+ dentry = file->f_path.dentry; |
17054 |
+ audit_inode(NULL, dentry->d_inode); |
17055 |
+- error = chown_common(dentry, user, group); |
17056 |
++ error = chown_common(dentry, user, group, file->f_vfsmnt); |
17057 |
+ fput(file); |
17058 |
+ out: |
17059 |
+ return error; |
17060 |
+@@ -934,6 +989,7 @@ repeat: |
17061 |
+ * N.B. For clone tasks sharing a files structure, this test |
17062 |
+ * will limit the total number of files that can be opened. |
17063 |
+ */ |
17064 |
++ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0); |
17065 |
+ if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) |
17066 |
+ goto out; |
17067 |
+ |
17068 |
+diff -Nurp linux-2.6.23.15/fs/partitions/efi.c linux-2.6.23.15-grsec/fs/partitions/efi.c |
17069 |
+--- linux-2.6.23.15/fs/partitions/efi.c 2007-10-09 21:31:38.000000000 +0100 |
17070 |
++++ linux-2.6.23.15-grsec/fs/partitions/efi.c 2008-02-11 10:37:44.000000000 +0000 |
17071 |
+@@ -99,7 +99,7 @@ |
17072 |
+ #ifdef EFI_DEBUG |
17073 |
+ #define Dprintk(x...) printk(KERN_DEBUG x) |
17074 |
+ #else |
17075 |
+-#define Dprintk(x...) |
17076 |
++#define Dprintk(x...) do {} while (0) |
17077 |
+ #endif |
17078 |
+ |
17079 |
+ /* This allows a kernel command line option 'gpt' to override |
17080 |
+diff -Nurp linux-2.6.23.15/fs/pipe.c linux-2.6.23.15-grsec/fs/pipe.c |
17081 |
+--- linux-2.6.23.15/fs/pipe.c 2007-10-09 21:31:38.000000000 +0100 |
17082 |
++++ linux-2.6.23.15-grsec/fs/pipe.c 2008-02-11 10:37:44.000000000 +0000 |
17083 |
+@@ -888,7 +888,7 @@ void free_pipe_info(struct inode *inode) |
17084 |
+ inode->i_pipe = NULL; |
17085 |
+ } |
17086 |
+ |
17087 |
+-static struct vfsmount *pipe_mnt __read_mostly; |
17088 |
++struct vfsmount *pipe_mnt __read_mostly; |
17089 |
+ static int pipefs_delete_dentry(struct dentry *dentry) |
17090 |
+ { |
17091 |
+ /* |
17092 |
+diff -Nurp linux-2.6.23.15/fs/proc/array.c linux-2.6.23.15-grsec/fs/proc/array.c |
17093 |
+--- linux-2.6.23.15/fs/proc/array.c 2008-02-11 10:36:03.000000000 +0000 |
17094 |
++++ linux-2.6.23.15-grsec/fs/proc/array.c 2008-02-11 10:37:44.000000000 +0000 |
17095 |
+@@ -298,6 +298,21 @@ static inline char *task_context_switch_ |
17096 |
+ p->nivcsw); |
17097 |
+ } |
17098 |
+ |
17099 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
17100 |
++static inline char *task_pax(struct task_struct *p, char *buffer) |
17101 |
++{ |
17102 |
++ if (p->mm) |
17103 |
++ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n", |
17104 |
++ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p', |
17105 |
++ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e', |
17106 |
++ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm', |
17107 |
++ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r', |
17108 |
++ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's'); |
17109 |
++ else |
17110 |
++ return buffer + sprintf(buffer, "PaX:\t-----\n"); |
17111 |
++} |
17112 |
++#endif |
17113 |
++ |
17114 |
+ int proc_pid_status(struct task_struct *task, char *buffer) |
17115 |
+ { |
17116 |
+ char *orig = buffer; |
17117 |
+@@ -317,6 +332,11 @@ int proc_pid_status(struct task_struct * |
17118 |
+ buffer = task_show_regs(task, buffer); |
17119 |
+ #endif |
17120 |
+ buffer = task_context_switch_counts(task, buffer); |
17121 |
++ |
17122 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
17123 |
++ buffer = task_pax(task, buffer); |
17124 |
++#endif |
17125 |
++ |
17126 |
+ return buffer - orig; |
17127 |
+ } |
17128 |
+ |
17129 |
+@@ -372,6 +392,12 @@ static cputime_t task_stime(struct task_ |
17130 |
+ } |
17131 |
+ #endif |
17132 |
+ |
17133 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17134 |
++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ |
17135 |
++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ |
17136 |
++ _mm->pax_flags & MF_PAX_SEGMEXEC)) |
17137 |
++#endif |
17138 |
++ |
17139 |
+ static int do_task_stat(struct task_struct *task, char *buffer, int whole) |
17140 |
+ { |
17141 |
+ unsigned long vsize, eip, esp, wchan = ~0UL; |
17142 |
+@@ -458,6 +484,19 @@ static int do_task_stat(struct task_stru |
17143 |
+ stime = task_stime(task); |
17144 |
+ } |
17145 |
+ |
17146 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17147 |
++ if (PAX_RAND_FLAGS(mm)) { |
17148 |
++ eip = 0; |
17149 |
++ esp = 0; |
17150 |
++ wchan = 0; |
17151 |
++ } |
17152 |
++#endif |
17153 |
++#ifdef CONFIG_GRKERNSEC_HIDESYM |
17154 |
++ wchan = 0; |
17155 |
++ eip =0; |
17156 |
++ esp =0; |
17157 |
++#endif |
17158 |
++ |
17159 |
+ /* scale priority and nice values from timeslices to -20..20 */ |
17160 |
+ /* to make it look like a "normal" Unix priority/nice value */ |
17161 |
+ priority = task_prio(task); |
17162 |
+@@ -498,9 +537,15 @@ static int do_task_stat(struct task_stru |
17163 |
+ vsize, |
17164 |
+ mm ? get_mm_rss(mm) : 0, |
17165 |
+ rsslim, |
17166 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17167 |
++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0), |
17168 |
++ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0), |
17169 |
++ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0), |
17170 |
++#else |
17171 |
+ mm ? mm->start_code : 0, |
17172 |
+ mm ? mm->end_code : 0, |
17173 |
+ mm ? mm->start_stack : 0, |
17174 |
++#endif |
17175 |
+ esp, |
17176 |
+ eip, |
17177 |
+ /* The signal information here is obsolete. |
17178 |
+@@ -547,3 +592,14 @@ int proc_pid_statm(struct task_struct *t |
17179 |
+ return sprintf(buffer, "%d %d %d %d %d %d %d\n", |
17180 |
+ size, resident, shared, text, lib, data, 0); |
17181 |
+ } |
17182 |
++ |
17183 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
17184 |
++int proc_pid_ipaddr(struct task_struct *task, char * buffer) |
17185 |
++{ |
17186 |
++ int len; |
17187 |
++ |
17188 |
++ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip)); |
17189 |
++ return len; |
17190 |
++} |
17191 |
++#endif |
17192 |
++ |
17193 |
+diff -Nurp linux-2.6.23.15/fs/proc/base.c linux-2.6.23.15-grsec/fs/proc/base.c |
17194 |
+--- linux-2.6.23.15/fs/proc/base.c 2007-10-09 21:31:38.000000000 +0100 |
17195 |
++++ linux-2.6.23.15-grsec/fs/proc/base.c 2008-02-11 10:37:44.000000000 +0000 |
17196 |
+@@ -73,6 +73,7 @@ |
17197 |
+ #include <linux/nsproxy.h> |
17198 |
+ #include <linux/oom.h> |
17199 |
+ #include <linux/elf.h> |
17200 |
++#include <linux/grsecurity.h> |
17201 |
+ #include "internal.h" |
17202 |
+ |
17203 |
+ /* NOTE: |
17204 |
+@@ -123,7 +124,7 @@ struct pid_entry { |
17205 |
+ NULL, &proc_info_file_operations, \ |
17206 |
+ { .proc_read = &proc_##OTYPE } ) |
17207 |
+ |
17208 |
+-int maps_protect; |
17209 |
++int maps_protect = 1; |
17210 |
+ EXPORT_SYMBOL(maps_protect); |
17211 |
+ |
17212 |
+ static struct fs_struct *get_fs_struct(struct task_struct *task) |
17213 |
+@@ -197,7 +198,7 @@ static int proc_root_link(struct inode * |
17214 |
+ (task->parent == current && \ |
17215 |
+ (task->ptrace & PT_PTRACED) && \ |
17216 |
+ (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \ |
17217 |
+- security_ptrace(current,task) == 0)) |
17218 |
++ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task))) |
17219 |
+ |
17220 |
+ static int proc_pid_environ(struct task_struct *task, char * buffer) |
17221 |
+ { |
17222 |
+@@ -263,9 +264,9 @@ static int proc_pid_auxv(struct task_str |
17223 |
+ struct mm_struct *mm = get_task_mm(task); |
17224 |
+ if (mm) { |
17225 |
+ unsigned int nwords = 0; |
17226 |
+- do |
17227 |
++ do { |
17228 |
+ nwords += 2; |
17229 |
+- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ |
17230 |
++ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ |
17231 |
+ res = nwords * sizeof(mm->saved_auxv[0]); |
17232 |
+ if (res > PAGE_SIZE) |
17233 |
+ res = PAGE_SIZE; |
17234 |
+@@ -338,6 +339,8 @@ static int proc_fd_access_allowed(struct |
17235 |
+ task = get_proc_task(inode); |
17236 |
+ if (task) { |
17237 |
+ allowed = ptrace_may_attach(task); |
17238 |
++ if (allowed != 0) |
17239 |
++ allowed = !gr_acl_handle_procpidmem(task); |
17240 |
+ put_task_struct(task); |
17241 |
+ } |
17242 |
+ return allowed; |
17243 |
+@@ -528,7 +531,7 @@ static ssize_t mem_read(struct file * fi |
17244 |
+ if (!task) |
17245 |
+ goto out_no_task; |
17246 |
+ |
17247 |
+- if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) |
17248 |
++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task)) |
17249 |
+ goto out; |
17250 |
+ |
17251 |
+ ret = -ENOMEM; |
17252 |
+@@ -598,7 +601,7 @@ static ssize_t mem_write(struct file * f |
17253 |
+ if (!task) |
17254 |
+ goto out_no_task; |
17255 |
+ |
17256 |
+- if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) |
17257 |
++ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task)) |
17258 |
+ goto out; |
17259 |
+ |
17260 |
+ copied = -ENOMEM; |
17261 |
+@@ -1050,7 +1053,11 @@ static struct inode *proc_pid_make_inode |
17262 |
+ inode->i_gid = 0; |
17263 |
+ if (task_dumpable(task)) { |
17264 |
+ inode->i_uid = task->euid; |
17265 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17266 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17267 |
++#else |
17268 |
+ inode->i_gid = task->egid; |
17269 |
++#endif |
17270 |
+ } |
17271 |
+ security_task_to_inode(task, inode); |
17272 |
+ |
17273 |
+@@ -1066,17 +1073,45 @@ static int pid_getattr(struct vfsmount * |
17274 |
+ { |
17275 |
+ struct inode *inode = dentry->d_inode; |
17276 |
+ struct task_struct *task; |
17277 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17278 |
++ struct task_struct *tmp = current; |
17279 |
++#endif |
17280 |
++ |
17281 |
+ generic_fillattr(inode, stat); |
17282 |
+ |
17283 |
+ rcu_read_lock(); |
17284 |
+ stat->uid = 0; |
17285 |
+ stat->gid = 0; |
17286 |
+ task = pid_task(proc_pid(inode), PIDTYPE_PID); |
17287 |
+- if (task) { |
17288 |
++ |
17289 |
++ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) { |
17290 |
++ rcu_read_unlock(); |
17291 |
++ return -ENOENT; |
17292 |
++ } |
17293 |
++ |
17294 |
++ |
17295 |
++ if (task |
17296 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17297 |
++ && (!tmp->uid || (tmp->uid == task->uid) |
17298 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17299 |
++ || in_group_p(CONFIG_GRKERNSEC_PROC_GID) |
17300 |
++#endif |
17301 |
++ ) |
17302 |
++#endif |
17303 |
++ ) { |
17304 |
+ if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
17305 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17306 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) || |
17307 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
17308 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) || |
17309 |
++#endif |
17310 |
+ task_dumpable(task)) { |
17311 |
+ stat->uid = task->euid; |
17312 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17313 |
++ stat->gid = CONFIG_GRKERNSEC_PROC_GID; |
17314 |
++#else |
17315 |
+ stat->gid = task->egid; |
17316 |
++#endif |
17317 |
+ } |
17318 |
+ } |
17319 |
+ rcu_read_unlock(); |
17320 |
+@@ -1104,11 +1139,21 @@ static int pid_revalidate(struct dentry |
17321 |
+ { |
17322 |
+ struct inode *inode = dentry->d_inode; |
17323 |
+ struct task_struct *task = get_proc_task(inode); |
17324 |
++ |
17325 |
+ if (task) { |
17326 |
+ if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
17327 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17328 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) || |
17329 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
17330 |
++ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) || |
17331 |
++#endif |
17332 |
+ task_dumpable(task)) { |
17333 |
+ inode->i_uid = task->euid; |
17334 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17335 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17336 |
++#else |
17337 |
+ inode->i_gid = task->egid; |
17338 |
++#endif |
17339 |
+ } else { |
17340 |
+ inode->i_uid = 0; |
17341 |
+ inode->i_gid = 0; |
17342 |
+@@ -1118,6 +1163,7 @@ static int pid_revalidate(struct dentry |
17343 |
+ put_task_struct(task); |
17344 |
+ return 1; |
17345 |
+ } |
17346 |
++out: |
17347 |
+ d_drop(dentry); |
17348 |
+ return 0; |
17349 |
+ } |
17350 |
+@@ -1374,6 +1420,9 @@ static struct dentry *proc_lookupfd_comm |
17351 |
+ if (fd == ~0U) |
17352 |
+ goto out; |
17353 |
+ |
17354 |
++ if (gr_acl_handle_procpidmem(task)) |
17355 |
++ goto out; |
17356 |
++ |
17357 |
+ result = instantiate(dir, dentry, task, &fd); |
17358 |
+ out: |
17359 |
+ put_task_struct(task); |
17360 |
+@@ -1410,6 +1459,8 @@ static int proc_readfd_common(struct fil |
17361 |
+ goto out; |
17362 |
+ filp->f_pos++; |
17363 |
+ default: |
17364 |
++ if (gr_acl_handle_procpidmem(p)) |
17365 |
++ goto out; |
17366 |
+ files = get_files_struct(p); |
17367 |
+ if (!files) |
17368 |
+ goto out; |
17369 |
+@@ -1598,6 +1649,9 @@ static struct dentry *proc_pident_lookup |
17370 |
+ if (!task) |
17371 |
+ goto out_no_task; |
17372 |
+ |
17373 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) |
17374 |
++ goto out; |
17375 |
++ |
17376 |
+ /* |
17377 |
+ * Yes, it does not scale. And it should not. Don't add |
17378 |
+ * new entries into /proc/<tgid>/ without very good reasons. |
17379 |
+@@ -1643,6 +1697,9 @@ static int proc_pident_readdir(struct fi |
17380 |
+ if (!task) |
17381 |
+ goto out_no_task; |
17382 |
+ |
17383 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) |
17384 |
++ goto out; |
17385 |
++ |
17386 |
+ ret = 0; |
17387 |
+ pid = task->pid; |
17388 |
+ i = filp->f_pos; |
17389 |
+@@ -1998,6 +2055,9 @@ static struct dentry *proc_base_lookup(s |
17390 |
+ if (p > last) |
17391 |
+ goto out; |
17392 |
+ |
17393 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)) |
17394 |
++ goto out; |
17395 |
++ |
17396 |
+ error = proc_base_instantiate(dir, dentry, task, p); |
17397 |
+ |
17398 |
+ out: |
17399 |
+@@ -2097,6 +2157,9 @@ static const struct pid_entry tgid_base_ |
17400 |
+ #ifdef CONFIG_TASK_IO_ACCOUNTING |
17401 |
+ INF("io", S_IRUGO, pid_io_accounting), |
17402 |
+ #endif |
17403 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
17404 |
++ INF("ipaddr", S_IRUSR, pid_ipaddr), |
17405 |
++#endif |
17406 |
+ }; |
17407 |
+ |
17408 |
+ static int proc_tgid_base_readdir(struct file * filp, |
17409 |
+@@ -2200,7 +2263,14 @@ static struct dentry *proc_pid_instantia |
17410 |
+ if (!inode) |
17411 |
+ goto out; |
17412 |
+ |
17413 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17414 |
++ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR; |
17415 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
17416 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17417 |
++ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP; |
17418 |
++#else |
17419 |
+ inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; |
17420 |
++#endif |
17421 |
+ inode->i_op = &proc_tgid_base_inode_operations; |
17422 |
+ inode->i_fop = &proc_tgid_base_operations; |
17423 |
+ inode->i_flags|=S_IMMUTABLE; |
17424 |
+@@ -2241,7 +2311,11 @@ struct dentry *proc_pid_lookup(struct in |
17425 |
+ if (!task) |
17426 |
+ goto out; |
17427 |
+ |
17428 |
++ if (gr_check_hidden_task(task)) |
17429 |
++ goto out_put_task; |
17430 |
++ |
17431 |
+ result = proc_pid_instantiate(dir, dentry, task, NULL); |
17432 |
++out_put_task: |
17433 |
+ put_task_struct(task); |
17434 |
+ out: |
17435 |
+ return result; |
17436 |
+@@ -2299,6 +2373,9 @@ int proc_pid_readdir(struct file * filp, |
17437 |
+ { |
17438 |
+ unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY; |
17439 |
+ struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
17440 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17441 |
++ struct task_struct *tmp = current; |
17442 |
++#endif |
17443 |
+ struct task_struct *task; |
17444 |
+ int tgid; |
17445 |
+ |
17446 |
+@@ -2316,6 +2393,18 @@ int proc_pid_readdir(struct file * filp, |
17447 |
+ task; |
17448 |
+ put_task_struct(task), task = next_tgid(tgid + 1)) { |
17449 |
+ tgid = task->pid; |
17450 |
++ |
17451 |
++ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task) |
17452 |
++#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17453 |
++ || (tmp->uid && (task->uid != tmp->uid) |
17454 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17455 |
++ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID) |
17456 |
++#endif |
17457 |
++ ) |
17458 |
++#endif |
17459 |
++ ) |
17460 |
++ continue; |
17461 |
++ |
17462 |
+ filp->f_pos = tgid + TGID_OFFSET; |
17463 |
+ if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { |
17464 |
+ put_task_struct(task); |
17465 |
+diff -Nurp linux-2.6.23.15/fs/proc/inode.c linux-2.6.23.15-grsec/fs/proc/inode.c |
17466 |
+--- linux-2.6.23.15/fs/proc/inode.c 2007-10-09 21:31:38.000000000 +0100 |
17467 |
++++ linux-2.6.23.15-grsec/fs/proc/inode.c 2008-02-11 10:37:44.000000000 +0000 |
17468 |
+@@ -418,7 +418,11 @@ struct inode *proc_get_inode(struct supe |
17469 |
+ if (de->mode) { |
17470 |
+ inode->i_mode = de->mode; |
17471 |
+ inode->i_uid = de->uid; |
17472 |
++#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP |
17473 |
++ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; |
17474 |
++#else |
17475 |
+ inode->i_gid = de->gid; |
17476 |
++#endif |
17477 |
+ } |
17478 |
+ if (de->size) |
17479 |
+ inode->i_size = de->size; |
17480 |
+diff -Nurp linux-2.6.23.15/fs/proc/internal.h linux-2.6.23.15-grsec/fs/proc/internal.h |
17481 |
+--- linux-2.6.23.15/fs/proc/internal.h 2007-10-09 21:31:38.000000000 +0100 |
17482 |
++++ linux-2.6.23.15-grsec/fs/proc/internal.h 2008-02-11 10:37:44.000000000 +0000 |
17483 |
+@@ -45,6 +45,9 @@ extern int proc_tid_stat(struct task_str |
17484 |
+ extern int proc_tgid_stat(struct task_struct *, char *); |
17485 |
+ extern int proc_pid_status(struct task_struct *, char *); |
17486 |
+ extern int proc_pid_statm(struct task_struct *, char *); |
17487 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
17488 |
++extern int proc_pid_ipaddr(struct task_struct*,char*); |
17489 |
++#endif |
17490 |
+ |
17491 |
+ extern const struct file_operations proc_maps_operations; |
17492 |
+ extern const struct file_operations proc_numa_maps_operations; |
17493 |
+diff -Nurp linux-2.6.23.15/fs/proc/proc_misc.c linux-2.6.23.15-grsec/fs/proc/proc_misc.c |
17494 |
+--- linux-2.6.23.15/fs/proc/proc_misc.c 2007-10-09 21:31:38.000000000 +0100 |
17495 |
++++ linux-2.6.23.15-grsec/fs/proc/proc_misc.c 2008-02-11 10:37:44.000000000 +0000 |
17496 |
+@@ -668,6 +668,8 @@ void create_seq_entry(char *name, mode_t |
17497 |
+ |
17498 |
+ void __init proc_misc_init(void) |
17499 |
+ { |
17500 |
++ int gr_mode = 0; |
17501 |
++ |
17502 |
+ static struct { |
17503 |
+ char *name; |
17504 |
+ int (*read_proc)(char*,char**,off_t,int,int*,void*); |
17505 |
+@@ -683,7 +685,9 @@ void __init proc_misc_init(void) |
17506 |
+ {"stram", stram_read_proc}, |
17507 |
+ #endif |
17508 |
+ {"filesystems", filesystems_read_proc}, |
17509 |
++#ifndef CONFIG_GRKERNSEC_PROC_ADD |
17510 |
+ {"cmdline", cmdline_read_proc}, |
17511 |
++#endif |
17512 |
+ {"locks", locks_read_proc}, |
17513 |
+ {"execdomains", execdomains_read_proc}, |
17514 |
+ {NULL,} |
17515 |
+@@ -691,6 +695,15 @@ void __init proc_misc_init(void) |
17516 |
+ for (p = simple_ones; p->name; p++) |
17517 |
+ create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL); |
17518 |
+ |
17519 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17520 |
++ gr_mode = S_IRUSR; |
17521 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17522 |
++ gr_mode = S_IRUSR | S_IRGRP; |
17523 |
++#endif |
17524 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17525 |
++ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL); |
17526 |
++#endif |
17527 |
++ |
17528 |
+ proc_symlink("mounts", NULL, "self/mounts"); |
17529 |
+ |
17530 |
+ /* And now for trickier ones */ |
17531 |
+@@ -702,7 +715,11 @@ void __init proc_misc_init(void) |
17532 |
+ entry->proc_fops = &proc_kmsg_operations; |
17533 |
+ } |
17534 |
+ #endif |
17535 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17536 |
++ create_seq_entry("devices", gr_mode, &proc_devinfo_operations); |
17537 |
++#else |
17538 |
+ create_seq_entry("devices", 0, &proc_devinfo_operations); |
17539 |
++#endif |
17540 |
+ create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); |
17541 |
+ #ifdef CONFIG_BLOCK |
17542 |
+ create_seq_entry("partitions", 0, &proc_partitions_operations); |
17543 |
+@@ -710,7 +727,11 @@ void __init proc_misc_init(void) |
17544 |
+ create_seq_entry("stat", 0, &proc_stat_operations); |
17545 |
+ create_seq_entry("interrupts", 0, &proc_interrupts_operations); |
17546 |
+ #ifdef CONFIG_SLAB |
17547 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17548 |
++ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations); |
17549 |
++#else |
17550 |
+ create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); |
17551 |
++#endif |
17552 |
+ #ifdef CONFIG_DEBUG_SLAB_LEAK |
17553 |
+ create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); |
17554 |
+ #endif |
17555 |
+@@ -727,7 +748,7 @@ void __init proc_misc_init(void) |
17556 |
+ #ifdef CONFIG_SCHEDSTATS |
17557 |
+ create_seq_entry("schedstat", 0, &proc_schedstat_operations); |
17558 |
+ #endif |
17559 |
+-#ifdef CONFIG_PROC_KCORE |
17560 |
++#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD) |
17561 |
+ proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); |
17562 |
+ if (proc_root_kcore) { |
17563 |
+ proc_root_kcore->proc_fops = &proc_kcore_operations; |
17564 |
+diff -Nurp linux-2.6.23.15/fs/proc/proc_sysctl.c linux-2.6.23.15-grsec/fs/proc/proc_sysctl.c |
17565 |
+--- linux-2.6.23.15/fs/proc/proc_sysctl.c 2007-10-09 21:31:38.000000000 +0100 |
17566 |
++++ linux-2.6.23.15-grsec/fs/proc/proc_sysctl.c 2008-02-11 10:37:44.000000000 +0000 |
17567 |
+@@ -7,6 +7,8 @@ |
17568 |
+ #include <linux/security.h> |
17569 |
+ #include "internal.h" |
17570 |
+ |
17571 |
++extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op); |
17572 |
++ |
17573 |
+ static struct dentry_operations proc_sys_dentry_operations; |
17574 |
+ static const struct file_operations proc_sys_file_operations; |
17575 |
+ static struct inode_operations proc_sys_inode_operations; |
17576 |
+@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st |
17577 |
+ if (!table) |
17578 |
+ goto out; |
17579 |
+ |
17580 |
++ if (gr_handle_sysctl(table, 001)) |
17581 |
++ goto out; |
17582 |
++ |
17583 |
+ err = ERR_PTR(-ENOMEM); |
17584 |
+ inode = proc_sys_make_inode(dir, table); |
17585 |
+ if (!inode) |
17586 |
+@@ -358,6 +363,9 @@ static int proc_sys_readdir(struct file |
17587 |
+ if (pos < filp->f_pos) |
17588 |
+ continue; |
17589 |
+ |
17590 |
++ if (gr_handle_sysctl(table, 0)) |
17591 |
++ continue; |
17592 |
++ |
17593 |
+ if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0) |
17594 |
+ goto out; |
17595 |
+ filp->f_pos = pos + 1; |
17596 |
+@@ -420,6 +428,30 @@ out: |
17597 |
+ return error; |
17598 |
+ } |
17599 |
+ |
17600 |
++/* Eric Biederman is to blame */ |
17601 |
++static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
17602 |
++{ |
17603 |
++ int error = 0; |
17604 |
++ struct ctl_table_header *head; |
17605 |
++ struct ctl_table *table; |
17606 |
++ |
17607 |
++ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); |
17608 |
++ /* Has the sysctl entry disappeared on us? */ |
17609 |
++ if (!table) |
17610 |
++ goto out; |
17611 |
++ |
17612 |
++ if (gr_handle_sysctl(table, 001)) { |
17613 |
++ error = -ENOENT; |
17614 |
++ goto out; |
17615 |
++ } |
17616 |
++ |
17617 |
++out: |
17618 |
++ sysctl_head_finish(head); |
17619 |
++ |
17620 |
++ generic_fillattr(dentry->d_inode, stat); |
17621 |
++ |
17622 |
++ return error; |
17623 |
++} |
17624 |
+ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr) |
17625 |
+ { |
17626 |
+ struct inode *inode = dentry->d_inode; |
17627 |
+@@ -448,6 +480,7 @@ static struct inode_operations proc_sys_ |
17628 |
+ .lookup = proc_sys_lookup, |
17629 |
+ .permission = proc_sys_permission, |
17630 |
+ .setattr = proc_sys_setattr, |
17631 |
++ .getattr = proc_sys_getattr, |
17632 |
+ }; |
17633 |
+ |
17634 |
+ static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) |
17635 |
+diff -Nurp linux-2.6.23.15/fs/proc/root.c linux-2.6.23.15-grsec/fs/proc/root.c |
17636 |
+--- linux-2.6.23.15/fs/proc/root.c 2007-10-09 21:31:38.000000000 +0100 |
17637 |
++++ linux-2.6.23.15-grsec/fs/proc/root.c 2008-02-11 10:37:44.000000000 +0000 |
17638 |
+@@ -61,7 +61,13 @@ void __init proc_root_init(void) |
17639 |
+ return; |
17640 |
+ } |
17641 |
+ proc_misc_init(); |
17642 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17643 |
++ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL); |
17644 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17645 |
++ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL); |
17646 |
++#else |
17647 |
+ proc_net = proc_mkdir("net", NULL); |
17648 |
++#endif |
17649 |
+ proc_net_stat = proc_mkdir("net/stat", NULL); |
17650 |
+ |
17651 |
+ #ifdef CONFIG_SYSVIPC |
17652 |
+@@ -78,7 +84,15 @@ void __init proc_root_init(void) |
17653 |
+ #ifdef CONFIG_PROC_DEVICETREE |
17654 |
+ proc_device_tree_init(); |
17655 |
+ #endif |
17656 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
17657 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
17658 |
++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL); |
17659 |
++#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) |
17660 |
++ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL); |
17661 |
++#endif |
17662 |
++#else |
17663 |
+ proc_bus = proc_mkdir("bus", NULL); |
17664 |
++#endif |
17665 |
+ proc_sys_init(); |
17666 |
+ } |
17667 |
+ |
17668 |
+diff -Nurp linux-2.6.23.15/fs/proc/task_mmu.c linux-2.6.23.15-grsec/fs/proc/task_mmu.c |
17669 |
+--- linux-2.6.23.15/fs/proc/task_mmu.c 2007-10-09 21:31:38.000000000 +0100 |
17670 |
++++ linux-2.6.23.15-grsec/fs/proc/task_mmu.c 2008-02-11 10:37:44.000000000 +0000 |
17671 |
+@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha |
17672 |
+ "VmStk:\t%8lu kB\n" |
17673 |
+ "VmExe:\t%8lu kB\n" |
17674 |
+ "VmLib:\t%8lu kB\n" |
17675 |
+- "VmPTE:\t%8lu kB\n", |
17676 |
+- hiwater_vm << (PAGE_SHIFT-10), |
17677 |
++ "VmPTE:\t%8lu kB\n" |
17678 |
++ |
17679 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
17680 |
++ "CsBase:\t%8lx\nCsLim:\t%8lx\n" |
17681 |
++#endif |
17682 |
++ |
17683 |
++ ,hiwater_vm << (PAGE_SHIFT-10), |
17684 |
+ (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10), |
17685 |
+ mm->locked_vm << (PAGE_SHIFT-10), |
17686 |
+ hiwater_rss << (PAGE_SHIFT-10), |
17687 |
+ total_rss << (PAGE_SHIFT-10), |
17688 |
+ data << (PAGE_SHIFT-10), |
17689 |
+ mm->stack_vm << (PAGE_SHIFT-10), text, lib, |
17690 |
+- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10); |
17691 |
++ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10 |
17692 |
++ |
17693 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
17694 |
++ , mm->context.user_cs_base, mm->context.user_cs_limit |
17695 |
++#endif |
17696 |
++ |
17697 |
++ ); |
17698 |
++ |
17699 |
+ return buffer; |
17700 |
+ } |
17701 |
+ |
17702 |
+@@ -131,6 +143,12 @@ struct pmd_walker { |
17703 |
+ unsigned long, void *); |
17704 |
+ }; |
17705 |
+ |
17706 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17707 |
++#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \ |
17708 |
++ (_mm->pax_flags & MF_PAX_RANDMMAP || \ |
17709 |
++ _mm->pax_flags & MF_PAX_SEGMEXEC)) |
17710 |
++#endif |
17711 |
++ |
17712 |
+ static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss) |
17713 |
+ { |
17714 |
+ struct proc_maps_private *priv = m->private; |
17715 |
+@@ -153,13 +171,22 @@ static int show_map_internal(struct seq_ |
17716 |
+ } |
17717 |
+ |
17718 |
+ seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n", |
17719 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17720 |
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start, |
17721 |
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end, |
17722 |
++#else |
17723 |
+ vma->vm_start, |
17724 |
+ vma->vm_end, |
17725 |
++#endif |
17726 |
+ flags & VM_READ ? 'r' : '-', |
17727 |
+ flags & VM_WRITE ? 'w' : '-', |
17728 |
+ flags & VM_EXEC ? 'x' : '-', |
17729 |
+ flags & VM_MAYSHARE ? 's' : 'p', |
17730 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17731 |
++ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT, |
17732 |
++#else |
17733 |
+ vma->vm_pgoff << PAGE_SHIFT, |
17734 |
++#endif |
17735 |
+ MAJOR(dev), MINOR(dev), ino, &len); |
17736 |
+ |
17737 |
+ /* |
17738 |
+@@ -173,11 +200,11 @@ static int show_map_internal(struct seq_ |
17739 |
+ const char *name = arch_vma_name(vma); |
17740 |
+ if (!name) { |
17741 |
+ if (mm) { |
17742 |
+- if (vma->vm_start <= mm->start_brk && |
17743 |
+- vma->vm_end >= mm->brk) { |
17744 |
++ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { |
17745 |
+ name = "[heap]"; |
17746 |
+- } else if (vma->vm_start <= mm->start_stack && |
17747 |
+- vma->vm_end >= mm->start_stack) { |
17748 |
++ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) || |
17749 |
++ (vma->vm_start <= mm->start_stack && |
17750 |
++ vma->vm_end >= mm->start_stack)) { |
17751 |
+ name = "[stack]"; |
17752 |
+ } |
17753 |
+ } else { |
17754 |
+@@ -191,7 +218,27 @@ static int show_map_internal(struct seq_ |
17755 |
+ } |
17756 |
+ seq_putc(m, '\n'); |
17757 |
+ |
17758 |
+- if (mss) |
17759 |
++ |
17760 |
++ if (mss) { |
17761 |
++#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP |
17762 |
++ if (PAX_RAND_FLAGS(mm)) |
17763 |
++ seq_printf(m, |
17764 |
++ "Size: %8lu kB\n" |
17765 |
++ "Rss: %8lu kB\n" |
17766 |
++ "Shared_Clean: %8lu kB\n" |
17767 |
++ "Shared_Dirty: %8lu kB\n" |
17768 |
++ "Private_Clean: %8lu kB\n" |
17769 |
++ "Private_Dirty: %8lu kB\n", |
17770 |
++ "Referenced: %8lu kB\n", |
17771 |
++ 0UL, |
17772 |
++ 0UL, |
17773 |
++ 0UL, |
17774 |
++ 0UL, |
17775 |
++ 0UL, |
17776 |
++ 0UL, |
17777 |
++ 0UL); |
17778 |
++ else |
17779 |
++#endif |
17780 |
+ seq_printf(m, |
17781 |
+ "Size: %8lu kB\n" |
17782 |
+ "Rss: %8lu kB\n" |
17783 |
+@@ -207,6 +254,7 @@ static int show_map_internal(struct seq_ |
17784 |
+ mss->private_clean >> 10, |
17785 |
+ mss->private_dirty >> 10, |
17786 |
+ mss->referenced >> 10); |
17787 |
++ } |
17788 |
+ |
17789 |
+ if (m->count < m->size) /* vma is copied successfully */ |
17790 |
+ m->version = (vma != get_gate_vma(task))? vma->vm_start: 0; |
17791 |
+diff -Nurp linux-2.6.23.15/fs/readdir.c linux-2.6.23.15-grsec/fs/readdir.c |
17792 |
+--- linux-2.6.23.15/fs/readdir.c 2007-10-09 21:31:38.000000000 +0100 |
17793 |
++++ linux-2.6.23.15-grsec/fs/readdir.c 2008-02-11 10:37:44.000000000 +0000 |
17794 |
+@@ -16,6 +16,8 @@ |
17795 |
+ #include <linux/security.h> |
17796 |
+ #include <linux/syscalls.h> |
17797 |
+ #include <linux/unistd.h> |
17798 |
++#include <linux/namei.h> |
17799 |
++#include <linux/grsecurity.h> |
17800 |
+ |
17801 |
+ #include <asm/uaccess.h> |
17802 |
+ |
17803 |
+@@ -64,6 +66,7 @@ struct old_linux_dirent { |
17804 |
+ |
17805 |
+ struct readdir_callback { |
17806 |
+ struct old_linux_dirent __user * dirent; |
17807 |
++ struct file * file; |
17808 |
+ int result; |
17809 |
+ }; |
17810 |
+ |
17811 |
+@@ -79,6 +82,10 @@ static int fillonedir(void * __buf, cons |
17812 |
+ d_ino = ino; |
17813 |
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) |
17814 |
+ return -EOVERFLOW; |
17815 |
++ |
17816 |
++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) |
17817 |
++ return 0; |
17818 |
++ |
17819 |
+ buf->result++; |
17820 |
+ dirent = buf->dirent; |
17821 |
+ if (!access_ok(VERIFY_WRITE, dirent, |
17822 |
+@@ -110,6 +117,7 @@ asmlinkage long old_readdir(unsigned int |
17823 |
+ |
17824 |
+ buf.result = 0; |
17825 |
+ buf.dirent = dirent; |
17826 |
++ buf.file = file; |
17827 |
+ |
17828 |
+ error = vfs_readdir(file, fillonedir, &buf); |
17829 |
+ if (error >= 0) |
17830 |
+@@ -136,6 +144,7 @@ struct linux_dirent { |
17831 |
+ struct getdents_callback { |
17832 |
+ struct linux_dirent __user * current_dir; |
17833 |
+ struct linux_dirent __user * previous; |
17834 |
++ struct file * file; |
17835 |
+ int count; |
17836 |
+ int error; |
17837 |
+ }; |
17838 |
+@@ -154,6 +163,10 @@ static int filldir(void * __buf, const c |
17839 |
+ d_ino = ino; |
17840 |
+ if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) |
17841 |
+ return -EOVERFLOW; |
17842 |
++ |
17843 |
++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) |
17844 |
++ return 0; |
17845 |
++ |
17846 |
+ dirent = buf->previous; |
17847 |
+ if (dirent) { |
17848 |
+ if (__put_user(offset, &dirent->d_off)) |
17849 |
+@@ -200,6 +213,7 @@ asmlinkage long sys_getdents(unsigned in |
17850 |
+ buf.previous = NULL; |
17851 |
+ buf.count = count; |
17852 |
+ buf.error = 0; |
17853 |
++ buf.file = file; |
17854 |
+ |
17855 |
+ error = vfs_readdir(file, filldir, &buf); |
17856 |
+ if (error < 0) |
17857 |
+@@ -222,6 +236,7 @@ out: |
17858 |
+ struct getdents_callback64 { |
17859 |
+ struct linux_dirent64 __user * current_dir; |
17860 |
+ struct linux_dirent64 __user * previous; |
17861 |
++ struct file *file; |
17862 |
+ int count; |
17863 |
+ int error; |
17864 |
+ }; |
17865 |
+@@ -236,6 +251,10 @@ static int filldir64(void * __buf, const |
17866 |
+ buf->error = -EINVAL; /* only used if we fail.. */ |
17867 |
+ if (reclen > buf->count) |
17868 |
+ return -EINVAL; |
17869 |
++ |
17870 |
++ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino)) |
17871 |
++ return 0; |
17872 |
++ |
17873 |
+ dirent = buf->previous; |
17874 |
+ if (dirent) { |
17875 |
+ if (__put_user(offset, &dirent->d_off)) |
17876 |
+@@ -282,6 +301,7 @@ asmlinkage long sys_getdents64(unsigned |
17877 |
+ |
17878 |
+ buf.current_dir = dirent; |
17879 |
+ buf.previous = NULL; |
17880 |
++ buf.file = file; |
17881 |
+ buf.count = count; |
17882 |
+ buf.error = 0; |
17883 |
+ |
17884 |
+diff -Nurp linux-2.6.23.15/fs/udf/balloc.c linux-2.6.23.15-grsec/fs/udf/balloc.c |
17885 |
+--- linux-2.6.23.15/fs/udf/balloc.c 2007-10-09 21:31:38.000000000 +0100 |
17886 |
++++ linux-2.6.23.15-grsec/fs/udf/balloc.c 2008-02-11 10:37:44.000000000 +0000 |
17887 |
+@@ -154,8 +154,7 @@ static void udf_bitmap_free_blocks(struc |
17888 |
+ unsigned long overflow; |
17889 |
+ |
17890 |
+ mutex_lock(&sbi->s_alloc_mutex); |
17891 |
+- if (bloc.logicalBlockNum < 0 || |
17892 |
+- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
17893 |
++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
17894 |
+ udf_debug("%d < %d || %d + %d > %d\n", |
17895 |
+ bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, |
17896 |
+ UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)); |
17897 |
+@@ -221,7 +220,7 @@ static int udf_bitmap_prealloc_blocks(st |
17898 |
+ struct buffer_head *bh; |
17899 |
+ |
17900 |
+ mutex_lock(&sbi->s_alloc_mutex); |
17901 |
+- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) |
17902 |
++ if (first_block >= UDF_SB_PARTLEN(sb, partition)) |
17903 |
+ goto out; |
17904 |
+ |
17905 |
+ if (first_block + block_count > UDF_SB_PARTLEN(sb, partition)) |
17906 |
+@@ -287,7 +286,7 @@ static int udf_bitmap_new_block(struct s |
17907 |
+ mutex_lock(&sbi->s_alloc_mutex); |
17908 |
+ |
17909 |
+ repeat: |
17910 |
+- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition)) |
17911 |
++ if (goal >= UDF_SB_PARTLEN(sb, partition)) |
17912 |
+ goal = 0; |
17913 |
+ |
17914 |
+ nr_groups = bitmap->s_nr_groups; |
17915 |
+@@ -420,8 +419,7 @@ static void udf_table_free_blocks(struct |
17916 |
+ int i; |
17917 |
+ |
17918 |
+ mutex_lock(&sbi->s_alloc_mutex); |
17919 |
+- if (bloc.logicalBlockNum < 0 || |
17920 |
+- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
17921 |
++ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)) { |
17922 |
+ udf_debug("%d < %d || %d + %d > %d\n", |
17923 |
+ bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count, |
17924 |
+ UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum)); |
17925 |
+@@ -627,7 +625,7 @@ static int udf_table_prealloc_blocks(str |
17926 |
+ struct extent_position epos; |
17927 |
+ int8_t etype = -1; |
17928 |
+ |
17929 |
+- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition)) |
17930 |
++ if (first_block >= UDF_SB_PARTLEN(sb, partition)) |
17931 |
+ return 0; |
17932 |
+ |
17933 |
+ if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT) |
17934 |
+@@ -703,7 +701,7 @@ static int udf_table_new_block(struct su |
17935 |
+ return newblock; |
17936 |
+ |
17937 |
+ mutex_lock(&sbi->s_alloc_mutex); |
17938 |
+- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition)) |
17939 |
++ if (goal >= UDF_SB_PARTLEN(sb, partition)) |
17940 |
+ goal = 0; |
17941 |
+ |
17942 |
+ /* We search for the closest matching block to goal. If we find a exact hit, |
17943 |
+diff -Nurp linux-2.6.23.15/fs/udf/inode.c linux-2.6.23.15-grsec/fs/udf/inode.c |
17944 |
+--- linux-2.6.23.15/fs/udf/inode.c 2007-10-09 21:31:38.000000000 +0100 |
17945 |
++++ linux-2.6.23.15-grsec/fs/udf/inode.c 2008-02-11 10:37:44.000000000 +0000 |
17946 |
+@@ -308,9 +308,6 @@ static int udf_get_block(struct inode *i |
17947 |
+ |
17948 |
+ lock_kernel(); |
17949 |
+ |
17950 |
+- if (block < 0) |
17951 |
+- goto abort_negative; |
17952 |
+- |
17953 |
+ if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1) { |
17954 |
+ UDF_I_NEXT_ALLOC_BLOCK(inode)++; |
17955 |
+ UDF_I_NEXT_ALLOC_GOAL(inode)++; |
17956 |
+@@ -331,10 +328,6 @@ static int udf_get_block(struct inode *i |
17957 |
+ abort: |
17958 |
+ unlock_kernel(); |
17959 |
+ return err; |
17960 |
+- |
17961 |
+-abort_negative: |
17962 |
+- udf_warning(inode->i_sb, "udf_get_block", "block < 0"); |
17963 |
+- goto abort; |
17964 |
+ } |
17965 |
+ |
17966 |
+ static struct buffer_head *udf_getblk(struct inode *inode, long block, |
17967 |
+diff -Nurp linux-2.6.23.15/fs/ufs/inode.c linux-2.6.23.15-grsec/fs/ufs/inode.c |
17968 |
+--- linux-2.6.23.15/fs/ufs/inode.c 2007-10-09 21:31:38.000000000 +0100 |
17969 |
++++ linux-2.6.23.15-grsec/fs/ufs/inode.c 2008-02-11 10:37:44.000000000 +0000 |
17970 |
+@@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod |
17971 |
+ |
17972 |
+ |
17973 |
+ UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks); |
17974 |
+- if (i_block < 0) { |
17975 |
+- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0"); |
17976 |
+- } else if (i_block < direct_blocks) { |
17977 |
++ if (i_block < direct_blocks) { |
17978 |
+ offsets[n++] = i_block; |
17979 |
+ } else if ((i_block -= direct_blocks) < indirect_blocks) { |
17980 |
+ offsets[n++] = UFS_IND_BLOCK; |
17981 |
+@@ -439,8 +437,6 @@ int ufs_getfrag_block(struct inode *inod |
17982 |
+ lock_kernel(); |
17983 |
+ |
17984 |
+ UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment); |
17985 |
+- if (fragment < 0) |
17986 |
+- goto abort_negative; |
17987 |
+ if (fragment > |
17988 |
+ ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb) |
17989 |
+ << uspi->s_fpbshift)) |
17990 |
+@@ -503,10 +499,6 @@ abort: |
17991 |
+ unlock_kernel(); |
17992 |
+ return err; |
17993 |
+ |
17994 |
+-abort_negative: |
17995 |
+- ufs_warning(sb, "ufs_get_block", "block < 0"); |
17996 |
+- goto abort; |
17997 |
+- |
17998 |
+ abort_too_big: |
17999 |
+ ufs_warning(sb, "ufs_get_block", "block > big"); |
18000 |
+ goto abort; |
18001 |
+diff -Nurp linux-2.6.23.15/fs/utimes.c linux-2.6.23.15-grsec/fs/utimes.c |
18002 |
+--- linux-2.6.23.15/fs/utimes.c 2007-10-09 21:31:38.000000000 +0100 |
18003 |
++++ linux-2.6.23.15-grsec/fs/utimes.c 2008-02-11 10:37:44.000000000 +0000 |
18004 |
+@@ -6,6 +6,7 @@ |
18005 |
+ #include <linux/sched.h> |
18006 |
+ #include <linux/stat.h> |
18007 |
+ #include <linux/utime.h> |
18008 |
++#include <linux/grsecurity.h> |
18009 |
+ #include <asm/uaccess.h> |
18010 |
+ #include <asm/unistd.h> |
18011 |
+ |
18012 |
+@@ -47,6 +48,7 @@ long do_utimes(int dfd, char __user *fil |
18013 |
+ int error; |
18014 |
+ struct nameidata nd; |
18015 |
+ struct dentry *dentry; |
18016 |
++ struct vfsmount *mnt; |
18017 |
+ struct inode *inode; |
18018 |
+ struct iattr newattrs; |
18019 |
+ struct file *f = NULL; |
18020 |
+@@ -65,12 +67,14 @@ long do_utimes(int dfd, char __user *fil |
18021 |
+ if (!f) |
18022 |
+ goto out; |
18023 |
+ dentry = f->f_path.dentry; |
18024 |
++ mnt = f->f_path.mnt; |
18025 |
+ } else { |
18026 |
+ error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd); |
18027 |
+ if (error) |
18028 |
+ goto out; |
18029 |
+ |
18030 |
+ dentry = nd.dentry; |
18031 |
++ mnt = nd.mnt; |
18032 |
+ } |
18033 |
+ |
18034 |
+ inode = dentry->d_inode; |
18035 |
+@@ -117,6 +121,12 @@ long do_utimes(int dfd, char __user *fil |
18036 |
+ } |
18037 |
+ } |
18038 |
+ } |
18039 |
++ |
18040 |
++ if (!gr_acl_handle_utime(dentry, mnt)) { |
18041 |
++ error = -EACCES; |
18042 |
++ goto dput_and_out; |
18043 |
++ } |
18044 |
++ |
18045 |
+ mutex_lock(&inode->i_mutex); |
18046 |
+ error = notify_change(dentry, &newattrs); |
18047 |
+ mutex_unlock(&inode->i_mutex); |
18048 |
+diff -Nurp linux-2.6.23.15/fs/xfs/xfs_bmap.c linux-2.6.23.15-grsec/fs/xfs/xfs_bmap.c |
18049 |
+--- linux-2.6.23.15/fs/xfs/xfs_bmap.c 2007-10-09 21:31:38.000000000 +0100 |
18050 |
++++ linux-2.6.23.15-grsec/fs/xfs/xfs_bmap.c 2008-02-11 10:37:44.000000000 +0000 |
18051 |
+@@ -374,7 +374,7 @@ xfs_bmap_validate_ret( |
18052 |
+ int nmap, |
18053 |
+ int ret_nmap); |
18054 |
+ #else |
18055 |
+-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) |
18056 |
++#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0) |
18057 |
+ #endif /* DEBUG */ |
18058 |
+ |
18059 |
+ #if defined(XFS_RW_TRACE) |
18060 |
+diff -Nurp linux-2.6.23.15/grsecurity/Kconfig linux-2.6.23.15-grsec/grsecurity/Kconfig |
18061 |
+--- linux-2.6.23.15/grsecurity/Kconfig 1970-01-01 01:00:00.000000000 +0100 |
18062 |
++++ linux-2.6.23.15-grsec/grsecurity/Kconfig 2008-02-11 10:37:44.000000000 +0000 |
18063 |
+@@ -0,0 +1,873 @@ |
18064 |
++# |
18065 |
++# grecurity configuration |
18066 |
++# |
18067 |
++ |
18068 |
++menu "Grsecurity" |
18069 |
++ |
18070 |
++config GRKERNSEC |
18071 |
++ bool "Grsecurity" |
18072 |
++ select CRYPTO |
18073 |
++ select CRYPTO_SHA256 |
18074 |
++ help |
18075 |
++ If you say Y here, you will be able to configure many features |
18076 |
++ that will enhance the security of your system. It is highly |
18077 |
++ recommended that you say Y here and read through the help |
18078 |
++ for each option so that you fully understand the features and |
18079 |
++ can evaluate their usefulness for your machine. |
18080 |
++ |
18081 |
++choice |
18082 |
++ prompt "Security Level" |
18083 |
++ depends GRKERNSEC |
18084 |
++ default GRKERNSEC_CUSTOM |
18085 |
++ |
18086 |
++config GRKERNSEC_LOW |
18087 |
++ bool "Low" |
18088 |
++ select GRKERNSEC_LINK |
18089 |
++ select GRKERNSEC_FIFO |
18090 |
++ select GRKERNSEC_EXECVE |
18091 |
++ select GRKERNSEC_RANDNET |
18092 |
++ select GRKERNSEC_DMESG |
18093 |
++ select GRKERNSEC_CHROOT_CHDIR |
18094 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
18095 |
++ |
18096 |
++ help |
18097 |
++ If you choose this option, several of the grsecurity options will |
18098 |
++ be enabled that will give you greater protection against a number |
18099 |
++ of attacks, while assuring that none of your software will have any |
18100 |
++ conflicts with the additional security measures. If you run a lot |
18101 |
++ of unusual software, or you are having problems with the higher |
18102 |
++ security levels, you should say Y here. With this option, the |
18103 |
++ following features are enabled: |
18104 |
++ |
18105 |
++ - Linking restrictions |
18106 |
++ - FIFO restrictions |
18107 |
++ - Enforcing RLIMIT_NPROC on execve |
18108 |
++ - Restricted dmesg |
18109 |
++ - Enforced chdir("/") on chroot |
18110 |
++ - Runtime module disabling |
18111 |
++ |
18112 |
++config GRKERNSEC_MEDIUM |
18113 |
++ bool "Medium" |
18114 |
++ select PAX |
18115 |
++ select PAX_EI_PAX |
18116 |
++ select PAX_PT_PAX_FLAGS |
18117 |
++ select PAX_HAVE_ACL_FLAGS |
18118 |
++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR) |
18119 |
++ select GRKERNSEC_CHROOT_SYSCTL |
18120 |
++ select GRKERNSEC_LINK |
18121 |
++ select GRKERNSEC_FIFO |
18122 |
++ select GRKERNSEC_EXECVE |
18123 |
++ select GRKERNSEC_DMESG |
18124 |
++ select GRKERNSEC_RANDNET |
18125 |
++ select GRKERNSEC_FORKFAIL |
18126 |
++ select GRKERNSEC_TIME |
18127 |
++ select GRKERNSEC_SIGNAL |
18128 |
++ select GRKERNSEC_CHROOT |
18129 |
++ select GRKERNSEC_CHROOT_UNIX |
18130 |
++ select GRKERNSEC_CHROOT_MOUNT |
18131 |
++ select GRKERNSEC_CHROOT_PIVOT |
18132 |
++ select GRKERNSEC_CHROOT_DOUBLE |
18133 |
++ select GRKERNSEC_CHROOT_CHDIR |
18134 |
++ select GRKERNSEC_CHROOT_MKNOD |
18135 |
++ select GRKERNSEC_PROC |
18136 |
++ select GRKERNSEC_PROC_USERGROUP |
18137 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
18138 |
++ select PAX_RANDUSTACK |
18139 |
++ select PAX_ASLR |
18140 |
++ select PAX_RANDMMAP |
18141 |
++ |
18142 |
++ help |
18143 |
++ If you say Y here, several features in addition to those included |
18144 |
++ in the low additional security level will be enabled. These |
18145 |
++ features provide even more security to your system, though in rare |
18146 |
++ cases they may be incompatible with very old or poorly written |
18147 |
++ software. If you enable this option, make sure that your auth |
18148 |
++ service (identd) is running as gid 1001. With this option, |
18149 |
++ the following features (in addition to those provided in the |
18150 |
++ low additional security level) will be enabled: |
18151 |
++ |
18152 |
++ - Randomized TCP source ports |
18153 |
++ - Failed fork logging |
18154 |
++ - Time change logging |
18155 |
++ - Signal logging |
18156 |
++ - Deny mounts in chroot |
18157 |
++ - Deny double chrooting |
18158 |
++ - Deny sysctl writes in chroot |
18159 |
++ - Deny mknod in chroot |
18160 |
++ - Deny access to abstract AF_UNIX sockets out of chroot |
18161 |
++ - Deny pivot_root in chroot |
18162 |
++ - Denied writes of /dev/kmem, /dev/mem, and /dev/port |
18163 |
++ - /proc restrictions with special GID set to 10 (usually wheel) |
18164 |
++ - Address Space Layout Randomization (ASLR) |
18165 |
++ |
18166 |
++config GRKERNSEC_HIGH |
18167 |
++ bool "High" |
18168 |
++ select GRKERNSEC_LINK |
18169 |
++ select GRKERNSEC_FIFO |
18170 |
++ select GRKERNSEC_EXECVE |
18171 |
++ select GRKERNSEC_DMESG |
18172 |
++ select GRKERNSEC_FORKFAIL |
18173 |
++ select GRKERNSEC_TIME |
18174 |
++ select GRKERNSEC_SIGNAL |
18175 |
++ select GRKERNSEC_CHROOT_SHMAT |
18176 |
++ select GRKERNSEC_CHROOT_UNIX |
18177 |
++ select GRKERNSEC_CHROOT_MOUNT |
18178 |
++ select GRKERNSEC_CHROOT_FCHDIR |
18179 |
++ select GRKERNSEC_CHROOT_PIVOT |
18180 |
++ select GRKERNSEC_CHROOT_DOUBLE |
18181 |
++ select GRKERNSEC_CHROOT_CHDIR |
18182 |
++ select GRKERNSEC_CHROOT_MKNOD |
18183 |
++ select GRKERNSEC_CHROOT_CAPS |
18184 |
++ select GRKERNSEC_CHROOT_SYSCTL |
18185 |
++ select GRKERNSEC_CHROOT_FINDTASK |
18186 |
++ select GRKERNSEC_PROC |
18187 |
++ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR) |
18188 |
++ select GRKERNSEC_HIDESYM |
18189 |
++ select GRKERNSEC_BRUTE |
18190 |
++ select GRKERNSEC_SHM if (SYSVIPC) |
18191 |
++ select GRKERNSEC_PROC_USERGROUP |
18192 |
++ select GRKERNSEC_KMEM |
18193 |
++ select GRKERNSEC_RESLOG |
18194 |
++ select GRKERNSEC_RANDNET |
18195 |
++ select GRKERNSEC_PROC_ADD |
18196 |
++ select GRKERNSEC_CHROOT_CHMOD |
18197 |
++ select GRKERNSEC_CHROOT_NICE |
18198 |
++ select GRKERNSEC_AUDIT_MOUNT |
18199 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
18200 |
++ select PAX |
18201 |
++ select PAX_RANDUSTACK |
18202 |
++ select PAX_ASLR |
18203 |
++ select PAX_RANDMMAP |
18204 |
++ select PAX_NOEXEC |
18205 |
++ select PAX_MPROTECT |
18206 |
++ select PAX_EI_PAX |
18207 |
++ select PAX_PT_PAX_FLAGS |
18208 |
++ select PAX_HAVE_ACL_FLAGS |
18209 |
++ select PAX_KERNEXEC if (!X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK) |
18210 |
++ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO) |
18211 |
++ select PAX_RANDKSTACK if (X86_TSC && !X86_64) |
18212 |
++ select PAX_SEGMEXEC if (X86 && !X86_64) |
18213 |
++ select PAX_PAGEEXEC if (!X86) |
18214 |
++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
18215 |
++ select PAX_DLRESOLVE if (SPARC32 || SPARC64) |
18216 |
++ select PAX_SYSCALL if (PPC32) |
18217 |
++ select PAX_EMUTRAMP if (PARISC) |
18218 |
++ select PAX_EMUSIGRT if (PARISC) |
18219 |
++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
18220 |
++ help |
18221 |
++ If you say Y here, many of the features of grsecurity will be |
18222 |
++ enabled, which will protect you against many kinds of attacks |
18223 |
++ against your system. The heightened security comes at a cost |
18224 |
++ of an increased chance of incompatibilities with rare software |
18225 |
++ on your machine. Since this security level enables PaX, you should |
18226 |
++ view <http://pax.grsecurity.net> and read about the PaX |
18227 |
++ project. While you are there, download chpax and run it on |
18228 |
++ binaries that cause problems with PaX. Also remember that |
18229 |
++ since the /proc restrictions are enabled, you must run your |
18230 |
++ identd as gid 1001. This security level enables the following |
18231 |
++ features in addition to those listed in the low and medium |
18232 |
++ security levels: |
18233 |
++ |
18234 |
++ - Additional /proc restrictions |
18235 |
++ - Chmod restrictions in chroot |
18236 |
++ - No signals, ptrace, or viewing of processes outside of chroot |
18237 |
++ - Capability restrictions in chroot |
18238 |
++ - Deny fchdir out of chroot |
18239 |
++ - Priority restrictions in chroot |
18240 |
++ - Segmentation-based implementation of PaX |
18241 |
++ - Mprotect restrictions |
18242 |
++ - Removal of addresses from /proc/<pid>/[smaps|maps|stat] |
18243 |
++ - Kernel stack randomization |
18244 |
++ - Mount/unmount/remount logging |
18245 |
++ - Kernel symbol hiding |
18246 |
++ - Destroy unused shared memory |
18247 |
++ - Prevention of memory exhaustion-based exploits |
18248 |
++config GRKERNSEC_CUSTOM |
18249 |
++ bool "Custom" |
18250 |
++ help |
18251 |
++ If you say Y here, you will be able to configure every grsecurity |
18252 |
++ option, which allows you to enable many more features that aren't |
18253 |
++ covered in the basic security levels. These additional features |
18254 |
++ include TPE, socket restrictions, and the sysctl system for |
18255 |
++ grsecurity. It is advised that you read through the help for |
18256 |
++ each option to determine its usefulness in your situation. |
18257 |
++ |
18258 |
++endchoice |
18259 |
++ |
18260 |
++menu "Address Space Protection" |
18261 |
++depends on GRKERNSEC |
18262 |
++ |
18263 |
++config GRKERNSEC_KMEM |
18264 |
++ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port" |
18265 |
++ help |
18266 |
++ If you say Y here, /dev/kmem and /dev/mem won't be allowed to |
18267 |
++ be written to via mmap or otherwise to modify the running kernel. |
18268 |
++ /dev/port will also not be allowed to be opened. If you have module |
18269 |
++ support disabled, enabling this will close up four ways that are |
18270 |
++ currently used to insert malicious code into the running kernel. |
18271 |
++ Even with all these features enabled, we still highly recommend that |
18272 |
++ you use the RBAC system, as it is still possible for an attacker to |
18273 |
++ modify the running kernel through privileged I/O granted by ioperm/iopl. |
18274 |
++ If you are not using XFree86, you may be able to stop this additional |
18275 |
++ case by enabling the 'Disable privileged I/O' option. Though nothing |
18276 |
++ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem, |
18277 |
++ but only to video memory, which is the only writing we allow in this |
18278 |
++ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will |
18279 |
++ not be allowed to mprotect it with PROT_WRITE later. |
18280 |
++ It is highly recommended that you say Y here if you meet all the |
18281 |
++ conditions above. |
18282 |
++ |
18283 |
++config GRKERNSEC_IO |
18284 |
++ bool "Disable privileged I/O" |
18285 |
++ depends on X86 |
18286 |
++ select RTC |
18287 |
++ help |
18288 |
++ If you say Y here, all ioperm and iopl calls will return an error. |
18289 |
++ Ioperm and iopl can be used to modify the running kernel. |
18290 |
++ Unfortunately, some programs need this access to operate properly, |
18291 |
++ the most notable of which are XFree86 and hwclock. hwclock can be |
18292 |
++ remedied by having RTC support in the kernel, so CONFIG_RTC is |
18293 |
++ enabled if this option is enabled, to ensure that hwclock operates |
18294 |
++ correctly. XFree86 still will not operate correctly with this option |
18295 |
++ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86 |
18296 |
++ and you still want to protect your kernel against modification, |
18297 |
++ use the RBAC system. |
18298 |
++ |
18299 |
++config GRKERNSEC_PROC_MEMMAP |
18300 |
++ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]" |
18301 |
++ depends on PAX_NOEXEC || PAX_ASLR |
18302 |
++ help |
18303 |
++ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will |
18304 |
++ give no information about the addresses of its mappings if |
18305 |
++ PaX features that rely on random addresses are enabled on the task. |
18306 |
++ If you use PaX it is greatly recommended that you say Y here as it |
18307 |
++ closes up a hole that makes the full ASLR useless for suid |
18308 |
++ binaries. |
18309 |
++ |
18310 |
++config GRKERNSEC_BRUTE |
18311 |
++ bool "Deter exploit bruteforcing" |
18312 |
++ help |
18313 |
++ If you say Y here, attempts to bruteforce exploits against forking |
18314 |
++ daemons such as apache or sshd will be deterred. When a child of a |
18315 |
++ forking daemon is killed by PaX or crashes due to an illegal |
18316 |
++ instruction, the parent process will be delayed 30 seconds upon every |
18317 |
++ subsequent fork until the administrator is able to assess the |
18318 |
++ situation and restart the daemon. It is recommended that you also |
18319 |
++ enable signal logging in the auditing section so that logs are |
18320 |
++ generated when a process performs an illegal instruction. |
18321 |
++ |
18322 |
++config GRKERNSEC_MODSTOP |
18323 |
++ bool "Runtime module disabling" |
18324 |
++ depends on MODULES |
18325 |
++ help |
18326 |
++ If you say Y here, you will be able to disable the ability to (un)load |
18327 |
++ modules at runtime. This feature is useful if you need the ability |
18328 |
++ to load kernel modules at boot time, but do not want to allow an |
18329 |
++ attacker to load a rootkit kernel module into the system, or to remove |
18330 |
++ a loaded kernel module important to system functioning. You should |
18331 |
++ enable the /dev/mem protection feature as well, since rootkits can be |
18332 |
++ inserted into the kernel via other methods than kernel modules. Since |
18333 |
++ an untrusted module could still be loaded by modifying init scripts and |
18334 |
++ rebooting the system, it is also recommended that you enable the RBAC |
18335 |
++ system. If you enable this option, a sysctl option with name |
18336 |
++ "disable_modules" will be created. Setting this option to "1" disables |
18337 |
++ module loading. After this option is set, no further writes to it are |
18338 |
++ allowed until the system is rebooted. |
18339 |
++ |
18340 |
++config GRKERNSEC_HIDESYM |
18341 |
++ bool "Hide kernel symbols" |
18342 |
++ help |
18343 |
++ If you say Y here, getting information on loaded modules, and |
18344 |
++ displaying all kernel symbols through a syscall will be restricted |
18345 |
++ to users with CAP_SYS_MODULE. This option is only effective |
18346 |
++ provided the following conditions are met: |
18347 |
++ 1) The kernel using grsecurity is not precompiled by some distribution |
18348 |
++ 2) You are using the RBAC system and hiding other files such as your |
18349 |
++ kernel image and System.map |
18350 |
++ 3) You have the additional /proc restrictions enabled, which removes |
18351 |
++ /proc/kcore |
18352 |
++ If the above conditions are met, this option will aid to provide a |
18353 |
++ useful protection against local and remote kernel exploitation of |
18354 |
++ overflows and arbitrary read/write vulnerabilities. |
18355 |
++ |
18356 |
++endmenu |
18357 |
++menu "Role Based Access Control Options" |
18358 |
++depends on GRKERNSEC |
18359 |
++ |
18360 |
++config GRKERNSEC_ACL_HIDEKERN |
18361 |
++ bool "Hide kernel processes" |
18362 |
++ help |
18363 |
++ If you say Y here, all kernel threads will be hidden to all |
18364 |
++ processes but those whose subject has the "view hidden processes" |
18365 |
++ flag. |
18366 |
++ |
18367 |
++config GRKERNSEC_ACL_MAXTRIES |
18368 |
++ int "Maximum tries before password lockout" |
18369 |
++ default 3 |
18370 |
++ help |
18371 |
++ This option enforces the maximum number of times a user can attempt |
18372 |
++ to authorize themselves with the grsecurity RBAC system before being |
18373 |
++ denied the ability to attempt authorization again for a specified time. |
18374 |
++ The lower the number, the harder it will be to brute-force a password. |
18375 |
++ |
18376 |
++config GRKERNSEC_ACL_TIMEOUT |
18377 |
++ int "Time to wait after max password tries, in seconds" |
18378 |
++ default 30 |
18379 |
++ help |
18380 |
++ This option specifies the time the user must wait after attempting to |
18381 |
++ authorize to the RBAC system with the maximum number of invalid |
18382 |
++ passwords. The higher the number, the harder it will be to brute-force |
18383 |
++ a password. |
18384 |
++ |
18385 |
++endmenu |
18386 |
++menu "Filesystem Protections" |
18387 |
++depends on GRKERNSEC |
18388 |
++ |
18389 |
++config GRKERNSEC_PROC |
18390 |
++ bool "Proc restrictions" |
18391 |
++ help |
18392 |
++ If you say Y here, the permissions of the /proc filesystem |
18393 |
++ will be altered to enhance system security and privacy. You MUST |
18394 |
++ choose either a user only restriction or a user and group restriction. |
18395 |
++ Depending upon the option you choose, you can either restrict users to |
18396 |
++ see only the processes they themselves run, or choose a group that can |
18397 |
++ view all processes and files normally restricted to root if you choose |
18398 |
++ the "restrict to user only" option. NOTE: If you're running identd as |
18399 |
++ a non-root user, you will have to run it as the group you specify here. |
18400 |
++ |
18401 |
++config GRKERNSEC_PROC_USER |
18402 |
++ bool "Restrict /proc to user only" |
18403 |
++ depends on GRKERNSEC_PROC |
18404 |
++ help |
18405 |
++ If you say Y here, non-root users will only be able to view their own |
18406 |
++ processes, and restricts them from viewing network-related information, |
18407 |
++ and viewing kernel symbol and module information. |
18408 |
++ |
18409 |
++config GRKERNSEC_PROC_USERGROUP |
18410 |
++ bool "Allow special group" |
18411 |
++ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER |
18412 |
++ help |
18413 |
++ If you say Y here, you will be able to select a group that will be |
18414 |
++ able to view all processes, network-related information, and |
18415 |
++ kernel and symbol information. This option is useful if you want |
18416 |
++ to run identd as a non-root user. |
18417 |
++ |
18418 |
++config GRKERNSEC_PROC_GID |
18419 |
++ int "GID for special group" |
18420 |
++ depends on GRKERNSEC_PROC_USERGROUP |
18421 |
++ default 1001 |
18422 |
++ |
18423 |
++config GRKERNSEC_PROC_ADD |
18424 |
++ bool "Additional restrictions" |
18425 |
++ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP |
18426 |
++ help |
18427 |
++ If you say Y here, additional restrictions will be placed on |
18428 |
++ /proc that keep normal users from viewing device information and |
18429 |
++ slabinfo information that could be useful for exploits. |
18430 |
++ |
18431 |
++config GRKERNSEC_LINK |
18432 |
++ bool "Linking restrictions" |
18433 |
++ help |
18434 |
++ If you say Y here, /tmp race exploits will be prevented, since users |
18435 |
++ will no longer be able to follow symlinks owned by other users in |
18436 |
++ world-writable +t directories (i.e. /tmp), unless the owner of the |
18437 |
++ symlink is the owner of the directory. users will also not be |
18438 |
++ able to hardlink to files they do not own. If the sysctl option is |
18439 |
++ enabled, a sysctl option with name "linking_restrictions" is created. |
18440 |
++ |
18441 |
++config GRKERNSEC_FIFO |
18442 |
++ bool "FIFO restrictions" |
18443 |
++ help |
18444 |
++ If you say Y here, users will not be able to write to FIFOs they don't |
18445 |
++ own in world-writable +t directories (i.e. /tmp), unless the owner of |
18446 |
++ the FIFO is the same owner of the directory it's held in. If the sysctl |
18447 |
++ option is enabled, a sysctl option with name "fifo_restrictions" is |
18448 |
++ created. |
18449 |
++ |
18450 |
++config GRKERNSEC_CHROOT |
18451 |
++ bool "Chroot jail restrictions" |
18452 |
++ help |
18453 |
++ If you say Y here, you will be able to choose several options that will |
18454 |
++ make breaking out of a chrooted jail much more difficult. If you |
18455 |
++ encounter no software incompatibilities with the following options, it |
18456 |
++ is recommended that you enable each one. |
18457 |
++ |
18458 |
++config GRKERNSEC_CHROOT_MOUNT |
18459 |
++ bool "Deny mounts" |
18460 |
++ depends on GRKERNSEC_CHROOT |
18461 |
++ help |
18462 |
++ If you say Y here, processes inside a chroot will not be able to |
18463 |
++ mount or remount filesystems. If the sysctl option is enabled, a |
18464 |
++ sysctl option with name "chroot_deny_mount" is created. |
18465 |
++ |
18466 |
++config GRKERNSEC_CHROOT_DOUBLE |
18467 |
++ bool "Deny double-chroots" |
18468 |
++ depends on GRKERNSEC_CHROOT |
18469 |
++ help |
18470 |
++ If you say Y here, processes inside a chroot will not be able to chroot |
18471 |
++ again outside the chroot. This is a widely used method of breaking |
18472 |
++ out of a chroot jail and should not be allowed. If the sysctl |
18473 |
++ option is enabled, a sysctl option with name |
18474 |
++ "chroot_deny_chroot" is created. |
18475 |
++ |
18476 |
++config GRKERNSEC_CHROOT_PIVOT |
18477 |
++ bool "Deny pivot_root in chroot" |
18478 |
++ depends on GRKERNSEC_CHROOT |
18479 |
++ help |
18480 |
++ If you say Y here, processes inside a chroot will not be able to use |
18481 |
++ a function called pivot_root() that was introduced in Linux 2.3.41. It |
18482 |
++ works similar to chroot in that it changes the root filesystem. This |
18483 |
++ function could be misused in a chrooted process to attempt to break out |
18484 |
++ of the chroot, and therefore should not be allowed. If the sysctl |
18485 |
++ option is enabled, a sysctl option with name "chroot_deny_pivot" is |
18486 |
++ created. |
18487 |
++ |
18488 |
++config GRKERNSEC_CHROOT_CHDIR |
18489 |
++ bool "Enforce chdir(\"/\") on all chroots" |
18490 |
++ depends on GRKERNSEC_CHROOT |
18491 |
++ help |
18492 |
++ If you say Y here, the current working directory of all newly-chrooted |
18493 |
++ applications will be set to the the root directory of the chroot. |
18494 |
++ The man page on chroot(2) states: |
18495 |
++ Note that this call does not change the current working |
18496 |
++ directory, so that `.' can be outside the tree rooted at |
18497 |
++ `/'. In particular, the super-user can escape from a |
18498 |
++ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'. |
18499 |
++ |
18500 |
++ It is recommended that you say Y here, since it's not known to break |
18501 |
++ any software. If the sysctl option is enabled, a sysctl option with |
18502 |
++ name "chroot_enforce_chdir" is created. |
18503 |
++ |
18504 |
++config GRKERNSEC_CHROOT_CHMOD |
18505 |
++ bool "Deny (f)chmod +s" |
18506 |
++ depends on GRKERNSEC_CHROOT |
18507 |
++ help |
18508 |
++ If you say Y here, processes inside a chroot will not be able to chmod |
18509 |
++ or fchmod files to make them have suid or sgid bits. This protects |
18510 |
++ against another published method of breaking a chroot. If the sysctl |
18511 |
++ option is enabled, a sysctl option with name "chroot_deny_chmod" is |
18512 |
++ created. |
18513 |
++ |
18514 |
++config GRKERNSEC_CHROOT_FCHDIR |
18515 |
++ bool "Deny fchdir out of chroot" |
18516 |
++ depends on GRKERNSEC_CHROOT |
18517 |
++ help |
18518 |
++ If you say Y here, a well-known method of breaking chroots by fchdir'ing |
18519 |
++ to a file descriptor of the chrooting process that points to a directory |
18520 |
++ outside the filesystem will be stopped. If the sysctl option |
18521 |
++ is enabled, a sysctl option with name "chroot_deny_fchdir" is created. |
18522 |
++ |
18523 |
++config GRKERNSEC_CHROOT_MKNOD |
18524 |
++ bool "Deny mknod" |
18525 |
++ depends on GRKERNSEC_CHROOT |
18526 |
++ help |
18527 |
++ If you say Y here, processes inside a chroot will not be allowed to |
18528 |
++ mknod. The problem with using mknod inside a chroot is that it |
18529 |
++ would allow an attacker to create a device entry that is the same |
18530 |
++ as one on the physical root of your system, which could range from |
18531 |
++ anything from the console device to a device for your harddrive (which |
18532 |
++ they could then use to wipe the drive or steal data). It is recommended |
18533 |
++ that you say Y here, unless you run into software incompatibilities. |
18534 |
++ If the sysctl option is enabled, a sysctl option with name |
18535 |
++ "chroot_deny_mknod" is created. |
18536 |
++ |
18537 |
++config GRKERNSEC_CHROOT_SHMAT |
18538 |
++ bool "Deny shmat() out of chroot" |
18539 |
++ depends on GRKERNSEC_CHROOT |
18540 |
++ help |
18541 |
++ If you say Y here, processes inside a chroot will not be able to attach |
18542 |
++ to shared memory segments that were created outside of the chroot jail. |
18543 |
++ It is recommended that you say Y here. If the sysctl option is enabled, |
18544 |
++ a sysctl option with name "chroot_deny_shmat" is created. |
18545 |
++ |
18546 |
++config GRKERNSEC_CHROOT_UNIX |
18547 |
++ bool "Deny access to abstract AF_UNIX sockets out of chroot" |
18548 |
++ depends on GRKERNSEC_CHROOT |
18549 |
++ help |
18550 |
++ If you say Y here, processes inside a chroot will not be able to |
18551 |
++ connect to abstract (meaning not belonging to a filesystem) Unix |
18552 |
++ domain sockets that were bound outside of a chroot. It is recommended |
18553 |
++ that you say Y here. If the sysctl option is enabled, a sysctl option |
18554 |
++ with name "chroot_deny_unix" is created. |
18555 |
++ |
18556 |
++config GRKERNSEC_CHROOT_FINDTASK |
18557 |
++ bool "Protect outside processes" |
18558 |
++ depends on GRKERNSEC_CHROOT |
18559 |
++ help |
18560 |
++ If you say Y here, processes inside a chroot will not be able to |
18561 |
++ kill, send signals with fcntl, ptrace, capget, getpgid, getsid, |
18562 |
++ or view any process outside of the chroot. If the sysctl |
18563 |
++ option is enabled, a sysctl option with name "chroot_findtask" is |
18564 |
++ created. |
18565 |
++ |
18566 |
++config GRKERNSEC_CHROOT_NICE |
18567 |
++ bool "Restrict priority changes" |
18568 |
++ depends on GRKERNSEC_CHROOT |
18569 |
++ help |
18570 |
++ If you say Y here, processes inside a chroot will not be able to raise |
18571 |
++ the priority of processes in the chroot, or alter the priority of |
18572 |
++ processes outside the chroot. This provides more security than simply |
18573 |
++ removing CAP_SYS_NICE from the process' capability set. If the |
18574 |
++ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice" |
18575 |
++ is created. |
18576 |
++ |
18577 |
++config GRKERNSEC_CHROOT_SYSCTL |
18578 |
++ bool "Deny sysctl writes" |
18579 |
++ depends on GRKERNSEC_CHROOT |
18580 |
++ help |
18581 |
++ If you say Y here, an attacker in a chroot will not be able to |
18582 |
++ write to sysctl entries, either by sysctl(2) or through a /proc |
18583 |
++ interface. It is strongly recommended that you say Y here. If the |
18584 |
++ sysctl option is enabled, a sysctl option with name |
18585 |
++ "chroot_deny_sysctl" is created. |
18586 |
++ |
18587 |
++config GRKERNSEC_CHROOT_CAPS |
18588 |
++ bool "Capability restrictions" |
18589 |
++ depends on GRKERNSEC_CHROOT |
18590 |
++ help |
18591 |
++ If you say Y here, the capabilities on all root processes within a |
18592 |
++ chroot jail will be lowered to stop module insertion, raw i/o, |
18593 |
++ system and net admin tasks, rebooting the system, modifying immutable |
18594 |
++ files, modifying IPC owned by another, and changing the system time. |
18595 |
++ This is left an option because it can break some apps. Disable this |
18596 |
++ if your chrooted apps are having problems performing those kinds of |
18597 |
++ tasks. If the sysctl option is enabled, a sysctl option with |
18598 |
++ name "chroot_caps" is created. |
18599 |
++ |
18600 |
++endmenu |
18601 |
++menu "Kernel Auditing" |
18602 |
++depends on GRKERNSEC |
18603 |
++ |
18604 |
++config GRKERNSEC_AUDIT_GROUP |
18605 |
++ bool "Single group for auditing" |
18606 |
++ help |
18607 |
++ If you say Y here, the exec, chdir, (un)mount, and ipc logging features |
18608 |
++ will only operate on a group you specify. This option is recommended |
18609 |
++ if you only want to watch certain users instead of having a large |
18610 |
++ amount of logs from the entire system. If the sysctl option is enabled, |
18611 |
++ a sysctl option with name "audit_group" is created. |
18612 |
++ |
18613 |
++config GRKERNSEC_AUDIT_GID |
18614 |
++ int "GID for auditing" |
18615 |
++ depends on GRKERNSEC_AUDIT_GROUP |
18616 |
++ default 1007 |
18617 |
++ |
18618 |
++config GRKERNSEC_EXECLOG |
18619 |
++ bool "Exec logging" |
18620 |
++ help |
18621 |
++ If you say Y here, all execve() calls will be logged (since the |
18622 |
++ other exec*() calls are frontends to execve(), all execution |
18623 |
++ will be logged). Useful for shell-servers that like to keep track |
18624 |
++ of their users. If the sysctl option is enabled, a sysctl option with |
18625 |
++ name "exec_logging" is created. |
18626 |
++ WARNING: This option when enabled will produce a LOT of logs, especially |
18627 |
++ on an active system. |
18628 |
++ |
18629 |
++config GRKERNSEC_RESLOG |
18630 |
++ bool "Resource logging" |
18631 |
++ help |
18632 |
++ If you say Y here, all attempts to overstep resource limits will |
18633 |
++ be logged with the resource name, the requested size, and the current |
18634 |
++ limit. It is highly recommended that you say Y here. If the sysctl |
18635 |
++ option is enabled, a sysctl option with name "resource_logging" is |
18636 |
++ created. If the RBAC system is enabled, the sysctl value is ignored. |
18637 |
++ |
18638 |
++config GRKERNSEC_CHROOT_EXECLOG |
18639 |
++ bool "Log execs within chroot" |
18640 |
++ help |
18641 |
++ If you say Y here, all executions inside a chroot jail will be logged |
18642 |
++ to syslog. This can cause a large amount of logs if certain |
18643 |
++ applications (eg. djb's daemontools) are installed on the system, and |
18644 |
++ is therefore left as an option. If the sysctl option is enabled, a |
18645 |
++ sysctl option with name "chroot_execlog" is created. |
18646 |
++ |
18647 |
++config GRKERNSEC_AUDIT_CHDIR |
18648 |
++ bool "Chdir logging" |
18649 |
++ help |
18650 |
++ If you say Y here, all chdir() calls will be logged. If the sysctl |
18651 |
++ option is enabled, a sysctl option with name "audit_chdir" is created. |
18652 |
++ |
18653 |
++config GRKERNSEC_AUDIT_MOUNT |
18654 |
++ bool "(Un)Mount logging" |
18655 |
++ help |
18656 |
++ If you say Y here, all mounts and unmounts will be logged. If the |
18657 |
++ sysctl option is enabled, a sysctl option with name "audit_mount" is |
18658 |
++ created. |
18659 |
++ |
18660 |
++config GRKERNSEC_AUDIT_IPC |
18661 |
++ bool "IPC logging" |
18662 |
++ help |
18663 |
++ If you say Y here, creation and removal of message queues, semaphores, |
18664 |
++ and shared memory will be logged. If the sysctl option is enabled, a |
18665 |
++ sysctl option with name "audit_ipc" is created. |
18666 |
++ |
18667 |
++config GRKERNSEC_SIGNAL |
18668 |
++ bool "Signal logging" |
18669 |
++ help |
18670 |
++ If you say Y here, certain important signals will be logged, such as |
18671 |
++ SIGSEGV, which will as a result inform you of when a error in a program |
18672 |
++ occurred, which in some cases could mean a possible exploit attempt. |
18673 |
++ If the sysctl option is enabled, a sysctl option with name |
18674 |
++ "signal_logging" is created. |
18675 |
++ |
18676 |
++config GRKERNSEC_FORKFAIL |
18677 |
++ bool "Fork failure logging" |
18678 |
++ help |
18679 |
++ If you say Y here, all failed fork() attempts will be logged. |
18680 |
++ This could suggest a fork bomb, or someone attempting to overstep |
18681 |
++ their process limit. If the sysctl option is enabled, a sysctl option |
18682 |
++ with name "forkfail_logging" is created. |
18683 |
++ |
18684 |
++config GRKERNSEC_TIME |
18685 |
++ bool "Time change logging" |
18686 |
++ help |
18687 |
++ If you say Y here, any changes of the system clock will be logged. |
18688 |
++ If the sysctl option is enabled, a sysctl option with name |
18689 |
++ "timechange_logging" is created. |
18690 |
++ |
18691 |
++config GRKERNSEC_PROC_IPADDR |
18692 |
++ bool "/proc/<pid>/ipaddr support" |
18693 |
++ help |
18694 |
++ If you say Y here, a new entry will be added to each /proc/<pid> |
18695 |
++ directory that contains the IP address of the person using the task. |
18696 |
++ The IP is carried across local TCP and AF_UNIX stream sockets. |
18697 |
++ This information can be useful for IDS/IPSes to perform remote response |
18698 |
++ to a local attack. The entry is readable by only the owner of the |
18699 |
++ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via |
18700 |
++ the RBAC system), and thus does not create privacy concerns. |
18701 |
++ |
18702 |
++config GRKERNSEC_AUDIT_TEXTREL |
18703 |
++ bool 'ELF text relocations logging (READ HELP)' |
18704 |
++ depends on PAX_MPROTECT |
18705 |
++ help |
18706 |
++ If you say Y here, text relocations will be logged with the filename |
18707 |
++ of the offending library or binary. The purpose of the feature is |
18708 |
++ to help Linux distribution developers get rid of libraries and |
18709 |
++ binaries that need text relocations which hinder the future progress |
18710 |
++ of PaX. Only Linux distribution developers should say Y here, and |
18711 |
++ never on a production machine, as this option creates an information |
18712 |
++ leak that could aid an attacker in defeating the randomization of |
18713 |
++ a single memory region. If the sysctl option is enabled, a sysctl |
18714 |
++ option with name "audit_textrel" is created. |
18715 |
++ |
18716 |
++endmenu |
18717 |
++ |
18718 |
++menu "Executable Protections" |
18719 |
++depends on GRKERNSEC |
18720 |
++ |
18721 |
++config GRKERNSEC_EXECVE |
18722 |
++ bool "Enforce RLIMIT_NPROC on execs" |
18723 |
++ help |
18724 |
++ If you say Y here, users with a resource limit on processes will |
18725 |
++ have the value checked during execve() calls. The current system |
18726 |
++ only checks the system limit during fork() calls. If the sysctl option |
18727 |
++ is enabled, a sysctl option with name "execve_limiting" is created. |
18728 |
++ |
18729 |
++config GRKERNSEC_SHM |
18730 |
++ bool "Destroy unused shared memory" |
18731 |
++ depends on SYSVIPC |
18732 |
++ help |
18733 |
++ If you say Y here, shared memory will be destroyed when no one is |
18734 |
++ attached to it. Otherwise, resources involved with the shared |
18735 |
++ memory can be used up and not be associated with any process (as the |
18736 |
++ shared memory still exists, and the creating process has exited). If |
18737 |
++ the sysctl option is enabled, a sysctl option with name |
18738 |
++ "destroy_unused_shm" is created. |
18739 |
++ |
18740 |
++config GRKERNSEC_DMESG |
18741 |
++ bool "Dmesg(8) restriction" |
18742 |
++ help |
18743 |
++ If you say Y here, non-root users will not be able to use dmesg(8) |
18744 |
++ to view up to the last 4kb of messages in the kernel's log buffer. |
18745 |
++ If the sysctl option is enabled, a sysctl option with name "dmesg" is |
18746 |
++ created. |
18747 |
++ |
18748 |
++config GRKERNSEC_TPE |
18749 |
++ bool "Trusted Path Execution (TPE)" |
18750 |
++ help |
18751 |
++ If you say Y here, you will be able to choose a gid to add to the |
18752 |
++ supplementary groups of users you want to mark as "untrusted." |
18753 |
++ These users will not be able to execute any files that are not in |
18754 |
++ root-owned directories writable only by root. If the sysctl option |
18755 |
++ is enabled, a sysctl option with name "tpe" is created. |
18756 |
++ |
18757 |
++config GRKERNSEC_TPE_ALL |
18758 |
++ bool "Partially restrict non-root users" |
18759 |
++ depends on GRKERNSEC_TPE |
18760 |
++ help |
18761 |
++ If you say Y here, All non-root users other than the ones in the |
18762 |
++ group specified in the main TPE option will only be allowed to |
18763 |
++ execute files in directories they own that are not group or |
18764 |
++ world-writable, or in directories owned by root and writable only by |
18765 |
++ root. If the sysctl option is enabled, a sysctl option with name |
18766 |
++ "tpe_restrict_all" is created. |
18767 |
++ |
18768 |
++config GRKERNSEC_TPE_INVERT |
18769 |
++ bool "Invert GID option" |
18770 |
++ depends on GRKERNSEC_TPE |
18771 |
++ help |
18772 |
++ If you say Y here, the group you specify in the TPE configuration will |
18773 |
++ decide what group TPE restrictions will be *disabled* for. This |
18774 |
++ option is useful if you want TPE restrictions to be applied to most |
18775 |
++ users on the system. |
18776 |
++ |
18777 |
++config GRKERNSEC_TPE_GID |
18778 |
++ int "GID for untrusted users" |
18779 |
++ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT |
18780 |
++ default 1005 |
18781 |
++ help |
18782 |
++ If you have selected the "Invert GID option" above, setting this |
18783 |
++ GID determines what group TPE restrictions will be *disabled* for. |
18784 |
++ If you have not selected the "Invert GID option" above, setting this |
18785 |
++ GID determines what group TPE restrictions will be *enabled* for. |
18786 |
++ If the sysctl option is enabled, a sysctl option with name "tpe_gid" |
18787 |
++ is created. |
18788 |
++ |
18789 |
++config GRKERNSEC_TPE_GID |
18790 |
++ int "GID for trusted users" |
18791 |
++ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT |
18792 |
++ default 1005 |
18793 |
++ help |
18794 |
++ If you have selected the "Invert GID option" above, setting this |
18795 |
++ GID determines what group TPE restrictions will be *disabled* for. |
18796 |
++ If you have not selected the "Invert GID option" above, setting this |
18797 |
++ GID determines what group TPE restrictions will be *enabled* for. |
18798 |
++ If the sysctl option is enabled, a sysctl option with name "tpe_gid" |
18799 |
++ is created. |
18800 |
++ |
18801 |
++endmenu |
18802 |
++menu "Network Protections" |
18803 |
++depends on GRKERNSEC |
18804 |
++ |
18805 |
++config GRKERNSEC_RANDNET |
18806 |
++ bool "Larger entropy pools" |
18807 |
++ help |
18808 |
++ If you say Y here, the entropy pools used for many features of Linux |
18809 |
++ and grsecurity will be doubled in size. Since several grsecurity |
18810 |
++ features use additional randomness, it is recommended that you say Y |
18811 |
++ here. Saying Y here has a similar effect as modifying |
18812 |
++ /proc/sys/kernel/random/poolsize. |
18813 |
++ |
18814 |
++config GRKERNSEC_SOCKET |
18815 |
++ bool "Socket restrictions" |
18816 |
++ help |
18817 |
++ If you say Y here, you will be able to choose from several options. |
18818 |
++ If you assign a GID on your system and add it to the supplementary |
18819 |
++ groups of users you want to restrict socket access to, this patch |
18820 |
++ will perform up to three things, based on the option(s) you choose. |
18821 |
++ |
18822 |
++config GRKERNSEC_SOCKET_ALL |
18823 |
++ bool "Deny any sockets to group" |
18824 |
++ depends on GRKERNSEC_SOCKET |
18825 |
++ help |
18826 |
++ If you say Y here, you will be able to choose a GID of whose users will |
18827 |
++ be unable to connect to other hosts from your machine or run server |
18828 |
++ applications from your machine. If the sysctl option is enabled, a |
18829 |
++ sysctl option with name "socket_all" is created. |
18830 |
++ |
18831 |
++config GRKERNSEC_SOCKET_ALL_GID |
18832 |
++ int "GID to deny all sockets for" |
18833 |
++ depends on GRKERNSEC_SOCKET_ALL |
18834 |
++ default 1004 |
18835 |
++ help |
18836 |
++ Here you can choose the GID to disable socket access for. Remember to |
18837 |
++ add the users you want socket access disabled for to the GID |
18838 |
++ specified here. If the sysctl option is enabled, a sysctl option |
18839 |
++ with name "socket_all_gid" is created. |
18840 |
++ |
18841 |
++config GRKERNSEC_SOCKET_CLIENT |
18842 |
++ bool "Deny client sockets to group" |
18843 |
++ depends on GRKERNSEC_SOCKET |
18844 |
++ help |
18845 |
++ If you say Y here, you will be able to choose a GID of whose users will |
18846 |
++ be unable to connect to other hosts from your machine, but will be |
18847 |
++ able to run servers. If this option is enabled, all users in the group |
18848 |
++ you specify will have to use passive mode when initiating ftp transfers |
18849 |
++ from the shell on your machine. If the sysctl option is enabled, a |
18850 |
++ sysctl option with name "socket_client" is created. |
18851 |
++ |
18852 |
++config GRKERNSEC_SOCKET_CLIENT_GID |
18853 |
++ int "GID to deny client sockets for" |
18854 |
++ depends on GRKERNSEC_SOCKET_CLIENT |
18855 |
++ default 1003 |
18856 |
++ help |
18857 |
++ Here you can choose the GID to disable client socket access for. |
18858 |
++ Remember to add the users you want client socket access disabled for to |
18859 |
++ the GID specified here. If the sysctl option is enabled, a sysctl |
18860 |
++ option with name "socket_client_gid" is created. |
18861 |
++ |
18862 |
++config GRKERNSEC_SOCKET_SERVER |
18863 |
++ bool "Deny server sockets to group" |
18864 |
++ depends on GRKERNSEC_SOCKET |
18865 |
++ help |
18866 |
++ If you say Y here, you will be able to choose a GID of whose users will |
18867 |
++ be unable to run server applications from your machine. If the sysctl |
18868 |
++ option is enabled, a sysctl option with name "socket_server" is created. |
18869 |
++ |
18870 |
++config GRKERNSEC_SOCKET_SERVER_GID |
18871 |
++ int "GID to deny server sockets for" |
18872 |
++ depends on GRKERNSEC_SOCKET_SERVER |
18873 |
++ default 1002 |
18874 |
++ help |
18875 |
++ Here you can choose the GID to disable server socket access for. |
18876 |
++ Remember to add the users you want server socket access disabled for to |
18877 |
++ the GID specified here. If the sysctl option is enabled, a sysctl |
18878 |
++ option with name "socket_server_gid" is created. |
18879 |
++ |
18880 |
++endmenu |
18881 |
++menu "Sysctl support" |
18882 |
++depends on GRKERNSEC && SYSCTL |
18883 |
++ |
18884 |
++config GRKERNSEC_SYSCTL |
18885 |
++ bool "Sysctl support" |
18886 |
++ help |
18887 |
++ If you say Y here, you will be able to change the options that |
18888 |
++ grsecurity runs with at bootup, without having to recompile your |
18889 |
++ kernel. You can echo values to files in /proc/sys/kernel/grsecurity |
18890 |
++ to enable (1) or disable (0) various features. All the sysctl entries |
18891 |
++ are mutable until the "grsec_lock" entry is set to a non-zero value. |
18892 |
++ All features enabled in the kernel configuration are disabled at boot |
18893 |
++ if you do not say Y to the "Turn on features by default" option. |
18894 |
++ All options should be set at startup, and the grsec_lock entry should |
18895 |
++ be set to a non-zero value after all the options are set. |
18896 |
++ *THIS IS EXTREMELY IMPORTANT* |
18897 |
++ |
18898 |
++config GRKERNSEC_SYSCTL_ON |
18899 |
++ bool "Turn on features by default" |
18900 |
++ depends on GRKERNSEC_SYSCTL |
18901 |
++ help |
18902 |
++ If you say Y here, instead of having all features enabled in the |
18903 |
++ kernel configuration disabled at boot time, the features will be |
18904 |
++ enabled at boot time. It is recommended you say Y here unless |
18905 |
++ there is some reason you would want all sysctl-tunable features to |
18906 |
++ be disabled by default. As mentioned elsewhere, it is important |
18907 |
++ to enable the grsec_lock entry once you have finished modifying |
18908 |
++ the sysctl entries. |
18909 |
++ |
18910 |
++endmenu |
18911 |
++menu "Logging Options" |
18912 |
++depends on GRKERNSEC |
18913 |
++ |
18914 |
++config GRKERNSEC_FLOODTIME |
18915 |
++ int "Seconds in between log messages (minimum)" |
18916 |
++ default 10 |
18917 |
++ help |
18918 |
++ This option allows you to enforce the number of seconds between |
18919 |
++ grsecurity log messages. The default should be suitable for most |
18920 |
++ people, however, if you choose to change it, choose a value small enough |
18921 |
++ to allow informative logs to be produced, but large enough to |
18922 |
++ prevent flooding. |
18923 |
++ |
18924 |
++config GRKERNSEC_FLOODBURST |
18925 |
++ int "Number of messages in a burst (maximum)" |
18926 |
++ default 4 |
18927 |
++ help |
18928 |
++ This option allows you to choose the maximum number of messages allowed |
18929 |
++ within the flood time interval you chose in a separate option. The |
18930 |
++ default should be suitable for most people, however if you find that |
18931 |
++ many of your logs are being interpreted as flooding, you may want to |
18932 |
++ raise this value. |
18933 |
++ |
18934 |
++endmenu |
18935 |
++ |
18936 |
++endmenu |
18937 |
+diff -Nurp linux-2.6.23.15/grsecurity/Makefile linux-2.6.23.15-grsec/grsecurity/Makefile |
18938 |
+--- linux-2.6.23.15/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100 |
18939 |
++++ linux-2.6.23.15-grsec/grsecurity/Makefile 2008-02-11 10:37:44.000000000 +0000 |
18940 |
+@@ -0,0 +1,20 @@ |
18941 |
++# grsecurity's ACL system was originally written in 2001 by Michael Dalton |
18942 |
++# during 2001-2005 it has been completely redesigned by Brad Spengler |
18943 |
++# into an RBAC system |
18944 |
++# |
18945 |
++# All code in this directory and various hooks inserted throughout the kernel |
18946 |
++# are copyright Brad Spengler, and released under the GPL v2 or higher |
18947 |
++ |
18948 |
++obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \ |
18949 |
++ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \ |
18950 |
++ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o |
18951 |
++ |
18952 |
++obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \ |
18953 |
++ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \ |
18954 |
++ gracl_learn.o grsec_log.o |
18955 |
++obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o |
18956 |
++ |
18957 |
++ifndef CONFIG_GRKERNSEC |
18958 |
++obj-y += grsec_disabled.o |
18959 |
++endif |
18960 |
++ |
18961 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl.c linux-2.6.23.15-grsec/grsecurity/gracl.c |
18962 |
+--- linux-2.6.23.15/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100 |
18963 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl.c 2008-02-11 10:37:44.000000000 +0000 |
18964 |
+@@ -0,0 +1,3722 @@ |
18965 |
++#include <linux/kernel.h> |
18966 |
++#include <linux/module.h> |
18967 |
++#include <linux/sched.h> |
18968 |
++#include <linux/mm.h> |
18969 |
++#include <linux/file.h> |
18970 |
++#include <linux/fs.h> |
18971 |
++#include <linux/namei.h> |
18972 |
++#include <linux/mount.h> |
18973 |
++#include <linux/tty.h> |
18974 |
++#include <linux/proc_fs.h> |
18975 |
++#include <linux/smp_lock.h> |
18976 |
++#include <linux/slab.h> |
18977 |
++#include <linux/vmalloc.h> |
18978 |
++#include <linux/types.h> |
18979 |
++#include <linux/capability.h> |
18980 |
++#include <linux/sysctl.h> |
18981 |
++#include <linux/netdevice.h> |
18982 |
++#include <linux/ptrace.h> |
18983 |
++#include <linux/gracl.h> |
18984 |
++#include <linux/gralloc.h> |
18985 |
++#include <linux/grsecurity.h> |
18986 |
++#include <linux/grinternal.h> |
18987 |
++#include <linux/pid_namespace.h> |
18988 |
++#include <linux/percpu.h> |
18989 |
++ |
18990 |
++#include <asm/uaccess.h> |
18991 |
++#include <asm/errno.h> |
18992 |
++#include <asm/mman.h> |
18993 |
++ |
18994 |
++static struct acl_role_db acl_role_set; |
18995 |
++static struct name_db name_set; |
18996 |
++static struct inodev_db inodev_set; |
18997 |
++ |
18998 |
++/* for keeping track of userspace pointers used for subjects, so we |
18999 |
++ can share references in the kernel as well |
19000 |
++*/ |
19001 |
++ |
19002 |
++static struct dentry *real_root; |
19003 |
++static struct vfsmount *real_root_mnt; |
19004 |
++ |
19005 |
++static struct acl_subj_map_db subj_map_set; |
19006 |
++ |
19007 |
++static struct acl_role_label *default_role; |
19008 |
++ |
19009 |
++static u16 acl_sp_role_value; |
19010 |
++ |
19011 |
++extern char *gr_shared_page[4]; |
19012 |
++static DECLARE_MUTEX(gr_dev_sem); |
19013 |
++rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED; |
19014 |
++ |
19015 |
++struct gr_arg *gr_usermode; |
19016 |
++ |
19017 |
++static unsigned int gr_status = GR_STATUS_INIT; |
19018 |
++ |
19019 |
++extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum); |
19020 |
++extern void gr_clear_learn_entries(void); |
19021 |
++ |
19022 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
19023 |
++extern void gr_log_resource(const struct task_struct *task, |
19024 |
++ const int res, const unsigned long wanted, const int gt); |
19025 |
++#endif |
19026 |
++ |
19027 |
++unsigned char *gr_system_salt; |
19028 |
++unsigned char *gr_system_sum; |
19029 |
++ |
19030 |
++static struct sprole_pw **acl_special_roles = NULL; |
19031 |
++static __u16 num_sprole_pws = 0; |
19032 |
++ |
19033 |
++static struct acl_role_label *kernel_role = NULL; |
19034 |
++ |
19035 |
++static unsigned int gr_auth_attempts = 0; |
19036 |
++static unsigned long gr_auth_expires = 0UL; |
19037 |
++ |
19038 |
++extern struct vfsmount *sock_mnt; |
19039 |
++extern struct vfsmount *pipe_mnt; |
19040 |
++extern struct vfsmount *shm_mnt; |
19041 |
++static struct acl_object_label *fakefs_obj; |
19042 |
++ |
19043 |
++extern int gr_init_uidset(void); |
19044 |
++extern void gr_free_uidset(void); |
19045 |
++extern void gr_remove_uid(uid_t uid); |
19046 |
++extern int gr_find_uid(uid_t uid); |
19047 |
++ |
19048 |
++__inline__ int |
19049 |
++gr_acl_is_enabled(void) |
19050 |
++{ |
19051 |
++ return (gr_status & GR_READY); |
19052 |
++} |
19053 |
++ |
19054 |
++char gr_roletype_to_char(void) |
19055 |
++{ |
19056 |
++ switch (current->role->roletype & |
19057 |
++ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP | |
19058 |
++ GR_ROLE_SPECIAL)) { |
19059 |
++ case GR_ROLE_DEFAULT: |
19060 |
++ return 'D'; |
19061 |
++ case GR_ROLE_USER: |
19062 |
++ return 'U'; |
19063 |
++ case GR_ROLE_GROUP: |
19064 |
++ return 'G'; |
19065 |
++ case GR_ROLE_SPECIAL: |
19066 |
++ return 'S'; |
19067 |
++ } |
19068 |
++ |
19069 |
++ return 'X'; |
19070 |
++} |
19071 |
++ |
19072 |
++__inline__ int |
19073 |
++gr_acl_tpe_check(void) |
19074 |
++{ |
19075 |
++ if (unlikely(!(gr_status & GR_READY))) |
19076 |
++ return 0; |
19077 |
++ if (current->role->roletype & GR_ROLE_TPE) |
19078 |
++ return 1; |
19079 |
++ else |
19080 |
++ return 0; |
19081 |
++} |
19082 |
++ |
19083 |
++int |
19084 |
++gr_handle_rawio(const struct inode *inode) |
19085 |
++{ |
19086 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
19087 |
++ if (inode && S_ISBLK(inode->i_mode) && |
19088 |
++ grsec_enable_chroot_caps && proc_is_chrooted(current) && |
19089 |
++ !capable(CAP_SYS_RAWIO)) |
19090 |
++ return 1; |
19091 |
++#endif |
19092 |
++ return 0; |
19093 |
++} |
19094 |
++ |
19095 |
++static int |
19096 |
++gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb) |
19097 |
++{ |
19098 |
++ int i; |
19099 |
++ unsigned long *l1; |
19100 |
++ unsigned long *l2; |
19101 |
++ unsigned char *c1; |
19102 |
++ unsigned char *c2; |
19103 |
++ int num_longs; |
19104 |
++ |
19105 |
++ if (likely(lena != lenb)) |
19106 |
++ return 0; |
19107 |
++ |
19108 |
++ l1 = (unsigned long *)a; |
19109 |
++ l2 = (unsigned long *)b; |
19110 |
++ |
19111 |
++ num_longs = lena / sizeof(unsigned long); |
19112 |
++ |
19113 |
++ for (i = num_longs; i--; l1++, l2++) { |
19114 |
++ if (unlikely(*l1 != *l2)) |
19115 |
++ return 0; |
19116 |
++ } |
19117 |
++ |
19118 |
++ c1 = (unsigned char *) l1; |
19119 |
++ c2 = (unsigned char *) l2; |
19120 |
++ |
19121 |
++ i = lena - (num_longs * sizeof(unsigned long)); |
19122 |
++ |
19123 |
++ for (; i--; c1++, c2++) { |
19124 |
++ if (unlikely(*c1 != *c2)) |
19125 |
++ return 0; |
19126 |
++ } |
19127 |
++ |
19128 |
++ return 1; |
19129 |
++} |
19130 |
++ |
19131 |
++static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt, |
19132 |
++ struct dentry *root, struct vfsmount *rootmnt, |
19133 |
++ char *buffer, int buflen) |
19134 |
++{ |
19135 |
++ char * end = buffer+buflen; |
19136 |
++ char * retval; |
19137 |
++ int namelen; |
19138 |
++ |
19139 |
++ *--end = '\0'; |
19140 |
++ buflen--; |
19141 |
++ |
19142 |
++ if (buflen < 1) |
19143 |
++ goto Elong; |
19144 |
++ /* Get '/' right */ |
19145 |
++ retval = end-1; |
19146 |
++ *retval = '/'; |
19147 |
++ |
19148 |
++ for (;;) { |
19149 |
++ struct dentry * parent; |
19150 |
++ |
19151 |
++ if (dentry == root && vfsmnt == rootmnt) |
19152 |
++ break; |
19153 |
++ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { |
19154 |
++ /* Global root? */ |
19155 |
++ spin_lock(&vfsmount_lock); |
19156 |
++ if (vfsmnt->mnt_parent == vfsmnt) { |
19157 |
++ spin_unlock(&vfsmount_lock); |
19158 |
++ goto global_root; |
19159 |
++ } |
19160 |
++ dentry = vfsmnt->mnt_mountpoint; |
19161 |
++ vfsmnt = vfsmnt->mnt_parent; |
19162 |
++ spin_unlock(&vfsmount_lock); |
19163 |
++ continue; |
19164 |
++ } |
19165 |
++ parent = dentry->d_parent; |
19166 |
++ prefetch(parent); |
19167 |
++ namelen = dentry->d_name.len; |
19168 |
++ buflen -= namelen + 1; |
19169 |
++ if (buflen < 0) |
19170 |
++ goto Elong; |
19171 |
++ end -= namelen; |
19172 |
++ memcpy(end, dentry->d_name.name, namelen); |
19173 |
++ *--end = '/'; |
19174 |
++ retval = end; |
19175 |
++ dentry = parent; |
19176 |
++ } |
19177 |
++ |
19178 |
++ return retval; |
19179 |
++ |
19180 |
++global_root: |
19181 |
++ namelen = dentry->d_name.len; |
19182 |
++ buflen -= namelen; |
19183 |
++ if (buflen < 0) |
19184 |
++ goto Elong; |
19185 |
++ retval -= namelen-1; /* hit the slash */ |
19186 |
++ memcpy(retval, dentry->d_name.name, namelen); |
19187 |
++ return retval; |
19188 |
++Elong: |
19189 |
++ return ERR_PTR(-ENAMETOOLONG); |
19190 |
++} |
19191 |
++ |
19192 |
++static char * |
19193 |
++gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt, |
19194 |
++ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen) |
19195 |
++{ |
19196 |
++ char *retval; |
19197 |
++ |
19198 |
++ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); |
19199 |
++ if (unlikely(IS_ERR(retval))) |
19200 |
++ retval = strcpy(buf, "<path too long>"); |
19201 |
++ else if (unlikely(retval[1] == '/' && retval[2] == '\0')) |
19202 |
++ retval[1] = '\0'; |
19203 |
++ |
19204 |
++ return retval; |
19205 |
++} |
19206 |
++ |
19207 |
++static char * |
19208 |
++__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, |
19209 |
++ char *buf, int buflen) |
19210 |
++{ |
19211 |
++ char *res; |
19212 |
++ |
19213 |
++ /* we can use real_root, real_root_mnt, because this is only called |
19214 |
++ by the RBAC system */ |
19215 |
++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen); |
19216 |
++ |
19217 |
++ return res; |
19218 |
++} |
19219 |
++ |
19220 |
++static char * |
19221 |
++d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, |
19222 |
++ char *buf, int buflen) |
19223 |
++{ |
19224 |
++ char *res; |
19225 |
++ struct dentry *root; |
19226 |
++ struct vfsmount *rootmnt; |
19227 |
++ struct task_struct *reaper = child_reaper(current); |
19228 |
++ |
19229 |
++ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */ |
19230 |
++ read_lock(&reaper->fs->lock); |
19231 |
++ root = dget(reaper->fs->root); |
19232 |
++ rootmnt = mntget(reaper->fs->rootmnt); |
19233 |
++ read_unlock(&reaper->fs->lock); |
19234 |
++ |
19235 |
++ spin_lock(&dcache_lock); |
19236 |
++ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen); |
19237 |
++ spin_unlock(&dcache_lock); |
19238 |
++ |
19239 |
++ dput(root); |
19240 |
++ mntput(rootmnt); |
19241 |
++ return res; |
19242 |
++} |
19243 |
++ |
19244 |
++static char * |
19245 |
++gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt) |
19246 |
++{ |
19247 |
++ char *ret; |
19248 |
++ spin_lock(&dcache_lock); |
19249 |
++ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()), |
19250 |
++ PAGE_SIZE); |
19251 |
++ spin_unlock(&dcache_lock); |
19252 |
++ return ret; |
19253 |
++} |
19254 |
++ |
19255 |
++char * |
19256 |
++gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt) |
19257 |
++{ |
19258 |
++ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()), |
19259 |
++ PAGE_SIZE); |
19260 |
++} |
19261 |
++ |
19262 |
++char * |
19263 |
++gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt) |
19264 |
++{ |
19265 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()), |
19266 |
++ PAGE_SIZE); |
19267 |
++} |
19268 |
++ |
19269 |
++char * |
19270 |
++gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt) |
19271 |
++{ |
19272 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()), |
19273 |
++ PAGE_SIZE); |
19274 |
++} |
19275 |
++ |
19276 |
++char * |
19277 |
++gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt) |
19278 |
++{ |
19279 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()), |
19280 |
++ PAGE_SIZE); |
19281 |
++} |
19282 |
++ |
19283 |
++char * |
19284 |
++gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt) |
19285 |
++{ |
19286 |
++ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()), |
19287 |
++ PAGE_SIZE); |
19288 |
++} |
19289 |
++ |
19290 |
++__inline__ __u32 |
19291 |
++to_gr_audit(const __u32 reqmode) |
19292 |
++{ |
19293 |
++ /* masks off auditable permission flags, then shifts them to create |
19294 |
++ auditing flags, and adds the special case of append auditing if |
19295 |
++ we're requesting write */ |
19296 |
++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0)); |
19297 |
++} |
19298 |
++ |
19299 |
++struct acl_subject_label * |
19300 |
++lookup_subject_map(const struct acl_subject_label *userp) |
19301 |
++{ |
19302 |
++ unsigned int index = shash(userp, subj_map_set.s_size); |
19303 |
++ struct subject_map *match; |
19304 |
++ |
19305 |
++ match = subj_map_set.s_hash[index]; |
19306 |
++ |
19307 |
++ while (match && match->user != userp) |
19308 |
++ match = match->next; |
19309 |
++ |
19310 |
++ if (match != NULL) |
19311 |
++ return match->kernel; |
19312 |
++ else |
19313 |
++ return NULL; |
19314 |
++} |
19315 |
++ |
19316 |
++static void |
19317 |
++insert_subj_map_entry(struct subject_map *subjmap) |
19318 |
++{ |
19319 |
++ unsigned int index = shash(subjmap->user, subj_map_set.s_size); |
19320 |
++ struct subject_map **curr; |
19321 |
++ |
19322 |
++ subjmap->prev = NULL; |
19323 |
++ |
19324 |
++ curr = &subj_map_set.s_hash[index]; |
19325 |
++ if (*curr != NULL) |
19326 |
++ (*curr)->prev = subjmap; |
19327 |
++ |
19328 |
++ subjmap->next = *curr; |
19329 |
++ *curr = subjmap; |
19330 |
++ |
19331 |
++ return; |
19332 |
++} |
19333 |
++ |
19334 |
++static struct acl_role_label * |
19335 |
++lookup_acl_role_label(const struct task_struct *task, const uid_t uid, |
19336 |
++ const gid_t gid) |
19337 |
++{ |
19338 |
++ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size); |
19339 |
++ struct acl_role_label *match; |
19340 |
++ struct role_allowed_ip *ipp; |
19341 |
++ unsigned int x; |
19342 |
++ |
19343 |
++ match = acl_role_set.r_hash[index]; |
19344 |
++ |
19345 |
++ while (match) { |
19346 |
++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) { |
19347 |
++ for (x = 0; x < match->domain_child_num; x++) { |
19348 |
++ if (match->domain_children[x] == uid) |
19349 |
++ goto found; |
19350 |
++ } |
19351 |
++ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER) |
19352 |
++ break; |
19353 |
++ match = match->next; |
19354 |
++ } |
19355 |
++found: |
19356 |
++ if (match == NULL) { |
19357 |
++ try_group: |
19358 |
++ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size); |
19359 |
++ match = acl_role_set.r_hash[index]; |
19360 |
++ |
19361 |
++ while (match) { |
19362 |
++ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) { |
19363 |
++ for (x = 0; x < match->domain_child_num; x++) { |
19364 |
++ if (match->domain_children[x] == gid) |
19365 |
++ goto found2; |
19366 |
++ } |
19367 |
++ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP) |
19368 |
++ break; |
19369 |
++ match = match->next; |
19370 |
++ } |
19371 |
++found2: |
19372 |
++ if (match == NULL) |
19373 |
++ match = default_role; |
19374 |
++ if (match->allowed_ips == NULL) |
19375 |
++ return match; |
19376 |
++ else { |
19377 |
++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { |
19378 |
++ if (likely |
19379 |
++ ((ntohl(task->signal->curr_ip) & ipp->netmask) == |
19380 |
++ (ntohl(ipp->addr) & ipp->netmask))) |
19381 |
++ return match; |
19382 |
++ } |
19383 |
++ match = default_role; |
19384 |
++ } |
19385 |
++ } else if (match->allowed_ips == NULL) { |
19386 |
++ return match; |
19387 |
++ } else { |
19388 |
++ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { |
19389 |
++ if (likely |
19390 |
++ ((ntohl(task->signal->curr_ip) & ipp->netmask) == |
19391 |
++ (ntohl(ipp->addr) & ipp->netmask))) |
19392 |
++ return match; |
19393 |
++ } |
19394 |
++ goto try_group; |
19395 |
++ } |
19396 |
++ |
19397 |
++ return match; |
19398 |
++} |
19399 |
++ |
19400 |
++struct acl_subject_label * |
19401 |
++lookup_acl_subj_label(const ino_t ino, const dev_t dev, |
19402 |
++ const struct acl_role_label *role) |
19403 |
++{ |
19404 |
++ unsigned int index = fhash(ino, dev, role->subj_hash_size); |
19405 |
++ struct acl_subject_label *match; |
19406 |
++ |
19407 |
++ match = role->subj_hash[index]; |
19408 |
++ |
19409 |
++ while (match && (match->inode != ino || match->device != dev || |
19410 |
++ (match->mode & GR_DELETED))) { |
19411 |
++ match = match->next; |
19412 |
++ } |
19413 |
++ |
19414 |
++ if (match && !(match->mode & GR_DELETED)) |
19415 |
++ return match; |
19416 |
++ else |
19417 |
++ return NULL; |
19418 |
++} |
19419 |
++ |
19420 |
++static struct acl_object_label * |
19421 |
++lookup_acl_obj_label(const ino_t ino, const dev_t dev, |
19422 |
++ const struct acl_subject_label *subj) |
19423 |
++{ |
19424 |
++ unsigned int index = fhash(ino, dev, subj->obj_hash_size); |
19425 |
++ struct acl_object_label *match; |
19426 |
++ |
19427 |
++ match = subj->obj_hash[index]; |
19428 |
++ |
19429 |
++ while (match && (match->inode != ino || match->device != dev || |
19430 |
++ (match->mode & GR_DELETED))) { |
19431 |
++ match = match->next; |
19432 |
++ } |
19433 |
++ |
19434 |
++ if (match && !(match->mode & GR_DELETED)) |
19435 |
++ return match; |
19436 |
++ else |
19437 |
++ return NULL; |
19438 |
++} |
19439 |
++ |
19440 |
++static struct acl_object_label * |
19441 |
++lookup_acl_obj_label_create(const ino_t ino, const dev_t dev, |
19442 |
++ const struct acl_subject_label *subj) |
19443 |
++{ |
19444 |
++ unsigned int index = fhash(ino, dev, subj->obj_hash_size); |
19445 |
++ struct acl_object_label *match; |
19446 |
++ |
19447 |
++ match = subj->obj_hash[index]; |
19448 |
++ |
19449 |
++ while (match && (match->inode != ino || match->device != dev || |
19450 |
++ !(match->mode & GR_DELETED))) { |
19451 |
++ match = match->next; |
19452 |
++ } |
19453 |
++ |
19454 |
++ if (match && (match->mode & GR_DELETED)) |
19455 |
++ return match; |
19456 |
++ |
19457 |
++ match = subj->obj_hash[index]; |
19458 |
++ |
19459 |
++ while (match && (match->inode != ino || match->device != dev || |
19460 |
++ (match->mode & GR_DELETED))) { |
19461 |
++ match = match->next; |
19462 |
++ } |
19463 |
++ |
19464 |
++ if (match && !(match->mode & GR_DELETED)) |
19465 |
++ return match; |
19466 |
++ else |
19467 |
++ return NULL; |
19468 |
++} |
19469 |
++ |
19470 |
++static struct name_entry * |
19471 |
++lookup_name_entry(const char *name) |
19472 |
++{ |
19473 |
++ unsigned int len = strlen(name); |
19474 |
++ unsigned int key = full_name_hash(name, len); |
19475 |
++ unsigned int index = key % name_set.n_size; |
19476 |
++ struct name_entry *match; |
19477 |
++ |
19478 |
++ match = name_set.n_hash[index]; |
19479 |
++ |
19480 |
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len))) |
19481 |
++ match = match->next; |
19482 |
++ |
19483 |
++ return match; |
19484 |
++} |
19485 |
++ |
19486 |
++static struct name_entry * |
19487 |
++lookup_name_entry_create(const char *name) |
19488 |
++{ |
19489 |
++ unsigned int len = strlen(name); |
19490 |
++ unsigned int key = full_name_hash(name, len); |
19491 |
++ unsigned int index = key % name_set.n_size; |
19492 |
++ struct name_entry *match; |
19493 |
++ |
19494 |
++ match = name_set.n_hash[index]; |
19495 |
++ |
19496 |
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || |
19497 |
++ !match->deleted)) |
19498 |
++ match = match->next; |
19499 |
++ |
19500 |
++ if (match && match->deleted) |
19501 |
++ return match; |
19502 |
++ |
19503 |
++ match = name_set.n_hash[index]; |
19504 |
++ |
19505 |
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || |
19506 |
++ match->deleted)) |
19507 |
++ match = match->next; |
19508 |
++ |
19509 |
++ if (match && !match->deleted) |
19510 |
++ return match; |
19511 |
++ else |
19512 |
++ return NULL; |
19513 |
++} |
19514 |
++ |
19515 |
++static struct inodev_entry * |
19516 |
++lookup_inodev_entry(const ino_t ino, const dev_t dev) |
19517 |
++{ |
19518 |
++ unsigned int index = fhash(ino, dev, inodev_set.i_size); |
19519 |
++ struct inodev_entry *match; |
19520 |
++ |
19521 |
++ match = inodev_set.i_hash[index]; |
19522 |
++ |
19523 |
++ while (match && (match->nentry->inode != ino || match->nentry->device != dev)) |
19524 |
++ match = match->next; |
19525 |
++ |
19526 |
++ return match; |
19527 |
++} |
19528 |
++ |
19529 |
++static void |
19530 |
++insert_inodev_entry(struct inodev_entry *entry) |
19531 |
++{ |
19532 |
++ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device, |
19533 |
++ inodev_set.i_size); |
19534 |
++ struct inodev_entry **curr; |
19535 |
++ |
19536 |
++ entry->prev = NULL; |
19537 |
++ |
19538 |
++ curr = &inodev_set.i_hash[index]; |
19539 |
++ if (*curr != NULL) |
19540 |
++ (*curr)->prev = entry; |
19541 |
++ |
19542 |
++ entry->next = *curr; |
19543 |
++ *curr = entry; |
19544 |
++ |
19545 |
++ return; |
19546 |
++} |
19547 |
++ |
19548 |
++static void |
19549 |
++__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid) |
19550 |
++{ |
19551 |
++ unsigned int index = |
19552 |
++ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size); |
19553 |
++ struct acl_role_label **curr; |
19554 |
++ |
19555 |
++ role->prev = NULL; |
19556 |
++ |
19557 |
++ curr = &acl_role_set.r_hash[index]; |
19558 |
++ if (*curr != NULL) |
19559 |
++ (*curr)->prev = role; |
19560 |
++ |
19561 |
++ role->next = *curr; |
19562 |
++ *curr = role; |
19563 |
++ |
19564 |
++ return; |
19565 |
++} |
19566 |
++ |
19567 |
++static void |
19568 |
++insert_acl_role_label(struct acl_role_label *role) |
19569 |
++{ |
19570 |
++ int i; |
19571 |
++ |
19572 |
++ if (role->roletype & GR_ROLE_DOMAIN) { |
19573 |
++ for (i = 0; i < role->domain_child_num; i++) |
19574 |
++ __insert_acl_role_label(role, role->domain_children[i]); |
19575 |
++ } else |
19576 |
++ __insert_acl_role_label(role, role->uidgid); |
19577 |
++} |
19578 |
++ |
19579 |
++static int |
19580 |
++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted) |
19581 |
++{ |
19582 |
++ struct name_entry **curr, *nentry; |
19583 |
++ struct inodev_entry *ientry; |
19584 |
++ unsigned int len = strlen(name); |
19585 |
++ unsigned int key = full_name_hash(name, len); |
19586 |
++ unsigned int index = key % name_set.n_size; |
19587 |
++ |
19588 |
++ curr = &name_set.n_hash[index]; |
19589 |
++ |
19590 |
++ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len))) |
19591 |
++ curr = &((*curr)->next); |
19592 |
++ |
19593 |
++ if (*curr != NULL) |
19594 |
++ return 1; |
19595 |
++ |
19596 |
++ nentry = acl_alloc(sizeof (struct name_entry)); |
19597 |
++ if (nentry == NULL) |
19598 |
++ return 0; |
19599 |
++ ientry = acl_alloc(sizeof (struct inodev_entry)); |
19600 |
++ if (ientry == NULL) |
19601 |
++ return 0; |
19602 |
++ ientry->nentry = nentry; |
19603 |
++ |
19604 |
++ nentry->key = key; |
19605 |
++ nentry->name = name; |
19606 |
++ nentry->inode = inode; |
19607 |
++ nentry->device = device; |
19608 |
++ nentry->len = len; |
19609 |
++ nentry->deleted = deleted; |
19610 |
++ |
19611 |
++ nentry->prev = NULL; |
19612 |
++ curr = &name_set.n_hash[index]; |
19613 |
++ if (*curr != NULL) |
19614 |
++ (*curr)->prev = nentry; |
19615 |
++ nentry->next = *curr; |
19616 |
++ *curr = nentry; |
19617 |
++ |
19618 |
++ /* insert us into the table searchable by inode/dev */ |
19619 |
++ insert_inodev_entry(ientry); |
19620 |
++ |
19621 |
++ return 1; |
19622 |
++} |
19623 |
++ |
19624 |
++static void |
19625 |
++insert_acl_obj_label(struct acl_object_label *obj, |
19626 |
++ struct acl_subject_label *subj) |
19627 |
++{ |
19628 |
++ unsigned int index = |
19629 |
++ fhash(obj->inode, obj->device, subj->obj_hash_size); |
19630 |
++ struct acl_object_label **curr; |
19631 |
++ |
19632 |
++ |
19633 |
++ obj->prev = NULL; |
19634 |
++ |
19635 |
++ curr = &subj->obj_hash[index]; |
19636 |
++ if (*curr != NULL) |
19637 |
++ (*curr)->prev = obj; |
19638 |
++ |
19639 |
++ obj->next = *curr; |
19640 |
++ *curr = obj; |
19641 |
++ |
19642 |
++ return; |
19643 |
++} |
19644 |
++ |
19645 |
++static void |
19646 |
++insert_acl_subj_label(struct acl_subject_label *obj, |
19647 |
++ struct acl_role_label *role) |
19648 |
++{ |
19649 |
++ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size); |
19650 |
++ struct acl_subject_label **curr; |
19651 |
++ |
19652 |
++ obj->prev = NULL; |
19653 |
++ |
19654 |
++ curr = &role->subj_hash[index]; |
19655 |
++ if (*curr != NULL) |
19656 |
++ (*curr)->prev = obj; |
19657 |
++ |
19658 |
++ obj->next = *curr; |
19659 |
++ *curr = obj; |
19660 |
++ |
19661 |
++ return; |
19662 |
++} |
19663 |
++ |
19664 |
++/* allocating chained hash tables, so optimal size is where lambda ~ 1 */ |
19665 |
++ |
19666 |
++static void * |
19667 |
++create_table(__u32 * len, int elementsize) |
19668 |
++{ |
19669 |
++ unsigned int table_sizes[] = { |
19670 |
++ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, |
19671 |
++ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, |
19672 |
++ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, |
19673 |
++ 268435399, 536870909, 1073741789, 2147483647 |
19674 |
++ }; |
19675 |
++ void *newtable = NULL; |
19676 |
++ unsigned int pwr = 0; |
19677 |
++ |
19678 |
++ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) && |
19679 |
++ table_sizes[pwr] <= *len) |
19680 |
++ pwr++; |
19681 |
++ |
19682 |
++ if (table_sizes[pwr] <= *len) |
19683 |
++ return newtable; |
19684 |
++ |
19685 |
++ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE) |
19686 |
++ newtable = |
19687 |
++ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL); |
19688 |
++ else |
19689 |
++ newtable = vmalloc(table_sizes[pwr] * elementsize); |
19690 |
++ |
19691 |
++ *len = table_sizes[pwr]; |
19692 |
++ |
19693 |
++ return newtable; |
19694 |
++} |
19695 |
++ |
19696 |
++static int |
19697 |
++init_variables(const struct gr_arg *arg) |
19698 |
++{ |
19699 |
++ struct task_struct *reaper = child_reaper(current); |
19700 |
++ unsigned int stacksize; |
19701 |
++ |
19702 |
++ subj_map_set.s_size = arg->role_db.num_subjects; |
19703 |
++ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children; |
19704 |
++ name_set.n_size = arg->role_db.num_objects; |
19705 |
++ inodev_set.i_size = arg->role_db.num_objects; |
19706 |
++ |
19707 |
++ if (!subj_map_set.s_size || !acl_role_set.r_size || |
19708 |
++ !name_set.n_size || !inodev_set.i_size) |
19709 |
++ return 1; |
19710 |
++ |
19711 |
++ if (!gr_init_uidset()) |
19712 |
++ return 1; |
19713 |
++ |
19714 |
++ /* set up the stack that holds allocation info */ |
19715 |
++ |
19716 |
++ stacksize = arg->role_db.num_pointers + 5; |
19717 |
++ |
19718 |
++ if (!acl_alloc_stack_init(stacksize)) |
19719 |
++ return 1; |
19720 |
++ |
19721 |
++ /* grab reference for the real root dentry and vfsmount */ |
19722 |
++ read_lock(&reaper->fs->lock); |
19723 |
++ real_root_mnt = mntget(reaper->fs->rootmnt); |
19724 |
++ real_root = dget(reaper->fs->root); |
19725 |
++ read_unlock(&reaper->fs->lock); |
19726 |
++ |
19727 |
++ fakefs_obj = acl_alloc(sizeof(struct acl_object_label)); |
19728 |
++ if (fakefs_obj == NULL) |
19729 |
++ return 1; |
19730 |
++ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC; |
19731 |
++ |
19732 |
++ subj_map_set.s_hash = |
19733 |
++ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *)); |
19734 |
++ acl_role_set.r_hash = |
19735 |
++ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *)); |
19736 |
++ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *)); |
19737 |
++ inodev_set.i_hash = |
19738 |
++ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *)); |
19739 |
++ |
19740 |
++ if (!subj_map_set.s_hash || !acl_role_set.r_hash || |
19741 |
++ !name_set.n_hash || !inodev_set.i_hash) |
19742 |
++ return 1; |
19743 |
++ |
19744 |
++ memset(subj_map_set.s_hash, 0, |
19745 |
++ sizeof(struct subject_map *) * subj_map_set.s_size); |
19746 |
++ memset(acl_role_set.r_hash, 0, |
19747 |
++ sizeof (struct acl_role_label *) * acl_role_set.r_size); |
19748 |
++ memset(name_set.n_hash, 0, |
19749 |
++ sizeof (struct name_entry *) * name_set.n_size); |
19750 |
++ memset(inodev_set.i_hash, 0, |
19751 |
++ sizeof (struct inodev_entry *) * inodev_set.i_size); |
19752 |
++ |
19753 |
++ return 0; |
19754 |
++} |
19755 |
++ |
19756 |
++/* free information not needed after startup |
19757 |
++ currently contains user->kernel pointer mappings for subjects |
19758 |
++*/ |
19759 |
++ |
19760 |
++static void |
19761 |
++free_init_variables(void) |
19762 |
++{ |
19763 |
++ __u32 i; |
19764 |
++ |
19765 |
++ if (subj_map_set.s_hash) { |
19766 |
++ for (i = 0; i < subj_map_set.s_size; i++) { |
19767 |
++ if (subj_map_set.s_hash[i]) { |
19768 |
++ kfree(subj_map_set.s_hash[i]); |
19769 |
++ subj_map_set.s_hash[i] = NULL; |
19770 |
++ } |
19771 |
++ } |
19772 |
++ |
19773 |
++ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <= |
19774 |
++ PAGE_SIZE) |
19775 |
++ kfree(subj_map_set.s_hash); |
19776 |
++ else |
19777 |
++ vfree(subj_map_set.s_hash); |
19778 |
++ } |
19779 |
++ |
19780 |
++ return; |
19781 |
++} |
19782 |
++ |
19783 |
++static void |
19784 |
++free_variables(void) |
19785 |
++{ |
19786 |
++ struct acl_subject_label *s; |
19787 |
++ struct acl_role_label *r; |
19788 |
++ struct task_struct *task, *task2; |
19789 |
++ unsigned int i, x; |
19790 |
++ |
19791 |
++ gr_clear_learn_entries(); |
19792 |
++ |
19793 |
++ read_lock(&tasklist_lock); |
19794 |
++ do_each_thread(task2, task) { |
19795 |
++ task->acl_sp_role = 0; |
19796 |
++ task->acl_role_id = 0; |
19797 |
++ task->acl = NULL; |
19798 |
++ task->role = NULL; |
19799 |
++ } while_each_thread(task2, task); |
19800 |
++ read_unlock(&tasklist_lock); |
19801 |
++ |
19802 |
++ /* release the reference to the real root dentry and vfsmount */ |
19803 |
++ if (real_root) |
19804 |
++ dput(real_root); |
19805 |
++ real_root = NULL; |
19806 |
++ if (real_root_mnt) |
19807 |
++ mntput(real_root_mnt); |
19808 |
++ real_root_mnt = NULL; |
19809 |
++ |
19810 |
++ /* free all object hash tables */ |
19811 |
++ |
19812 |
++ FOR_EACH_ROLE_START(r, i) |
19813 |
++ if (r->subj_hash == NULL) |
19814 |
++ break; |
19815 |
++ FOR_EACH_SUBJECT_START(r, s, x) |
19816 |
++ if (s->obj_hash == NULL) |
19817 |
++ break; |
19818 |
++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE) |
19819 |
++ kfree(s->obj_hash); |
19820 |
++ else |
19821 |
++ vfree(s->obj_hash); |
19822 |
++ FOR_EACH_SUBJECT_END(s, x) |
19823 |
++ FOR_EACH_NESTED_SUBJECT_START(r, s) |
19824 |
++ if (s->obj_hash == NULL) |
19825 |
++ break; |
19826 |
++ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE) |
19827 |
++ kfree(s->obj_hash); |
19828 |
++ else |
19829 |
++ vfree(s->obj_hash); |
19830 |
++ FOR_EACH_NESTED_SUBJECT_END(s) |
19831 |
++ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE) |
19832 |
++ kfree(r->subj_hash); |
19833 |
++ else |
19834 |
++ vfree(r->subj_hash); |
19835 |
++ r->subj_hash = NULL; |
19836 |
++ FOR_EACH_ROLE_END(r,i) |
19837 |
++ |
19838 |
++ acl_free_all(); |
19839 |
++ |
19840 |
++ if (acl_role_set.r_hash) { |
19841 |
++ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <= |
19842 |
++ PAGE_SIZE) |
19843 |
++ kfree(acl_role_set.r_hash); |
19844 |
++ else |
19845 |
++ vfree(acl_role_set.r_hash); |
19846 |
++ } |
19847 |
++ if (name_set.n_hash) { |
19848 |
++ if ((name_set.n_size * sizeof (struct name_entry *)) <= |
19849 |
++ PAGE_SIZE) |
19850 |
++ kfree(name_set.n_hash); |
19851 |
++ else |
19852 |
++ vfree(name_set.n_hash); |
19853 |
++ } |
19854 |
++ |
19855 |
++ if (inodev_set.i_hash) { |
19856 |
++ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <= |
19857 |
++ PAGE_SIZE) |
19858 |
++ kfree(inodev_set.i_hash); |
19859 |
++ else |
19860 |
++ vfree(inodev_set.i_hash); |
19861 |
++ } |
19862 |
++ |
19863 |
++ gr_free_uidset(); |
19864 |
++ |
19865 |
++ memset(&name_set, 0, sizeof (struct name_db)); |
19866 |
++ memset(&inodev_set, 0, sizeof (struct inodev_db)); |
19867 |
++ memset(&acl_role_set, 0, sizeof (struct acl_role_db)); |
19868 |
++ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db)); |
19869 |
++ |
19870 |
++ default_role = NULL; |
19871 |
++ |
19872 |
++ return; |
19873 |
++} |
19874 |
++ |
19875 |
++static __u32 |
19876 |
++count_user_objs(struct acl_object_label *userp) |
19877 |
++{ |
19878 |
++ struct acl_object_label o_tmp; |
19879 |
++ __u32 num = 0; |
19880 |
++ |
19881 |
++ while (userp) { |
19882 |
++ if (copy_from_user(&o_tmp, userp, |
19883 |
++ sizeof (struct acl_object_label))) |
19884 |
++ break; |
19885 |
++ |
19886 |
++ userp = o_tmp.prev; |
19887 |
++ num++; |
19888 |
++ } |
19889 |
++ |
19890 |
++ return num; |
19891 |
++} |
19892 |
++ |
19893 |
++static struct acl_subject_label * |
19894 |
++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role); |
19895 |
++ |
19896 |
++static int |
19897 |
++copy_user_glob(struct acl_object_label *obj) |
19898 |
++{ |
19899 |
++ struct acl_object_label *g_tmp, **guser; |
19900 |
++ unsigned int len; |
19901 |
++ char *tmp; |
19902 |
++ |
19903 |
++ if (obj->globbed == NULL) |
19904 |
++ return 0; |
19905 |
++ |
19906 |
++ guser = &obj->globbed; |
19907 |
++ while (*guser) { |
19908 |
++ g_tmp = (struct acl_object_label *) |
19909 |
++ acl_alloc(sizeof (struct acl_object_label)); |
19910 |
++ if (g_tmp == NULL) |
19911 |
++ return -ENOMEM; |
19912 |
++ |
19913 |
++ if (copy_from_user(g_tmp, *guser, |
19914 |
++ sizeof (struct acl_object_label))) |
19915 |
++ return -EFAULT; |
19916 |
++ |
19917 |
++ len = strnlen_user(g_tmp->filename, PATH_MAX); |
19918 |
++ |
19919 |
++ if (!len || len >= PATH_MAX) |
19920 |
++ return -EINVAL; |
19921 |
++ |
19922 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
19923 |
++ return -ENOMEM; |
19924 |
++ |
19925 |
++ if (copy_from_user(tmp, g_tmp->filename, len)) |
19926 |
++ return -EFAULT; |
19927 |
++ |
19928 |
++ g_tmp->filename = tmp; |
19929 |
++ |
19930 |
++ *guser = g_tmp; |
19931 |
++ guser = &(g_tmp->next); |
19932 |
++ } |
19933 |
++ |
19934 |
++ return 0; |
19935 |
++} |
19936 |
++ |
19937 |
++static int |
19938 |
++copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj, |
19939 |
++ struct acl_role_label *role) |
19940 |
++{ |
19941 |
++ struct acl_object_label *o_tmp; |
19942 |
++ unsigned int len; |
19943 |
++ int ret; |
19944 |
++ char *tmp; |
19945 |
++ |
19946 |
++ while (userp) { |
19947 |
++ if ((o_tmp = (struct acl_object_label *) |
19948 |
++ acl_alloc(sizeof (struct acl_object_label))) == NULL) |
19949 |
++ return -ENOMEM; |
19950 |
++ |
19951 |
++ if (copy_from_user(o_tmp, userp, |
19952 |
++ sizeof (struct acl_object_label))) |
19953 |
++ return -EFAULT; |
19954 |
++ |
19955 |
++ userp = o_tmp->prev; |
19956 |
++ |
19957 |
++ len = strnlen_user(o_tmp->filename, PATH_MAX); |
19958 |
++ |
19959 |
++ if (!len || len >= PATH_MAX) |
19960 |
++ return -EINVAL; |
19961 |
++ |
19962 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
19963 |
++ return -ENOMEM; |
19964 |
++ |
19965 |
++ if (copy_from_user(tmp, o_tmp->filename, len)) |
19966 |
++ return -EFAULT; |
19967 |
++ |
19968 |
++ o_tmp->filename = tmp; |
19969 |
++ |
19970 |
++ insert_acl_obj_label(o_tmp, subj); |
19971 |
++ if (!insert_name_entry(o_tmp->filename, o_tmp->inode, |
19972 |
++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0)) |
19973 |
++ return -ENOMEM; |
19974 |
++ |
19975 |
++ ret = copy_user_glob(o_tmp); |
19976 |
++ if (ret) |
19977 |
++ return ret; |
19978 |
++ |
19979 |
++ if (o_tmp->nested) { |
19980 |
++ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role); |
19981 |
++ if (IS_ERR(o_tmp->nested)) |
19982 |
++ return PTR_ERR(o_tmp->nested); |
19983 |
++ |
19984 |
++ /* insert into nested subject list */ |
19985 |
++ o_tmp->nested->next = role->hash->first; |
19986 |
++ role->hash->first = o_tmp->nested; |
19987 |
++ } |
19988 |
++ } |
19989 |
++ |
19990 |
++ return 0; |
19991 |
++} |
19992 |
++ |
19993 |
++static __u32 |
19994 |
++count_user_subjs(struct acl_subject_label *userp) |
19995 |
++{ |
19996 |
++ struct acl_subject_label s_tmp; |
19997 |
++ __u32 num = 0; |
19998 |
++ |
19999 |
++ while (userp) { |
20000 |
++ if (copy_from_user(&s_tmp, userp, |
20001 |
++ sizeof (struct acl_subject_label))) |
20002 |
++ break; |
20003 |
++ |
20004 |
++ userp = s_tmp.prev; |
20005 |
++ /* do not count nested subjects against this count, since |
20006 |
++ they are not included in the hash table, but are |
20007 |
++ attached to objects. We have already counted |
20008 |
++ the subjects in userspace for the allocation |
20009 |
++ stack |
20010 |
++ */ |
20011 |
++ if (!(s_tmp.mode & GR_NESTED)) |
20012 |
++ num++; |
20013 |
++ } |
20014 |
++ |
20015 |
++ return num; |
20016 |
++} |
20017 |
++ |
20018 |
++static int |
20019 |
++copy_user_allowedips(struct acl_role_label *rolep) |
20020 |
++{ |
20021 |
++ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast; |
20022 |
++ |
20023 |
++ ruserip = rolep->allowed_ips; |
20024 |
++ |
20025 |
++ while (ruserip) { |
20026 |
++ rlast = rtmp; |
20027 |
++ |
20028 |
++ if ((rtmp = (struct role_allowed_ip *) |
20029 |
++ acl_alloc(sizeof (struct role_allowed_ip))) == NULL) |
20030 |
++ return -ENOMEM; |
20031 |
++ |
20032 |
++ if (copy_from_user(rtmp, ruserip, |
20033 |
++ sizeof (struct role_allowed_ip))) |
20034 |
++ return -EFAULT; |
20035 |
++ |
20036 |
++ ruserip = rtmp->prev; |
20037 |
++ |
20038 |
++ if (!rlast) { |
20039 |
++ rtmp->prev = NULL; |
20040 |
++ rolep->allowed_ips = rtmp; |
20041 |
++ } else { |
20042 |
++ rlast->next = rtmp; |
20043 |
++ rtmp->prev = rlast; |
20044 |
++ } |
20045 |
++ |
20046 |
++ if (!ruserip) |
20047 |
++ rtmp->next = NULL; |
20048 |
++ } |
20049 |
++ |
20050 |
++ return 0; |
20051 |
++} |
20052 |
++ |
20053 |
++static int |
20054 |
++copy_user_transitions(struct acl_role_label *rolep) |
20055 |
++{ |
20056 |
++ struct role_transition *rusertp, *rtmp = NULL, *rlast; |
20057 |
++ |
20058 |
++ unsigned int len; |
20059 |
++ char *tmp; |
20060 |
++ |
20061 |
++ rusertp = rolep->transitions; |
20062 |
++ |
20063 |
++ while (rusertp) { |
20064 |
++ rlast = rtmp; |
20065 |
++ |
20066 |
++ if ((rtmp = (struct role_transition *) |
20067 |
++ acl_alloc(sizeof (struct role_transition))) == NULL) |
20068 |
++ return -ENOMEM; |
20069 |
++ |
20070 |
++ if (copy_from_user(rtmp, rusertp, |
20071 |
++ sizeof (struct role_transition))) |
20072 |
++ return -EFAULT; |
20073 |
++ |
20074 |
++ rusertp = rtmp->prev; |
20075 |
++ |
20076 |
++ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN); |
20077 |
++ |
20078 |
++ if (!len || len >= GR_SPROLE_LEN) |
20079 |
++ return -EINVAL; |
20080 |
++ |
20081 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
20082 |
++ return -ENOMEM; |
20083 |
++ |
20084 |
++ if (copy_from_user(tmp, rtmp->rolename, len)) |
20085 |
++ return -EFAULT; |
20086 |
++ |
20087 |
++ rtmp->rolename = tmp; |
20088 |
++ |
20089 |
++ if (!rlast) { |
20090 |
++ rtmp->prev = NULL; |
20091 |
++ rolep->transitions = rtmp; |
20092 |
++ } else { |
20093 |
++ rlast->next = rtmp; |
20094 |
++ rtmp->prev = rlast; |
20095 |
++ } |
20096 |
++ |
20097 |
++ if (!rusertp) |
20098 |
++ rtmp->next = NULL; |
20099 |
++ } |
20100 |
++ |
20101 |
++ return 0; |
20102 |
++} |
20103 |
++ |
20104 |
++static struct acl_subject_label * |
20105 |
++do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role) |
20106 |
++{ |
20107 |
++ struct acl_subject_label *s_tmp = NULL, *s_tmp2; |
20108 |
++ unsigned int len; |
20109 |
++ char *tmp; |
20110 |
++ __u32 num_objs; |
20111 |
++ struct acl_ip_label **i_tmp, *i_utmp2; |
20112 |
++ struct gr_hash_struct ghash; |
20113 |
++ struct subject_map *subjmap; |
20114 |
++ unsigned int i_num; |
20115 |
++ int err; |
20116 |
++ |
20117 |
++ s_tmp = lookup_subject_map(userp); |
20118 |
++ |
20119 |
++ /* we've already copied this subject into the kernel, just return |
20120 |
++ the reference to it, and don't copy it over again |
20121 |
++ */ |
20122 |
++ if (s_tmp) |
20123 |
++ return(s_tmp); |
20124 |
++ |
20125 |
++ if ((s_tmp = (struct acl_subject_label *) |
20126 |
++ acl_alloc(sizeof (struct acl_subject_label))) == NULL) |
20127 |
++ return ERR_PTR(-ENOMEM); |
20128 |
++ |
20129 |
++ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL); |
20130 |
++ if (subjmap == NULL) |
20131 |
++ return ERR_PTR(-ENOMEM); |
20132 |
++ |
20133 |
++ subjmap->user = userp; |
20134 |
++ subjmap->kernel = s_tmp; |
20135 |
++ insert_subj_map_entry(subjmap); |
20136 |
++ |
20137 |
++ if (copy_from_user(s_tmp, userp, |
20138 |
++ sizeof (struct acl_subject_label))) |
20139 |
++ return ERR_PTR(-EFAULT); |
20140 |
++ |
20141 |
++ len = strnlen_user(s_tmp->filename, PATH_MAX); |
20142 |
++ |
20143 |
++ if (!len || len >= PATH_MAX) |
20144 |
++ return ERR_PTR(-EINVAL); |
20145 |
++ |
20146 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) |
20147 |
++ return ERR_PTR(-ENOMEM); |
20148 |
++ |
20149 |
++ if (copy_from_user(tmp, s_tmp->filename, len)) |
20150 |
++ return ERR_PTR(-EFAULT); |
20151 |
++ |
20152 |
++ s_tmp->filename = tmp; |
20153 |
++ |
20154 |
++ if (!strcmp(s_tmp->filename, "/")) |
20155 |
++ role->root_label = s_tmp; |
20156 |
++ |
20157 |
++ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct))) |
20158 |
++ return ERR_PTR(-EFAULT); |
20159 |
++ |
20160 |
++ /* copy user and group transition tables */ |
20161 |
++ |
20162 |
++ if (s_tmp->user_trans_num) { |
20163 |
++ uid_t *uidlist; |
20164 |
++ |
20165 |
++ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t)); |
20166 |
++ if (uidlist == NULL) |
20167 |
++ return ERR_PTR(-ENOMEM); |
20168 |
++ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t))) |
20169 |
++ return ERR_PTR(-EFAULT); |
20170 |
++ |
20171 |
++ s_tmp->user_transitions = uidlist; |
20172 |
++ } |
20173 |
++ |
20174 |
++ if (s_tmp->group_trans_num) { |
20175 |
++ gid_t *gidlist; |
20176 |
++ |
20177 |
++ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t)); |
20178 |
++ if (gidlist == NULL) |
20179 |
++ return ERR_PTR(-ENOMEM); |
20180 |
++ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t))) |
20181 |
++ return ERR_PTR(-EFAULT); |
20182 |
++ |
20183 |
++ s_tmp->group_transitions = gidlist; |
20184 |
++ } |
20185 |
++ |
20186 |
++ /* set up object hash table */ |
20187 |
++ num_objs = count_user_objs(ghash.first); |
20188 |
++ |
20189 |
++ s_tmp->obj_hash_size = num_objs; |
20190 |
++ s_tmp->obj_hash = |
20191 |
++ (struct acl_object_label **) |
20192 |
++ create_table(&(s_tmp->obj_hash_size), sizeof(void *)); |
20193 |
++ |
20194 |
++ if (!s_tmp->obj_hash) |
20195 |
++ return ERR_PTR(-ENOMEM); |
20196 |
++ |
20197 |
++ memset(s_tmp->obj_hash, 0, |
20198 |
++ s_tmp->obj_hash_size * |
20199 |
++ sizeof (struct acl_object_label *)); |
20200 |
++ |
20201 |
++ /* add in objects */ |
20202 |
++ err = copy_user_objs(ghash.first, s_tmp, role); |
20203 |
++ |
20204 |
++ if (err) |
20205 |
++ return ERR_PTR(err); |
20206 |
++ |
20207 |
++ /* set pointer for parent subject */ |
20208 |
++ if (s_tmp->parent_subject) { |
20209 |
++ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role); |
20210 |
++ |
20211 |
++ if (IS_ERR(s_tmp2)) |
20212 |
++ return s_tmp2; |
20213 |
++ |
20214 |
++ s_tmp->parent_subject = s_tmp2; |
20215 |
++ } |
20216 |
++ |
20217 |
++ /* add in ip acls */ |
20218 |
++ |
20219 |
++ if (!s_tmp->ip_num) { |
20220 |
++ s_tmp->ips = NULL; |
20221 |
++ goto insert; |
20222 |
++ } |
20223 |
++ |
20224 |
++ i_tmp = |
20225 |
++ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num * |
20226 |
++ sizeof (struct |
20227 |
++ acl_ip_label *)); |
20228 |
++ |
20229 |
++ if (!i_tmp) |
20230 |
++ return ERR_PTR(-ENOMEM); |
20231 |
++ |
20232 |
++ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) { |
20233 |
++ *(i_tmp + i_num) = |
20234 |
++ (struct acl_ip_label *) |
20235 |
++ acl_alloc(sizeof (struct acl_ip_label)); |
20236 |
++ if (!*(i_tmp + i_num)) |
20237 |
++ return ERR_PTR(-ENOMEM); |
20238 |
++ |
20239 |
++ if (copy_from_user |
20240 |
++ (&i_utmp2, s_tmp->ips + i_num, |
20241 |
++ sizeof (struct acl_ip_label *))) |
20242 |
++ return ERR_PTR(-EFAULT); |
20243 |
++ |
20244 |
++ if (copy_from_user |
20245 |
++ (*(i_tmp + i_num), i_utmp2, |
20246 |
++ sizeof (struct acl_ip_label))) |
20247 |
++ return ERR_PTR(-EFAULT); |
20248 |
++ |
20249 |
++ if ((*(i_tmp + i_num))->iface == NULL) |
20250 |
++ continue; |
20251 |
++ |
20252 |
++ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ); |
20253 |
++ if (!len || len >= IFNAMSIZ) |
20254 |
++ return ERR_PTR(-EINVAL); |
20255 |
++ tmp = acl_alloc(len); |
20256 |
++ if (tmp == NULL) |
20257 |
++ return ERR_PTR(-ENOMEM); |
20258 |
++ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len)) |
20259 |
++ return ERR_PTR(-EFAULT); |
20260 |
++ (*(i_tmp + i_num))->iface = tmp; |
20261 |
++ } |
20262 |
++ |
20263 |
++ s_tmp->ips = i_tmp; |
20264 |
++ |
20265 |
++insert: |
20266 |
++ if (!insert_name_entry(s_tmp->filename, s_tmp->inode, |
20267 |
++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0)) |
20268 |
++ return ERR_PTR(-ENOMEM); |
20269 |
++ |
20270 |
++ return s_tmp; |
20271 |
++} |
20272 |
++ |
20273 |
++static int |
20274 |
++copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role) |
20275 |
++{ |
20276 |
++ struct acl_subject_label s_pre; |
20277 |
++ struct acl_subject_label * ret; |
20278 |
++ int err; |
20279 |
++ |
20280 |
++ while (userp) { |
20281 |
++ if (copy_from_user(&s_pre, userp, |
20282 |
++ sizeof (struct acl_subject_label))) |
20283 |
++ return -EFAULT; |
20284 |
++ |
20285 |
++ /* do not add nested subjects here, add |
20286 |
++ while parsing objects |
20287 |
++ */ |
20288 |
++ |
20289 |
++ if (s_pre.mode & GR_NESTED) { |
20290 |
++ userp = s_pre.prev; |
20291 |
++ continue; |
20292 |
++ } |
20293 |
++ |
20294 |
++ ret = do_copy_user_subj(userp, role); |
20295 |
++ |
20296 |
++ err = PTR_ERR(ret); |
20297 |
++ if (IS_ERR(ret)) |
20298 |
++ return err; |
20299 |
++ |
20300 |
++ insert_acl_subj_label(ret, role); |
20301 |
++ |
20302 |
++ userp = s_pre.prev; |
20303 |
++ } |
20304 |
++ |
20305 |
++ return 0; |
20306 |
++} |
20307 |
++ |
20308 |
++static int |
20309 |
++copy_user_acl(struct gr_arg *arg) |
20310 |
++{ |
20311 |
++ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2; |
20312 |
++ struct sprole_pw *sptmp; |
20313 |
++ struct gr_hash_struct *ghash; |
20314 |
++ uid_t *domainlist; |
20315 |
++ unsigned int r_num; |
20316 |
++ unsigned int len; |
20317 |
++ char *tmp; |
20318 |
++ int err = 0; |
20319 |
++ __u16 i; |
20320 |
++ __u32 num_subjs; |
20321 |
++ |
20322 |
++ /* we need a default and kernel role */ |
20323 |
++ if (arg->role_db.num_roles < 2) |
20324 |
++ return -EINVAL; |
20325 |
++ |
20326 |
++ /* copy special role authentication info from userspace */ |
20327 |
++ |
20328 |
++ num_sprole_pws = arg->num_sprole_pws; |
20329 |
++ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *)); |
20330 |
++ |
20331 |
++ if (!acl_special_roles) { |
20332 |
++ err = -ENOMEM; |
20333 |
++ goto cleanup; |
20334 |
++ } |
20335 |
++ |
20336 |
++ for (i = 0; i < num_sprole_pws; i++) { |
20337 |
++ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw)); |
20338 |
++ if (!sptmp) { |
20339 |
++ err = -ENOMEM; |
20340 |
++ goto cleanup; |
20341 |
++ } |
20342 |
++ if (copy_from_user(sptmp, arg->sprole_pws + i, |
20343 |
++ sizeof (struct sprole_pw))) { |
20344 |
++ err = -EFAULT; |
20345 |
++ goto cleanup; |
20346 |
++ } |
20347 |
++ |
20348 |
++ len = |
20349 |
++ strnlen_user(sptmp->rolename, GR_SPROLE_LEN); |
20350 |
++ |
20351 |
++ if (!len || len >= GR_SPROLE_LEN) { |
20352 |
++ err = -EINVAL; |
20353 |
++ goto cleanup; |
20354 |
++ } |
20355 |
++ |
20356 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) { |
20357 |
++ err = -ENOMEM; |
20358 |
++ goto cleanup; |
20359 |
++ } |
20360 |
++ |
20361 |
++ if (copy_from_user(tmp, sptmp->rolename, len)) { |
20362 |
++ err = -EFAULT; |
20363 |
++ goto cleanup; |
20364 |
++ } |
20365 |
++ |
20366 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
20367 |
++ printk(KERN_ALERT "Copying special role %s\n", tmp); |
20368 |
++#endif |
20369 |
++ sptmp->rolename = tmp; |
20370 |
++ acl_special_roles[i] = sptmp; |
20371 |
++ } |
20372 |
++ |
20373 |
++ r_utmp = (struct acl_role_label **) arg->role_db.r_table; |
20374 |
++ |
20375 |
++ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) { |
20376 |
++ r_tmp = acl_alloc(sizeof (struct acl_role_label)); |
20377 |
++ |
20378 |
++ if (!r_tmp) { |
20379 |
++ err = -ENOMEM; |
20380 |
++ goto cleanup; |
20381 |
++ } |
20382 |
++ |
20383 |
++ if (copy_from_user(&r_utmp2, r_utmp + r_num, |
20384 |
++ sizeof (struct acl_role_label *))) { |
20385 |
++ err = -EFAULT; |
20386 |
++ goto cleanup; |
20387 |
++ } |
20388 |
++ |
20389 |
++ if (copy_from_user(r_tmp, r_utmp2, |
20390 |
++ sizeof (struct acl_role_label))) { |
20391 |
++ err = -EFAULT; |
20392 |
++ goto cleanup; |
20393 |
++ } |
20394 |
++ |
20395 |
++ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN); |
20396 |
++ |
20397 |
++ if (!len || len >= PATH_MAX) { |
20398 |
++ err = -EINVAL; |
20399 |
++ goto cleanup; |
20400 |
++ } |
20401 |
++ |
20402 |
++ if ((tmp = (char *) acl_alloc(len)) == NULL) { |
20403 |
++ err = -ENOMEM; |
20404 |
++ goto cleanup; |
20405 |
++ } |
20406 |
++ if (copy_from_user(tmp, r_tmp->rolename, len)) { |
20407 |
++ err = -EFAULT; |
20408 |
++ goto cleanup; |
20409 |
++ } |
20410 |
++ r_tmp->rolename = tmp; |
20411 |
++ |
20412 |
++ if (!strcmp(r_tmp->rolename, "default") |
20413 |
++ && (r_tmp->roletype & GR_ROLE_DEFAULT)) { |
20414 |
++ default_role = r_tmp; |
20415 |
++ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) { |
20416 |
++ kernel_role = r_tmp; |
20417 |
++ } |
20418 |
++ |
20419 |
++ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) { |
20420 |
++ err = -ENOMEM; |
20421 |
++ goto cleanup; |
20422 |
++ } |
20423 |
++ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) { |
20424 |
++ err = -EFAULT; |
20425 |
++ goto cleanup; |
20426 |
++ } |
20427 |
++ |
20428 |
++ r_tmp->hash = ghash; |
20429 |
++ |
20430 |
++ num_subjs = count_user_subjs(r_tmp->hash->first); |
20431 |
++ |
20432 |
++ r_tmp->subj_hash_size = num_subjs; |
20433 |
++ r_tmp->subj_hash = |
20434 |
++ (struct acl_subject_label **) |
20435 |
++ create_table(&(r_tmp->subj_hash_size), sizeof(void *)); |
20436 |
++ |
20437 |
++ if (!r_tmp->subj_hash) { |
20438 |
++ err = -ENOMEM; |
20439 |
++ goto cleanup; |
20440 |
++ } |
20441 |
++ |
20442 |
++ err = copy_user_allowedips(r_tmp); |
20443 |
++ if (err) |
20444 |
++ goto cleanup; |
20445 |
++ |
20446 |
++ /* copy domain info */ |
20447 |
++ if (r_tmp->domain_children != NULL) { |
20448 |
++ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t)); |
20449 |
++ if (domainlist == NULL) { |
20450 |
++ err = -ENOMEM; |
20451 |
++ goto cleanup; |
20452 |
++ } |
20453 |
++ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) { |
20454 |
++ err = -EFAULT; |
20455 |
++ goto cleanup; |
20456 |
++ } |
20457 |
++ r_tmp->domain_children = domainlist; |
20458 |
++ } |
20459 |
++ |
20460 |
++ err = copy_user_transitions(r_tmp); |
20461 |
++ if (err) |
20462 |
++ goto cleanup; |
20463 |
++ |
20464 |
++ memset(r_tmp->subj_hash, 0, |
20465 |
++ r_tmp->subj_hash_size * |
20466 |
++ sizeof (struct acl_subject_label *)); |
20467 |
++ |
20468 |
++ err = copy_user_subjs(r_tmp->hash->first, r_tmp); |
20469 |
++ |
20470 |
++ if (err) |
20471 |
++ goto cleanup; |
20472 |
++ |
20473 |
++ /* set nested subject list to null */ |
20474 |
++ r_tmp->hash->first = NULL; |
20475 |
++ |
20476 |
++ insert_acl_role_label(r_tmp); |
20477 |
++ } |
20478 |
++ |
20479 |
++ goto return_err; |
20480 |
++ cleanup: |
20481 |
++ free_variables(); |
20482 |
++ return_err: |
20483 |
++ return err; |
20484 |
++ |
20485 |
++} |
20486 |
++ |
20487 |
++static int |
20488 |
++gracl_init(struct gr_arg *args) |
20489 |
++{ |
20490 |
++ int error = 0; |
20491 |
++ |
20492 |
++ memcpy(gr_system_salt, args->salt, GR_SALT_LEN); |
20493 |
++ memcpy(gr_system_sum, args->sum, GR_SHA_LEN); |
20494 |
++ |
20495 |
++ if (init_variables(args)) { |
20496 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION); |
20497 |
++ error = -ENOMEM; |
20498 |
++ free_variables(); |
20499 |
++ goto out; |
20500 |
++ } |
20501 |
++ |
20502 |
++ error = copy_user_acl(args); |
20503 |
++ free_init_variables(); |
20504 |
++ if (error) { |
20505 |
++ free_variables(); |
20506 |
++ goto out; |
20507 |
++ } |
20508 |
++ |
20509 |
++ if ((error = gr_set_acls(0))) { |
20510 |
++ free_variables(); |
20511 |
++ goto out; |
20512 |
++ } |
20513 |
++ |
20514 |
++ gr_status |= GR_READY; |
20515 |
++ out: |
20516 |
++ return error; |
20517 |
++} |
20518 |
++ |
20519 |
++/* derived from glibc fnmatch() 0: match, 1: no match*/ |
20520 |
++ |
20521 |
++static int |
20522 |
++glob_match(const char *p, const char *n) |
20523 |
++{ |
20524 |
++ char c; |
20525 |
++ |
20526 |
++ while ((c = *p++) != '\0') { |
20527 |
++ switch (c) { |
20528 |
++ case '?': |
20529 |
++ if (*n == '\0') |
20530 |
++ return 1; |
20531 |
++ else if (*n == '/') |
20532 |
++ return 1; |
20533 |
++ break; |
20534 |
++ case '\\': |
20535 |
++ if (*n != c) |
20536 |
++ return 1; |
20537 |
++ break; |
20538 |
++ case '*': |
20539 |
++ for (c = *p++; c == '?' || c == '*'; c = *p++) { |
20540 |
++ if (*n == '/') |
20541 |
++ return 1; |
20542 |
++ else if (c == '?') { |
20543 |
++ if (*n == '\0') |
20544 |
++ return 1; |
20545 |
++ else |
20546 |
++ ++n; |
20547 |
++ } |
20548 |
++ } |
20549 |
++ if (c == '\0') { |
20550 |
++ return 0; |
20551 |
++ } else { |
20552 |
++ const char *endp; |
20553 |
++ |
20554 |
++ if ((endp = strchr(n, '/')) == NULL) |
20555 |
++ endp = n + strlen(n); |
20556 |
++ |
20557 |
++ if (c == '[') { |
20558 |
++ for (--p; n < endp; ++n) |
20559 |
++ if (!glob_match(p, n)) |
20560 |
++ return 0; |
20561 |
++ } else if (c == '/') { |
20562 |
++ while (*n != '\0' && *n != '/') |
20563 |
++ ++n; |
20564 |
++ if (*n == '/' && !glob_match(p, n + 1)) |
20565 |
++ return 0; |
20566 |
++ } else { |
20567 |
++ for (--p; n < endp; ++n) |
20568 |
++ if (*n == c && !glob_match(p, n)) |
20569 |
++ return 0; |
20570 |
++ } |
20571 |
++ |
20572 |
++ return 1; |
20573 |
++ } |
20574 |
++ case '[': |
20575 |
++ { |
20576 |
++ int not; |
20577 |
++ char cold; |
20578 |
++ |
20579 |
++ if (*n == '\0' || *n == '/') |
20580 |
++ return 1; |
20581 |
++ |
20582 |
++ not = (*p == '!' || *p == '^'); |
20583 |
++ if (not) |
20584 |
++ ++p; |
20585 |
++ |
20586 |
++ c = *p++; |
20587 |
++ for (;;) { |
20588 |
++ unsigned char fn = (unsigned char)*n; |
20589 |
++ |
20590 |
++ if (c == '\0') |
20591 |
++ return 1; |
20592 |
++ else { |
20593 |
++ if (c == fn) |
20594 |
++ goto matched; |
20595 |
++ cold = c; |
20596 |
++ c = *p++; |
20597 |
++ |
20598 |
++ if (c == '-' && *p != ']') { |
20599 |
++ unsigned char cend = *p++; |
20600 |
++ |
20601 |
++ if (cend == '\0') |
20602 |
++ return 1; |
20603 |
++ |
20604 |
++ if (cold <= fn && fn <= cend) |
20605 |
++ goto matched; |
20606 |
++ |
20607 |
++ c = *p++; |
20608 |
++ } |
20609 |
++ } |
20610 |
++ |
20611 |
++ if (c == ']') |
20612 |
++ break; |
20613 |
++ } |
20614 |
++ if (!not) |
20615 |
++ return 1; |
20616 |
++ break; |
20617 |
++ matched: |
20618 |
++ while (c != ']') { |
20619 |
++ if (c == '\0') |
20620 |
++ return 1; |
20621 |
++ |
20622 |
++ c = *p++; |
20623 |
++ } |
20624 |
++ if (not) |
20625 |
++ return 1; |
20626 |
++ } |
20627 |
++ break; |
20628 |
++ default: |
20629 |
++ if (c != *n) |
20630 |
++ return 1; |
20631 |
++ } |
20632 |
++ |
20633 |
++ ++n; |
20634 |
++ } |
20635 |
++ |
20636 |
++ if (*n == '\0') |
20637 |
++ return 0; |
20638 |
++ |
20639 |
++ if (*n == '/') |
20640 |
++ return 0; |
20641 |
++ |
20642 |
++ return 1; |
20643 |
++} |
20644 |
++ |
20645 |
++static struct acl_object_label * |
20646 |
++chk_glob_label(struct acl_object_label *globbed, |
20647 |
++ struct dentry *dentry, struct vfsmount *mnt, char **path) |
20648 |
++{ |
20649 |
++ struct acl_object_label *tmp; |
20650 |
++ |
20651 |
++ if (*path == NULL) |
20652 |
++ *path = gr_to_filename_nolock(dentry, mnt); |
20653 |
++ |
20654 |
++ tmp = globbed; |
20655 |
++ |
20656 |
++ while (tmp) { |
20657 |
++ if (!glob_match(tmp->filename, *path)) |
20658 |
++ return tmp; |
20659 |
++ tmp = tmp->next; |
20660 |
++ } |
20661 |
++ |
20662 |
++ return NULL; |
20663 |
++} |
20664 |
++ |
20665 |
++static struct acl_object_label * |
20666 |
++__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, |
20667 |
++ const ino_t curr_ino, const dev_t curr_dev, |
20668 |
++ const struct acl_subject_label *subj, char **path) |
20669 |
++{ |
20670 |
++ struct acl_subject_label *tmpsubj; |
20671 |
++ struct acl_object_label *retval; |
20672 |
++ struct acl_object_label *retval2; |
20673 |
++ |
20674 |
++ tmpsubj = (struct acl_subject_label *) subj; |
20675 |
++ read_lock(&gr_inode_lock); |
20676 |
++ do { |
20677 |
++ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj); |
20678 |
++ if (retval) { |
20679 |
++ if (retval->globbed) { |
20680 |
++ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry, |
20681 |
++ (struct vfsmount *)orig_mnt, path); |
20682 |
++ if (retval2) |
20683 |
++ retval = retval2; |
20684 |
++ } |
20685 |
++ break; |
20686 |
++ } |
20687 |
++ } while ((tmpsubj = tmpsubj->parent_subject)); |
20688 |
++ read_unlock(&gr_inode_lock); |
20689 |
++ |
20690 |
++ return retval; |
20691 |
++} |
20692 |
++ |
20693 |
++static __inline__ struct acl_object_label * |
20694 |
++full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt, |
20695 |
++ const struct dentry *curr_dentry, |
20696 |
++ const struct acl_subject_label *subj, char **path) |
20697 |
++{ |
20698 |
++ return __full_lookup(orig_dentry, orig_mnt, |
20699 |
++ curr_dentry->d_inode->i_ino, |
20700 |
++ curr_dentry->d_inode->i_sb->s_dev, subj, path); |
20701 |
++} |
20702 |
++ |
20703 |
++static struct acl_object_label * |
20704 |
++__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20705 |
++ const struct acl_subject_label *subj, char *path) |
20706 |
++{ |
20707 |
++ struct dentry *dentry = (struct dentry *) l_dentry; |
20708 |
++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; |
20709 |
++ struct acl_object_label *retval; |
20710 |
++ |
20711 |
++ spin_lock(&dcache_lock); |
20712 |
++ |
20713 |
++ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt || |
20714 |
++ /* ignore Eric Biederman */ |
20715 |
++ IS_PRIVATE(l_dentry->d_inode))) { |
20716 |
++ retval = fakefs_obj; |
20717 |
++ goto out; |
20718 |
++ } |
20719 |
++ |
20720 |
++ for (;;) { |
20721 |
++ if (dentry == real_root && mnt == real_root_mnt) |
20722 |
++ break; |
20723 |
++ |
20724 |
++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { |
20725 |
++ if (mnt->mnt_parent == mnt) |
20726 |
++ break; |
20727 |
++ |
20728 |
++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); |
20729 |
++ if (retval != NULL) |
20730 |
++ goto out; |
20731 |
++ |
20732 |
++ dentry = mnt->mnt_mountpoint; |
20733 |
++ mnt = mnt->mnt_parent; |
20734 |
++ continue; |
20735 |
++ } |
20736 |
++ |
20737 |
++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); |
20738 |
++ if (retval != NULL) |
20739 |
++ goto out; |
20740 |
++ |
20741 |
++ dentry = dentry->d_parent; |
20742 |
++ } |
20743 |
++ |
20744 |
++ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path); |
20745 |
++ |
20746 |
++ if (retval == NULL) |
20747 |
++ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path); |
20748 |
++out: |
20749 |
++ spin_unlock(&dcache_lock); |
20750 |
++ return retval; |
20751 |
++} |
20752 |
++ |
20753 |
++static __inline__ struct acl_object_label * |
20754 |
++chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20755 |
++ const struct acl_subject_label *subj) |
20756 |
++{ |
20757 |
++ char *path = NULL; |
20758 |
++ return __chk_obj_label(l_dentry, l_mnt, subj, path); |
20759 |
++} |
20760 |
++ |
20761 |
++static __inline__ struct acl_object_label * |
20762 |
++chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20763 |
++ const struct acl_subject_label *subj, char *path) |
20764 |
++{ |
20765 |
++ return __chk_obj_label(l_dentry, l_mnt, subj, path); |
20766 |
++} |
20767 |
++ |
20768 |
++static struct acl_subject_label * |
20769 |
++chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, |
20770 |
++ const struct acl_role_label *role) |
20771 |
++{ |
20772 |
++ struct dentry *dentry = (struct dentry *) l_dentry; |
20773 |
++ struct vfsmount *mnt = (struct vfsmount *) l_mnt; |
20774 |
++ struct acl_subject_label *retval; |
20775 |
++ |
20776 |
++ spin_lock(&dcache_lock); |
20777 |
++ |
20778 |
++ for (;;) { |
20779 |
++ if (dentry == real_root && mnt == real_root_mnt) |
20780 |
++ break; |
20781 |
++ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) { |
20782 |
++ if (mnt->mnt_parent == mnt) |
20783 |
++ break; |
20784 |
++ |
20785 |
++ read_lock(&gr_inode_lock); |
20786 |
++ retval = |
20787 |
++ lookup_acl_subj_label(dentry->d_inode->i_ino, |
20788 |
++ dentry->d_inode->i_sb->s_dev, role); |
20789 |
++ read_unlock(&gr_inode_lock); |
20790 |
++ if (retval != NULL) |
20791 |
++ goto out; |
20792 |
++ |
20793 |
++ dentry = mnt->mnt_mountpoint; |
20794 |
++ mnt = mnt->mnt_parent; |
20795 |
++ continue; |
20796 |
++ } |
20797 |
++ |
20798 |
++ read_lock(&gr_inode_lock); |
20799 |
++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, |
20800 |
++ dentry->d_inode->i_sb->s_dev, role); |
20801 |
++ read_unlock(&gr_inode_lock); |
20802 |
++ if (retval != NULL) |
20803 |
++ goto out; |
20804 |
++ |
20805 |
++ dentry = dentry->d_parent; |
20806 |
++ } |
20807 |
++ |
20808 |
++ read_lock(&gr_inode_lock); |
20809 |
++ retval = lookup_acl_subj_label(dentry->d_inode->i_ino, |
20810 |
++ dentry->d_inode->i_sb->s_dev, role); |
20811 |
++ read_unlock(&gr_inode_lock); |
20812 |
++ |
20813 |
++ if (unlikely(retval == NULL)) { |
20814 |
++ read_lock(&gr_inode_lock); |
20815 |
++ retval = lookup_acl_subj_label(real_root->d_inode->i_ino, |
20816 |
++ real_root->d_inode->i_sb->s_dev, role); |
20817 |
++ read_unlock(&gr_inode_lock); |
20818 |
++ } |
20819 |
++out: |
20820 |
++ spin_unlock(&dcache_lock); |
20821 |
++ |
20822 |
++ return retval; |
20823 |
++} |
20824 |
++ |
20825 |
++static void |
20826 |
++gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode) |
20827 |
++{ |
20828 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype, |
20829 |
++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, |
20830 |
++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, |
20831 |
++ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip)); |
20832 |
++ |
20833 |
++ return; |
20834 |
++} |
20835 |
++ |
20836 |
++static void |
20837 |
++gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode) |
20838 |
++{ |
20839 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype, |
20840 |
++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, |
20841 |
++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, |
20842 |
++ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip)); |
20843 |
++ |
20844 |
++ return; |
20845 |
++} |
20846 |
++ |
20847 |
++static void |
20848 |
++gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, |
20849 |
++ const unsigned int effective, const unsigned int fs) |
20850 |
++{ |
20851 |
++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype, |
20852 |
++ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, |
20853 |
++ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, |
20854 |
++ type, real, effective, fs, NIPQUAD(task->signal->curr_ip)); |
20855 |
++ |
20856 |
++ return; |
20857 |
++} |
20858 |
++ |
20859 |
++__u32 |
20860 |
++gr_check_link(const struct dentry * new_dentry, |
20861 |
++ const struct dentry * parent_dentry, |
20862 |
++ const struct vfsmount * parent_mnt, |
20863 |
++ const struct dentry * old_dentry, const struct vfsmount * old_mnt) |
20864 |
++{ |
20865 |
++ struct acl_object_label *obj; |
20866 |
++ __u32 oldmode, newmode; |
20867 |
++ __u32 needmode; |
20868 |
++ |
20869 |
++ if (unlikely(!(gr_status & GR_READY))) |
20870 |
++ return (GR_CREATE | GR_LINK); |
20871 |
++ |
20872 |
++ obj = chk_obj_label(old_dentry, old_mnt, current->acl); |
20873 |
++ oldmode = obj->mode; |
20874 |
++ |
20875 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
20876 |
++ oldmode |= (GR_CREATE | GR_LINK); |
20877 |
++ |
20878 |
++ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS; |
20879 |
++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID)) |
20880 |
++ needmode |= GR_SETID | GR_AUDIT_SETID; |
20881 |
++ |
20882 |
++ newmode = |
20883 |
++ gr_check_create(new_dentry, parent_dentry, parent_mnt, |
20884 |
++ oldmode | needmode); |
20885 |
++ |
20886 |
++ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC | |
20887 |
++ GR_SETID | GR_READ | GR_FIND | GR_DELETE | |
20888 |
++ GR_INHERIT | GR_AUDIT_INHERIT); |
20889 |
++ |
20890 |
++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID)) |
20891 |
++ goto bad; |
20892 |
++ |
20893 |
++ if ((oldmode & needmode) != needmode) |
20894 |
++ goto bad; |
20895 |
++ |
20896 |
++ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS); |
20897 |
++ if ((newmode & needmode) != needmode) |
20898 |
++ goto bad; |
20899 |
++ |
20900 |
++ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK)) |
20901 |
++ return newmode; |
20902 |
++bad: |
20903 |
++ needmode = oldmode; |
20904 |
++ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID)) |
20905 |
++ needmode |= GR_SETID; |
20906 |
++ |
20907 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) { |
20908 |
++ gr_log_learn(current, old_dentry, old_mnt, needmode); |
20909 |
++ return (GR_CREATE | GR_LINK); |
20910 |
++ } else if (newmode & GR_SUPPRESS) |
20911 |
++ return GR_SUPPRESS; |
20912 |
++ else |
20913 |
++ return 0; |
20914 |
++} |
20915 |
++ |
20916 |
++__u32 |
20917 |
++gr_search_file(const struct dentry * dentry, const __u32 mode, |
20918 |
++ const struct vfsmount * mnt) |
20919 |
++{ |
20920 |
++ __u32 retval = mode; |
20921 |
++ struct acl_subject_label *curracl; |
20922 |
++ struct acl_object_label *currobj; |
20923 |
++ |
20924 |
++ if (unlikely(!(gr_status & GR_READY))) |
20925 |
++ return (mode & ~GR_AUDITS); |
20926 |
++ |
20927 |
++ curracl = current->acl; |
20928 |
++ |
20929 |
++ currobj = chk_obj_label(dentry, mnt, curracl); |
20930 |
++ retval = currobj->mode & mode; |
20931 |
++ |
20932 |
++ if (unlikely |
20933 |
++ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE) |
20934 |
++ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) { |
20935 |
++ __u32 new_mode = mode; |
20936 |
++ |
20937 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
20938 |
++ |
20939 |
++ retval = new_mode; |
20940 |
++ |
20941 |
++ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN) |
20942 |
++ new_mode |= GR_INHERIT; |
20943 |
++ |
20944 |
++ if (!(mode & GR_NOLEARN)) |
20945 |
++ gr_log_learn(current, dentry, mnt, new_mode); |
20946 |
++ } |
20947 |
++ |
20948 |
++ return retval; |
20949 |
++} |
20950 |
++ |
20951 |
++__u32 |
20952 |
++gr_check_create(const struct dentry * new_dentry, const struct dentry * parent, |
20953 |
++ const struct vfsmount * mnt, const __u32 mode) |
20954 |
++{ |
20955 |
++ struct name_entry *match; |
20956 |
++ struct acl_object_label *matchpo; |
20957 |
++ struct acl_subject_label *curracl; |
20958 |
++ char *path; |
20959 |
++ __u32 retval; |
20960 |
++ |
20961 |
++ if (unlikely(!(gr_status & GR_READY))) |
20962 |
++ return (mode & ~GR_AUDITS); |
20963 |
++ |
20964 |
++ preempt_disable(); |
20965 |
++ path = gr_to_filename_rbac(new_dentry, mnt); |
20966 |
++ match = lookup_name_entry_create(path); |
20967 |
++ |
20968 |
++ if (!match) |
20969 |
++ goto check_parent; |
20970 |
++ |
20971 |
++ curracl = current->acl; |
20972 |
++ |
20973 |
++ read_lock(&gr_inode_lock); |
20974 |
++ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl); |
20975 |
++ read_unlock(&gr_inode_lock); |
20976 |
++ |
20977 |
++ if (matchpo) { |
20978 |
++ if ((matchpo->mode & mode) != |
20979 |
++ (mode & ~(GR_AUDITS | GR_SUPPRESS)) |
20980 |
++ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) { |
20981 |
++ __u32 new_mode = mode; |
20982 |
++ |
20983 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
20984 |
++ |
20985 |
++ gr_log_learn(current, new_dentry, mnt, new_mode); |
20986 |
++ |
20987 |
++ preempt_enable(); |
20988 |
++ return new_mode; |
20989 |
++ } |
20990 |
++ preempt_enable(); |
20991 |
++ return (matchpo->mode & mode); |
20992 |
++ } |
20993 |
++ |
20994 |
++ check_parent: |
20995 |
++ curracl = current->acl; |
20996 |
++ |
20997 |
++ matchpo = chk_obj_create_label(parent, mnt, curracl, path); |
20998 |
++ retval = matchpo->mode & mode; |
20999 |
++ |
21000 |
++ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))) |
21001 |
++ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) { |
21002 |
++ __u32 new_mode = mode; |
21003 |
++ |
21004 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
21005 |
++ |
21006 |
++ gr_log_learn(current, new_dentry, mnt, new_mode); |
21007 |
++ preempt_enable(); |
21008 |
++ return new_mode; |
21009 |
++ } |
21010 |
++ |
21011 |
++ preempt_enable(); |
21012 |
++ return retval; |
21013 |
++} |
21014 |
++ |
21015 |
++int |
21016 |
++gr_check_hidden_task(const struct task_struct *task) |
21017 |
++{ |
21018 |
++ if (unlikely(!(gr_status & GR_READY))) |
21019 |
++ return 0; |
21020 |
++ |
21021 |
++ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW)) |
21022 |
++ return 1; |
21023 |
++ |
21024 |
++ return 0; |
21025 |
++} |
21026 |
++ |
21027 |
++int |
21028 |
++gr_check_protected_task(const struct task_struct *task) |
21029 |
++{ |
21030 |
++ if (unlikely(!(gr_status & GR_READY) || !task)) |
21031 |
++ return 0; |
21032 |
++ |
21033 |
++ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) && |
21034 |
++ task->acl != current->acl) |
21035 |
++ return 1; |
21036 |
++ |
21037 |
++ return 0; |
21038 |
++} |
21039 |
++ |
21040 |
++void |
21041 |
++gr_copy_label(struct task_struct *tsk) |
21042 |
++{ |
21043 |
++ tsk->signal->used_accept = 0; |
21044 |
++ tsk->acl_sp_role = 0; |
21045 |
++ tsk->acl_role_id = current->acl_role_id; |
21046 |
++ tsk->acl = current->acl; |
21047 |
++ tsk->role = current->role; |
21048 |
++ tsk->signal->curr_ip = current->signal->curr_ip; |
21049 |
++ if (current->exec_file) |
21050 |
++ get_file(current->exec_file); |
21051 |
++ tsk->exec_file = current->exec_file; |
21052 |
++ tsk->is_writable = current->is_writable; |
21053 |
++ if (unlikely(current->signal->used_accept)) |
21054 |
++ current->signal->curr_ip = 0; |
21055 |
++ |
21056 |
++ return; |
21057 |
++} |
21058 |
++ |
21059 |
++static void |
21060 |
++gr_set_proc_res(struct task_struct *task) |
21061 |
++{ |
21062 |
++ struct acl_subject_label *proc; |
21063 |
++ unsigned short i; |
21064 |
++ |
21065 |
++ proc = task->acl; |
21066 |
++ |
21067 |
++ if (proc->mode & (GR_LEARN | GR_INHERITLEARN)) |
21068 |
++ return; |
21069 |
++ |
21070 |
++ for (i = 0; i < (GR_NLIMITS - 1); i++) { |
21071 |
++ if (!(proc->resmask & (1 << i))) |
21072 |
++ continue; |
21073 |
++ |
21074 |
++ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur; |
21075 |
++ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max; |
21076 |
++ } |
21077 |
++ |
21078 |
++ return; |
21079 |
++} |
21080 |
++ |
21081 |
++int |
21082 |
++gr_check_user_change(int real, int effective, int fs) |
21083 |
++{ |
21084 |
++ unsigned int i; |
21085 |
++ __u16 num; |
21086 |
++ uid_t *uidlist; |
21087 |
++ int curuid; |
21088 |
++ int realok = 0; |
21089 |
++ int effectiveok = 0; |
21090 |
++ int fsok = 0; |
21091 |
++ |
21092 |
++ if (unlikely(!(gr_status & GR_READY))) |
21093 |
++ return 0; |
21094 |
++ |
21095 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
21096 |
++ gr_log_learn_id_change(current, 'u', real, effective, fs); |
21097 |
++ |
21098 |
++ num = current->acl->user_trans_num; |
21099 |
++ uidlist = current->acl->user_transitions; |
21100 |
++ |
21101 |
++ if (uidlist == NULL) |
21102 |
++ return 0; |
21103 |
++ |
21104 |
++ if (real == -1) |
21105 |
++ realok = 1; |
21106 |
++ if (effective == -1) |
21107 |
++ effectiveok = 1; |
21108 |
++ if (fs == -1) |
21109 |
++ fsok = 1; |
21110 |
++ |
21111 |
++ if (current->acl->user_trans_type & GR_ID_ALLOW) { |
21112 |
++ for (i = 0; i < num; i++) { |
21113 |
++ curuid = (int)uidlist[i]; |
21114 |
++ if (real == curuid) |
21115 |
++ realok = 1; |
21116 |
++ if (effective == curuid) |
21117 |
++ effectiveok = 1; |
21118 |
++ if (fs == curuid) |
21119 |
++ fsok = 1; |
21120 |
++ } |
21121 |
++ } else if (current->acl->user_trans_type & GR_ID_DENY) { |
21122 |
++ for (i = 0; i < num; i++) { |
21123 |
++ curuid = (int)uidlist[i]; |
21124 |
++ if (real == curuid) |
21125 |
++ break; |
21126 |
++ if (effective == curuid) |
21127 |
++ break; |
21128 |
++ if (fs == curuid) |
21129 |
++ break; |
21130 |
++ } |
21131 |
++ /* not in deny list */ |
21132 |
++ if (i == num) { |
21133 |
++ realok = 1; |
21134 |
++ effectiveok = 1; |
21135 |
++ fsok = 1; |
21136 |
++ } |
21137 |
++ } |
21138 |
++ |
21139 |
++ if (realok && effectiveok && fsok) |
21140 |
++ return 0; |
21141 |
++ else { |
21142 |
++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real); |
21143 |
++ return 1; |
21144 |
++ } |
21145 |
++} |
21146 |
++ |
21147 |
++int |
21148 |
++gr_check_group_change(int real, int effective, int fs) |
21149 |
++{ |
21150 |
++ unsigned int i; |
21151 |
++ __u16 num; |
21152 |
++ gid_t *gidlist; |
21153 |
++ int curgid; |
21154 |
++ int realok = 0; |
21155 |
++ int effectiveok = 0; |
21156 |
++ int fsok = 0; |
21157 |
++ |
21158 |
++ if (unlikely(!(gr_status & GR_READY))) |
21159 |
++ return 0; |
21160 |
++ |
21161 |
++ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
21162 |
++ gr_log_learn_id_change(current, 'g', real, effective, fs); |
21163 |
++ |
21164 |
++ num = current->acl->group_trans_num; |
21165 |
++ gidlist = current->acl->group_transitions; |
21166 |
++ |
21167 |
++ if (gidlist == NULL) |
21168 |
++ return 0; |
21169 |
++ |
21170 |
++ if (real == -1) |
21171 |
++ realok = 1; |
21172 |
++ if (effective == -1) |
21173 |
++ effectiveok = 1; |
21174 |
++ if (fs == -1) |
21175 |
++ fsok = 1; |
21176 |
++ |
21177 |
++ if (current->acl->group_trans_type & GR_ID_ALLOW) { |
21178 |
++ for (i = 0; i < num; i++) { |
21179 |
++ curgid = (int)gidlist[i]; |
21180 |
++ if (real == curgid) |
21181 |
++ realok = 1; |
21182 |
++ if (effective == curgid) |
21183 |
++ effectiveok = 1; |
21184 |
++ if (fs == curgid) |
21185 |
++ fsok = 1; |
21186 |
++ } |
21187 |
++ } else if (current->acl->group_trans_type & GR_ID_DENY) { |
21188 |
++ for (i = 0; i < num; i++) { |
21189 |
++ curgid = (int)gidlist[i]; |
21190 |
++ if (real == curgid) |
21191 |
++ break; |
21192 |
++ if (effective == curgid) |
21193 |
++ break; |
21194 |
++ if (fs == curgid) |
21195 |
++ break; |
21196 |
++ } |
21197 |
++ /* not in deny list */ |
21198 |
++ if (i == num) { |
21199 |
++ realok = 1; |
21200 |
++ effectiveok = 1; |
21201 |
++ fsok = 1; |
21202 |
++ } |
21203 |
++ } |
21204 |
++ |
21205 |
++ if (realok && effectiveok && fsok) |
21206 |
++ return 0; |
21207 |
++ else { |
21208 |
++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real); |
21209 |
++ return 1; |
21210 |
++ } |
21211 |
++} |
21212 |
++ |
21213 |
++void |
21214 |
++gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid) |
21215 |
++{ |
21216 |
++ struct acl_role_label *role = task->role; |
21217 |
++ struct acl_subject_label *subj = NULL; |
21218 |
++ struct acl_object_label *obj; |
21219 |
++ struct file *filp; |
21220 |
++ |
21221 |
++ if (unlikely(!(gr_status & GR_READY))) |
21222 |
++ return; |
21223 |
++ |
21224 |
++ filp = task->exec_file; |
21225 |
++ |
21226 |
++ /* kernel process, we'll give them the kernel role */ |
21227 |
++ if (unlikely(!filp)) { |
21228 |
++ task->role = kernel_role; |
21229 |
++ task->acl = kernel_role->root_label; |
21230 |
++ return; |
21231 |
++ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL)) |
21232 |
++ role = lookup_acl_role_label(task, uid, gid); |
21233 |
++ |
21234 |
++ /* perform subject lookup in possibly new role |
21235 |
++ we can use this result below in the case where role == task->role |
21236 |
++ */ |
21237 |
++ subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role); |
21238 |
++ |
21239 |
++ /* if we changed uid/gid, but result in the same role |
21240 |
++ and are using inheritance, don't lose the inherited subject |
21241 |
++ if current subject is other than what normal lookup |
21242 |
++ would result in, we arrived via inheritance, don't |
21243 |
++ lose subject |
21244 |
++ */ |
21245 |
++ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) && |
21246 |
++ (subj == task->acl))) |
21247 |
++ task->acl = subj; |
21248 |
++ |
21249 |
++ task->role = role; |
21250 |
++ |
21251 |
++ task->is_writable = 0; |
21252 |
++ |
21253 |
++ /* ignore additional mmap checks for processes that are writable |
21254 |
++ by the default ACL */ |
21255 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
21256 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21257 |
++ task->is_writable = 1; |
21258 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label); |
21259 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21260 |
++ task->is_writable = 1; |
21261 |
++ |
21262 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
21263 |
++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); |
21264 |
++#endif |
21265 |
++ |
21266 |
++ gr_set_proc_res(task); |
21267 |
++ |
21268 |
++ return; |
21269 |
++} |
21270 |
++ |
21271 |
++int |
21272 |
++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt) |
21273 |
++{ |
21274 |
++ struct task_struct *task = current; |
21275 |
++ struct acl_subject_label *newacl; |
21276 |
++ struct acl_object_label *obj; |
21277 |
++ __u32 retmode; |
21278 |
++ |
21279 |
++ if (unlikely(!(gr_status & GR_READY))) |
21280 |
++ return 0; |
21281 |
++ |
21282 |
++ newacl = chk_subj_label(dentry, mnt, task->role); |
21283 |
++ |
21284 |
++ task_lock(task); |
21285 |
++ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode & |
21286 |
++ GR_POVERRIDE) && (task->acl != newacl) && |
21287 |
++ !(task->role->roletype & GR_ROLE_GOD) && |
21288 |
++ !gr_search_file(dentry, GR_PTRACERD, mnt) && |
21289 |
++ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) || |
21290 |
++ (atomic_read(&task->fs->count) > 1 || |
21291 |
++ atomic_read(&task->files->count) > 1 || |
21292 |
++ atomic_read(&task->sighand->count) > 1)) { |
21293 |
++ task_unlock(task); |
21294 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt); |
21295 |
++ return -EACCES; |
21296 |
++ } |
21297 |
++ task_unlock(task); |
21298 |
++ |
21299 |
++ obj = chk_obj_label(dentry, mnt, task->acl); |
21300 |
++ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT); |
21301 |
++ |
21302 |
++ if (!(task->acl->mode & GR_INHERITLEARN) && |
21303 |
++ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) { |
21304 |
++ if (obj->nested) |
21305 |
++ task->acl = obj->nested; |
21306 |
++ else |
21307 |
++ task->acl = newacl; |
21308 |
++ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT) |
21309 |
++ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt); |
21310 |
++ |
21311 |
++ task->is_writable = 0; |
21312 |
++ |
21313 |
++ /* ignore additional mmap checks for processes that are writable |
21314 |
++ by the default ACL */ |
21315 |
++ obj = chk_obj_label(dentry, mnt, default_role->root_label); |
21316 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21317 |
++ task->is_writable = 1; |
21318 |
++ obj = chk_obj_label(dentry, mnt, task->role->root_label); |
21319 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21320 |
++ task->is_writable = 1; |
21321 |
++ |
21322 |
++ gr_set_proc_res(task); |
21323 |
++ |
21324 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
21325 |
++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); |
21326 |
++#endif |
21327 |
++ return 0; |
21328 |
++} |
21329 |
++ |
21330 |
++/* always called with valid inodev ptr */ |
21331 |
++static void |
21332 |
++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev) |
21333 |
++{ |
21334 |
++ struct acl_object_label *matchpo; |
21335 |
++ struct acl_subject_label *matchps; |
21336 |
++ struct acl_subject_label *subj; |
21337 |
++ struct acl_role_label *role; |
21338 |
++ unsigned int i, x; |
21339 |
++ |
21340 |
++ FOR_EACH_ROLE_START(role, i) |
21341 |
++ FOR_EACH_SUBJECT_START(role, subj, x) |
21342 |
++ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL) |
21343 |
++ matchpo->mode |= GR_DELETED; |
21344 |
++ FOR_EACH_SUBJECT_END(subj,x) |
21345 |
++ FOR_EACH_NESTED_SUBJECT_START(role, subj) |
21346 |
++ if (subj->inode == ino && subj->device == dev) |
21347 |
++ subj->mode |= GR_DELETED; |
21348 |
++ FOR_EACH_NESTED_SUBJECT_END(subj) |
21349 |
++ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL) |
21350 |
++ matchps->mode |= GR_DELETED; |
21351 |
++ FOR_EACH_ROLE_END(role,i) |
21352 |
++ |
21353 |
++ inodev->nentry->deleted = 1; |
21354 |
++ |
21355 |
++ return; |
21356 |
++} |
21357 |
++ |
21358 |
++void |
21359 |
++gr_handle_delete(const ino_t ino, const dev_t dev) |
21360 |
++{ |
21361 |
++ struct inodev_entry *inodev; |
21362 |
++ |
21363 |
++ if (unlikely(!(gr_status & GR_READY))) |
21364 |
++ return; |
21365 |
++ |
21366 |
++ write_lock(&gr_inode_lock); |
21367 |
++ inodev = lookup_inodev_entry(ino, dev); |
21368 |
++ if (inodev != NULL) |
21369 |
++ do_handle_delete(inodev, ino, dev); |
21370 |
++ write_unlock(&gr_inode_lock); |
21371 |
++ |
21372 |
++ return; |
21373 |
++} |
21374 |
++ |
21375 |
++static void |
21376 |
++update_acl_obj_label(const ino_t oldinode, const dev_t olddevice, |
21377 |
++ const ino_t newinode, const dev_t newdevice, |
21378 |
++ struct acl_subject_label *subj) |
21379 |
++{ |
21380 |
++ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size); |
21381 |
++ struct acl_object_label *match; |
21382 |
++ |
21383 |
++ match = subj->obj_hash[index]; |
21384 |
++ |
21385 |
++ while (match && (match->inode != oldinode || |
21386 |
++ match->device != olddevice || |
21387 |
++ !(match->mode & GR_DELETED))) |
21388 |
++ match = match->next; |
21389 |
++ |
21390 |
++ if (match && (match->inode == oldinode) |
21391 |
++ && (match->device == olddevice) |
21392 |
++ && (match->mode & GR_DELETED)) { |
21393 |
++ if (match->prev == NULL) { |
21394 |
++ subj->obj_hash[index] = match->next; |
21395 |
++ if (match->next != NULL) |
21396 |
++ match->next->prev = NULL; |
21397 |
++ } else { |
21398 |
++ match->prev->next = match->next; |
21399 |
++ if (match->next != NULL) |
21400 |
++ match->next->prev = match->prev; |
21401 |
++ } |
21402 |
++ match->prev = NULL; |
21403 |
++ match->next = NULL; |
21404 |
++ match->inode = newinode; |
21405 |
++ match->device = newdevice; |
21406 |
++ match->mode &= ~GR_DELETED; |
21407 |
++ |
21408 |
++ insert_acl_obj_label(match, subj); |
21409 |
++ } |
21410 |
++ |
21411 |
++ return; |
21412 |
++} |
21413 |
++ |
21414 |
++static void |
21415 |
++update_acl_subj_label(const ino_t oldinode, const dev_t olddevice, |
21416 |
++ const ino_t newinode, const dev_t newdevice, |
21417 |
++ struct acl_role_label *role) |
21418 |
++{ |
21419 |
++ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size); |
21420 |
++ struct acl_subject_label *match; |
21421 |
++ |
21422 |
++ match = role->subj_hash[index]; |
21423 |
++ |
21424 |
++ while (match && (match->inode != oldinode || |
21425 |
++ match->device != olddevice || |
21426 |
++ !(match->mode & GR_DELETED))) |
21427 |
++ match = match->next; |
21428 |
++ |
21429 |
++ if (match && (match->inode == oldinode) |
21430 |
++ && (match->device == olddevice) |
21431 |
++ && (match->mode & GR_DELETED)) { |
21432 |
++ if (match->prev == NULL) { |
21433 |
++ role->subj_hash[index] = match->next; |
21434 |
++ if (match->next != NULL) |
21435 |
++ match->next->prev = NULL; |
21436 |
++ } else { |
21437 |
++ match->prev->next = match->next; |
21438 |
++ if (match->next != NULL) |
21439 |
++ match->next->prev = match->prev; |
21440 |
++ } |
21441 |
++ match->prev = NULL; |
21442 |
++ match->next = NULL; |
21443 |
++ match->inode = newinode; |
21444 |
++ match->device = newdevice; |
21445 |
++ match->mode &= ~GR_DELETED; |
21446 |
++ |
21447 |
++ insert_acl_subj_label(match, role); |
21448 |
++ } |
21449 |
++ |
21450 |
++ return; |
21451 |
++} |
21452 |
++ |
21453 |
++static void |
21454 |
++update_inodev_entry(const ino_t oldinode, const dev_t olddevice, |
21455 |
++ const ino_t newinode, const dev_t newdevice) |
21456 |
++{ |
21457 |
++ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size); |
21458 |
++ struct inodev_entry *match; |
21459 |
++ |
21460 |
++ match = inodev_set.i_hash[index]; |
21461 |
++ |
21462 |
++ while (match && (match->nentry->inode != oldinode || |
21463 |
++ match->nentry->device != olddevice || !match->nentry->deleted)) |
21464 |
++ match = match->next; |
21465 |
++ |
21466 |
++ if (match && (match->nentry->inode == oldinode) |
21467 |
++ && (match->nentry->device == olddevice) && |
21468 |
++ match->nentry->deleted) { |
21469 |
++ if (match->prev == NULL) { |
21470 |
++ inodev_set.i_hash[index] = match->next; |
21471 |
++ if (match->next != NULL) |
21472 |
++ match->next->prev = NULL; |
21473 |
++ } else { |
21474 |
++ match->prev->next = match->next; |
21475 |
++ if (match->next != NULL) |
21476 |
++ match->next->prev = match->prev; |
21477 |
++ } |
21478 |
++ match->prev = NULL; |
21479 |
++ match->next = NULL; |
21480 |
++ match->nentry->inode = newinode; |
21481 |
++ match->nentry->device = newdevice; |
21482 |
++ match->nentry->deleted = 0; |
21483 |
++ |
21484 |
++ insert_inodev_entry(match); |
21485 |
++ } |
21486 |
++ |
21487 |
++ return; |
21488 |
++} |
21489 |
++ |
21490 |
++static void |
21491 |
++do_handle_create(const struct name_entry *matchn, const struct dentry *dentry, |
21492 |
++ const struct vfsmount *mnt) |
21493 |
++{ |
21494 |
++ struct acl_subject_label *subj; |
21495 |
++ struct acl_role_label *role; |
21496 |
++ unsigned int i, x; |
21497 |
++ |
21498 |
++ FOR_EACH_ROLE_START(role, i) |
21499 |
++ update_acl_subj_label(matchn->inode, matchn->device, |
21500 |
++ dentry->d_inode->i_ino, |
21501 |
++ dentry->d_inode->i_sb->s_dev, role); |
21502 |
++ |
21503 |
++ FOR_EACH_NESTED_SUBJECT_START(role, subj) |
21504 |
++ if ((subj->inode == dentry->d_inode->i_ino) && |
21505 |
++ (subj->device == dentry->d_inode->i_sb->s_dev)) { |
21506 |
++ subj->inode = dentry->d_inode->i_ino; |
21507 |
++ subj->device = dentry->d_inode->i_sb->s_dev; |
21508 |
++ } |
21509 |
++ FOR_EACH_NESTED_SUBJECT_END(subj) |
21510 |
++ FOR_EACH_SUBJECT_START(role, subj, x) |
21511 |
++ update_acl_obj_label(matchn->inode, matchn->device, |
21512 |
++ dentry->d_inode->i_ino, |
21513 |
++ dentry->d_inode->i_sb->s_dev, subj); |
21514 |
++ FOR_EACH_SUBJECT_END(subj,x) |
21515 |
++ FOR_EACH_ROLE_END(role,i) |
21516 |
++ |
21517 |
++ update_inodev_entry(matchn->inode, matchn->device, |
21518 |
++ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev); |
21519 |
++ |
21520 |
++ return; |
21521 |
++} |
21522 |
++ |
21523 |
++void |
21524 |
++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) |
21525 |
++{ |
21526 |
++ struct name_entry *matchn; |
21527 |
++ |
21528 |
++ if (unlikely(!(gr_status & GR_READY))) |
21529 |
++ return; |
21530 |
++ |
21531 |
++ preempt_disable(); |
21532 |
++ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt)); |
21533 |
++ |
21534 |
++ if (unlikely((unsigned long)matchn)) { |
21535 |
++ write_lock(&gr_inode_lock); |
21536 |
++ do_handle_create(matchn, dentry, mnt); |
21537 |
++ write_unlock(&gr_inode_lock); |
21538 |
++ } |
21539 |
++ preempt_enable(); |
21540 |
++ |
21541 |
++ return; |
21542 |
++} |
21543 |
++ |
21544 |
++void |
21545 |
++gr_handle_rename(struct inode *old_dir, struct inode *new_dir, |
21546 |
++ struct dentry *old_dentry, |
21547 |
++ struct dentry *new_dentry, |
21548 |
++ struct vfsmount *mnt, const __u8 replace) |
21549 |
++{ |
21550 |
++ struct name_entry *matchn; |
21551 |
++ struct inodev_entry *inodev; |
21552 |
++ |
21553 |
++ /* vfs_rename swaps the name and parent link for old_dentry and |
21554 |
++ new_dentry |
21555 |
++ at this point, old_dentry has the new name, parent link, and inode |
21556 |
++ for the renamed file |
21557 |
++ if a file is being replaced by a rename, new_dentry has the inode |
21558 |
++ and name for the replaced file |
21559 |
++ */ |
21560 |
++ |
21561 |
++ if (unlikely(!(gr_status & GR_READY))) |
21562 |
++ return; |
21563 |
++ |
21564 |
++ preempt_disable(); |
21565 |
++ matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt)); |
21566 |
++ |
21567 |
++ /* we wouldn't have to check d_inode if it weren't for |
21568 |
++ NFS silly-renaming |
21569 |
++ */ |
21570 |
++ |
21571 |
++ write_lock(&gr_inode_lock); |
21572 |
++ if (unlikely(replace && new_dentry->d_inode)) { |
21573 |
++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino, |
21574 |
++ new_dentry->d_inode->i_sb->s_dev); |
21575 |
++ if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1)) |
21576 |
++ do_handle_delete(inodev, new_dentry->d_inode->i_ino, |
21577 |
++ new_dentry->d_inode->i_sb->s_dev); |
21578 |
++ } |
21579 |
++ |
21580 |
++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino, |
21581 |
++ old_dentry->d_inode->i_sb->s_dev); |
21582 |
++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1)) |
21583 |
++ do_handle_delete(inodev, old_dentry->d_inode->i_ino, |
21584 |
++ old_dentry->d_inode->i_sb->s_dev); |
21585 |
++ |
21586 |
++ if (unlikely((unsigned long)matchn)) |
21587 |
++ do_handle_create(matchn, old_dentry, mnt); |
21588 |
++ |
21589 |
++ write_unlock(&gr_inode_lock); |
21590 |
++ preempt_enable(); |
21591 |
++ |
21592 |
++ return; |
21593 |
++} |
21594 |
++ |
21595 |
++static int |
21596 |
++lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt, |
21597 |
++ unsigned char **sum) |
21598 |
++{ |
21599 |
++ struct acl_role_label *r; |
21600 |
++ struct role_allowed_ip *ipp; |
21601 |
++ struct role_transition *trans; |
21602 |
++ unsigned int i; |
21603 |
++ int found = 0; |
21604 |
++ |
21605 |
++ /* check transition table */ |
21606 |
++ |
21607 |
++ for (trans = current->role->transitions; trans; trans = trans->next) { |
21608 |
++ if (!strcmp(rolename, trans->rolename)) { |
21609 |
++ found = 1; |
21610 |
++ break; |
21611 |
++ } |
21612 |
++ } |
21613 |
++ |
21614 |
++ if (!found) |
21615 |
++ return 0; |
21616 |
++ |
21617 |
++ /* handle special roles that do not require authentication |
21618 |
++ and check ip */ |
21619 |
++ |
21620 |
++ FOR_EACH_ROLE_START(r, i) |
21621 |
++ if (!strcmp(rolename, r->rolename) && |
21622 |
++ (r->roletype & GR_ROLE_SPECIAL)) { |
21623 |
++ found = 0; |
21624 |
++ if (r->allowed_ips != NULL) { |
21625 |
++ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) { |
21626 |
++ if ((ntohl(current->signal->curr_ip) & ipp->netmask) == |
21627 |
++ (ntohl(ipp->addr) & ipp->netmask)) |
21628 |
++ found = 1; |
21629 |
++ } |
21630 |
++ } else |
21631 |
++ found = 2; |
21632 |
++ if (!found) |
21633 |
++ return 0; |
21634 |
++ |
21635 |
++ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) || |
21636 |
++ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) { |
21637 |
++ *salt = NULL; |
21638 |
++ *sum = NULL; |
21639 |
++ return 1; |
21640 |
++ } |
21641 |
++ } |
21642 |
++ FOR_EACH_ROLE_END(r,i) |
21643 |
++ |
21644 |
++ for (i = 0; i < num_sprole_pws; i++) { |
21645 |
++ if (!strcmp(rolename, acl_special_roles[i]->rolename)) { |
21646 |
++ *salt = acl_special_roles[i]->salt; |
21647 |
++ *sum = acl_special_roles[i]->sum; |
21648 |
++ return 1; |
21649 |
++ } |
21650 |
++ } |
21651 |
++ |
21652 |
++ return 0; |
21653 |
++} |
21654 |
++ |
21655 |
++static void |
21656 |
++assign_special_role(char *rolename) |
21657 |
++{ |
21658 |
++ struct acl_object_label *obj; |
21659 |
++ struct acl_role_label *r; |
21660 |
++ struct acl_role_label *assigned = NULL; |
21661 |
++ struct task_struct *tsk; |
21662 |
++ struct file *filp; |
21663 |
++ unsigned int i; |
21664 |
++ |
21665 |
++ FOR_EACH_ROLE_START(r, i) |
21666 |
++ if (!strcmp(rolename, r->rolename) && |
21667 |
++ (r->roletype & GR_ROLE_SPECIAL)) |
21668 |
++ assigned = r; |
21669 |
++ FOR_EACH_ROLE_END(r,i) |
21670 |
++ |
21671 |
++ if (!assigned) |
21672 |
++ return; |
21673 |
++ |
21674 |
++ read_lock(&tasklist_lock); |
21675 |
++ read_lock(&grsec_exec_file_lock); |
21676 |
++ |
21677 |
++ tsk = current->parent; |
21678 |
++ if (tsk == NULL) |
21679 |
++ goto out_unlock; |
21680 |
++ |
21681 |
++ filp = tsk->exec_file; |
21682 |
++ if (filp == NULL) |
21683 |
++ goto out_unlock; |
21684 |
++ |
21685 |
++ tsk->is_writable = 0; |
21686 |
++ |
21687 |
++ tsk->acl_sp_role = 1; |
21688 |
++ tsk->acl_role_id = ++acl_sp_role_value; |
21689 |
++ tsk->role = assigned; |
21690 |
++ tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role); |
21691 |
++ |
21692 |
++ /* ignore additional mmap checks for processes that are writable |
21693 |
++ by the default ACL */ |
21694 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
21695 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21696 |
++ tsk->is_writable = 1; |
21697 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label); |
21698 |
++ if (unlikely(obj->mode & GR_WRITE)) |
21699 |
++ tsk->is_writable = 1; |
21700 |
++ |
21701 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
21702 |
++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid); |
21703 |
++#endif |
21704 |
++ |
21705 |
++out_unlock: |
21706 |
++ read_unlock(&grsec_exec_file_lock); |
21707 |
++ read_unlock(&tasklist_lock); |
21708 |
++ return; |
21709 |
++} |
21710 |
++ |
21711 |
++int gr_check_secure_terminal(struct task_struct *task) |
21712 |
++{ |
21713 |
++ struct task_struct *p, *p2, *p3; |
21714 |
++ struct files_struct *files; |
21715 |
++ struct fdtable *fdt; |
21716 |
++ struct file *our_file = NULL, *file; |
21717 |
++ int i; |
21718 |
++ |
21719 |
++ if (task->signal->tty == NULL) |
21720 |
++ return 1; |
21721 |
++ |
21722 |
++ files = get_files_struct(task); |
21723 |
++ if (files != NULL) { |
21724 |
++ rcu_read_lock(); |
21725 |
++ fdt = files_fdtable(files); |
21726 |
++ for (i=0; i < fdt->max_fds; i++) { |
21727 |
++ file = fcheck_files(files, i); |
21728 |
++ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) { |
21729 |
++ get_file(file); |
21730 |
++ our_file = file; |
21731 |
++ } |
21732 |
++ } |
21733 |
++ rcu_read_unlock(); |
21734 |
++ put_files_struct(files); |
21735 |
++ } |
21736 |
++ |
21737 |
++ if (our_file == NULL) |
21738 |
++ return 1; |
21739 |
++ |
21740 |
++ read_lock(&tasklist_lock); |
21741 |
++ do_each_thread(p2, p) { |
21742 |
++ files = get_files_struct(p); |
21743 |
++ if (files == NULL || |
21744 |
++ (p->signal && p->signal->tty == task->signal->tty)) { |
21745 |
++ if (files != NULL) |
21746 |
++ put_files_struct(files); |
21747 |
++ continue; |
21748 |
++ } |
21749 |
++ rcu_read_lock(); |
21750 |
++ fdt = files_fdtable(files); |
21751 |
++ for (i=0; i < fdt->max_fds; i++) { |
21752 |
++ file = fcheck_files(files, i); |
21753 |
++ if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) && |
21754 |
++ file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) { |
21755 |
++ p3 = task; |
21756 |
++ while (p3->pid > 0) { |
21757 |
++ if (p3 == p) |
21758 |
++ break; |
21759 |
++ p3 = p3->parent; |
21760 |
++ } |
21761 |
++ if (p3 == p) |
21762 |
++ break; |
21763 |
++ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p); |
21764 |
++ gr_handle_alertkill(p); |
21765 |
++ rcu_read_unlock(); |
21766 |
++ put_files_struct(files); |
21767 |
++ read_unlock(&tasklist_lock); |
21768 |
++ fput(our_file); |
21769 |
++ return 0; |
21770 |
++ } |
21771 |
++ } |
21772 |
++ rcu_read_unlock(); |
21773 |
++ put_files_struct(files); |
21774 |
++ } while_each_thread(p2, p); |
21775 |
++ read_unlock(&tasklist_lock); |
21776 |
++ |
21777 |
++ fput(our_file); |
21778 |
++ return 1; |
21779 |
++} |
21780 |
++ |
21781 |
++ssize_t |
21782 |
++write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos) |
21783 |
++{ |
21784 |
++ struct gr_arg_wrapper uwrap; |
21785 |
++ unsigned char *sprole_salt; |
21786 |
++ unsigned char *sprole_sum; |
21787 |
++ int error = sizeof (struct gr_arg_wrapper); |
21788 |
++ int error2 = 0; |
21789 |
++ |
21790 |
++ down(&gr_dev_sem); |
21791 |
++ |
21792 |
++ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) { |
21793 |
++ error = -EPERM; |
21794 |
++ goto out; |
21795 |
++ } |
21796 |
++ |
21797 |
++ if (count != sizeof (struct gr_arg_wrapper)) { |
21798 |
++ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper)); |
21799 |
++ error = -EINVAL; |
21800 |
++ goto out; |
21801 |
++ } |
21802 |
++ |
21803 |
++ |
21804 |
++ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) { |
21805 |
++ gr_auth_expires = 0; |
21806 |
++ gr_auth_attempts = 0; |
21807 |
++ } |
21808 |
++ |
21809 |
++ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) { |
21810 |
++ error = -EFAULT; |
21811 |
++ goto out; |
21812 |
++ } |
21813 |
++ |
21814 |
++ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) { |
21815 |
++ error = -EINVAL; |
21816 |
++ goto out; |
21817 |
++ } |
21818 |
++ |
21819 |
++ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) { |
21820 |
++ error = -EFAULT; |
21821 |
++ goto out; |
21822 |
++ } |
21823 |
++ |
21824 |
++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM && |
21825 |
++ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES && |
21826 |
++ time_after(gr_auth_expires, get_seconds())) { |
21827 |
++ error = -EBUSY; |
21828 |
++ goto out; |
21829 |
++ } |
21830 |
++ |
21831 |
++ /* if non-root trying to do anything other than use a special role, |
21832 |
++ do not attempt authentication, do not count towards authentication |
21833 |
++ locking |
21834 |
++ */ |
21835 |
++ |
21836 |
++ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS && |
21837 |
++ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM && |
21838 |
++ current->uid) { |
21839 |
++ error = -EPERM; |
21840 |
++ goto out; |
21841 |
++ } |
21842 |
++ |
21843 |
++ /* ensure pw and special role name are null terminated */ |
21844 |
++ |
21845 |
++ gr_usermode->pw[GR_PW_LEN - 1] = '\0'; |
21846 |
++ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0'; |
21847 |
++ |
21848 |
++ /* Okay. |
21849 |
++ * We have our enough of the argument structure..(we have yet |
21850 |
++ * to copy_from_user the tables themselves) . Copy the tables |
21851 |
++ * only if we need them, i.e. for loading operations. */ |
21852 |
++ |
21853 |
++ switch (gr_usermode->mode) { |
21854 |
++ case STATUS: |
21855 |
++ if (gr_status & GR_READY) { |
21856 |
++ error = 1; |
21857 |
++ if (!gr_check_secure_terminal(current)) |
21858 |
++ error = 3; |
21859 |
++ } else |
21860 |
++ error = 2; |
21861 |
++ goto out; |
21862 |
++ case SHUTDOWN: |
21863 |
++ if ((gr_status & GR_READY) |
21864 |
++ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { |
21865 |
++ gr_status &= ~GR_READY; |
21866 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG); |
21867 |
++ free_variables(); |
21868 |
++ memset(gr_usermode, 0, sizeof (struct gr_arg)); |
21869 |
++ memset(gr_system_salt, 0, GR_SALT_LEN); |
21870 |
++ memset(gr_system_sum, 0, GR_SHA_LEN); |
21871 |
++ } else if (gr_status & GR_READY) { |
21872 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG); |
21873 |
++ error = -EPERM; |
21874 |
++ } else { |
21875 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG); |
21876 |
++ error = -EAGAIN; |
21877 |
++ } |
21878 |
++ break; |
21879 |
++ case ENABLE: |
21880 |
++ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode))) |
21881 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION); |
21882 |
++ else { |
21883 |
++ if (gr_status & GR_READY) |
21884 |
++ error = -EAGAIN; |
21885 |
++ else |
21886 |
++ error = error2; |
21887 |
++ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION); |
21888 |
++ } |
21889 |
++ break; |
21890 |
++ case RELOAD: |
21891 |
++ if (!(gr_status & GR_READY)) { |
21892 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION); |
21893 |
++ error = -EAGAIN; |
21894 |
++ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { |
21895 |
++ lock_kernel(); |
21896 |
++ gr_status &= ~GR_READY; |
21897 |
++ free_variables(); |
21898 |
++ if (!(error2 = gracl_init(gr_usermode))) { |
21899 |
++ unlock_kernel(); |
21900 |
++ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION); |
21901 |
++ } else { |
21902 |
++ unlock_kernel(); |
21903 |
++ error = error2; |
21904 |
++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION); |
21905 |
++ } |
21906 |
++ } else { |
21907 |
++ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION); |
21908 |
++ error = -EPERM; |
21909 |
++ } |
21910 |
++ break; |
21911 |
++ case SEGVMOD: |
21912 |
++ if (unlikely(!(gr_status & GR_READY))) { |
21913 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG); |
21914 |
++ error = -EAGAIN; |
21915 |
++ break; |
21916 |
++ } |
21917 |
++ |
21918 |
++ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { |
21919 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG); |
21920 |
++ if (gr_usermode->segv_device && gr_usermode->segv_inode) { |
21921 |
++ struct acl_subject_label *segvacl; |
21922 |
++ segvacl = |
21923 |
++ lookup_acl_subj_label(gr_usermode->segv_inode, |
21924 |
++ gr_usermode->segv_device, |
21925 |
++ current->role); |
21926 |
++ if (segvacl) { |
21927 |
++ segvacl->crashes = 0; |
21928 |
++ segvacl->expires = 0; |
21929 |
++ } |
21930 |
++ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) { |
21931 |
++ gr_remove_uid(gr_usermode->segv_uid); |
21932 |
++ } |
21933 |
++ } else { |
21934 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG); |
21935 |
++ error = -EPERM; |
21936 |
++ } |
21937 |
++ break; |
21938 |
++ case SPROLE: |
21939 |
++ case SPROLEPAM: |
21940 |
++ if (unlikely(!(gr_status & GR_READY))) { |
21941 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG); |
21942 |
++ error = -EAGAIN; |
21943 |
++ break; |
21944 |
++ } |
21945 |
++ |
21946 |
++ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) { |
21947 |
++ current->role->expires = 0; |
21948 |
++ current->role->auth_attempts = 0; |
21949 |
++ } |
21950 |
++ |
21951 |
++ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES && |
21952 |
++ time_after(current->role->expires, get_seconds())) { |
21953 |
++ error = -EBUSY; |
21954 |
++ goto out; |
21955 |
++ } |
21956 |
++ |
21957 |
++ if (lookup_special_role_auth |
21958 |
++ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum) |
21959 |
++ && ((!sprole_salt && !sprole_sum) |
21960 |
++ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) { |
21961 |
++ char *p = ""; |
21962 |
++ assign_special_role(gr_usermode->sp_role); |
21963 |
++ read_lock(&tasklist_lock); |
21964 |
++ if (current->parent) |
21965 |
++ p = current->parent->role->rolename; |
21966 |
++ read_unlock(&tasklist_lock); |
21967 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG, |
21968 |
++ p, acl_sp_role_value); |
21969 |
++ } else { |
21970 |
++ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role); |
21971 |
++ error = -EPERM; |
21972 |
++ if(!(current->role->auth_attempts++)) |
21973 |
++ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT; |
21974 |
++ |
21975 |
++ goto out; |
21976 |
++ } |
21977 |
++ break; |
21978 |
++ case UNSPROLE: |
21979 |
++ if (unlikely(!(gr_status & GR_READY))) { |
21980 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG); |
21981 |
++ error = -EAGAIN; |
21982 |
++ break; |
21983 |
++ } |
21984 |
++ |
21985 |
++ if (current->role->roletype & GR_ROLE_SPECIAL) { |
21986 |
++ char *p = ""; |
21987 |
++ int i = 0; |
21988 |
++ |
21989 |
++ read_lock(&tasklist_lock); |
21990 |
++ if (current->parent) { |
21991 |
++ p = current->parent->role->rolename; |
21992 |
++ i = current->parent->acl_role_id; |
21993 |
++ } |
21994 |
++ read_unlock(&tasklist_lock); |
21995 |
++ |
21996 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i); |
21997 |
++ gr_set_acls(1); |
21998 |
++ } else { |
21999 |
++ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename); |
22000 |
++ error = -EPERM; |
22001 |
++ goto out; |
22002 |
++ } |
22003 |
++ break; |
22004 |
++ default: |
22005 |
++ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode); |
22006 |
++ error = -EINVAL; |
22007 |
++ break; |
22008 |
++ } |
22009 |
++ |
22010 |
++ if (error != -EPERM) |
22011 |
++ goto out; |
22012 |
++ |
22013 |
++ if(!(gr_auth_attempts++)) |
22014 |
++ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT; |
22015 |
++ |
22016 |
++ out: |
22017 |
++ up(&gr_dev_sem); |
22018 |
++ return error; |
22019 |
++} |
22020 |
++ |
22021 |
++int |
22022 |
++gr_set_acls(const int type) |
22023 |
++{ |
22024 |
++ struct acl_object_label *obj; |
22025 |
++ struct task_struct *task, *task2; |
22026 |
++ struct file *filp; |
22027 |
++ struct acl_role_label *role = current->role; |
22028 |
++ __u16 acl_role_id = current->acl_role_id; |
22029 |
++ |
22030 |
++ read_lock(&tasklist_lock); |
22031 |
++ read_lock(&grsec_exec_file_lock); |
22032 |
++ do_each_thread(task2, task) { |
22033 |
++ /* check to see if we're called from the exit handler, |
22034 |
++ if so, only replace ACLs that have inherited the admin |
22035 |
++ ACL */ |
22036 |
++ |
22037 |
++ if (type && (task->role != role || |
22038 |
++ task->acl_role_id != acl_role_id)) |
22039 |
++ continue; |
22040 |
++ |
22041 |
++ task->acl_role_id = 0; |
22042 |
++ task->acl_sp_role = 0; |
22043 |
++ |
22044 |
++ if ((filp = task->exec_file)) { |
22045 |
++ task->role = lookup_acl_role_label(task, task->uid, task->gid); |
22046 |
++ |
22047 |
++ task->acl = |
22048 |
++ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, |
22049 |
++ task->role); |
22050 |
++ if (task->acl) { |
22051 |
++ struct acl_subject_label *curr; |
22052 |
++ curr = task->acl; |
22053 |
++ |
22054 |
++ task->is_writable = 0; |
22055 |
++ /* ignore additional mmap checks for processes that are writable |
22056 |
++ by the default ACL */ |
22057 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
22058 |
++ if (unlikely(obj->mode & GR_WRITE)) |
22059 |
++ task->is_writable = 1; |
22060 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label); |
22061 |
++ if (unlikely(obj->mode & GR_WRITE)) |
22062 |
++ task->is_writable = 1; |
22063 |
++ |
22064 |
++ gr_set_proc_res(task); |
22065 |
++ |
22066 |
++#ifdef CONFIG_GRKERNSEC_ACL_DEBUG |
22067 |
++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); |
22068 |
++#endif |
22069 |
++ } else { |
22070 |
++ read_unlock(&grsec_exec_file_lock); |
22071 |
++ read_unlock(&tasklist_lock); |
22072 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid); |
22073 |
++ return 1; |
22074 |
++ } |
22075 |
++ } else { |
22076 |
++ // it's a kernel process |
22077 |
++ task->role = kernel_role; |
22078 |
++ task->acl = kernel_role->root_label; |
22079 |
++#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN |
22080 |
++ task->acl->mode &= ~GR_PROCFIND; |
22081 |
++#endif |
22082 |
++ } |
22083 |
++ } while_each_thread(task2, task); |
22084 |
++ read_unlock(&grsec_exec_file_lock); |
22085 |
++ read_unlock(&tasklist_lock); |
22086 |
++ return 0; |
22087 |
++} |
22088 |
++ |
22089 |
++void |
22090 |
++gr_learn_resource(const struct task_struct *task, |
22091 |
++ const int res, const unsigned long wanted, const int gt) |
22092 |
++{ |
22093 |
++ struct acl_subject_label *acl; |
22094 |
++ |
22095 |
++ if (unlikely((gr_status & GR_READY) && |
22096 |
++ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN)))) |
22097 |
++ goto skip_reslog; |
22098 |
++ |
22099 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
22100 |
++ gr_log_resource(task, res, wanted, gt); |
22101 |
++#endif |
22102 |
++ skip_reslog: |
22103 |
++ |
22104 |
++ if (unlikely(!(gr_status & GR_READY) || !wanted)) |
22105 |
++ return; |
22106 |
++ |
22107 |
++ acl = task->acl; |
22108 |
++ |
22109 |
++ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) || |
22110 |
++ !(acl->resmask & (1 << (unsigned short) res)))) |
22111 |
++ return; |
22112 |
++ |
22113 |
++ if (wanted >= acl->res[res].rlim_cur) { |
22114 |
++ unsigned long res_add; |
22115 |
++ |
22116 |
++ res_add = wanted; |
22117 |
++ switch (res) { |
22118 |
++ case RLIMIT_CPU: |
22119 |
++ res_add += GR_RLIM_CPU_BUMP; |
22120 |
++ break; |
22121 |
++ case RLIMIT_FSIZE: |
22122 |
++ res_add += GR_RLIM_FSIZE_BUMP; |
22123 |
++ break; |
22124 |
++ case RLIMIT_DATA: |
22125 |
++ res_add += GR_RLIM_DATA_BUMP; |
22126 |
++ break; |
22127 |
++ case RLIMIT_STACK: |
22128 |
++ res_add += GR_RLIM_STACK_BUMP; |
22129 |
++ break; |
22130 |
++ case RLIMIT_CORE: |
22131 |
++ res_add += GR_RLIM_CORE_BUMP; |
22132 |
++ break; |
22133 |
++ case RLIMIT_RSS: |
22134 |
++ res_add += GR_RLIM_RSS_BUMP; |
22135 |
++ break; |
22136 |
++ case RLIMIT_NPROC: |
22137 |
++ res_add += GR_RLIM_NPROC_BUMP; |
22138 |
++ break; |
22139 |
++ case RLIMIT_NOFILE: |
22140 |
++ res_add += GR_RLIM_NOFILE_BUMP; |
22141 |
++ break; |
22142 |
++ case RLIMIT_MEMLOCK: |
22143 |
++ res_add += GR_RLIM_MEMLOCK_BUMP; |
22144 |
++ break; |
22145 |
++ case RLIMIT_AS: |
22146 |
++ res_add += GR_RLIM_AS_BUMP; |
22147 |
++ break; |
22148 |
++ case RLIMIT_LOCKS: |
22149 |
++ res_add += GR_RLIM_LOCKS_BUMP; |
22150 |
++ break; |
22151 |
++ } |
22152 |
++ |
22153 |
++ acl->res[res].rlim_cur = res_add; |
22154 |
++ |
22155 |
++ if (wanted > acl->res[res].rlim_max) |
22156 |
++ acl->res[res].rlim_max = res_add; |
22157 |
++ |
22158 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, |
22159 |
++ task->role->roletype, acl->filename, |
22160 |
++ acl->res[res].rlim_cur, acl->res[res].rlim_max, |
22161 |
++ "", (unsigned long) res); |
22162 |
++ } |
22163 |
++ |
22164 |
++ return; |
22165 |
++} |
22166 |
++ |
22167 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
22168 |
++void |
22169 |
++pax_set_initial_flags(struct linux_binprm *bprm) |
22170 |
++{ |
22171 |
++ struct task_struct *task = current; |
22172 |
++ struct acl_subject_label *proc; |
22173 |
++ unsigned long flags; |
22174 |
++ |
22175 |
++ if (unlikely(!(gr_status & GR_READY))) |
22176 |
++ return; |
22177 |
++ |
22178 |
++ flags = pax_get_flags(task); |
22179 |
++ |
22180 |
++ proc = task->acl; |
22181 |
++ |
22182 |
++ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC) |
22183 |
++ flags &= ~MF_PAX_PAGEEXEC; |
22184 |
++ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC) |
22185 |
++ flags &= ~MF_PAX_SEGMEXEC; |
22186 |
++ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP) |
22187 |
++ flags &= ~MF_PAX_RANDMMAP; |
22188 |
++ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP) |
22189 |
++ flags &= ~MF_PAX_EMUTRAMP; |
22190 |
++ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT) |
22191 |
++ flags &= ~MF_PAX_MPROTECT; |
22192 |
++ |
22193 |
++ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC) |
22194 |
++ flags |= MF_PAX_PAGEEXEC; |
22195 |
++ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC) |
22196 |
++ flags |= MF_PAX_SEGMEXEC; |
22197 |
++ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP) |
22198 |
++ flags |= MF_PAX_RANDMMAP; |
22199 |
++ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP) |
22200 |
++ flags |= MF_PAX_EMUTRAMP; |
22201 |
++ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT) |
22202 |
++ flags |= MF_PAX_MPROTECT; |
22203 |
++ |
22204 |
++ pax_set_flags(task, flags); |
22205 |
++ |
22206 |
++ return; |
22207 |
++} |
22208 |
++#endif |
22209 |
++ |
22210 |
++#ifdef CONFIG_SYSCTL |
22211 |
++/* Eric Biederman likes breaking userland ABI and every inode-based security |
22212 |
++ system to save 35kb of memory */ |
22213 |
++ |
22214 |
++/* we modify the passed in filename, but adjust it back before returning */ |
22215 |
++static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len) |
22216 |
++{ |
22217 |
++ struct name_entry *nmatch; |
22218 |
++ char *p, *lastp = NULL; |
22219 |
++ struct acl_object_label *obj = NULL, *tmp; |
22220 |
++ struct acl_subject_label *tmpsubj; |
22221 |
++ int done = 0; |
22222 |
++ char c = '\0'; |
22223 |
++ |
22224 |
++ read_lock(&gr_inode_lock); |
22225 |
++ |
22226 |
++ p = name + len - 1; |
22227 |
++ do { |
22228 |
++ nmatch = lookup_name_entry(name); |
22229 |
++ if (lastp != NULL) |
22230 |
++ *lastp = c; |
22231 |
++ |
22232 |
++ if (nmatch == NULL) |
22233 |
++ goto next_component; |
22234 |
++ tmpsubj = current->acl; |
22235 |
++ do { |
22236 |
++ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj); |
22237 |
++ if (obj != NULL) { |
22238 |
++ tmp = obj->globbed; |
22239 |
++ while (tmp) { |
22240 |
++ if (!glob_match(tmp->filename, name)) { |
22241 |
++ obj = tmp; |
22242 |
++ goto found_obj; |
22243 |
++ } |
22244 |
++ tmp = tmp->next; |
22245 |
++ } |
22246 |
++ goto found_obj; |
22247 |
++ } |
22248 |
++ } while ((tmpsubj = tmpsubj->parent_subject)); |
22249 |
++next_component: |
22250 |
++ /* end case */ |
22251 |
++ if (p == name) |
22252 |
++ break; |
22253 |
++ |
22254 |
++ while (*p != '/') |
22255 |
++ p--; |
22256 |
++ if (p == name) |
22257 |
++ lastp = p + 1; |
22258 |
++ else { |
22259 |
++ lastp = p; |
22260 |
++ p--; |
22261 |
++ } |
22262 |
++ c = *lastp; |
22263 |
++ *lastp = '\0'; |
22264 |
++ } while (1); |
22265 |
++found_obj: |
22266 |
++ read_unlock(&gr_inode_lock); |
22267 |
++ /* obj returned will always be non-null */ |
22268 |
++ return obj; |
22269 |
++} |
22270 |
++ |
22271 |
++/* returns 0 when allowing, non-zero on error |
22272 |
++ op of 0 is used for readdir, so we don't log the names of hidden files |
22273 |
++*/ |
22274 |
++__u32 |
22275 |
++gr_handle_sysctl(const struct ctl_table *table, const int op) |
22276 |
++{ |
22277 |
++ ctl_table *tmp; |
22278 |
++ struct nameidata nd; |
22279 |
++ const char *proc_sys = "/proc/sys"; |
22280 |
++ char *path; |
22281 |
++ struct acl_object_label *obj; |
22282 |
++ unsigned short len = 0, pos = 0, depth = 0, i; |
22283 |
++ __u32 err = 0; |
22284 |
++ __u32 mode = 0; |
22285 |
++ |
22286 |
++ if (unlikely(!(gr_status & GR_READY))) |
22287 |
++ return 0; |
22288 |
++ |
22289 |
++ /* for now, ignore operations on non-sysctl entries if it's not a |
22290 |
++ readdir*/ |
22291 |
++ if (table->child != NULL && op != 0) |
22292 |
++ return 0; |
22293 |
++ |
22294 |
++ mode |= GR_FIND; |
22295 |
++ /* it's only a read if it's an entry, read on dirs is for readdir */ |
22296 |
++ if (op & 004) |
22297 |
++ mode |= GR_READ; |
22298 |
++ if (op & 002) |
22299 |
++ mode |= GR_WRITE; |
22300 |
++ |
22301 |
++ preempt_disable(); |
22302 |
++ |
22303 |
++ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id()); |
22304 |
++ |
22305 |
++ /* it's only a read/write if it's an actual entry, not a dir |
22306 |
++ (which are opened for readdir) |
22307 |
++ */ |
22308 |
++ |
22309 |
++ /* convert the requested sysctl entry into a pathname */ |
22310 |
++ |
22311 |
++ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) { |
22312 |
++ len += strlen(tmp->procname); |
22313 |
++ len++; |
22314 |
++ depth++; |
22315 |
++ } |
22316 |
++ |
22317 |
++ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) { |
22318 |
++ /* deny */ |
22319 |
++ goto out; |
22320 |
++ } |
22321 |
++ |
22322 |
++ memset(path, 0, PAGE_SIZE); |
22323 |
++ |
22324 |
++ memcpy(path, proc_sys, strlen(proc_sys)); |
22325 |
++ |
22326 |
++ pos += strlen(proc_sys); |
22327 |
++ |
22328 |
++ for (; depth > 0; depth--) { |
22329 |
++ path[pos] = '/'; |
22330 |
++ pos++; |
22331 |
++ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) { |
22332 |
++ if (depth == i) { |
22333 |
++ memcpy(path + pos, tmp->procname, |
22334 |
++ strlen(tmp->procname)); |
22335 |
++ pos += strlen(tmp->procname); |
22336 |
++ } |
22337 |
++ i++; |
22338 |
++ } |
22339 |
++ } |
22340 |
++ |
22341 |
++ obj = gr_lookup_by_name(path, pos); |
22342 |
++ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS); |
22343 |
++ |
22344 |
++ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) && |
22345 |
++ ((err & mode) != mode))) { |
22346 |
++ __u32 new_mode = mode; |
22347 |
++ |
22348 |
++ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); |
22349 |
++ |
22350 |
++ err = 0; |
22351 |
++ gr_log_learn_sysctl(current, path, new_mode); |
22352 |
++ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) { |
22353 |
++ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path); |
22354 |
++ err = -ENOENT; |
22355 |
++ } else if (!(err & GR_FIND)) { |
22356 |
++ err = -ENOENT; |
22357 |
++ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) { |
22358 |
++ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied", |
22359 |
++ path, (mode & GR_READ) ? " reading" : "", |
22360 |
++ (mode & GR_WRITE) ? " writing" : ""); |
22361 |
++ err = -EACCES; |
22362 |
++ } else if ((err & mode) != mode) { |
22363 |
++ err = -EACCES; |
22364 |
++ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) { |
22365 |
++ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful", |
22366 |
++ path, (mode & GR_READ) ? " reading" : "", |
22367 |
++ (mode & GR_WRITE) ? " writing" : ""); |
22368 |
++ err = 0; |
22369 |
++ } else |
22370 |
++ err = 0; |
22371 |
++ |
22372 |
++ out: |
22373 |
++ preempt_enable(); |
22374 |
++ |
22375 |
++ return err; |
22376 |
++} |
22377 |
++#endif |
22378 |
++ |
22379 |
++int |
22380 |
++gr_handle_proc_ptrace(struct task_struct *task) |
22381 |
++{ |
22382 |
++ struct file *filp; |
22383 |
++ struct task_struct *tmp = task; |
22384 |
++ struct task_struct *curtemp = current; |
22385 |
++ __u32 retmode; |
22386 |
++ |
22387 |
++ if (unlikely(!(gr_status & GR_READY))) |
22388 |
++ return 0; |
22389 |
++ |
22390 |
++ read_lock(&tasklist_lock); |
22391 |
++ read_lock(&grsec_exec_file_lock); |
22392 |
++ filp = task->exec_file; |
22393 |
++ |
22394 |
++ while (tmp->pid > 0) { |
22395 |
++ if (tmp == curtemp) |
22396 |
++ break; |
22397 |
++ tmp = tmp->parent; |
22398 |
++ } |
22399 |
++ |
22400 |
++ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) { |
22401 |
++ read_unlock(&grsec_exec_file_lock); |
22402 |
++ read_unlock(&tasklist_lock); |
22403 |
++ return 1; |
22404 |
++ } |
22405 |
++ |
22406 |
++ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt); |
22407 |
++ read_unlock(&grsec_exec_file_lock); |
22408 |
++ read_unlock(&tasklist_lock); |
22409 |
++ |
22410 |
++ if (retmode & GR_NOPTRACE) |
22411 |
++ return 1; |
22412 |
++ |
22413 |
++ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD) |
22414 |
++ && (current->acl != task->acl || (current->acl != current->role->root_label |
22415 |
++ && current->pid != task->pid))) |
22416 |
++ return 1; |
22417 |
++ |
22418 |
++ return 0; |
22419 |
++} |
22420 |
++ |
22421 |
++int |
22422 |
++gr_handle_ptrace(struct task_struct *task, const long request) |
22423 |
++{ |
22424 |
++ struct task_struct *tmp = task; |
22425 |
++ struct task_struct *curtemp = current; |
22426 |
++ __u32 retmode; |
22427 |
++ |
22428 |
++ if (unlikely(!(gr_status & GR_READY))) |
22429 |
++ return 0; |
22430 |
++ |
22431 |
++ read_lock(&tasklist_lock); |
22432 |
++ while (tmp->pid > 0) { |
22433 |
++ if (tmp == curtemp) |
22434 |
++ break; |
22435 |
++ tmp = tmp->parent; |
22436 |
++ } |
22437 |
++ |
22438 |
++ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) { |
22439 |
++ read_unlock(&tasklist_lock); |
22440 |
++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); |
22441 |
++ return 1; |
22442 |
++ } |
22443 |
++ read_unlock(&tasklist_lock); |
22444 |
++ |
22445 |
++ read_lock(&grsec_exec_file_lock); |
22446 |
++ if (unlikely(!task->exec_file)) { |
22447 |
++ read_unlock(&grsec_exec_file_lock); |
22448 |
++ return 0; |
22449 |
++ } |
22450 |
++ |
22451 |
++ retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt); |
22452 |
++ read_unlock(&grsec_exec_file_lock); |
22453 |
++ |
22454 |
++ if (retmode & GR_NOPTRACE) { |
22455 |
++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); |
22456 |
++ return 1; |
22457 |
++ } |
22458 |
++ |
22459 |
++ if (retmode & GR_PTRACERD) { |
22460 |
++ switch (request) { |
22461 |
++ case PTRACE_POKETEXT: |
22462 |
++ case PTRACE_POKEDATA: |
22463 |
++ case PTRACE_POKEUSR: |
22464 |
++#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) |
22465 |
++ case PTRACE_SETREGS: |
22466 |
++ case PTRACE_SETFPREGS: |
22467 |
++#endif |
22468 |
++#ifdef CONFIG_X86 |
22469 |
++ case PTRACE_SETFPXREGS: |
22470 |
++#endif |
22471 |
++#ifdef CONFIG_ALTIVEC |
22472 |
++ case PTRACE_SETVRREGS: |
22473 |
++#endif |
22474 |
++ return 1; |
22475 |
++ default: |
22476 |
++ return 0; |
22477 |
++ } |
22478 |
++ } else if (!(current->acl->mode & GR_POVERRIDE) && |
22479 |
++ !(current->role->roletype & GR_ROLE_GOD) && |
22480 |
++ (current->acl != task->acl)) { |
22481 |
++ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); |
22482 |
++ return 1; |
22483 |
++ } |
22484 |
++ |
22485 |
++ return 0; |
22486 |
++} |
22487 |
++ |
22488 |
++static int is_writable_mmap(const struct file *filp) |
22489 |
++{ |
22490 |
++ struct task_struct *task = current; |
22491 |
++ struct acl_object_label *obj, *obj2; |
22492 |
++ |
22493 |
++ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) && |
22494 |
++ !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) { |
22495 |
++ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); |
22496 |
++ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, |
22497 |
++ task->role->root_label); |
22498 |
++ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) { |
22499 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt); |
22500 |
++ return 1; |
22501 |
++ } |
22502 |
++ } |
22503 |
++ return 0; |
22504 |
++} |
22505 |
++ |
22506 |
++int |
22507 |
++gr_acl_handle_mmap(const struct file *file, const unsigned long prot) |
22508 |
++{ |
22509 |
++ __u32 mode; |
22510 |
++ |
22511 |
++ if (unlikely(!file || !(prot & PROT_EXEC))) |
22512 |
++ return 1; |
22513 |
++ |
22514 |
++ if (is_writable_mmap(file)) |
22515 |
++ return 0; |
22516 |
++ |
22517 |
++ mode = |
22518 |
++ gr_search_file(file->f_dentry, |
22519 |
++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, |
22520 |
++ file->f_vfsmnt); |
22521 |
++ |
22522 |
++ if (!gr_tpe_allow(file)) |
22523 |
++ return 0; |
22524 |
++ |
22525 |
++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) { |
22526 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22527 |
++ return 0; |
22528 |
++ } else if (unlikely(!(mode & GR_EXEC))) { |
22529 |
++ return 0; |
22530 |
++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { |
22531 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22532 |
++ return 1; |
22533 |
++ } |
22534 |
++ |
22535 |
++ return 1; |
22536 |
++} |
22537 |
++ |
22538 |
++int |
22539 |
++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) |
22540 |
++{ |
22541 |
++ __u32 mode; |
22542 |
++ |
22543 |
++ if (unlikely(!file || !(prot & PROT_EXEC))) |
22544 |
++ return 1; |
22545 |
++ |
22546 |
++ if (is_writable_mmap(file)) |
22547 |
++ return 0; |
22548 |
++ |
22549 |
++ mode = |
22550 |
++ gr_search_file(file->f_dentry, |
22551 |
++ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, |
22552 |
++ file->f_vfsmnt); |
22553 |
++ |
22554 |
++ if (!gr_tpe_allow(file)) |
22555 |
++ return 0; |
22556 |
++ |
22557 |
++ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) { |
22558 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22559 |
++ return 0; |
22560 |
++ } else if (unlikely(!(mode & GR_EXEC))) { |
22561 |
++ return 0; |
22562 |
++ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { |
22563 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt); |
22564 |
++ return 1; |
22565 |
++ } |
22566 |
++ |
22567 |
++ return 1; |
22568 |
++} |
22569 |
++ |
22570 |
++void |
22571 |
++gr_acl_handle_psacct(struct task_struct *task, const long code) |
22572 |
++{ |
22573 |
++ unsigned long runtime; |
22574 |
++ unsigned long cputime; |
22575 |
++ unsigned int wday, cday; |
22576 |
++ __u8 whr, chr; |
22577 |
++ __u8 wmin, cmin; |
22578 |
++ __u8 wsec, csec; |
22579 |
++ |
22580 |
++ if (unlikely(!(gr_status & GR_READY) || !task->acl || |
22581 |
++ !(task->acl->mode & GR_PROCACCT))) |
22582 |
++ return; |
22583 |
++ |
22584 |
++ runtime = xtime.tv_sec - task->start_time.tv_sec; |
22585 |
++ wday = runtime / (3600 * 24); |
22586 |
++ runtime -= wday * (3600 * 24); |
22587 |
++ whr = runtime / 3600; |
22588 |
++ runtime -= whr * 3600; |
22589 |
++ wmin = runtime / 60; |
22590 |
++ runtime -= wmin * 60; |
22591 |
++ wsec = runtime; |
22592 |
++ |
22593 |
++ cputime = (task->utime + task->stime) / HZ; |
22594 |
++ cday = cputime / (3600 * 24); |
22595 |
++ cputime -= cday * (3600 * 24); |
22596 |
++ chr = cputime / 3600; |
22597 |
++ cputime -= chr * 3600; |
22598 |
++ cmin = cputime / 60; |
22599 |
++ cputime -= cmin * 60; |
22600 |
++ csec = cputime; |
22601 |
++ |
22602 |
++ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code); |
22603 |
++ |
22604 |
++ return; |
22605 |
++} |
22606 |
++ |
22607 |
++void gr_set_kernel_label(struct task_struct *task) |
22608 |
++{ |
22609 |
++ if (gr_status & GR_READY) { |
22610 |
++ task->role = kernel_role; |
22611 |
++ task->acl = kernel_role->root_label; |
22612 |
++ } |
22613 |
++ return; |
22614 |
++} |
22615 |
++ |
22616 |
++int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino) |
22617 |
++{ |
22618 |
++ struct task_struct *task = current; |
22619 |
++ struct dentry *dentry = file->f_dentry; |
22620 |
++ struct vfsmount *mnt = file->f_vfsmnt; |
22621 |
++ struct acl_object_label *obj, *tmp; |
22622 |
++ struct acl_subject_label *subj; |
22623 |
++ unsigned int bufsize; |
22624 |
++ int is_not_root; |
22625 |
++ char *path; |
22626 |
++ |
22627 |
++ if (unlikely(!(gr_status & GR_READY))) |
22628 |
++ return 1; |
22629 |
++ |
22630 |
++ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN)) |
22631 |
++ return 1; |
22632 |
++ |
22633 |
++ /* ignore Eric Biederman */ |
22634 |
++ if (IS_PRIVATE(dentry->d_inode)) |
22635 |
++ return 1; |
22636 |
++ |
22637 |
++ subj = task->acl; |
22638 |
++ do { |
22639 |
++ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj); |
22640 |
++ if (obj != NULL) |
22641 |
++ return (obj->mode & GR_FIND) ? 1 : 0; |
22642 |
++ } while ((subj = subj->parent_subject)); |
22643 |
++ |
22644 |
++ obj = chk_obj_label(dentry, mnt, task->acl); |
22645 |
++ if (obj->globbed == NULL) |
22646 |
++ return (obj->mode & GR_FIND) ? 1 : 0; |
22647 |
++ |
22648 |
++ is_not_root = ((obj->filename[0] == '/') && |
22649 |
++ (obj->filename[1] == '\0')) ? 0 : 1; |
22650 |
++ bufsize = PAGE_SIZE - namelen - is_not_root; |
22651 |
++ |
22652 |
++ /* check bufsize > PAGE_SIZE || bufsize == 0 */ |
22653 |
++ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1))) |
22654 |
++ return 1; |
22655 |
++ |
22656 |
++ preempt_disable(); |
22657 |
++ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()), |
22658 |
++ bufsize); |
22659 |
++ |
22660 |
++ bufsize = strlen(path); |
22661 |
++ |
22662 |
++ /* if base is "/", don't append an additional slash */ |
22663 |
++ if (is_not_root) |
22664 |
++ *(path + bufsize) = '/'; |
22665 |
++ memcpy(path + bufsize + is_not_root, name, namelen); |
22666 |
++ *(path + bufsize + namelen + is_not_root) = '\0'; |
22667 |
++ |
22668 |
++ tmp = obj->globbed; |
22669 |
++ while (tmp) { |
22670 |
++ if (!glob_match(tmp->filename, path)) { |
22671 |
++ preempt_enable(); |
22672 |
++ return (tmp->mode & GR_FIND) ? 1 : 0; |
22673 |
++ } |
22674 |
++ tmp = tmp->next; |
22675 |
++ } |
22676 |
++ preempt_enable(); |
22677 |
++ return (obj->mode & GR_FIND) ? 1 : 0; |
22678 |
++} |
22679 |
++ |
22680 |
++EXPORT_SYMBOL(gr_learn_resource); |
22681 |
++EXPORT_SYMBOL(gr_set_kernel_label); |
22682 |
++#ifdef CONFIG_SECURITY |
22683 |
++EXPORT_SYMBOL(gr_check_user_change); |
22684 |
++EXPORT_SYMBOL(gr_check_group_change); |
22685 |
++#endif |
22686 |
++ |
22687 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_alloc.c linux-2.6.23.15-grsec/grsecurity/gracl_alloc.c |
22688 |
+--- linux-2.6.23.15/grsecurity/gracl_alloc.c 1970-01-01 01:00:00.000000000 +0100 |
22689 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_alloc.c 2008-02-11 10:37:44.000000000 +0000 |
22690 |
+@@ -0,0 +1,91 @@ |
22691 |
++#include <linux/kernel.h> |
22692 |
++#include <linux/mm.h> |
22693 |
++#include <linux/slab.h> |
22694 |
++#include <linux/vmalloc.h> |
22695 |
++#include <linux/gracl.h> |
22696 |
++#include <linux/grsecurity.h> |
22697 |
++ |
22698 |
++static unsigned long alloc_stack_next = 1; |
22699 |
++static unsigned long alloc_stack_size = 1; |
22700 |
++static void **alloc_stack; |
22701 |
++ |
22702 |
++static __inline__ int |
22703 |
++alloc_pop(void) |
22704 |
++{ |
22705 |
++ if (alloc_stack_next == 1) |
22706 |
++ return 0; |
22707 |
++ |
22708 |
++ kfree(alloc_stack[alloc_stack_next - 2]); |
22709 |
++ |
22710 |
++ alloc_stack_next--; |
22711 |
++ |
22712 |
++ return 1; |
22713 |
++} |
22714 |
++ |
22715 |
++static __inline__ void |
22716 |
++alloc_push(void *buf) |
22717 |
++{ |
22718 |
++ if (alloc_stack_next >= alloc_stack_size) |
22719 |
++ BUG(); |
22720 |
++ |
22721 |
++ alloc_stack[alloc_stack_next - 1] = buf; |
22722 |
++ |
22723 |
++ alloc_stack_next++; |
22724 |
++ |
22725 |
++ return; |
22726 |
++} |
22727 |
++ |
22728 |
++void * |
22729 |
++acl_alloc(unsigned long len) |
22730 |
++{ |
22731 |
++ void *ret; |
22732 |
++ |
22733 |
++ if (len > PAGE_SIZE) |
22734 |
++ BUG(); |
22735 |
++ |
22736 |
++ ret = kmalloc(len, GFP_KERNEL); |
22737 |
++ |
22738 |
++ if (ret) |
22739 |
++ alloc_push(ret); |
22740 |
++ |
22741 |
++ return ret; |
22742 |
++} |
22743 |
++ |
22744 |
++void |
22745 |
++acl_free_all(void) |
22746 |
++{ |
22747 |
++ if (gr_acl_is_enabled() || !alloc_stack) |
22748 |
++ return; |
22749 |
++ |
22750 |
++ while (alloc_pop()) ; |
22751 |
++ |
22752 |
++ if (alloc_stack) { |
22753 |
++ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE) |
22754 |
++ kfree(alloc_stack); |
22755 |
++ else |
22756 |
++ vfree(alloc_stack); |
22757 |
++ } |
22758 |
++ |
22759 |
++ alloc_stack = NULL; |
22760 |
++ alloc_stack_size = 1; |
22761 |
++ alloc_stack_next = 1; |
22762 |
++ |
22763 |
++ return; |
22764 |
++} |
22765 |
++ |
22766 |
++int |
22767 |
++acl_alloc_stack_init(unsigned long size) |
22768 |
++{ |
22769 |
++ if ((size * sizeof (void *)) <= PAGE_SIZE) |
22770 |
++ alloc_stack = |
22771 |
++ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL); |
22772 |
++ else |
22773 |
++ alloc_stack = (void **) vmalloc(size * sizeof (void *)); |
22774 |
++ |
22775 |
++ alloc_stack_size = size; |
22776 |
++ |
22777 |
++ if (!alloc_stack) |
22778 |
++ return 0; |
22779 |
++ else |
22780 |
++ return 1; |
22781 |
++} |
22782 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_cap.c linux-2.6.23.15-grsec/grsecurity/gracl_cap.c |
22783 |
+--- linux-2.6.23.15/grsecurity/gracl_cap.c 1970-01-01 01:00:00.000000000 +0100 |
22784 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_cap.c 2008-02-11 10:37:44.000000000 +0000 |
22785 |
+@@ -0,0 +1,112 @@ |
22786 |
++#include <linux/kernel.h> |
22787 |
++#include <linux/module.h> |
22788 |
++#include <linux/sched.h> |
22789 |
++#include <linux/capability.h> |
22790 |
++#include <linux/gracl.h> |
22791 |
++#include <linux/grsecurity.h> |
22792 |
++#include <linux/grinternal.h> |
22793 |
++ |
22794 |
++static const char *captab_log[] = { |
22795 |
++ "CAP_CHOWN", |
22796 |
++ "CAP_DAC_OVERRIDE", |
22797 |
++ "CAP_DAC_READ_SEARCH", |
22798 |
++ "CAP_FOWNER", |
22799 |
++ "CAP_FSETID", |
22800 |
++ "CAP_KILL", |
22801 |
++ "CAP_SETGID", |
22802 |
++ "CAP_SETUID", |
22803 |
++ "CAP_SETPCAP", |
22804 |
++ "CAP_LINUX_IMMUTABLE", |
22805 |
++ "CAP_NET_BIND_SERVICE", |
22806 |
++ "CAP_NET_BROADCAST", |
22807 |
++ "CAP_NET_ADMIN", |
22808 |
++ "CAP_NET_RAW", |
22809 |
++ "CAP_IPC_LOCK", |
22810 |
++ "CAP_IPC_OWNER", |
22811 |
++ "CAP_SYS_MODULE", |
22812 |
++ "CAP_SYS_RAWIO", |
22813 |
++ "CAP_SYS_CHROOT", |
22814 |
++ "CAP_SYS_PTRACE", |
22815 |
++ "CAP_SYS_PACCT", |
22816 |
++ "CAP_SYS_ADMIN", |
22817 |
++ "CAP_SYS_BOOT", |
22818 |
++ "CAP_SYS_NICE", |
22819 |
++ "CAP_SYS_RESOURCE", |
22820 |
++ "CAP_SYS_TIME", |
22821 |
++ "CAP_SYS_TTY_CONFIG", |
22822 |
++ "CAP_MKNOD", |
22823 |
++ "CAP_LEASE", |
22824 |
++ "CAP_AUDIT_WRITE", |
22825 |
++ "CAP_AUDIT_CONTROL" |
22826 |
++}; |
22827 |
++ |
22828 |
++EXPORT_SYMBOL(gr_task_is_capable); |
22829 |
++EXPORT_SYMBOL(gr_is_capable_nolog); |
22830 |
++ |
22831 |
++int |
22832 |
++gr_task_is_capable(struct task_struct *task, const int cap) |
22833 |
++{ |
22834 |
++ struct acl_subject_label *curracl; |
22835 |
++ __u32 cap_drop = 0, cap_mask = 0; |
22836 |
++ |
22837 |
++ if (!gr_acl_is_enabled()) |
22838 |
++ return 1; |
22839 |
++ |
22840 |
++ curracl = task->acl; |
22841 |
++ |
22842 |
++ cap_drop = curracl->cap_lower; |
22843 |
++ cap_mask = curracl->cap_mask; |
22844 |
++ |
22845 |
++ while ((curracl = curracl->parent_subject)) { |
22846 |
++ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap))) |
22847 |
++ cap_drop |= curracl->cap_lower & (1 << cap); |
22848 |
++ cap_mask |= curracl->cap_mask; |
22849 |
++ } |
22850 |
++ |
22851 |
++ if (!cap_raised(cap_drop, cap)) |
22852 |
++ return 1; |
22853 |
++ |
22854 |
++ curracl = task->acl; |
22855 |
++ |
22856 |
++ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) |
22857 |
++ && cap_raised(task->cap_effective, cap)) { |
22858 |
++ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, |
22859 |
++ task->role->roletype, task->uid, |
22860 |
++ task->gid, task->exec_file ? |
22861 |
++ gr_to_filename(task->exec_file->f_dentry, |
22862 |
++ task->exec_file->f_vfsmnt) : curracl->filename, |
22863 |
++ curracl->filename, 0UL, |
22864 |
++ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip)); |
22865 |
++ return 1; |
22866 |
++ } |
22867 |
++ |
22868 |
++ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap)) |
22869 |
++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]); |
22870 |
++ return 0; |
22871 |
++} |
22872 |
++ |
22873 |
++int |
22874 |
++gr_is_capable_nolog(const int cap) |
22875 |
++{ |
22876 |
++ struct acl_subject_label *curracl; |
22877 |
++ __u32 cap_drop = 0, cap_mask = 0; |
22878 |
++ |
22879 |
++ if (!gr_acl_is_enabled()) |
22880 |
++ return 1; |
22881 |
++ |
22882 |
++ curracl = current->acl; |
22883 |
++ |
22884 |
++ cap_drop = curracl->cap_lower; |
22885 |
++ cap_mask = curracl->cap_mask; |
22886 |
++ |
22887 |
++ while ((curracl = curracl->parent_subject)) { |
22888 |
++ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask); |
22889 |
++ cap_mask |= curracl->cap_mask; |
22890 |
++ } |
22891 |
++ |
22892 |
++ if (!cap_raised(cap_drop, cap)) |
22893 |
++ return 1; |
22894 |
++ |
22895 |
++ return 0; |
22896 |
++} |
22897 |
++ |
22898 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_fs.c linux-2.6.23.15-grsec/grsecurity/gracl_fs.c |
22899 |
+--- linux-2.6.23.15/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100 |
22900 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_fs.c 2008-02-11 10:37:44.000000000 +0000 |
22901 |
+@@ -0,0 +1,423 @@ |
22902 |
++#include <linux/kernel.h> |
22903 |
++#include <linux/sched.h> |
22904 |
++#include <linux/types.h> |
22905 |
++#include <linux/fs.h> |
22906 |
++#include <linux/file.h> |
22907 |
++#include <linux/stat.h> |
22908 |
++#include <linux/grsecurity.h> |
22909 |
++#include <linux/grinternal.h> |
22910 |
++#include <linux/gracl.h> |
22911 |
++ |
22912 |
++__u32 |
22913 |
++gr_acl_handle_hidden_file(const struct dentry * dentry, |
22914 |
++ const struct vfsmount * mnt) |
22915 |
++{ |
22916 |
++ __u32 mode; |
22917 |
++ |
22918 |
++ if (unlikely(!dentry->d_inode)) |
22919 |
++ return GR_FIND; |
22920 |
++ |
22921 |
++ mode = |
22922 |
++ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt); |
22923 |
++ |
22924 |
++ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) { |
22925 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); |
22926 |
++ return mode; |
22927 |
++ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) { |
22928 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt); |
22929 |
++ return 0; |
22930 |
++ } else if (unlikely(!(mode & GR_FIND))) |
22931 |
++ return 0; |
22932 |
++ |
22933 |
++ return GR_FIND; |
22934 |
++} |
22935 |
++ |
22936 |
++__u32 |
22937 |
++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, |
22938 |
++ const int fmode) |
22939 |
++{ |
22940 |
++ __u32 reqmode = GR_FIND; |
22941 |
++ __u32 mode; |
22942 |
++ |
22943 |
++ if (unlikely(!dentry->d_inode)) |
22944 |
++ return reqmode; |
22945 |
++ |
22946 |
++ if (unlikely(fmode & O_APPEND)) |
22947 |
++ reqmode |= GR_APPEND; |
22948 |
++ else if (unlikely(fmode & FMODE_WRITE)) |
22949 |
++ reqmode |= GR_WRITE; |
22950 |
++ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) |
22951 |
++ reqmode |= GR_READ; |
22952 |
++ |
22953 |
++ mode = |
22954 |
++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, |
22955 |
++ mnt); |
22956 |
++ |
22957 |
++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { |
22958 |
++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, |
22959 |
++ reqmode & GR_READ ? " reading" : "", |
22960 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
22961 |
++ GR_APPEND ? " appending" : ""); |
22962 |
++ return reqmode; |
22963 |
++ } else |
22964 |
++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) |
22965 |
++ { |
22966 |
++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt, |
22967 |
++ reqmode & GR_READ ? " reading" : "", |
22968 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
22969 |
++ GR_APPEND ? " appending" : ""); |
22970 |
++ return 0; |
22971 |
++ } else if (unlikely((mode & reqmode) != reqmode)) |
22972 |
++ return 0; |
22973 |
++ |
22974 |
++ return reqmode; |
22975 |
++} |
22976 |
++ |
22977 |
++__u32 |
22978 |
++gr_acl_handle_creat(const struct dentry * dentry, |
22979 |
++ const struct dentry * p_dentry, |
22980 |
++ const struct vfsmount * p_mnt, const int fmode, |
22981 |
++ const int imode) |
22982 |
++{ |
22983 |
++ __u32 reqmode = GR_WRITE | GR_CREATE; |
22984 |
++ __u32 mode; |
22985 |
++ |
22986 |
++ if (unlikely(fmode & O_APPEND)) |
22987 |
++ reqmode |= GR_APPEND; |
22988 |
++ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) |
22989 |
++ reqmode |= GR_READ; |
22990 |
++ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID)))) |
22991 |
++ reqmode |= GR_SETID; |
22992 |
++ |
22993 |
++ mode = |
22994 |
++ gr_check_create(dentry, p_dentry, p_mnt, |
22995 |
++ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); |
22996 |
++ |
22997 |
++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { |
22998 |
++ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt, |
22999 |
++ reqmode & GR_READ ? " reading" : "", |
23000 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
23001 |
++ GR_APPEND ? " appending" : ""); |
23002 |
++ return reqmode; |
23003 |
++ } else |
23004 |
++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) |
23005 |
++ { |
23006 |
++ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt, |
23007 |
++ reqmode & GR_READ ? " reading" : "", |
23008 |
++ reqmode & GR_WRITE ? " writing" : reqmode & |
23009 |
++ GR_APPEND ? " appending" : ""); |
23010 |
++ return 0; |
23011 |
++ } else if (unlikely((mode & reqmode) != reqmode)) |
23012 |
++ return 0; |
23013 |
++ |
23014 |
++ return reqmode; |
23015 |
++} |
23016 |
++ |
23017 |
++__u32 |
23018 |
++gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt, |
23019 |
++ const int fmode) |
23020 |
++{ |
23021 |
++ __u32 mode, reqmode = GR_FIND; |
23022 |
++ |
23023 |
++ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode)) |
23024 |
++ reqmode |= GR_EXEC; |
23025 |
++ if (fmode & S_IWOTH) |
23026 |
++ reqmode |= GR_WRITE; |
23027 |
++ if (fmode & S_IROTH) |
23028 |
++ reqmode |= GR_READ; |
23029 |
++ |
23030 |
++ mode = |
23031 |
++ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, |
23032 |
++ mnt); |
23033 |
++ |
23034 |
++ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { |
23035 |
++ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, |
23036 |
++ reqmode & GR_READ ? " reading" : "", |
23037 |
++ reqmode & GR_WRITE ? " writing" : "", |
23038 |
++ reqmode & GR_EXEC ? " executing" : ""); |
23039 |
++ return reqmode; |
23040 |
++ } else |
23041 |
++ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) |
23042 |
++ { |
23043 |
++ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt, |
23044 |
++ reqmode & GR_READ ? " reading" : "", |
23045 |
++ reqmode & GR_WRITE ? " writing" : "", |
23046 |
++ reqmode & GR_EXEC ? " executing" : ""); |
23047 |
++ return 0; |
23048 |
++ } else if (unlikely((mode & reqmode) != reqmode)) |
23049 |
++ return 0; |
23050 |
++ |
23051 |
++ return reqmode; |
23052 |
++} |
23053 |
++ |
23054 |
++static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt) |
23055 |
++{ |
23056 |
++ __u32 mode; |
23057 |
++ |
23058 |
++ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); |
23059 |
++ |
23060 |
++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { |
23061 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt); |
23062 |
++ return mode; |
23063 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { |
23064 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt); |
23065 |
++ return 0; |
23066 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode))) |
23067 |
++ return 0; |
23068 |
++ |
23069 |
++ return (reqmode); |
23070 |
++} |
23071 |
++ |
23072 |
++__u32 |
23073 |
++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) |
23074 |
++{ |
23075 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG); |
23076 |
++} |
23077 |
++ |
23078 |
++__u32 |
23079 |
++gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt) |
23080 |
++{ |
23081 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG); |
23082 |
++} |
23083 |
++ |
23084 |
++__u32 |
23085 |
++gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt) |
23086 |
++{ |
23087 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG); |
23088 |
++} |
23089 |
++ |
23090 |
++__u32 |
23091 |
++gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt) |
23092 |
++{ |
23093 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG); |
23094 |
++} |
23095 |
++ |
23096 |
++__u32 |
23097 |
++gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt, |
23098 |
++ mode_t mode) |
23099 |
++{ |
23100 |
++ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode))) |
23101 |
++ return 1; |
23102 |
++ |
23103 |
++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { |
23104 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, |
23105 |
++ GR_FCHMOD_ACL_MSG); |
23106 |
++ } else { |
23107 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG); |
23108 |
++ } |
23109 |
++} |
23110 |
++ |
23111 |
++__u32 |
23112 |
++gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt, |
23113 |
++ mode_t mode) |
23114 |
++{ |
23115 |
++ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { |
23116 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, |
23117 |
++ GR_CHMOD_ACL_MSG); |
23118 |
++ } else { |
23119 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG); |
23120 |
++ } |
23121 |
++} |
23122 |
++ |
23123 |
++__u32 |
23124 |
++gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt) |
23125 |
++{ |
23126 |
++ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG); |
23127 |
++} |
23128 |
++ |
23129 |
++__u32 |
23130 |
++gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt) |
23131 |
++{ |
23132 |
++ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG); |
23133 |
++} |
23134 |
++ |
23135 |
++__u32 |
23136 |
++gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt) |
23137 |
++{ |
23138 |
++ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE, |
23139 |
++ GR_UNIXCONNECT_ACL_MSG); |
23140 |
++} |
23141 |
++ |
23142 |
++/* hardlinks require at minimum create permission, |
23143 |
++ any additional privilege required is based on the |
23144 |
++ privilege of the file being linked to |
23145 |
++*/ |
23146 |
++__u32 |
23147 |
++gr_acl_handle_link(const struct dentry * new_dentry, |
23148 |
++ const struct dentry * parent_dentry, |
23149 |
++ const struct vfsmount * parent_mnt, |
23150 |
++ const struct dentry * old_dentry, |
23151 |
++ const struct vfsmount * old_mnt, const char *to) |
23152 |
++{ |
23153 |
++ __u32 mode; |
23154 |
++ __u32 needmode = GR_CREATE | GR_LINK; |
23155 |
++ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK; |
23156 |
++ |
23157 |
++ mode = |
23158 |
++ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry, |
23159 |
++ old_mnt); |
23160 |
++ |
23161 |
++ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) { |
23162 |
++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to); |
23163 |
++ return mode; |
23164 |
++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { |
23165 |
++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to); |
23166 |
++ return 0; |
23167 |
++ } else if (unlikely((mode & needmode) != needmode)) |
23168 |
++ return 0; |
23169 |
++ |
23170 |
++ return 1; |
23171 |
++} |
23172 |
++ |
23173 |
++__u32 |
23174 |
++gr_acl_handle_symlink(const struct dentry * new_dentry, |
23175 |
++ const struct dentry * parent_dentry, |
23176 |
++ const struct vfsmount * parent_mnt, const char *from) |
23177 |
++{ |
23178 |
++ __u32 needmode = GR_WRITE | GR_CREATE; |
23179 |
++ __u32 mode; |
23180 |
++ |
23181 |
++ mode = |
23182 |
++ gr_check_create(new_dentry, parent_dentry, parent_mnt, |
23183 |
++ GR_CREATE | GR_AUDIT_CREATE | |
23184 |
++ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS); |
23185 |
++ |
23186 |
++ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) { |
23187 |
++ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); |
23188 |
++ return mode; |
23189 |
++ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { |
23190 |
++ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt); |
23191 |
++ return 0; |
23192 |
++ } else if (unlikely((mode & needmode) != needmode)) |
23193 |
++ return 0; |
23194 |
++ |
23195 |
++ return (GR_WRITE | GR_CREATE); |
23196 |
++} |
23197 |
++ |
23198 |
++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) |
23199 |
++{ |
23200 |
++ __u32 mode; |
23201 |
++ |
23202 |
++ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); |
23203 |
++ |
23204 |
++ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { |
23205 |
++ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt); |
23206 |
++ return mode; |
23207 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { |
23208 |
++ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt); |
23209 |
++ return 0; |
23210 |
++ } else if (unlikely((mode & (reqmode)) != (reqmode))) |
23211 |
++ return 0; |
23212 |
++ |
23213 |
++ return (reqmode); |
23214 |
++} |
23215 |
++ |
23216 |
++__u32 |
23217 |
++gr_acl_handle_mknod(const struct dentry * new_dentry, |
23218 |
++ const struct dentry * parent_dentry, |
23219 |
++ const struct vfsmount * parent_mnt, |
23220 |
++ const int mode) |
23221 |
++{ |
23222 |
++ __u32 reqmode = GR_WRITE | GR_CREATE; |
23223 |
++ if (unlikely(mode & (S_ISUID | S_ISGID))) |
23224 |
++ reqmode |= GR_SETID; |
23225 |
++ |
23226 |
++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, |
23227 |
++ reqmode, GR_MKNOD_ACL_MSG); |
23228 |
++} |
23229 |
++ |
23230 |
++__u32 |
23231 |
++gr_acl_handle_mkdir(const struct dentry *new_dentry, |
23232 |
++ const struct dentry *parent_dentry, |
23233 |
++ const struct vfsmount *parent_mnt) |
23234 |
++{ |
23235 |
++ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, |
23236 |
++ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG); |
23237 |
++} |
23238 |
++ |
23239 |
++#define RENAME_CHECK_SUCCESS(old, new) \ |
23240 |
++ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \ |
23241 |
++ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ))) |
23242 |
++ |
23243 |
++int |
23244 |
++gr_acl_handle_rename(struct dentry *new_dentry, |
23245 |
++ struct dentry *parent_dentry, |
23246 |
++ const struct vfsmount *parent_mnt, |
23247 |
++ struct dentry *old_dentry, |
23248 |
++ struct inode *old_parent_inode, |
23249 |
++ struct vfsmount *old_mnt, const char *newname) |
23250 |
++{ |
23251 |
++ __u32 comp1, comp2; |
23252 |
++ int error = 0; |
23253 |
++ |
23254 |
++ if (unlikely(!gr_acl_is_enabled())) |
23255 |
++ return 0; |
23256 |
++ |
23257 |
++ if (!new_dentry->d_inode) { |
23258 |
++ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt, |
23259 |
++ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ | |
23260 |
++ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS); |
23261 |
++ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | |
23262 |
++ GR_DELETE | GR_AUDIT_DELETE | |
23263 |
++ GR_AUDIT_READ | GR_AUDIT_WRITE | |
23264 |
++ GR_SUPPRESS, old_mnt); |
23265 |
++ } else { |
23266 |
++ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE | |
23267 |
++ GR_CREATE | GR_DELETE | |
23268 |
++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | |
23269 |
++ GR_AUDIT_READ | GR_AUDIT_WRITE | |
23270 |
++ GR_SUPPRESS, parent_mnt); |
23271 |
++ comp2 = |
23272 |
++ gr_search_file(old_dentry, |
23273 |
++ GR_READ | GR_WRITE | GR_AUDIT_READ | |
23274 |
++ GR_DELETE | GR_AUDIT_DELETE | |
23275 |
++ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); |
23276 |
++ } |
23277 |
++ |
23278 |
++ if (RENAME_CHECK_SUCCESS(comp1, comp2) && |
23279 |
++ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS))) |
23280 |
++ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname); |
23281 |
++ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS) |
23282 |
++ && !(comp2 & GR_SUPPRESS)) { |
23283 |
++ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname); |
23284 |
++ error = -EACCES; |
23285 |
++ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2))) |
23286 |
++ error = -EACCES; |
23287 |
++ |
23288 |
++ return error; |
23289 |
++} |
23290 |
++ |
23291 |
++void |
23292 |
++gr_acl_handle_exit(void) |
23293 |
++{ |
23294 |
++ u16 id; |
23295 |
++ char *rolename; |
23296 |
++ struct file *exec_file; |
23297 |
++ |
23298 |
++ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) { |
23299 |
++ id = current->acl_role_id; |
23300 |
++ rolename = current->role->rolename; |
23301 |
++ gr_set_acls(1); |
23302 |
++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id); |
23303 |
++ } |
23304 |
++ |
23305 |
++ write_lock(&grsec_exec_file_lock); |
23306 |
++ exec_file = current->exec_file; |
23307 |
++ current->exec_file = NULL; |
23308 |
++ write_unlock(&grsec_exec_file_lock); |
23309 |
++ |
23310 |
++ if (exec_file) |
23311 |
++ fput(exec_file); |
23312 |
++} |
23313 |
++ |
23314 |
++int |
23315 |
++gr_acl_handle_procpidmem(const struct task_struct *task) |
23316 |
++{ |
23317 |
++ if (unlikely(!gr_acl_is_enabled())) |
23318 |
++ return 0; |
23319 |
++ |
23320 |
++ if (task->acl->mode & GR_PROTPROCFD) |
23321 |
++ return -EACCES; |
23322 |
++ |
23323 |
++ return 0; |
23324 |
++} |
23325 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_ip.c linux-2.6.23.15-grsec/grsecurity/gracl_ip.c |
23326 |
+--- linux-2.6.23.15/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100 |
23327 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_ip.c 2008-02-11 10:37:44.000000000 +0000 |
23328 |
+@@ -0,0 +1,313 @@ |
23329 |
++#include <linux/kernel.h> |
23330 |
++#include <asm/uaccess.h> |
23331 |
++#include <asm/errno.h> |
23332 |
++#include <net/sock.h> |
23333 |
++#include <linux/file.h> |
23334 |
++#include <linux/fs.h> |
23335 |
++#include <linux/net.h> |
23336 |
++#include <linux/in.h> |
23337 |
++#include <linux/skbuff.h> |
23338 |
++#include <linux/ip.h> |
23339 |
++#include <linux/udp.h> |
23340 |
++#include <linux/smp_lock.h> |
23341 |
++#include <linux/types.h> |
23342 |
++#include <linux/sched.h> |
23343 |
++#include <linux/netdevice.h> |
23344 |
++#include <linux/inetdevice.h> |
23345 |
++#include <linux/gracl.h> |
23346 |
++#include <linux/grsecurity.h> |
23347 |
++#include <linux/grinternal.h> |
23348 |
++ |
23349 |
++#define GR_BIND 0x01 |
23350 |
++#define GR_CONNECT 0x02 |
23351 |
++#define GR_INVERT 0x04 |
23352 |
++ |
23353 |
++static const char * gr_protocols[256] = { |
23354 |
++ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt", |
23355 |
++ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet", |
23356 |
++ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1", |
23357 |
++ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp", |
23358 |
++ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++", |
23359 |
++ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre", |
23360 |
++ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile", |
23361 |
++ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63", |
23362 |
++ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv", |
23363 |
++ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", |
23364 |
++ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", |
23365 |
++ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp", |
23366 |
++ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim", |
23367 |
++ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip", |
23368 |
++ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp", |
23369 |
++ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup", |
23370 |
++ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135", |
23371 |
++ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143", |
23372 |
++ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151", |
23373 |
++ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159", |
23374 |
++ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167", |
23375 |
++ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175", |
23376 |
++ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183", |
23377 |
++ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191", |
23378 |
++ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199", |
23379 |
++ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207", |
23380 |
++ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215", |
23381 |
++ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223", |
23382 |
++ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231", |
23383 |
++ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239", |
23384 |
++ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247", |
23385 |
++ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255", |
23386 |
++ }; |
23387 |
++ |
23388 |
++static const char * gr_socktypes[11] = { |
23389 |
++ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", |
23390 |
++ "unknown:7", "unknown:8", "unknown:9", "packet" |
23391 |
++ }; |
23392 |
++ |
23393 |
++const char * |
23394 |
++gr_proto_to_name(unsigned char proto) |
23395 |
++{ |
23396 |
++ return gr_protocols[proto]; |
23397 |
++} |
23398 |
++ |
23399 |
++const char * |
23400 |
++gr_socktype_to_name(unsigned char type) |
23401 |
++{ |
23402 |
++ return gr_socktypes[type]; |
23403 |
++} |
23404 |
++ |
23405 |
++int |
23406 |
++gr_search_socket(const int domain, const int type, const int protocol) |
23407 |
++{ |
23408 |
++ struct acl_subject_label *curr; |
23409 |
++ |
23410 |
++ if (unlikely(!gr_acl_is_enabled())) |
23411 |
++ goto exit; |
23412 |
++ |
23413 |
++ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET) |
23414 |
++ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255)) |
23415 |
++ goto exit; // let the kernel handle it |
23416 |
++ |
23417 |
++ curr = current->acl; |
23418 |
++ |
23419 |
++ if (!curr->ips) |
23420 |
++ goto exit; |
23421 |
++ |
23422 |
++ if ((curr->ip_type & (1 << type)) && |
23423 |
++ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32)))) |
23424 |
++ goto exit; |
23425 |
++ |
23426 |
++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) { |
23427 |
++ /* we don't place acls on raw sockets , and sometimes |
23428 |
++ dgram/ip sockets are opened for ioctl and not |
23429 |
++ bind/connect, so we'll fake a bind learn log */ |
23430 |
++ if (type == SOCK_RAW || type == SOCK_PACKET) { |
23431 |
++ __u32 fakeip = 0; |
23432 |
++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, |
23433 |
++ current->role->roletype, current->uid, |
23434 |
++ current->gid, current->exec_file ? |
23435 |
++ gr_to_filename(current->exec_file->f_dentry, |
23436 |
++ current->exec_file->f_vfsmnt) : |
23437 |
++ curr->filename, curr->filename, |
23438 |
++ NIPQUAD(fakeip), 0, type, |
23439 |
++ protocol, GR_CONNECT, |
23440 |
++NIPQUAD(current->signal->curr_ip)); |
23441 |
++ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) { |
23442 |
++ __u32 fakeip = 0; |
23443 |
++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, |
23444 |
++ current->role->roletype, current->uid, |
23445 |
++ current->gid, current->exec_file ? |
23446 |
++ gr_to_filename(current->exec_file->f_dentry, |
23447 |
++ current->exec_file->f_vfsmnt) : |
23448 |
++ curr->filename, curr->filename, |
23449 |
++ NIPQUAD(fakeip), 0, type, |
23450 |
++ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip)); |
23451 |
++ } |
23452 |
++ /* we'll log when they use connect or bind */ |
23453 |
++ goto exit; |
23454 |
++ } |
23455 |
++ |
23456 |
++ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", |
23457 |
++ gr_socktype_to_name(type), gr_proto_to_name(protocol)); |
23458 |
++ |
23459 |
++ return 0; |
23460 |
++ exit: |
23461 |
++ return 1; |
23462 |
++} |
23463 |
++ |
23464 |
++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) |
23465 |
++{ |
23466 |
++ if ((ip->mode & mode) && |
23467 |
++ (ip_port >= ip->low) && |
23468 |
++ (ip_port <= ip->high) && |
23469 |
++ ((ntohl(ip_addr) & our_netmask) == |
23470 |
++ (ntohl(our_addr) & our_netmask)) |
23471 |
++ && (ip->proto[protocol / 32] & (1 << (protocol % 32))) |
23472 |
++ && (ip->type & (1 << type))) { |
23473 |
++ if (ip->mode & GR_INVERT) |
23474 |
++ return 2; // specifically denied |
23475 |
++ else |
23476 |
++ return 1; // allowed |
23477 |
++ } |
23478 |
++ |
23479 |
++ return 0; // not specifically allowed, may continue parsing |
23480 |
++} |
23481 |
++ |
23482 |
++static int |
23483 |
++gr_search_connectbind(const int mode, const struct sock *sk, |
23484 |
++ const struct sockaddr_in *addr, const int type) |
23485 |
++{ |
23486 |
++ char iface[IFNAMSIZ] = {0}; |
23487 |
++ struct acl_subject_label *curr; |
23488 |
++ struct acl_ip_label *ip; |
23489 |
++ struct net_device *dev; |
23490 |
++ struct in_device *idev; |
23491 |
++ unsigned long i; |
23492 |
++ int ret; |
23493 |
++ __u32 ip_addr = 0; |
23494 |
++ __u32 our_addr; |
23495 |
++ __u32 our_netmask; |
23496 |
++ char *p; |
23497 |
++ __u16 ip_port = 0; |
23498 |
++ |
23499 |
++ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET)) |
23500 |
++ return 1; |
23501 |
++ |
23502 |
++ curr = current->acl; |
23503 |
++ |
23504 |
++ if (!curr->ips) |
23505 |
++ return 1; |
23506 |
++ |
23507 |
++ ip_addr = addr->sin_addr.s_addr; |
23508 |
++ ip_port = ntohs(addr->sin_port); |
23509 |
++ |
23510 |
++ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) { |
23511 |
++ security_learn(GR_IP_LEARN_MSG, current->role->rolename, |
23512 |
++ current->role->roletype, current->uid, |
23513 |
++ current->gid, current->exec_file ? |
23514 |
++ gr_to_filename(current->exec_file->f_dentry, |
23515 |
++ current->exec_file->f_vfsmnt) : |
23516 |
++ curr->filename, curr->filename, |
23517 |
++ NIPQUAD(ip_addr), ip_port, type, |
23518 |
++ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip)); |
23519 |
++ return 1; |
23520 |
++ } |
23521 |
++ |
23522 |
++ for (i = 0; i < curr->ip_num; i++) { |
23523 |
++ ip = *(curr->ips + i); |
23524 |
++ if (ip->iface != NULL) { |
23525 |
++ strncpy(iface, ip->iface, IFNAMSIZ - 1); |
23526 |
++ p = strchr(iface, ':'); |
23527 |
++ if (p != NULL) |
23528 |
++ *p = '\0'; |
23529 |
++ dev = dev_get_by_name(iface); |
23530 |
++ if (dev == NULL) |
23531 |
++ continue; |
23532 |
++ idev = in_dev_get(dev); |
23533 |
++ if (idev == NULL) { |
23534 |
++ dev_put(dev); |
23535 |
++ continue; |
23536 |
++ } |
23537 |
++ rcu_read_lock(); |
23538 |
++ for_ifa(idev) { |
23539 |
++ if (!strcmp(ip->iface, ifa->ifa_label)) { |
23540 |
++ our_addr = ifa->ifa_address; |
23541 |
++ our_netmask = 0xffffffff; |
23542 |
++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask); |
23543 |
++ if (ret == 1) { |
23544 |
++ rcu_read_unlock(); |
23545 |
++ in_dev_put(idev); |
23546 |
++ dev_put(dev); |
23547 |
++ return 1; |
23548 |
++ } else if (ret == 2) { |
23549 |
++ rcu_read_unlock(); |
23550 |
++ in_dev_put(idev); |
23551 |
++ dev_put(dev); |
23552 |
++ goto denied; |
23553 |
++ } |
23554 |
++ } |
23555 |
++ } endfor_ifa(idev); |
23556 |
++ rcu_read_unlock(); |
23557 |
++ in_dev_put(idev); |
23558 |
++ dev_put(dev); |
23559 |
++ } else { |
23560 |
++ our_addr = ip->addr; |
23561 |
++ our_netmask = ip->netmask; |
23562 |
++ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask); |
23563 |
++ if (ret == 1) |
23564 |
++ return 1; |
23565 |
++ else if (ret == 2) |
23566 |
++ goto denied; |
23567 |
++ } |
23568 |
++ } |
23569 |
++ |
23570 |
++denied: |
23571 |
++ if (mode == GR_BIND) |
23572 |
++ 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)); |
23573 |
++ else if (mode == GR_CONNECT) |
23574 |
++ 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)); |
23575 |
++ |
23576 |
++ return 0; |
23577 |
++} |
23578 |
++ |
23579 |
++int |
23580 |
++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) |
23581 |
++{ |
23582 |
++ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type); |
23583 |
++} |
23584 |
++ |
23585 |
++int |
23586 |
++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) |
23587 |
++{ |
23588 |
++ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type); |
23589 |
++} |
23590 |
++ |
23591 |
++int gr_search_listen(const struct socket *sock) |
23592 |
++{ |
23593 |
++ struct sock *sk = sock->sk; |
23594 |
++ struct sockaddr_in addr; |
23595 |
++ |
23596 |
++ addr.sin_addr.s_addr = inet_sk(sk)->saddr; |
23597 |
++ addr.sin_port = inet_sk(sk)->sport; |
23598 |
++ |
23599 |
++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type); |
23600 |
++} |
23601 |
++ |
23602 |
++int gr_search_accept(const struct socket *sock) |
23603 |
++{ |
23604 |
++ struct sock *sk = sock->sk; |
23605 |
++ struct sockaddr_in addr; |
23606 |
++ |
23607 |
++ addr.sin_addr.s_addr = inet_sk(sk)->saddr; |
23608 |
++ addr.sin_port = inet_sk(sk)->sport; |
23609 |
++ |
23610 |
++ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type); |
23611 |
++} |
23612 |
++ |
23613 |
++int |
23614 |
++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) |
23615 |
++{ |
23616 |
++ if (addr) |
23617 |
++ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM); |
23618 |
++ else { |
23619 |
++ struct sockaddr_in sin; |
23620 |
++ const struct inet_sock *inet = inet_sk(sk); |
23621 |
++ |
23622 |
++ sin.sin_addr.s_addr = inet->daddr; |
23623 |
++ sin.sin_port = inet->dport; |
23624 |
++ |
23625 |
++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM); |
23626 |
++ } |
23627 |
++} |
23628 |
++ |
23629 |
++int |
23630 |
++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) |
23631 |
++{ |
23632 |
++ struct sockaddr_in sin; |
23633 |
++ |
23634 |
++ if (unlikely(skb->len < sizeof (struct udphdr))) |
23635 |
++ return 1; // skip this packet |
23636 |
++ |
23637 |
++ sin.sin_addr.s_addr = ip_hdr(skb)->saddr; |
23638 |
++ sin.sin_port = udp_hdr(skb)->source; |
23639 |
++ |
23640 |
++ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM); |
23641 |
++} |
23642 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_learn.c linux-2.6.23.15-grsec/grsecurity/gracl_learn.c |
23643 |
+--- linux-2.6.23.15/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100 |
23644 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_learn.c 2008-02-11 10:37:44.000000000 +0000 |
23645 |
+@@ -0,0 +1,211 @@ |
23646 |
++#include <linux/kernel.h> |
23647 |
++#include <linux/mm.h> |
23648 |
++#include <linux/sched.h> |
23649 |
++#include <linux/poll.h> |
23650 |
++#include <linux/smp_lock.h> |
23651 |
++#include <linux/string.h> |
23652 |
++#include <linux/file.h> |
23653 |
++#include <linux/types.h> |
23654 |
++#include <linux/vmalloc.h> |
23655 |
++#include <linux/grinternal.h> |
23656 |
++ |
23657 |
++extern ssize_t write_grsec_handler(struct file * file, const char __user * buf, |
23658 |
++ size_t count, loff_t *ppos); |
23659 |
++extern int gr_acl_is_enabled(void); |
23660 |
++ |
23661 |
++static DECLARE_WAIT_QUEUE_HEAD(learn_wait); |
23662 |
++static int gr_learn_attached; |
23663 |
++ |
23664 |
++/* use a 512k buffer */ |
23665 |
++#define LEARN_BUFFER_SIZE (512 * 1024) |
23666 |
++ |
23667 |
++static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED; |
23668 |
++static DECLARE_MUTEX(gr_learn_user_sem); |
23669 |
++ |
23670 |
++/* we need to maintain two buffers, so that the kernel context of grlearn |
23671 |
++ uses a semaphore around the userspace copying, and the other kernel contexts |
23672 |
++ use a spinlock when copying into the buffer, since they cannot sleep |
23673 |
++*/ |
23674 |
++static char *learn_buffer; |
23675 |
++static char *learn_buffer_user; |
23676 |
++static int learn_buffer_len; |
23677 |
++static int learn_buffer_user_len; |
23678 |
++ |
23679 |
++static ssize_t |
23680 |
++read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos) |
23681 |
++{ |
23682 |
++ DECLARE_WAITQUEUE(wait, current); |
23683 |
++ ssize_t retval = 0; |
23684 |
++ |
23685 |
++ add_wait_queue(&learn_wait, &wait); |
23686 |
++ set_current_state(TASK_INTERRUPTIBLE); |
23687 |
++ do { |
23688 |
++ down(&gr_learn_user_sem); |
23689 |
++ spin_lock(&gr_learn_lock); |
23690 |
++ if (learn_buffer_len) |
23691 |
++ break; |
23692 |
++ spin_unlock(&gr_learn_lock); |
23693 |
++ up(&gr_learn_user_sem); |
23694 |
++ if (file->f_flags & O_NONBLOCK) { |
23695 |
++ retval = -EAGAIN; |
23696 |
++ goto out; |
23697 |
++ } |
23698 |
++ if (signal_pending(current)) { |
23699 |
++ retval = -ERESTARTSYS; |
23700 |
++ goto out; |
23701 |
++ } |
23702 |
++ |
23703 |
++ schedule(); |
23704 |
++ } while (1); |
23705 |
++ |
23706 |
++ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len); |
23707 |
++ learn_buffer_user_len = learn_buffer_len; |
23708 |
++ retval = learn_buffer_len; |
23709 |
++ learn_buffer_len = 0; |
23710 |
++ |
23711 |
++ spin_unlock(&gr_learn_lock); |
23712 |
++ |
23713 |
++ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len)) |
23714 |
++ retval = -EFAULT; |
23715 |
++ |
23716 |
++ up(&gr_learn_user_sem); |
23717 |
++out: |
23718 |
++ set_current_state(TASK_RUNNING); |
23719 |
++ remove_wait_queue(&learn_wait, &wait); |
23720 |
++ return retval; |
23721 |
++} |
23722 |
++ |
23723 |
++static unsigned int |
23724 |
++poll_learn(struct file * file, poll_table * wait) |
23725 |
++{ |
23726 |
++ poll_wait(file, &learn_wait, wait); |
23727 |
++ |
23728 |
++ if (learn_buffer_len) |
23729 |
++ return (POLLIN | POLLRDNORM); |
23730 |
++ |
23731 |
++ return 0; |
23732 |
++} |
23733 |
++ |
23734 |
++void |
23735 |
++gr_clear_learn_entries(void) |
23736 |
++{ |
23737 |
++ char *tmp; |
23738 |
++ |
23739 |
++ down(&gr_learn_user_sem); |
23740 |
++ if (learn_buffer != NULL) { |
23741 |
++ spin_lock(&gr_learn_lock); |
23742 |
++ tmp = learn_buffer; |
23743 |
++ learn_buffer = NULL; |
23744 |
++ spin_unlock(&gr_learn_lock); |
23745 |
++ vfree(learn_buffer); |
23746 |
++ } |
23747 |
++ if (learn_buffer_user != NULL) { |
23748 |
++ vfree(learn_buffer_user); |
23749 |
++ learn_buffer_user = NULL; |
23750 |
++ } |
23751 |
++ learn_buffer_len = 0; |
23752 |
++ up(&gr_learn_user_sem); |
23753 |
++ |
23754 |
++ return; |
23755 |
++} |
23756 |
++ |
23757 |
++void |
23758 |
++gr_add_learn_entry(const char *fmt, ...) |
23759 |
++{ |
23760 |
++ va_list args; |
23761 |
++ unsigned int len; |
23762 |
++ |
23763 |
++ if (!gr_learn_attached) |
23764 |
++ return; |
23765 |
++ |
23766 |
++ spin_lock(&gr_learn_lock); |
23767 |
++ |
23768 |
++ /* leave a gap at the end so we know when it's "full" but don't have to |
23769 |
++ compute the exact length of the string we're trying to append |
23770 |
++ */ |
23771 |
++ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) { |
23772 |
++ spin_unlock(&gr_learn_lock); |
23773 |
++ wake_up_interruptible(&learn_wait); |
23774 |
++ return; |
23775 |
++ } |
23776 |
++ if (learn_buffer == NULL) { |
23777 |
++ spin_unlock(&gr_learn_lock); |
23778 |
++ return; |
23779 |
++ } |
23780 |
++ |
23781 |
++ va_start(args, fmt); |
23782 |
++ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args); |
23783 |
++ va_end(args); |
23784 |
++ |
23785 |
++ learn_buffer_len += len + 1; |
23786 |
++ |
23787 |
++ spin_unlock(&gr_learn_lock); |
23788 |
++ wake_up_interruptible(&learn_wait); |
23789 |
++ |
23790 |
++ return; |
23791 |
++} |
23792 |
++ |
23793 |
++static int |
23794 |
++open_learn(struct inode *inode, struct file *file) |
23795 |
++{ |
23796 |
++ if (file->f_mode & FMODE_READ && gr_learn_attached) |
23797 |
++ return -EBUSY; |
23798 |
++ if (file->f_mode & FMODE_READ) { |
23799 |
++ int retval = 0; |
23800 |
++ down(&gr_learn_user_sem); |
23801 |
++ if (learn_buffer == NULL) |
23802 |
++ learn_buffer = vmalloc(LEARN_BUFFER_SIZE); |
23803 |
++ if (learn_buffer_user == NULL) |
23804 |
++ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE); |
23805 |
++ if (learn_buffer == NULL) { |
23806 |
++ retval = -ENOMEM; |
23807 |
++ goto out_error; |
23808 |
++ } |
23809 |
++ if (learn_buffer_user == NULL) { |
23810 |
++ retval = -ENOMEM; |
23811 |
++ goto out_error; |
23812 |
++ } |
23813 |
++ learn_buffer_len = 0; |
23814 |
++ learn_buffer_user_len = 0; |
23815 |
++ gr_learn_attached = 1; |
23816 |
++out_error: |
23817 |
++ up(&gr_learn_user_sem); |
23818 |
++ return retval; |
23819 |
++ } |
23820 |
++ return 0; |
23821 |
++} |
23822 |
++ |
23823 |
++static int |
23824 |
++close_learn(struct inode *inode, struct file *file) |
23825 |
++{ |
23826 |
++ char *tmp; |
23827 |
++ |
23828 |
++ if (file->f_mode & FMODE_READ) { |
23829 |
++ down(&gr_learn_user_sem); |
23830 |
++ if (learn_buffer != NULL) { |
23831 |
++ spin_lock(&gr_learn_lock); |
23832 |
++ tmp = learn_buffer; |
23833 |
++ learn_buffer = NULL; |
23834 |
++ spin_unlock(&gr_learn_lock); |
23835 |
++ vfree(tmp); |
23836 |
++ } |
23837 |
++ if (learn_buffer_user != NULL) { |
23838 |
++ vfree(learn_buffer_user); |
23839 |
++ learn_buffer_user = NULL; |
23840 |
++ } |
23841 |
++ learn_buffer_len = 0; |
23842 |
++ learn_buffer_user_len = 0; |
23843 |
++ gr_learn_attached = 0; |
23844 |
++ up(&gr_learn_user_sem); |
23845 |
++ } |
23846 |
++ |
23847 |
++ return 0; |
23848 |
++} |
23849 |
++ |
23850 |
++struct file_operations grsec_fops = { |
23851 |
++ .read = read_learn, |
23852 |
++ .write = write_grsec_handler, |
23853 |
++ .open = open_learn, |
23854 |
++ .release = close_learn, |
23855 |
++ .poll = poll_learn, |
23856 |
++}; |
23857 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_res.c linux-2.6.23.15-grsec/grsecurity/gracl_res.c |
23858 |
+--- linux-2.6.23.15/grsecurity/gracl_res.c 1970-01-01 01:00:00.000000000 +0100 |
23859 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_res.c 2008-02-11 10:37:44.000000000 +0000 |
23860 |
+@@ -0,0 +1,45 @@ |
23861 |
++#include <linux/kernel.h> |
23862 |
++#include <linux/sched.h> |
23863 |
++#include <linux/gracl.h> |
23864 |
++#include <linux/grinternal.h> |
23865 |
++ |
23866 |
++static const char *restab_log[] = { |
23867 |
++ [RLIMIT_CPU] = "RLIMIT_CPU", |
23868 |
++ [RLIMIT_FSIZE] = "RLIMIT_FSIZE", |
23869 |
++ [RLIMIT_DATA] = "RLIMIT_DATA", |
23870 |
++ [RLIMIT_STACK] = "RLIMIT_STACK", |
23871 |
++ [RLIMIT_CORE] = "RLIMIT_CORE", |
23872 |
++ [RLIMIT_RSS] = "RLIMIT_RSS", |
23873 |
++ [RLIMIT_NPROC] = "RLIMIT_NPROC", |
23874 |
++ [RLIMIT_NOFILE] = "RLIMIT_NOFILE", |
23875 |
++ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK", |
23876 |
++ [RLIMIT_AS] = "RLIMIT_AS", |
23877 |
++ [RLIMIT_LOCKS] = "RLIMIT_LOCKS", |
23878 |
++ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH" |
23879 |
++}; |
23880 |
++ |
23881 |
++void |
23882 |
++gr_log_resource(const struct task_struct *task, |
23883 |
++ const int res, const unsigned long wanted, const int gt) |
23884 |
++{ |
23885 |
++ if (res == RLIMIT_NPROC && |
23886 |
++ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || |
23887 |
++ cap_raised(task->cap_effective, CAP_SYS_RESOURCE))) |
23888 |
++ return; |
23889 |
++ else if (res == RLIMIT_MEMLOCK && |
23890 |
++ cap_raised(task->cap_effective, CAP_IPC_LOCK)) |
23891 |
++ return; |
23892 |
++ |
23893 |
++ if (!gr_acl_is_enabled() && !grsec_resource_logging) |
23894 |
++ return; |
23895 |
++ |
23896 |
++ preempt_disable(); |
23897 |
++ |
23898 |
++ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) || |
23899 |
++ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) && |
23900 |
++ task->signal->rlim[res].rlim_cur != RLIM_INFINITY)) |
23901 |
++ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur); |
23902 |
++ preempt_enable_no_resched(); |
23903 |
++ |
23904 |
++ return; |
23905 |
++} |
23906 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_segv.c linux-2.6.23.15-grsec/grsecurity/gracl_segv.c |
23907 |
+--- linux-2.6.23.15/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100 |
23908 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_segv.c 2008-02-11 10:37:44.000000000 +0000 |
23909 |
+@@ -0,0 +1,301 @@ |
23910 |
++#include <linux/kernel.h> |
23911 |
++#include <linux/mm.h> |
23912 |
++#include <asm/uaccess.h> |
23913 |
++#include <asm/errno.h> |
23914 |
++#include <asm/mman.h> |
23915 |
++#include <net/sock.h> |
23916 |
++#include <linux/file.h> |
23917 |
++#include <linux/fs.h> |
23918 |
++#include <linux/net.h> |
23919 |
++#include <linux/in.h> |
23920 |
++#include <linux/smp_lock.h> |
23921 |
++#include <linux/slab.h> |
23922 |
++#include <linux/types.h> |
23923 |
++#include <linux/sched.h> |
23924 |
++#include <linux/timer.h> |
23925 |
++#include <linux/gracl.h> |
23926 |
++#include <linux/grsecurity.h> |
23927 |
++#include <linux/grinternal.h> |
23928 |
++ |
23929 |
++static struct crash_uid *uid_set; |
23930 |
++static unsigned short uid_used; |
23931 |
++static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED; |
23932 |
++extern rwlock_t gr_inode_lock; |
23933 |
++extern struct acl_subject_label * |
23934 |
++ lookup_acl_subj_label(const ino_t inode, const dev_t dev, |
23935 |
++ struct acl_role_label *role); |
23936 |
++extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t); |
23937 |
++ |
23938 |
++int |
23939 |
++gr_init_uidset(void) |
23940 |
++{ |
23941 |
++ uid_set = |
23942 |
++ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL); |
23943 |
++ uid_used = 0; |
23944 |
++ |
23945 |
++ return uid_set ? 1 : 0; |
23946 |
++} |
23947 |
++ |
23948 |
++void |
23949 |
++gr_free_uidset(void) |
23950 |
++{ |
23951 |
++ if (uid_set) |
23952 |
++ kfree(uid_set); |
23953 |
++ |
23954 |
++ return; |
23955 |
++} |
23956 |
++ |
23957 |
++int |
23958 |
++gr_find_uid(const uid_t uid) |
23959 |
++{ |
23960 |
++ struct crash_uid *tmp = uid_set; |
23961 |
++ uid_t buid; |
23962 |
++ int low = 0, high = uid_used - 1, mid; |
23963 |
++ |
23964 |
++ while (high >= low) { |
23965 |
++ mid = (low + high) >> 1; |
23966 |
++ buid = tmp[mid].uid; |
23967 |
++ if (buid == uid) |
23968 |
++ return mid; |
23969 |
++ if (buid > uid) |
23970 |
++ high = mid - 1; |
23971 |
++ if (buid < uid) |
23972 |
++ low = mid + 1; |
23973 |
++ } |
23974 |
++ |
23975 |
++ return -1; |
23976 |
++} |
23977 |
++ |
23978 |
++static __inline__ void |
23979 |
++gr_insertsort(void) |
23980 |
++{ |
23981 |
++ unsigned short i, j; |
23982 |
++ struct crash_uid index; |
23983 |
++ |
23984 |
++ for (i = 1; i < uid_used; i++) { |
23985 |
++ index = uid_set[i]; |
23986 |
++ j = i; |
23987 |
++ while ((j > 0) && uid_set[j - 1].uid > index.uid) { |
23988 |
++ uid_set[j] = uid_set[j - 1]; |
23989 |
++ j--; |
23990 |
++ } |
23991 |
++ uid_set[j] = index; |
23992 |
++ } |
23993 |
++ |
23994 |
++ return; |
23995 |
++} |
23996 |
++ |
23997 |
++static __inline__ void |
23998 |
++gr_insert_uid(const uid_t uid, const unsigned long expires) |
23999 |
++{ |
24000 |
++ int loc; |
24001 |
++ |
24002 |
++ if (uid_used == GR_UIDTABLE_MAX) |
24003 |
++ return; |
24004 |
++ |
24005 |
++ loc = gr_find_uid(uid); |
24006 |
++ |
24007 |
++ if (loc >= 0) { |
24008 |
++ uid_set[loc].expires = expires; |
24009 |
++ return; |
24010 |
++ } |
24011 |
++ |
24012 |
++ uid_set[uid_used].uid = uid; |
24013 |
++ uid_set[uid_used].expires = expires; |
24014 |
++ uid_used++; |
24015 |
++ |
24016 |
++ gr_insertsort(); |
24017 |
++ |
24018 |
++ return; |
24019 |
++} |
24020 |
++ |
24021 |
++void |
24022 |
++gr_remove_uid(const unsigned short loc) |
24023 |
++{ |
24024 |
++ unsigned short i; |
24025 |
++ |
24026 |
++ for (i = loc + 1; i < uid_used; i++) |
24027 |
++ uid_set[i - 1] = uid_set[i]; |
24028 |
++ |
24029 |
++ uid_used--; |
24030 |
++ |
24031 |
++ return; |
24032 |
++} |
24033 |
++ |
24034 |
++int |
24035 |
++gr_check_crash_uid(const uid_t uid) |
24036 |
++{ |
24037 |
++ int loc; |
24038 |
++ int ret = 0; |
24039 |
++ |
24040 |
++ if (unlikely(!gr_acl_is_enabled())) |
24041 |
++ return 0; |
24042 |
++ |
24043 |
++ spin_lock(&gr_uid_lock); |
24044 |
++ loc = gr_find_uid(uid); |
24045 |
++ |
24046 |
++ if (loc < 0) |
24047 |
++ goto out_unlock; |
24048 |
++ |
24049 |
++ if (time_before_eq(uid_set[loc].expires, get_seconds())) |
24050 |
++ gr_remove_uid(loc); |
24051 |
++ else |
24052 |
++ ret = 1; |
24053 |
++ |
24054 |
++out_unlock: |
24055 |
++ spin_unlock(&gr_uid_lock); |
24056 |
++ return ret; |
24057 |
++} |
24058 |
++ |
24059 |
++static __inline__ int |
24060 |
++proc_is_setxid(const struct task_struct *task) |
24061 |
++{ |
24062 |
++ if (task->uid != task->euid || task->uid != task->suid || |
24063 |
++ task->uid != task->fsuid) |
24064 |
++ return 1; |
24065 |
++ if (task->gid != task->egid || task->gid != task->sgid || |
24066 |
++ task->gid != task->fsgid) |
24067 |
++ return 1; |
24068 |
++ |
24069 |
++ return 0; |
24070 |
++} |
24071 |
++static __inline__ int |
24072 |
++gr_fake_force_sig(int sig, struct task_struct *t) |
24073 |
++{ |
24074 |
++ unsigned long int flags; |
24075 |
++ int ret, blocked, ignored; |
24076 |
++ struct k_sigaction *action; |
24077 |
++ |
24078 |
++ spin_lock_irqsave(&t->sighand->siglock, flags); |
24079 |
++ action = &t->sighand->action[sig-1]; |
24080 |
++ ignored = action->sa.sa_handler == SIG_IGN; |
24081 |
++ blocked = sigismember(&t->blocked, sig); |
24082 |
++ if (blocked || ignored) { |
24083 |
++ action->sa.sa_handler = SIG_DFL; |
24084 |
++ if (blocked) { |
24085 |
++ sigdelset(&t->blocked, sig); |
24086 |
++ recalc_sigpending_and_wake(t); |
24087 |
++ } |
24088 |
++ } |
24089 |
++ ret = specific_send_sig_info(sig, (void*)1L, t); |
24090 |
++ spin_unlock_irqrestore(&t->sighand->siglock, flags); |
24091 |
++ |
24092 |
++ return ret; |
24093 |
++} |
24094 |
++ |
24095 |
++void |
24096 |
++gr_handle_crash(struct task_struct *task, const int sig) |
24097 |
++{ |
24098 |
++ struct acl_subject_label *curr; |
24099 |
++ struct acl_subject_label *curr2; |
24100 |
++ struct task_struct *tsk, *tsk2; |
24101 |
++ |
24102 |
++ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL) |
24103 |
++ return; |
24104 |
++ |
24105 |
++ if (unlikely(!gr_acl_is_enabled())) |
24106 |
++ return; |
24107 |
++ |
24108 |
++ curr = task->acl; |
24109 |
++ |
24110 |
++ if (!(curr->resmask & (1 << GR_CRASH_RES))) |
24111 |
++ return; |
24112 |
++ |
24113 |
++ if (time_before_eq(curr->expires, get_seconds())) { |
24114 |
++ curr->expires = 0; |
24115 |
++ curr->crashes = 0; |
24116 |
++ } |
24117 |
++ |
24118 |
++ curr->crashes++; |
24119 |
++ |
24120 |
++ if (!curr->expires) |
24121 |
++ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max; |
24122 |
++ |
24123 |
++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && |
24124 |
++ time_after(curr->expires, get_seconds())) { |
24125 |
++ if (task->uid && proc_is_setxid(task)) { |
24126 |
++ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); |
24127 |
++ spin_lock(&gr_uid_lock); |
24128 |
++ gr_insert_uid(task->uid, curr->expires); |
24129 |
++ spin_unlock(&gr_uid_lock); |
24130 |
++ curr->expires = 0; |
24131 |
++ curr->crashes = 0; |
24132 |
++ read_lock(&tasklist_lock); |
24133 |
++ do_each_thread(tsk2, tsk) { |
24134 |
++ if (tsk != task && tsk->uid == task->uid) |
24135 |
++ gr_fake_force_sig(SIGKILL, tsk); |
24136 |
++ } while_each_thread(tsk2, tsk); |
24137 |
++ read_unlock(&tasklist_lock); |
24138 |
++ } else { |
24139 |
++ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); |
24140 |
++ read_lock(&tasklist_lock); |
24141 |
++ do_each_thread(tsk2, tsk) { |
24142 |
++ if (likely(tsk != task)) { |
24143 |
++ curr2 = tsk->acl; |
24144 |
++ |
24145 |
++ if (curr2->device == curr->device && |
24146 |
++ curr2->inode == curr->inode) |
24147 |
++ gr_fake_force_sig(SIGKILL, tsk); |
24148 |
++ } |
24149 |
++ } while_each_thread(tsk2, tsk); |
24150 |
++ read_unlock(&tasklist_lock); |
24151 |
++ } |
24152 |
++ } |
24153 |
++ |
24154 |
++ return; |
24155 |
++} |
24156 |
++ |
24157 |
++int |
24158 |
++gr_check_crash_exec(const struct file *filp) |
24159 |
++{ |
24160 |
++ struct acl_subject_label *curr; |
24161 |
++ |
24162 |
++ if (unlikely(!gr_acl_is_enabled())) |
24163 |
++ return 0; |
24164 |
++ |
24165 |
++ read_lock(&gr_inode_lock); |
24166 |
++ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino, |
24167 |
++ filp->f_dentry->d_inode->i_sb->s_dev, |
24168 |
++ current->role); |
24169 |
++ read_unlock(&gr_inode_lock); |
24170 |
++ |
24171 |
++ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) || |
24172 |
++ (!curr->crashes && !curr->expires)) |
24173 |
++ return 0; |
24174 |
++ |
24175 |
++ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && |
24176 |
++ time_after(curr->expires, get_seconds())) |
24177 |
++ return 1; |
24178 |
++ else if (time_before_eq(curr->expires, get_seconds())) { |
24179 |
++ curr->crashes = 0; |
24180 |
++ curr->expires = 0; |
24181 |
++ } |
24182 |
++ |
24183 |
++ return 0; |
24184 |
++} |
24185 |
++ |
24186 |
++void |
24187 |
++gr_handle_alertkill(struct task_struct *task) |
24188 |
++{ |
24189 |
++ struct acl_subject_label *curracl; |
24190 |
++ __u32 curr_ip; |
24191 |
++ struct task_struct *p, *p2; |
24192 |
++ |
24193 |
++ if (unlikely(!gr_acl_is_enabled())) |
24194 |
++ return; |
24195 |
++ |
24196 |
++ curracl = task->acl; |
24197 |
++ curr_ip = task->signal->curr_ip; |
24198 |
++ |
24199 |
++ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) { |
24200 |
++ read_lock(&tasklist_lock); |
24201 |
++ do_each_thread(p2, p) { |
24202 |
++ if (p->signal->curr_ip == curr_ip) |
24203 |
++ gr_fake_force_sig(SIGKILL, p); |
24204 |
++ } while_each_thread(p2, p); |
24205 |
++ read_unlock(&tasklist_lock); |
24206 |
++ } else if (curracl->mode & GR_KILLPROC) |
24207 |
++ gr_fake_force_sig(SIGKILL, task); |
24208 |
++ |
24209 |
++ return; |
24210 |
++} |
24211 |
+diff -Nurp linux-2.6.23.15/grsecurity/gracl_shm.c linux-2.6.23.15-grsec/grsecurity/gracl_shm.c |
24212 |
+--- linux-2.6.23.15/grsecurity/gracl_shm.c 1970-01-01 01:00:00.000000000 +0100 |
24213 |
++++ linux-2.6.23.15-grsec/grsecurity/gracl_shm.c 2008-02-11 10:37:44.000000000 +0000 |
24214 |
+@@ -0,0 +1,33 @@ |
24215 |
++#include <linux/kernel.h> |
24216 |
++#include <linux/mm.h> |
24217 |
++#include <linux/sched.h> |
24218 |
++#include <linux/file.h> |
24219 |
++#include <linux/ipc.h> |
24220 |
++#include <linux/gracl.h> |
24221 |
++#include <linux/grsecurity.h> |
24222 |
++#include <linux/grinternal.h> |
24223 |
++ |
24224 |
++int |
24225 |
++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
24226 |
++ const time_t shm_createtime, const uid_t cuid, const int shmid) |
24227 |
++{ |
24228 |
++ struct task_struct *task; |
24229 |
++ |
24230 |
++ if (!gr_acl_is_enabled()) |
24231 |
++ return 1; |
24232 |
++ |
24233 |
++ task = find_task_by_pid(shm_cprid); |
24234 |
++ |
24235 |
++ if (unlikely(!task)) |
24236 |
++ task = find_task_by_pid(shm_lapid); |
24237 |
++ |
24238 |
++ if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) || |
24239 |
++ (task->pid == shm_lapid)) && |
24240 |
++ (task->acl->mode & GR_PROTSHM) && |
24241 |
++ (task->acl != current->acl))) { |
24242 |
++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid); |
24243 |
++ return 0; |
24244 |
++ } |
24245 |
++ |
24246 |
++ return 1; |
24247 |
++} |
24248 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_chdir.c linux-2.6.23.15-grsec/grsecurity/grsec_chdir.c |
24249 |
+--- linux-2.6.23.15/grsecurity/grsec_chdir.c 1970-01-01 01:00:00.000000000 +0100 |
24250 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_chdir.c 2008-02-11 10:37:44.000000000 +0000 |
24251 |
+@@ -0,0 +1,19 @@ |
24252 |
++#include <linux/kernel.h> |
24253 |
++#include <linux/sched.h> |
24254 |
++#include <linux/fs.h> |
24255 |
++#include <linux/file.h> |
24256 |
++#include <linux/grsecurity.h> |
24257 |
++#include <linux/grinternal.h> |
24258 |
++ |
24259 |
++void |
24260 |
++gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt) |
24261 |
++{ |
24262 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR |
24263 |
++ if ((grsec_enable_chdir && grsec_enable_group && |
24264 |
++ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir && |
24265 |
++ !grsec_enable_group)) { |
24266 |
++ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt); |
24267 |
++ } |
24268 |
++#endif |
24269 |
++ return; |
24270 |
++} |
24271 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_chroot.c linux-2.6.23.15-grsec/grsecurity/grsec_chroot.c |
24272 |
+--- linux-2.6.23.15/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100 |
24273 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_chroot.c 2008-02-11 10:37:44.000000000 +0000 |
24274 |
+@@ -0,0 +1,335 @@ |
24275 |
++#include <linux/kernel.h> |
24276 |
++#include <linux/module.h> |
24277 |
++#include <linux/sched.h> |
24278 |
++#include <linux/file.h> |
24279 |
++#include <linux/fs.h> |
24280 |
++#include <linux/mount.h> |
24281 |
++#include <linux/types.h> |
24282 |
++#include <linux/pid_namespace.h> |
24283 |
++#include <linux/grsecurity.h> |
24284 |
++#include <linux/grinternal.h> |
24285 |
++ |
24286 |
++int |
24287 |
++gr_handle_chroot_unix(const pid_t pid) |
24288 |
++{ |
24289 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
24290 |
++ struct pid *spid = NULL; |
24291 |
++ |
24292 |
++ if (unlikely(!grsec_enable_chroot_unix)) |
24293 |
++ return 1; |
24294 |
++ |
24295 |
++ if (likely(!proc_is_chrooted(current))) |
24296 |
++ return 1; |
24297 |
++ |
24298 |
++ read_lock(&tasklist_lock); |
24299 |
++ |
24300 |
++ spid = find_pid(pid); |
24301 |
++ if (spid) { |
24302 |
++ struct task_struct *p; |
24303 |
++ p = pid_task(spid, PIDTYPE_PID); |
24304 |
++ task_lock(p); |
24305 |
++ if (unlikely(!have_same_root(current, p))) { |
24306 |
++ task_unlock(p); |
24307 |
++ read_unlock(&tasklist_lock); |
24308 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG); |
24309 |
++ return 0; |
24310 |
++ } |
24311 |
++ task_unlock(p); |
24312 |
++ } |
24313 |
++ read_unlock(&tasklist_lock); |
24314 |
++#endif |
24315 |
++ return 1; |
24316 |
++} |
24317 |
++ |
24318 |
++int |
24319 |
++gr_handle_chroot_nice(void) |
24320 |
++{ |
24321 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
24322 |
++ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) { |
24323 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG); |
24324 |
++ return -EPERM; |
24325 |
++ } |
24326 |
++#endif |
24327 |
++ return 0; |
24328 |
++} |
24329 |
++ |
24330 |
++int |
24331 |
++gr_handle_chroot_setpriority(struct task_struct *p, const int niceval) |
24332 |
++{ |
24333 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
24334 |
++ if (grsec_enable_chroot_nice && (niceval < task_nice(p)) |
24335 |
++ && proc_is_chrooted(current)) { |
24336 |
++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid); |
24337 |
++ return -EACCES; |
24338 |
++ } |
24339 |
++#endif |
24340 |
++ return 0; |
24341 |
++} |
24342 |
++ |
24343 |
++int |
24344 |
++gr_handle_chroot_rawio(const struct inode *inode) |
24345 |
++{ |
24346 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
24347 |
++ if (grsec_enable_chroot_caps && proc_is_chrooted(current) && |
24348 |
++ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO)) |
24349 |
++ return 1; |
24350 |
++#endif |
24351 |
++ return 0; |
24352 |
++} |
24353 |
++ |
24354 |
++int |
24355 |
++gr_pid_is_chrooted(struct task_struct *p) |
24356 |
++{ |
24357 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK |
24358 |
++ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL) |
24359 |
++ return 0; |
24360 |
++ |
24361 |
++ task_lock(p); |
24362 |
++ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) || |
24363 |
++ !have_same_root(current, p)) { |
24364 |
++ task_unlock(p); |
24365 |
++ return 1; |
24366 |
++ } |
24367 |
++ task_unlock(p); |
24368 |
++#endif |
24369 |
++ return 0; |
24370 |
++} |
24371 |
++ |
24372 |
++EXPORT_SYMBOL(gr_pid_is_chrooted); |
24373 |
++ |
24374 |
++#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR) |
24375 |
++int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt) |
24376 |
++{ |
24377 |
++ struct dentry *dentry = (struct dentry *)u_dentry; |
24378 |
++ struct vfsmount *mnt = (struct vfsmount *)u_mnt; |
24379 |
++ struct dentry *realroot; |
24380 |
++ struct vfsmount *realrootmnt; |
24381 |
++ struct dentry *currentroot; |
24382 |
++ struct vfsmount *currentmnt; |
24383 |
++ struct task_struct *reaper = child_reaper(current); |
24384 |
++ int ret = 1; |
24385 |
++ |
24386 |
++ read_lock(&reaper->fs->lock); |
24387 |
++ realrootmnt = mntget(reaper->fs->rootmnt); |
24388 |
++ realroot = dget(reaper->fs->root); |
24389 |
++ read_unlock(&reaper->fs->lock); |
24390 |
++ |
24391 |
++ read_lock(¤t->fs->lock); |
24392 |
++ currentmnt = mntget(current->fs->rootmnt); |
24393 |
++ currentroot = dget(current->fs->root); |
24394 |
++ read_unlock(¤t->fs->lock); |
24395 |
++ |
24396 |
++ spin_lock(&dcache_lock); |
24397 |
++ for (;;) { |
24398 |
++ if (unlikely((dentry == realroot && mnt == realrootmnt) |
24399 |
++ || (dentry == currentroot && mnt == currentmnt))) |
24400 |
++ break; |
24401 |
++ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { |
24402 |
++ if (mnt->mnt_parent == mnt) |
24403 |
++ break; |
24404 |
++ dentry = mnt->mnt_mountpoint; |
24405 |
++ mnt = mnt->mnt_parent; |
24406 |
++ continue; |
24407 |
++ } |
24408 |
++ dentry = dentry->d_parent; |
24409 |
++ } |
24410 |
++ spin_unlock(&dcache_lock); |
24411 |
++ |
24412 |
++ dput(currentroot); |
24413 |
++ mntput(currentmnt); |
24414 |
++ |
24415 |
++ /* access is outside of chroot */ |
24416 |
++ if (dentry == realroot && mnt == realrootmnt) |
24417 |
++ ret = 0; |
24418 |
++ |
24419 |
++ dput(realroot); |
24420 |
++ mntput(realrootmnt); |
24421 |
++ return ret; |
24422 |
++} |
24423 |
++#endif |
24424 |
++ |
24425 |
++int |
24426 |
++gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt) |
24427 |
++{ |
24428 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR |
24429 |
++ if (!grsec_enable_chroot_fchdir) |
24430 |
++ return 1; |
24431 |
++ |
24432 |
++ if (!proc_is_chrooted(current)) |
24433 |
++ return 1; |
24434 |
++ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) { |
24435 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt); |
24436 |
++ return 0; |
24437 |
++ } |
24438 |
++#endif |
24439 |
++ return 1; |
24440 |
++} |
24441 |
++ |
24442 |
++int |
24443 |
++gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
24444 |
++ const time_t shm_createtime) |
24445 |
++{ |
24446 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT |
24447 |
++ struct pid *pid = NULL; |
24448 |
++ time_t starttime; |
24449 |
++ |
24450 |
++ if (unlikely(!grsec_enable_chroot_shmat)) |
24451 |
++ return 1; |
24452 |
++ |
24453 |
++ if (likely(!proc_is_chrooted(current))) |
24454 |
++ return 1; |
24455 |
++ |
24456 |
++ read_lock(&tasklist_lock); |
24457 |
++ |
24458 |
++ pid = find_pid(shm_cprid); |
24459 |
++ if (pid) { |
24460 |
++ struct task_struct *p; |
24461 |
++ p = pid_task(pid, PIDTYPE_PID); |
24462 |
++ task_lock(p); |
24463 |
++ starttime = p->start_time.tv_sec; |
24464 |
++ if (unlikely(!have_same_root(current, p) && |
24465 |
++ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) { |
24466 |
++ task_unlock(p); |
24467 |
++ read_unlock(&tasklist_lock); |
24468 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG); |
24469 |
++ return 0; |
24470 |
++ } |
24471 |
++ task_unlock(p); |
24472 |
++ } else { |
24473 |
++ pid = find_pid(shm_lapid); |
24474 |
++ if (pid) { |
24475 |
++ struct task_struct *p; |
24476 |
++ p = pid_task(pid, PIDTYPE_PID); |
24477 |
++ task_lock(p); |
24478 |
++ if (unlikely(!have_same_root(current, p))) { |
24479 |
++ task_unlock(p); |
24480 |
++ read_unlock(&tasklist_lock); |
24481 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG); |
24482 |
++ return 0; |
24483 |
++ } |
24484 |
++ task_unlock(p); |
24485 |
++ } |
24486 |
++ } |
24487 |
++ |
24488 |
++ read_unlock(&tasklist_lock); |
24489 |
++#endif |
24490 |
++ return 1; |
24491 |
++} |
24492 |
++ |
24493 |
++void |
24494 |
++gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt) |
24495 |
++{ |
24496 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG |
24497 |
++ if (grsec_enable_chroot_execlog && proc_is_chrooted(current)) |
24498 |
++ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt); |
24499 |
++#endif |
24500 |
++ return; |
24501 |
++} |
24502 |
++ |
24503 |
++int |
24504 |
++gr_handle_chroot_mknod(const struct dentry *dentry, |
24505 |
++ const struct vfsmount *mnt, const int mode) |
24506 |
++{ |
24507 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD |
24508 |
++ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && |
24509 |
++ proc_is_chrooted(current)) { |
24510 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt); |
24511 |
++ return -EPERM; |
24512 |
++ } |
24513 |
++#endif |
24514 |
++ return 0; |
24515 |
++} |
24516 |
++ |
24517 |
++int |
24518 |
++gr_handle_chroot_mount(const struct dentry *dentry, |
24519 |
++ const struct vfsmount *mnt, const char *dev_name) |
24520 |
++{ |
24521 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT |
24522 |
++ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) { |
24523 |
++ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt); |
24524 |
++ return -EPERM; |
24525 |
++ } |
24526 |
++#endif |
24527 |
++ return 0; |
24528 |
++} |
24529 |
++ |
24530 |
++int |
24531 |
++gr_handle_chroot_pivot(void) |
24532 |
++{ |
24533 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT |
24534 |
++ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) { |
24535 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG); |
24536 |
++ return -EPERM; |
24537 |
++ } |
24538 |
++#endif |
24539 |
++ return 0; |
24540 |
++} |
24541 |
++ |
24542 |
++int |
24543 |
++gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt) |
24544 |
++{ |
24545 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE |
24546 |
++ if (grsec_enable_chroot_double && proc_is_chrooted(current) && |
24547 |
++ !gr_is_outside_chroot(dentry, mnt)) { |
24548 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt); |
24549 |
++ return -EPERM; |
24550 |
++ } |
24551 |
++#endif |
24552 |
++ return 0; |
24553 |
++} |
24554 |
++ |
24555 |
++void |
24556 |
++gr_handle_chroot_caps(struct task_struct *task) |
24557 |
++{ |
24558 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
24559 |
++ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) { |
24560 |
++ task->cap_permitted = |
24561 |
++ cap_drop(task->cap_permitted, GR_CHROOT_CAPS); |
24562 |
++ task->cap_inheritable = |
24563 |
++ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS); |
24564 |
++ task->cap_effective = |
24565 |
++ cap_drop(task->cap_effective, GR_CHROOT_CAPS); |
24566 |
++ } |
24567 |
++#endif |
24568 |
++ return; |
24569 |
++} |
24570 |
++ |
24571 |
++int |
24572 |
++gr_handle_chroot_sysctl(const int op) |
24573 |
++{ |
24574 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL |
24575 |
++ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current) |
24576 |
++ && (op & 002)) |
24577 |
++ return -EACCES; |
24578 |
++#endif |
24579 |
++ return 0; |
24580 |
++} |
24581 |
++ |
24582 |
++void |
24583 |
++gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt) |
24584 |
++{ |
24585 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR |
24586 |
++ if (grsec_enable_chroot_chdir) |
24587 |
++ set_fs_pwd(current->fs, mnt, dentry); |
24588 |
++#endif |
24589 |
++ return; |
24590 |
++} |
24591 |
++ |
24592 |
++int |
24593 |
++gr_handle_chroot_chmod(const struct dentry *dentry, |
24594 |
++ const struct vfsmount *mnt, const int mode) |
24595 |
++{ |
24596 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD |
24597 |
++ if (grsec_enable_chroot_chmod && |
24598 |
++ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) && |
24599 |
++ proc_is_chrooted(current)) { |
24600 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt); |
24601 |
++ return -EPERM; |
24602 |
++ } |
24603 |
++#endif |
24604 |
++ return 0; |
24605 |
++} |
24606 |
++ |
24607 |
++#ifdef CONFIG_SECURITY |
24608 |
++EXPORT_SYMBOL(gr_handle_chroot_caps); |
24609 |
++#endif |
24610 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_disabled.c linux-2.6.23.15-grsec/grsecurity/grsec_disabled.c |
24611 |
+--- linux-2.6.23.15/grsecurity/grsec_disabled.c 1970-01-01 01:00:00.000000000 +0100 |
24612 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_disabled.c 2008-02-11 10:37:44.000000000 +0000 |
24613 |
+@@ -0,0 +1,418 @@ |
24614 |
++#include <linux/kernel.h> |
24615 |
++#include <linux/module.h> |
24616 |
++#include <linux/sched.h> |
24617 |
++#include <linux/file.h> |
24618 |
++#include <linux/fs.h> |
24619 |
++#include <linux/kdev_t.h> |
24620 |
++#include <linux/net.h> |
24621 |
++#include <linux/in.h> |
24622 |
++#include <linux/ip.h> |
24623 |
++#include <linux/skbuff.h> |
24624 |
++#include <linux/sysctl.h> |
24625 |
++ |
24626 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
24627 |
++void |
24628 |
++pax_set_initial_flags(struct linux_binprm *bprm) |
24629 |
++{ |
24630 |
++ return; |
24631 |
++} |
24632 |
++#endif |
24633 |
++ |
24634 |
++#ifdef CONFIG_SYSCTL |
24635 |
++__u32 |
24636 |
++gr_handle_sysctl(const struct ctl_table * table, const int op) |
24637 |
++{ |
24638 |
++ return 0; |
24639 |
++} |
24640 |
++#endif |
24641 |
++ |
24642 |
++int |
24643 |
++gr_acl_is_enabled(void) |
24644 |
++{ |
24645 |
++ return 0; |
24646 |
++} |
24647 |
++ |
24648 |
++int |
24649 |
++gr_handle_rawio(const struct inode *inode) |
24650 |
++{ |
24651 |
++ return 0; |
24652 |
++} |
24653 |
++ |
24654 |
++void |
24655 |
++gr_acl_handle_psacct(struct task_struct *task, const long code) |
24656 |
++{ |
24657 |
++ return; |
24658 |
++} |
24659 |
++ |
24660 |
++int |
24661 |
++gr_handle_ptrace(struct task_struct *task, const long request) |
24662 |
++{ |
24663 |
++ return 0; |
24664 |
++} |
24665 |
++ |
24666 |
++int |
24667 |
++gr_handle_proc_ptrace(struct task_struct *task) |
24668 |
++{ |
24669 |
++ return 0; |
24670 |
++} |
24671 |
++ |
24672 |
++void |
24673 |
++gr_learn_resource(const struct task_struct *task, |
24674 |
++ const int res, const unsigned long wanted, const int gt) |
24675 |
++{ |
24676 |
++ return; |
24677 |
++} |
24678 |
++ |
24679 |
++int |
24680 |
++gr_set_acls(const int type) |
24681 |
++{ |
24682 |
++ return 0; |
24683 |
++} |
24684 |
++ |
24685 |
++int |
24686 |
++gr_check_hidden_task(const struct task_struct *tsk) |
24687 |
++{ |
24688 |
++ return 0; |
24689 |
++} |
24690 |
++ |
24691 |
++int |
24692 |
++gr_check_protected_task(const struct task_struct *task) |
24693 |
++{ |
24694 |
++ return 0; |
24695 |
++} |
24696 |
++ |
24697 |
++void |
24698 |
++gr_copy_label(struct task_struct *tsk) |
24699 |
++{ |
24700 |
++ return; |
24701 |
++} |
24702 |
++ |
24703 |
++void |
24704 |
++gr_set_pax_flags(struct task_struct *task) |
24705 |
++{ |
24706 |
++ return; |
24707 |
++} |
24708 |
++ |
24709 |
++int |
24710 |
++gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt) |
24711 |
++{ |
24712 |
++ return 0; |
24713 |
++} |
24714 |
++ |
24715 |
++void |
24716 |
++gr_handle_delete(const ino_t ino, const dev_t dev) |
24717 |
++{ |
24718 |
++ return; |
24719 |
++} |
24720 |
++ |
24721 |
++void |
24722 |
++gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) |
24723 |
++{ |
24724 |
++ return; |
24725 |
++} |
24726 |
++ |
24727 |
++void |
24728 |
++gr_handle_crash(struct task_struct *task, const int sig) |
24729 |
++{ |
24730 |
++ return; |
24731 |
++} |
24732 |
++ |
24733 |
++int |
24734 |
++gr_check_crash_exec(const struct file *filp) |
24735 |
++{ |
24736 |
++ return 0; |
24737 |
++} |
24738 |
++ |
24739 |
++int |
24740 |
++gr_check_crash_uid(const uid_t uid) |
24741 |
++{ |
24742 |
++ return 0; |
24743 |
++} |
24744 |
++ |
24745 |
++void |
24746 |
++gr_handle_rename(struct inode *old_dir, struct inode *new_dir, |
24747 |
++ struct dentry *old_dentry, |
24748 |
++ struct dentry *new_dentry, |
24749 |
++ struct vfsmount *mnt, const __u8 replace) |
24750 |
++{ |
24751 |
++ return; |
24752 |
++} |
24753 |
++ |
24754 |
++int |
24755 |
++gr_search_socket(const int family, const int type, const int protocol) |
24756 |
++{ |
24757 |
++ return 1; |
24758 |
++} |
24759 |
++ |
24760 |
++int |
24761 |
++gr_search_connectbind(const int mode, const struct socket *sock, |
24762 |
++ const struct sockaddr_in *addr) |
24763 |
++{ |
24764 |
++ return 1; |
24765 |
++} |
24766 |
++ |
24767 |
++int |
24768 |
++gr_task_is_capable(struct task_struct *task, const int cap) |
24769 |
++{ |
24770 |
++ return 1; |
24771 |
++} |
24772 |
++ |
24773 |
++int |
24774 |
++gr_is_capable_nolog(const int cap) |
24775 |
++{ |
24776 |
++ return 1; |
24777 |
++} |
24778 |
++ |
24779 |
++void |
24780 |
++gr_handle_alertkill(struct task_struct *task) |
24781 |
++{ |
24782 |
++ return; |
24783 |
++} |
24784 |
++ |
24785 |
++__u32 |
24786 |
++gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt) |
24787 |
++{ |
24788 |
++ return 1; |
24789 |
++} |
24790 |
++ |
24791 |
++__u32 |
24792 |
++gr_acl_handle_hidden_file(const struct dentry * dentry, |
24793 |
++ const struct vfsmount * mnt) |
24794 |
++{ |
24795 |
++ return 1; |
24796 |
++} |
24797 |
++ |
24798 |
++__u32 |
24799 |
++gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, |
24800 |
++ const int fmode) |
24801 |
++{ |
24802 |
++ return 1; |
24803 |
++} |
24804 |
++ |
24805 |
++__u32 |
24806 |
++gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) |
24807 |
++{ |
24808 |
++ return 1; |
24809 |
++} |
24810 |
++ |
24811 |
++__u32 |
24812 |
++gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt) |
24813 |
++{ |
24814 |
++ return 1; |
24815 |
++} |
24816 |
++ |
24817 |
++int |
24818 |
++gr_acl_handle_mmap(const struct file *file, const unsigned long prot, |
24819 |
++ unsigned int *vm_flags) |
24820 |
++{ |
24821 |
++ return 1; |
24822 |
++} |
24823 |
++ |
24824 |
++__u32 |
24825 |
++gr_acl_handle_truncate(const struct dentry * dentry, |
24826 |
++ const struct vfsmount * mnt) |
24827 |
++{ |
24828 |
++ return 1; |
24829 |
++} |
24830 |
++ |
24831 |
++__u32 |
24832 |
++gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt) |
24833 |
++{ |
24834 |
++ return 1; |
24835 |
++} |
24836 |
++ |
24837 |
++__u32 |
24838 |
++gr_acl_handle_access(const struct dentry * dentry, |
24839 |
++ const struct vfsmount * mnt, const int fmode) |
24840 |
++{ |
24841 |
++ return 1; |
24842 |
++} |
24843 |
++ |
24844 |
++__u32 |
24845 |
++gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt, |
24846 |
++ mode_t mode) |
24847 |
++{ |
24848 |
++ return 1; |
24849 |
++} |
24850 |
++ |
24851 |
++__u32 |
24852 |
++gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt, |
24853 |
++ mode_t mode) |
24854 |
++{ |
24855 |
++ return 1; |
24856 |
++} |
24857 |
++ |
24858 |
++__u32 |
24859 |
++gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt) |
24860 |
++{ |
24861 |
++ return 1; |
24862 |
++} |
24863 |
++ |
24864 |
++void |
24865 |
++grsecurity_init(void) |
24866 |
++{ |
24867 |
++ return; |
24868 |
++} |
24869 |
++ |
24870 |
++__u32 |
24871 |
++gr_acl_handle_mknod(const struct dentry * new_dentry, |
24872 |
++ const struct dentry * parent_dentry, |
24873 |
++ const struct vfsmount * parent_mnt, |
24874 |
++ const int mode) |
24875 |
++{ |
24876 |
++ return 1; |
24877 |
++} |
24878 |
++ |
24879 |
++__u32 |
24880 |
++gr_acl_handle_mkdir(const struct dentry * new_dentry, |
24881 |
++ const struct dentry * parent_dentry, |
24882 |
++ const struct vfsmount * parent_mnt) |
24883 |
++{ |
24884 |
++ return 1; |
24885 |
++} |
24886 |
++ |
24887 |
++__u32 |
24888 |
++gr_acl_handle_symlink(const struct dentry * new_dentry, |
24889 |
++ const struct dentry * parent_dentry, |
24890 |
++ const struct vfsmount * parent_mnt, const char *from) |
24891 |
++{ |
24892 |
++ return 1; |
24893 |
++} |
24894 |
++ |
24895 |
++__u32 |
24896 |
++gr_acl_handle_link(const struct dentry * new_dentry, |
24897 |
++ const struct dentry * parent_dentry, |
24898 |
++ const struct vfsmount * parent_mnt, |
24899 |
++ const struct dentry * old_dentry, |
24900 |
++ const struct vfsmount * old_mnt, const char *to) |
24901 |
++{ |
24902 |
++ return 1; |
24903 |
++} |
24904 |
++ |
24905 |
++int |
24906 |
++gr_acl_handle_rename(const struct dentry *new_dentry, |
24907 |
++ const struct dentry *parent_dentry, |
24908 |
++ const struct vfsmount *parent_mnt, |
24909 |
++ const struct dentry *old_dentry, |
24910 |
++ const struct inode *old_parent_inode, |
24911 |
++ const struct vfsmount *old_mnt, const char *newname) |
24912 |
++{ |
24913 |
++ return 0; |
24914 |
++} |
24915 |
++ |
24916 |
++int |
24917 |
++gr_acl_handle_filldir(const struct file *file, const char *name, |
24918 |
++ const int namelen, const ino_t ino) |
24919 |
++{ |
24920 |
++ return 1; |
24921 |
++} |
24922 |
++ |
24923 |
++int |
24924 |
++gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
24925 |
++ const time_t shm_createtime, const uid_t cuid, const int shmid) |
24926 |
++{ |
24927 |
++ return 1; |
24928 |
++} |
24929 |
++ |
24930 |
++int |
24931 |
++gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) |
24932 |
++{ |
24933 |
++ return 1; |
24934 |
++} |
24935 |
++ |
24936 |
++int |
24937 |
++gr_search_accept(const struct socket *sock) |
24938 |
++{ |
24939 |
++ return 1; |
24940 |
++} |
24941 |
++ |
24942 |
++int |
24943 |
++gr_search_listen(const struct socket *sock) |
24944 |
++{ |
24945 |
++ return 1; |
24946 |
++} |
24947 |
++ |
24948 |
++int |
24949 |
++gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) |
24950 |
++{ |
24951 |
++ return 1; |
24952 |
++} |
24953 |
++ |
24954 |
++__u32 |
24955 |
++gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt) |
24956 |
++{ |
24957 |
++ return 1; |
24958 |
++} |
24959 |
++ |
24960 |
++__u32 |
24961 |
++gr_acl_handle_creat(const struct dentry * dentry, |
24962 |
++ const struct dentry * p_dentry, |
24963 |
++ const struct vfsmount * p_mnt, const int fmode, |
24964 |
++ const int imode) |
24965 |
++{ |
24966 |
++ return 1; |
24967 |
++} |
24968 |
++ |
24969 |
++void |
24970 |
++gr_acl_handle_exit(void) |
24971 |
++{ |
24972 |
++ return; |
24973 |
++} |
24974 |
++ |
24975 |
++int |
24976 |
++gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) |
24977 |
++{ |
24978 |
++ return 1; |
24979 |
++} |
24980 |
++ |
24981 |
++void |
24982 |
++gr_set_role_label(const uid_t uid, const gid_t gid) |
24983 |
++{ |
24984 |
++ return; |
24985 |
++} |
24986 |
++ |
24987 |
++int |
24988 |
++gr_acl_handle_procpidmem(const struct task_struct *task) |
24989 |
++{ |
24990 |
++ return 0; |
24991 |
++} |
24992 |
++ |
24993 |
++int |
24994 |
++gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) |
24995 |
++{ |
24996 |
++ return 1; |
24997 |
++} |
24998 |
++ |
24999 |
++int |
25000 |
++gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) |
25001 |
++{ |
25002 |
++ return 1; |
25003 |
++} |
25004 |
++ |
25005 |
++void |
25006 |
++gr_set_kernel_label(struct task_struct *task) |
25007 |
++{ |
25008 |
++ return; |
25009 |
++} |
25010 |
++ |
25011 |
++int |
25012 |
++gr_check_user_change(int real, int effective, int fs) |
25013 |
++{ |
25014 |
++ return 0; |
25015 |
++} |
25016 |
++ |
25017 |
++int |
25018 |
++gr_check_group_change(int real, int effective, int fs) |
25019 |
++{ |
25020 |
++ return 0; |
25021 |
++} |
25022 |
++ |
25023 |
++ |
25024 |
++EXPORT_SYMBOL(gr_task_is_capable); |
25025 |
++EXPORT_SYMBOL(gr_is_capable_nolog); |
25026 |
++EXPORT_SYMBOL(gr_learn_resource); |
25027 |
++EXPORT_SYMBOL(gr_set_kernel_label); |
25028 |
++#ifdef CONFIG_SECURITY |
25029 |
++EXPORT_SYMBOL(gr_check_user_change); |
25030 |
++EXPORT_SYMBOL(gr_check_group_change); |
25031 |
++#endif |
25032 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_exec.c linux-2.6.23.15-grsec/grsecurity/grsec_exec.c |
25033 |
+--- linux-2.6.23.15/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100 |
25034 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_exec.c 2008-02-11 10:37:44.000000000 +0000 |
25035 |
+@@ -0,0 +1,88 @@ |
25036 |
++#include <linux/kernel.h> |
25037 |
++#include <linux/sched.h> |
25038 |
++#include <linux/file.h> |
25039 |
++#include <linux/binfmts.h> |
25040 |
++#include <linux/smp_lock.h> |
25041 |
++#include <linux/fs.h> |
25042 |
++#include <linux/types.h> |
25043 |
++#include <linux/grdefs.h> |
25044 |
++#include <linux/grinternal.h> |
25045 |
++#include <linux/capability.h> |
25046 |
++ |
25047 |
++#include <asm/uaccess.h> |
25048 |
++ |
25049 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
25050 |
++static char gr_exec_arg_buf[132]; |
25051 |
++static DECLARE_MUTEX(gr_exec_arg_sem); |
25052 |
++#endif |
25053 |
++ |
25054 |
++int |
25055 |
++gr_handle_nproc(void) |
25056 |
++{ |
25057 |
++#ifdef CONFIG_GRKERNSEC_EXECVE |
25058 |
++ if (grsec_enable_execve && current->user && |
25059 |
++ (atomic_read(¤t->user->processes) > |
25060 |
++ current->signal->rlim[RLIMIT_NPROC].rlim_cur) && |
25061 |
++ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) { |
25062 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG); |
25063 |
++ return -EAGAIN; |
25064 |
++ } |
25065 |
++#endif |
25066 |
++ return 0; |
25067 |
++} |
25068 |
++ |
25069 |
++void |
25070 |
++gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv) |
25071 |
++{ |
25072 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
25073 |
++ char *grarg = gr_exec_arg_buf; |
25074 |
++ unsigned int i, x, execlen = 0; |
25075 |
++ char c; |
25076 |
++ |
25077 |
++ if (!((grsec_enable_execlog && grsec_enable_group && |
25078 |
++ in_group_p(grsec_audit_gid)) |
25079 |
++ || (grsec_enable_execlog && !grsec_enable_group))) |
25080 |
++ return; |
25081 |
++ |
25082 |
++ down(&gr_exec_arg_sem); |
25083 |
++ memset(grarg, 0, sizeof(gr_exec_arg_buf)); |
25084 |
++ |
25085 |
++ if (unlikely(argv == NULL)) |
25086 |
++ goto log; |
25087 |
++ |
25088 |
++ for (i = 0; i < bprm->argc && execlen < 128; i++) { |
25089 |
++ const char __user *p; |
25090 |
++ unsigned int len; |
25091 |
++ |
25092 |
++ if (copy_from_user(&p, argv + i, sizeof(p))) |
25093 |
++ goto log; |
25094 |
++ if (!p) |
25095 |
++ goto log; |
25096 |
++ len = strnlen_user(p, 128 - execlen); |
25097 |
++ if (len > 128 - execlen) |
25098 |
++ len = 128 - execlen; |
25099 |
++ else if (len > 0) |
25100 |
++ len--; |
25101 |
++ if (copy_from_user(grarg + execlen, p, len)) |
25102 |
++ goto log; |
25103 |
++ |
25104 |
++ /* rewrite unprintable characters */ |
25105 |
++ for (x = 0; x < len; x++) { |
25106 |
++ c = *(grarg + execlen + x); |
25107 |
++ if (c < 32 || c > 126) |
25108 |
++ *(grarg + execlen + x) = ' '; |
25109 |
++ } |
25110 |
++ |
25111 |
++ execlen += len; |
25112 |
++ *(grarg + execlen) = ' '; |
25113 |
++ *(grarg + execlen + 1) = '\0'; |
25114 |
++ execlen++; |
25115 |
++ } |
25116 |
++ |
25117 |
++ log: |
25118 |
++ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry, |
25119 |
++ bprm->file->f_vfsmnt, grarg); |
25120 |
++ up(&gr_exec_arg_sem); |
25121 |
++#endif |
25122 |
++ return; |
25123 |
++} |
25124 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_fifo.c linux-2.6.23.15-grsec/grsecurity/grsec_fifo.c |
25125 |
+--- linux-2.6.23.15/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100 |
25126 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_fifo.c 2008-02-11 10:37:44.000000000 +0000 |
25127 |
+@@ -0,0 +1,22 @@ |
25128 |
++#include <linux/kernel.h> |
25129 |
++#include <linux/sched.h> |
25130 |
++#include <linux/fs.h> |
25131 |
++#include <linux/file.h> |
25132 |
++#include <linux/grinternal.h> |
25133 |
++ |
25134 |
++int |
25135 |
++gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt, |
25136 |
++ const struct dentry *dir, const int flag, const int acc_mode) |
25137 |
++{ |
25138 |
++#ifdef CONFIG_GRKERNSEC_FIFO |
25139 |
++ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) && |
25140 |
++ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) && |
25141 |
++ (dentry->d_inode->i_uid != dir->d_inode->i_uid) && |
25142 |
++ (current->fsuid != dentry->d_inode->i_uid)) { |
25143 |
++ if (!generic_permission(dentry->d_inode, acc_mode, NULL)) |
25144 |
++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid); |
25145 |
++ return -EACCES; |
25146 |
++ } |
25147 |
++#endif |
25148 |
++ return 0; |
25149 |
++} |
25150 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_fork.c linux-2.6.23.15-grsec/grsecurity/grsec_fork.c |
25151 |
+--- linux-2.6.23.15/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100 |
25152 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_fork.c 2008-02-11 10:37:44.000000000 +0000 |
25153 |
+@@ -0,0 +1,15 @@ |
25154 |
++#include <linux/kernel.h> |
25155 |
++#include <linux/sched.h> |
25156 |
++#include <linux/grsecurity.h> |
25157 |
++#include <linux/grinternal.h> |
25158 |
++#include <linux/errno.h> |
25159 |
++ |
25160 |
++void |
25161 |
++gr_log_forkfail(const int retval) |
25162 |
++{ |
25163 |
++#ifdef CONFIG_GRKERNSEC_FORKFAIL |
25164 |
++ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR) |
25165 |
++ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval); |
25166 |
++#endif |
25167 |
++ return; |
25168 |
++} |
25169 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_init.c linux-2.6.23.15-grsec/grsecurity/grsec_init.c |
25170 |
+--- linux-2.6.23.15/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100 |
25171 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_init.c 2008-02-11 10:37:44.000000000 +0000 |
25172 |
+@@ -0,0 +1,230 @@ |
25173 |
++#include <linux/kernel.h> |
25174 |
++#include <linux/sched.h> |
25175 |
++#include <linux/mm.h> |
25176 |
++#include <linux/smp_lock.h> |
25177 |
++#include <linux/gracl.h> |
25178 |
++#include <linux/slab.h> |
25179 |
++#include <linux/vmalloc.h> |
25180 |
++#include <linux/percpu.h> |
25181 |
++ |
25182 |
++int grsec_enable_shm; |
25183 |
++int grsec_enable_link; |
25184 |
++int grsec_enable_dmesg; |
25185 |
++int grsec_enable_fifo; |
25186 |
++int grsec_enable_execve; |
25187 |
++int grsec_enable_execlog; |
25188 |
++int grsec_enable_signal; |
25189 |
++int grsec_enable_forkfail; |
25190 |
++int grsec_enable_time; |
25191 |
++int grsec_enable_audit_textrel; |
25192 |
++int grsec_enable_group; |
25193 |
++int grsec_audit_gid; |
25194 |
++int grsec_enable_chdir; |
25195 |
++int grsec_enable_audit_ipc; |
25196 |
++int grsec_enable_mount; |
25197 |
++int grsec_enable_chroot_findtask; |
25198 |
++int grsec_enable_chroot_mount; |
25199 |
++int grsec_enable_chroot_shmat; |
25200 |
++int grsec_enable_chroot_fchdir; |
25201 |
++int grsec_enable_chroot_double; |
25202 |
++int grsec_enable_chroot_pivot; |
25203 |
++int grsec_enable_chroot_chdir; |
25204 |
++int grsec_enable_chroot_chmod; |
25205 |
++int grsec_enable_chroot_mknod; |
25206 |
++int grsec_enable_chroot_nice; |
25207 |
++int grsec_enable_chroot_execlog; |
25208 |
++int grsec_enable_chroot_caps; |
25209 |
++int grsec_enable_chroot_sysctl; |
25210 |
++int grsec_enable_chroot_unix; |
25211 |
++int grsec_enable_tpe; |
25212 |
++int grsec_tpe_gid; |
25213 |
++int grsec_enable_tpe_all; |
25214 |
++int grsec_enable_socket_all; |
25215 |
++int grsec_socket_all_gid; |
25216 |
++int grsec_enable_socket_client; |
25217 |
++int grsec_socket_client_gid; |
25218 |
++int grsec_enable_socket_server; |
25219 |
++int grsec_socket_server_gid; |
25220 |
++int grsec_resource_logging; |
25221 |
++int grsec_lock; |
25222 |
++ |
25223 |
++spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED; |
25224 |
++unsigned long grsec_alert_wtime = 0; |
25225 |
++unsigned long grsec_alert_fyet = 0; |
25226 |
++ |
25227 |
++spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED; |
25228 |
++ |
25229 |
++rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED; |
25230 |
++ |
25231 |
++char *gr_shared_page[4]; |
25232 |
++ |
25233 |
++char *gr_alert_log_fmt; |
25234 |
++char *gr_audit_log_fmt; |
25235 |
++char *gr_alert_log_buf; |
25236 |
++char *gr_audit_log_buf; |
25237 |
++ |
25238 |
++extern struct gr_arg *gr_usermode; |
25239 |
++extern unsigned char *gr_system_salt; |
25240 |
++extern unsigned char *gr_system_sum; |
25241 |
++ |
25242 |
++void |
25243 |
++grsecurity_init(void) |
25244 |
++{ |
25245 |
++ int j; |
25246 |
++ /* create the per-cpu shared pages */ |
25247 |
++ |
25248 |
++ for (j = 0; j < 4; j++) { |
25249 |
++ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE); |
25250 |
++ if (gr_shared_page[j] == NULL) { |
25251 |
++ panic("Unable to allocate grsecurity shared page"); |
25252 |
++ return; |
25253 |
++ } |
25254 |
++ } |
25255 |
++ |
25256 |
++ /* allocate log buffers */ |
25257 |
++ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL); |
25258 |
++ if (!gr_alert_log_fmt) { |
25259 |
++ panic("Unable to allocate grsecurity alert log format buffer"); |
25260 |
++ return; |
25261 |
++ } |
25262 |
++ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL); |
25263 |
++ if (!gr_audit_log_fmt) { |
25264 |
++ panic("Unable to allocate grsecurity audit log format buffer"); |
25265 |
++ return; |
25266 |
++ } |
25267 |
++ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL); |
25268 |
++ if (!gr_alert_log_buf) { |
25269 |
++ panic("Unable to allocate grsecurity alert log buffer"); |
25270 |
++ return; |
25271 |
++ } |
25272 |
++ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL); |
25273 |
++ if (!gr_audit_log_buf) { |
25274 |
++ panic("Unable to allocate grsecurity audit log buffer"); |
25275 |
++ return; |
25276 |
++ } |
25277 |
++ |
25278 |
++ /* allocate memory for authentication structure */ |
25279 |
++ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL); |
25280 |
++ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL); |
25281 |
++ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL); |
25282 |
++ |
25283 |
++ if (!gr_usermode || !gr_system_salt || !gr_system_sum) { |
25284 |
++ panic("Unable to allocate grsecurity authentication structure"); |
25285 |
++ return; |
25286 |
++ } |
25287 |
++ |
25288 |
++#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON) |
25289 |
++#ifndef CONFIG_GRKERNSEC_SYSCTL |
25290 |
++ grsec_lock = 1; |
25291 |
++#endif |
25292 |
++#ifdef CONFIG_GRKERNSEC_SHM |
25293 |
++ grsec_enable_shm = 1; |
25294 |
++#endif |
25295 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL |
25296 |
++ grsec_enable_audit_textrel = 1; |
25297 |
++#endif |
25298 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP |
25299 |
++ grsec_enable_group = 1; |
25300 |
++ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID; |
25301 |
++#endif |
25302 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR |
25303 |
++ grsec_enable_chdir = 1; |
25304 |
++#endif |
25305 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25306 |
++ grsec_enable_audit_ipc = 1; |
25307 |
++#endif |
25308 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25309 |
++ grsec_enable_mount = 1; |
25310 |
++#endif |
25311 |
++#ifdef CONFIG_GRKERNSEC_LINK |
25312 |
++ grsec_enable_link = 1; |
25313 |
++#endif |
25314 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
25315 |
++ grsec_enable_dmesg = 1; |
25316 |
++#endif |
25317 |
++#ifdef CONFIG_GRKERNSEC_FIFO |
25318 |
++ grsec_enable_fifo = 1; |
25319 |
++#endif |
25320 |
++#ifdef CONFIG_GRKERNSEC_EXECVE |
25321 |
++ grsec_enable_execve = 1; |
25322 |
++#endif |
25323 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
25324 |
++ grsec_enable_execlog = 1; |
25325 |
++#endif |
25326 |
++#ifdef CONFIG_GRKERNSEC_SIGNAL |
25327 |
++ grsec_enable_signal = 1; |
25328 |
++#endif |
25329 |
++#ifdef CONFIG_GRKERNSEC_FORKFAIL |
25330 |
++ grsec_enable_forkfail = 1; |
25331 |
++#endif |
25332 |
++#ifdef CONFIG_GRKERNSEC_TIME |
25333 |
++ grsec_enable_time = 1; |
25334 |
++#endif |
25335 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
25336 |
++ grsec_resource_logging = 1; |
25337 |
++#endif |
25338 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK |
25339 |
++ grsec_enable_chroot_findtask = 1; |
25340 |
++#endif |
25341 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
25342 |
++ grsec_enable_chroot_unix = 1; |
25343 |
++#endif |
25344 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT |
25345 |
++ grsec_enable_chroot_mount = 1; |
25346 |
++#endif |
25347 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR |
25348 |
++ grsec_enable_chroot_fchdir = 1; |
25349 |
++#endif |
25350 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT |
25351 |
++ grsec_enable_chroot_shmat = 1; |
25352 |
++#endif |
25353 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE |
25354 |
++ grsec_enable_chroot_double = 1; |
25355 |
++#endif |
25356 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT |
25357 |
++ grsec_enable_chroot_pivot = 1; |
25358 |
++#endif |
25359 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR |
25360 |
++ grsec_enable_chroot_chdir = 1; |
25361 |
++#endif |
25362 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD |
25363 |
++ grsec_enable_chroot_chmod = 1; |
25364 |
++#endif |
25365 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD |
25366 |
++ grsec_enable_chroot_mknod = 1; |
25367 |
++#endif |
25368 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
25369 |
++ grsec_enable_chroot_nice = 1; |
25370 |
++#endif |
25371 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG |
25372 |
++ grsec_enable_chroot_execlog = 1; |
25373 |
++#endif |
25374 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
25375 |
++ grsec_enable_chroot_caps = 1; |
25376 |
++#endif |
25377 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL |
25378 |
++ grsec_enable_chroot_sysctl = 1; |
25379 |
++#endif |
25380 |
++#ifdef CONFIG_GRKERNSEC_TPE |
25381 |
++ grsec_enable_tpe = 1; |
25382 |
++ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID; |
25383 |
++#ifdef CONFIG_GRKERNSEC_TPE_ALL |
25384 |
++ grsec_enable_tpe_all = 1; |
25385 |
++#endif |
25386 |
++#endif |
25387 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL |
25388 |
++ grsec_enable_socket_all = 1; |
25389 |
++ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID; |
25390 |
++#endif |
25391 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT |
25392 |
++ grsec_enable_socket_client = 1; |
25393 |
++ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID; |
25394 |
++#endif |
25395 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
25396 |
++ grsec_enable_socket_server = 1; |
25397 |
++ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID; |
25398 |
++#endif |
25399 |
++#endif |
25400 |
++ |
25401 |
++ return; |
25402 |
++} |
25403 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_ipc.c linux-2.6.23.15-grsec/grsecurity/grsec_ipc.c |
25404 |
+--- linux-2.6.23.15/grsecurity/grsec_ipc.c 1970-01-01 01:00:00.000000000 +0100 |
25405 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_ipc.c 2008-02-11 10:37:44.000000000 +0000 |
25406 |
+@@ -0,0 +1,81 @@ |
25407 |
++#include <linux/kernel.h> |
25408 |
++#include <linux/sched.h> |
25409 |
++#include <linux/types.h> |
25410 |
++#include <linux/ipc.h> |
25411 |
++#include <linux/grsecurity.h> |
25412 |
++#include <linux/grinternal.h> |
25413 |
++ |
25414 |
++void |
25415 |
++gr_log_msgget(const int ret, const int msgflg) |
25416 |
++{ |
25417 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25418 |
++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && |
25419 |
++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && |
25420 |
++ !grsec_enable_group)) && (ret >= 0) |
25421 |
++ && (msgflg & IPC_CREAT)) |
25422 |
++ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG); |
25423 |
++#endif |
25424 |
++ return; |
25425 |
++} |
25426 |
++ |
25427 |
++void |
25428 |
++gr_log_msgrm(const uid_t uid, const uid_t cuid) |
25429 |
++{ |
25430 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25431 |
++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && |
25432 |
++ grsec_enable_audit_ipc) || |
25433 |
++ (grsec_enable_audit_ipc && !grsec_enable_group)) |
25434 |
++ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid); |
25435 |
++#endif |
25436 |
++ return; |
25437 |
++} |
25438 |
++ |
25439 |
++void |
25440 |
++gr_log_semget(const int err, const int semflg) |
25441 |
++{ |
25442 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25443 |
++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && |
25444 |
++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && |
25445 |
++ !grsec_enable_group)) && (err >= 0) |
25446 |
++ && (semflg & IPC_CREAT)) |
25447 |
++ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG); |
25448 |
++#endif |
25449 |
++ return; |
25450 |
++} |
25451 |
++ |
25452 |
++void |
25453 |
++gr_log_semrm(const uid_t uid, const uid_t cuid) |
25454 |
++{ |
25455 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25456 |
++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && |
25457 |
++ grsec_enable_audit_ipc) || |
25458 |
++ (grsec_enable_audit_ipc && !grsec_enable_group)) |
25459 |
++ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid); |
25460 |
++#endif |
25461 |
++ return; |
25462 |
++} |
25463 |
++ |
25464 |
++void |
25465 |
++gr_log_shmget(const int err, const int shmflg, const size_t size) |
25466 |
++{ |
25467 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25468 |
++ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && |
25469 |
++ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && |
25470 |
++ !grsec_enable_group)) && (err >= 0) |
25471 |
++ && (shmflg & IPC_CREAT)) |
25472 |
++ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size); |
25473 |
++#endif |
25474 |
++ return; |
25475 |
++} |
25476 |
++ |
25477 |
++void |
25478 |
++gr_log_shmrm(const uid_t uid, const uid_t cuid) |
25479 |
++{ |
25480 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
25481 |
++ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && |
25482 |
++ grsec_enable_audit_ipc) || |
25483 |
++ (grsec_enable_audit_ipc && !grsec_enable_group)) |
25484 |
++ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid); |
25485 |
++#endif |
25486 |
++ return; |
25487 |
++} |
25488 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_link.c linux-2.6.23.15-grsec/grsecurity/grsec_link.c |
25489 |
+--- linux-2.6.23.15/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100 |
25490 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_link.c 2008-02-11 10:37:44.000000000 +0000 |
25491 |
+@@ -0,0 +1,39 @@ |
25492 |
++#include <linux/kernel.h> |
25493 |
++#include <linux/sched.h> |
25494 |
++#include <linux/fs.h> |
25495 |
++#include <linux/file.h> |
25496 |
++#include <linux/grinternal.h> |
25497 |
++ |
25498 |
++int |
25499 |
++gr_handle_follow_link(const struct inode *parent, |
25500 |
++ const struct inode *inode, |
25501 |
++ const struct dentry *dentry, const struct vfsmount *mnt) |
25502 |
++{ |
25503 |
++#ifdef CONFIG_GRKERNSEC_LINK |
25504 |
++ if (grsec_enable_link && S_ISLNK(inode->i_mode) && |
25505 |
++ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) && |
25506 |
++ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) { |
25507 |
++ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid); |
25508 |
++ return -EACCES; |
25509 |
++ } |
25510 |
++#endif |
25511 |
++ return 0; |
25512 |
++} |
25513 |
++ |
25514 |
++int |
25515 |
++gr_handle_hardlink(const struct dentry *dentry, |
25516 |
++ const struct vfsmount *mnt, |
25517 |
++ struct inode *inode, const int mode, const char *to) |
25518 |
++{ |
25519 |
++#ifdef CONFIG_GRKERNSEC_LINK |
25520 |
++ if (grsec_enable_link && current->fsuid != inode->i_uid && |
25521 |
++ (!S_ISREG(mode) || (mode & S_ISUID) || |
25522 |
++ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) || |
25523 |
++ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) && |
25524 |
++ !capable(CAP_FOWNER) && current->uid) { |
25525 |
++ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to); |
25526 |
++ return -EPERM; |
25527 |
++ } |
25528 |
++#endif |
25529 |
++ return 0; |
25530 |
++} |
25531 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_log.c linux-2.6.23.15-grsec/grsecurity/grsec_log.c |
25532 |
+--- linux-2.6.23.15/grsecurity/grsec_log.c 1970-01-01 01:00:00.000000000 +0100 |
25533 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_log.c 2008-02-11 10:37:44.000000000 +0000 |
25534 |
+@@ -0,0 +1,269 @@ |
25535 |
++#include <linux/kernel.h> |
25536 |
++#include <linux/sched.h> |
25537 |
++#include <linux/file.h> |
25538 |
++#include <linux/tty.h> |
25539 |
++#include <linux/fs.h> |
25540 |
++#include <linux/grinternal.h> |
25541 |
++ |
25542 |
++#define BEGIN_LOCKS(x) \ |
25543 |
++ read_lock(&tasklist_lock); \ |
25544 |
++ read_lock(&grsec_exec_file_lock); \ |
25545 |
++ if (x != GR_DO_AUDIT) \ |
25546 |
++ spin_lock(&grsec_alert_lock); \ |
25547 |
++ else \ |
25548 |
++ spin_lock(&grsec_audit_lock) |
25549 |
++ |
25550 |
++#define END_LOCKS(x) \ |
25551 |
++ if (x != GR_DO_AUDIT) \ |
25552 |
++ spin_unlock(&grsec_alert_lock); \ |
25553 |
++ else \ |
25554 |
++ spin_unlock(&grsec_audit_lock); \ |
25555 |
++ read_unlock(&grsec_exec_file_lock); \ |
25556 |
++ read_unlock(&tasklist_lock); \ |
25557 |
++ if (x == GR_DONT_AUDIT) \ |
25558 |
++ gr_handle_alertkill(current) |
25559 |
++ |
25560 |
++enum { |
25561 |
++ FLOODING, |
25562 |
++ NO_FLOODING |
25563 |
++}; |
25564 |
++ |
25565 |
++extern char *gr_alert_log_fmt; |
25566 |
++extern char *gr_audit_log_fmt; |
25567 |
++extern char *gr_alert_log_buf; |
25568 |
++extern char *gr_audit_log_buf; |
25569 |
++ |
25570 |
++static int gr_log_start(int audit) |
25571 |
++{ |
25572 |
++ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT; |
25573 |
++ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt; |
25574 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25575 |
++ |
25576 |
++ if (audit == GR_DO_AUDIT) |
25577 |
++ goto set_fmt; |
25578 |
++ |
25579 |
++ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { |
25580 |
++ grsec_alert_wtime = jiffies; |
25581 |
++ grsec_alert_fyet = 0; |
25582 |
++ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { |
25583 |
++ grsec_alert_fyet++; |
25584 |
++ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { |
25585 |
++ grsec_alert_wtime = jiffies; |
25586 |
++ grsec_alert_fyet++; |
25587 |
++ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); |
25588 |
++ return FLOODING; |
25589 |
++ } else return FLOODING; |
25590 |
++ |
25591 |
++set_fmt: |
25592 |
++ memset(buf, 0, PAGE_SIZE); |
25593 |
++ if (current->signal->curr_ip && gr_acl_is_enabled()) { |
25594 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) "); |
25595 |
++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename); |
25596 |
++ } else if (current->signal->curr_ip) { |
25597 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: "); |
25598 |
++ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip)); |
25599 |
++ } else if (gr_acl_is_enabled()) { |
25600 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) "); |
25601 |
++ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename); |
25602 |
++ } else { |
25603 |
++ sprintf(fmt, "%s%s", loglevel, "grsec: "); |
25604 |
++ strcpy(buf, fmt); |
25605 |
++ } |
25606 |
++ |
25607 |
++ return NO_FLOODING; |
25608 |
++} |
25609 |
++ |
25610 |
++static void gr_log_middle(int audit, const char *msg, va_list ap) |
25611 |
++{ |
25612 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25613 |
++ unsigned int len = strlen(buf); |
25614 |
++ |
25615 |
++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap); |
25616 |
++ |
25617 |
++ return; |
25618 |
++} |
25619 |
++ |
25620 |
++static void gr_log_middle_varargs(int audit, const char *msg, ...) |
25621 |
++{ |
25622 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25623 |
++ unsigned int len = strlen(buf); |
25624 |
++ va_list ap; |
25625 |
++ |
25626 |
++ va_start(ap, msg); |
25627 |
++ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap); |
25628 |
++ va_end(ap); |
25629 |
++ |
25630 |
++ return; |
25631 |
++} |
25632 |
++ |
25633 |
++static void gr_log_end(int audit) |
25634 |
++{ |
25635 |
++ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf; |
25636 |
++ unsigned int len = strlen(buf); |
25637 |
++ |
25638 |
++ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current)); |
25639 |
++ printk("%s\n", buf); |
25640 |
++ |
25641 |
++ return; |
25642 |
++} |
25643 |
++ |
25644 |
++void gr_log_varargs(int audit, const char *msg, int argtypes, ...) |
25645 |
++{ |
25646 |
++ int logtype; |
25647 |
++ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied"; |
25648 |
++ char *str1, *str2, *str3; |
25649 |
++ int num1, num2; |
25650 |
++ unsigned long ulong1, ulong2; |
25651 |
++ struct dentry *dentry; |
25652 |
++ struct vfsmount *mnt; |
25653 |
++ struct file *file; |
25654 |
++ struct task_struct *task; |
25655 |
++ va_list ap; |
25656 |
++ |
25657 |
++ BEGIN_LOCKS(audit); |
25658 |
++ logtype = gr_log_start(audit); |
25659 |
++ if (logtype == FLOODING) { |
25660 |
++ END_LOCKS(audit); |
25661 |
++ return; |
25662 |
++ } |
25663 |
++ va_start(ap, argtypes); |
25664 |
++ switch (argtypes) { |
25665 |
++ case GR_TTYSNIFF: |
25666 |
++ task = va_arg(ap, struct task_struct *); |
25667 |
++ 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); |
25668 |
++ break; |
25669 |
++ case GR_SYSCTL_HIDDEN: |
25670 |
++ str1 = va_arg(ap, char *); |
25671 |
++ gr_log_middle_varargs(audit, msg, result, str1); |
25672 |
++ break; |
25673 |
++ case GR_RBAC: |
25674 |
++ dentry = va_arg(ap, struct dentry *); |
25675 |
++ mnt = va_arg(ap, struct vfsmount *); |
25676 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt)); |
25677 |
++ break; |
25678 |
++ case GR_RBAC_STR: |
25679 |
++ dentry = va_arg(ap, struct dentry *); |
25680 |
++ mnt = va_arg(ap, struct vfsmount *); |
25681 |
++ str1 = va_arg(ap, char *); |
25682 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1); |
25683 |
++ break; |
25684 |
++ case GR_STR_RBAC: |
25685 |
++ str1 = va_arg(ap, char *); |
25686 |
++ dentry = va_arg(ap, struct dentry *); |
25687 |
++ mnt = va_arg(ap, struct vfsmount *); |
25688 |
++ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt)); |
25689 |
++ break; |
25690 |
++ case GR_RBAC_MODE2: |
25691 |
++ dentry = va_arg(ap, struct dentry *); |
25692 |
++ mnt = va_arg(ap, struct vfsmount *); |
25693 |
++ str1 = va_arg(ap, char *); |
25694 |
++ str2 = va_arg(ap, char *); |
25695 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2); |
25696 |
++ break; |
25697 |
++ case GR_RBAC_MODE3: |
25698 |
++ dentry = va_arg(ap, struct dentry *); |
25699 |
++ mnt = va_arg(ap, struct vfsmount *); |
25700 |
++ str1 = va_arg(ap, char *); |
25701 |
++ str2 = va_arg(ap, char *); |
25702 |
++ str3 = va_arg(ap, char *); |
25703 |
++ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3); |
25704 |
++ break; |
25705 |
++ case GR_FILENAME: |
25706 |
++ dentry = va_arg(ap, struct dentry *); |
25707 |
++ mnt = va_arg(ap, struct vfsmount *); |
25708 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt)); |
25709 |
++ break; |
25710 |
++ case GR_STR_FILENAME: |
25711 |
++ str1 = va_arg(ap, char *); |
25712 |
++ dentry = va_arg(ap, struct dentry *); |
25713 |
++ mnt = va_arg(ap, struct vfsmount *); |
25714 |
++ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt)); |
25715 |
++ break; |
25716 |
++ case GR_FILENAME_STR: |
25717 |
++ dentry = va_arg(ap, struct dentry *); |
25718 |
++ mnt = va_arg(ap, struct vfsmount *); |
25719 |
++ str1 = va_arg(ap, char *); |
25720 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1); |
25721 |
++ break; |
25722 |
++ case GR_FILENAME_TWO_INT: |
25723 |
++ dentry = va_arg(ap, struct dentry *); |
25724 |
++ mnt = va_arg(ap, struct vfsmount *); |
25725 |
++ num1 = va_arg(ap, int); |
25726 |
++ num2 = va_arg(ap, int); |
25727 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2); |
25728 |
++ break; |
25729 |
++ case GR_FILENAME_TWO_INT_STR: |
25730 |
++ dentry = va_arg(ap, struct dentry *); |
25731 |
++ mnt = va_arg(ap, struct vfsmount *); |
25732 |
++ num1 = va_arg(ap, int); |
25733 |
++ num2 = va_arg(ap, int); |
25734 |
++ str1 = va_arg(ap, char *); |
25735 |
++ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1); |
25736 |
++ break; |
25737 |
++ case GR_TEXTREL: |
25738 |
++ file = va_arg(ap, struct file *); |
25739 |
++ ulong1 = va_arg(ap, unsigned long); |
25740 |
++ ulong2 = va_arg(ap, unsigned long); |
25741 |
++ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2); |
25742 |
++ break; |
25743 |
++ case GR_PTRACE: |
25744 |
++ task = va_arg(ap, struct task_struct *); |
25745 |
++ 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); |
25746 |
++ break; |
25747 |
++ case GR_RESOURCE: |
25748 |
++ task = va_arg(ap, struct task_struct *); |
25749 |
++ ulong1 = va_arg(ap, unsigned long); |
25750 |
++ str1 = va_arg(ap, char *); |
25751 |
++ ulong2 = va_arg(ap, unsigned long); |
25752 |
++ 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); |
25753 |
++ break; |
25754 |
++ case GR_CAP: |
25755 |
++ task = va_arg(ap, struct task_struct *); |
25756 |
++ str1 = va_arg(ap, char *); |
25757 |
++ 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); |
25758 |
++ break; |
25759 |
++ case GR_SIG: |
25760 |
++ task = va_arg(ap, struct task_struct *); |
25761 |
++ num1 = va_arg(ap, int); |
25762 |
++ 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); |
25763 |
++ break; |
25764 |
++ case GR_CRASH1: |
25765 |
++ task = va_arg(ap, struct task_struct *); |
25766 |
++ ulong1 = va_arg(ap, unsigned long); |
25767 |
++ 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); |
25768 |
++ break; |
25769 |
++ case GR_CRASH2: |
25770 |
++ task = va_arg(ap, struct task_struct *); |
25771 |
++ ulong1 = va_arg(ap, unsigned long); |
25772 |
++ 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); |
25773 |
++ break; |
25774 |
++ case GR_PSACCT: |
25775 |
++ { |
25776 |
++ unsigned int wday, cday; |
25777 |
++ __u8 whr, chr; |
25778 |
++ __u8 wmin, cmin; |
25779 |
++ __u8 wsec, csec; |
25780 |
++ char cur_tty[64] = { 0 }; |
25781 |
++ char parent_tty[64] = { 0 }; |
25782 |
++ |
25783 |
++ task = va_arg(ap, struct task_struct *); |
25784 |
++ wday = va_arg(ap, unsigned int); |
25785 |
++ cday = va_arg(ap, unsigned int); |
25786 |
++ whr = va_arg(ap, int); |
25787 |
++ chr = va_arg(ap, int); |
25788 |
++ wmin = va_arg(ap, int); |
25789 |
++ cmin = va_arg(ap, int); |
25790 |
++ wsec = va_arg(ap, int); |
25791 |
++ csec = va_arg(ap, int); |
25792 |
++ ulong1 = va_arg(ap, unsigned long); |
25793 |
++ |
25794 |
++ 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); |
25795 |
++ } |
25796 |
++ break; |
25797 |
++ default: |
25798 |
++ gr_log_middle(audit, msg, ap); |
25799 |
++ } |
25800 |
++ va_end(ap); |
25801 |
++ gr_log_end(audit); |
25802 |
++ END_LOCKS(audit); |
25803 |
++} |
25804 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_mem.c linux-2.6.23.15-grsec/grsecurity/grsec_mem.c |
25805 |
+--- linux-2.6.23.15/grsecurity/grsec_mem.c 1970-01-01 01:00:00.000000000 +0100 |
25806 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_mem.c 2008-02-11 10:37:44.000000000 +0000 |
25807 |
+@@ -0,0 +1,71 @@ |
25808 |
++#include <linux/kernel.h> |
25809 |
++#include <linux/sched.h> |
25810 |
++#include <linux/mm.h> |
25811 |
++#include <linux/mman.h> |
25812 |
++#include <linux/grinternal.h> |
25813 |
++ |
25814 |
++void |
25815 |
++gr_handle_ioperm(void) |
25816 |
++{ |
25817 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG); |
25818 |
++ return; |
25819 |
++} |
25820 |
++ |
25821 |
++void |
25822 |
++gr_handle_iopl(void) |
25823 |
++{ |
25824 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG); |
25825 |
++ return; |
25826 |
++} |
25827 |
++ |
25828 |
++void |
25829 |
++gr_handle_mem_write(void) |
25830 |
++{ |
25831 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG); |
25832 |
++ return; |
25833 |
++} |
25834 |
++ |
25835 |
++void |
25836 |
++gr_handle_kmem_write(void) |
25837 |
++{ |
25838 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG); |
25839 |
++ return; |
25840 |
++} |
25841 |
++ |
25842 |
++void |
25843 |
++gr_handle_open_port(void) |
25844 |
++{ |
25845 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG); |
25846 |
++ return; |
25847 |
++} |
25848 |
++ |
25849 |
++int |
25850 |
++gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma) |
25851 |
++{ |
25852 |
++ unsigned long start, end; |
25853 |
++ |
25854 |
++ start = offset; |
25855 |
++ end = start + vma->vm_end - vma->vm_start; |
25856 |
++ |
25857 |
++ if (start > end) { |
25858 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG); |
25859 |
++ return -EPERM; |
25860 |
++ } |
25861 |
++ |
25862 |
++ /* allowed ranges : ISA I/O BIOS */ |
25863 |
++ if ((start >= __pa(high_memory)) |
25864 |
++#ifdef CONFIG_X86 |
25865 |
++ || (start >= 0x000a0000 && end <= 0x00100000) |
25866 |
++ || (start >= 0x00000000 && end <= 0x00001000) |
25867 |
++#endif |
25868 |
++ ) |
25869 |
++ return 0; |
25870 |
++ |
25871 |
++ if (vma->vm_flags & VM_WRITE) { |
25872 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG); |
25873 |
++ return -EPERM; |
25874 |
++ } else |
25875 |
++ vma->vm_flags &= ~VM_MAYWRITE; |
25876 |
++ |
25877 |
++ return 0; |
25878 |
++} |
25879 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_mount.c linux-2.6.23.15-grsec/grsecurity/grsec_mount.c |
25880 |
+--- linux-2.6.23.15/grsecurity/grsec_mount.c 1970-01-01 01:00:00.000000000 +0100 |
25881 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_mount.c 2008-02-11 10:37:44.000000000 +0000 |
25882 |
+@@ -0,0 +1,34 @@ |
25883 |
++#include <linux/kernel.h> |
25884 |
++#include <linux/sched.h> |
25885 |
++#include <linux/grsecurity.h> |
25886 |
++#include <linux/grinternal.h> |
25887 |
++ |
25888 |
++void |
25889 |
++gr_log_remount(const char *devname, const int retval) |
25890 |
++{ |
25891 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25892 |
++ if (grsec_enable_mount && (retval >= 0)) |
25893 |
++ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none"); |
25894 |
++#endif |
25895 |
++ return; |
25896 |
++} |
25897 |
++ |
25898 |
++void |
25899 |
++gr_log_unmount(const char *devname, const int retval) |
25900 |
++{ |
25901 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25902 |
++ if (grsec_enable_mount && (retval >= 0)) |
25903 |
++ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none"); |
25904 |
++#endif |
25905 |
++ return; |
25906 |
++} |
25907 |
++ |
25908 |
++void |
25909 |
++gr_log_mount(const char *from, const char *to, const int retval) |
25910 |
++{ |
25911 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
25912 |
++ if (grsec_enable_mount && (retval >= 0)) |
25913 |
++ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to); |
25914 |
++#endif |
25915 |
++ return; |
25916 |
++} |
25917 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_sig.c linux-2.6.23.15-grsec/grsecurity/grsec_sig.c |
25918 |
+--- linux-2.6.23.15/grsecurity/grsec_sig.c 1970-01-01 01:00:00.000000000 +0100 |
25919 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_sig.c 2008-02-11 10:37:44.000000000 +0000 |
25920 |
+@@ -0,0 +1,59 @@ |
25921 |
++#include <linux/kernel.h> |
25922 |
++#include <linux/sched.h> |
25923 |
++#include <linux/grsecurity.h> |
25924 |
++#include <linux/grinternal.h> |
25925 |
++ |
25926 |
++void |
25927 |
++gr_log_signal(const int sig, const struct task_struct *t) |
25928 |
++{ |
25929 |
++#ifdef CONFIG_GRKERNSEC_SIGNAL |
25930 |
++ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) || |
25931 |
++ (sig == SIGABRT) || (sig == SIGBUS))) { |
25932 |
++ if (t->pid == current->pid) { |
25933 |
++ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig); |
25934 |
++ } else { |
25935 |
++ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig); |
25936 |
++ } |
25937 |
++ } |
25938 |
++#endif |
25939 |
++ return; |
25940 |
++} |
25941 |
++ |
25942 |
++int |
25943 |
++gr_handle_signal(const struct task_struct *p, const int sig) |
25944 |
++{ |
25945 |
++#ifdef CONFIG_GRKERNSEC |
25946 |
++ if (current->pid > 1 && gr_check_protected_task(p)) { |
25947 |
++ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig); |
25948 |
++ return -EPERM; |
25949 |
++ } else if (gr_pid_is_chrooted((struct task_struct *)p)) { |
25950 |
++ return -EPERM; |
25951 |
++ } |
25952 |
++#endif |
25953 |
++ return 0; |
25954 |
++} |
25955 |
++ |
25956 |
++void gr_handle_brute_attach(struct task_struct *p) |
25957 |
++{ |
25958 |
++#ifdef CONFIG_GRKERNSEC_BRUTE |
25959 |
++ read_lock(&tasklist_lock); |
25960 |
++ read_lock(&grsec_exec_file_lock); |
25961 |
++ if (p->parent && p->parent->exec_file == p->exec_file) |
25962 |
++ p->parent->brute = 1; |
25963 |
++ read_unlock(&grsec_exec_file_lock); |
25964 |
++ read_unlock(&tasklist_lock); |
25965 |
++#endif |
25966 |
++ return; |
25967 |
++} |
25968 |
++ |
25969 |
++void gr_handle_brute_check(void) |
25970 |
++{ |
25971 |
++#ifdef CONFIG_GRKERNSEC_BRUTE |
25972 |
++ if (current->brute) { |
25973 |
++ set_current_state(TASK_UNINTERRUPTIBLE); |
25974 |
++ schedule_timeout(30 * HZ); |
25975 |
++ } |
25976 |
++#endif |
25977 |
++ return; |
25978 |
++} |
25979 |
++ |
25980 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_sock.c linux-2.6.23.15-grsec/grsecurity/grsec_sock.c |
25981 |
+--- linux-2.6.23.15/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100 |
25982 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_sock.c 2008-02-11 10:37:44.000000000 +0000 |
25983 |
+@@ -0,0 +1,263 @@ |
25984 |
++#include <linux/kernel.h> |
25985 |
++#include <linux/module.h> |
25986 |
++#include <linux/sched.h> |
25987 |
++#include <linux/file.h> |
25988 |
++#include <linux/net.h> |
25989 |
++#include <linux/in.h> |
25990 |
++#include <linux/ip.h> |
25991 |
++#include <net/sock.h> |
25992 |
++#include <net/inet_sock.h> |
25993 |
++#include <linux/grsecurity.h> |
25994 |
++#include <linux/grinternal.h> |
25995 |
++#include <linux/gracl.h> |
25996 |
++ |
25997 |
++#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE) |
25998 |
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); |
25999 |
++EXPORT_SYMBOL(udp_v4_lookup); |
26000 |
++#endif |
26001 |
++ |
26002 |
++EXPORT_SYMBOL(gr_cap_rtnetlink); |
26003 |
++ |
26004 |
++extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb); |
26005 |
++extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr); |
26006 |
++ |
26007 |
++EXPORT_SYMBOL(gr_search_udp_recvmsg); |
26008 |
++EXPORT_SYMBOL(gr_search_udp_sendmsg); |
26009 |
++ |
26010 |
++#ifdef CONFIG_UNIX_MODULE |
26011 |
++EXPORT_SYMBOL(gr_acl_handle_unix); |
26012 |
++EXPORT_SYMBOL(gr_acl_handle_mknod); |
26013 |
++EXPORT_SYMBOL(gr_handle_chroot_unix); |
26014 |
++EXPORT_SYMBOL(gr_handle_create); |
26015 |
++#endif |
26016 |
++ |
26017 |
++#ifdef CONFIG_GRKERNSEC |
26018 |
++#define gr_conn_table_size 32749 |
26019 |
++struct conn_table_entry { |
26020 |
++ struct conn_table_entry *next; |
26021 |
++ struct signal_struct *sig; |
26022 |
++}; |
26023 |
++ |
26024 |
++struct conn_table_entry *gr_conn_table[gr_conn_table_size]; |
26025 |
++spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED; |
26026 |
++ |
26027 |
++extern const char * gr_socktype_to_name(unsigned char type); |
26028 |
++extern const char * gr_proto_to_name(unsigned char proto); |
26029 |
++ |
26030 |
++static __inline__ int |
26031 |
++conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size) |
26032 |
++{ |
26033 |
++ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size); |
26034 |
++} |
26035 |
++ |
26036 |
++static __inline__ int |
26037 |
++conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, |
26038 |
++ __u16 sport, __u16 dport) |
26039 |
++{ |
26040 |
++ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr && |
26041 |
++ sig->gr_sport == sport && sig->gr_dport == dport)) |
26042 |
++ return 1; |
26043 |
++ else |
26044 |
++ return 0; |
26045 |
++} |
26046 |
++ |
26047 |
++static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent) |
26048 |
++{ |
26049 |
++ struct conn_table_entry **match; |
26050 |
++ unsigned int index; |
26051 |
++ |
26052 |
++ index = conn_hash(sig->gr_saddr, sig->gr_daddr, |
26053 |
++ sig->gr_sport, sig->gr_dport, |
26054 |
++ gr_conn_table_size); |
26055 |
++ |
26056 |
++ newent->sig = sig; |
26057 |
++ |
26058 |
++ match = &gr_conn_table[index]; |
26059 |
++ newent->next = *match; |
26060 |
++ *match = newent; |
26061 |
++ |
26062 |
++ return; |
26063 |
++} |
26064 |
++ |
26065 |
++static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig) |
26066 |
++{ |
26067 |
++ struct conn_table_entry *match, *last = NULL; |
26068 |
++ unsigned int index; |
26069 |
++ |
26070 |
++ index = conn_hash(sig->gr_saddr, sig->gr_daddr, |
26071 |
++ sig->gr_sport, sig->gr_dport, |
26072 |
++ gr_conn_table_size); |
26073 |
++ |
26074 |
++ match = gr_conn_table[index]; |
26075 |
++ while (match && !conn_match(match->sig, |
26076 |
++ sig->gr_saddr, sig->gr_daddr, sig->gr_sport, |
26077 |
++ sig->gr_dport)) { |
26078 |
++ last = match; |
26079 |
++ match = match->next; |
26080 |
++ } |
26081 |
++ |
26082 |
++ if (match) { |
26083 |
++ if (last) |
26084 |
++ last->next = match->next; |
26085 |
++ else |
26086 |
++ gr_conn_table[index] = NULL; |
26087 |
++ kfree(match); |
26088 |
++ } |
26089 |
++ |
26090 |
++ return; |
26091 |
++} |
26092 |
++ |
26093 |
++static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr, |
26094 |
++ __u16 sport, __u16 dport) |
26095 |
++{ |
26096 |
++ struct conn_table_entry *match; |
26097 |
++ unsigned int index; |
26098 |
++ |
26099 |
++ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size); |
26100 |
++ |
26101 |
++ match = gr_conn_table[index]; |
26102 |
++ while (match && !conn_match(match->sig, saddr, daddr, sport, dport)) |
26103 |
++ match = match->next; |
26104 |
++ |
26105 |
++ if (match) |
26106 |
++ return match->sig; |
26107 |
++ else |
26108 |
++ return NULL; |
26109 |
++} |
26110 |
++ |
26111 |
++#endif |
26112 |
++ |
26113 |
++void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet) |
26114 |
++{ |
26115 |
++#ifdef CONFIG_GRKERNSEC |
26116 |
++ struct signal_struct *sig = task->signal; |
26117 |
++ struct conn_table_entry *newent; |
26118 |
++ |
26119 |
++ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC); |
26120 |
++ if (newent == NULL) |
26121 |
++ return; |
26122 |
++ /* no bh lock needed since we are called with bh disabled */ |
26123 |
++ spin_lock(&gr_conn_table_lock); |
26124 |
++ gr_del_task_from_ip_table_nolock(sig); |
26125 |
++ sig->gr_saddr = inet->rcv_saddr; |
26126 |
++ sig->gr_daddr = inet->daddr; |
26127 |
++ sig->gr_sport = inet->sport; |
26128 |
++ sig->gr_dport = inet->dport; |
26129 |
++ gr_add_to_task_ip_table_nolock(sig, newent); |
26130 |
++ spin_unlock(&gr_conn_table_lock); |
26131 |
++#endif |
26132 |
++ return; |
26133 |
++} |
26134 |
++ |
26135 |
++void gr_del_task_from_ip_table(struct task_struct *task) |
26136 |
++{ |
26137 |
++#ifdef CONFIG_GRKERNSEC |
26138 |
++ spin_lock(&gr_conn_table_lock); |
26139 |
++ gr_del_task_from_ip_table_nolock(task->signal); |
26140 |
++ spin_unlock(&gr_conn_table_lock); |
26141 |
++#endif |
26142 |
++ return; |
26143 |
++} |
26144 |
++ |
26145 |
++void |
26146 |
++gr_attach_curr_ip(const struct sock *sk) |
26147 |
++{ |
26148 |
++#ifdef CONFIG_GRKERNSEC |
26149 |
++ struct signal_struct *p, *set; |
26150 |
++ const struct inet_sock *inet = inet_sk(sk); |
26151 |
++ |
26152 |
++ if (unlikely(sk->sk_protocol != IPPROTO_TCP)) |
26153 |
++ return; |
26154 |
++ |
26155 |
++ set = current->signal; |
26156 |
++ |
26157 |
++ spin_lock_bh(&gr_conn_table_lock); |
26158 |
++ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr, |
26159 |
++ inet->dport, inet->sport); |
26160 |
++ if (unlikely(p != NULL)) { |
26161 |
++ set->curr_ip = p->curr_ip; |
26162 |
++ set->used_accept = 1; |
26163 |
++ gr_del_task_from_ip_table_nolock(p); |
26164 |
++ spin_unlock_bh(&gr_conn_table_lock); |
26165 |
++ return; |
26166 |
++ } |
26167 |
++ spin_unlock_bh(&gr_conn_table_lock); |
26168 |
++ |
26169 |
++ set->curr_ip = inet->daddr; |
26170 |
++ set->used_accept = 1; |
26171 |
++#endif |
26172 |
++ return; |
26173 |
++} |
26174 |
++ |
26175 |
++int |
26176 |
++gr_handle_sock_all(const int family, const int type, const int protocol) |
26177 |
++{ |
26178 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL |
26179 |
++ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) && |
26180 |
++ (family != AF_UNIX) && (family != AF_LOCAL)) { |
26181 |
++ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol)); |
26182 |
++ return -EACCES; |
26183 |
++ } |
26184 |
++#endif |
26185 |
++ return 0; |
26186 |
++} |
26187 |
++ |
26188 |
++int |
26189 |
++gr_handle_sock_server(const struct sockaddr *sck) |
26190 |
++{ |
26191 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
26192 |
++ if (grsec_enable_socket_server && |
26193 |
++ in_group_p(grsec_socket_server_gid) && |
26194 |
++ sck && (sck->sa_family != AF_UNIX) && |
26195 |
++ (sck->sa_family != AF_LOCAL)) { |
26196 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG); |
26197 |
++ return -EACCES; |
26198 |
++ } |
26199 |
++#endif |
26200 |
++ return 0; |
26201 |
++} |
26202 |
++ |
26203 |
++int |
26204 |
++gr_handle_sock_server_other(const struct sock *sck) |
26205 |
++{ |
26206 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
26207 |
++ if (grsec_enable_socket_server && |
26208 |
++ in_group_p(grsec_socket_server_gid) && |
26209 |
++ sck && (sck->sk_family != AF_UNIX) && |
26210 |
++ (sck->sk_family != AF_LOCAL)) { |
26211 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG); |
26212 |
++ return -EACCES; |
26213 |
++ } |
26214 |
++#endif |
26215 |
++ return 0; |
26216 |
++} |
26217 |
++ |
26218 |
++int |
26219 |
++gr_handle_sock_client(const struct sockaddr *sck) |
26220 |
++{ |
26221 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT |
26222 |
++ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) && |
26223 |
++ sck && (sck->sa_family != AF_UNIX) && |
26224 |
++ (sck->sa_family != AF_LOCAL)) { |
26225 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG); |
26226 |
++ return -EACCES; |
26227 |
++ } |
26228 |
++#endif |
26229 |
++ return 0; |
26230 |
++} |
26231 |
++ |
26232 |
++__u32 |
26233 |
++gr_cap_rtnetlink(void) |
26234 |
++{ |
26235 |
++#ifdef CONFIG_GRKERNSEC |
26236 |
++ if (!gr_acl_is_enabled()) |
26237 |
++ return current->cap_effective; |
26238 |
++ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) && |
26239 |
++ gr_task_is_capable(current, CAP_NET_ADMIN)) |
26240 |
++ return current->cap_effective; |
26241 |
++ else |
26242 |
++ return 0; |
26243 |
++#else |
26244 |
++ return current->cap_effective; |
26245 |
++#endif |
26246 |
++} |
26247 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_sysctl.c linux-2.6.23.15-grsec/grsecurity/grsec_sysctl.c |
26248 |
+--- linux-2.6.23.15/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100 |
26249 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_sysctl.c 2008-02-11 10:37:44.000000000 +0000 |
26250 |
+@@ -0,0 +1,456 @@ |
26251 |
++#include <linux/kernel.h> |
26252 |
++#include <linux/sched.h> |
26253 |
++#include <linux/sysctl.h> |
26254 |
++#include <linux/grsecurity.h> |
26255 |
++#include <linux/grinternal.h> |
26256 |
++ |
26257 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
26258 |
++int grsec_modstop; |
26259 |
++#endif |
26260 |
++ |
26261 |
++int |
26262 |
++gr_handle_sysctl_mod(const char *dirname, const char *name, const int op) |
26263 |
++{ |
26264 |
++#ifdef CONFIG_GRKERNSEC_SYSCTL |
26265 |
++ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) { |
26266 |
++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name); |
26267 |
++ return -EACCES; |
26268 |
++ } |
26269 |
++#endif |
26270 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
26271 |
++ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") && |
26272 |
++ grsec_modstop && (op & 002)) { |
26273 |
++ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name); |
26274 |
++ return -EACCES; |
26275 |
++ } |
26276 |
++#endif |
26277 |
++ return 0; |
26278 |
++} |
26279 |
++ |
26280 |
++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP) |
26281 |
++enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL, |
26282 |
++GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT, |
26283 |
++GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM, |
26284 |
++GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, |
26285 |
++GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS, |
26286 |
++GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT, |
26287 |
++GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, |
26288 |
++GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, |
26289 |
++GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG}; |
26290 |
++ |
26291 |
++ |
26292 |
++ctl_table grsecurity_table[] = { |
26293 |
++#ifdef CONFIG_GRKERNSEC_SYSCTL |
26294 |
++#ifdef CONFIG_GRKERNSEC_LINK |
26295 |
++ { |
26296 |
++ .ctl_name = GS_LINK, |
26297 |
++ .procname = "linking_restrictions", |
26298 |
++ .data = &grsec_enable_link, |
26299 |
++ .maxlen = sizeof(int), |
26300 |
++ .mode = 0600, |
26301 |
++ .proc_handler = &proc_dointvec, |
26302 |
++ }, |
26303 |
++#endif |
26304 |
++#ifdef CONFIG_GRKERNSEC_FIFO |
26305 |
++ { |
26306 |
++ .ctl_name = GS_FIFO, |
26307 |
++ .procname = "fifo_restrictions", |
26308 |
++ .data = &grsec_enable_fifo, |
26309 |
++ .maxlen = sizeof(int), |
26310 |
++ .mode = 0600, |
26311 |
++ .proc_handler = &proc_dointvec, |
26312 |
++ }, |
26313 |
++#endif |
26314 |
++#ifdef CONFIG_GRKERNSEC_EXECVE |
26315 |
++ { |
26316 |
++ .ctl_name = GS_EXECVE, |
26317 |
++ .procname = "execve_limiting", |
26318 |
++ .data = &grsec_enable_execve, |
26319 |
++ .maxlen = sizeof(int), |
26320 |
++ .mode = 0600, |
26321 |
++ .proc_handler = &proc_dointvec, |
26322 |
++ }, |
26323 |
++#endif |
26324 |
++#ifdef CONFIG_GRKERNSEC_EXECLOG |
26325 |
++ { |
26326 |
++ .ctl_name = GS_EXECLOG, |
26327 |
++ .procname = "exec_logging", |
26328 |
++ .data = &grsec_enable_execlog, |
26329 |
++ .maxlen = sizeof(int), |
26330 |
++ .mode = 0600, |
26331 |
++ .proc_handler = &proc_dointvec, |
26332 |
++ }, |
26333 |
++#endif |
26334 |
++#ifdef CONFIG_GRKERNSEC_SIGNAL |
26335 |
++ { |
26336 |
++ .ctl_name = GS_SIGNAL, |
26337 |
++ .procname = "signal_logging", |
26338 |
++ .data = &grsec_enable_signal, |
26339 |
++ .maxlen = sizeof(int), |
26340 |
++ .mode = 0600, |
26341 |
++ .proc_handler = &proc_dointvec, |
26342 |
++ }, |
26343 |
++#endif |
26344 |
++#ifdef CONFIG_GRKERNSEC_FORKFAIL |
26345 |
++ { |
26346 |
++ .ctl_name = GS_FORKFAIL, |
26347 |
++ .procname = "forkfail_logging", |
26348 |
++ .data = &grsec_enable_forkfail, |
26349 |
++ .maxlen = sizeof(int), |
26350 |
++ .mode = 0600, |
26351 |
++ .proc_handler = &proc_dointvec, |
26352 |
++ }, |
26353 |
++#endif |
26354 |
++#ifdef CONFIG_GRKERNSEC_TIME |
26355 |
++ { |
26356 |
++ .ctl_name = GS_TIME, |
26357 |
++ .procname = "timechange_logging", |
26358 |
++ .data = &grsec_enable_time, |
26359 |
++ .maxlen = sizeof(int), |
26360 |
++ .mode = 0600, |
26361 |
++ .proc_handler = &proc_dointvec, |
26362 |
++ }, |
26363 |
++#endif |
26364 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT |
26365 |
++ { |
26366 |
++ .ctl_name = GS_CHROOT_SHMAT, |
26367 |
++ .procname = "chroot_deny_shmat", |
26368 |
++ .data = &grsec_enable_chroot_shmat, |
26369 |
++ .maxlen = sizeof(int), |
26370 |
++ .mode = 0600, |
26371 |
++ .proc_handler = &proc_dointvec, |
26372 |
++ }, |
26373 |
++#endif |
26374 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
26375 |
++ { |
26376 |
++ .ctl_name = GS_CHROOT_UNIX, |
26377 |
++ .procname = "chroot_deny_unix", |
26378 |
++ .data = &grsec_enable_chroot_unix, |
26379 |
++ .maxlen = sizeof(int), |
26380 |
++ .mode = 0600, |
26381 |
++ .proc_handler = &proc_dointvec, |
26382 |
++ }, |
26383 |
++#endif |
26384 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT |
26385 |
++ { |
26386 |
++ .ctl_name = GS_CHROOT_MNT, |
26387 |
++ .procname = "chroot_deny_mount", |
26388 |
++ .data = &grsec_enable_chroot_mount, |
26389 |
++ .maxlen = sizeof(int), |
26390 |
++ .mode = 0600, |
26391 |
++ .proc_handler = &proc_dointvec, |
26392 |
++ }, |
26393 |
++#endif |
26394 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR |
26395 |
++ { |
26396 |
++ .ctl_name = GS_CHROOT_FCHDIR, |
26397 |
++ .procname = "chroot_deny_fchdir", |
26398 |
++ .data = &grsec_enable_chroot_fchdir, |
26399 |
++ .maxlen = sizeof(int), |
26400 |
++ .mode = 0600, |
26401 |
++ .proc_handler = &proc_dointvec, |
26402 |
++ }, |
26403 |
++#endif |
26404 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE |
26405 |
++ { |
26406 |
++ .ctl_name = GS_CHROOT_DBL, |
26407 |
++ .procname = "chroot_deny_chroot", |
26408 |
++ .data = &grsec_enable_chroot_double, |
26409 |
++ .maxlen = sizeof(int), |
26410 |
++ .mode = 0600, |
26411 |
++ .proc_handler = &proc_dointvec, |
26412 |
++ }, |
26413 |
++#endif |
26414 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT |
26415 |
++ { |
26416 |
++ .ctl_name = GS_CHROOT_PVT, |
26417 |
++ .procname = "chroot_deny_pivot", |
26418 |
++ .data = &grsec_enable_chroot_pivot, |
26419 |
++ .maxlen = sizeof(int), |
26420 |
++ .mode = 0600, |
26421 |
++ .proc_handler = &proc_dointvec, |
26422 |
++ }, |
26423 |
++#endif |
26424 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR |
26425 |
++ { |
26426 |
++ .ctl_name = GS_CHROOT_CD, |
26427 |
++ .procname = "chroot_enforce_chdir", |
26428 |
++ .data = &grsec_enable_chroot_chdir, |
26429 |
++ .maxlen = sizeof(int), |
26430 |
++ .mode = 0600, |
26431 |
++ .proc_handler = &proc_dointvec, |
26432 |
++ }, |
26433 |
++#endif |
26434 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD |
26435 |
++ { |
26436 |
++ .ctl_name = GS_CHROOT_CM, |
26437 |
++ .procname = "chroot_deny_chmod", |
26438 |
++ .data = &grsec_enable_chroot_chmod, |
26439 |
++ .maxlen = sizeof(int), |
26440 |
++ .mode = 0600, |
26441 |
++ .proc_handler = &proc_dointvec, |
26442 |
++ }, |
26443 |
++#endif |
26444 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD |
26445 |
++ { |
26446 |
++ .ctl_name = GS_CHROOT_MK, |
26447 |
++ .procname = "chroot_deny_mknod", |
26448 |
++ .data = &grsec_enable_chroot_mknod, |
26449 |
++ .maxlen = sizeof(int), |
26450 |
++ .mode = 0600, |
26451 |
++ .proc_handler = &proc_dointvec, |
26452 |
++ }, |
26453 |
++#endif |
26454 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_NICE |
26455 |
++ { |
26456 |
++ .ctl_name = GS_CHROOT_NI, |
26457 |
++ .procname = "chroot_restrict_nice", |
26458 |
++ .data = &grsec_enable_chroot_nice, |
26459 |
++ .maxlen = sizeof(int), |
26460 |
++ .mode = 0600, |
26461 |
++ .proc_handler = &proc_dointvec, |
26462 |
++ }, |
26463 |
++#endif |
26464 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG |
26465 |
++ { |
26466 |
++ .ctl_name = GS_CHROOT_EXECLOG, |
26467 |
++ .procname = "chroot_execlog", |
26468 |
++ .data = &grsec_enable_chroot_execlog, |
26469 |
++ .maxlen = sizeof(int), |
26470 |
++ .mode = 0600, |
26471 |
++ .proc_handler = &proc_dointvec, |
26472 |
++ }, |
26473 |
++#endif |
26474 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS |
26475 |
++ { |
26476 |
++ .ctl_name = GS_CHROOT_CAPS, |
26477 |
++ .procname = "chroot_caps", |
26478 |
++ .data = &grsec_enable_chroot_caps, |
26479 |
++ .maxlen = sizeof(int), |
26480 |
++ .mode = 0600, |
26481 |
++ .proc_handler = &proc_dointvec, |
26482 |
++ }, |
26483 |
++#endif |
26484 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL |
26485 |
++ { |
26486 |
++ .ctl_name = GS_CHROOT_SYSCTL, |
26487 |
++ .procname = "chroot_deny_sysctl", |
26488 |
++ .data = &grsec_enable_chroot_sysctl, |
26489 |
++ .maxlen = sizeof(int), |
26490 |
++ .mode = 0600, |
26491 |
++ .proc_handler = &proc_dointvec, |
26492 |
++ }, |
26493 |
++#endif |
26494 |
++#ifdef CONFIG_GRKERNSEC_TPE |
26495 |
++ { |
26496 |
++ .ctl_name = GS_TPE, |
26497 |
++ .procname = "tpe", |
26498 |
++ .data = &grsec_enable_tpe, |
26499 |
++ .maxlen = sizeof(int), |
26500 |
++ .mode = 0600, |
26501 |
++ .proc_handler = &proc_dointvec, |
26502 |
++ }, |
26503 |
++ { |
26504 |
++ .ctl_name = GS_TPE_GID, |
26505 |
++ .procname = "tpe_gid", |
26506 |
++ .data = &grsec_tpe_gid, |
26507 |
++ .maxlen = sizeof(int), |
26508 |
++ .mode = 0600, |
26509 |
++ .proc_handler = &proc_dointvec, |
26510 |
++ }, |
26511 |
++#endif |
26512 |
++#ifdef CONFIG_GRKERNSEC_TPE_ALL |
26513 |
++ { |
26514 |
++ .ctl_name = GS_TPE_ALL, |
26515 |
++ .procname = "tpe_restrict_all", |
26516 |
++ .data = &grsec_enable_tpe_all, |
26517 |
++ .maxlen = sizeof(int), |
26518 |
++ .mode = 0600, |
26519 |
++ .proc_handler = &proc_dointvec, |
26520 |
++ }, |
26521 |
++#endif |
26522 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_ALL |
26523 |
++ { |
26524 |
++ .ctl_name = GS_SOCKET_ALL, |
26525 |
++ .procname = "socket_all", |
26526 |
++ .data = &grsec_enable_socket_all, |
26527 |
++ .maxlen = sizeof(int), |
26528 |
++ .mode = 0600, |
26529 |
++ .proc_handler = &proc_dointvec, |
26530 |
++ }, |
26531 |
++ { |
26532 |
++ .ctl_name = GS_SOCKET_ALL_GID, |
26533 |
++ .procname = "socket_all_gid", |
26534 |
++ .data = &grsec_socket_all_gid, |
26535 |
++ .maxlen = sizeof(int), |
26536 |
++ .mode = 0600, |
26537 |
++ .proc_handler = &proc_dointvec, |
26538 |
++ }, |
26539 |
++#endif |
26540 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT |
26541 |
++ { |
26542 |
++ .ctl_name = GS_SOCKET_CLIENT, |
26543 |
++ .procname = "socket_client", |
26544 |
++ .data = &grsec_enable_socket_client, |
26545 |
++ .maxlen = sizeof(int), |
26546 |
++ .mode = 0600, |
26547 |
++ .proc_handler = &proc_dointvec, |
26548 |
++ }, |
26549 |
++ { |
26550 |
++ .ctl_name = GS_SOCKET_CLIENT_GID, |
26551 |
++ .procname = "socket_client_gid", |
26552 |
++ .data = &grsec_socket_client_gid, |
26553 |
++ .maxlen = sizeof(int), |
26554 |
++ .mode = 0600, |
26555 |
++ .proc_handler = &proc_dointvec, |
26556 |
++ }, |
26557 |
++#endif |
26558 |
++#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER |
26559 |
++ { |
26560 |
++ .ctl_name = GS_SOCKET_SERVER, |
26561 |
++ .procname = "socket_server", |
26562 |
++ .data = &grsec_enable_socket_server, |
26563 |
++ .maxlen = sizeof(int), |
26564 |
++ .mode = 0600, |
26565 |
++ .proc_handler = &proc_dointvec, |
26566 |
++ }, |
26567 |
++ { |
26568 |
++ .ctl_name = GS_SOCKET_SERVER_GID, |
26569 |
++ .procname = "socket_server_gid", |
26570 |
++ .data = &grsec_socket_server_gid, |
26571 |
++ .maxlen = sizeof(int), |
26572 |
++ .mode = 0600, |
26573 |
++ .proc_handler = &proc_dointvec, |
26574 |
++ }, |
26575 |
++#endif |
26576 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP |
26577 |
++ { |
26578 |
++ .ctl_name = GS_GROUP, |
26579 |
++ .procname = "audit_group", |
26580 |
++ .data = &grsec_enable_group, |
26581 |
++ .maxlen = sizeof(int), |
26582 |
++ .mode = 0600, |
26583 |
++ .proc_handler = &proc_dointvec, |
26584 |
++ }, |
26585 |
++ { |
26586 |
++ .ctl_name = GS_GID, |
26587 |
++ .procname = "audit_gid", |
26588 |
++ .data = &grsec_audit_gid, |
26589 |
++ .maxlen = sizeof(int), |
26590 |
++ .mode = 0600, |
26591 |
++ .proc_handler = &proc_dointvec, |
26592 |
++ }, |
26593 |
++#endif |
26594 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR |
26595 |
++ { |
26596 |
++ .ctl_name = GS_ACHDIR, |
26597 |
++ .procname = "audit_chdir", |
26598 |
++ .data = &grsec_enable_chdir, |
26599 |
++ .maxlen = sizeof(int), |
26600 |
++ .mode = 0600, |
26601 |
++ .proc_handler = &proc_dointvec, |
26602 |
++ }, |
26603 |
++#endif |
26604 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT |
26605 |
++ { |
26606 |
++ .ctl_name = GS_AMOUNT, |
26607 |
++ .procname = "audit_mount", |
26608 |
++ .data = &grsec_enable_mount, |
26609 |
++ .maxlen = sizeof(int), |
26610 |
++ .mode = 0600, |
26611 |
++ .proc_handler = &proc_dointvec, |
26612 |
++ }, |
26613 |
++#endif |
26614 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_IPC |
26615 |
++ { |
26616 |
++ .ctl_name = GS_AIPC, |
26617 |
++ .procname = "audit_ipc", |
26618 |
++ .data = &grsec_enable_audit_ipc, |
26619 |
++ .maxlen = sizeof(int), |
26620 |
++ .mode = 0600, |
26621 |
++ .proc_handler = &proc_dointvec, |
26622 |
++ }, |
26623 |
++#endif |
26624 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL |
26625 |
++ { |
26626 |
++ .ctl_name = GS_TEXTREL, |
26627 |
++ .procname = "audit_textrel", |
26628 |
++ .data = &grsec_enable_audit_textrel, |
26629 |
++ .maxlen = sizeof(int), |
26630 |
++ .mode = 0600, |
26631 |
++ .proc_handler = &proc_dointvec, |
26632 |
++ }, |
26633 |
++#endif |
26634 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
26635 |
++ { |
26636 |
++ .ctl_name = GS_DMSG, |
26637 |
++ .procname = "dmesg", |
26638 |
++ .data = &grsec_enable_dmesg, |
26639 |
++ .maxlen = sizeof(int), |
26640 |
++ .mode = 0600, |
26641 |
++ .proc_handler = &proc_dointvec, |
26642 |
++ }, |
26643 |
++#endif |
26644 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK |
26645 |
++ { |
26646 |
++ .ctl_name = GS_FINDTASK, |
26647 |
++ .procname = "chroot_findtask", |
26648 |
++ .data = &grsec_enable_chroot_findtask, |
26649 |
++ .maxlen = sizeof(int), |
26650 |
++ .mode = 0600, |
26651 |
++ .proc_handler = &proc_dointvec, |
26652 |
++ }, |
26653 |
++#endif |
26654 |
++#ifdef CONFIG_GRKERNSEC_SHM |
26655 |
++ { |
26656 |
++ .ctl_name = GS_SHM, |
26657 |
++ .procname = "destroy_unused_shm", |
26658 |
++ .data = &grsec_enable_shm, |
26659 |
++ .maxlen = sizeof(int), |
26660 |
++ .mode = 0600, |
26661 |
++ .proc_handler = &proc_dointvec, |
26662 |
++ }, |
26663 |
++#endif |
26664 |
++#ifdef CONFIG_GRKERNSEC_RESLOG |
26665 |
++ { |
26666 |
++ .ctl_name = GS_RESLOG, |
26667 |
++ .procname = "resource_logging", |
26668 |
++ .data = &grsec_resource_logging, |
26669 |
++ .maxlen = sizeof(int), |
26670 |
++ .mode = 0600, |
26671 |
++ .proc_handler = &proc_dointvec, |
26672 |
++ }, |
26673 |
++#endif |
26674 |
++ { |
26675 |
++ .ctl_name = GS_LOCK, |
26676 |
++ .procname = "grsec_lock", |
26677 |
++ .data = &grsec_lock, |
26678 |
++ .maxlen = sizeof(int), |
26679 |
++ .mode = 0600, |
26680 |
++ .proc_handler = &proc_dointvec, |
26681 |
++ }, |
26682 |
++#endif |
26683 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
26684 |
++ { |
26685 |
++ .ctl_name = GS_MODSTOP, |
26686 |
++ .procname = "disable_modules", |
26687 |
++ .data = &grsec_modstop, |
26688 |
++ .maxlen = sizeof(int), |
26689 |
++ .mode = 0600, |
26690 |
++ .proc_handler = &proc_dointvec, |
26691 |
++ }, |
26692 |
++#endif |
26693 |
++ { .ctl_name = 0 } |
26694 |
++}; |
26695 |
++#endif |
26696 |
++ |
26697 |
++int gr_check_modstop(void) |
26698 |
++{ |
26699 |
++#ifdef CONFIG_GRKERNSEC_MODSTOP |
26700 |
++ if (grsec_modstop == 1) { |
26701 |
++ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG); |
26702 |
++ return 1; |
26703 |
++ } |
26704 |
++#endif |
26705 |
++ return 0; |
26706 |
++} |
26707 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_textrel.c linux-2.6.23.15-grsec/grsecurity/grsec_textrel.c |
26708 |
+--- linux-2.6.23.15/grsecurity/grsec_textrel.c 1970-01-01 01:00:00.000000000 +0100 |
26709 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_textrel.c 2008-02-11 10:37:44.000000000 +0000 |
26710 |
+@@ -0,0 +1,16 @@ |
26711 |
++#include <linux/kernel.h> |
26712 |
++#include <linux/sched.h> |
26713 |
++#include <linux/mm.h> |
26714 |
++#include <linux/file.h> |
26715 |
++#include <linux/grinternal.h> |
26716 |
++#include <linux/grsecurity.h> |
26717 |
++ |
26718 |
++void |
26719 |
++gr_log_textrel(struct vm_area_struct * vma) |
26720 |
++{ |
26721 |
++#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL |
26722 |
++ if (grsec_enable_audit_textrel) |
26723 |
++ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff); |
26724 |
++#endif |
26725 |
++ return; |
26726 |
++} |
26727 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_time.c linux-2.6.23.15-grsec/grsecurity/grsec_time.c |
26728 |
+--- linux-2.6.23.15/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100 |
26729 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_time.c 2008-02-11 10:37:44.000000000 +0000 |
26730 |
+@@ -0,0 +1,13 @@ |
26731 |
++#include <linux/kernel.h> |
26732 |
++#include <linux/sched.h> |
26733 |
++#include <linux/grinternal.h> |
26734 |
++ |
26735 |
++void |
26736 |
++gr_log_timechange(void) |
26737 |
++{ |
26738 |
++#ifdef CONFIG_GRKERNSEC_TIME |
26739 |
++ if (grsec_enable_time) |
26740 |
++ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG); |
26741 |
++#endif |
26742 |
++ return; |
26743 |
++} |
26744 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsec_tpe.c linux-2.6.23.15-grsec/grsecurity/grsec_tpe.c |
26745 |
+--- linux-2.6.23.15/grsecurity/grsec_tpe.c 1970-01-01 01:00:00.000000000 +0100 |
26746 |
++++ linux-2.6.23.15-grsec/grsecurity/grsec_tpe.c 2008-02-11 10:37:44.000000000 +0000 |
26747 |
+@@ -0,0 +1,37 @@ |
26748 |
++#include <linux/kernel.h> |
26749 |
++#include <linux/sched.h> |
26750 |
++#include <linux/file.h> |
26751 |
++#include <linux/fs.h> |
26752 |
++#include <linux/grinternal.h> |
26753 |
++ |
26754 |
++extern int gr_acl_tpe_check(void); |
26755 |
++ |
26756 |
++int |
26757 |
++gr_tpe_allow(const struct file *file) |
26758 |
++{ |
26759 |
++#ifdef CONFIG_GRKERNSEC |
26760 |
++ struct inode *inode = file->f_dentry->d_parent->d_inode; |
26761 |
++ |
26762 |
++ if (current->uid && ((grsec_enable_tpe && |
26763 |
++#ifdef CONFIG_GRKERNSEC_TPE_INVERT |
26764 |
++ !in_group_p(grsec_tpe_gid) |
26765 |
++#else |
26766 |
++ in_group_p(grsec_tpe_gid) |
26767 |
++#endif |
26768 |
++ ) || gr_acl_tpe_check()) && |
26769 |
++ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) || |
26770 |
++ (inode->i_mode & S_IWOTH))))) { |
26771 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt); |
26772 |
++ return 0; |
26773 |
++ } |
26774 |
++#ifdef CONFIG_GRKERNSEC_TPE_ALL |
26775 |
++ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all && |
26776 |
++ ((inode->i_uid && (inode->i_uid != current->uid)) || |
26777 |
++ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) { |
26778 |
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt); |
26779 |
++ return 0; |
26780 |
++ } |
26781 |
++#endif |
26782 |
++#endif |
26783 |
++ return 1; |
26784 |
++} |
26785 |
+diff -Nurp linux-2.6.23.15/grsecurity/grsum.c linux-2.6.23.15-grsec/grsecurity/grsum.c |
26786 |
+--- linux-2.6.23.15/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100 |
26787 |
++++ linux-2.6.23.15-grsec/grsecurity/grsum.c 2008-02-11 10:37:44.000000000 +0000 |
26788 |
+@@ -0,0 +1,59 @@ |
26789 |
++#include <linux/err.h> |
26790 |
++#include <linux/kernel.h> |
26791 |
++#include <linux/sched.h> |
26792 |
++#include <linux/mm.h> |
26793 |
++#include <linux/scatterlist.h> |
26794 |
++#include <linux/crypto.h> |
26795 |
++#include <linux/gracl.h> |
26796 |
++ |
26797 |
++ |
26798 |
++#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE) |
26799 |
++#error "crypto and sha256 must be built into the kernel" |
26800 |
++#endif |
26801 |
++ |
26802 |
++int |
26803 |
++chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum) |
26804 |
++{ |
26805 |
++ char *p; |
26806 |
++ struct crypto_hash *tfm; |
26807 |
++ struct hash_desc desc; |
26808 |
++ struct scatterlist sg; |
26809 |
++ unsigned char temp_sum[GR_SHA_LEN]; |
26810 |
++ volatile int retval = 0; |
26811 |
++ volatile int dummy = 0; |
26812 |
++ unsigned int i; |
26813 |
++ |
26814 |
++ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC); |
26815 |
++ if (IS_ERR(tfm)) { |
26816 |
++ /* should never happen, since sha256 should be built in */ |
26817 |
++ return 1; |
26818 |
++ } |
26819 |
++ |
26820 |
++ desc.tfm = tfm; |
26821 |
++ desc.flags = 0; |
26822 |
++ |
26823 |
++ crypto_hash_init(&desc); |
26824 |
++ |
26825 |
++ p = salt; |
26826 |
++ sg_set_buf(&sg, p, GR_SALT_LEN); |
26827 |
++ crypto_hash_update(&desc, &sg, sg.length); |
26828 |
++ |
26829 |
++ p = entry->pw; |
26830 |
++ sg_set_buf(&sg, p, strlen(p)); |
26831 |
++ |
26832 |
++ crypto_hash_update(&desc, &sg, sg.length); |
26833 |
++ |
26834 |
++ crypto_hash_final(&desc, temp_sum); |
26835 |
++ |
26836 |
++ memset(entry->pw, 0, GR_PW_LEN); |
26837 |
++ |
26838 |
++ for (i = 0; i < GR_SHA_LEN; i++) |
26839 |
++ if (sum[i] != temp_sum[i]) |
26840 |
++ retval = 1; |
26841 |
++ else |
26842 |
++ dummy = 1; // waste a cycle |
26843 |
++ |
26844 |
++ crypto_free_hash(tfm); |
26845 |
++ |
26846 |
++ return retval; |
26847 |
++} |
26848 |
+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 |
26849 |
+--- linux-2.6.23.15/include/asm-alpha/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
26850 |
++++ linux-2.6.23.15-grsec/include/asm-alpha/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
26851 |
+@@ -98,7 +98,7 @@ struct exec |
26852 |
+ set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \ |
26853 |
+ ? ADDR_LIMIT_32BIT : 0) | PER_OSF4)) |
26854 |
+ |
26855 |
+-#define STACK_TOP \ |
26856 |
++#define __STACK_TOP \ |
26857 |
+ (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL) |
26858 |
+ |
26859 |
+ #define STACK_TOP_MAX 0x00120000000UL |
26860 |
+diff -Nurp linux-2.6.23.15/include/asm-alpha/elf.h linux-2.6.23.15-grsec/include/asm-alpha/elf.h |
26861 |
+--- linux-2.6.23.15/include/asm-alpha/elf.h 2007-10-09 21:31:38.000000000 +0100 |
26862 |
++++ linux-2.6.23.15-grsec/include/asm-alpha/elf.h 2008-02-11 10:37:44.000000000 +0000 |
26863 |
+@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N |
26864 |
+ |
26865 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) |
26866 |
+ |
26867 |
++#ifdef CONFIG_PAX_ASLR |
26868 |
++#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL) |
26869 |
++ |
26870 |
++#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28) |
26871 |
++#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19) |
26872 |
++#endif |
26873 |
++ |
26874 |
+ /* $0 is set by ld.so to a pointer to a function which might be |
26875 |
+ registered using atexit. This provides a mean for the dynamic |
26876 |
+ linker to call DT_FINI functions for shared libraries that have |
26877 |
+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 |
26878 |
+--- linux-2.6.23.15/include/asm-alpha/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
26879 |
++++ linux-2.6.23.15-grsec/include/asm-alpha/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
26880 |
+@@ -24,7 +24,8 @@ D(9) KM_IRQ0, |
26881 |
+ D(10) KM_IRQ1, |
26882 |
+ D(11) KM_SOFTIRQ0, |
26883 |
+ D(12) KM_SOFTIRQ1, |
26884 |
+-D(13) KM_TYPE_NR |
26885 |
++D(13) KM_CLEARPAGE, |
26886 |
++D(14) KM_TYPE_NR |
26887 |
+ }; |
26888 |
+ |
26889 |
+ #undef D |
26890 |
+diff -Nurp linux-2.6.23.15/include/asm-alpha/pgtable.h linux-2.6.23.15-grsec/include/asm-alpha/pgtable.h |
26891 |
+--- linux-2.6.23.15/include/asm-alpha/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
26892 |
++++ linux-2.6.23.15-grsec/include/asm-alpha/pgtable.h 2008-02-11 10:37:44.000000000 +0000 |
26893 |
+@@ -101,6 +101,17 @@ struct vm_area_struct; |
26894 |
+ #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS) |
26895 |
+ #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) |
26896 |
+ #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) |
26897 |
++ |
26898 |
++#ifdef CONFIG_PAX_PAGEEXEC |
26899 |
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE) |
26900 |
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) |
26901 |
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) |
26902 |
++#else |
26903 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
26904 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
26905 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
26906 |
++#endif |
26907 |
++ |
26908 |
+ #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE) |
26909 |
+ |
26910 |
+ #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x)) |
26911 |
+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 |
26912 |
+--- linux-2.6.23.15/include/asm-arm/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
26913 |
++++ linux-2.6.23.15-grsec/include/asm-arm/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
26914 |
+@@ -28,7 +28,7 @@ struct exec |
26915 |
+ #define M_ARM 103 |
26916 |
+ |
26917 |
+ #ifdef __KERNEL__ |
26918 |
+-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \ |
26919 |
++#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \ |
26920 |
+ TASK_SIZE : TASK_SIZE_26) |
26921 |
+ #define STACK_TOP_MAX TASK_SIZE |
26922 |
+ #endif |
26923 |
+diff -Nurp linux-2.6.23.15/include/asm-arm/elf.h linux-2.6.23.15-grsec/include/asm-arm/elf.h |
26924 |
+--- linux-2.6.23.15/include/asm-arm/elf.h 2007-10-09 21:31:38.000000000 +0100 |
26925 |
++++ linux-2.6.23.15-grsec/include/asm-arm/elf.h 2008-02-11 10:37:44.000000000 +0000 |
26926 |
+@@ -90,6 +90,13 @@ extern char elf_platform[]; |
26927 |
+ |
26928 |
+ #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) |
26929 |
+ |
26930 |
++#ifdef CONFIG_PAX_ASLR |
26931 |
++#define PAX_ELF_ET_DYN_BASE 0x00008000UL |
26932 |
++ |
26933 |
++#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10) |
26934 |
++#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10) |
26935 |
++#endif |
26936 |
++ |
26937 |
+ /* When the program starts, a1 contains a pointer to a function to be |
26938 |
+ registered with atexit, as per the SVR4 ABI. A value of 0 means we |
26939 |
+ have no such handler. */ |
26940 |
+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 |
26941 |
+--- linux-2.6.23.15/include/asm-arm/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
26942 |
++++ linux-2.6.23.15-grsec/include/asm-arm/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
26943 |
+@@ -18,6 +18,7 @@ enum km_type { |
26944 |
+ KM_IRQ1, |
26945 |
+ KM_SOFTIRQ0, |
26946 |
+ KM_SOFTIRQ1, |
26947 |
++ KM_CLEARPAGE, |
26948 |
+ KM_TYPE_NR |
26949 |
+ }; |
26950 |
+ |
26951 |
+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 |
26952 |
+--- linux-2.6.23.15/include/asm-avr32/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
26953 |
++++ linux-2.6.23.15-grsec/include/asm-avr32/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
26954 |
+@@ -19,8 +19,8 @@ struct exec |
26955 |
+ |
26956 |
+ #ifdef __KERNEL__ |
26957 |
+ |
26958 |
+-#define STACK_TOP TASK_SIZE |
26959 |
+-#define STACK_TOP_MAX STACK_TOP |
26960 |
++#define __STACK_TOP TASK_SIZE |
26961 |
++#define STACK_TOP_MAX __STACK_TOP |
26962 |
+ |
26963 |
+ #endif |
26964 |
+ |
26965 |
+diff -Nurp linux-2.6.23.15/include/asm-avr32/elf.h linux-2.6.23.15-grsec/include/asm-avr32/elf.h |
26966 |
+--- linux-2.6.23.15/include/asm-avr32/elf.h 2007-10-09 21:31:38.000000000 +0100 |
26967 |
++++ linux-2.6.23.15-grsec/include/asm-avr32/elf.h 2008-02-11 10:37:44.000000000 +0000 |
26968 |
+@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg |
26969 |
+ the loader. We need to make sure that it is out of the way of the program |
26970 |
+ that it will "exec", and that there is sufficient room for the brk. */ |
26971 |
+ |
26972 |
+-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) |
26973 |
++#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
26974 |
+ |
26975 |
++#ifdef CONFIG_PAX_ASLR |
26976 |
++#define PAX_ELF_ET_DYN_BASE 0x00001000UL |
26977 |
++ |
26978 |
++#define PAX_DELTA_MMAP_LEN 15 |
26979 |
++#define PAX_DELTA_STACK_LEN 15 |
26980 |
++#endif |
26981 |
+ |
26982 |
+ /* This yields a mask that user programs can use to figure out what |
26983 |
+ instruction set this CPU supports. This could be done in user space, |
26984 |
+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 |
26985 |
+--- linux-2.6.23.15/include/asm-avr32/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
26986 |
++++ linux-2.6.23.15-grsec/include/asm-avr32/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
26987 |
+@@ -22,7 +22,8 @@ D(10) KM_IRQ0, |
26988 |
+ D(11) KM_IRQ1, |
26989 |
+ D(12) KM_SOFTIRQ0, |
26990 |
+ D(13) KM_SOFTIRQ1, |
26991 |
+-D(14) KM_TYPE_NR |
26992 |
++D(14) KM_CLEARPAGE, |
26993 |
++D(15) KM_TYPE_NR |
26994 |
+ }; |
26995 |
+ |
26996 |
+ #undef D |
26997 |
+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 |
26998 |
+--- linux-2.6.23.15/include/asm-blackfin/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
26999 |
++++ linux-2.6.23.15-grsec/include/asm-blackfin/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
27000 |
+@@ -15,6 +15,7 @@ enum km_type { |
27001 |
+ KM_IRQ1, |
27002 |
+ KM_SOFTIRQ0, |
27003 |
+ KM_SOFTIRQ1, |
27004 |
++ KM_CLEARPAGE, |
27005 |
+ KM_TYPE_NR |
27006 |
+ }; |
27007 |
+ |
27008 |
+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 |
27009 |
+--- linux-2.6.23.15/include/asm-cris/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
27010 |
++++ linux-2.6.23.15-grsec/include/asm-cris/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
27011 |
+@@ -19,6 +19,7 @@ enum km_type { |
27012 |
+ KM_IRQ1, |
27013 |
+ KM_SOFTIRQ0, |
27014 |
+ KM_SOFTIRQ1, |
27015 |
++ KM_CLEARPAGE, |
27016 |
+ KM_TYPE_NR |
27017 |
+ }; |
27018 |
+ |
27019 |
+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 |
27020 |
+--- linux-2.6.23.15/include/asm-frv/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
27021 |
++++ linux-2.6.23.15-grsec/include/asm-frv/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
27022 |
+@@ -23,6 +23,7 @@ enum km_type { |
27023 |
+ KM_IRQ1, |
27024 |
+ KM_SOFTIRQ0, |
27025 |
+ KM_SOFTIRQ1, |
27026 |
++ KM_CLEARPAGE, |
27027 |
+ KM_TYPE_NR |
27028 |
+ }; |
27029 |
+ |
27030 |
+diff -Nurp linux-2.6.23.15/include/asm-generic/futex.h linux-2.6.23.15-grsec/include/asm-generic/futex.h |
27031 |
+--- linux-2.6.23.15/include/asm-generic/futex.h 2007-10-09 21:31:38.000000000 +0100 |
27032 |
++++ linux-2.6.23.15-grsec/include/asm-generic/futex.h 2008-02-11 10:37:44.000000000 +0000 |
27033 |
+@@ -8,7 +8,7 @@ |
27034 |
+ #include <asm/uaccess.h> |
27035 |
+ |
27036 |
+ static inline int |
27037 |
+-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) |
27038 |
++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
27039 |
+ { |
27040 |
+ int op = (encoded_op >> 28) & 7; |
27041 |
+ int cmp = (encoded_op >> 24) & 15; |
27042 |
+@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op, |
27043 |
+ } |
27044 |
+ |
27045 |
+ static inline int |
27046 |
+-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) |
27047 |
++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) |
27048 |
+ { |
27049 |
+ return -ENOSYS; |
27050 |
+ } |
27051 |
+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 |
27052 |
+--- linux-2.6.23.15/include/asm-generic/vmlinux.lds.h 2007-10-09 21:31:38.000000000 +0100 |
27053 |
++++ linux-2.6.23.15-grsec/include/asm-generic/vmlinux.lds.h 2008-02-11 10:37:44.000000000 +0000 |
27054 |
+@@ -19,6 +19,7 @@ |
27055 |
+ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \ |
27056 |
+ VMLINUX_SYMBOL(__start_rodata) = .; \ |
27057 |
+ *(.rodata) *(.rodata.*) \ |
27058 |
++ *(.data.read_only) \ |
27059 |
+ *(__vermagic) /* Kernel version magic */ \ |
27060 |
+ } \ |
27061 |
+ \ |
27062 |
+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 |
27063 |
+--- linux-2.6.23.15/include/asm-h8300/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
27064 |
++++ linux-2.6.23.15-grsec/include/asm-h8300/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
27065 |
+@@ -15,6 +15,7 @@ enum km_type { |
27066 |
+ KM_IRQ1, |
27067 |
+ KM_SOFTIRQ0, |
27068 |
+ KM_SOFTIRQ1, |
27069 |
++ KM_CLEARPAGE, |
27070 |
+ KM_TYPE_NR |
27071 |
+ }; |
27072 |
+ |
27073 |
+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 |
27074 |
+--- linux-2.6.23.15/include/asm-i386/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
27075 |
++++ linux-2.6.23.15-grsec/include/asm-i386/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
27076 |
+@@ -19,8 +19,13 @@ struct exec |
27077 |
+ |
27078 |
+ #ifdef __KERNEL__ |
27079 |
+ |
27080 |
+-#define STACK_TOP TASK_SIZE |
27081 |
+-#define STACK_TOP_MAX STACK_TOP |
27082 |
++#ifdef CONFIG_PAX_SEGMEXEC |
27083 |
++#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE) |
27084 |
++#else |
27085 |
++#define __STACK_TOP TASK_SIZE |
27086 |
++#endif |
27087 |
++ |
27088 |
++#define STACK_TOP_MAX TASK_SIZE |
27089 |
+ |
27090 |
+ #endif |
27091 |
+ |
27092 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/alternative.h linux-2.6.23.15-grsec/include/asm-i386/alternative.h |
27093 |
+--- linux-2.6.23.15/include/asm-i386/alternative.h 2007-10-09 21:31:38.000000000 +0100 |
27094 |
++++ linux-2.6.23.15-grsec/include/asm-i386/alternative.h 2008-02-11 10:37:44.000000000 +0000 |
27095 |
+@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit |
27096 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
27097 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
27098 |
+ ".previous\n" \ |
27099 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
27100 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
27101 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */\ |
27102 |
+ ".previous" :: "i" (feature) : "memory") |
27103 |
+ |
27104 |
+@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit |
27105 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
27106 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
27107 |
+ ".previous\n" \ |
27108 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
27109 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
27110 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */\ |
27111 |
+ ".previous" :: "i" (feature), ##input) |
27112 |
+ |
27113 |
+@@ -93,7 +93,7 @@ static inline void alternatives_smp_swit |
27114 |
+ " .byte 662b-661b\n" /* sourcelen */ \ |
27115 |
+ " .byte 664f-663f\n" /* replacementlen */ \ |
27116 |
+ ".previous\n" \ |
27117 |
+- ".section .altinstr_replacement,\"ax\"\n" \ |
27118 |
++ ".section .altinstr_replacement,\"a\"\n" \ |
27119 |
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \ |
27120 |
+ ".previous" : output : [feat] "i" (feature), ##input) |
27121 |
+ |
27122 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/apic.h linux-2.6.23.15-grsec/include/asm-i386/apic.h |
27123 |
+--- linux-2.6.23.15/include/asm-i386/apic.h 2007-10-09 21:31:38.000000000 +0100 |
27124 |
++++ linux-2.6.23.15-grsec/include/asm-i386/apic.h 2008-02-11 10:37:44.000000000 +0000 |
27125 |
+@@ -8,7 +8,7 @@ |
27126 |
+ #include <asm/processor.h> |
27127 |
+ #include <asm/system.h> |
27128 |
+ |
27129 |
+-#define Dprintk(x...) |
27130 |
++#define Dprintk(x...) do {} while (0) |
27131 |
+ |
27132 |
+ /* |
27133 |
+ * Debugging macros |
27134 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/cache.h linux-2.6.23.15-grsec/include/asm-i386/cache.h |
27135 |
+--- linux-2.6.23.15/include/asm-i386/cache.h 2007-10-09 21:31:38.000000000 +0100 |
27136 |
++++ linux-2.6.23.15-grsec/include/asm-i386/cache.h 2008-02-11 10:37:44.000000000 +0000 |
27137 |
+@@ -10,5 +10,6 @@ |
27138 |
+ #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) |
27139 |
+ |
27140 |
+ #define __read_mostly __attribute__((__section__(".data.read_mostly"))) |
27141 |
++#define __read_only __attribute__((__section__(".data.read_only"))) |
27142 |
+ |
27143 |
+ #endif |
27144 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/checksum.h linux-2.6.23.15-grsec/include/asm-i386/checksum.h |
27145 |
+--- linux-2.6.23.15/include/asm-i386/checksum.h 2007-10-09 21:31:38.000000000 +0100 |
27146 |
++++ linux-2.6.23.15-grsec/include/asm-i386/checksum.h 2008-02-11 10:37:44.000000000 +0000 |
27147 |
+@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi |
27148 |
+ asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, |
27149 |
+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr); |
27150 |
+ |
27151 |
++asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst, |
27152 |
++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr); |
27153 |
++ |
27154 |
++asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst, |
27155 |
++ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr); |
27156 |
++ |
27157 |
+ /* |
27158 |
+ * Note: when you get a NULL pointer exception here this means someone |
27159 |
+ * passed in an incorrect kernel address to one of these functions. |
27160 |
+@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const |
27161 |
+ int len, __wsum sum, int *err_ptr) |
27162 |
+ { |
27163 |
+ might_sleep(); |
27164 |
+- return csum_partial_copy_generic((__force void *)src, dst, |
27165 |
++ return csum_partial_copy_generic_from_user((__force void *)src, dst, |
27166 |
+ len, sum, err_ptr, NULL); |
27167 |
+ } |
27168 |
+ |
27169 |
+@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t |
27170 |
+ { |
27171 |
+ might_sleep(); |
27172 |
+ if (access_ok(VERIFY_WRITE, dst, len)) |
27173 |
+- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr); |
27174 |
++ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr); |
27175 |
+ |
27176 |
+ if (len) |
27177 |
+ *err_ptr = -EFAULT; |
27178 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/desc.h linux-2.6.23.15-grsec/include/asm-i386/desc.h |
27179 |
+--- linux-2.6.23.15/include/asm-i386/desc.h 2007-10-09 21:31:38.000000000 +0100 |
27180 |
++++ linux-2.6.23.15-grsec/include/asm-i386/desc.h 2008-02-11 10:37:44.000000000 +0000 |
27181 |
+@@ -7,26 +7,22 @@ |
27182 |
+ #ifndef __ASSEMBLY__ |
27183 |
+ |
27184 |
+ #include <linux/preempt.h> |
27185 |
+-#include <linux/smp.h> |
27186 |
+ #include <linux/percpu.h> |
27187 |
++#include <linux/smp.h> |
27188 |
+ |
27189 |
+ #include <asm/mmu.h> |
27190 |
+ |
27191 |
++extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)]; |
27192 |
++ |
27193 |
+ struct Xgt_desc_struct { |
27194 |
+ unsigned short size; |
27195 |
+- unsigned long address __attribute__((packed)); |
27196 |
++ struct desc_struct *address __attribute__((packed)); |
27197 |
+ unsigned short pad; |
27198 |
+ } __attribute__ ((packed)); |
27199 |
+ |
27200 |
+-struct gdt_page |
27201 |
+-{ |
27202 |
+- struct desc_struct gdt[GDT_ENTRIES]; |
27203 |
+-} __attribute__((aligned(PAGE_SIZE))); |
27204 |
+-DECLARE_PER_CPU(struct gdt_page, gdt_page); |
27205 |
+- |
27206 |
+ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) |
27207 |
+ { |
27208 |
+- return per_cpu(gdt_page, cpu).gdt; |
27209 |
++ return cpu_gdt_table[cpu]; |
27210 |
+ } |
27211 |
+ |
27212 |
+ extern struct Xgt_desc_struct idt_descr; |
27213 |
+@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _ |
27214 |
+ static inline void write_dt_entry(struct desc_struct *dt, |
27215 |
+ int entry, u32 entry_low, u32 entry_high) |
27216 |
+ { |
27217 |
++ |
27218 |
++#ifdef CONFIG_PAX_KERNEXEC |
27219 |
++ unsigned long cr0; |
27220 |
++ |
27221 |
++ pax_open_kernel(cr0); |
27222 |
++#endif |
27223 |
++ |
27224 |
+ dt[entry].a = entry_low; |
27225 |
+ dt[entry].b = entry_high; |
27226 |
++ |
27227 |
++#ifdef CONFIG_PAX_KERNEXEC |
27228 |
++ pax_close_kernel(cr0); |
27229 |
++#endif |
27230 |
++ |
27231 |
+ } |
27232 |
+ |
27233 |
+ static inline void native_set_ldt(const void *addr, unsigned int entries) |
27234 |
+@@ -139,8 +147,19 @@ static inline void native_load_tls(struc |
27235 |
+ unsigned int i; |
27236 |
+ struct desc_struct *gdt = get_cpu_gdt_table(cpu); |
27237 |
+ |
27238 |
++#ifdef CONFIG_PAX_KERNEXEC |
27239 |
++ unsigned long cr0; |
27240 |
++ |
27241 |
++ pax_open_kernel(cr0); |
27242 |
++#endif |
27243 |
++ |
27244 |
+ for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++) |
27245 |
+ gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; |
27246 |
++ |
27247 |
++#ifdef CONFIG_PAX_KERNEXEC |
27248 |
++ pax_close_kernel(cr0); |
27249 |
++#endif |
27250 |
++ |
27251 |
+ } |
27252 |
+ |
27253 |
+ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) |
27254 |
+@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign |
27255 |
+ ((info)->seg_32bit << 22) | \ |
27256 |
+ ((info)->limit_in_pages << 23) | \ |
27257 |
+ ((info)->useable << 20) | \ |
27258 |
+- 0x7000) |
27259 |
++ 0x7100) |
27260 |
+ |
27261 |
+ #define LDT_empty(info) (\ |
27262 |
+ (info)->base_addr == 0 && \ |
27263 |
+@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t |
27264 |
+ preempt_enable(); |
27265 |
+ } |
27266 |
+ |
27267 |
+-static inline unsigned long get_desc_base(unsigned long *desc) |
27268 |
++static inline unsigned long get_desc_base(struct desc_struct *desc) |
27269 |
+ { |
27270 |
+ unsigned long base; |
27271 |
+- base = ((desc[0] >> 16) & 0x0000ffff) | |
27272 |
+- ((desc[1] << 16) & 0x00ff0000) | |
27273 |
+- (desc[1] & 0xff000000); |
27274 |
++ base = ((desc->a >> 16) & 0x0000ffff) | |
27275 |
++ ((desc->b << 16) & 0x00ff0000) | |
27276 |
++ (desc->b & 0xff000000); |
27277 |
+ return base; |
27278 |
+ } |
27279 |
+ |
27280 |
++static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu) |
27281 |
++{ |
27282 |
++ __u32 a, b; |
27283 |
++ |
27284 |
++ if (likely(limit)) |
27285 |
++ limit = (limit - 1UL) >> PAGE_SHIFT; |
27286 |
++ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC); |
27287 |
++ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b); |
27288 |
++} |
27289 |
++ |
27290 |
+ #else /* __ASSEMBLY__ */ |
27291 |
+ |
27292 |
+ /* |
27293 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/elf.h linux-2.6.23.15-grsec/include/asm-i386/elf.h |
27294 |
+--- linux-2.6.23.15/include/asm-i386/elf.h 2007-10-09 21:31:38.000000000 +0100 |
27295 |
++++ linux-2.6.23.15-grsec/include/asm-i386/elf.h 2008-02-11 10:37:44.000000000 +0000 |
27296 |
+@@ -73,7 +73,18 @@ typedef struct user_fxsr_struct elf_fpxr |
27297 |
+ the loader. We need to make sure that it is out of the way of the program |
27298 |
+ that it will "exec", and that there is sufficient room for the brk. */ |
27299 |
+ |
27300 |
++#ifdef CONFIG_PAX_SEGMEXEC |
27301 |
++#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2) |
27302 |
++#else |
27303 |
+ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
27304 |
++#endif |
27305 |
++ |
27306 |
++#ifdef CONFIG_PAX_ASLR |
27307 |
++#define PAX_ELF_ET_DYN_BASE 0x10000000UL |
27308 |
++ |
27309 |
++#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) |
27310 |
++#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16) |
27311 |
++#endif |
27312 |
+ |
27313 |
+ /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is |
27314 |
+ now struct_user_regs, they are different) */ |
27315 |
+@@ -131,7 +142,7 @@ extern int dump_task_extended_fpu (struc |
27316 |
+ #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs) |
27317 |
+ |
27318 |
+ #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO)) |
27319 |
+-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso) |
27320 |
++#define VDSO_CURRENT_BASE (current->mm->context.vdso) |
27321 |
+ #define VDSO_PRELINK 0 |
27322 |
+ |
27323 |
+ #define VDSO_SYM(x) \ |
27324 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/futex.h linux-2.6.23.15-grsec/include/asm-i386/futex.h |
27325 |
+--- linux-2.6.23.15/include/asm-i386/futex.h 2007-10-09 21:31:38.000000000 +0100 |
27326 |
++++ linux-2.6.23.15-grsec/include/asm-i386/futex.h 2008-02-11 10:37:44.000000000 +0000 |
27327 |
+@@ -11,8 +11,11 @@ |
27328 |
+ |
27329 |
+ #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \ |
27330 |
+ __asm__ __volatile ( \ |
27331 |
++ "movw %w6, %%ds\n"\ |
27332 |
+ "1: " insn "\n" \ |
27333 |
+-"2: .section .fixup,\"ax\"\n\ |
27334 |
++"2: pushl %%ss\n\ |
27335 |
++ popl %%ds\n\ |
27336 |
++ .section .fixup,\"ax\"\n\ |
27337 |
+ 3: mov %3, %1\n\ |
27338 |
+ jmp 2b\n\ |
27339 |
+ .previous\n\ |
27340 |
+@@ -21,16 +24,19 @@ |
27341 |
+ .long 1b,3b\n\ |
27342 |
+ .previous" \ |
27343 |
+ : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \ |
27344 |
+- : "i" (-EFAULT), "0" (oparg), "1" (0)) |
27345 |
++ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS)) |
27346 |
+ |
27347 |
+ #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \ |
27348 |
+ __asm__ __volatile ( \ |
27349 |
+-"1: movl %2, %0\n\ |
27350 |
++" movw %w7, %%es\n\ |
27351 |
++1: movl %%es:%2, %0\n\ |
27352 |
+ movl %0, %3\n" \ |
27353 |
+ insn "\n" \ |
27354 |
+-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\ |
27355 |
++"2: " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\ |
27356 |
+ jnz 1b\n\ |
27357 |
+-3: .section .fixup,\"ax\"\n\ |
27358 |
++3: pushl %%ss\n\ |
27359 |
++ popl %%es\n\ |
27360 |
++ .section .fixup,\"ax\"\n\ |
27361 |
+ 4: mov %5, %1\n\ |
27362 |
+ jmp 3b\n\ |
27363 |
+ .previous\n\ |
27364 |
+@@ -40,10 +46,10 @@ |
27365 |
+ .previous" \ |
27366 |
+ : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \ |
27367 |
+ "=&r" (tem) \ |
27368 |
+- : "r" (oparg), "i" (-EFAULT), "1" (0)) |
27369 |
++ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS)) |
27370 |
+ |
27371 |
+ static inline int |
27372 |
+-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) |
27373 |
++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
27374 |
+ { |
27375 |
+ int op = (encoded_op >> 28) & 7; |
27376 |
+ int cmp = (encoded_op >> 24) & 15; |
27377 |
+@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op, |
27378 |
+ pagefault_disable(); |
27379 |
+ |
27380 |
+ if (op == FUTEX_OP_SET) |
27381 |
+- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); |
27382 |
++ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg); |
27383 |
+ else { |
27384 |
+ #ifndef CONFIG_X86_BSWAP |
27385 |
+ if (boot_cpu_data.x86 == 3) |
27386 |
+@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op, |
27387 |
+ #endif |
27388 |
+ switch (op) { |
27389 |
+ case FUTEX_OP_ADD: |
27390 |
+- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret, |
27391 |
++ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret, |
27392 |
+ oldval, uaddr, oparg); |
27393 |
+ break; |
27394 |
+ case FUTEX_OP_OR: |
27395 |
+@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op, |
27396 |
+ } |
27397 |
+ |
27398 |
+ static inline int |
27399 |
+-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) |
27400 |
++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) |
27401 |
+ { |
27402 |
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
27403 |
+ return -EFAULT; |
27404 |
+ |
27405 |
+ __asm__ __volatile__( |
27406 |
+- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n" |
27407 |
+- |
27408 |
+- "2: .section .fixup, \"ax\" \n" |
27409 |
++ " movw %w5, %%ds \n" |
27410 |
++ "1: " LOCK_PREFIX "cmpxchgl %3, %%ds:%1 \n" |
27411 |
++ "2: pushl %%ss \n" |
27412 |
++ " popl %%ds \n" |
27413 |
++ " .section .fixup, \"ax\" \n" |
27414 |
+ "3: mov %2, %0 \n" |
27415 |
+ " jmp 2b \n" |
27416 |
+ " .previous \n" |
27417 |
+@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user |
27418 |
+ " .previous \n" |
27419 |
+ |
27420 |
+ : "=a" (oldval), "+m" (*uaddr) |
27421 |
+- : "i" (-EFAULT), "r" (newval), "0" (oldval) |
27422 |
++ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS) |
27423 |
+ : "memory" |
27424 |
+ ); |
27425 |
+ |
27426 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/i387.h linux-2.6.23.15-grsec/include/asm-i386/i387.h |
27427 |
+--- linux-2.6.23.15/include/asm-i386/i387.h 2007-10-09 21:31:38.000000000 +0100 |
27428 |
++++ linux-2.6.23.15-grsec/include/asm-i386/i387.h 2008-02-11 10:37:44.000000000 +0000 |
27429 |
+@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void); |
27430 |
+ #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) |
27431 |
+ |
27432 |
+ /* We need a safe address that is cheap to find and that is already |
27433 |
+- in L1 during context switch. The best choices are unfortunately |
27434 |
+- different for UP and SMP */ |
27435 |
+-#ifdef CONFIG_SMP |
27436 |
+-#define safe_address (__per_cpu_offset[0]) |
27437 |
+-#else |
27438 |
+-#define safe_address (kstat_cpu(0).cpustat.user) |
27439 |
+-#endif |
27440 |
++ in L1 during context switch. */ |
27441 |
++#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0) |
27442 |
+ |
27443 |
+ /* |
27444 |
+ * These must be called with preempt disabled |
27445 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/irqflags.h linux-2.6.23.15-grsec/include/asm-i386/irqflags.h |
27446 |
+--- linux-2.6.23.15/include/asm-i386/irqflags.h 2007-10-09 21:31:38.000000000 +0100 |
27447 |
++++ linux-2.6.23.15-grsec/include/asm-i386/irqflags.h 2008-02-11 10:37:44.000000000 +0000 |
27448 |
+@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_ |
27449 |
+ #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit |
27450 |
+ #define INTERRUPT_RETURN iret |
27451 |
+ #define GET_CR0_INTO_EAX movl %cr0, %eax |
27452 |
++#define GET_CR0_INTO_EDX movl %cr0, %edx |
27453 |
++#define SET_CR0_FROM_EDX movl %edx, %cr0 |
27454 |
+ #endif /* __ASSEMBLY__ */ |
27455 |
+ #endif /* CONFIG_PARAVIRT */ |
27456 |
+ |
27457 |
+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 |
27458 |
+--- linux-2.6.23.15/include/asm-i386/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
27459 |
++++ linux-2.6.23.15-grsec/include/asm-i386/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
27460 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
27461 |
+ D(10) KM_IRQ1, |
27462 |
+ D(11) KM_SOFTIRQ0, |
27463 |
+ D(12) KM_SOFTIRQ1, |
27464 |
+-D(13) KM_TYPE_NR |
27465 |
++D(13) KM_CLEARPAGE, |
27466 |
++D(14) KM_TYPE_NR |
27467 |
+ }; |
27468 |
+ |
27469 |
+ #undef D |
27470 |
+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 |
27471 |
+--- linux-2.6.23.15/include/asm-i386/mach-default/apm.h 2007-10-09 21:31:38.000000000 +0100 |
27472 |
++++ linux-2.6.23.15-grsec/include/asm-i386/mach-default/apm.h 2008-02-11 10:37:44.000000000 +0000 |
27473 |
+@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32 |
27474 |
+ __asm__ __volatile__(APM_DO_ZERO_SEGS |
27475 |
+ "pushl %%edi\n\t" |
27476 |
+ "pushl %%ebp\n\t" |
27477 |
+- "lcall *%%cs:apm_bios_entry\n\t" |
27478 |
++ "lcall *%%ss:apm_bios_entry\n\t" |
27479 |
+ "setc %%al\n\t" |
27480 |
+ "popl %%ebp\n\t" |
27481 |
+ "popl %%edi\n\t" |
27482 |
+@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as |
27483 |
+ __asm__ __volatile__(APM_DO_ZERO_SEGS |
27484 |
+ "pushl %%edi\n\t" |
27485 |
+ "pushl %%ebp\n\t" |
27486 |
+- "lcall *%%cs:apm_bios_entry\n\t" |
27487 |
++ "lcall *%%ss:apm_bios_entry\n\t" |
27488 |
+ "setc %%bl\n\t" |
27489 |
+ "popl %%ebp\n\t" |
27490 |
+ "popl %%edi\n\t" |
27491 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/mman.h linux-2.6.23.15-grsec/include/asm-i386/mman.h |
27492 |
+--- linux-2.6.23.15/include/asm-i386/mman.h 2007-10-09 21:31:38.000000000 +0100 |
27493 |
++++ linux-2.6.23.15-grsec/include/asm-i386/mman.h 2008-02-11 10:37:44.000000000 +0000 |
27494 |
+@@ -14,4 +14,12 @@ |
27495 |
+ #define MCL_CURRENT 1 /* lock all current mappings */ |
27496 |
+ #define MCL_FUTURE 2 /* lock all future mappings */ |
27497 |
+ |
27498 |
++#ifdef __KERNEL__ |
27499 |
++#ifndef __ASSEMBLY__ |
27500 |
++#define arch_mmap_check i386_mmap_check |
27501 |
++int i386_mmap_check(unsigned long addr, unsigned long len, |
27502 |
++ unsigned long flags); |
27503 |
++#endif |
27504 |
++#endif |
27505 |
++ |
27506 |
+ #endif /* __I386_MMAN_H__ */ |
27507 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/mmu.h linux-2.6.23.15-grsec/include/asm-i386/mmu.h |
27508 |
+--- linux-2.6.23.15/include/asm-i386/mmu.h 2007-10-09 21:31:38.000000000 +0100 |
27509 |
++++ linux-2.6.23.15-grsec/include/asm-i386/mmu.h 2008-02-11 10:37:44.000000000 +0000 |
27510 |
+@@ -11,8 +11,19 @@ |
27511 |
+ typedef struct { |
27512 |
+ int size; |
27513 |
+ struct semaphore sem; |
27514 |
+- void *ldt; |
27515 |
+- void *vdso; |
27516 |
++ struct desc_struct *ldt; |
27517 |
++ unsigned long vdso; |
27518 |
++ |
27519 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
27520 |
++ unsigned long user_cs_base; |
27521 |
++ unsigned long user_cs_limit; |
27522 |
++ |
27523 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) |
27524 |
++ cpumask_t cpu_user_cs_mask; |
27525 |
++#endif |
27526 |
++ |
27527 |
++#endif |
27528 |
++ |
27529 |
+ } mm_context_t; |
27530 |
+ |
27531 |
+ #endif |
27532 |
+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 |
27533 |
+--- linux-2.6.23.15/include/asm-i386/mmu_context.h 2007-10-09 21:31:38.000000000 +0100 |
27534 |
++++ linux-2.6.23.15-grsec/include/asm-i386/mmu_context.h 2008-02-11 10:37:44.000000000 +0000 |
27535 |
+@@ -57,6 +57,22 @@ static inline void switch_mm(struct mm_s |
27536 |
+ */ |
27537 |
+ if (unlikely(prev->context.ldt != next->context.ldt)) |
27538 |
+ load_LDT_nolock(&next->context); |
27539 |
++ |
27540 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP) |
27541 |
++ if (!nx_enabled) { |
27542 |
++ smp_mb__before_clear_bit(); |
27543 |
++ cpu_clear(cpu, prev->context.cpu_user_cs_mask); |
27544 |
++ smp_mb__after_clear_bit(); |
27545 |
++ cpu_set(cpu, next->context.cpu_user_cs_mask); |
27546 |
++ } |
27547 |
++#endif |
27548 |
++ |
27549 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
27550 |
++ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base || |
27551 |
++ prev->context.user_cs_limit != next->context.user_cs_limit)) |
27552 |
++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu); |
27553 |
++#endif |
27554 |
++ |
27555 |
+ } |
27556 |
+ #ifdef CONFIG_SMP |
27557 |
+ else { |
27558 |
+@@ -69,6 +85,19 @@ static inline void switch_mm(struct mm_s |
27559 |
+ */ |
27560 |
+ load_cr3(next->pgd); |
27561 |
+ load_LDT_nolock(&next->context); |
27562 |
++ |
27563 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27564 |
++ if (!nx_enabled) |
27565 |
++ cpu_set(cpu, next->context.cpu_user_cs_mask); |
27566 |
++#endif |
27567 |
++ |
27568 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
27569 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27570 |
++ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled)) |
27571 |
++#endif |
27572 |
++ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu); |
27573 |
++#endif |
27574 |
++ |
27575 |
+ } |
27576 |
+ } |
27577 |
+ #endif |
27578 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/module.h linux-2.6.23.15-grsec/include/asm-i386/module.h |
27579 |
+--- linux-2.6.23.15/include/asm-i386/module.h 2007-10-09 21:31:38.000000000 +0100 |
27580 |
++++ linux-2.6.23.15-grsec/include/asm-i386/module.h 2008-02-11 10:37:44.000000000 +0000 |
27581 |
+@@ -70,6 +70,12 @@ struct mod_arch_specific |
27582 |
+ #define MODULE_STACKSIZE "" |
27583 |
+ #endif |
27584 |
+ |
27585 |
+-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE |
27586 |
++#ifdef CONFIG_GRKERNSEC |
27587 |
++#define MODULE_GRSEC "GRSECURTY " |
27588 |
++#else |
27589 |
++#define MODULE_GRSEC "" |
27590 |
++#endif |
27591 |
++ |
27592 |
++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC |
27593 |
+ |
27594 |
+ #endif /* _ASM_I386_MODULE_H */ |
27595 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/page.h linux-2.6.23.15-grsec/include/asm-i386/page.h |
27596 |
+--- linux-2.6.23.15/include/asm-i386/page.h 2007-10-09 21:31:38.000000000 +0100 |
27597 |
++++ linux-2.6.23.15-grsec/include/asm-i386/page.h 2008-02-11 10:37:44.000000000 +0000 |
27598 |
+@@ -10,6 +10,7 @@ |
27599 |
+ #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT) |
27600 |
+ |
27601 |
+ #ifdef __KERNEL__ |
27602 |
++#include <asm/boot.h> |
27603 |
+ #ifndef __ASSEMBLY__ |
27604 |
+ |
27605 |
+ #ifdef CONFIG_X86_USE_3DNOW |
27606 |
+@@ -90,7 +91,6 @@ static inline pte_t native_make_pte(unsi |
27607 |
+ typedef struct { unsigned long pte_low; } pte_t; |
27608 |
+ typedef struct { unsigned long pgd; } pgd_t; |
27609 |
+ typedef struct { unsigned long pgprot; } pgprot_t; |
27610 |
+-#define boot_pte_t pte_t /* or would you rather have a typedef */ |
27611 |
+ |
27612 |
+ static inline unsigned long native_pgd_val(pgd_t pgd) |
27613 |
+ { |
27614 |
+@@ -175,6 +175,18 @@ extern int page_is_ram(unsigned long pag |
27615 |
+ #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET) |
27616 |
+ #endif |
27617 |
+ |
27618 |
++#ifdef CONFIG_PAX_KERNEXEC |
27619 |
++#ifdef __ASSEMBLY__ |
27620 |
++#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 6*1024*1024 - 1) & ~(4*1024*1024 - 1))) |
27621 |
++#else |
27622 |
++extern unsigned char KERNEL_TEXT_OFFSET[]; |
27623 |
++#define __KERNEL_TEXT_OFFSET ((unsigned long)KERNEL_TEXT_OFFSET) |
27624 |
++extern unsigned char MODULES_VADDR[]; |
27625 |
++extern unsigned char MODULES_END[]; |
27626 |
++#endif |
27627 |
++#else |
27628 |
++#define __KERNEL_TEXT_OFFSET (0) |
27629 |
++#endif |
27630 |
+ |
27631 |
+ #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET) |
27632 |
+ #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE) |
27633 |
+@@ -197,6 +209,10 @@ extern int page_is_ram(unsigned long pag |
27634 |
+ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
27635 |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
27636 |
+ |
27637 |
++#ifdef CONFIG_PAX_PAGEEXEC |
27638 |
++#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1 |
27639 |
++#endif |
27640 |
++ |
27641 |
+ #include <asm-generic/memory_model.h> |
27642 |
+ #include <asm-generic/page.h> |
27643 |
+ |
27644 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/paravirt.h linux-2.6.23.15-grsec/include/asm-i386/paravirt.h |
27645 |
+--- linux-2.6.23.15/include/asm-i386/paravirt.h 2007-10-09 21:31:38.000000000 +0100 |
27646 |
++++ linux-2.6.23.15-grsec/include/asm-i386/paravirt.h 2008-02-11 10:37:44.000000000 +0000 |
27647 |
+@@ -1057,23 +1057,23 @@ static inline unsigned long __raw_local_ |
27648 |
+ |
27649 |
+ #define INTERRUPT_RETURN \ |
27650 |
+ PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \ |
27651 |
+- jmp *%cs:paravirt_ops+PARAVIRT_iret) |
27652 |
++ jmp *%ss:paravirt_ops+PARAVIRT_iret) |
27653 |
+ |
27654 |
+ #define DISABLE_INTERRUPTS(clobbers) \ |
27655 |
+ PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \ |
27656 |
+ pushl %eax; pushl %ecx; pushl %edx; \ |
27657 |
+- call *%cs:paravirt_ops+PARAVIRT_irq_disable; \ |
27658 |
++ call *%ss:paravirt_ops+PARAVIRT_irq_disable; \ |
27659 |
+ popl %edx; popl %ecx; popl %eax) \ |
27660 |
+ |
27661 |
+ #define ENABLE_INTERRUPTS(clobbers) \ |
27662 |
+ PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \ |
27663 |
+ pushl %eax; pushl %ecx; pushl %edx; \ |
27664 |
+- call *%cs:paravirt_ops+PARAVIRT_irq_enable; \ |
27665 |
++ call *%ss:paravirt_ops+PARAVIRT_irq_enable; \ |
27666 |
+ popl %edx; popl %ecx; popl %eax) |
27667 |
+ |
27668 |
+ #define ENABLE_INTERRUPTS_SYSEXIT \ |
27669 |
+ PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \ |
27670 |
+- jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit) |
27671 |
++ jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit) |
27672 |
+ |
27673 |
+ #define GET_CR0_INTO_EAX \ |
27674 |
+ push %ecx; push %edx; \ |
27675 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/percpu.h linux-2.6.23.15-grsec/include/asm-i386/percpu.h |
27676 |
+--- linux-2.6.23.15/include/asm-i386/percpu.h 2007-10-09 21:31:38.000000000 +0100 |
27677 |
++++ linux-2.6.23.15-grsec/include/asm-i386/percpu.h 2008-02-11 10:37:44.000000000 +0000 |
27678 |
+@@ -22,7 +22,7 @@ |
27679 |
+ #define PER_CPU_VAR(var) %fs:per_cpu__##var |
27680 |
+ #else /* ! SMP */ |
27681 |
+ #define PER_CPU(var, reg) \ |
27682 |
+- movl $per_cpu__##var, reg |
27683 |
++ movl per_cpu__##var, reg |
27684 |
+ #define PER_CPU_VAR(var) per_cpu__##var |
27685 |
+ #endif /* SMP */ |
27686 |
+ |
27687 |
+@@ -42,12 +42,12 @@ |
27688 |
+ */ |
27689 |
+ #ifdef CONFIG_SMP |
27690 |
+ /* Same as generic implementation except for optimized local access. */ |
27691 |
+-#define __GENERIC_PER_CPU |
27692 |
+ |
27693 |
+ /* This is used for other cpus to find our section. */ |
27694 |
+ extern unsigned long __per_cpu_offset[]; |
27695 |
++extern void setup_per_cpu_areas(void); |
27696 |
+ |
27697 |
+-#define per_cpu_offset(x) (__per_cpu_offset[x]) |
27698 |
++#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start) |
27699 |
+ |
27700 |
+ /* Separate out the type, so (int[3], foo) works. */ |
27701 |
+ #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name |
27702 |
+@@ -64,11 +64,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_ |
27703 |
+ |
27704 |
+ /* var is in discarded region: offset to particular copy we want */ |
27705 |
+ #define per_cpu(var, cpu) (*({ \ |
27706 |
+- extern int simple_indentifier_##var(void); \ |
27707 |
++ extern int simple_identifier_##var(void); \ |
27708 |
+ RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); })) |
27709 |
+ |
27710 |
+ #define __raw_get_cpu_var(var) (*({ \ |
27711 |
+- extern int simple_indentifier_##var(void); \ |
27712 |
++ extern int simple_identifier_##var(void); \ |
27713 |
+ RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \ |
27714 |
+ })) |
27715 |
+ |
27716 |
+@@ -79,7 +79,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_ |
27717 |
+ do { \ |
27718 |
+ unsigned int __i; \ |
27719 |
+ for_each_possible_cpu(__i) \ |
27720 |
+- memcpy((pcpudst)+__per_cpu_offset[__i], \ |
27721 |
++ memcpy((pcpudst)+per_cpu_offset(__i), \ |
27722 |
+ (src), (size)); \ |
27723 |
+ } while (0) |
27724 |
+ |
27725 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/pgalloc.h linux-2.6.23.15-grsec/include/asm-i386/pgalloc.h |
27726 |
+--- linux-2.6.23.15/include/asm-i386/pgalloc.h 2007-10-09 21:31:38.000000000 +0100 |
27727 |
++++ linux-2.6.23.15-grsec/include/asm-i386/pgalloc.h 2008-02-11 10:37:44.000000000 +0000 |
27728 |
+@@ -15,11 +15,19 @@ |
27729 |
+ #define paravirt_release_pd(pfn) do { } while (0) |
27730 |
+ #endif |
27731 |
+ |
27732 |
++#ifdef CONFIG_COMPAT_VDSO |
27733 |
+ #define pmd_populate_kernel(mm, pmd, pte) \ |
27734 |
+ do { \ |
27735 |
+ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \ |
27736 |
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \ |
27737 |
+ } while (0) |
27738 |
++#else |
27739 |
++#define pmd_populate_kernel(mm, pmd, pte) \ |
27740 |
++do { \ |
27741 |
++ paravirt_alloc_pt(mm, __pa(pte) >> PAGE_SHIFT); \ |
27742 |
++ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \ |
27743 |
++} while (0) |
27744 |
++#endif |
27745 |
+ |
27746 |
+ #define pmd_populate(mm, pmd, pte) \ |
27747 |
+ do { \ |
27748 |
+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 |
27749 |
+--- linux-2.6.23.15/include/asm-i386/pgtable-2level.h 2007-10-09 21:31:38.000000000 +0100 |
27750 |
++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable-2level.h 2008-02-11 10:37:44.000000000 +0000 |
27751 |
+@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str |
27752 |
+ } |
27753 |
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) |
27754 |
+ { |
27755 |
++ |
27756 |
++#ifdef CONFIG_PAX_KERNEXEC |
27757 |
++ unsigned long cr0; |
27758 |
++ |
27759 |
++ pax_open_kernel(cr0); |
27760 |
++#endif |
27761 |
++ |
27762 |
+ *pmdp = pmd; |
27763 |
++ |
27764 |
++#ifdef CONFIG_PAX_KERNEXEC |
27765 |
++ pax_close_kernel(cr0); |
27766 |
++#endif |
27767 |
++ |
27768 |
+ } |
27769 |
+ #ifndef CONFIG_PARAVIRT |
27770 |
+ #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval) |
27771 |
+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 |
27772 |
+--- linux-2.6.23.15/include/asm-i386/pgtable-3level.h 2007-10-09 21:31:38.000000000 +0100 |
27773 |
++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable-3level.h 2008-02-11 10:37:44.000000000 +0000 |
27774 |
+@@ -67,11 +67,35 @@ static inline void native_set_pte_atomic |
27775 |
+ } |
27776 |
+ static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd) |
27777 |
+ { |
27778 |
++ |
27779 |
++#ifdef CONFIG_PAX_KERNEXEC |
27780 |
++ unsigned long cr0; |
27781 |
++ |
27782 |
++ pax_open_kernel(cr0); |
27783 |
++#endif |
27784 |
++ |
27785 |
+ set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd)); |
27786 |
++ |
27787 |
++#ifdef CONFIG_PAX_KERNEXEC |
27788 |
++ pax_close_kernel(cr0); |
27789 |
++#endif |
27790 |
++ |
27791 |
+ } |
27792 |
+ static inline void native_set_pud(pud_t *pudp, pud_t pud) |
27793 |
+ { |
27794 |
++ |
27795 |
++#ifdef CONFIG_PAX_KERNEXEC |
27796 |
++ unsigned long cr0; |
27797 |
++ |
27798 |
++ pax_open_kernel(cr0); |
27799 |
++#endif |
27800 |
++ |
27801 |
+ *pudp = pud; |
27802 |
++ |
27803 |
++#ifdef CONFIG_PAX_KERNEXEC |
27804 |
++ pax_close_kernel(cr0); |
27805 |
++#endif |
27806 |
++ |
27807 |
+ } |
27808 |
+ |
27809 |
+ /* |
27810 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/pgtable.h linux-2.6.23.15-grsec/include/asm-i386/pgtable.h |
27811 |
+--- linux-2.6.23.15/include/asm-i386/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
27812 |
++++ linux-2.6.23.15-grsec/include/asm-i386/pgtable.h 2008-02-11 10:37:44.000000000 +0000 |
27813 |
+@@ -34,7 +34,6 @@ struct vm_area_struct; |
27814 |
+ */ |
27815 |
+ #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) |
27816 |
+ extern unsigned long empty_zero_page[1024]; |
27817 |
+-extern pgd_t swapper_pg_dir[1024]; |
27818 |
+ extern struct kmem_cache *pmd_cache; |
27819 |
+ extern spinlock_t pgd_lock; |
27820 |
+ extern struct page *pgd_list; |
27821 |
+@@ -58,6 +57,11 @@ void paging_init(void); |
27822 |
+ # include <asm/pgtable-2level-defs.h> |
27823 |
+ #endif |
27824 |
+ |
27825 |
++extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
27826 |
++#ifdef CONFIG_X86_PAE |
27827 |
++extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD]; |
27828 |
++#endif |
27829 |
++ |
27830 |
+ #define PGDIR_SIZE (1UL << PGDIR_SHIFT) |
27831 |
+ #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
27832 |
+ |
27833 |
+@@ -67,9 +71,11 @@ void paging_init(void); |
27834 |
+ #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) |
27835 |
+ #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) |
27836 |
+ |
27837 |
++#ifndef CONFIG_X86_PAE |
27838 |
+ #define TWOLEVEL_PGDIR_SHIFT 22 |
27839 |
+ #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT) |
27840 |
+ #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS) |
27841 |
++#endif |
27842 |
+ |
27843 |
+ /* Just any arbitrary offset to the start of the vmalloc VM area: the |
27844 |
+ * current 8MB value just means that there will be a 8MB "hole" after the |
27845 |
+@@ -136,7 +142,7 @@ void paging_init(void); |
27846 |
+ #define PAGE_NONE \ |
27847 |
+ __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) |
27848 |
+ #define PAGE_SHARED \ |
27849 |
+- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) |
27850 |
++ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) |
27851 |
+ |
27852 |
+ #define PAGE_SHARED_EXEC \ |
27853 |
+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) |
27854 |
+@@ -202,7 +208,7 @@ extern unsigned long long __PAGE_KERNEL, |
27855 |
+ #undef TEST_ACCESS_OK |
27856 |
+ |
27857 |
+ /* The boot page tables (all created as a single array) */ |
27858 |
+-extern unsigned long pg0[]; |
27859 |
++extern pte_t pg0[]; |
27860 |
+ |
27861 |
+ #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) |
27862 |
+ |
27863 |
+@@ -218,30 +224,55 @@ extern unsigned long pg0[]; |
27864 |
+ * The following only work if pte_present() is true. |
27865 |
+ * Undefined behaviour if not.. |
27866 |
+ */ |
27867 |
++static inline int pte_user(pte_t pte) { return (pte).pte_low & _PAGE_USER; } |
27868 |
+ static inline int pte_dirty(pte_t pte) { return (pte).pte_low & _PAGE_DIRTY; } |
27869 |
+ static inline int pte_young(pte_t pte) { return (pte).pte_low & _PAGE_ACCESSED; } |
27870 |
+ static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; } |
27871 |
+ static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; } |
27872 |
+ |
27873 |
++#ifdef CONFIG_X86_PAE |
27874 |
++# include <asm/pgtable-3level.h> |
27875 |
++#else |
27876 |
++# include <asm/pgtable-2level.h> |
27877 |
++#endif |
27878 |
++ |
27879 |
+ /* |
27880 |
+ * The following only works if pte_present() is not true. |
27881 |
+ */ |
27882 |
+ static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; } |
27883 |
+ |
27884 |
++static inline pte_t pte_exprotect(pte_t pte) |
27885 |
++{ |
27886 |
++#ifdef CONFIG_X86_PAE |
27887 |
++ if (__supported_pte_mask & _PAGE_NX) |
27888 |
++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX)); |
27889 |
++ else |
27890 |
++#endif |
27891 |
++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); |
27892 |
++ return pte; |
27893 |
++} |
27894 |
++ |
27895 |
+ static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; } |
27896 |
+ static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; } |
27897 |
+ static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; } |
27898 |
++static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; } |
27899 |
++ |
27900 |
++static inline pte_t pte_mkexec(pte_t pte) |
27901 |
++{ |
27902 |
++#ifdef CONFIG_X86_PAE |
27903 |
++ if (__supported_pte_mask & _PAGE_NX) |
27904 |
++ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); |
27905 |
++ else |
27906 |
++#endif |
27907 |
++ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); |
27908 |
++ return pte; |
27909 |
++} |
27910 |
++ |
27911 |
+ static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; } |
27912 |
+ static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; } |
27913 |
+ static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; } |
27914 |
+ static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; } |
27915 |
+ |
27916 |
+-#ifdef CONFIG_X86_PAE |
27917 |
+-# include <asm/pgtable-3level.h> |
27918 |
+-#else |
27919 |
+-# include <asm/pgtable-2level.h> |
27920 |
+-#endif |
27921 |
+- |
27922 |
+ #ifndef CONFIG_PARAVIRT |
27923 |
+ /* |
27924 |
+ * Rules for using pte_update - it must be called after any PTE update which |
27925 |
+@@ -353,7 +384,19 @@ static inline void ptep_set_wrprotect(st |
27926 |
+ */ |
27927 |
+ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count) |
27928 |
+ { |
27929 |
+- memcpy(dst, src, count * sizeof(pgd_t)); |
27930 |
++ |
27931 |
++#ifdef CONFIG_PAX_KERNEXEC |
27932 |
++ unsigned long cr0; |
27933 |
++ |
27934 |
++ pax_open_kernel(cr0); |
27935 |
++#endif |
27936 |
++ |
27937 |
++ memcpy(dst, src, count * sizeof(pgd_t)); |
27938 |
++ |
27939 |
++#ifdef CONFIG_PAX_KERNEXEC |
27940 |
++ pax_close_kernel(cr0); |
27941 |
++#endif |
27942 |
++ |
27943 |
+ } |
27944 |
+ |
27945 |
+ /* |
27946 |
+@@ -500,6 +543,9 @@ static inline void paravirt_pagetable_se |
27947 |
+ |
27948 |
+ #endif /* !__ASSEMBLY__ */ |
27949 |
+ |
27950 |
++#define HAVE_ARCH_UNMAPPED_AREA |
27951 |
++#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN |
27952 |
++ |
27953 |
+ #ifdef CONFIG_FLATMEM |
27954 |
+ #define kern_addr_valid(addr) (1) |
27955 |
+ #endif /* CONFIG_FLATMEM */ |
27956 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/processor.h linux-2.6.23.15-grsec/include/asm-i386/processor.h |
27957 |
+--- linux-2.6.23.15/include/asm-i386/processor.h 2007-10-09 21:31:38.000000000 +0100 |
27958 |
++++ linux-2.6.23.15-grsec/include/asm-i386/processor.h 2008-02-11 10:37:44.000000000 +0000 |
27959 |
+@@ -99,8 +99,6 @@ struct cpuinfo_x86 { |
27960 |
+ |
27961 |
+ extern struct cpuinfo_x86 boot_cpu_data; |
27962 |
+ extern struct cpuinfo_x86 new_cpu_data; |
27963 |
+-extern struct tss_struct doublefault_tss; |
27964 |
+-DECLARE_PER_CPU(struct tss_struct, init_tss); |
27965 |
+ |
27966 |
+ #ifdef CONFIG_SMP |
27967 |
+ extern struct cpuinfo_x86 cpu_data[]; |
27968 |
+@@ -209,11 +207,19 @@ extern int bootloader_type; |
27969 |
+ */ |
27970 |
+ #define TASK_SIZE (PAGE_OFFSET) |
27971 |
+ |
27972 |
++#ifdef CONFIG_PAX_SEGMEXEC |
27973 |
++#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2) |
27974 |
++#endif |
27975 |
++ |
27976 |
+ /* This decides where the kernel will search for a free chunk of vm |
27977 |
+ * space during mmap's. |
27978 |
+ */ |
27979 |
+ #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) |
27980 |
+ |
27981 |
++#ifdef CONFIG_PAX_SEGMEXEC |
27982 |
++#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3)) |
27983 |
++#endif |
27984 |
++ |
27985 |
+ #define HAVE_ARCH_PICK_MMAP_LAYOUT |
27986 |
+ |
27987 |
+ extern void hard_disable_TSC(void); |
27988 |
+@@ -338,6 +344,9 @@ struct tss_struct { |
27989 |
+ |
27990 |
+ #define ARCH_MIN_TASKALIGN 16 |
27991 |
+ |
27992 |
++extern struct tss_struct doublefault_tss; |
27993 |
++extern struct tss_struct init_tss[NR_CPUS]; |
27994 |
++ |
27995 |
+ struct thread_struct { |
27996 |
+ /* cached TLS descriptors. */ |
27997 |
+ struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; |
27998 |
+@@ -366,7 +375,7 @@ struct thread_struct { |
27999 |
+ }; |
28000 |
+ |
28001 |
+ #define INIT_THREAD { \ |
28002 |
+- .esp0 = sizeof(init_stack) + (long)&init_stack, \ |
28003 |
++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \ |
28004 |
+ .vm86_info = NULL, \ |
28005 |
+ .sysenter_cs = __KERNEL_CS, \ |
28006 |
+ .io_bitmap_ptr = NULL, \ |
28007 |
+@@ -381,7 +390,7 @@ struct thread_struct { |
28008 |
+ */ |
28009 |
+ #define INIT_TSS { \ |
28010 |
+ .x86_tss = { \ |
28011 |
+- .esp0 = sizeof(init_stack) + (long)&init_stack, \ |
28012 |
++ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \ |
28013 |
+ .ss0 = __KERNEL_DS, \ |
28014 |
+ .ss1 = __KERNEL_CS, \ |
28015 |
+ .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \ |
28016 |
+@@ -422,11 +431,7 @@ void show_trace(struct task_struct *task |
28017 |
+ unsigned long get_wchan(struct task_struct *p); |
28018 |
+ |
28019 |
+ #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long)) |
28020 |
+-#define KSTK_TOP(info) \ |
28021 |
+-({ \ |
28022 |
+- unsigned long *__ptr = (unsigned long *)(info); \ |
28023 |
+- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \ |
28024 |
+-}) |
28025 |
++#define KSTK_TOP(info) ((info)->task.thread.esp0) |
28026 |
+ |
28027 |
+ /* |
28028 |
+ * The below -8 is to reserve 8 bytes on top of the ring0 stack. |
28029 |
+@@ -441,7 +446,7 @@ unsigned long get_wchan(struct task_stru |
28030 |
+ #define task_pt_regs(task) \ |
28031 |
+ ({ \ |
28032 |
+ struct pt_regs *__regs__; \ |
28033 |
+- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \ |
28034 |
++ __regs__ = (struct pt_regs *)((task)->thread.esp0); \ |
28035 |
+ __regs__ - 1; \ |
28036 |
+ }) |
28037 |
+ |
28038 |
+@@ -603,8 +608,8 @@ static inline void cpuid(unsigned int op |
28039 |
+ } |
28040 |
+ |
28041 |
+ /* Some CPUID calls want 'count' to be placed in ecx */ |
28042 |
+-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, |
28043 |
+- int *edx) |
28044 |
++static inline void cpuid_count(unsigned int op, unsigned int count, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, |
28045 |
++ unsigned int *edx) |
28046 |
+ { |
28047 |
+ *eax = op; |
28048 |
+ *ecx = count; |
28049 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/ptrace.h linux-2.6.23.15-grsec/include/asm-i386/ptrace.h |
28050 |
+--- linux-2.6.23.15/include/asm-i386/ptrace.h 2007-10-09 21:31:38.000000000 +0100 |
28051 |
++++ linux-2.6.23.15-grsec/include/asm-i386/ptrace.h 2008-02-11 10:37:44.000000000 +0000 |
28052 |
+@@ -35,17 +35,18 @@ struct task_struct; |
28053 |
+ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code); |
28054 |
+ |
28055 |
+ /* |
28056 |
+- * user_mode_vm(regs) determines whether a register set came from user mode. |
28057 |
++ * user_mode(regs) determines whether a register set came from user mode. |
28058 |
+ * This is true if V8086 mode was enabled OR if the register set was from |
28059 |
+ * protected mode with RPL-3 CS value. This tricky test checks that with |
28060 |
+ * one comparison. Many places in the kernel can bypass this full check |
28061 |
+- * if they have already ruled out V8086 mode, so user_mode(regs) can be used. |
28062 |
++ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can |
28063 |
++ * be used. |
28064 |
+ */ |
28065 |
+-static inline int user_mode(struct pt_regs *regs) |
28066 |
++static inline int user_mode_novm(struct pt_regs *regs) |
28067 |
+ { |
28068 |
+ return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL; |
28069 |
+ } |
28070 |
+-static inline int user_mode_vm(struct pt_regs *regs) |
28071 |
++static inline int user_mode(struct pt_regs *regs) |
28072 |
+ { |
28073 |
+ return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL; |
28074 |
+ } |
28075 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/reboot.h linux-2.6.23.15-grsec/include/asm-i386/reboot.h |
28076 |
+--- linux-2.6.23.15/include/asm-i386/reboot.h 2007-10-09 21:31:38.000000000 +0100 |
28077 |
++++ linux-2.6.23.15-grsec/include/asm-i386/reboot.h 2008-02-11 10:37:44.000000000 +0000 |
28078 |
+@@ -15,6 +15,6 @@ struct machine_ops |
28079 |
+ |
28080 |
+ extern struct machine_ops machine_ops; |
28081 |
+ |
28082 |
+-void machine_real_restart(unsigned char *code, int length); |
28083 |
++void machine_real_restart(const unsigned char *code, unsigned int length); |
28084 |
+ |
28085 |
+ #endif /* _ASM_REBOOT_H */ |
28086 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/segment.h linux-2.6.23.15-grsec/include/asm-i386/segment.h |
28087 |
+--- linux-2.6.23.15/include/asm-i386/segment.h 2007-10-09 21:31:38.000000000 +0100 |
28088 |
++++ linux-2.6.23.15-grsec/include/asm-i386/segment.h 2008-02-11 10:37:44.000000000 +0000 |
28089 |
+@@ -81,6 +81,12 @@ |
28090 |
+ #define __KERNEL_PERCPU 0 |
28091 |
+ #endif |
28092 |
+ |
28093 |
++#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16) |
28094 |
++#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8) |
28095 |
++ |
28096 |
++#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17) |
28097 |
++#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8) |
28098 |
++ |
28099 |
+ #define GDT_ENTRY_DOUBLEFAULT_TSS 31 |
28100 |
+ |
28101 |
+ /* |
28102 |
+@@ -140,9 +146,9 @@ |
28103 |
+ #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8) |
28104 |
+ |
28105 |
+ /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */ |
28106 |
+-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8) |
28107 |
++#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS) |
28108 |
+ |
28109 |
+ /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */ |
28110 |
+-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8) |
28111 |
++#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16) |
28112 |
+ |
28113 |
+ #endif |
28114 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/system.h linux-2.6.23.15-grsec/include/asm-i386/system.h |
28115 |
+--- linux-2.6.23.15/include/asm-i386/system.h 2008-02-11 10:36:03.000000000 +0000 |
28116 |
++++ linux-2.6.23.15-grsec/include/asm-i386/system.h 2008-02-11 10:37:44.000000000 +0000 |
28117 |
+@@ -183,6 +183,21 @@ static inline void native_wbinvd(void) |
28118 |
+ /* Set the 'TS' bit */ |
28119 |
+ #define stts() write_cr0(8 | read_cr0()) |
28120 |
+ |
28121 |
++#define pax_open_kernel(cr0) \ |
28122 |
++do { \ |
28123 |
++ typecheck(unsigned long, cr0); \ |
28124 |
++ preempt_disable(); \ |
28125 |
++ cr0 = read_cr0(); \ |
28126 |
++ write_cr0(cr0 & ~X86_CR0_WP); \ |
28127 |
++} while (0) |
28128 |
++ |
28129 |
++#define pax_close_kernel(cr0) \ |
28130 |
++do { \ |
28131 |
++ typecheck(unsigned long, cr0); \ |
28132 |
++ write_cr0(cr0); \ |
28133 |
++ preempt_enable_no_resched(); \ |
28134 |
++} while (0) |
28135 |
++ |
28136 |
+ #endif /* __KERNEL__ */ |
28137 |
+ |
28138 |
+ static inline unsigned long get_limit(unsigned long segment) |
28139 |
+@@ -190,7 +205,7 @@ static inline unsigned long get_limit(un |
28140 |
+ unsigned long __limit; |
28141 |
+ __asm__("lsll %1,%0" |
28142 |
+ :"=r" (__limit):"r" (segment)); |
28143 |
+- return __limit+1; |
28144 |
++ return __limit; |
28145 |
+ } |
28146 |
+ |
28147 |
+ #define nop() __asm__ __volatile__ ("nop") |
28148 |
+@@ -305,7 +320,7 @@ void enable_hlt(void); |
28149 |
+ extern int es7000_plat; |
28150 |
+ void cpu_idle_wait(void); |
28151 |
+ |
28152 |
+-extern unsigned long arch_align_stack(unsigned long sp); |
28153 |
++#define arch_align_stack(x) (x) |
28154 |
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long end); |
28155 |
+ |
28156 |
+ void default_idle(void); |
28157 |
+diff -Nurp linux-2.6.23.15/include/asm-i386/uaccess.h linux-2.6.23.15-grsec/include/asm-i386/uaccess.h |
28158 |
+--- linux-2.6.23.15/include/asm-i386/uaccess.h 2007-10-09 21:31:38.000000000 +0100 |
28159 |
++++ linux-2.6.23.15-grsec/include/asm-i386/uaccess.h 2008-02-11 10:37:44.000000000 +0000 |
28160 |
+@@ -9,6 +9,7 @@ |
28161 |
+ #include <linux/prefetch.h> |
28162 |
+ #include <linux/string.h> |
28163 |
+ #include <asm/page.h> |
28164 |
++#include <asm/segment.h> |
28165 |
+ |
28166 |
+ #define VERIFY_READ 0 |
28167 |
+ #define VERIFY_WRITE 1 |
28168 |
+@@ -29,7 +30,8 @@ |
28169 |
+ |
28170 |
+ #define get_ds() (KERNEL_DS) |
28171 |
+ #define get_fs() (current_thread_info()->addr_limit) |
28172 |
+-#define set_fs(x) (current_thread_info()->addr_limit = (x)) |
28173 |
++void __set_fs(mm_segment_t x, int cpu); |
28174 |
++void set_fs(mm_segment_t x); |
28175 |
+ |
28176 |
+ #define segment_eq(a,b) ((a).seg == (b).seg) |
28177 |
+ |
28178 |
+@@ -101,6 +103,7 @@ struct exception_table_entry |
28179 |
+ }; |
28180 |
+ |
28181 |
+ extern int fixup_exception(struct pt_regs *regs); |
28182 |
++#define ARCH_HAS_SORT_EXTABLE |
28183 |
+ |
28184 |
+ /* |
28185 |
+ * These are the main single-value transfer routines. They automatically |
28186 |
+@@ -280,9 +283,12 @@ extern void __put_user_8(void); |
28187 |
+ |
28188 |
+ #define __put_user_u64(x, addr, err) \ |
28189 |
+ __asm__ __volatile__( \ |
28190 |
+- "1: movl %%eax,0(%2)\n" \ |
28191 |
+- "2: movl %%edx,4(%2)\n" \ |
28192 |
++ " movw %w5,%%ds\n" \ |
28193 |
++ "1: movl %%eax,%%ds:0(%2)\n" \ |
28194 |
++ "2: movl %%edx,%%ds:4(%2)\n" \ |
28195 |
+ "3:\n" \ |
28196 |
++ " pushl %%ss\n" \ |
28197 |
++ " popl %%ds\n" \ |
28198 |
+ ".section .fixup,\"ax\"\n" \ |
28199 |
+ "4: movl %3,%0\n" \ |
28200 |
+ " jmp 3b\n" \ |
28201 |
+@@ -293,7 +299,8 @@ extern void __put_user_8(void); |
28202 |
+ " .long 2b,4b\n" \ |
28203 |
+ ".previous" \ |
28204 |
+ : "=r"(err) \ |
28205 |
+- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err)) |
28206 |
++ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \ |
28207 |
++ "r"(__USER_DS)) |
28208 |
+ |
28209 |
+ #ifdef CONFIG_X86_WP_WORKS_OK |
28210 |
+ |
28211 |
+@@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu |
28212 |
+ */ |
28213 |
+ #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ |
28214 |
+ __asm__ __volatile__( \ |
28215 |
+- "1: mov"itype" %"rtype"1,%2\n" \ |
28216 |
++ " movw %w5,%%ds\n" \ |
28217 |
++ "1: mov"itype" %"rtype"1,%%ds:%2\n" \ |
28218 |
+ "2:\n" \ |
28219 |
++ " pushl %%ss\n" \ |
28220 |
++ " popl %%ds\n" \ |
28221 |
+ ".section .fixup,\"ax\"\n" \ |
28222 |
+ "3: movl %3,%0\n" \ |
28223 |
+ " jmp 2b\n" \ |
28224 |
+@@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu |
28225 |
+ " .long 1b,3b\n" \ |
28226 |
+ ".previous" \ |
28227 |
+ : "=r"(err) \ |
28228 |
+- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err)) |
28229 |
++ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \ |
28230 |
++ "r"(__USER_DS)) |
28231 |
+ |
28232 |
+ |
28233 |
+ #define __get_user_nocheck(x,ptr,size) \ |
28234 |
+@@ -371,8 +382,11 @@ do { \ |
28235 |
+ |
28236 |
+ #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \ |
28237 |
+ __asm__ __volatile__( \ |
28238 |
+- "1: mov"itype" %2,%"rtype"1\n" \ |
28239 |
++ " movw %w5,%%ds\n" \ |
28240 |
++ "1: mov"itype" %%ds:%2,%"rtype"1\n" \ |
28241 |
+ "2:\n" \ |
28242 |
++ " pushl %%ss\n" \ |
28243 |
++ " popl %%ds\n" \ |
28244 |
+ ".section .fixup,\"ax\"\n" \ |
28245 |
+ "3: movl %3,%0\n" \ |
28246 |
+ " xor"itype" %"rtype"1,%"rtype"1\n" \ |
28247 |
+@@ -383,7 +397,7 @@ do { \ |
28248 |
+ " .long 1b,3b\n" \ |
28249 |
+ ".previous" \ |
28250 |
+ : "=r"(err), ltype (x) \ |
28251 |
+- : "m"(__m(addr)), "i"(errret), "0"(err)) |
28252 |
++ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS)) |
28253 |
+ |
28254 |
+ |
28255 |
+ unsigned long __must_check __copy_to_user_ll(void __user *to, |
28256 |
+diff -Nurp linux-2.6.23.15/include/asm-ia64/elf.h linux-2.6.23.15-grsec/include/asm-ia64/elf.h |
28257 |
+--- linux-2.6.23.15/include/asm-ia64/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28258 |
++++ linux-2.6.23.15-grsec/include/asm-ia64/elf.h 2008-02-11 10:37:44.000000000 +0000 |
28259 |
+@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR |
28260 |
+ typedef struct ia64_fpreg elf_fpreg_t; |
28261 |
+ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; |
28262 |
+ |
28263 |
++#ifdef CONFIG_PAX_ASLR |
28264 |
++#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) |
28265 |
+ |
28266 |
++#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
28267 |
++#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13) |
28268 |
++#endif |
28269 |
+ |
28270 |
+ struct pt_regs; /* forward declaration... */ |
28271 |
+ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst); |
28272 |
+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 |
28273 |
+--- linux-2.6.23.15/include/asm-ia64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28274 |
++++ linux-2.6.23.15-grsec/include/asm-ia64/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28275 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
28276 |
+ D(10) KM_IRQ1, |
28277 |
+ D(11) KM_SOFTIRQ0, |
28278 |
+ D(12) KM_SOFTIRQ1, |
28279 |
+-D(13) KM_TYPE_NR |
28280 |
++D(13) KM_CLEARPAGE, |
28281 |
++D(14) KM_TYPE_NR |
28282 |
+ }; |
28283 |
+ |
28284 |
+ #undef D |
28285 |
+diff -Nurp linux-2.6.23.15/include/asm-ia64/pgtable.h linux-2.6.23.15-grsec/include/asm-ia64/pgtable.h |
28286 |
+--- linux-2.6.23.15/include/asm-ia64/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
28287 |
++++ linux-2.6.23.15-grsec/include/asm-ia64/pgtable.h 2008-02-11 10:37:44.000000000 +0000 |
28288 |
+@@ -143,6 +143,17 @@ |
28289 |
+ #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
28290 |
+ #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
28291 |
+ #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX) |
28292 |
++ |
28293 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28294 |
++# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW) |
28295 |
++# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
28296 |
++# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R) |
28297 |
++#else |
28298 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
28299 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
28300 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
28301 |
++#endif |
28302 |
++ |
28303 |
+ #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX) |
28304 |
+ #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX) |
28305 |
+ #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX) |
28306 |
+diff -Nurp linux-2.6.23.15/include/asm-ia64/processor.h linux-2.6.23.15-grsec/include/asm-ia64/processor.h |
28307 |
+--- linux-2.6.23.15/include/asm-ia64/processor.h 2007-10-09 21:31:38.000000000 +0100 |
28308 |
++++ linux-2.6.23.15-grsec/include/asm-ia64/processor.h 2008-02-11 10:37:44.000000000 +0000 |
28309 |
+@@ -275,7 +275,7 @@ struct thread_struct { |
28310 |
+ .on_ustack = 0, \ |
28311 |
+ .ksp = 0, \ |
28312 |
+ .map_base = DEFAULT_MAP_BASE, \ |
28313 |
+- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \ |
28314 |
++ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \ |
28315 |
+ .task_size = DEFAULT_TASK_SIZE, \ |
28316 |
+ .last_fph_cpu = -1, \ |
28317 |
+ INIT_THREAD_IA32 \ |
28318 |
+diff -Nurp linux-2.6.23.15/include/asm-ia64/ustack.h linux-2.6.23.15-grsec/include/asm-ia64/ustack.h |
28319 |
+--- linux-2.6.23.15/include/asm-ia64/ustack.h 2007-10-09 21:31:38.000000000 +0100 |
28320 |
++++ linux-2.6.23.15-grsec/include/asm-ia64/ustack.h 2008-02-11 10:37:44.000000000 +0000 |
28321 |
+@@ -10,8 +10,8 @@ |
28322 |
+ |
28323 |
+ /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */ |
28324 |
+ #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2) |
28325 |
+-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) |
28326 |
+-#define STACK_TOP_MAX STACK_TOP |
28327 |
++#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT) |
28328 |
++#define STACK_TOP_MAX __STACK_TOP |
28329 |
+ #endif |
28330 |
+ |
28331 |
+ /* Make a default stack size of 2GiB */ |
28332 |
+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 |
28333 |
+--- linux-2.6.23.15/include/asm-m32r/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28334 |
++++ linux-2.6.23.15-grsec/include/asm-m32r/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28335 |
+@@ -21,7 +21,8 @@ D(9) KM_IRQ0, |
28336 |
+ D(10) KM_IRQ1, |
28337 |
+ D(11) KM_SOFTIRQ0, |
28338 |
+ D(12) KM_SOFTIRQ1, |
28339 |
+-D(13) KM_TYPE_NR |
28340 |
++D(13) KM_CLEARPAGE, |
28341 |
++D(14) KM_TYPE_NR |
28342 |
+ }; |
28343 |
+ |
28344 |
+ #undef D |
28345 |
+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 |
28346 |
+--- linux-2.6.23.15/include/asm-m68k/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28347 |
++++ linux-2.6.23.15-grsec/include/asm-m68k/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28348 |
+@@ -15,6 +15,7 @@ enum km_type { |
28349 |
+ KM_IRQ1, |
28350 |
+ KM_SOFTIRQ0, |
28351 |
+ KM_SOFTIRQ1, |
28352 |
++ KM_CLEARPAGE, |
28353 |
+ KM_TYPE_NR |
28354 |
+ }; |
28355 |
+ |
28356 |
+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 |
28357 |
+--- linux-2.6.23.15/include/asm-m68knommu/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28358 |
++++ linux-2.6.23.15-grsec/include/asm-m68knommu/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28359 |
+@@ -15,6 +15,7 @@ enum km_type { |
28360 |
+ KM_IRQ1, |
28361 |
+ KM_SOFTIRQ0, |
28362 |
+ KM_SOFTIRQ1, |
28363 |
++ KM_CLEARPAGE, |
28364 |
+ KM_TYPE_NR |
28365 |
+ }; |
28366 |
+ |
28367 |
+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 |
28368 |
+--- linux-2.6.23.15/include/asm-mips/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
28369 |
++++ linux-2.6.23.15-grsec/include/asm-mips/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
28370 |
+@@ -35,10 +35,10 @@ struct exec |
28371 |
+ #ifdef __KERNEL__ |
28372 |
+ |
28373 |
+ #ifdef CONFIG_32BIT |
28374 |
+-#define STACK_TOP TASK_SIZE |
28375 |
++#define __STACK_TOP TASK_SIZE |
28376 |
+ #endif |
28377 |
+ #ifdef CONFIG_64BIT |
28378 |
+-#define STACK_TOP \ |
28379 |
++#define __STACK_TOP \ |
28380 |
+ (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE) |
28381 |
+ #endif |
28382 |
+ #define STACK_TOP_MAX TASK_SIZE |
28383 |
+diff -Nurp linux-2.6.23.15/include/asm-mips/elf.h linux-2.6.23.15-grsec/include/asm-mips/elf.h |
28384 |
+--- linux-2.6.23.15/include/asm-mips/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28385 |
++++ linux-2.6.23.15-grsec/include/asm-mips/elf.h 2008-02-11 10:37:44.000000000 +0000 |
28386 |
+@@ -372,4 +372,11 @@ extern int dump_task_fpu(struct task_str |
28387 |
+ #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) |
28388 |
+ #endif |
28389 |
+ |
28390 |
++#ifdef CONFIG_PAX_ASLR |
28391 |
++#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) |
28392 |
++ |
28393 |
++#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
28394 |
++#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) |
28395 |
++#endif |
28396 |
++ |
28397 |
+ #endif /* _ASM_ELF_H */ |
28398 |
+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 |
28399 |
+--- linux-2.6.23.15/include/asm-mips/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28400 |
++++ linux-2.6.23.15-grsec/include/asm-mips/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28401 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
28402 |
+ D(10) KM_IRQ1, |
28403 |
+ D(11) KM_SOFTIRQ0, |
28404 |
+ D(12) KM_SOFTIRQ1, |
28405 |
+-D(13) KM_TYPE_NR |
28406 |
++D(13) KM_CLEARPAGE, |
28407 |
++D(14) KM_TYPE_NR |
28408 |
+ }; |
28409 |
+ |
28410 |
+ #undef D |
28411 |
+diff -Nurp linux-2.6.23.15/include/asm-mips/page.h linux-2.6.23.15-grsec/include/asm-mips/page.h |
28412 |
+--- linux-2.6.23.15/include/asm-mips/page.h 2007-10-09 21:31:38.000000000 +0100 |
28413 |
++++ linux-2.6.23.15-grsec/include/asm-mips/page.h 2008-02-11 10:37:44.000000000 +0000 |
28414 |
+@@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa |
28415 |
+ #ifdef CONFIG_CPU_MIPS32 |
28416 |
+ typedef struct { unsigned long pte_low, pte_high; } pte_t; |
28417 |
+ #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) |
28418 |
+- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; }) |
28419 |
++ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; }) |
28420 |
+ #else |
28421 |
+ typedef struct { unsigned long long pte; } pte_t; |
28422 |
+ #define pte_val(x) ((x).pte) |
28423 |
+diff -Nurp linux-2.6.23.15/include/asm-mips/system.h linux-2.6.23.15-grsec/include/asm-mips/system.h |
28424 |
+--- linux-2.6.23.15/include/asm-mips/system.h 2007-10-09 21:31:38.000000000 +0100 |
28425 |
++++ linux-2.6.23.15-grsec/include/asm-mips/system.h 2008-02-11 10:37:44.000000000 +0000 |
28426 |
+@@ -213,6 +213,6 @@ extern int stop_a_enabled; |
28427 |
+ */ |
28428 |
+ #define __ARCH_WANT_UNLOCKED_CTXSW |
28429 |
+ |
28430 |
+-extern unsigned long arch_align_stack(unsigned long sp); |
28431 |
++#define arch_align_stack(x) (x) |
28432 |
+ |
28433 |
+ #endif /* _ASM_SYSTEM_H */ |
28434 |
+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 |
28435 |
+--- linux-2.6.23.15/include/asm-parisc/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
28436 |
++++ linux-2.6.23.15-grsec/include/asm-parisc/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
28437 |
+@@ -22,7 +22,7 @@ struct exec |
28438 |
+ /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc. |
28439 |
+ * prumpf */ |
28440 |
+ |
28441 |
+-#define STACK_TOP TASK_SIZE |
28442 |
++#define __STACK_TOP TASK_SIZE |
28443 |
+ #define STACK_TOP_MAX DEFAULT_TASK_SIZE |
28444 |
+ |
28445 |
+ #endif |
28446 |
+diff -Nurp linux-2.6.23.15/include/asm-parisc/elf.h linux-2.6.23.15-grsec/include/asm-parisc/elf.h |
28447 |
+--- linux-2.6.23.15/include/asm-parisc/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28448 |
++++ linux-2.6.23.15-grsec/include/asm-parisc/elf.h 2008-02-11 10:37:44.000000000 +0000 |
28449 |
+@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration.. |
28450 |
+ |
28451 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) |
28452 |
+ |
28453 |
++#ifdef CONFIG_PAX_ASLR |
28454 |
++#define PAX_ELF_ET_DYN_BASE 0x10000UL |
28455 |
++ |
28456 |
++#define PAX_DELTA_MMAP_LEN 16 |
28457 |
++#define PAX_DELTA_STACK_LEN 16 |
28458 |
++#endif |
28459 |
++ |
28460 |
+ /* This yields a mask that user programs can use to figure out what |
28461 |
+ instruction set this CPU supports. This could be done in user space, |
28462 |
+ but it's not easy, and we've already done it here. */ |
28463 |
+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 |
28464 |
+--- linux-2.6.23.15/include/asm-parisc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28465 |
++++ linux-2.6.23.15-grsec/include/asm-parisc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28466 |
+@@ -22,7 +22,8 @@ D(9) KM_IRQ0, |
28467 |
+ D(10) KM_IRQ1, |
28468 |
+ D(11) KM_SOFTIRQ0, |
28469 |
+ D(12) KM_SOFTIRQ1, |
28470 |
+-D(13) KM_TYPE_NR |
28471 |
++D(13) KM_CLEARPAGE, |
28472 |
++D(14) KM_TYPE_NR |
28473 |
+ }; |
28474 |
+ |
28475 |
+ #undef D |
28476 |
+diff -Nurp linux-2.6.23.15/include/asm-parisc/pgtable.h linux-2.6.23.15-grsec/include/asm-parisc/pgtable.h |
28477 |
+--- linux-2.6.23.15/include/asm-parisc/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
28478 |
++++ linux-2.6.23.15-grsec/include/asm-parisc/pgtable.h 2008-02-11 10:37:44.000000000 +0000 |
28479 |
+@@ -218,6 +218,17 @@ extern void *vmalloc_start; |
28480 |
+ #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) |
28481 |
+ #define PAGE_COPY PAGE_EXECREAD |
28482 |
+ #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) |
28483 |
++ |
28484 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28485 |
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED) |
28486 |
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) |
28487 |
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) |
28488 |
++#else |
28489 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
28490 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
28491 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
28492 |
++#endif |
28493 |
++ |
28494 |
+ #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) |
28495 |
+ #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) |
28496 |
+ #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) |
28497 |
+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 |
28498 |
+--- linux-2.6.23.15/include/asm-powerpc/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
28499 |
++++ linux-2.6.23.15-grsec/include/asm-powerpc/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
28500 |
+@@ -23,15 +23,15 @@ struct exec |
28501 |
+ #define STACK_TOP_USER64 TASK_SIZE_USER64 |
28502 |
+ #define STACK_TOP_USER32 TASK_SIZE_USER32 |
28503 |
+ |
28504 |
+-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
28505 |
++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
28506 |
+ STACK_TOP_USER32 : STACK_TOP_USER64) |
28507 |
+ |
28508 |
+ #define STACK_TOP_MAX STACK_TOP_USER64 |
28509 |
+ |
28510 |
+ #else /* __powerpc64__ */ |
28511 |
+ |
28512 |
+-#define STACK_TOP TASK_SIZE |
28513 |
+-#define STACK_TOP_MAX STACK_TOP |
28514 |
++#define __STACK_TOP TASK_SIZE |
28515 |
++#define STACK_TOP_MAX __STACK_TOP |
28516 |
+ |
28517 |
+ #endif /* __powerpc64__ */ |
28518 |
+ #endif /* __KERNEL__ */ |
28519 |
+diff -Nurp linux-2.6.23.15/include/asm-powerpc/elf.h linux-2.6.23.15-grsec/include/asm-powerpc/elf.h |
28520 |
+--- linux-2.6.23.15/include/asm-powerpc/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28521 |
++++ linux-2.6.23.15-grsec/include/asm-powerpc/elf.h 2008-02-11 10:37:44.000000000 +0000 |
28522 |
+@@ -159,6 +159,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N |
28523 |
+ typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32]; |
28524 |
+ #endif |
28525 |
+ |
28526 |
++#ifdef CONFIG_PAX_ASLR |
28527 |
++#define PAX_ELF_ET_DYN_BASE (0x10000000UL) |
28528 |
++ |
28529 |
++#ifdef __powerpc64__ |
28530 |
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28) |
28531 |
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28) |
28532 |
++#else |
28533 |
++#define PAX_DELTA_MMAP_LEN 15 |
28534 |
++#define PAX_DELTA_STACK_LEN 15 |
28535 |
++#endif |
28536 |
++#endif |
28537 |
++ |
28538 |
+ #ifdef __KERNEL__ |
28539 |
+ /* |
28540 |
+ * This is used to ensure we don't load something for the wrong architecture. |
28541 |
+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 |
28542 |
+--- linux-2.6.23.15/include/asm-powerpc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28543 |
++++ linux-2.6.23.15-grsec/include/asm-powerpc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28544 |
+@@ -26,6 +26,7 @@ enum km_type { |
28545 |
+ KM_SOFTIRQ1, |
28546 |
+ KM_PPC_SYNC_PAGE, |
28547 |
+ KM_PPC_SYNC_ICACHE, |
28548 |
++ KM_CLEARPAGE, |
28549 |
+ KM_TYPE_NR |
28550 |
+ }; |
28551 |
+ |
28552 |
+diff -Nurp linux-2.6.23.15/include/asm-powerpc/page.h linux-2.6.23.15-grsec/include/asm-powerpc/page.h |
28553 |
+--- linux-2.6.23.15/include/asm-powerpc/page.h 2007-10-09 21:31:38.000000000 +0100 |
28554 |
++++ linux-2.6.23.15-grsec/include/asm-powerpc/page.h 2008-02-11 10:37:44.000000000 +0000 |
28555 |
+@@ -71,8 +71,9 @@ |
28556 |
+ * and needs to be executable. This means the whole heap ends |
28557 |
+ * up being executable. |
28558 |
+ */ |
28559 |
+-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ |
28560 |
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28561 |
++#define VM_DATA_DEFAULT_FLAGS32 \ |
28562 |
++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
28563 |
++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28564 |
+ |
28565 |
+ #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ |
28566 |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28567 |
+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 |
28568 |
+--- linux-2.6.23.15/include/asm-powerpc/page_64.h 2007-10-09 21:31:38.000000000 +0100 |
28569 |
++++ linux-2.6.23.15-grsec/include/asm-powerpc/page_64.h 2008-02-11 10:37:44.000000000 +0000 |
28570 |
+@@ -158,15 +158,18 @@ extern int is_hugepage_only_range(struct |
28571 |
+ * stack by default, so in the absense of a PT_GNU_STACK program header |
28572 |
+ * we turn execute permission off. |
28573 |
+ */ |
28574 |
+-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \ |
28575 |
+- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28576 |
++#define VM_STACK_DEFAULT_FLAGS32 \ |
28577 |
++ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \ |
28578 |
++ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28579 |
+ |
28580 |
+ #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \ |
28581 |
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
28582 |
+ |
28583 |
++#ifndef CONFIG_PAX_PAGEEXEC |
28584 |
+ #define VM_STACK_DEFAULT_FLAGS \ |
28585 |
+ (test_thread_flag(TIF_32BIT) ? \ |
28586 |
+ VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64) |
28587 |
++#endif |
28588 |
+ |
28589 |
+ #include <asm-generic/page.h> |
28590 |
+ |
28591 |
+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 |
28592 |
+--- linux-2.6.23.15/include/asm-ppc/mmu_context.h 2007-10-09 21:31:38.000000000 +0100 |
28593 |
++++ linux-2.6.23.15-grsec/include/asm-ppc/mmu_context.h 2008-02-11 10:37:44.000000000 +0000 |
28594 |
+@@ -145,7 +145,8 @@ static inline void get_mmu_context(struc |
28595 |
+ static inline int init_new_context(struct task_struct *t, struct mm_struct *mm) |
28596 |
+ { |
28597 |
+ mm->context.id = NO_CONTEXT; |
28598 |
+- mm->context.vdso_base = 0; |
28599 |
++ if (t == current) |
28600 |
++ mm->context.vdso_base = ~0UL; |
28601 |
+ return 0; |
28602 |
+ } |
28603 |
+ |
28604 |
+diff -Nurp linux-2.6.23.15/include/asm-ppc/pgtable.h linux-2.6.23.15-grsec/include/asm-ppc/pgtable.h |
28605 |
+--- linux-2.6.23.15/include/asm-ppc/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
28606 |
++++ linux-2.6.23.15-grsec/include/asm-ppc/pgtable.h 2008-02-11 10:37:44.000000000 +0000 |
28607 |
+@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema |
28608 |
+ |
28609 |
+ #define PAGE_NONE __pgprot(_PAGE_BASE) |
28610 |
+ #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER) |
28611 |
+-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) |
28612 |
++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC) |
28613 |
+ #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) |
28614 |
+-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) |
28615 |
++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC) |
28616 |
+ #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) |
28617 |
+-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) |
28618 |
++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC) |
28619 |
++ |
28620 |
++#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x) |
28621 |
++# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED) |
28622 |
++# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED) |
28623 |
++# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED) |
28624 |
++#else |
28625 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
28626 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
28627 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
28628 |
++#endif |
28629 |
+ |
28630 |
+ #define PAGE_KERNEL __pgprot(_PAGE_RAM) |
28631 |
+ #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO) |
28632 |
+@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema |
28633 |
+ * This is the closest we can get.. |
28634 |
+ */ |
28635 |
+ #define __P000 PAGE_NONE |
28636 |
+-#define __P001 PAGE_READONLY_X |
28637 |
+-#define __P010 PAGE_COPY |
28638 |
+-#define __P011 PAGE_COPY_X |
28639 |
+-#define __P100 PAGE_READONLY |
28640 |
++#define __P001 PAGE_READONLY_NOEXEC |
28641 |
++#define __P010 PAGE_COPY_NOEXEC |
28642 |
++#define __P011 PAGE_COPY_NOEXEC |
28643 |
++#define __P100 PAGE_READONLY_X |
28644 |
+ #define __P101 PAGE_READONLY_X |
28645 |
+-#define __P110 PAGE_COPY |
28646 |
++#define __P110 PAGE_COPY_X |
28647 |
+ #define __P111 PAGE_COPY_X |
28648 |
+ |
28649 |
+ #define __S000 PAGE_NONE |
28650 |
+-#define __S001 PAGE_READONLY_X |
28651 |
+-#define __S010 PAGE_SHARED |
28652 |
+-#define __S011 PAGE_SHARED_X |
28653 |
+-#define __S100 PAGE_READONLY |
28654 |
++#define __S001 PAGE_READONLY_NOEXEC |
28655 |
++#define __S010 PAGE_SHARED_NOEXEC |
28656 |
++#define __S011 PAGE_SHARED_NOEXEC |
28657 |
++#define __S100 PAGE_READONLY_X |
28658 |
+ #define __S101 PAGE_READONLY_X |
28659 |
+-#define __S110 PAGE_SHARED |
28660 |
++#define __S110 PAGE_SHARED_X |
28661 |
+ #define __S111 PAGE_SHARED_X |
28662 |
+ |
28663 |
+ #ifndef __ASSEMBLY__ |
28664 |
+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 |
28665 |
+--- linux-2.6.23.15/include/asm-s390/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28666 |
++++ linux-2.6.23.15-grsec/include/asm-s390/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28667 |
+@@ -16,6 +16,7 @@ enum km_type { |
28668 |
+ KM_IRQ1, |
28669 |
+ KM_SOFTIRQ0, |
28670 |
+ KM_SOFTIRQ1, |
28671 |
++ KM_CLEARPAGE, |
28672 |
+ KM_TYPE_NR |
28673 |
+ }; |
28674 |
+ |
28675 |
+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 |
28676 |
+--- linux-2.6.23.15/include/asm-sh/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28677 |
++++ linux-2.6.23.15-grsec/include/asm-sh/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28678 |
+@@ -24,7 +24,8 @@ D(9) KM_IRQ0, |
28679 |
+ D(10) KM_IRQ1, |
28680 |
+ D(11) KM_SOFTIRQ0, |
28681 |
+ D(12) KM_SOFTIRQ1, |
28682 |
+-D(13) KM_TYPE_NR |
28683 |
++D(13) KM_CLEARPAGE, |
28684 |
++D(14) KM_TYPE_NR |
28685 |
+ }; |
28686 |
+ |
28687 |
+ #undef D |
28688 |
+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 |
28689 |
+--- linux-2.6.23.15/include/asm-sparc/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
28690 |
++++ linux-2.6.23.15-grsec/include/asm-sparc/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
28691 |
+@@ -91,8 +91,8 @@ struct relocation_info /* used when head |
28692 |
+ |
28693 |
+ #include <asm/page.h> |
28694 |
+ |
28695 |
+-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE) |
28696 |
+-#define STACK_TOP_MAX STACK_TOP |
28697 |
++#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE) |
28698 |
++#define STACK_TOP_MAX __STACK_TOP |
28699 |
+ |
28700 |
+ #endif /* __KERNEL__ */ |
28701 |
+ |
28702 |
+diff -Nurp linux-2.6.23.15/include/asm-sparc/elf.h linux-2.6.23.15-grsec/include/asm-sparc/elf.h |
28703 |
+--- linux-2.6.23.15/include/asm-sparc/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28704 |
++++ linux-2.6.23.15-grsec/include/asm-sparc/elf.h 2008-02-11 10:37:44.000000000 +0000 |
28705 |
+@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[ |
28706 |
+ |
28707 |
+ #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE) |
28708 |
+ |
28709 |
++#ifdef CONFIG_PAX_ASLR |
28710 |
++#define PAX_ELF_ET_DYN_BASE 0x10000UL |
28711 |
++ |
28712 |
++#define PAX_DELTA_MMAP_LEN 16 |
28713 |
++#define PAX_DELTA_STACK_LEN 16 |
28714 |
++#endif |
28715 |
++ |
28716 |
+ /* This yields a mask that user programs can use to figure out what |
28717 |
+ instruction set this cpu supports. This can NOT be done in userspace |
28718 |
+ on Sparc. */ |
28719 |
+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 |
28720 |
+--- linux-2.6.23.15/include/asm-sparc/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28721 |
++++ linux-2.6.23.15-grsec/include/asm-sparc/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28722 |
+@@ -15,6 +15,7 @@ enum km_type { |
28723 |
+ KM_IRQ1, |
28724 |
+ KM_SOFTIRQ0, |
28725 |
+ KM_SOFTIRQ1, |
28726 |
++ KM_CLEARPAGE, |
28727 |
+ KM_TYPE_NR |
28728 |
+ }; |
28729 |
+ |
28730 |
+diff -Nurp linux-2.6.23.15/include/asm-sparc/pgtable.h linux-2.6.23.15-grsec/include/asm-sparc/pgtable.h |
28731 |
+--- linux-2.6.23.15/include/asm-sparc/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
28732 |
++++ linux-2.6.23.15-grsec/include/asm-sparc/pgtable.h 2008-02-11 10:37:44.000000000 +0000 |
28733 |
+@@ -69,6 +69,16 @@ extern pgprot_t PAGE_SHARED; |
28734 |
+ #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) |
28735 |
+ #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) |
28736 |
+ |
28737 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28738 |
++extern pgprot_t PAGE_SHARED_NOEXEC; |
28739 |
++# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec)) |
28740 |
++# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec)) |
28741 |
++#else |
28742 |
++# define PAGE_SHARED_NOEXEC PAGE_SHARED |
28743 |
++# define PAGE_COPY_NOEXEC PAGE_COPY |
28744 |
++# define PAGE_READONLY_NOEXEC PAGE_READONLY |
28745 |
++#endif |
28746 |
++ |
28747 |
+ extern unsigned long page_kernel; |
28748 |
+ |
28749 |
+ #ifdef MODULE |
28750 |
+diff -Nurp linux-2.6.23.15/include/asm-sparc/pgtsrmmu.h linux-2.6.23.15-grsec/include/asm-sparc/pgtsrmmu.h |
28751 |
+--- linux-2.6.23.15/include/asm-sparc/pgtsrmmu.h 2007-10-09 21:31:38.000000000 +0100 |
28752 |
++++ linux-2.6.23.15-grsec/include/asm-sparc/pgtsrmmu.h 2008-02-11 10:37:44.000000000 +0000 |
28753 |
+@@ -115,6 +115,16 @@ |
28754 |
+ SRMMU_EXEC | SRMMU_REF) |
28755 |
+ #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
28756 |
+ SRMMU_EXEC | SRMMU_REF) |
28757 |
++ |
28758 |
++#ifdef CONFIG_PAX_PAGEEXEC |
28759 |
++#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
28760 |
++ SRMMU_WRITE | SRMMU_REF) |
28761 |
++#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
28762 |
++ SRMMU_REF) |
28763 |
++#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ |
28764 |
++ SRMMU_REF) |
28765 |
++#endif |
28766 |
++ |
28767 |
+ #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \ |
28768 |
+ SRMMU_DIRTY | SRMMU_REF) |
28769 |
+ |
28770 |
+diff -Nurp linux-2.6.23.15/include/asm-sparc/uaccess.h linux-2.6.23.15-grsec/include/asm-sparc/uaccess.h |
28771 |
+--- linux-2.6.23.15/include/asm-sparc/uaccess.h 2007-10-09 21:31:38.000000000 +0100 |
28772 |
++++ linux-2.6.23.15-grsec/include/asm-sparc/uaccess.h 2008-02-11 10:37:44.000000000 +0000 |
28773 |
+@@ -41,7 +41,7 @@ |
28774 |
+ * No one can read/write anything from userland in the kernel space by setting |
28775 |
+ * large size and address near to PAGE_OFFSET - a fault will break his intentions. |
28776 |
+ */ |
28777 |
+-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) |
28778 |
++#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; }) |
28779 |
+ #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) |
28780 |
+ #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) |
28781 |
+ #define access_ok(type, addr, size) \ |
28782 |
+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 |
28783 |
+--- linux-2.6.23.15/include/asm-sparc64/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
28784 |
++++ linux-2.6.23.15-grsec/include/asm-sparc64/a.out.h 2008-02-11 10:37:44.000000000 +0000 |
28785 |
+@@ -98,7 +98,7 @@ struct relocation_info /* used when head |
28786 |
+ #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE) |
28787 |
+ #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL)) |
28788 |
+ |
28789 |
+-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
28790 |
++#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \ |
28791 |
+ STACK_TOP32 : STACK_TOP64) |
28792 |
+ |
28793 |
+ #define STACK_TOP_MAX STACK_TOP64 |
28794 |
+diff -Nurp linux-2.6.23.15/include/asm-sparc64/elf.h linux-2.6.23.15-grsec/include/asm-sparc64/elf.h |
28795 |
+--- linux-2.6.23.15/include/asm-sparc64/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28796 |
++++ linux-2.6.23.15-grsec/include/asm-sparc64/elf.h 2008-02-11 10:37:44.000000000 +0000 |
28797 |
+@@ -143,6 +143,12 @@ typedef struct { |
28798 |
+ #define ELF_ET_DYN_BASE 0x0000010000000000UL |
28799 |
+ #endif |
28800 |
+ |
28801 |
++#ifdef CONFIG_PAX_ASLR |
28802 |
++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL) |
28803 |
++ |
28804 |
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 ) |
28805 |
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 ) |
28806 |
++#endif |
28807 |
+ |
28808 |
+ /* This yields a mask that user programs can use to figure out what |
28809 |
+ instruction set this cpu supports. */ |
28810 |
+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 |
28811 |
+--- linux-2.6.23.15/include/asm-sparc64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28812 |
++++ linux-2.6.23.15-grsec/include/asm-sparc64/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28813 |
+@@ -19,6 +19,7 @@ enum km_type { |
28814 |
+ KM_IRQ1, |
28815 |
+ KM_SOFTIRQ0, |
28816 |
+ KM_SOFTIRQ1, |
28817 |
++ KM_CLEARPAGE, |
28818 |
+ KM_TYPE_NR |
28819 |
+ }; |
28820 |
+ |
28821 |
+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 |
28822 |
+--- linux-2.6.23.15/include/asm-um/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28823 |
++++ linux-2.6.23.15-grsec/include/asm-um/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28824 |
+@@ -23,6 +23,7 @@ enum km_type { |
28825 |
+ KM_IRQ1, |
28826 |
+ KM_SOFTIRQ0, |
28827 |
+ KM_SOFTIRQ1, |
28828 |
++ KM_CLEARPAGE, |
28829 |
+ KM_TYPE_NR |
28830 |
+ }; |
28831 |
+ |
28832 |
+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 |
28833 |
+--- linux-2.6.23.15/include/asm-v850/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28834 |
++++ linux-2.6.23.15-grsec/include/asm-v850/kmap_types.h 2008-02-11 10:37:44.000000000 +0000 |
28835 |
+@@ -13,6 +13,7 @@ enum km_type { |
28836 |
+ KM_PTE1, |
28837 |
+ KM_IRQ0, |
28838 |
+ KM_IRQ1, |
28839 |
++ KM_CLEARPAGE, |
28840 |
+ KM_TYPE_NR |
28841 |
+ }; |
28842 |
+ |
28843 |
+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 |
28844 |
+--- linux-2.6.23.15/include/asm-x86_64/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
28845 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/a.out.h 2008-02-11 10:37:45.000000000 +0000 |
28846 |
+@@ -21,7 +21,7 @@ struct exec |
28847 |
+ |
28848 |
+ #ifdef __KERNEL__ |
28849 |
+ #include <linux/thread_info.h> |
28850 |
+-#define STACK_TOP TASK_SIZE |
28851 |
++#define __STACK_TOP TASK_SIZE |
28852 |
+ #define STACK_TOP_MAX TASK_SIZE64 |
28853 |
+ #endif |
28854 |
+ |
28855 |
+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 |
28856 |
+--- linux-2.6.23.15/include/asm-x86_64/apic.h 2007-10-09 21:31:38.000000000 +0100 |
28857 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/apic.h 2008-02-11 10:37:45.000000000 +0000 |
28858 |
+@@ -7,7 +7,7 @@ |
28859 |
+ #include <asm/apicdef.h> |
28860 |
+ #include <asm/system.h> |
28861 |
+ |
28862 |
+-#define Dprintk(x...) |
28863 |
++#define Dprintk(x...) do {} while (0) |
28864 |
+ |
28865 |
+ /* |
28866 |
+ * Debugging macros |
28867 |
+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 |
28868 |
+--- linux-2.6.23.15/include/asm-x86_64/elf.h 2007-10-09 21:31:38.000000000 +0100 |
28869 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/elf.h 2008-02-11 10:37:45.000000000 +0000 |
28870 |
+@@ -92,6 +92,13 @@ typedef struct user_i387_struct elf_fpre |
28871 |
+ |
28872 |
+ #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) |
28873 |
+ |
28874 |
++#ifdef CONFIG_PAX_ASLR |
28875 |
++#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL) |
28876 |
++ |
28877 |
++#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_IA32) ? 16 : 32) |
28878 |
++#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_IA32) ? 16 : 32) |
28879 |
++#endif |
28880 |
++ |
28881 |
+ /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is |
28882 |
+ now struct_user_regs, they are different). Assumes current is the process |
28883 |
+ getting dumped. */ |
28884 |
+@@ -172,7 +179,7 @@ extern int vdso_enabled; |
28885 |
+ |
28886 |
+ #define ARCH_DLINFO \ |
28887 |
+ do if (vdso_enabled) { \ |
28888 |
+- NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\ |
28889 |
++ NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\ |
28890 |
+ } while (0) |
28891 |
+ |
28892 |
+ #endif |
28893 |
+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 |
28894 |
+--- linux-2.6.23.15/include/asm-x86_64/futex.h 2007-10-09 21:31:38.000000000 +0100 |
28895 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/futex.h 2008-02-11 10:37:45.000000000 +0000 |
28896 |
+@@ -42,7 +42,7 @@ |
28897 |
+ : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0)) |
28898 |
+ |
28899 |
+ static inline int |
28900 |
+-futex_atomic_op_inuser (int encoded_op, int __user *uaddr) |
28901 |
++futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) |
28902 |
+ { |
28903 |
+ int op = (encoded_op >> 28) & 7; |
28904 |
+ int cmp = (encoded_op >> 24) & 15; |
28905 |
+@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op, |
28906 |
+ } |
28907 |
+ |
28908 |
+ static inline int |
28909 |
+-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval) |
28910 |
++futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval) |
28911 |
+ { |
28912 |
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) |
28913 |
+ return -EFAULT; |
28914 |
+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 |
28915 |
+--- linux-2.6.23.15/include/asm-x86_64/ia32.h 2007-10-09 21:31:38.000000000 +0100 |
28916 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/ia32.h 2008-02-11 10:37:45.000000000 +0000 |
28917 |
+@@ -156,7 +156,13 @@ struct ustat32 { |
28918 |
+ char f_fpack[6]; |
28919 |
+ }; |
28920 |
+ |
28921 |
+-#define IA32_STACK_TOP IA32_PAGE_OFFSET |
28922 |
++#ifdef CONFIG_PAX_RANDUSTACK |
28923 |
++#define IA32_DELTA_STACK (current->mm->delta_stack) |
28924 |
++#else |
28925 |
++#define IA32_DELTA_STACK 0UL |
28926 |
++#endif |
28927 |
++ |
28928 |
++#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK) |
28929 |
+ |
28930 |
+ #ifdef __KERNEL__ |
28931 |
+ struct user_desc; |
28932 |
+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 |
28933 |
+--- linux-2.6.23.15/include/asm-x86_64/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
28934 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/kmap_types.h 2008-02-11 10:37:45.000000000 +0000 |
28935 |
+@@ -13,6 +13,7 @@ enum km_type { |
28936 |
+ KM_IRQ1, |
28937 |
+ KM_SOFTIRQ0, |
28938 |
+ KM_SOFTIRQ1, |
28939 |
++ KM_CLEARPAGE, |
28940 |
+ KM_TYPE_NR |
28941 |
+ }; |
28942 |
+ |
28943 |
+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 |
28944 |
+--- linux-2.6.23.15/include/asm-x86_64/mmu.h 2007-10-09 21:31:38.000000000 +0100 |
28945 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/mmu.h 2008-02-11 10:37:45.000000000 +0000 |
28946 |
+@@ -15,7 +15,7 @@ typedef struct { |
28947 |
+ rwlock_t ldtlock; |
28948 |
+ int size; |
28949 |
+ struct semaphore sem; |
28950 |
+- void *vdso; |
28951 |
++ unsigned long vdso; |
28952 |
+ } mm_context_t; |
28953 |
+ |
28954 |
+ #endif |
28955 |
+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 |
28956 |
+--- linux-2.6.23.15/include/asm-x86_64/page.h 2007-10-09 21:31:38.000000000 +0100 |
28957 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/page.h 2008-02-11 10:37:45.000000000 +0000 |
28958 |
+@@ -94,6 +94,8 @@ extern unsigned long phys_base; |
28959 |
+ #define __START_KERNEL_map _AC(0xffffffff80000000, UL) |
28960 |
+ #define __PAGE_OFFSET _AC(0xffff810000000000, UL) |
28961 |
+ |
28962 |
++#define __KERNEL_TEXT_OFFSET (0) |
28963 |
++ |
28964 |
+ /* to align the pointer to the (next) page boundary */ |
28965 |
+ #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) |
28966 |
+ |
28967 |
+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 |
28968 |
+--- linux-2.6.23.15/include/asm-x86_64/pgalloc.h 2007-10-09 21:31:38.000000000 +0100 |
28969 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/pgalloc.h 2008-02-11 10:37:45.000000000 +0000 |
28970 |
+@@ -6,7 +6,7 @@ |
28971 |
+ #include <linux/mm.h> |
28972 |
+ |
28973 |
+ #define pmd_populate_kernel(mm, pmd, pte) \ |
28974 |
+- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte))) |
28975 |
++ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte))) |
28976 |
+ #define pud_populate(mm, pud, pmd) \ |
28977 |
+ set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd))) |
28978 |
+ #define pgd_populate(mm, pgd, pud) \ |
28979 |
+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 |
28980 |
+--- linux-2.6.23.15/include/asm-x86_64/pgtable.h 2007-10-09 21:31:38.000000000 +0100 |
28981 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/pgtable.h 2008-02-11 10:37:45.000000000 +0000 |
28982 |
+@@ -179,6 +179,10 @@ static inline pte_t ptep_get_and_clear_f |
28983 |
+ #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
28984 |
+ #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX) |
28985 |
+ #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) |
28986 |
++ |
28987 |
++#define PAGE_READONLY_NOEXEC PAGE_READONLY |
28988 |
++#define PAGE_SHARED_NOEXEC PAGE_SHARED |
28989 |
++ |
28990 |
+ #define __PAGE_KERNEL \ |
28991 |
+ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX) |
28992 |
+ #define __PAGE_KERNEL_EXEC \ |
28993 |
+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 |
28994 |
+--- linux-2.6.23.15/include/asm-x86_64/processor.h 2007-10-09 21:31:38.000000000 +0100 |
28995 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/processor.h 2008-02-11 10:37:45.000000000 +0000 |
28996 |
+@@ -140,7 +140,7 @@ static inline void clear_in_cr4 (unsigne |
28997 |
+ /* This decides where the kernel will search for a free chunk of vm |
28998 |
+ * space during mmap's. |
28999 |
+ */ |
29000 |
+-#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFe000) |
29001 |
++#define IA32_PAGE_OFFSET ((current->personality & ADDR_LIMIT_3GB) ? 0xc0000000 : 0xFFFFf000) |
29002 |
+ |
29003 |
+ #define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE64) |
29004 |
+ #define TASK_SIZE_OF(child) ((test_tsk_thread_flag(child, TIF_IA32)) ? IA32_PAGE_OFFSET : TASK_SIZE64) |
29005 |
+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 |
29006 |
+--- linux-2.6.23.15/include/asm-x86_64/system.h 2008-02-11 10:36:03.000000000 +0000 |
29007 |
++++ linux-2.6.23.15-grsec/include/asm-x86_64/system.h 2008-02-11 10:37:45.000000000 +0000 |
29008 |
+@@ -174,7 +174,7 @@ static inline void write_cr8(unsigned lo |
29009 |
+ |
29010 |
+ void cpu_idle_wait(void); |
29011 |
+ |
29012 |
+-extern unsigned long arch_align_stack(unsigned long sp); |
29013 |
++#define arch_align_stack(x) (x) |
29014 |
+ extern void free_init_pages(char *what, unsigned long begin, unsigned long end); |
29015 |
+ |
29016 |
+ #endif |
29017 |
+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 |
29018 |
+--- linux-2.6.23.15/include/asm-xtensa/kmap_types.h 2007-10-09 21:31:38.000000000 +0100 |
29019 |
++++ linux-2.6.23.15-grsec/include/asm-xtensa/kmap_types.h 2008-02-11 10:37:45.000000000 +0000 |
29020 |
+@@ -25,6 +25,7 @@ enum km_type { |
29021 |
+ KM_IRQ1, |
29022 |
+ KM_SOFTIRQ0, |
29023 |
+ KM_SOFTIRQ1, |
29024 |
++ KM_CLEARPAGE, |
29025 |
+ KM_TYPE_NR |
29026 |
+ }; |
29027 |
+ |
29028 |
+diff -Nurp linux-2.6.23.15/include/linux/a.out.h linux-2.6.23.15-grsec/include/linux/a.out.h |
29029 |
+--- linux-2.6.23.15/include/linux/a.out.h 2007-10-09 21:31:38.000000000 +0100 |
29030 |
++++ linux-2.6.23.15-grsec/include/linux/a.out.h 2008-02-11 10:37:45.000000000 +0000 |
29031 |
+@@ -7,6 +7,16 @@ |
29032 |
+ |
29033 |
+ #include <asm/a.out.h> |
29034 |
+ |
29035 |
++#ifdef CONFIG_PAX_RANDUSTACK |
29036 |
++#define __DELTA_STACK (current->mm->delta_stack) |
29037 |
++#else |
29038 |
++#define __DELTA_STACK 0UL |
29039 |
++#endif |
29040 |
++ |
29041 |
++#ifndef STACK_TOP |
29042 |
++#define STACK_TOP (__STACK_TOP - __DELTA_STACK) |
29043 |
++#endif |
29044 |
++ |
29045 |
+ #endif /* __STRUCT_EXEC_OVERRIDE__ */ |
29046 |
+ |
29047 |
+ /* these go in the N_MACHTYPE field */ |
29048 |
+@@ -37,6 +47,14 @@ enum machine_type { |
29049 |
+ M_MIPS2 = 152 /* MIPS R6000/R4000 binary */ |
29050 |
+ }; |
29051 |
+ |
29052 |
++/* Constants for the N_FLAGS field */ |
29053 |
++#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ |
29054 |
++#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */ |
29055 |
++#define F_PAX_MPROTECT 4 /* Restrict mprotect() */ |
29056 |
++#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */ |
29057 |
++/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */ |
29058 |
++#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ |
29059 |
++ |
29060 |
+ #if !defined (N_MAGIC) |
29061 |
+ #define N_MAGIC(exec) ((exec).a_info & 0xffff) |
29062 |
+ #endif |
29063 |
+diff -Nurp linux-2.6.23.15/include/linux/binfmts.h linux-2.6.23.15-grsec/include/linux/binfmts.h |
29064 |
+--- linux-2.6.23.15/include/linux/binfmts.h 2007-10-09 21:31:38.000000000 +0100 |
29065 |
++++ linux-2.6.23.15-grsec/include/linux/binfmts.h 2008-02-11 10:37:45.000000000 +0000 |
29066 |
+@@ -48,6 +48,7 @@ struct linux_binprm{ |
29067 |
+ unsigned interp_data; |
29068 |
+ unsigned long loader, exec; |
29069 |
+ unsigned long argv_len; |
29070 |
++ int misc; |
29071 |
+ }; |
29072 |
+ |
29073 |
+ #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 |
29074 |
+@@ -99,5 +100,8 @@ extern void compute_creds(struct linux_b |
29075 |
+ extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); |
29076 |
+ extern int set_binfmt(struct linux_binfmt *new); |
29077 |
+ |
29078 |
++void pax_report_fault(struct pt_regs *regs, void *pc, void *sp); |
29079 |
++void pax_report_insns(void *pc, void *sp); |
29080 |
++ |
29081 |
+ #endif /* __KERNEL__ */ |
29082 |
+ #endif /* _LINUX_BINFMTS_H */ |
29083 |
+diff -Nurp linux-2.6.23.15/include/linux/cache.h linux-2.6.23.15-grsec/include/linux/cache.h |
29084 |
+--- linux-2.6.23.15/include/linux/cache.h 2007-10-09 21:31:38.000000000 +0100 |
29085 |
++++ linux-2.6.23.15-grsec/include/linux/cache.h 2008-02-11 10:37:45.000000000 +0000 |
29086 |
+@@ -16,6 +16,10 @@ |
29087 |
+ #define __read_mostly |
29088 |
+ #endif |
29089 |
+ |
29090 |
++#ifndef __read_only |
29091 |
++#define __read_only |
29092 |
++#endif |
29093 |
++ |
29094 |
+ #ifndef ____cacheline_aligned |
29095 |
+ #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES))) |
29096 |
+ #endif |
29097 |
+diff -Nurp linux-2.6.23.15/include/linux/capability.h linux-2.6.23.15-grsec/include/linux/capability.h |
29098 |
+--- linux-2.6.23.15/include/linux/capability.h 2007-10-09 21:31:38.000000000 +0100 |
29099 |
++++ linux-2.6.23.15-grsec/include/linux/capability.h 2008-02-11 10:37:45.000000000 +0000 |
29100 |
+@@ -359,6 +359,7 @@ static inline kernel_cap_t cap_invert(ke |
29101 |
+ #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK) |
29102 |
+ |
29103 |
+ int capable(int cap); |
29104 |
++int capable_nolog(int cap); |
29105 |
+ int __capable(struct task_struct *t, int cap); |
29106 |
+ |
29107 |
+ #endif /* __KERNEL__ */ |
29108 |
+diff -Nurp linux-2.6.23.15/include/linux/elf.h linux-2.6.23.15-grsec/include/linux/elf.h |
29109 |
+--- linux-2.6.23.15/include/linux/elf.h 2007-10-09 21:31:38.000000000 +0100 |
29110 |
++++ linux-2.6.23.15-grsec/include/linux/elf.h 2008-02-11 10:37:45.000000000 +0000 |
29111 |
+@@ -8,6 +8,10 @@ |
29112 |
+ |
29113 |
+ struct file; |
29114 |
+ |
29115 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
29116 |
++#undef elf_read_implies_exec |
29117 |
++#endif |
29118 |
++ |
29119 |
+ #ifndef elf_read_implies_exec |
29120 |
+ /* Executables for which elf_read_implies_exec() returns TRUE will |
29121 |
+ have the READ_IMPLIES_EXEC personality flag set automatically. |
29122 |
+@@ -49,6 +53,16 @@ typedef __s64 Elf64_Sxword; |
29123 |
+ |
29124 |
+ #define PT_GNU_STACK (PT_LOOS + 0x474e551) |
29125 |
+ |
29126 |
++#define PT_PAX_FLAGS (PT_LOOS + 0x5041580) |
29127 |
++ |
29128 |
++/* Constants for the e_flags field */ |
29129 |
++#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ |
29130 |
++#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */ |
29131 |
++#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */ |
29132 |
++#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */ |
29133 |
++/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */ |
29134 |
++#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ |
29135 |
++ |
29136 |
+ /* These constants define the different elf file types */ |
29137 |
+ #define ET_NONE 0 |
29138 |
+ #define ET_REL 1 |
29139 |
+@@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword; |
29140 |
+ #define DT_DEBUG 21 |
29141 |
+ #define DT_TEXTREL 22 |
29142 |
+ #define DT_JMPREL 23 |
29143 |
++#define DT_FLAGS 30 |
29144 |
++ #define DF_TEXTREL 0x00000004 |
29145 |
+ #define DT_ENCODING 32 |
29146 |
+ #define OLD_DT_LOOS 0x60000000 |
29147 |
+ #define DT_LOOS 0x6000000d |
29148 |
+@@ -229,6 +245,19 @@ typedef struct elf64_hdr { |
29149 |
+ #define PF_W 0x2 |
29150 |
+ #define PF_X 0x1 |
29151 |
+ |
29152 |
++#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */ |
29153 |
++#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */ |
29154 |
++#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */ |
29155 |
++#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */ |
29156 |
++#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */ |
29157 |
++#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */ |
29158 |
++/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */ |
29159 |
++/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */ |
29160 |
++#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */ |
29161 |
++#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */ |
29162 |
++#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */ |
29163 |
++#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */ |
29164 |
++ |
29165 |
+ typedef struct elf32_phdr{ |
29166 |
+ Elf32_Word p_type; |
29167 |
+ Elf32_Off p_offset; |
29168 |
+@@ -321,6 +350,8 @@ typedef struct elf64_shdr { |
29169 |
+ #define EI_OSABI 7 |
29170 |
+ #define EI_PAD 8 |
29171 |
+ |
29172 |
++#define EI_PAX 14 |
29173 |
++ |
29174 |
+ #define ELFMAG0 0x7f /* EI_MAG */ |
29175 |
+ #define ELFMAG1 'E' |
29176 |
+ #define ELFMAG2 'L' |
29177 |
+@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC []; |
29178 |
+ #define elf_phdr elf32_phdr |
29179 |
+ #define elf_note elf32_note |
29180 |
+ #define elf_addr_t Elf32_Off |
29181 |
++#define elf_dyn Elf32_Dyn |
29182 |
+ |
29183 |
+ #else |
29184 |
+ |
29185 |
+@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC []; |
29186 |
+ #define elf_phdr elf64_phdr |
29187 |
+ #define elf_note elf64_note |
29188 |
+ #define elf_addr_t Elf64_Off |
29189 |
++#define elf_dyn Elf64_Dyn |
29190 |
+ |
29191 |
+ #endif |
29192 |
+ |
29193 |
+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 |
29194 |
+--- linux-2.6.23.15/include/linux/ext4_fs_extents.h 2007-10-09 21:31:38.000000000 +0100 |
29195 |
++++ linux-2.6.23.15-grsec/include/linux/ext4_fs_extents.h 2008-02-11 10:37:45.000000000 +0000 |
29196 |
+@@ -50,7 +50,7 @@ |
29197 |
+ #ifdef EXT_DEBUG |
29198 |
+ #define ext_debug(a...) printk(a) |
29199 |
+ #else |
29200 |
+-#define ext_debug(a...) |
29201 |
++#define ext_debug(a...) do {} while (0) |
29202 |
+ #endif |
29203 |
+ |
29204 |
+ /* |
29205 |
+diff -Nurp linux-2.6.23.15/include/linux/gracl.h linux-2.6.23.15-grsec/include/linux/gracl.h |
29206 |
+--- linux-2.6.23.15/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100 |
29207 |
++++ linux-2.6.23.15-grsec/include/linux/gracl.h 2008-02-11 10:37:45.000000000 +0000 |
29208 |
+@@ -0,0 +1,317 @@ |
29209 |
++#ifndef GR_ACL_H |
29210 |
++#define GR_ACL_H |
29211 |
++ |
29212 |
++#include <linux/grdefs.h> |
29213 |
++#include <linux/resource.h> |
29214 |
++#include <linux/dcache.h> |
29215 |
++#include <asm/resource.h> |
29216 |
++ |
29217 |
++/* Major status information */ |
29218 |
++ |
29219 |
++#define GR_VERSION "grsecurity 2.1.11" |
29220 |
++#define GRSECURITY_VERSION 0x2111 |
29221 |
++ |
29222 |
++enum { |
29223 |
++ |
29224 |
++ SHUTDOWN = 0, |
29225 |
++ ENABLE = 1, |
29226 |
++ SPROLE = 2, |
29227 |
++ RELOAD = 3, |
29228 |
++ SEGVMOD = 4, |
29229 |
++ STATUS = 5, |
29230 |
++ UNSPROLE = 6, |
29231 |
++ PASSSET = 7, |
29232 |
++ SPROLEPAM = 8 |
29233 |
++}; |
29234 |
++ |
29235 |
++/* Password setup definitions |
29236 |
++ * kernel/grhash.c */ |
29237 |
++enum { |
29238 |
++ GR_PW_LEN = 128, |
29239 |
++ GR_SALT_LEN = 16, |
29240 |
++ GR_SHA_LEN = 32, |
29241 |
++}; |
29242 |
++ |
29243 |
++enum { |
29244 |
++ GR_SPROLE_LEN = 64, |
29245 |
++}; |
29246 |
++ |
29247 |
++#define GR_NLIMITS (RLIMIT_LOCKS + 2) |
29248 |
++ |
29249 |
++/* Begin Data Structures */ |
29250 |
++ |
29251 |
++struct sprole_pw { |
29252 |
++ unsigned char *rolename; |
29253 |
++ unsigned char salt[GR_SALT_LEN]; |
29254 |
++ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */ |
29255 |
++}; |
29256 |
++ |
29257 |
++struct name_entry { |
29258 |
++ __u32 key; |
29259 |
++ ino_t inode; |
29260 |
++ dev_t device; |
29261 |
++ char *name; |
29262 |
++ __u16 len; |
29263 |
++ __u8 deleted; |
29264 |
++ struct name_entry *prev; |
29265 |
++ struct name_entry *next; |
29266 |
++}; |
29267 |
++ |
29268 |
++struct inodev_entry { |
29269 |
++ struct name_entry *nentry; |
29270 |
++ struct inodev_entry *prev; |
29271 |
++ struct inodev_entry *next; |
29272 |
++}; |
29273 |
++ |
29274 |
++struct acl_role_db { |
29275 |
++ struct acl_role_label **r_hash; |
29276 |
++ __u32 r_size; |
29277 |
++}; |
29278 |
++ |
29279 |
++struct inodev_db { |
29280 |
++ struct inodev_entry **i_hash; |
29281 |
++ __u32 i_size; |
29282 |
++}; |
29283 |
++ |
29284 |
++struct name_db { |
29285 |
++ struct name_entry **n_hash; |
29286 |
++ __u32 n_size; |
29287 |
++}; |
29288 |
++ |
29289 |
++struct crash_uid { |
29290 |
++ uid_t uid; |
29291 |
++ unsigned long expires; |
29292 |
++}; |
29293 |
++ |
29294 |
++struct gr_hash_struct { |
29295 |
++ void **table; |
29296 |
++ void **nametable; |
29297 |
++ void *first; |
29298 |
++ __u32 table_size; |
29299 |
++ __u32 used_size; |
29300 |
++ int type; |
29301 |
++}; |
29302 |
++ |
29303 |
++/* Userspace Grsecurity ACL data structures */ |
29304 |
++ |
29305 |
++struct acl_subject_label { |
29306 |
++ char *filename; |
29307 |
++ ino_t inode; |
29308 |
++ dev_t device; |
29309 |
++ __u32 mode; |
29310 |
++ __u32 cap_mask; |
29311 |
++ __u32 cap_lower; |
29312 |
++ |
29313 |
++ struct rlimit res[GR_NLIMITS]; |
29314 |
++ __u16 resmask; |
29315 |
++ |
29316 |
++ __u8 user_trans_type; |
29317 |
++ __u8 group_trans_type; |
29318 |
++ uid_t *user_transitions; |
29319 |
++ gid_t *group_transitions; |
29320 |
++ __u16 user_trans_num; |
29321 |
++ __u16 group_trans_num; |
29322 |
++ |
29323 |
++ __u32 ip_proto[8]; |
29324 |
++ __u32 ip_type; |
29325 |
++ struct acl_ip_label **ips; |
29326 |
++ __u32 ip_num; |
29327 |
++ |
29328 |
++ __u32 crashes; |
29329 |
++ unsigned long expires; |
29330 |
++ |
29331 |
++ struct acl_subject_label *parent_subject; |
29332 |
++ struct gr_hash_struct *hash; |
29333 |
++ struct acl_subject_label *prev; |
29334 |
++ struct acl_subject_label *next; |
29335 |
++ |
29336 |
++ struct acl_object_label **obj_hash; |
29337 |
++ __u32 obj_hash_size; |
29338 |
++ __u16 pax_flags; |
29339 |
++}; |
29340 |
++ |
29341 |
++struct role_allowed_ip { |
29342 |
++ __u32 addr; |
29343 |
++ __u32 netmask; |
29344 |
++ |
29345 |
++ struct role_allowed_ip *prev; |
29346 |
++ struct role_allowed_ip *next; |
29347 |
++}; |
29348 |
++ |
29349 |
++struct role_transition { |
29350 |
++ char *rolename; |
29351 |
++ |
29352 |
++ struct role_transition *prev; |
29353 |
++ struct role_transition *next; |
29354 |
++}; |
29355 |
++ |
29356 |
++struct acl_role_label { |
29357 |
++ char *rolename; |
29358 |
++ uid_t uidgid; |
29359 |
++ __u16 roletype; |
29360 |
++ |
29361 |
++ __u16 auth_attempts; |
29362 |
++ unsigned long expires; |
29363 |
++ |
29364 |
++ struct acl_subject_label *root_label; |
29365 |
++ struct gr_hash_struct *hash; |
29366 |
++ |
29367 |
++ struct acl_role_label *prev; |
29368 |
++ struct acl_role_label *next; |
29369 |
++ |
29370 |
++ struct role_transition *transitions; |
29371 |
++ struct role_allowed_ip *allowed_ips; |
29372 |
++ uid_t *domain_children; |
29373 |
++ __u16 domain_child_num; |
29374 |
++ |
29375 |
++ struct acl_subject_label **subj_hash; |
29376 |
++ __u32 subj_hash_size; |
29377 |
++}; |
29378 |
++ |
29379 |
++struct user_acl_role_db { |
29380 |
++ struct acl_role_label **r_table; |
29381 |
++ __u32 num_pointers; /* Number of allocations to track */ |
29382 |
++ __u32 num_roles; /* Number of roles */ |
29383 |
++ __u32 num_domain_children; /* Number of domain children */ |
29384 |
++ __u32 num_subjects; /* Number of subjects */ |
29385 |
++ __u32 num_objects; /* Number of objects */ |
29386 |
++}; |
29387 |
++ |
29388 |
++struct acl_object_label { |
29389 |
++ char *filename; |
29390 |
++ ino_t inode; |
29391 |
++ dev_t device; |
29392 |
++ __u32 mode; |
29393 |
++ |
29394 |
++ struct acl_subject_label *nested; |
29395 |
++ struct acl_object_label *globbed; |
29396 |
++ |
29397 |
++ /* next two structures not used */ |
29398 |
++ |
29399 |
++ struct acl_object_label *prev; |
29400 |
++ struct acl_object_label *next; |
29401 |
++}; |
29402 |
++ |
29403 |
++struct acl_ip_label { |
29404 |
++ char *iface; |
29405 |
++ __u32 addr; |
29406 |
++ __u32 netmask; |
29407 |
++ __u16 low, high; |
29408 |
++ __u8 mode; |
29409 |
++ __u32 type; |
29410 |
++ __u32 proto[8]; |
29411 |
++ |
29412 |
++ /* next two structures not used */ |
29413 |
++ |
29414 |
++ struct acl_ip_label *prev; |
29415 |
++ struct acl_ip_label *next; |
29416 |
++}; |
29417 |
++ |
29418 |
++struct gr_arg { |
29419 |
++ struct user_acl_role_db role_db; |
29420 |
++ unsigned char pw[GR_PW_LEN]; |
29421 |
++ unsigned char salt[GR_SALT_LEN]; |
29422 |
++ unsigned char sum[GR_SHA_LEN]; |
29423 |
++ unsigned char sp_role[GR_SPROLE_LEN]; |
29424 |
++ struct sprole_pw *sprole_pws; |
29425 |
++ dev_t segv_device; |
29426 |
++ ino_t segv_inode; |
29427 |
++ uid_t segv_uid; |
29428 |
++ __u16 num_sprole_pws; |
29429 |
++ __u16 mode; |
29430 |
++}; |
29431 |
++ |
29432 |
++struct gr_arg_wrapper { |
29433 |
++ struct gr_arg *arg; |
29434 |
++ __u32 version; |
29435 |
++ __u32 size; |
29436 |
++}; |
29437 |
++ |
29438 |
++struct subject_map { |
29439 |
++ struct acl_subject_label *user; |
29440 |
++ struct acl_subject_label *kernel; |
29441 |
++ struct subject_map *prev; |
29442 |
++ struct subject_map *next; |
29443 |
++}; |
29444 |
++ |
29445 |
++struct acl_subj_map_db { |
29446 |
++ struct subject_map **s_hash; |
29447 |
++ __u32 s_size; |
29448 |
++}; |
29449 |
++ |
29450 |
++/* End Data Structures Section */ |
29451 |
++ |
29452 |
++/* Hash functions generated by empirical testing by Brad Spengler |
29453 |
++ Makes good use of the low bits of the inode. Generally 0-1 times |
29454 |
++ in loop for successful match. 0-3 for unsuccessful match. |
29455 |
++ Shift/add algorithm with modulus of table size and an XOR*/ |
29456 |
++ |
29457 |
++static __inline__ unsigned int |
29458 |
++rhash(const uid_t uid, const __u16 type, const unsigned int sz) |
29459 |
++{ |
29460 |
++ return (((uid << type) + (uid ^ type)) % sz); |
29461 |
++} |
29462 |
++ |
29463 |
++ static __inline__ unsigned int |
29464 |
++shash(const struct acl_subject_label *userp, const unsigned int sz) |
29465 |
++{ |
29466 |
++ return ((const unsigned long)userp % sz); |
29467 |
++} |
29468 |
++ |
29469 |
++static __inline__ unsigned int |
29470 |
++fhash(const ino_t ino, const dev_t dev, const unsigned int sz) |
29471 |
++{ |
29472 |
++ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz); |
29473 |
++} |
29474 |
++ |
29475 |
++static __inline__ unsigned int |
29476 |
++nhash(const char *name, const __u16 len, const unsigned int sz) |
29477 |
++{ |
29478 |
++ return full_name_hash(name, len) % sz; |
29479 |
++} |
29480 |
++ |
29481 |
++#define FOR_EACH_ROLE_START(role,iter) \ |
29482 |
++ role = NULL; \ |
29483 |
++ iter = 0; \ |
29484 |
++ while (iter < acl_role_set.r_size) { \ |
29485 |
++ if (role == NULL) \ |
29486 |
++ role = acl_role_set.r_hash[iter]; \ |
29487 |
++ if (role == NULL) { \ |
29488 |
++ iter++; \ |
29489 |
++ continue; \ |
29490 |
++ } |
29491 |
++ |
29492 |
++#define FOR_EACH_ROLE_END(role,iter) \ |
29493 |
++ role = role->next; \ |
29494 |
++ if (role == NULL) \ |
29495 |
++ iter++; \ |
29496 |
++ } |
29497 |
++ |
29498 |
++#define FOR_EACH_SUBJECT_START(role,subj,iter) \ |
29499 |
++ subj = NULL; \ |
29500 |
++ iter = 0; \ |
29501 |
++ while (iter < role->subj_hash_size) { \ |
29502 |
++ if (subj == NULL) \ |
29503 |
++ subj = role->subj_hash[iter]; \ |
29504 |
++ if (subj == NULL) { \ |
29505 |
++ iter++; \ |
29506 |
++ continue; \ |
29507 |
++ } |
29508 |
++ |
29509 |
++#define FOR_EACH_SUBJECT_END(subj,iter) \ |
29510 |
++ subj = subj->next; \ |
29511 |
++ if (subj == NULL) \ |
29512 |
++ iter++; \ |
29513 |
++ } |
29514 |
++ |
29515 |
++ |
29516 |
++#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \ |
29517 |
++ subj = role->hash->first; \ |
29518 |
++ while (subj != NULL) { |
29519 |
++ |
29520 |
++#define FOR_EACH_NESTED_SUBJECT_END(subj) \ |
29521 |
++ subj = subj->next; \ |
29522 |
++ } |
29523 |
++ |
29524 |
++#endif |
29525 |
++ |
29526 |
+diff -Nurp linux-2.6.23.15/include/linux/gralloc.h linux-2.6.23.15-grsec/include/linux/gralloc.h |
29527 |
+--- linux-2.6.23.15/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100 |
29528 |
++++ linux-2.6.23.15-grsec/include/linux/gralloc.h 2008-02-11 10:37:45.000000000 +0000 |
29529 |
+@@ -0,0 +1,8 @@ |
29530 |
++#ifndef __GRALLOC_H |
29531 |
++#define __GRALLOC_H |
29532 |
++ |
29533 |
++void acl_free_all(void); |
29534 |
++int acl_alloc_stack_init(unsigned long size); |
29535 |
++void *acl_alloc(unsigned long len); |
29536 |
++ |
29537 |
++#endif |
29538 |
+diff -Nurp linux-2.6.23.15/include/linux/grdefs.h linux-2.6.23.15-grsec/include/linux/grdefs.h |
29539 |
+--- linux-2.6.23.15/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100 |
29540 |
++++ linux-2.6.23.15-grsec/include/linux/grdefs.h 2008-02-11 10:37:45.000000000 +0000 |
29541 |
+@@ -0,0 +1,131 @@ |
29542 |
++#ifndef GRDEFS_H |
29543 |
++#define GRDEFS_H |
29544 |
++ |
29545 |
++/* Begin grsecurity status declarations */ |
29546 |
++ |
29547 |
++enum { |
29548 |
++ GR_READY = 0x01, |
29549 |
++ GR_STATUS_INIT = 0x00 // disabled state |
29550 |
++}; |
29551 |
++ |
29552 |
++/* Begin ACL declarations */ |
29553 |
++ |
29554 |
++/* Role flags */ |
29555 |
++ |
29556 |
++enum { |
29557 |
++ GR_ROLE_USER = 0x0001, |
29558 |
++ GR_ROLE_GROUP = 0x0002, |
29559 |
++ GR_ROLE_DEFAULT = 0x0004, |
29560 |
++ GR_ROLE_SPECIAL = 0x0008, |
29561 |
++ GR_ROLE_AUTH = 0x0010, |
29562 |
++ GR_ROLE_NOPW = 0x0020, |
29563 |
++ GR_ROLE_GOD = 0x0040, |
29564 |
++ GR_ROLE_LEARN = 0x0080, |
29565 |
++ GR_ROLE_TPE = 0x0100, |
29566 |
++ GR_ROLE_DOMAIN = 0x0200, |
29567 |
++ GR_ROLE_PAM = 0x0400 |
29568 |
++}; |
29569 |
++ |
29570 |
++/* ACL Subject and Object mode flags */ |
29571 |
++enum { |
29572 |
++ GR_DELETED = 0x80000000 |
29573 |
++}; |
29574 |
++ |
29575 |
++/* ACL Object-only mode flags */ |
29576 |
++enum { |
29577 |
++ GR_READ = 0x00000001, |
29578 |
++ GR_APPEND = 0x00000002, |
29579 |
++ GR_WRITE = 0x00000004, |
29580 |
++ GR_EXEC = 0x00000008, |
29581 |
++ GR_FIND = 0x00000010, |
29582 |
++ GR_INHERIT = 0x00000020, |
29583 |
++ GR_SETID = 0x00000040, |
29584 |
++ GR_CREATE = 0x00000080, |
29585 |
++ GR_DELETE = 0x00000100, |
29586 |
++ GR_LINK = 0x00000200, |
29587 |
++ GR_AUDIT_READ = 0x00000400, |
29588 |
++ GR_AUDIT_APPEND = 0x00000800, |
29589 |
++ GR_AUDIT_WRITE = 0x00001000, |
29590 |
++ GR_AUDIT_EXEC = 0x00002000, |
29591 |
++ GR_AUDIT_FIND = 0x00004000, |
29592 |
++ GR_AUDIT_INHERIT= 0x00008000, |
29593 |
++ GR_AUDIT_SETID = 0x00010000, |
29594 |
++ GR_AUDIT_CREATE = 0x00020000, |
29595 |
++ GR_AUDIT_DELETE = 0x00040000, |
29596 |
++ GR_AUDIT_LINK = 0x00080000, |
29597 |
++ GR_PTRACERD = 0x00100000, |
29598 |
++ GR_NOPTRACE = 0x00200000, |
29599 |
++ GR_SUPPRESS = 0x00400000, |
29600 |
++ GR_NOLEARN = 0x00800000 |
29601 |
++}; |
29602 |
++ |
29603 |
++#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \ |
29604 |
++ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \ |
29605 |
++ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK) |
29606 |
++ |
29607 |
++/* ACL subject-only mode flags */ |
29608 |
++enum { |
29609 |
++ GR_KILL = 0x00000001, |
29610 |
++ GR_VIEW = 0x00000002, |
29611 |
++ GR_PROTECTED = 0x00000004, |
29612 |
++ GR_LEARN = 0x00000008, |
29613 |
++ GR_OVERRIDE = 0x00000010, |
29614 |
++ /* just a placeholder, this mode is only used in userspace */ |
29615 |
++ GR_DUMMY = 0x00000020, |
29616 |
++ GR_PROTSHM = 0x00000040, |
29617 |
++ GR_KILLPROC = 0x00000080, |
29618 |
++ GR_KILLIPPROC = 0x00000100, |
29619 |
++ /* just a placeholder, this mode is only used in userspace */ |
29620 |
++ GR_NOTROJAN = 0x00000200, |
29621 |
++ GR_PROTPROCFD = 0x00000400, |
29622 |
++ GR_PROCACCT = 0x00000800, |
29623 |
++ GR_RELAXPTRACE = 0x00001000, |
29624 |
++ GR_NESTED = 0x00002000, |
29625 |
++ GR_INHERITLEARN = 0x00004000, |
29626 |
++ GR_PROCFIND = 0x00008000, |
29627 |
++ GR_POVERRIDE = 0x00010000, |
29628 |
++ GR_KERNELAUTH = 0x00020000, |
29629 |
++}; |
29630 |
++ |
29631 |
++enum { |
29632 |
++ GR_PAX_ENABLE_SEGMEXEC = 0x0001, |
29633 |
++ GR_PAX_ENABLE_PAGEEXEC = 0x0002, |
29634 |
++ GR_PAX_ENABLE_MPROTECT = 0x0004, |
29635 |
++ GR_PAX_ENABLE_RANDMMAP = 0x0008, |
29636 |
++ GR_PAX_ENABLE_EMUTRAMP = 0x0010, |
29637 |
++ GR_PAX_DISABLE_SEGMEXEC = 0x0100, |
29638 |
++ GR_PAX_DISABLE_PAGEEXEC = 0x0200, |
29639 |
++ GR_PAX_DISABLE_MPROTECT = 0x0400, |
29640 |
++ GR_PAX_DISABLE_RANDMMAP = 0x0800, |
29641 |
++ GR_PAX_DISABLE_EMUTRAMP = 0x1000, |
29642 |
++}; |
29643 |
++ |
29644 |
++enum { |
29645 |
++ GR_ID_USER = 0x01, |
29646 |
++ GR_ID_GROUP = 0x02, |
29647 |
++}; |
29648 |
++ |
29649 |
++enum { |
29650 |
++ GR_ID_ALLOW = 0x01, |
29651 |
++ GR_ID_DENY = 0x02, |
29652 |
++}; |
29653 |
++ |
29654 |
++#define GR_CRASH_RES 11 |
29655 |
++#define GR_UIDTABLE_MAX 500 |
29656 |
++ |
29657 |
++/* begin resource learning section */ |
29658 |
++enum { |
29659 |
++ GR_RLIM_CPU_BUMP = 60, |
29660 |
++ GR_RLIM_FSIZE_BUMP = 50000, |
29661 |
++ GR_RLIM_DATA_BUMP = 10000, |
29662 |
++ GR_RLIM_STACK_BUMP = 1000, |
29663 |
++ GR_RLIM_CORE_BUMP = 10000, |
29664 |
++ GR_RLIM_RSS_BUMP = 500000, |
29665 |
++ GR_RLIM_NPROC_BUMP = 1, |
29666 |
++ GR_RLIM_NOFILE_BUMP = 5, |
29667 |
++ GR_RLIM_MEMLOCK_BUMP = 50000, |
29668 |
++ GR_RLIM_AS_BUMP = 500000, |
29669 |
++ GR_RLIM_LOCKS_BUMP = 2 |
29670 |
++}; |
29671 |
++ |
29672 |
++#endif |
29673 |
+diff -Nurp linux-2.6.23.15/include/linux/grinternal.h linux-2.6.23.15-grsec/include/linux/grinternal.h |
29674 |
+--- linux-2.6.23.15/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100 |
29675 |
++++ linux-2.6.23.15-grsec/include/linux/grinternal.h 2008-02-11 10:37:45.000000000 +0000 |
29676 |
+@@ -0,0 +1,210 @@ |
29677 |
++#ifndef __GRINTERNAL_H |
29678 |
++#define __GRINTERNAL_H |
29679 |
++ |
29680 |
++#ifdef CONFIG_GRKERNSEC |
29681 |
++ |
29682 |
++#include <linux/fs.h> |
29683 |
++#include <linux/gracl.h> |
29684 |
++#include <linux/grdefs.h> |
29685 |
++#include <linux/grmsg.h> |
29686 |
++ |
29687 |
++void gr_add_learn_entry(const char *fmt, ...); |
29688 |
++__u32 gr_search_file(const struct dentry *dentry, const __u32 mode, |
29689 |
++ const struct vfsmount *mnt); |
29690 |
++__u32 gr_check_create(const struct dentry *new_dentry, |
29691 |
++ const struct dentry *parent, |
29692 |
++ const struct vfsmount *mnt, const __u32 mode); |
29693 |
++int gr_check_protected_task(const struct task_struct *task); |
29694 |
++__u32 to_gr_audit(const __u32 reqmode); |
29695 |
++int gr_set_acls(const int type); |
29696 |
++ |
29697 |
++int gr_acl_is_enabled(void); |
29698 |
++char gr_roletype_to_char(void); |
29699 |
++ |
29700 |
++void gr_handle_alertkill(struct task_struct *task); |
29701 |
++char *gr_to_filename(const struct dentry *dentry, |
29702 |
++ const struct vfsmount *mnt); |
29703 |
++char *gr_to_filename1(const struct dentry *dentry, |
29704 |
++ const struct vfsmount *mnt); |
29705 |
++char *gr_to_filename2(const struct dentry *dentry, |
29706 |
++ const struct vfsmount *mnt); |
29707 |
++char *gr_to_filename3(const struct dentry *dentry, |
29708 |
++ const struct vfsmount *mnt); |
29709 |
++ |
29710 |
++extern int grsec_enable_link; |
29711 |
++extern int grsec_enable_fifo; |
29712 |
++extern int grsec_enable_execve; |
29713 |
++extern int grsec_enable_shm; |
29714 |
++extern int grsec_enable_execlog; |
29715 |
++extern int grsec_enable_signal; |
29716 |
++extern int grsec_enable_forkfail; |
29717 |
++extern int grsec_enable_time; |
29718 |
++extern int grsec_enable_chroot_shmat; |
29719 |
++extern int grsec_enable_chroot_findtask; |
29720 |
++extern int grsec_enable_chroot_mount; |
29721 |
++extern int grsec_enable_chroot_double; |
29722 |
++extern int grsec_enable_chroot_pivot; |
29723 |
++extern int grsec_enable_chroot_chdir; |
29724 |
++extern int grsec_enable_chroot_chmod; |
29725 |
++extern int grsec_enable_chroot_mknod; |
29726 |
++extern int grsec_enable_chroot_fchdir; |
29727 |
++extern int grsec_enable_chroot_nice; |
29728 |
++extern int grsec_enable_chroot_execlog; |
29729 |
++extern int grsec_enable_chroot_caps; |
29730 |
++extern int grsec_enable_chroot_sysctl; |
29731 |
++extern int grsec_enable_chroot_unix; |
29732 |
++extern int grsec_enable_tpe; |
29733 |
++extern int grsec_tpe_gid; |
29734 |
++extern int grsec_enable_tpe_all; |
29735 |
++extern int grsec_enable_sidcaps; |
29736 |
++extern int grsec_enable_socket_all; |
29737 |
++extern int grsec_socket_all_gid; |
29738 |
++extern int grsec_enable_socket_client; |
29739 |
++extern int grsec_socket_client_gid; |
29740 |
++extern int grsec_enable_socket_server; |
29741 |
++extern int grsec_socket_server_gid; |
29742 |
++extern int grsec_audit_gid; |
29743 |
++extern int grsec_enable_group; |
29744 |
++extern int grsec_enable_audit_ipc; |
29745 |
++extern int grsec_enable_audit_textrel; |
29746 |
++extern int grsec_enable_mount; |
29747 |
++extern int grsec_enable_chdir; |
29748 |
++extern int grsec_resource_logging; |
29749 |
++extern int grsec_lock; |
29750 |
++ |
29751 |
++extern spinlock_t grsec_alert_lock; |
29752 |
++extern unsigned long grsec_alert_wtime; |
29753 |
++extern unsigned long grsec_alert_fyet; |
29754 |
++ |
29755 |
++extern spinlock_t grsec_audit_lock; |
29756 |
++ |
29757 |
++extern rwlock_t grsec_exec_file_lock; |
29758 |
++ |
29759 |
++#define gr_task_fullpath(tsk) (tsk->exec_file ? \ |
29760 |
++ gr_to_filename2(tsk->exec_file->f_dentry, \ |
29761 |
++ tsk->exec_file->f_vfsmnt) : "/") |
29762 |
++ |
29763 |
++#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \ |
29764 |
++ gr_to_filename3(tsk->parent->exec_file->f_dentry, \ |
29765 |
++ tsk->parent->exec_file->f_vfsmnt) : "/") |
29766 |
++ |
29767 |
++#define gr_task_fullpath0(tsk) (tsk->exec_file ? \ |
29768 |
++ gr_to_filename(tsk->exec_file->f_dentry, \ |
29769 |
++ tsk->exec_file->f_vfsmnt) : "/") |
29770 |
++ |
29771 |
++#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \ |
29772 |
++ gr_to_filename1(tsk->parent->exec_file->f_dentry, \ |
29773 |
++ tsk->parent->exec_file->f_vfsmnt) : "/") |
29774 |
++ |
29775 |
++#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \ |
29776 |
++ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \ |
29777 |
++ child_reaper(tsk_a)->fs->root->d_inode->i_sb->s_dev) || \ |
29778 |
++ (tsk_a->fs->root->d_inode->i_ino != \ |
29779 |
++ child_reaper(tsk_a)->fs->root->d_inode->i_ino))) |
29780 |
++ |
29781 |
++#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \ |
29782 |
++ (tsk_a->fs->root->d_inode->i_sb->s_dev == \ |
29783 |
++ tsk_b->fs->root->d_inode->i_sb->s_dev) && \ |
29784 |
++ (tsk_a->fs->root->d_inode->i_ino == \ |
29785 |
++ tsk_b->fs->root->d_inode->i_ino)) |
29786 |
++ |
29787 |
++#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \ |
29788 |
++ task->pid, task->uid, \ |
29789 |
++ task->euid, task->gid, task->egid, \ |
29790 |
++ gr_parent_task_fullpath(task), \ |
29791 |
++ task->parent->comm, task->parent->pid, \ |
29792 |
++ task->parent->uid, task->parent->euid, \ |
29793 |
++ task->parent->gid, task->parent->egid |
29794 |
++ |
29795 |
++#define GR_CHROOT_CAPS ( \ |
29796 |
++ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \ |
29797 |
++ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \ |
29798 |
++ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \ |
29799 |
++ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \ |
29800 |
++ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \ |
29801 |
++ CAP_TO_MASK(CAP_IPC_OWNER)) |
29802 |
++ |
29803 |
++#define security_learn(normal_msg,args...) \ |
29804 |
++({ \ |
29805 |
++ read_lock(&grsec_exec_file_lock); \ |
29806 |
++ gr_add_learn_entry(normal_msg "\n", ## args); \ |
29807 |
++ read_unlock(&grsec_exec_file_lock); \ |
29808 |
++}) |
29809 |
++ |
29810 |
++enum { |
29811 |
++ GR_DO_AUDIT, |
29812 |
++ GR_DONT_AUDIT, |
29813 |
++ GR_DONT_AUDIT_GOOD |
29814 |
++}; |
29815 |
++ |
29816 |
++enum { |
29817 |
++ GR_TTYSNIFF, |
29818 |
++ GR_RBAC, |
29819 |
++ GR_RBAC_STR, |
29820 |
++ GR_STR_RBAC, |
29821 |
++ GR_RBAC_MODE2, |
29822 |
++ GR_RBAC_MODE3, |
29823 |
++ GR_FILENAME, |
29824 |
++ GR_SYSCTL_HIDDEN, |
29825 |
++ GR_NOARGS, |
29826 |
++ GR_ONE_INT, |
29827 |
++ GR_ONE_INT_TWO_STR, |
29828 |
++ GR_ONE_STR, |
29829 |
++ GR_STR_INT, |
29830 |
++ GR_TWO_INT, |
29831 |
++ GR_THREE_INT, |
29832 |
++ GR_FIVE_INT_TWO_STR, |
29833 |
++ GR_TWO_STR, |
29834 |
++ GR_THREE_STR, |
29835 |
++ GR_FOUR_STR, |
29836 |
++ GR_STR_FILENAME, |
29837 |
++ GR_FILENAME_STR, |
29838 |
++ GR_FILENAME_TWO_INT, |
29839 |
++ GR_FILENAME_TWO_INT_STR, |
29840 |
++ GR_TEXTREL, |
29841 |
++ GR_PTRACE, |
29842 |
++ GR_RESOURCE, |
29843 |
++ GR_CAP, |
29844 |
++ GR_SIG, |
29845 |
++ GR_CRASH1, |
29846 |
++ GR_CRASH2, |
29847 |
++ GR_PSACCT |
29848 |
++}; |
29849 |
++ |
29850 |
++#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str) |
29851 |
++#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task) |
29852 |
++#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt) |
29853 |
++#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str) |
29854 |
++#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt) |
29855 |
++#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2) |
29856 |
++#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) |
29857 |
++#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt) |
29858 |
++#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS) |
29859 |
++#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num) |
29860 |
++#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2) |
29861 |
++#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str) |
29862 |
++#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num) |
29863 |
++#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2) |
29864 |
++#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3) |
29865 |
++#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) |
29866 |
++#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2) |
29867 |
++#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3) |
29868 |
++#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4) |
29869 |
++#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt) |
29870 |
++#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str) |
29871 |
++#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2) |
29872 |
++#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) |
29873 |
++#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2) |
29874 |
++#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task) |
29875 |
++#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2) |
29876 |
++#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str) |
29877 |
++#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num) |
29878 |
++#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong) |
29879 |
++#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1) |
29880 |
++#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) |
29881 |
++ |
29882 |
++void gr_log_varargs(int audit, const char *msg, int argtypes, ...); |
29883 |
++ |
29884 |
++#endif |
29885 |
++ |
29886 |
++#endif |
29887 |
+diff -Nurp linux-2.6.23.15/include/linux/grmsg.h linux-2.6.23.15-grsec/include/linux/grmsg.h |
29888 |
+--- linux-2.6.23.15/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100 |
29889 |
++++ linux-2.6.23.15-grsec/include/linux/grmsg.h 2008-02-11 10:37:45.000000000 +0000 |
29890 |
+@@ -0,0 +1,108 @@ |
29891 |
++#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" |
29892 |
++#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" |
29893 |
++#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " |
29894 |
++#define GR_STOPMOD_MSG "denied modification of module state by " |
29895 |
++#define GR_IOPERM_MSG "denied use of ioperm() by " |
29896 |
++#define GR_IOPL_MSG "denied use of iopl() by " |
29897 |
++#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " |
29898 |
++#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by " |
29899 |
++#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " |
29900 |
++#define GR_KMEM_MSG "denied write of /dev/kmem by " |
29901 |
++#define GR_PORT_OPEN_MSG "denied open of /dev/port by " |
29902 |
++#define GR_MEM_WRITE_MSG "denied write of /dev/mem by " |
29903 |
++#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by " |
29904 |
++#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " |
29905 |
++#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" |
29906 |
++#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" |
29907 |
++#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " |
29908 |
++#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " |
29909 |
++#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " |
29910 |
++#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " |
29911 |
++#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by " |
29912 |
++#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " |
29913 |
++#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by " |
29914 |
++#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against " |
29915 |
++#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " |
29916 |
++#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " |
29917 |
++#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " |
29918 |
++#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " |
29919 |
++#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " |
29920 |
++#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " |
29921 |
++#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " |
29922 |
++#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " |
29923 |
++#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " |
29924 |
++#define GR_NPROC_MSG "denied overstep of process limit by " |
29925 |
++#define GR_EXEC_ACL_MSG "%s execution of %.950s by " |
29926 |
++#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " |
29927 |
++#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds" |
29928 |
++#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds" |
29929 |
++#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by " |
29930 |
++#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by " |
29931 |
++#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " |
29932 |
++#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " |
29933 |
++#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " |
29934 |
++#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by " |
29935 |
++#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " |
29936 |
++#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by " |
29937 |
++#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " |
29938 |
++#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by " |
29939 |
++#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " |
29940 |
++#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " |
29941 |
++#define GR_INITF_ACL_MSG "init_variables() failed %s by " |
29942 |
++#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" |
29943 |
++#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by " |
29944 |
++#define GR_SHUTS_ACL_MSG "shutdown auth success for " |
29945 |
++#define GR_SHUTF_ACL_MSG "shutdown auth failure for " |
29946 |
++#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " |
29947 |
++#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " |
29948 |
++#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " |
29949 |
++#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " |
29950 |
++#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by " |
29951 |
++#define GR_ENABLEF_ACL_MSG "unable to load %s for " |
29952 |
++#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system" |
29953 |
++#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by " |
29954 |
++#define GR_RELOADF_ACL_MSG "failed reload of %s for " |
29955 |
++#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for " |
29956 |
++#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " |
29957 |
++#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " |
29958 |
++#define GR_SPROLEF_ACL_MSG "special role %s failure for " |
29959 |
++#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for " |
29960 |
++#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " |
29961 |
++#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " |
29962 |
++#define GR_INVMODE_ACL_MSG "invalid mode %d by " |
29963 |
++#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by " |
29964 |
++#define GR_FAILFORK_MSG "failed fork with errno %d by " |
29965 |
++#define GR_NICE_CHROOT_MSG "denied priority change by " |
29966 |
++#define GR_UNISIGLOG_MSG "signal %d sent to " |
29967 |
++#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " |
29968 |
++#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by " |
29969 |
++#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by " |
29970 |
++#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " |
29971 |
++#define GR_TIME_MSG "time set by " |
29972 |
++#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by " |
29973 |
++#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " |
29974 |
++#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " |
29975 |
++#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by " |
29976 |
++#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by " |
29977 |
++#define GR_BIND_MSG "denied bind() by " |
29978 |
++#define GR_CONNECT_MSG "denied connect() by " |
29979 |
++#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " |
29980 |
++#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " |
29981 |
++#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" |
29982 |
++#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " |
29983 |
++#define GR_CAP_ACL_MSG "use of %s denied for " |
29984 |
++#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for " |
29985 |
++#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for " |
29986 |
++#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " |
29987 |
++#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " |
29988 |
++#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by " |
29989 |
++#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " |
29990 |
++#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by " |
29991 |
++#define GR_MSGQ_AUDIT_MSG "message queue created by " |
29992 |
++#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by " |
29993 |
++#define GR_SEM_AUDIT_MSG "semaphore created by " |
29994 |
++#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by " |
29995 |
++#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " |
29996 |
++#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by " |
29997 |
++#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for " |
29998 |
++#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by " |
29999 |
+diff -Nurp linux-2.6.23.15/include/linux/grsecurity.h linux-2.6.23.15-grsec/include/linux/grsecurity.h |
30000 |
+--- linux-2.6.23.15/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100 |
30001 |
++++ linux-2.6.23.15-grsec/include/linux/grsecurity.h 2008-02-11 10:37:45.000000000 +0000 |
30002 |
+@@ -0,0 +1,193 @@ |
30003 |
++#ifndef GR_SECURITY_H |
30004 |
++#define GR_SECURITY_H |
30005 |
++#include <linux/fs.h> |
30006 |
++#include <linux/binfmts.h> |
30007 |
++#include <linux/gracl.h> |
30008 |
++ |
30009 |
++void gr_handle_brute_attach(struct task_struct *p); |
30010 |
++void gr_handle_brute_check(void); |
30011 |
++ |
30012 |
++char gr_roletype_to_char(void); |
30013 |
++ |
30014 |
++int gr_check_user_change(int real, int effective, int fs); |
30015 |
++int gr_check_group_change(int real, int effective, int fs); |
30016 |
++ |
30017 |
++void gr_del_task_from_ip_table(struct task_struct *p); |
30018 |
++ |
30019 |
++int gr_pid_is_chrooted(struct task_struct *p); |
30020 |
++int gr_handle_chroot_nice(void); |
30021 |
++int gr_handle_chroot_sysctl(const int op); |
30022 |
++int gr_handle_chroot_setpriority(struct task_struct *p, |
30023 |
++ const int niceval); |
30024 |
++int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt); |
30025 |
++int gr_handle_chroot_chroot(const struct dentry *dentry, |
30026 |
++ const struct vfsmount *mnt); |
30027 |
++void gr_handle_chroot_caps(struct task_struct *task); |
30028 |
++void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt); |
30029 |
++int gr_handle_chroot_chmod(const struct dentry *dentry, |
30030 |
++ const struct vfsmount *mnt, const int mode); |
30031 |
++int gr_handle_chroot_mknod(const struct dentry *dentry, |
30032 |
++ const struct vfsmount *mnt, const int mode); |
30033 |
++int gr_handle_chroot_mount(const struct dentry *dentry, |
30034 |
++ const struct vfsmount *mnt, |
30035 |
++ const char *dev_name); |
30036 |
++int gr_handle_chroot_pivot(void); |
30037 |
++int gr_handle_chroot_unix(const pid_t pid); |
30038 |
++ |
30039 |
++int gr_handle_rawio(const struct inode *inode); |
30040 |
++int gr_handle_nproc(void); |
30041 |
++ |
30042 |
++void gr_handle_ioperm(void); |
30043 |
++void gr_handle_iopl(void); |
30044 |
++ |
30045 |
++int gr_tpe_allow(const struct file *file); |
30046 |
++ |
30047 |
++int gr_random_pid(void); |
30048 |
++ |
30049 |
++void gr_log_forkfail(const int retval); |
30050 |
++void gr_log_timechange(void); |
30051 |
++void gr_log_signal(const int sig, const struct task_struct *t); |
30052 |
++void gr_log_chdir(const struct dentry *dentry, |
30053 |
++ const struct vfsmount *mnt); |
30054 |
++void gr_log_chroot_exec(const struct dentry *dentry, |
30055 |
++ const struct vfsmount *mnt); |
30056 |
++void gr_handle_exec_args(struct linux_binprm *bprm, char **argv); |
30057 |
++void gr_log_remount(const char *devname, const int retval); |
30058 |
++void gr_log_unmount(const char *devname, const int retval); |
30059 |
++void gr_log_mount(const char *from, const char *to, const int retval); |
30060 |
++void gr_log_msgget(const int ret, const int msgflg); |
30061 |
++void gr_log_msgrm(const uid_t uid, const uid_t cuid); |
30062 |
++void gr_log_semget(const int err, const int semflg); |
30063 |
++void gr_log_semrm(const uid_t uid, const uid_t cuid); |
30064 |
++void gr_log_shmget(const int err, const int shmflg, const size_t size); |
30065 |
++void gr_log_shmrm(const uid_t uid, const uid_t cuid); |
30066 |
++void gr_log_textrel(struct vm_area_struct *vma); |
30067 |
++ |
30068 |
++int gr_handle_follow_link(const struct inode *parent, |
30069 |
++ const struct inode *inode, |
30070 |
++ const struct dentry *dentry, |
30071 |
++ const struct vfsmount *mnt); |
30072 |
++int gr_handle_fifo(const struct dentry *dentry, |
30073 |
++ const struct vfsmount *mnt, |
30074 |
++ const struct dentry *dir, const int flag, |
30075 |
++ const int acc_mode); |
30076 |
++int gr_handle_hardlink(const struct dentry *dentry, |
30077 |
++ const struct vfsmount *mnt, |
30078 |
++ struct inode *inode, |
30079 |
++ const int mode, const char *to); |
30080 |
++ |
30081 |
++int gr_task_is_capable(struct task_struct *task, const int cap); |
30082 |
++int gr_is_capable_nolog(const int cap); |
30083 |
++void gr_learn_resource(const struct task_struct *task, const int limit, |
30084 |
++ const unsigned long wanted, const int gt); |
30085 |
++void gr_copy_label(struct task_struct *tsk); |
30086 |
++void gr_handle_crash(struct task_struct *task, const int sig); |
30087 |
++int gr_handle_signal(const struct task_struct *p, const int sig); |
30088 |
++int gr_check_crash_uid(const uid_t uid); |
30089 |
++int gr_check_protected_task(const struct task_struct *task); |
30090 |
++int gr_acl_handle_mmap(const struct file *file, |
30091 |
++ const unsigned long prot); |
30092 |
++int gr_acl_handle_mprotect(const struct file *file, |
30093 |
++ const unsigned long prot); |
30094 |
++int gr_check_hidden_task(const struct task_struct *tsk); |
30095 |
++__u32 gr_acl_handle_truncate(const struct dentry *dentry, |
30096 |
++ const struct vfsmount *mnt); |
30097 |
++__u32 gr_acl_handle_utime(const struct dentry *dentry, |
30098 |
++ const struct vfsmount *mnt); |
30099 |
++__u32 gr_acl_handle_access(const struct dentry *dentry, |
30100 |
++ const struct vfsmount *mnt, const int fmode); |
30101 |
++__u32 gr_acl_handle_fchmod(const struct dentry *dentry, |
30102 |
++ const struct vfsmount *mnt, mode_t mode); |
30103 |
++__u32 gr_acl_handle_chmod(const struct dentry *dentry, |
30104 |
++ const struct vfsmount *mnt, mode_t mode); |
30105 |
++__u32 gr_acl_handle_chown(const struct dentry *dentry, |
30106 |
++ const struct vfsmount *mnt); |
30107 |
++int gr_handle_ptrace(struct task_struct *task, const long request); |
30108 |
++int gr_handle_proc_ptrace(struct task_struct *task); |
30109 |
++__u32 gr_acl_handle_execve(const struct dentry *dentry, |
30110 |
++ const struct vfsmount *mnt); |
30111 |
++int gr_check_crash_exec(const struct file *filp); |
30112 |
++int gr_acl_is_enabled(void); |
30113 |
++void gr_set_kernel_label(struct task_struct *task); |
30114 |
++void gr_set_role_label(struct task_struct *task, const uid_t uid, |
30115 |
++ const gid_t gid); |
30116 |
++int gr_set_proc_label(const struct dentry *dentry, |
30117 |
++ const struct vfsmount *mnt); |
30118 |
++__u32 gr_acl_handle_hidden_file(const struct dentry *dentry, |
30119 |
++ const struct vfsmount *mnt); |
30120 |
++__u32 gr_acl_handle_open(const struct dentry *dentry, |
30121 |
++ const struct vfsmount *mnt, const int fmode); |
30122 |
++__u32 gr_acl_handle_creat(const struct dentry *dentry, |
30123 |
++ const struct dentry *p_dentry, |
30124 |
++ const struct vfsmount *p_mnt, const int fmode, |
30125 |
++ const int imode); |
30126 |
++void gr_handle_create(const struct dentry *dentry, |
30127 |
++ const struct vfsmount *mnt); |
30128 |
++__u32 gr_acl_handle_mknod(const struct dentry *new_dentry, |
30129 |
++ const struct dentry *parent_dentry, |
30130 |
++ const struct vfsmount *parent_mnt, |
30131 |
++ const int mode); |
30132 |
++__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry, |
30133 |
++ const struct dentry *parent_dentry, |
30134 |
++ const struct vfsmount *parent_mnt); |
30135 |
++__u32 gr_acl_handle_rmdir(const struct dentry *dentry, |
30136 |
++ const struct vfsmount *mnt); |
30137 |
++void gr_handle_delete(const ino_t ino, const dev_t dev); |
30138 |
++__u32 gr_acl_handle_unlink(const struct dentry *dentry, |
30139 |
++ const struct vfsmount *mnt); |
30140 |
++__u32 gr_acl_handle_symlink(const struct dentry *new_dentry, |
30141 |
++ const struct dentry *parent_dentry, |
30142 |
++ const struct vfsmount *parent_mnt, |
30143 |
++ const char *from); |
30144 |
++__u32 gr_acl_handle_link(const struct dentry *new_dentry, |
30145 |
++ const struct dentry *parent_dentry, |
30146 |
++ const struct vfsmount *parent_mnt, |
30147 |
++ const struct dentry *old_dentry, |
30148 |
++ const struct vfsmount *old_mnt, const char *to); |
30149 |
++int gr_acl_handle_rename(struct dentry *new_dentry, |
30150 |
++ struct dentry *parent_dentry, |
30151 |
++ const struct vfsmount *parent_mnt, |
30152 |
++ struct dentry *old_dentry, |
30153 |
++ struct inode *old_parent_inode, |
30154 |
++ struct vfsmount *old_mnt, const char *newname); |
30155 |
++void gr_handle_rename(struct inode *old_dir, struct inode *new_dir, |
30156 |
++ struct dentry *old_dentry, |
30157 |
++ struct dentry *new_dentry, |
30158 |
++ struct vfsmount *mnt, const __u8 replace); |
30159 |
++__u32 gr_check_link(const struct dentry *new_dentry, |
30160 |
++ const struct dentry *parent_dentry, |
30161 |
++ const struct vfsmount *parent_mnt, |
30162 |
++ const struct dentry *old_dentry, |
30163 |
++ const struct vfsmount *old_mnt); |
30164 |
++int gr_acl_handle_filldir(const struct file *file, const char *name, |
30165 |
++ const unsigned int namelen, const ino_t ino); |
30166 |
++ |
30167 |
++__u32 gr_acl_handle_unix(const struct dentry *dentry, |
30168 |
++ const struct vfsmount *mnt); |
30169 |
++void gr_acl_handle_exit(void); |
30170 |
++void gr_acl_handle_psacct(struct task_struct *task, const long code); |
30171 |
++int gr_acl_handle_procpidmem(const struct task_struct *task); |
30172 |
++__u32 gr_cap_rtnetlink(void); |
30173 |
++ |
30174 |
++#ifdef CONFIG_SYSVIPC |
30175 |
++void gr_shm_exit(struct task_struct *task); |
30176 |
++#else |
30177 |
++static inline void gr_shm_exit(struct task_struct *task) |
30178 |
++{ |
30179 |
++ return; |
30180 |
++} |
30181 |
++#endif |
30182 |
++ |
30183 |
++#ifdef CONFIG_GRKERNSEC |
30184 |
++void gr_handle_mem_write(void); |
30185 |
++void gr_handle_kmem_write(void); |
30186 |
++void gr_handle_open_port(void); |
30187 |
++int gr_handle_mem_mmap(const unsigned long offset, |
30188 |
++ struct vm_area_struct *vma); |
30189 |
++ |
30190 |
++extern int grsec_enable_dmesg; |
30191 |
++extern int grsec_enable_randsrc; |
30192 |
++extern int grsec_enable_shm; |
30193 |
++#endif |
30194 |
++ |
30195 |
++#endif |
30196 |
+diff -Nurp linux-2.6.23.15/include/linux/highmem.h linux-2.6.23.15-grsec/include/linux/highmem.h |
30197 |
+--- linux-2.6.23.15/include/linux/highmem.h 2007-10-09 21:31:38.000000000 +0100 |
30198 |
++++ linux-2.6.23.15-grsec/include/linux/highmem.h 2008-02-11 10:37:45.000000000 +0000 |
30199 |
+@@ -124,6 +124,13 @@ static inline void clear_highpage(struct |
30200 |
+ kunmap_atomic(kaddr, KM_USER0); |
30201 |
+ } |
30202 |
+ |
30203 |
++static inline void sanitize_highpage(struct page *page) |
30204 |
++{ |
30205 |
++ void *kaddr = kmap_atomic(page, KM_CLEARPAGE); |
30206 |
++ clear_page(kaddr); |
30207 |
++ kunmap_atomic(kaddr, KM_CLEARPAGE); |
30208 |
++} |
30209 |
++ |
30210 |
+ /* |
30211 |
+ * Same but also flushes aliased cache contents to RAM. |
30212 |
+ * |
30213 |
+@@ -132,14 +139,14 @@ static inline void clear_highpage(struct |
30214 |
+ */ |
30215 |
+ #define zero_user_page(page, offset, size, km_type) \ |
30216 |
+ do { \ |
30217 |
+- void *kaddr; \ |
30218 |
++ void *__kaddr; \ |
30219 |
+ \ |
30220 |
+ BUG_ON((offset) + (size) > PAGE_SIZE); \ |
30221 |
+ \ |
30222 |
+- kaddr = kmap_atomic(page, km_type); \ |
30223 |
+- memset((char *)kaddr + (offset), 0, (size)); \ |
30224 |
++ __kaddr = kmap_atomic(page, km_type); \ |
30225 |
++ memset((char *)__kaddr + (offset), 0, (size)); \ |
30226 |
+ flush_dcache_page(page); \ |
30227 |
+- kunmap_atomic(kaddr, (km_type)); \ |
30228 |
++ kunmap_atomic(__kaddr, (km_type)); \ |
30229 |
+ } while (0) |
30230 |
+ |
30231 |
+ static inline void __deprecated memclear_highpage_flush(struct page *page, |
30232 |
+diff -Nurp linux-2.6.23.15/include/linux/irqflags.h linux-2.6.23.15-grsec/include/linux/irqflags.h |
30233 |
+--- linux-2.6.23.15/include/linux/irqflags.h 2007-10-09 21:31:38.000000000 +0100 |
30234 |
++++ linux-2.6.23.15-grsec/include/linux/irqflags.h 2008-02-11 10:37:45.000000000 +0000 |
30235 |
+@@ -84,10 +84,10 @@ |
30236 |
+ |
30237 |
+ #define irqs_disabled() \ |
30238 |
+ ({ \ |
30239 |
+- unsigned long flags; \ |
30240 |
++ unsigned long __flags; \ |
30241 |
+ \ |
30242 |
+- raw_local_save_flags(flags); \ |
30243 |
+- raw_irqs_disabled_flags(flags); \ |
30244 |
++ raw_local_save_flags(__flags); \ |
30245 |
++ raw_irqs_disabled_flags(__flags); \ |
30246 |
+ }) |
30247 |
+ |
30248 |
+ #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) |
30249 |
+diff -Nurp linux-2.6.23.15/include/linux/jbd.h linux-2.6.23.15-grsec/include/linux/jbd.h |
30250 |
+--- linux-2.6.23.15/include/linux/jbd.h 2007-10-09 21:31:38.000000000 +0100 |
30251 |
++++ linux-2.6.23.15-grsec/include/linux/jbd.h 2008-02-11 10:37:45.000000000 +0000 |
30252 |
+@@ -68,7 +68,7 @@ extern int journal_enable_debug; |
30253 |
+ } \ |
30254 |
+ } while (0) |
30255 |
+ #else |
30256 |
+-#define jbd_debug(f, a...) /**/ |
30257 |
++#define jbd_debug(f, a...) do {} while (0) |
30258 |
+ #endif |
30259 |
+ |
30260 |
+ extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry); |
30261 |
+diff -Nurp linux-2.6.23.15/include/linux/jbd2.h linux-2.6.23.15-grsec/include/linux/jbd2.h |
30262 |
+--- linux-2.6.23.15/include/linux/jbd2.h 2007-10-09 21:31:38.000000000 +0100 |
30263 |
++++ linux-2.6.23.15-grsec/include/linux/jbd2.h 2008-02-11 10:37:45.000000000 +0000 |
30264 |
+@@ -68,7 +68,7 @@ extern u8 jbd2_journal_enable_debug; |
30265 |
+ } \ |
30266 |
+ } while (0) |
30267 |
+ #else |
30268 |
+-#define jbd_debug(f, a...) /**/ |
30269 |
++#define jbd_debug(f, a...) do {} while (0) |
30270 |
+ #endif |
30271 |
+ |
30272 |
+ extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry); |
30273 |
+diff -Nurp linux-2.6.23.15/include/linux/libata.h linux-2.6.23.15-grsec/include/linux/libata.h |
30274 |
+--- linux-2.6.23.15/include/linux/libata.h 2008-02-11 10:36:03.000000000 +0000 |
30275 |
++++ linux-2.6.23.15-grsec/include/linux/libata.h 2008-02-11 10:37:45.000000000 +0000 |
30276 |
+@@ -63,11 +63,11 @@ |
30277 |
+ #ifdef ATA_VERBOSE_DEBUG |
30278 |
+ #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) |
30279 |
+ #else |
30280 |
+-#define VPRINTK(fmt, args...) |
30281 |
++#define VPRINTK(fmt, args...) do {} while (0) |
30282 |
+ #endif /* ATA_VERBOSE_DEBUG */ |
30283 |
+ #else |
30284 |
+-#define DPRINTK(fmt, args...) |
30285 |
+-#define VPRINTK(fmt, args...) |
30286 |
++#define DPRINTK(fmt, args...) do {} while (0) |
30287 |
++#define VPRINTK(fmt, args...) do {} while (0) |
30288 |
+ #endif /* ATA_DEBUG */ |
30289 |
+ |
30290 |
+ #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) |
30291 |
+diff -Nurp linux-2.6.23.15/include/linux/mm.h linux-2.6.23.15-grsec/include/linux/mm.h |
30292 |
+--- linux-2.6.23.15/include/linux/mm.h 2007-10-09 21:31:38.000000000 +0100 |
30293 |
++++ linux-2.6.23.15-grsec/include/linux/mm.h 2008-02-11 10:37:45.000000000 +0000 |
30294 |
+@@ -38,6 +38,7 @@ extern int sysctl_legacy_va_layout; |
30295 |
+ #include <asm/page.h> |
30296 |
+ #include <asm/pgtable.h> |
30297 |
+ #include <asm/processor.h> |
30298 |
++#include <asm/mman.h> |
30299 |
+ |
30300 |
+ #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) |
30301 |
+ |
30302 |
+@@ -111,6 +112,8 @@ struct vm_area_struct { |
30303 |
+ #ifdef CONFIG_NUMA |
30304 |
+ struct mempolicy *vm_policy; /* NUMA policy for the VMA */ |
30305 |
+ #endif |
30306 |
++ |
30307 |
++ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */ |
30308 |
+ }; |
30309 |
+ |
30310 |
+ extern struct kmem_cache *vm_area_cachep; |
30311 |
+@@ -171,6 +174,14 @@ extern unsigned int kobjsize(const void |
30312 |
+ |
30313 |
+ #define VM_CAN_NONLINEAR 0x08000000 /* Has ->fault & does nonlinear pages */ |
30314 |
+ |
30315 |
++#ifdef CONFIG_PAX_PAGEEXEC |
30316 |
++#define VM_PAGEEXEC 0x10000000 /* vma->vm_page_prot needs special handling */ |
30317 |
++#endif |
30318 |
++ |
30319 |
++#ifdef CONFIG_PAX_MPROTECT |
30320 |
++#define VM_MAYNOTWRITE 0x20000000 /* vma cannot be granted VM_WRITE any more */ |
30321 |
++#endif |
30322 |
++ |
30323 |
+ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ |
30324 |
+ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS |
30325 |
+ #endif |
30326 |
+@@ -862,6 +873,8 @@ struct shrinker { |
30327 |
+ extern void register_shrinker(struct shrinker *); |
30328 |
+ extern void unregister_shrinker(struct shrinker *); |
30329 |
+ |
30330 |
++pgprot_t vm_get_page_prot(unsigned long vm_flags); |
30331 |
++ |
30332 |
+ int vma_wants_writenotify(struct vm_area_struct *vma); |
30333 |
+ |
30334 |
+ extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)); |
30335 |
+@@ -1088,6 +1101,7 @@ out: |
30336 |
+ } |
30337 |
+ |
30338 |
+ extern int do_munmap(struct mm_struct *, unsigned long, size_t); |
30339 |
++extern int __do_munmap(struct mm_struct *, unsigned long, size_t); |
30340 |
+ |
30341 |
+ extern unsigned long do_brk(unsigned long, unsigned long); |
30342 |
+ |
30343 |
+@@ -1142,6 +1156,10 @@ extern struct vm_area_struct * find_vma( |
30344 |
+ extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, |
30345 |
+ struct vm_area_struct **pprev); |
30346 |
+ |
30347 |
++extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma); |
30348 |
++extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma); |
30349 |
++extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl); |
30350 |
++ |
30351 |
+ /* Look up the first VMA which intersects the interval start_addr..end_addr-1, |
30352 |
+ NULL if none. Assume start_addr < end_addr. */ |
30353 |
+ static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) |
30354 |
+@@ -1158,7 +1176,6 @@ static inline unsigned long vma_pages(st |
30355 |
+ return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
30356 |
+ } |
30357 |
+ |
30358 |
+-pgprot_t vm_get_page_prot(unsigned long vm_flags); |
30359 |
+ struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr); |
30360 |
+ struct page *vmalloc_to_page(void *addr); |
30361 |
+ unsigned long vmalloc_to_pfn(void *addr); |
30362 |
+@@ -1218,5 +1235,11 @@ extern int randomize_va_space; |
30363 |
+ |
30364 |
+ const char * arch_vma_name(struct vm_area_struct *vma); |
30365 |
+ |
30366 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
30367 |
++extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot); |
30368 |
++#else |
30369 |
++static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {} |
30370 |
++#endif |
30371 |
++ |
30372 |
+ #endif /* __KERNEL__ */ |
30373 |
+ #endif /* _LINUX_MM_H */ |
30374 |
+diff -Nurp linux-2.6.23.15/include/linux/module.h linux-2.6.23.15-grsec/include/linux/module.h |
30375 |
+--- linux-2.6.23.15/include/linux/module.h 2007-10-09 21:31:38.000000000 +0100 |
30376 |
++++ linux-2.6.23.15-grsec/include/linux/module.h 2008-02-11 10:37:45.000000000 +0000 |
30377 |
+@@ -295,16 +295,16 @@ struct module |
30378 |
+ int (*init)(void); |
30379 |
+ |
30380 |
+ /* If this is non-NULL, vfree after init() returns */ |
30381 |
+- void *module_init; |
30382 |
++ void *module_init_rx, *module_init_rw; |
30383 |
+ |
30384 |
+ /* Here is the actual code + data, vfree'd on unload. */ |
30385 |
+- void *module_core; |
30386 |
++ void *module_core_rx, *module_core_rw; |
30387 |
+ |
30388 |
+ /* Here are the sizes of the init and core sections */ |
30389 |
+- unsigned long init_size, core_size; |
30390 |
++ unsigned long init_size_rw, core_size_rw; |
30391 |
+ |
30392 |
+ /* The size of the executable code in each section. */ |
30393 |
+- unsigned long init_text_size, core_text_size; |
30394 |
++ unsigned long init_size_rx, core_size_rx; |
30395 |
+ |
30396 |
+ /* The handle returned from unwind_add_table. */ |
30397 |
+ void *unwind_info; |
30398 |
+diff -Nurp linux-2.6.23.15/include/linux/moduleloader.h linux-2.6.23.15-grsec/include/linux/moduleloader.h |
30399 |
+--- linux-2.6.23.15/include/linux/moduleloader.h 2007-10-09 21:31:38.000000000 +0100 |
30400 |
++++ linux-2.6.23.15-grsec/include/linux/moduleloader.h 2008-02-11 10:37:45.000000000 +0000 |
30401 |
+@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr * |
30402 |
+ sections. Returns NULL on failure. */ |
30403 |
+ void *module_alloc(unsigned long size); |
30404 |
+ |
30405 |
++#ifdef CONFIG_PAX_KERNEXEC |
30406 |
++void *module_alloc_exec(unsigned long size); |
30407 |
++#else |
30408 |
++#define module_alloc_exec(x) module_alloc(x) |
30409 |
++#endif |
30410 |
++ |
30411 |
+ /* Free memory returned from module_alloc. */ |
30412 |
+ void module_free(struct module *mod, void *module_region); |
30413 |
+ |
30414 |
++#ifdef CONFIG_PAX_KERNEXEC |
30415 |
++void module_free_exec(struct module *mod, void *module_region); |
30416 |
++#else |
30417 |
++#define module_free_exec(x, y) module_free(x, y) |
30418 |
++#endif |
30419 |
++ |
30420 |
+ /* Apply the given relocation to the (simplified) ELF. Return -error |
30421 |
+ or 0. */ |
30422 |
+ int apply_relocate(Elf_Shdr *sechdrs, |
30423 |
+diff -Nurp linux-2.6.23.15/include/linux/percpu.h linux-2.6.23.15-grsec/include/linux/percpu.h |
30424 |
+--- linux-2.6.23.15/include/linux/percpu.h 2007-10-09 21:31:38.000000000 +0100 |
30425 |
++++ linux-2.6.23.15-grsec/include/linux/percpu.h 2008-02-11 10:37:45.000000000 +0000 |
30426 |
+@@ -18,7 +18,7 @@ |
30427 |
+ #endif |
30428 |
+ |
30429 |
+ #define PERCPU_ENOUGH_ROOM \ |
30430 |
+- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE) |
30431 |
++ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)) |
30432 |
+ #endif /* PERCPU_ENOUGH_ROOM */ |
30433 |
+ |
30434 |
+ /* |
30435 |
+diff -Nurp linux-2.6.23.15/include/linux/random.h linux-2.6.23.15-grsec/include/linux/random.h |
30436 |
+--- linux-2.6.23.15/include/linux/random.h 2007-10-09 21:31:38.000000000 +0100 |
30437 |
++++ linux-2.6.23.15-grsec/include/linux/random.h 2008-02-11 10:37:45.000000000 +0000 |
30438 |
+@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l |
30439 |
+ u32 random32(void); |
30440 |
+ void srandom32(u32 seed); |
30441 |
+ |
30442 |
++static inline unsigned long pax_get_random_long(void) |
30443 |
++{ |
30444 |
++ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0); |
30445 |
++} |
30446 |
++ |
30447 |
+ #endif /* __KERNEL___ */ |
30448 |
+ |
30449 |
+ #endif /* _LINUX_RANDOM_H */ |
30450 |
+diff -Nurp linux-2.6.23.15/include/linux/sched.h linux-2.6.23.15-grsec/include/linux/sched.h |
30451 |
+--- linux-2.6.23.15/include/linux/sched.h 2008-02-11 10:36:03.000000000 +0000 |
30452 |
++++ linux-2.6.23.15-grsec/include/linux/sched.h 2008-02-11 10:37:45.000000000 +0000 |
30453 |
+@@ -92,6 +92,7 @@ struct sched_param { |
30454 |
+ struct exec_domain; |
30455 |
+ struct futex_pi_state; |
30456 |
+ struct bio; |
30457 |
++struct linux_binprm; |
30458 |
+ |
30459 |
+ /* |
30460 |
+ * List of flags we want to share for kernel threads, |
30461 |
+@@ -432,6 +433,24 @@ struct mm_struct { |
30462 |
+ /* aio bits */ |
30463 |
+ rwlock_t ioctx_list_lock; |
30464 |
+ struct kioctx *ioctx_list; |
30465 |
++ |
30466 |
++#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
30467 |
++ unsigned long pax_flags; |
30468 |
++#endif |
30469 |
++ |
30470 |
++#ifdef CONFIG_PAX_DLRESOLVE |
30471 |
++ unsigned long call_dl_resolve; |
30472 |
++#endif |
30473 |
++ |
30474 |
++#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) |
30475 |
++ unsigned long call_syscall; |
30476 |
++#endif |
30477 |
++ |
30478 |
++#ifdef CONFIG_PAX_ASLR |
30479 |
++ unsigned long delta_mmap; /* randomized offset */ |
30480 |
++ unsigned long delta_stack; /* randomized offset */ |
30481 |
++#endif |
30482 |
++ |
30483 |
+ }; |
30484 |
+ |
30485 |
+ struct sighand_struct { |
30486 |
+@@ -556,6 +575,15 @@ struct signal_struct { |
30487 |
+ unsigned audit_tty; |
30488 |
+ struct tty_audit_buf *tty_audit_buf; |
30489 |
+ #endif |
30490 |
++ |
30491 |
++#ifdef CONFIG_GRKERNSEC |
30492 |
++ u32 curr_ip; |
30493 |
++ u32 gr_saddr; |
30494 |
++ u32 gr_daddr; |
30495 |
++ u16 gr_sport; |
30496 |
++ u16 gr_dport; |
30497 |
++ u8 used_accept:1; |
30498 |
++#endif |
30499 |
+ }; |
30500 |
+ |
30501 |
+ /* Context switch must be unlocked if interrupts are to be enabled */ |
30502 |
+@@ -1017,8 +1045,8 @@ struct task_struct { |
30503 |
+ struct list_head thread_group; |
30504 |
+ |
30505 |
+ struct completion *vfork_done; /* for vfork() */ |
30506 |
+- int __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
30507 |
+- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
30508 |
++ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */ |
30509 |
++ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ |
30510 |
+ |
30511 |
+ unsigned int rt_priority; |
30512 |
+ cputime_t utime, stime; |
30513 |
+@@ -1183,6 +1211,17 @@ struct task_struct { |
30514 |
+ struct list_head pi_state_list; |
30515 |
+ struct futex_pi_state *pi_state_cache; |
30516 |
+ |
30517 |
++#ifdef CONFIG_GRKERNSEC |
30518 |
++ /* grsecurity */ |
30519 |
++ struct acl_subject_label *acl; |
30520 |
++ struct acl_role_label *role; |
30521 |
++ struct file *exec_file; |
30522 |
++ u16 acl_role_id; |
30523 |
++ u8 acl_sp_role:1; |
30524 |
++ u8 is_writable:1; |
30525 |
++ u8 brute:1; |
30526 |
++#endif |
30527 |
++ |
30528 |
+ atomic_t fs_excl; /* holding fs exclusive resources */ |
30529 |
+ struct rcu_head rcu; |
30530 |
+ |
30531 |
+@@ -1198,6 +1237,46 @@ struct task_struct { |
30532 |
+ #endif |
30533 |
+ }; |
30534 |
+ |
30535 |
++#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */ |
30536 |
++#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */ |
30537 |
++#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */ |
30538 |
++#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */ |
30539 |
++/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */ |
30540 |
++#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */ |
30541 |
++ |
30542 |
++#ifdef CONFIG_PAX_SOFTMODE |
30543 |
++extern unsigned int pax_softmode; |
30544 |
++#endif |
30545 |
++ |
30546 |
++extern int pax_check_flags(unsigned long *); |
30547 |
++ |
30548 |
++/* if tsk != current then task_lock must be held on it */ |
30549 |
++#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) |
30550 |
++static inline unsigned long pax_get_flags(struct task_struct *tsk) |
30551 |
++{ |
30552 |
++ if (likely(tsk->mm)) |
30553 |
++ return tsk->mm->pax_flags; |
30554 |
++ else |
30555 |
++ return 0UL; |
30556 |
++} |
30557 |
++ |
30558 |
++/* if tsk != current then task_lock must be held on it */ |
30559 |
++static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags) |
30560 |
++{ |
30561 |
++ if (likely(tsk->mm)) { |
30562 |
++ tsk->mm->pax_flags = flags; |
30563 |
++ return 0; |
30564 |
++ } |
30565 |
++ return -EINVAL; |
30566 |
++} |
30567 |
++#endif |
30568 |
++ |
30569 |
++#ifdef CONFIG_PAX_HAVE_ACL_FLAGS |
30570 |
++extern void pax_set_initial_flags(struct linux_binprm *bprm); |
30571 |
++#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) |
30572 |
++extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); |
30573 |
++#endif |
30574 |
++ |
30575 |
+ /* |
30576 |
+ * Priority of a process goes from 0..MAX_PRIO-1, valid RT |
30577 |
+ * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH |
30578 |
+@@ -1831,6 +1910,12 @@ extern void arch_pick_mmap_layout(struct |
30579 |
+ static inline void arch_pick_mmap_layout(struct mm_struct *mm) |
30580 |
+ { |
30581 |
+ mm->mmap_base = TASK_UNMAPPED_BASE; |
30582 |
++ |
30583 |
++#ifdef CONFIG_PAX_RANDMMAP |
30584 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
30585 |
++ mm->mmap_base += mm->delta_mmap; |
30586 |
++#endif |
30587 |
++ |
30588 |
+ mm->get_unmapped_area = arch_get_unmapped_area; |
30589 |
+ mm->unmap_area = arch_unmap_area; |
30590 |
+ } |
30591 |
+diff -Nurp linux-2.6.23.15/include/linux/screen_info.h linux-2.6.23.15-grsec/include/linux/screen_info.h |
30592 |
+--- linux-2.6.23.15/include/linux/screen_info.h 2007-10-09 21:31:38.000000000 +0100 |
30593 |
++++ linux-2.6.23.15-grsec/include/linux/screen_info.h 2008-02-11 10:37:45.000000000 +0000 |
30594 |
+@@ -42,7 +42,8 @@ struct screen_info { |
30595 |
+ u16 pages; /* 0x32 */ |
30596 |
+ u16 vesa_attributes; /* 0x34 */ |
30597 |
+ u32 capabilities; /* 0x36 */ |
30598 |
+- u8 _reserved[6]; /* 0x3a */ |
30599 |
++ u16 vesapm_size; /* 0x3a */ |
30600 |
++ u8 _reserved[4]; /* 0x3c */ |
30601 |
+ } __attribute__((packed)); |
30602 |
+ |
30603 |
+ extern struct screen_info screen_info; |
30604 |
+diff -Nurp linux-2.6.23.15/include/linux/security.h linux-2.6.23.15-grsec/include/linux/security.h |
30605 |
+--- linux-2.6.23.15/include/linux/security.h 2007-10-09 21:31:38.000000000 +0100 |
30606 |
++++ linux-2.6.23.15-grsec/include/linux/security.h 2008-02-11 10:37:45.000000000 +0000 |
30607 |
+@@ -2796,7 +2796,7 @@ static inline struct dentry *securityfs_ |
30608 |
+ mode_t mode, |
30609 |
+ struct dentry *parent, |
30610 |
+ void *data, |
30611 |
+- struct file_operations *fops) |
30612 |
++ const struct file_operations *fops) |
30613 |
+ { |
30614 |
+ return ERR_PTR(-ENODEV); |
30615 |
+ } |
30616 |
+diff -Nurp linux-2.6.23.15/include/linux/shm.h linux-2.6.23.15-grsec/include/linux/shm.h |
30617 |
+--- linux-2.6.23.15/include/linux/shm.h 2007-10-09 21:31:38.000000000 +0100 |
30618 |
++++ linux-2.6.23.15-grsec/include/linux/shm.h 2008-02-11 10:37:45.000000000 +0000 |
30619 |
+@@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke |
30620 |
+ pid_t shm_cprid; |
30621 |
+ pid_t shm_lprid; |
30622 |
+ struct user_struct *mlock_user; |
30623 |
++#ifdef CONFIG_GRKERNSEC |
30624 |
++ time_t shm_createtime; |
30625 |
++ pid_t shm_lapid; |
30626 |
++#endif |
30627 |
+ }; |
30628 |
+ |
30629 |
+ /* shm_mode upper byte flags */ |
30630 |
+diff -Nurp linux-2.6.23.15/include/linux/skbuff.h linux-2.6.23.15-grsec/include/linux/skbuff.h |
30631 |
+--- linux-2.6.23.15/include/linux/skbuff.h 2008-02-11 10:36:03.000000000 +0000 |
30632 |
++++ linux-2.6.23.15-grsec/include/linux/skbuff.h 2008-02-11 10:37:45.000000000 +0000 |
30633 |
+@@ -385,7 +385,7 @@ extern void skb_truesize_bug(struc |
30634 |
+ |
30635 |
+ static inline void skb_truesize_check(struct sk_buff *skb) |
30636 |
+ { |
30637 |
+- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len)) |
30638 |
++ if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len)) |
30639 |
+ skb_truesize_bug(skb); |
30640 |
+ } |
30641 |
+ |
30642 |
+diff -Nurp linux-2.6.23.15/include/linux/sysctl.h linux-2.6.23.15-grsec/include/linux/sysctl.h |
30643 |
+--- linux-2.6.23.15/include/linux/sysctl.h 2008-02-11 10:36:24.000000000 +0000 |
30644 |
++++ linux-2.6.23.15-grsec/include/linux/sysctl.h 2008-02-11 10:37:45.000000000 +0000 |
30645 |
+@@ -168,9 +168,22 @@ enum |
30646 |
+ #ifdef CONFIG_ALPHA_UAC_SYSCTL |
30647 |
+ KERN_UAC_POLICY=78, /* int: Alpha unaligned access control policy flags */ |
30648 |
+ #endif /* CONFIG_ALPHA_UAC_SYSCTL */ |
30649 |
+-}; |
30650 |
+ |
30651 |
++#ifdef CONFIG_GRKERNSEC |
30652 |
++ KERN_GRSECURITY=98, /* grsecurity */ |
30653 |
++#endif |
30654 |
++ |
30655 |
++#ifdef CONFIG_PAX_SOFTMODE |
30656 |
++ KERN_PAX=99, /* PaX control */ |
30657 |
++#endif |
30658 |
++ |
30659 |
++}; |
30660 |
+ |
30661 |
++#ifdef CONFIG_PAX_SOFTMODE |
30662 |
++enum { |
30663 |
++ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */ |
30664 |
++}; |
30665 |
++#endif |
30666 |
+ |
30667 |
+ /* CTL_VM names: */ |
30668 |
+ enum |
30669 |
+diff -Nurp linux-2.6.23.15/include/linux/uaccess.h linux-2.6.23.15-grsec/include/linux/uaccess.h |
30670 |
+--- linux-2.6.23.15/include/linux/uaccess.h 2007-10-09 21:31:38.000000000 +0100 |
30671 |
++++ linux-2.6.23.15-grsec/include/linux/uaccess.h 2008-02-11 10:37:45.000000000 +0000 |
30672 |
+@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_ |
30673 |
+ long ret; \ |
30674 |
+ mm_segment_t old_fs = get_fs(); \ |
30675 |
+ \ |
30676 |
+- set_fs(KERNEL_DS); \ |
30677 |
+ pagefault_disable(); \ |
30678 |
++ set_fs(KERNEL_DS); \ |
30679 |
+ ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \ |
30680 |
+- pagefault_enable(); \ |
30681 |
+ set_fs(old_fs); \ |
30682 |
++ pagefault_enable(); \ |
30683 |
+ ret; \ |
30684 |
+ }) |
30685 |
+ |
30686 |
+diff -Nurp linux-2.6.23.15/include/linux/udf_fs.h linux-2.6.23.15-grsec/include/linux/udf_fs.h |
30687 |
+--- linux-2.6.23.15/include/linux/udf_fs.h 2007-10-09 21:31:38.000000000 +0100 |
30688 |
++++ linux-2.6.23.15-grsec/include/linux/udf_fs.h 2008-02-11 10:37:45.000000000 +0000 |
30689 |
+@@ -45,7 +45,7 @@ |
30690 |
+ printk (f, ##a); \ |
30691 |
+ } |
30692 |
+ #else |
30693 |
+-#define udf_debug(f, a...) /**/ |
30694 |
++#define udf_debug(f, a...) do {} while (0) |
30695 |
+ #endif |
30696 |
+ |
30697 |
+ #define udf_info(f, a...) \ |
30698 |
+diff -Nurp linux-2.6.23.15/include/net/sctp/sctp.h linux-2.6.23.15-grsec/include/net/sctp/sctp.h |
30699 |
+--- linux-2.6.23.15/include/net/sctp/sctp.h 2007-10-09 21:31:38.000000000 +0100 |
30700 |
++++ linux-2.6.23.15-grsec/include/net/sctp/sctp.h 2008-02-11 10:37:45.000000000 +0000 |
30701 |
+@@ -317,8 +317,8 @@ extern int sctp_debug_flag; |
30702 |
+ |
30703 |
+ #else /* SCTP_DEBUG */ |
30704 |
+ |
30705 |
+-#define SCTP_DEBUG_PRINTK(whatever...) |
30706 |
+-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) |
30707 |
++#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0) |
30708 |
++#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0) |
30709 |
+ #define SCTP_ENABLE_DEBUG |
30710 |
+ #define SCTP_DISABLE_DEBUG |
30711 |
+ #define SCTP_ASSERT(expr, str, func) |
30712 |
+diff -Nurp linux-2.6.23.15/include/sound/core.h linux-2.6.23.15-grsec/include/sound/core.h |
30713 |
+--- linux-2.6.23.15/include/sound/core.h 2007-10-09 21:31:38.000000000 +0100 |
30714 |
++++ linux-2.6.23.15-grsec/include/sound/core.h 2008-02-11 10:37:45.000000000 +0000 |
30715 |
+@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file |
30716 |
+ |
30717 |
+ #else /* !CONFIG_SND_DEBUG */ |
30718 |
+ |
30719 |
+-#define snd_printd(fmt, args...) /* nothing */ |
30720 |
++#define snd_printd(fmt, args...) do {} while (0) |
30721 |
+ #define snd_assert(expr, args...) (void)(expr) |
30722 |
+-#define snd_BUG() /* nothing */ |
30723 |
++#define snd_BUG() do {} while (0) |
30724 |
+ |
30725 |
+ #endif /* CONFIG_SND_DEBUG */ |
30726 |
+ |
30727 |
+@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file |
30728 |
+ */ |
30729 |
+ #define snd_printdd(format, args...) snd_printk(format, ##args) |
30730 |
+ #else |
30731 |
+-#define snd_printdd(format, args...) /* nothing */ |
30732 |
++#define snd_printdd(format, args...) do {} while (0) |
30733 |
+ #endif |
30734 |
+ |
30735 |
+ |
30736 |
+diff -Nurp linux-2.6.23.15/init/Kconfig linux-2.6.23.15-grsec/init/Kconfig |
30737 |
+--- linux-2.6.23.15/init/Kconfig 2007-10-09 21:31:38.000000000 +0100 |
30738 |
++++ linux-2.6.23.15-grsec/init/Kconfig 2008-02-11 10:37:45.000000000 +0000 |
30739 |
+@@ -384,6 +384,7 @@ config SYSCTL_SYSCALL |
30740 |
+ config KALLSYMS |
30741 |
+ bool "Load all symbols for debugging/ksymoops" if EMBEDDED |
30742 |
+ default y |
30743 |
++ depends on !GRKERNSEC_HIDESYM |
30744 |
+ help |
30745 |
+ Say Y here to let the kernel print out symbolic crash information and |
30746 |
+ symbolic stack backtraces. This increases the size of the kernel |
30747 |
+diff -Nurp linux-2.6.23.15/init/do_mounts.c linux-2.6.23.15-grsec/init/do_mounts.c |
30748 |
+--- linux-2.6.23.15/init/do_mounts.c 2007-10-09 21:31:38.000000000 +0100 |
30749 |
++++ linux-2.6.23.15-grsec/init/do_mounts.c 2008-02-11 10:37:45.000000000 +0000 |
30750 |
+@@ -68,11 +68,12 @@ static dev_t try_name(char *name, int pa |
30751 |
+ |
30752 |
+ /* read device number from .../dev */ |
30753 |
+ |
30754 |
+- sprintf(path, "/sys/block/%s/dev", name); |
30755 |
+- fd = sys_open(path, 0, 0); |
30756 |
++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name)) |
30757 |
++ goto fail; |
30758 |
++ fd = sys_open((char __user *)path, 0, 0); |
30759 |
+ if (fd < 0) |
30760 |
+ goto fail; |
30761 |
+- len = sys_read(fd, buf, 32); |
30762 |
++ len = sys_read(fd, (char __user *)buf, 32); |
30763 |
+ sys_close(fd); |
30764 |
+ if (len <= 0 || len == 32 || buf[len - 1] != '\n') |
30765 |
+ goto fail; |
30766 |
+@@ -98,11 +99,12 @@ static dev_t try_name(char *name, int pa |
30767 |
+ return res; |
30768 |
+ |
30769 |
+ /* otherwise read range from .../range */ |
30770 |
+- sprintf(path, "/sys/block/%s/range", name); |
30771 |
+- fd = sys_open(path, 0, 0); |
30772 |
++ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name)) |
30773 |
++ goto fail; |
30774 |
++ fd = sys_open((char __user *)path, 0, 0); |
30775 |
+ if (fd < 0) |
30776 |
+ goto fail; |
30777 |
+- len = sys_read(fd, buf, 32); |
30778 |
++ len = sys_read(fd, (char __user *)buf, 32); |
30779 |
+ sys_close(fd); |
30780 |
+ if (len <= 0 || len == 32 || buf[len - 1] != '\n') |
30781 |
+ goto fail; |
30782 |
+@@ -145,8 +147,8 @@ dev_t name_to_dev_t(char *name) |
30783 |
+ int part; |
30784 |
+ |
30785 |
+ #ifdef CONFIG_SYSFS |
30786 |
+- int mkdir_err = sys_mkdir("/sys", 0700); |
30787 |
+- if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0) |
30788 |
++ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700); |
30789 |
++ if (sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL) < 0) |
30790 |
+ goto out; |
30791 |
+ #endif |
30792 |
+ |
30793 |
+@@ -198,10 +200,10 @@ dev_t name_to_dev_t(char *name) |
30794 |
+ res = try_name(s, part); |
30795 |
+ done: |
30796 |
+ #ifdef CONFIG_SYSFS |
30797 |
+- sys_umount("/sys", 0); |
30798 |
++ sys_umount((char __user *)"/sys", 0); |
30799 |
+ out: |
30800 |
+ if (!mkdir_err) |
30801 |
+- sys_rmdir("/sys"); |
30802 |
++ sys_rmdir((char __user *)"/sys"); |
30803 |
+ #endif |
30804 |
+ return res; |
30805 |
+ fail: |
30806 |
+@@ -281,11 +283,11 @@ static void __init get_fs_names(char *pa |
30807 |
+ |
30808 |
+ static int __init do_mount_root(char *name, char *fs, int flags, void *data) |
30809 |
+ { |
30810 |
+- int err = sys_mount(name, "/root", fs, flags, data); |
30811 |
++ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data); |
30812 |
+ if (err) |
30813 |
+ return err; |
30814 |
+ |
30815 |
+- sys_chdir("/root"); |
30816 |
++ sys_chdir((char __user *)"/root"); |
30817 |
+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev; |
30818 |
+ printk("VFS: Mounted root (%s filesystem)%s.\n", |
30819 |
+ current->fs->pwdmnt->mnt_sb->s_type->name, |
30820 |
+@@ -371,18 +373,18 @@ void __init change_floppy(char *fmt, ... |
30821 |
+ va_start(args, fmt); |
30822 |
+ vsprintf(buf, fmt, args); |
30823 |
+ va_end(args); |
30824 |
+- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); |
30825 |
++ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0); |
30826 |
+ if (fd >= 0) { |
30827 |
+ sys_ioctl(fd, FDEJECT, 0); |
30828 |
+ sys_close(fd); |
30829 |
+ } |
30830 |
+ printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); |
30831 |
+- fd = sys_open("/dev/console", O_RDWR, 0); |
30832 |
++ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0); |
30833 |
+ if (fd >= 0) { |
30834 |
+ sys_ioctl(fd, TCGETS, (long)&termios); |
30835 |
+ termios.c_lflag &= ~ICANON; |
30836 |
+ sys_ioctl(fd, TCSETSF, (long)&termios); |
30837 |
+- sys_read(fd, &c, 1); |
30838 |
++ sys_read(fd, (char __user *)&c, 1); |
30839 |
+ termios.c_lflag |= ICANON; |
30840 |
+ sys_ioctl(fd, TCSETSF, (long)&termios); |
30841 |
+ sys_close(fd); |
30842 |
+@@ -468,8 +470,8 @@ void __init prepare_namespace(void) |
30843 |
+ |
30844 |
+ mount_root(); |
30845 |
+ out: |
30846 |
+- sys_mount(".", "/", NULL, MS_MOVE, NULL); |
30847 |
+- sys_chroot("."); |
30848 |
++ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL); |
30849 |
++ sys_chroot((char __user *)"."); |
30850 |
+ security_sb_post_mountroot(); |
30851 |
+ } |
30852 |
+ |
30853 |
+diff -Nurp linux-2.6.23.15/init/do_mounts.h linux-2.6.23.15-grsec/init/do_mounts.h |
30854 |
+--- linux-2.6.23.15/init/do_mounts.h 2007-10-09 21:31:38.000000000 +0100 |
30855 |
++++ linux-2.6.23.15-grsec/init/do_mounts.h 2008-02-11 10:37:45.000000000 +0000 |
30856 |
+@@ -15,15 +15,15 @@ extern char *root_device_name; |
30857 |
+ |
30858 |
+ static inline int create_dev(char *name, dev_t dev) |
30859 |
+ { |
30860 |
+- sys_unlink(name); |
30861 |
+- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev)); |
30862 |
++ sys_unlink((char __user *)name); |
30863 |
++ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev)); |
30864 |
+ } |
30865 |
+ |
30866 |
+ #if BITS_PER_LONG == 32 |
30867 |
+ static inline u32 bstat(char *name) |
30868 |
+ { |
30869 |
+ struct stat64 stat; |
30870 |
+- if (sys_stat64(name, &stat) != 0) |
30871 |
++ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0) |
30872 |
+ return 0; |
30873 |
+ if (!S_ISBLK(stat.st_mode)) |
30874 |
+ return 0; |
30875 |
+diff -Nurp linux-2.6.23.15/init/do_mounts_md.c linux-2.6.23.15-grsec/init/do_mounts_md.c |
30876 |
+--- linux-2.6.23.15/init/do_mounts_md.c 2007-10-09 21:31:38.000000000 +0100 |
30877 |
++++ linux-2.6.23.15-grsec/init/do_mounts_md.c 2008-02-11 10:37:45.000000000 +0000 |
30878 |
+@@ -167,7 +167,7 @@ static void __init md_setup_drive(void) |
30879 |
+ partitioned ? "_d" : "", minor, |
30880 |
+ md_setup_args[ent].device_names); |
30881 |
+ |
30882 |
+- fd = sys_open(name, 0, 0); |
30883 |
++ fd = sys_open((char __user *)name, 0, 0); |
30884 |
+ if (fd < 0) { |
30885 |
+ printk(KERN_ERR "md: open failed - cannot start " |
30886 |
+ "array %s\n", name); |
30887 |
+@@ -230,7 +230,7 @@ static void __init md_setup_drive(void) |
30888 |
+ * array without it |
30889 |
+ */ |
30890 |
+ sys_close(fd); |
30891 |
+- fd = sys_open(name, 0, 0); |
30892 |
++ fd = sys_open((char __user *)name, 0, 0); |
30893 |
+ sys_ioctl(fd, BLKRRPART, 0); |
30894 |
+ } |
30895 |
+ sys_close(fd); |
30896 |
+@@ -271,7 +271,7 @@ void __init md_run_setup(void) |
30897 |
+ if (raid_noautodetect) |
30898 |
+ printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n"); |
30899 |
+ else { |
30900 |
+- int fd = sys_open("/dev/md0", 0, 0); |
30901 |
++ int fd = sys_open((char __user *)"/dev/md0", 0, 0); |
30902 |
+ if (fd >= 0) { |
30903 |
+ sys_ioctl(fd, RAID_AUTORUN, raid_autopart); |
30904 |
+ sys_close(fd); |
30905 |
+diff -Nurp linux-2.6.23.15/init/initramfs.c linux-2.6.23.15-grsec/init/initramfs.c |
30906 |
+--- linux-2.6.23.15/init/initramfs.c 2007-10-09 21:31:38.000000000 +0100 |
30907 |
++++ linux-2.6.23.15-grsec/init/initramfs.c 2008-02-11 10:37:45.000000000 +0000 |
30908 |
+@@ -240,7 +240,7 @@ static int __init maybe_link(void) |
30909 |
+ if (nlink >= 2) { |
30910 |
+ char *old = find_link(major, minor, ino, mode, collected); |
30911 |
+ if (old) |
30912 |
+- return (sys_link(old, collected) < 0) ? -1 : 1; |
30913 |
++ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1; |
30914 |
+ } |
30915 |
+ return 0; |
30916 |
+ } |
30917 |
+@@ -249,11 +249,11 @@ static void __init clean_path(char *path |
30918 |
+ { |
30919 |
+ struct stat st; |
30920 |
+ |
30921 |
+- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) { |
30922 |
++ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) { |
30923 |
+ if (S_ISDIR(st.st_mode)) |
30924 |
+- sys_rmdir(path); |
30925 |
++ sys_rmdir((char __user *)path); |
30926 |
+ else |
30927 |
+- sys_unlink(path); |
30928 |
++ sys_unlink((char __user *)path); |
30929 |
+ } |
30930 |
+ } |
30931 |
+ |
30932 |
+@@ -276,7 +276,7 @@ static int __init do_name(void) |
30933 |
+ int openflags = O_WRONLY|O_CREAT; |
30934 |
+ if (ml != 1) |
30935 |
+ openflags |= O_TRUNC; |
30936 |
+- wfd = sys_open(collected, openflags, mode); |
30937 |
++ wfd = sys_open((char __user *)collected, openflags, mode); |
30938 |
+ |
30939 |
+ if (wfd >= 0) { |
30940 |
+ sys_fchown(wfd, uid, gid); |
30941 |
+@@ -285,15 +285,15 @@ static int __init do_name(void) |
30942 |
+ } |
30943 |
+ } |
30944 |
+ } else if (S_ISDIR(mode)) { |
30945 |
+- sys_mkdir(collected, mode); |
30946 |
+- sys_chown(collected, uid, gid); |
30947 |
+- sys_chmod(collected, mode); |
30948 |
++ sys_mkdir((char __user *)collected, mode); |
30949 |
++ sys_chown((char __user *)collected, uid, gid); |
30950 |
++ sys_chmod((char __user *)collected, mode); |
30951 |
+ } else if (S_ISBLK(mode) || S_ISCHR(mode) || |
30952 |
+ S_ISFIFO(mode) || S_ISSOCK(mode)) { |
30953 |
+ if (maybe_link() == 0) { |
30954 |
+- sys_mknod(collected, mode, rdev); |
30955 |
+- sys_chown(collected, uid, gid); |
30956 |
+- sys_chmod(collected, mode); |
30957 |
++ sys_mknod((char __user *)collected, mode, rdev); |
30958 |
++ sys_chown((char __user *)collected, uid, gid); |
30959 |
++ sys_chmod((char __user *)collected, mode); |
30960 |
+ } |
30961 |
+ } |
30962 |
+ return 0; |
30963 |
+@@ -302,13 +302,13 @@ static int __init do_name(void) |
30964 |
+ static int __init do_copy(void) |
30965 |
+ { |
30966 |
+ if (count >= body_len) { |
30967 |
+- sys_write(wfd, victim, body_len); |
30968 |
++ sys_write(wfd, (char __user *)victim, body_len); |
30969 |
+ sys_close(wfd); |
30970 |
+ eat(body_len); |
30971 |
+ state = SkipIt; |
30972 |
+ return 0; |
30973 |
+ } else { |
30974 |
+- sys_write(wfd, victim, count); |
30975 |
++ sys_write(wfd, (char __user *)victim, count); |
30976 |
+ body_len -= count; |
30977 |
+ eat(count); |
30978 |
+ return 1; |
30979 |
+@@ -319,8 +319,8 @@ static int __init do_symlink(void) |
30980 |
+ { |
30981 |
+ collected[N_ALIGN(name_len) + body_len] = '\0'; |
30982 |
+ clean_path(collected, 0); |
30983 |
+- sys_symlink(collected + N_ALIGN(name_len), collected); |
30984 |
+- sys_lchown(collected, uid, gid); |
30985 |
++ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected); |
30986 |
++ sys_lchown((char __user *)collected, uid, gid); |
30987 |
+ state = SkipIt; |
30988 |
+ next_state = Reset; |
30989 |
+ return 0; |
30990 |
+diff -Nurp linux-2.6.23.15/init/main.c linux-2.6.23.15-grsec/init/main.c |
30991 |
+--- linux-2.6.23.15/init/main.c 2007-10-09 21:31:38.000000000 +0100 |
30992 |
++++ linux-2.6.23.15-grsec/init/main.c 2008-02-11 10:37:45.000000000 +0000 |
30993 |
+@@ -107,6 +107,7 @@ static inline void mark_rodata_ro(void) |
30994 |
+ #ifdef CONFIG_TC |
30995 |
+ extern void tc_init(void); |
30996 |
+ #endif |
30997 |
++extern void grsecurity_init(void); |
30998 |
+ |
30999 |
+ enum system_states system_state; |
31000 |
+ EXPORT_SYMBOL(system_state); |
31001 |
+@@ -193,6 +194,17 @@ static int __init set_reset_devices(char |
31002 |
+ |
31003 |
+ __setup("reset_devices", set_reset_devices); |
31004 |
+ |
31005 |
++#ifdef CONFIG_PAX_SOFTMODE |
31006 |
++unsigned int pax_softmode; |
31007 |
++ |
31008 |
++static int __init setup_pax_softmode(char *str) |
31009 |
++{ |
31010 |
++ get_option(&str, &pax_softmode); |
31011 |
++ return 1; |
31012 |
++} |
31013 |
++__setup("pax_softmode=", setup_pax_softmode); |
31014 |
++#endif |
31015 |
++ |
31016 |
+ static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, }; |
31017 |
+ char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, }; |
31018 |
+ static const char *panic_later, *panic_param; |
31019 |
+@@ -854,6 +866,8 @@ static int __init kernel_init(void * unu |
31020 |
+ prepare_namespace(); |
31021 |
+ } |
31022 |
+ |
31023 |
++ grsecurity_init(); |
31024 |
++ |
31025 |
+ /* |
31026 |
+ * Ok, we have completed the initial bootup, and |
31027 |
+ * we're essentially up and running. Get rid of the |
31028 |
+diff -Nurp linux-2.6.23.15/init/noinitramfs.c linux-2.6.23.15-grsec/init/noinitramfs.c |
31029 |
+--- linux-2.6.23.15/init/noinitramfs.c 2007-10-09 21:31:38.000000000 +0100 |
31030 |
++++ linux-2.6.23.15-grsec/init/noinitramfs.c 2008-02-11 10:37:45.000000000 +0000 |
31031 |
+@@ -29,7 +29,7 @@ static int __init default_rootfs(void) |
31032 |
+ { |
31033 |
+ int err; |
31034 |
+ |
31035 |
+- err = sys_mkdir("/dev", 0755); |
31036 |
++ err = sys_mkdir((const char __user *)"/dev", 0755); |
31037 |
+ if (err < 0) |
31038 |
+ goto out; |
31039 |
+ |
31040 |
+@@ -39,7 +39,7 @@ static int __init default_rootfs(void) |
31041 |
+ if (err < 0) |
31042 |
+ goto out; |
31043 |
+ |
31044 |
+- err = sys_mkdir("/root", 0700); |
31045 |
++ err = sys_mkdir((const char __user *)"/root", 0700); |
31046 |
+ if (err < 0) |
31047 |
+ goto out; |
31048 |
+ |
31049 |
+diff -Nurp linux-2.6.23.15/ipc/ipc_sysctl.c linux-2.6.23.15-grsec/ipc/ipc_sysctl.c |
31050 |
+--- linux-2.6.23.15/ipc/ipc_sysctl.c 2007-10-09 21:31:38.000000000 +0100 |
31051 |
++++ linux-2.6.23.15-grsec/ipc/ipc_sysctl.c 2008-02-11 10:37:45.000000000 +0000 |
31052 |
+@@ -161,7 +161,7 @@ static struct ctl_table ipc_kern_table[] |
31053 |
+ .proc_handler = proc_ipc_dointvec, |
31054 |
+ .strategy = sysctl_ipc_data, |
31055 |
+ }, |
31056 |
+- {} |
31057 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
31058 |
+ }; |
31059 |
+ |
31060 |
+ static struct ctl_table ipc_root_table[] = { |
31061 |
+@@ -171,7 +171,7 @@ static struct ctl_table ipc_root_table[] |
31062 |
+ .mode = 0555, |
31063 |
+ .child = ipc_kern_table, |
31064 |
+ }, |
31065 |
+- {} |
31066 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
31067 |
+ }; |
31068 |
+ |
31069 |
+ static int __init ipc_sysctl_init(void) |
31070 |
+diff -Nurp linux-2.6.23.15/ipc/msg.c linux-2.6.23.15-grsec/ipc/msg.c |
31071 |
+--- linux-2.6.23.15/ipc/msg.c 2007-10-09 21:31:38.000000000 +0100 |
31072 |
++++ linux-2.6.23.15-grsec/ipc/msg.c 2008-02-11 10:37:45.000000000 +0000 |
31073 |
+@@ -36,6 +36,7 @@ |
31074 |
+ #include <linux/seq_file.h> |
31075 |
+ #include <linux/mutex.h> |
31076 |
+ #include <linux/nsproxy.h> |
31077 |
++#include <linux/grsecurity.h> |
31078 |
+ |
31079 |
+ #include <asm/current.h> |
31080 |
+ #include <asm/uaccess.h> |
31081 |
+@@ -286,6 +287,8 @@ asmlinkage long sys_msgget(key_t key, in |
31082 |
+ } |
31083 |
+ mutex_unlock(&msg_ids(ns).mutex); |
31084 |
+ |
31085 |
++ gr_log_msgget(ret, msgflg); |
31086 |
++ |
31087 |
+ return ret; |
31088 |
+ } |
31089 |
+ |
31090 |
+@@ -552,6 +555,7 @@ asmlinkage long sys_msgctl(int msqid, in |
31091 |
+ break; |
31092 |
+ } |
31093 |
+ case IPC_RMID: |
31094 |
++ gr_log_msgrm(ipcp->uid, ipcp->cuid); |
31095 |
+ freeque(ns, msq, msqid); |
31096 |
+ break; |
31097 |
+ } |
31098 |
+diff -Nurp linux-2.6.23.15/ipc/sem.c linux-2.6.23.15-grsec/ipc/sem.c |
31099 |
+--- linux-2.6.23.15/ipc/sem.c 2007-10-09 21:31:38.000000000 +0100 |
31100 |
++++ linux-2.6.23.15-grsec/ipc/sem.c 2008-02-11 10:37:45.000000000 +0000 |
31101 |
+@@ -82,6 +82,7 @@ |
31102 |
+ #include <linux/seq_file.h> |
31103 |
+ #include <linux/mutex.h> |
31104 |
+ #include <linux/nsproxy.h> |
31105 |
++#include <linux/grsecurity.h> |
31106 |
+ |
31107 |
+ #include <asm/uaccess.h> |
31108 |
+ #include "util.h" |
31109 |
+@@ -293,6 +294,9 @@ asmlinkage long sys_semget (key_t key, i |
31110 |
+ } |
31111 |
+ |
31112 |
+ mutex_unlock(&sem_ids(ns).mutex); |
31113 |
++ |
31114 |
++ gr_log_semget(err, semflg); |
31115 |
++ |
31116 |
+ return err; |
31117 |
+ } |
31118 |
+ |
31119 |
+@@ -894,6 +898,7 @@ static int semctl_down(struct ipc_namesp |
31120 |
+ |
31121 |
+ switch(cmd){ |
31122 |
+ case IPC_RMID: |
31123 |
++ gr_log_semrm(ipcp->uid, ipcp->cuid); |
31124 |
+ freeary(ns, sma, semid); |
31125 |
+ err = 0; |
31126 |
+ break; |
31127 |
+diff -Nurp linux-2.6.23.15/ipc/shm.c linux-2.6.23.15-grsec/ipc/shm.c |
31128 |
+--- linux-2.6.23.15/ipc/shm.c 2007-10-09 21:31:38.000000000 +0100 |
31129 |
++++ linux-2.6.23.15-grsec/ipc/shm.c 2008-02-11 10:37:45.000000000 +0000 |
31130 |
+@@ -38,6 +38,7 @@ |
31131 |
+ #include <linux/mutex.h> |
31132 |
+ #include <linux/nsproxy.h> |
31133 |
+ #include <linux/mount.h> |
31134 |
++#include <linux/grsecurity.h> |
31135 |
+ |
31136 |
+ #include <asm/uaccess.h> |
31137 |
+ |
31138 |
+@@ -77,6 +78,14 @@ static void shm_destroy (struct ipc_name |
31139 |
+ static int sysvipc_shm_proc_show(struct seq_file *s, void *it); |
31140 |
+ #endif |
31141 |
+ |
31142 |
++#ifdef CONFIG_GRKERNSEC |
31143 |
++extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
31144 |
++ const time_t shm_createtime, const uid_t cuid, |
31145 |
++ const int shmid); |
31146 |
++extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, |
31147 |
++ const time_t shm_createtime); |
31148 |
++#endif |
31149 |
++ |
31150 |
+ static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) |
31151 |
+ { |
31152 |
+ ns->ids[IPC_SHM_IDS] = ids; |
31153 |
+@@ -89,6 +98,8 @@ static void __shm_init_ns(struct ipc_nam |
31154 |
+ |
31155 |
+ static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) |
31156 |
+ { |
31157 |
++ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid); |
31158 |
++ |
31159 |
+ if (shp->shm_nattch){ |
31160 |
+ shp->shm_perm.mode |= SHM_DEST; |
31161 |
+ /* Do not find it any more */ |
31162 |
+@@ -216,6 +227,17 @@ static void shm_close(struct vm_area_str |
31163 |
+ shp->shm_lprid = current->tgid; |
31164 |
+ shp->shm_dtim = get_seconds(); |
31165 |
+ shp->shm_nattch--; |
31166 |
++#ifdef CONFIG_GRKERNSEC_SHM |
31167 |
++ if (grsec_enable_shm) { |
31168 |
++ if (shp->shm_nattch == 0) { |
31169 |
++ shp->shm_perm.mode |= SHM_DEST; |
31170 |
++ shm_destroy(ns, shp); |
31171 |
++ } else |
31172 |
++ shm_unlock(shp); |
31173 |
++ mutex_unlock(&shm_ids(ns).mutex); |
31174 |
++ return; |
31175 |
++ } |
31176 |
++#endif |
31177 |
+ if(shp->shm_nattch == 0 && |
31178 |
+ shp->shm_perm.mode & SHM_DEST) |
31179 |
+ shm_destroy(ns, shp); |
31180 |
+@@ -395,6 +417,9 @@ static int newseg (struct ipc_namespace |
31181 |
+ shp->shm_lprid = 0; |
31182 |
+ shp->shm_atim = shp->shm_dtim = 0; |
31183 |
+ shp->shm_ctim = get_seconds(); |
31184 |
++#ifdef CONFIG_GRKERNSEC |
31185 |
++ shp->shm_createtime = get_seconds(); |
31186 |
++#endif |
31187 |
+ shp->shm_segsz = size; |
31188 |
+ shp->shm_nattch = 0; |
31189 |
+ shp->id = shm_buildid(ns, id, shp->shm_perm.seq); |
31190 |
+@@ -452,6 +477,8 @@ asmlinkage long sys_shmget (key_t key, s |
31191 |
+ } |
31192 |
+ mutex_unlock(&shm_ids(ns).mutex); |
31193 |
+ |
31194 |
++ gr_log_shmget(err, shmflg, size); |
31195 |
++ |
31196 |
+ return err; |
31197 |
+ } |
31198 |
+ |
31199 |
+@@ -905,9 +932,21 @@ long do_shmat(int shmid, char __user *sh |
31200 |
+ if (err) |
31201 |
+ goto out_unlock; |
31202 |
+ |
31203 |
++#ifdef CONFIG_GRKERNSEC |
31204 |
++ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime, |
31205 |
++ shp->shm_perm.cuid, shmid) || |
31206 |
++ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) { |
31207 |
++ err = -EACCES; |
31208 |
++ goto out_unlock; |
31209 |
++ } |
31210 |
++#endif |
31211 |
++ |
31212 |
+ path.dentry = dget(shp->shm_file->f_path.dentry); |
31213 |
+ path.mnt = mntget(shp->shm_file->f_path.mnt); |
31214 |
+ shp->shm_nattch++; |
31215 |
++#ifdef CONFIG_GRKERNSEC |
31216 |
++ shp->shm_lapid = current->pid; |
31217 |
++#endif |
31218 |
+ size = i_size_read(path.dentry->d_inode); |
31219 |
+ shm_unlock(shp); |
31220 |
+ |
31221 |
+@@ -1111,3 +1150,27 @@ static int sysvipc_shm_proc_show(struct |
31222 |
+ shp->shm_ctim); |
31223 |
+ } |
31224 |
+ #endif |
31225 |
++ |
31226 |
++void gr_shm_exit(struct task_struct *task) |
31227 |
++{ |
31228 |
++#ifdef CONFIG_GRKERNSEC_SHM |
31229 |
++ int i; |
31230 |
++ struct shmid_kernel *shp; |
31231 |
++ struct ipc_namespace *ns; |
31232 |
++ |
31233 |
++ ns = current->nsproxy->ipc_ns; |
31234 |
++ |
31235 |
++ if (!grsec_enable_shm) |
31236 |
++ return; |
31237 |
++ |
31238 |
++ for (i = 0; i <= shm_ids(ns).max_id; i++) { |
31239 |
++ shp = shm_get(ns, i); |
31240 |
++ if (shp && (shp->shm_cprid == task->pid) && |
31241 |
++ (shp->shm_nattch <= 0)) { |
31242 |
++ shp->shm_perm.mode |= SHM_DEST; |
31243 |
++ shm_destroy(ns, shp); |
31244 |
++ } |
31245 |
++ } |
31246 |
++#endif |
31247 |
++ return; |
31248 |
++} |
31249 |
+diff -Nurp linux-2.6.23.15/kernel/acct.c linux-2.6.23.15-grsec/kernel/acct.c |
31250 |
+--- linux-2.6.23.15/kernel/acct.c 2007-10-09 21:31:38.000000000 +0100 |
31251 |
++++ linux-2.6.23.15-grsec/kernel/acct.c 2008-02-11 10:37:45.000000000 +0000 |
31252 |
+@@ -511,7 +511,7 @@ static void do_acct_process(struct file |
31253 |
+ */ |
31254 |
+ flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
31255 |
+ current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; |
31256 |
+- file->f_op->write(file, (char *)&ac, |
31257 |
++ file->f_op->write(file, (char __user *)&ac, |
31258 |
+ sizeof(acct_t), &file->f_pos); |
31259 |
+ current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; |
31260 |
+ set_fs(fs); |
31261 |
+diff -Nurp linux-2.6.23.15/kernel/capability.c linux-2.6.23.15-grsec/kernel/capability.c |
31262 |
+--- linux-2.6.23.15/kernel/capability.c 2007-10-09 21:31:38.000000000 +0100 |
31263 |
++++ linux-2.6.23.15-grsec/kernel/capability.c 2008-02-11 10:37:45.000000000 +0000 |
31264 |
+@@ -12,6 +12,7 @@ |
31265 |
+ #include <linux/module.h> |
31266 |
+ #include <linux/security.h> |
31267 |
+ #include <linux/syscalls.h> |
31268 |
++#include <linux/grsecurity.h> |
31269 |
+ #include <asm/uaccess.h> |
31270 |
+ |
31271 |
+ unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ |
31272 |
+@@ -236,14 +237,25 @@ out: |
31273 |
+ return ret; |
31274 |
+ } |
31275 |
+ |
31276 |
++extern int gr_task_is_capable(struct task_struct *task, const int cap); |
31277 |
++extern int gr_is_capable_nolog(const int cap); |
31278 |
++ |
31279 |
+ int __capable(struct task_struct *t, int cap) |
31280 |
+ { |
31281 |
+- if (security_capable(t, cap) == 0) { |
31282 |
++ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) { |
31283 |
+ t->flags |= PF_SUPERPRIV; |
31284 |
+ return 1; |
31285 |
+ } |
31286 |
+ return 0; |
31287 |
+ } |
31288 |
++int capable_nolog(int cap) |
31289 |
++{ |
31290 |
++ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) { |
31291 |
++ current->flags |= PF_SUPERPRIV; |
31292 |
++ return 1; |
31293 |
++ } |
31294 |
++ return 0; |
31295 |
++} |
31296 |
+ EXPORT_SYMBOL(__capable); |
31297 |
+ |
31298 |
+ int capable(int cap) |
31299 |
+@@ -251,3 +263,4 @@ int capable(int cap) |
31300 |
+ return __capable(current, cap); |
31301 |
+ } |
31302 |
+ EXPORT_SYMBOL(capable); |
31303 |
++EXPORT_SYMBOL(capable_nolog); |
31304 |
+diff -Nurp linux-2.6.23.15/kernel/configs.c linux-2.6.23.15-grsec/kernel/configs.c |
31305 |
+--- linux-2.6.23.15/kernel/configs.c 2007-10-09 21:31:38.000000000 +0100 |
31306 |
++++ linux-2.6.23.15-grsec/kernel/configs.c 2008-02-11 10:37:45.000000000 +0000 |
31307 |
+@@ -79,8 +79,16 @@ static int __init ikconfig_init(void) |
31308 |
+ struct proc_dir_entry *entry; |
31309 |
+ |
31310 |
+ /* create the current config file */ |
31311 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
31312 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
31313 |
++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root); |
31314 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
31315 |
++ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root); |
31316 |
++#endif |
31317 |
++#else |
31318 |
+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO, |
31319 |
+ &proc_root); |
31320 |
++#endif |
31321 |
+ if (!entry) |
31322 |
+ return -ENOMEM; |
31323 |
+ |
31324 |
+diff -Nurp linux-2.6.23.15/kernel/exit.c linux-2.6.23.15-grsec/kernel/exit.c |
31325 |
+--- linux-2.6.23.15/kernel/exit.c 2008-02-11 10:36:03.000000000 +0000 |
31326 |
++++ linux-2.6.23.15-grsec/kernel/exit.c 2008-02-11 10:37:45.000000000 +0000 |
31327 |
+@@ -45,6 +45,11 @@ |
31328 |
+ #include <linux/blkdev.h> |
31329 |
+ #include <linux/task_io_accounting_ops.h> |
31330 |
+ #include <linux/freezer.h> |
31331 |
++#include <linux/grsecurity.h> |
31332 |
++ |
31333 |
++#ifdef CONFIG_GRKERNSEC |
31334 |
++extern rwlock_t grsec_exec_file_lock; |
31335 |
++#endif |
31336 |
+ |
31337 |
+ #include <asm/uaccess.h> |
31338 |
+ #include <asm/unistd.h> |
31339 |
+@@ -123,6 +128,7 @@ static void __exit_signal(struct task_st |
31340 |
+ |
31341 |
+ __unhash_process(tsk); |
31342 |
+ |
31343 |
++ gr_del_task_from_ip_table(tsk); |
31344 |
+ tsk->signal = NULL; |
31345 |
+ tsk->sighand = NULL; |
31346 |
+ spin_unlock(&sighand->siglock); |
31347 |
+@@ -274,12 +280,23 @@ static void reparent_to_kthreadd(void) |
31348 |
+ { |
31349 |
+ write_lock_irq(&tasklist_lock); |
31350 |
+ |
31351 |
++#ifdef CONFIG_GRKERNSEC |
31352 |
++ write_lock(&grsec_exec_file_lock); |
31353 |
++ if (current->exec_file) { |
31354 |
++ fput(current->exec_file); |
31355 |
++ current->exec_file = NULL; |
31356 |
++ } |
31357 |
++ write_unlock(&grsec_exec_file_lock); |
31358 |
++#endif |
31359 |
++ |
31360 |
+ ptrace_unlink(current); |
31361 |
+ /* Reparent to init */ |
31362 |
+ remove_parent(current); |
31363 |
+ current->real_parent = current->parent = kthreadd_task; |
31364 |
+ add_parent(current); |
31365 |
+ |
31366 |
++ gr_set_kernel_label(current); |
31367 |
++ |
31368 |
+ /* Set the exit signal to SIGCHLD so we signal init on exit */ |
31369 |
+ current->exit_signal = SIGCHLD; |
31370 |
+ |
31371 |
+@@ -374,6 +391,17 @@ void daemonize(const char *name, ...) |
31372 |
+ vsnprintf(current->comm, sizeof(current->comm), name, args); |
31373 |
+ va_end(args); |
31374 |
+ |
31375 |
++#ifdef CONFIG_GRKERNSEC |
31376 |
++ write_lock(&grsec_exec_file_lock); |
31377 |
++ if (current->exec_file) { |
31378 |
++ fput(current->exec_file); |
31379 |
++ current->exec_file = NULL; |
31380 |
++ } |
31381 |
++ write_unlock(&grsec_exec_file_lock); |
31382 |
++#endif |
31383 |
++ |
31384 |
++ gr_set_kernel_label(current); |
31385 |
++ |
31386 |
+ /* |
31387 |
+ * If we were started as result of loading a module, close all of the |
31388 |
+ * user space pages. We don't need them, and if we didn't close them |
31389 |
+@@ -969,11 +997,15 @@ fastcall NORET_TYPE void do_exit(long co |
31390 |
+ tsk->exit_code = code; |
31391 |
+ taskstats_exit(tsk, group_dead); |
31392 |
+ |
31393 |
++ gr_acl_handle_psacct(tsk, code); |
31394 |
++ gr_acl_handle_exit(); |
31395 |
++ |
31396 |
+ exit_mm(tsk); |
31397 |
+ |
31398 |
+ if (group_dead) |
31399 |
+ acct_process(); |
31400 |
+ exit_sem(tsk); |
31401 |
++ gr_shm_exit(tsk); |
31402 |
+ __exit_files(tsk); |
31403 |
+ __exit_fs(tsk); |
31404 |
+ check_stack_usage(); |
31405 |
+@@ -1174,7 +1206,7 @@ static int wait_task_zombie(struct task_ |
31406 |
+ pid_t pid = p->pid; |
31407 |
+ uid_t uid = p->uid; |
31408 |
+ int exit_code = p->exit_code; |
31409 |
+- int why, status; |
31410 |
++ int why; |
31411 |
+ |
31412 |
+ if (unlikely(p->exit_state != EXIT_ZOMBIE)) |
31413 |
+ return 0; |
31414 |
+diff -Nurp linux-2.6.23.15/kernel/fork.c linux-2.6.23.15-grsec/kernel/fork.c |
31415 |
+--- linux-2.6.23.15/kernel/fork.c 2008-02-11 10:36:03.000000000 +0000 |
31416 |
++++ linux-2.6.23.15-grsec/kernel/fork.c 2008-02-11 10:37:45.000000000 +0000 |
31417 |
+@@ -50,6 +50,7 @@ |
31418 |
+ #include <linux/taskstats_kern.h> |
31419 |
+ #include <linux/random.h> |
31420 |
+ #include <linux/tty.h> |
31421 |
++#include <linux/grsecurity.h> |
31422 |
+ |
31423 |
+ #include <asm/pgtable.h> |
31424 |
+ #include <asm/pgalloc.h> |
31425 |
+@@ -181,7 +182,7 @@ static struct task_struct *dup_task_stru |
31426 |
+ setup_thread_stack(tsk, orig); |
31427 |
+ |
31428 |
+ #ifdef CONFIG_CC_STACKPROTECTOR |
31429 |
+- tsk->stack_canary = get_random_int(); |
31430 |
++ tsk->stack_canary = pax_get_random_long(); |
31431 |
+ #endif |
31432 |
+ |
31433 |
+ /* One for us, one for whoever does the "release_task()" (usually parent) */ |
31434 |
+@@ -203,6 +204,10 @@ static inline int dup_mmap(struct mm_str |
31435 |
+ unsigned long charge; |
31436 |
+ struct mempolicy *pol; |
31437 |
+ |
31438 |
++#ifdef CONFIG_PAX_SEGMEXEC |
31439 |
++ struct vm_area_struct *mpnt_m; |
31440 |
++#endif |
31441 |
++ |
31442 |
+ down_write(&oldmm->mmap_sem); |
31443 |
+ flush_cache_dup_mm(oldmm); |
31444 |
+ /* |
31445 |
+@@ -213,8 +218,8 @@ static inline int dup_mmap(struct mm_str |
31446 |
+ mm->locked_vm = 0; |
31447 |
+ mm->mmap = NULL; |
31448 |
+ mm->mmap_cache = NULL; |
31449 |
+- mm->free_area_cache = oldmm->mmap_base; |
31450 |
+- mm->cached_hole_size = ~0UL; |
31451 |
++ mm->free_area_cache = oldmm->free_area_cache; |
31452 |
++ mm->cached_hole_size = oldmm->cached_hole_size; |
31453 |
+ mm->map_count = 0; |
31454 |
+ cpus_clear(mm->cpu_vm_mask); |
31455 |
+ mm->mm_rb = RB_ROOT; |
31456 |
+@@ -233,6 +238,7 @@ static inline int dup_mmap(struct mm_str |
31457 |
+ continue; |
31458 |
+ } |
31459 |
+ charge = 0; |
31460 |
++ |
31461 |
+ if (mpnt->vm_flags & VM_ACCOUNT) { |
31462 |
+ unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT; |
31463 |
+ if (security_vm_enough_memory(len)) |
31464 |
+@@ -251,6 +257,7 @@ static inline int dup_mmap(struct mm_str |
31465 |
+ tmp->vm_flags &= ~VM_LOCKED; |
31466 |
+ tmp->vm_mm = mm; |
31467 |
+ tmp->vm_next = NULL; |
31468 |
++ tmp->vm_mirror = NULL; |
31469 |
+ anon_vma_link(tmp); |
31470 |
+ file = tmp->vm_file; |
31471 |
+ if (file) { |
31472 |
+@@ -287,6 +294,29 @@ static inline int dup_mmap(struct mm_str |
31473 |
+ if (retval) |
31474 |
+ goto out; |
31475 |
+ } |
31476 |
++ |
31477 |
++#ifdef CONFIG_PAX_SEGMEXEC |
31478 |
++ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) { |
31479 |
++ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) { |
31480 |
++ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm); |
31481 |
++ |
31482 |
++ if (!mpnt->vm_mirror) |
31483 |
++ continue; |
31484 |
++ |
31485 |
++ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) { |
31486 |
++ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt); |
31487 |
++ mpnt->vm_mirror = mpnt_m; |
31488 |
++ } else { |
31489 |
++ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm); |
31490 |
++ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror; |
31491 |
++ mpnt_m->vm_mirror->vm_mirror = mpnt_m; |
31492 |
++ mpnt->vm_mirror->vm_mirror = mpnt; |
31493 |
++ } |
31494 |
++ } |
31495 |
++ BUG_ON(mpnt_m); |
31496 |
++ } |
31497 |
++#endif |
31498 |
++ |
31499 |
+ /* a new mm has just been created */ |
31500 |
+ arch_dup_mmap(oldmm, mm); |
31501 |
+ retval = 0; |
31502 |
+@@ -464,7 +494,7 @@ void mm_release(struct task_struct *tsk, |
31503 |
+ if (tsk->clear_child_tid |
31504 |
+ && !(tsk->flags & PF_SIGNALED) |
31505 |
+ && atomic_read(&mm->mm_users) > 1) { |
31506 |
+- u32 __user * tidptr = tsk->clear_child_tid; |
31507 |
++ pid_t __user * tidptr = tsk->clear_child_tid; |
31508 |
+ tsk->clear_child_tid = NULL; |
31509 |
+ |
31510 |
+ /* |
31511 |
+@@ -472,7 +502,7 @@ void mm_release(struct task_struct *tsk, |
31512 |
+ * not set up a proper pointer then tough luck. |
31513 |
+ */ |
31514 |
+ put_user(0, tidptr); |
31515 |
+- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); |
31516 |
++ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0); |
31517 |
+ } |
31518 |
+ } |
31519 |
+ |
31520 |
+@@ -1001,6 +1031,9 @@ static struct task_struct *copy_process( |
31521 |
+ DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
31522 |
+ #endif |
31523 |
+ retval = -EAGAIN; |
31524 |
++ |
31525 |
++ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0); |
31526 |
++ |
31527 |
+ if (atomic_read(&p->user->processes) >= |
31528 |
+ p->signal->rlim[RLIMIT_NPROC].rlim_cur) { |
31529 |
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && |
31530 |
+@@ -1140,6 +1173,8 @@ static struct task_struct *copy_process( |
31531 |
+ if (retval) |
31532 |
+ goto bad_fork_cleanup_namespaces; |
31533 |
+ |
31534 |
++ gr_copy_label(p); |
31535 |
++ |
31536 |
+ p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; |
31537 |
+ /* |
31538 |
+ * Clear TID on mm_release()? |
31539 |
+@@ -1318,6 +1353,8 @@ bad_fork_cleanup_count: |
31540 |
+ bad_fork_free: |
31541 |
+ free_task(p); |
31542 |
+ fork_out: |
31543 |
++ gr_log_forkfail(retval); |
31544 |
++ |
31545 |
+ return ERR_PTR(retval); |
31546 |
+ } |
31547 |
+ |
31548 |
+@@ -1391,6 +1428,8 @@ long do_fork(unsigned long clone_flags, |
31549 |
+ if (!IS_ERR(p)) { |
31550 |
+ struct completion vfork; |
31551 |
+ |
31552 |
++ gr_handle_brute_check(); |
31553 |
++ |
31554 |
+ if (clone_flags & CLONE_VFORK) { |
31555 |
+ p->vfork_done = &vfork; |
31556 |
+ init_completion(&vfork); |
31557 |
+diff -Nurp linux-2.6.23.15/kernel/futex.c linux-2.6.23.15-grsec/kernel/futex.c |
31558 |
+--- linux-2.6.23.15/kernel/futex.c 2008-02-11 10:36:03.000000000 +0000 |
31559 |
++++ linux-2.6.23.15-grsec/kernel/futex.c 2008-02-11 10:37:45.000000000 +0000 |
31560 |
+@@ -186,6 +186,11 @@ int get_futex_key(u32 __user *uaddr, str |
31561 |
+ struct page *page; |
31562 |
+ int err; |
31563 |
+ |
31564 |
++#ifdef CONFIG_PAX_SEGMEXEC |
31565 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE) |
31566 |
++ return -EFAULT; |
31567 |
++#endif |
31568 |
++ |
31569 |
+ /* |
31570 |
+ * The futex address must be "naturally" aligned. |
31571 |
+ */ |
31572 |
+@@ -212,8 +217,8 @@ int get_futex_key(u32 __user *uaddr, str |
31573 |
+ * The futex is hashed differently depending on whether |
31574 |
+ * it's in a shared or private mapping. So check vma first. |
31575 |
+ */ |
31576 |
+- vma = find_extend_vma(mm, address); |
31577 |
+- if (unlikely(!vma)) |
31578 |
++ vma = find_vma(mm, address); |
31579 |
++ if (unlikely(!vma || address < vma->vm_start)) |
31580 |
+ return -EFAULT; |
31581 |
+ |
31582 |
+ /* |
31583 |
+@@ -1922,7 +1927,7 @@ retry: |
31584 |
+ */ |
31585 |
+ static inline int fetch_robust_entry(struct robust_list __user **entry, |
31586 |
+ struct robust_list __user * __user *head, |
31587 |
+- int *pi) |
31588 |
++ unsigned int *pi) |
31589 |
+ { |
31590 |
+ unsigned long uentry; |
31591 |
+ |
31592 |
+diff -Nurp linux-2.6.23.15/kernel/irq/handle.c linux-2.6.23.15-grsec/kernel/irq/handle.c |
31593 |
+--- linux-2.6.23.15/kernel/irq/handle.c 2007-10-09 21:31:38.000000000 +0100 |
31594 |
++++ linux-2.6.23.15-grsec/kernel/irq/handle.c 2008-02-11 10:37:45.000000000 +0000 |
31595 |
+@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach |
31596 |
+ .depth = 1, |
31597 |
+ .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), |
31598 |
+ #ifdef CONFIG_SMP |
31599 |
+- .affinity = CPU_MASK_ALL |
31600 |
++ .affinity = CPU_MASK_ALL, |
31601 |
++ .cpu = 0, |
31602 |
+ #endif |
31603 |
+ } |
31604 |
+ }; |
31605 |
+diff -Nurp linux-2.6.23.15/kernel/kallsyms.c linux-2.6.23.15-grsec/kernel/kallsyms.c |
31606 |
+--- linux-2.6.23.15/kernel/kallsyms.c 2007-10-09 21:31:38.000000000 +0100 |
31607 |
++++ linux-2.6.23.15-grsec/kernel/kallsyms.c 2008-02-11 10:37:45.000000000 +0000 |
31608 |
+@@ -65,6 +65,19 @@ static inline int is_kernel_text(unsigne |
31609 |
+ |
31610 |
+ static inline int is_kernel(unsigned long addr) |
31611 |
+ { |
31612 |
++ |
31613 |
++#ifdef CONFIG_PAX_KERNEXEC |
31614 |
++ |
31615 |
++#ifdef CONFIG_MODULES |
31616 |
++ if ((unsigned long)MODULES_VADDR <= addr + __KERNEL_TEXT_OFFSET && |
31617 |
++ addr + __KERNEL_TEXT_OFFSET < (unsigned long)MODULES_END) |
31618 |
++ return 0; |
31619 |
++#endif |
31620 |
++ |
31621 |
++ if (is_kernel_inittext(addr)) |
31622 |
++ return 1; |
31623 |
++#endif |
31624 |
++ |
31625 |
+ if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) |
31626 |
+ return 1; |
31627 |
+ return in_gate_area_no_task(addr); |
31628 |
+@@ -373,7 +386,6 @@ static unsigned long get_ksymbol_core(st |
31629 |
+ |
31630 |
+ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos) |
31631 |
+ { |
31632 |
+- iter->name[0] = '\0'; |
31633 |
+ iter->nameoff = get_symbol_offset(new_pos); |
31634 |
+ iter->pos = new_pos; |
31635 |
+ } |
31636 |
+@@ -457,7 +469,7 @@ static int kallsyms_open(struct inode *i |
31637 |
+ struct kallsym_iter *iter; |
31638 |
+ int ret; |
31639 |
+ |
31640 |
+- iter = kmalloc(sizeof(*iter), GFP_KERNEL); |
31641 |
++ iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
31642 |
+ if (!iter) |
31643 |
+ return -ENOMEM; |
31644 |
+ reset_iter(iter, 0); |
31645 |
+@@ -481,7 +493,15 @@ static int __init kallsyms_init(void) |
31646 |
+ { |
31647 |
+ struct proc_dir_entry *entry; |
31648 |
+ |
31649 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
31650 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
31651 |
++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL); |
31652 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
31653 |
++ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL); |
31654 |
++#endif |
31655 |
++#else |
31656 |
+ entry = create_proc_entry("kallsyms", 0444, NULL); |
31657 |
++#endif |
31658 |
+ if (entry) |
31659 |
+ entry->proc_fops = &kallsyms_operations; |
31660 |
+ return 0; |
31661 |
+diff -Nurp linux-2.6.23.15/kernel/kprobes.c linux-2.6.23.15-grsec/kernel/kprobes.c |
31662 |
+--- linux-2.6.23.15/kernel/kprobes.c 2007-10-09 21:31:38.000000000 +0100 |
31663 |
++++ linux-2.6.23.15-grsec/kernel/kprobes.c 2008-02-11 10:37:45.000000000 +0000 |
31664 |
+@@ -168,7 +168,7 @@ kprobe_opcode_t __kprobes *get_insn_slot |
31665 |
+ * kernel image and loaded module images reside. This is required |
31666 |
+ * so x86_64 can correctly handle the %rip-relative fixups. |
31667 |
+ */ |
31668 |
+- kip->insns = module_alloc(PAGE_SIZE); |
31669 |
++ kip->insns = module_alloc_exec(PAGE_SIZE); |
31670 |
+ if (!kip->insns) { |
31671 |
+ kfree(kip); |
31672 |
+ return NULL; |
31673 |
+@@ -200,7 +200,7 @@ static int __kprobes collect_one_slot(st |
31674 |
+ hlist_add_head(&kip->hlist, |
31675 |
+ &kprobe_insn_pages); |
31676 |
+ } else { |
31677 |
+- module_free(NULL, kip->insns); |
31678 |
++ module_free_exec(NULL, kip->insns); |
31679 |
+ kfree(kip); |
31680 |
+ } |
31681 |
+ return 1; |
31682 |
+diff -Nurp linux-2.6.23.15/kernel/module.c linux-2.6.23.15-grsec/kernel/module.c |
31683 |
+--- linux-2.6.23.15/kernel/module.c 2007-10-09 21:31:38.000000000 +0100 |
31684 |
++++ linux-2.6.23.15-grsec/kernel/module.c 2008-02-11 10:37:45.000000000 +0000 |
31685 |
+@@ -44,6 +44,11 @@ |
31686 |
+ #include <asm/uaccess.h> |
31687 |
+ #include <asm/semaphore.h> |
31688 |
+ #include <asm/cacheflush.h> |
31689 |
++ |
31690 |
++#ifdef CONFIG_PAX_KERNEXEC |
31691 |
++#include <asm/desc.h> |
31692 |
++#endif |
31693 |
++ |
31694 |
+ #include <linux/license.h> |
31695 |
+ |
31696 |
+ extern int module_sysfs_initialized; |
31697 |
+@@ -68,6 +73,8 @@ static LIST_HEAD(modules); |
31698 |
+ |
31699 |
+ static BLOCKING_NOTIFIER_HEAD(module_notify_list); |
31700 |
+ |
31701 |
++extern int gr_check_modstop(void); |
31702 |
++ |
31703 |
+ int register_module_notifier(struct notifier_block * nb) |
31704 |
+ { |
31705 |
+ return blocking_notifier_chain_register(&module_notify_list, nb); |
31706 |
+@@ -347,7 +354,7 @@ static void *percpu_modalloc(unsigned lo |
31707 |
+ unsigned int i; |
31708 |
+ void *ptr; |
31709 |
+ |
31710 |
+- if (align > PAGE_SIZE) { |
31711 |
++ if (align-1 >= PAGE_SIZE) { |
31712 |
+ printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", |
31713 |
+ name, align, PAGE_SIZE); |
31714 |
+ align = PAGE_SIZE; |
31715 |
+@@ -660,6 +667,9 @@ sys_delete_module(const char __user *nam |
31716 |
+ char name[MODULE_NAME_LEN]; |
31717 |
+ int ret, forced = 0; |
31718 |
+ |
31719 |
++ if (gr_check_modstop()) |
31720 |
++ return -EPERM; |
31721 |
++ |
31722 |
+ if (!capable(CAP_SYS_MODULE)) |
31723 |
+ return -EPERM; |
31724 |
+ |
31725 |
+@@ -1209,16 +1219,19 @@ static void free_module(struct module *m |
31726 |
+ module_unload_free(mod); |
31727 |
+ |
31728 |
+ /* This may be NULL, but that's OK */ |
31729 |
+- module_free(mod, mod->module_init); |
31730 |
++ module_free(mod, mod->module_init_rw); |
31731 |
++ module_free_exec(mod, mod->module_init_rx); |
31732 |
+ kfree(mod->args); |
31733 |
+ if (mod->percpu) |
31734 |
+ percpu_modfree(mod->percpu); |
31735 |
+ |
31736 |
+ /* Free lock-classes: */ |
31737 |
+- lockdep_free_key_range(mod->module_core, mod->core_size); |
31738 |
++ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx); |
31739 |
++ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw); |
31740 |
+ |
31741 |
+ /* Finally, free the core (containing the module structure) */ |
31742 |
+- module_free(mod, mod->module_core); |
31743 |
++ module_free_exec(mod, mod->module_core_rx); |
31744 |
++ module_free(mod, mod->module_core_rw); |
31745 |
+ } |
31746 |
+ |
31747 |
+ void *__symbol_get(const char *symbol) |
31748 |
+@@ -1279,10 +1292,14 @@ static int simplify_symbols(Elf_Shdr *se |
31749 |
+ struct module *mod) |
31750 |
+ { |
31751 |
+ Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; |
31752 |
+- unsigned long secbase; |
31753 |
++ unsigned long secbase, symbol; |
31754 |
+ unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
31755 |
+ int ret = 0; |
31756 |
+ |
31757 |
++#ifdef CONFIG_PAX_KERNEXEC |
31758 |
++ unsigned long cr0; |
31759 |
++#endif |
31760 |
++ |
31761 |
+ for (i = 1; i < n; i++) { |
31762 |
+ switch (sym[i].st_shndx) { |
31763 |
+ case SHN_COMMON: |
31764 |
+@@ -1301,10 +1318,19 @@ static int simplify_symbols(Elf_Shdr *se |
31765 |
+ break; |
31766 |
+ |
31767 |
+ case SHN_UNDEF: |
31768 |
+- sym[i].st_value |
31769 |
+- = resolve_symbol(sechdrs, versindex, |
31770 |
++ symbol = resolve_symbol(sechdrs, versindex, |
31771 |
+ strtab + sym[i].st_name, mod); |
31772 |
+ |
31773 |
++#ifdef CONFIG_PAX_KERNEXEC |
31774 |
++ pax_open_kernel(cr0); |
31775 |
++#endif |
31776 |
++ |
31777 |
++ sym[i].st_value = symbol; |
31778 |
++ |
31779 |
++#ifdef CONFIG_PAX_KERNEXEC |
31780 |
++ pax_close_kernel(cr0); |
31781 |
++#endif |
31782 |
++ |
31783 |
+ /* Ok if resolved. */ |
31784 |
+ if (sym[i].st_value != 0) |
31785 |
+ break; |
31786 |
+@@ -1319,11 +1345,27 @@ static int simplify_symbols(Elf_Shdr *se |
31787 |
+ |
31788 |
+ default: |
31789 |
+ /* Divert to percpu allocation if a percpu var. */ |
31790 |
+- if (sym[i].st_shndx == pcpuindex) |
31791 |
++ if (sym[i].st_shndx == pcpuindex) { |
31792 |
++ |
31793 |
++#if defined(CONFIG_X86_32) && defined(CONFIG_SMP) |
31794 |
++ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start; |
31795 |
++#else |
31796 |
+ secbase = (unsigned long)mod->percpu; |
31797 |
+- else |
31798 |
++#endif |
31799 |
++ |
31800 |
++ } else |
31801 |
+ secbase = sechdrs[sym[i].st_shndx].sh_addr; |
31802 |
++ |
31803 |
++#ifdef CONFIG_PAX_KERNEXEC |
31804 |
++ pax_open_kernel(cr0); |
31805 |
++#endif |
31806 |
++ |
31807 |
+ sym[i].st_value += secbase; |
31808 |
++ |
31809 |
++#ifdef CONFIG_PAX_KERNEXEC |
31810 |
++ pax_close_kernel(cr0); |
31811 |
++#endif |
31812 |
++ |
31813 |
+ break; |
31814 |
+ } |
31815 |
+ } |
31816 |
+@@ -1375,11 +1417,14 @@ static void layout_sections(struct modul |
31817 |
+ || strncmp(secstrings + s->sh_name, |
31818 |
+ ".init", 5) == 0) |
31819 |
+ continue; |
31820 |
+- s->sh_entsize = get_offset(&mod->core_size, s); |
31821 |
++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC)) |
31822 |
++ s->sh_entsize = get_offset(&mod->core_size_rw, s); |
31823 |
++ else |
31824 |
++ s->sh_entsize = get_offset(&mod->core_size_rx, s); |
31825 |
+ DEBUGP("\t%s\n", secstrings + s->sh_name); |
31826 |
+ } |
31827 |
+ if (m == 0) |
31828 |
+- mod->core_text_size = mod->core_size; |
31829 |
++ mod->core_size_rx = mod->core_size_rx; |
31830 |
+ } |
31831 |
+ |
31832 |
+ DEBUGP("Init section allocation order:\n"); |
31833 |
+@@ -1393,12 +1438,15 @@ static void layout_sections(struct modul |
31834 |
+ || strncmp(secstrings + s->sh_name, |
31835 |
+ ".init", 5) != 0) |
31836 |
+ continue; |
31837 |
+- s->sh_entsize = (get_offset(&mod->init_size, s) |
31838 |
+- | INIT_OFFSET_MASK); |
31839 |
++ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC)) |
31840 |
++ s->sh_entsize = get_offset(&mod->init_size_rw, s); |
31841 |
++ else |
31842 |
++ s->sh_entsize = get_offset(&mod->init_size_rx, s); |
31843 |
++ s->sh_entsize |= INIT_OFFSET_MASK; |
31844 |
+ DEBUGP("\t%s\n", secstrings + s->sh_name); |
31845 |
+ } |
31846 |
+ if (m == 0) |
31847 |
+- mod->init_text_size = mod->init_size; |
31848 |
++ mod->init_size_rx = mod->init_size_rx; |
31849 |
+ } |
31850 |
+ } |
31851 |
+ |
31852 |
+@@ -1525,14 +1573,31 @@ static void add_kallsyms(struct module * |
31853 |
+ { |
31854 |
+ unsigned int i; |
31855 |
+ |
31856 |
++#ifdef CONFIG_PAX_KERNEXEC |
31857 |
++ unsigned long cr0; |
31858 |
++#endif |
31859 |
++ |
31860 |
+ mod->symtab = (void *)sechdrs[symindex].sh_addr; |
31861 |
+ mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
31862 |
+ mod->strtab = (void *)sechdrs[strindex].sh_addr; |
31863 |
+ |
31864 |
+ /* Set types up while we still have access to sections. */ |
31865 |
+- for (i = 0; i < mod->num_symtab; i++) |
31866 |
+- mod->symtab[i].st_info |
31867 |
+- = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); |
31868 |
++ |
31869 |
++ for (i = 0; i < mod->num_symtab; i++) { |
31870 |
++ char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod); |
31871 |
++ |
31872 |
++#ifdef CONFIG_PAX_KERNEXEC |
31873 |
++ pax_open_kernel(cr0); |
31874 |
++#endif |
31875 |
++ |
31876 |
++ mod->symtab[i].st_info = type; |
31877 |
++ |
31878 |
++#ifdef CONFIG_PAX_KERNEXEC |
31879 |
++ pax_close_kernel(cr0); |
31880 |
++#endif |
31881 |
++ |
31882 |
++ } |
31883 |
++ |
31884 |
+ } |
31885 |
+ #else |
31886 |
+ static inline void add_kallsyms(struct module *mod, |
31887 |
+@@ -1580,6 +1645,10 @@ static struct module *load_module(void _ |
31888 |
+ struct exception_table_entry *extable; |
31889 |
+ mm_segment_t old_fs; |
31890 |
+ |
31891 |
++#ifdef CONFIG_PAX_KERNEXEC |
31892 |
++ unsigned long cr0; |
31893 |
++#endif |
31894 |
++ |
31895 |
+ DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
31896 |
+ umod, len, uargs); |
31897 |
+ if (len < sizeof(*hdr)) |
31898 |
+@@ -1738,21 +1807,57 @@ static struct module *load_module(void _ |
31899 |
+ layout_sections(mod, hdr, sechdrs, secstrings); |
31900 |
+ |
31901 |
+ /* Do the allocs. */ |
31902 |
+- ptr = module_alloc(mod->core_size); |
31903 |
++ ptr = module_alloc(mod->core_size_rw); |
31904 |
+ if (!ptr) { |
31905 |
+ err = -ENOMEM; |
31906 |
+ goto free_percpu; |
31907 |
+ } |
31908 |
+- memset(ptr, 0, mod->core_size); |
31909 |
+- mod->module_core = ptr; |
31910 |
++ memset(ptr, 0, mod->core_size_rw); |
31911 |
++ mod->module_core_rw = ptr; |
31912 |
++ |
31913 |
++ ptr = module_alloc(mod->init_size_rw); |
31914 |
++ if (!ptr && mod->init_size_rw) { |
31915 |
++ err = -ENOMEM; |
31916 |
++ goto free_core_rw; |
31917 |
++ } |
31918 |
++ memset(ptr, 0, mod->init_size_rw); |
31919 |
++ mod->module_init_rw = ptr; |
31920 |
++ |
31921 |
++ ptr = module_alloc_exec(mod->core_size_rx); |
31922 |
++ if (!ptr) { |
31923 |
++ err = -ENOMEM; |
31924 |
++ goto free_init_rw; |
31925 |
++ } |
31926 |
++ |
31927 |
++#ifdef CONFIG_PAX_KERNEXEC |
31928 |
++ pax_open_kernel(cr0); |
31929 |
++#endif |
31930 |
+ |
31931 |
+- ptr = module_alloc(mod->init_size); |
31932 |
+- if (!ptr && mod->init_size) { |
31933 |
++ memset(ptr, 0, mod->core_size_rx); |
31934 |
++ |
31935 |
++#ifdef CONFIG_PAX_KERNEXEC |
31936 |
++ pax_close_kernel(cr0); |
31937 |
++#endif |
31938 |
++ |
31939 |
++ mod->module_core_rx = ptr; |
31940 |
++ |
31941 |
++ ptr = module_alloc_exec(mod->init_size_rx); |
31942 |
++ if (!ptr && mod->init_size_rx) { |
31943 |
+ err = -ENOMEM; |
31944 |
+- goto free_core; |
31945 |
++ goto free_core_rx; |
31946 |
+ } |
31947 |
+- memset(ptr, 0, mod->init_size); |
31948 |
+- mod->module_init = ptr; |
31949 |
++ |
31950 |
++#ifdef CONFIG_PAX_KERNEXEC |
31951 |
++ pax_open_kernel(cr0); |
31952 |
++#endif |
31953 |
++ |
31954 |
++ memset(ptr, 0, mod->init_size_rx); |
31955 |
++ |
31956 |
++#ifdef CONFIG_PAX_KERNEXEC |
31957 |
++ pax_close_kernel(cr0); |
31958 |
++#endif |
31959 |
++ |
31960 |
++ mod->module_init_rx = ptr; |
31961 |
+ |
31962 |
+ /* Transfer each section which specifies SHF_ALLOC */ |
31963 |
+ DEBUGP("final section addresses:\n"); |
31964 |
+@@ -1762,17 +1867,41 @@ static struct module *load_module(void _ |
31965 |
+ if (!(sechdrs[i].sh_flags & SHF_ALLOC)) |
31966 |
+ continue; |
31967 |
+ |
31968 |
+- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) |
31969 |
+- dest = mod->module_init |
31970 |
+- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); |
31971 |
+- else |
31972 |
+- dest = mod->module_core + sechdrs[i].sh_entsize; |
31973 |
++ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) { |
31974 |
++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC)) |
31975 |
++ dest = mod->module_init_rw |
31976 |
++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); |
31977 |
++ else |
31978 |
++ dest = mod->module_init_rx |
31979 |
++ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK); |
31980 |
++ } else { |
31981 |
++ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC)) |
31982 |
++ dest = mod->module_core_rw + sechdrs[i].sh_entsize; |
31983 |
++ else |
31984 |
++ dest = mod->module_core_rx + sechdrs[i].sh_entsize; |
31985 |
++ } |
31986 |
++ |
31987 |
++ if (sechdrs[i].sh_type != SHT_NOBITS) { |
31988 |
+ |
31989 |
+- if (sechdrs[i].sh_type != SHT_NOBITS) |
31990 |
+- memcpy(dest, (void *)sechdrs[i].sh_addr, |
31991 |
+- sechdrs[i].sh_size); |
31992 |
++#ifdef CONFIG_PAX_KERNEXEC |
31993 |
++ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) { |
31994 |
++ pax_open_kernel(cr0); |
31995 |
++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size); |
31996 |
++ pax_close_kernel(cr0); |
31997 |
++ } else |
31998 |
++#endif |
31999 |
++ |
32000 |
++ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size); |
32001 |
++ } |
32002 |
+ /* Update sh_addr to point to copy in image. */ |
32003 |
+- sechdrs[i].sh_addr = (unsigned long)dest; |
32004 |
++ |
32005 |
++#ifdef CONFIG_PAX_KERNEXEC |
32006 |
++ if (sechdrs[i].sh_flags & SHF_EXECINSTR) |
32007 |
++ sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET; |
32008 |
++ else |
32009 |
++#endif |
32010 |
++ |
32011 |
++ sechdrs[i].sh_addr = (unsigned long)dest; |
32012 |
+ DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name); |
32013 |
+ } |
32014 |
+ /* Module has been moved. */ |
32015 |
+@@ -1892,12 +2021,12 @@ static struct module *load_module(void _ |
32016 |
+ * Do it before processing of module parameters, so the module |
32017 |
+ * can provide parameter accessor functions of its own. |
32018 |
+ */ |
32019 |
+- if (mod->module_init) |
32020 |
+- flush_icache_range((unsigned long)mod->module_init, |
32021 |
+- (unsigned long)mod->module_init |
32022 |
+- + mod->init_size); |
32023 |
+- flush_icache_range((unsigned long)mod->module_core, |
32024 |
+- (unsigned long)mod->module_core + mod->core_size); |
32025 |
++ if (mod->module_init_rx) |
32026 |
++ flush_icache_range((unsigned long)mod->module_init_rx, |
32027 |
++ (unsigned long)mod->module_init_rx |
32028 |
++ + mod->init_size_rx); |
32029 |
++ flush_icache_range((unsigned long)mod->module_core_rx, |
32030 |
++ (unsigned long)mod->module_core_rx + mod->core_size_rx); |
32031 |
+ |
32032 |
+ set_fs(old_fs); |
32033 |
+ |
32034 |
+@@ -1940,9 +2069,13 @@ static struct module *load_module(void _ |
32035 |
+ module_arch_cleanup(mod); |
32036 |
+ cleanup: |
32037 |
+ module_unload_free(mod); |
32038 |
+- module_free(mod, mod->module_init); |
32039 |
+- free_core: |
32040 |
+- module_free(mod, mod->module_core); |
32041 |
++ module_free_exec(mod, mod->module_init_rx); |
32042 |
++ free_core_rx: |
32043 |
++ module_free_exec(mod, mod->module_core_rx); |
32044 |
++ free_init_rw: |
32045 |
++ module_free(mod, mod->module_init_rw); |
32046 |
++ free_core_rw: |
32047 |
++ module_free(mod, mod->module_core_rw); |
32048 |
+ free_percpu: |
32049 |
+ if (percpu) |
32050 |
+ percpu_modfree(percpu); |
32051 |
+@@ -1978,6 +2111,9 @@ sys_init_module(void __user *umod, |
32052 |
+ struct module *mod; |
32053 |
+ int ret = 0; |
32054 |
+ |
32055 |
++ if (gr_check_modstop()) |
32056 |
++ return -EPERM; |
32057 |
++ |
32058 |
+ /* Must have permission */ |
32059 |
+ if (!capable(CAP_SYS_MODULE)) |
32060 |
+ return -EPERM; |
32061 |
+@@ -2029,10 +2165,12 @@ sys_init_module(void __user *umod, |
32062 |
+ /* Drop initial reference. */ |
32063 |
+ module_put(mod); |
32064 |
+ unwind_remove_table(mod->unwind_info, 1); |
32065 |
+- module_free(mod, mod->module_init); |
32066 |
+- mod->module_init = NULL; |
32067 |
+- mod->init_size = 0; |
32068 |
+- mod->init_text_size = 0; |
32069 |
++ module_free(mod, mod->module_init_rw); |
32070 |
++ module_free_exec(mod, mod->module_init_rx); |
32071 |
++ mod->module_init_rw = NULL; |
32072 |
++ mod->module_init_rx = NULL; |
32073 |
++ mod->init_size_rw = 0; |
32074 |
++ mod->init_size_rx = 0; |
32075 |
+ mutex_unlock(&module_mutex); |
32076 |
+ |
32077 |
+ return 0; |
32078 |
+@@ -2040,6 +2178,13 @@ sys_init_module(void __user *umod, |
32079 |
+ |
32080 |
+ static inline int within(unsigned long addr, void *start, unsigned long size) |
32081 |
+ { |
32082 |
++ |
32083 |
++#ifdef CONFIG_PAX_KERNEXEC |
32084 |
++ if (addr + __KERNEL_TEXT_OFFSET >= (unsigned long)start && |
32085 |
++ addr + __KERNEL_TEXT_OFFSET < (unsigned long)start + size) |
32086 |
++ return 1; |
32087 |
++#endif |
32088 |
++ |
32089 |
+ return ((void *)addr >= start && (void *)addr < start + size); |
32090 |
+ } |
32091 |
+ |
32092 |
+@@ -2063,10 +2208,14 @@ static const char *get_ksymbol(struct mo |
32093 |
+ unsigned long nextval; |
32094 |
+ |
32095 |
+ /* At worse, next value is at end of module */ |
32096 |
+- if (within(addr, mod->module_init, mod->init_size)) |
32097 |
+- nextval = (unsigned long)mod->module_init+mod->init_text_size; |
32098 |
+- else |
32099 |
+- nextval = (unsigned long)mod->module_core+mod->core_text_size; |
32100 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx)) |
32101 |
++ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx; |
32102 |
++ else if (within(addr, mod->module_init_rw, mod->init_size_rw)) |
32103 |
++ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw; |
32104 |
++ else if (within(addr, mod->module_core_rx, mod->core_size_rx)) |
32105 |
++ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx; |
32106 |
++ else |
32107 |
++ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw; |
32108 |
+ |
32109 |
+ /* Scan for closest preceeding symbol, and next symbol. (ELF |
32110 |
+ starts real symbols at 1). */ |
32111 |
+@@ -2109,8 +2258,10 @@ const char *module_address_lookup(unsign |
32112 |
+ struct module *mod; |
32113 |
+ |
32114 |
+ list_for_each_entry(mod, &modules, list) { |
32115 |
+- if (within(addr, mod->module_init, mod->init_size) |
32116 |
+- || within(addr, mod->module_core, mod->core_size)) { |
32117 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) || |
32118 |
++ within(addr, mod->module_init_rw, mod->init_size_rw) || |
32119 |
++ within(addr, mod->module_core_rx, mod->core_size_rx) || |
32120 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32121 |
+ if (modname) |
32122 |
+ *modname = mod->name; |
32123 |
+ return get_ksymbol(mod, addr, size, offset); |
32124 |
+@@ -2125,8 +2276,10 @@ int lookup_module_symbol_name(unsigned l |
32125 |
+ |
32126 |
+ mutex_lock(&module_mutex); |
32127 |
+ list_for_each_entry(mod, &modules, list) { |
32128 |
+- if (within(addr, mod->module_init, mod->init_size) || |
32129 |
+- within(addr, mod->module_core, mod->core_size)) { |
32130 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) || |
32131 |
++ within(addr, mod->module_init_rw, mod->init_size_rw) || |
32132 |
++ within(addr, mod->module_core_rx, mod->core_size_rx) || |
32133 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32134 |
+ const char *sym; |
32135 |
+ |
32136 |
+ sym = get_ksymbol(mod, addr, NULL, NULL); |
32137 |
+@@ -2149,8 +2302,10 @@ int lookup_module_symbol_attrs(unsigned |
32138 |
+ |
32139 |
+ mutex_lock(&module_mutex); |
32140 |
+ list_for_each_entry(mod, &modules, list) { |
32141 |
+- if (within(addr, mod->module_init, mod->init_size) || |
32142 |
+- within(addr, mod->module_core, mod->core_size)) { |
32143 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) || |
32144 |
++ within(addr, mod->module_init_rw, mod->init_size_rw) || |
32145 |
++ within(addr, mod->module_core_rx, mod->core_size_rx) || |
32146 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32147 |
+ const char *sym; |
32148 |
+ |
32149 |
+ sym = get_ksymbol(mod, addr, size, offset); |
32150 |
+@@ -2270,7 +2425,7 @@ static int m_show(struct seq_file *m, vo |
32151 |
+ char buf[8]; |
32152 |
+ |
32153 |
+ seq_printf(m, "%s %lu", |
32154 |
+- mod->name, mod->init_size + mod->core_size); |
32155 |
++ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw); |
32156 |
+ print_unload_info(m, mod); |
32157 |
+ |
32158 |
+ /* Informative for users. */ |
32159 |
+@@ -2279,7 +2434,7 @@ static int m_show(struct seq_file *m, vo |
32160 |
+ mod->state == MODULE_STATE_COMING ? "Loading": |
32161 |
+ "Live"); |
32162 |
+ /* Used by oprofile and other similar tools. */ |
32163 |
+- seq_printf(m, " 0x%p", mod->module_core); |
32164 |
++ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw); |
32165 |
+ |
32166 |
+ /* Taints info */ |
32167 |
+ if (mod->taints) |
32168 |
+@@ -2335,7 +2490,8 @@ int is_module_address(unsigned long addr |
32169 |
+ preempt_disable(); |
32170 |
+ |
32171 |
+ list_for_each_entry(mod, &modules, list) { |
32172 |
+- if (within(addr, mod->module_core, mod->core_size)) { |
32173 |
++ if (within(addr, mod->module_core_rx, mod->core_size_rx) || |
32174 |
++ within(addr, mod->module_core_rw, mod->core_size_rw)) { |
32175 |
+ preempt_enable(); |
32176 |
+ return 1; |
32177 |
+ } |
32178 |
+@@ -2353,8 +2509,8 @@ struct module *__module_text_address(uns |
32179 |
+ struct module *mod; |
32180 |
+ |
32181 |
+ list_for_each_entry(mod, &modules, list) |
32182 |
+- if (within(addr, mod->module_init, mod->init_text_size) |
32183 |
+- || within(addr, mod->module_core, mod->core_text_size)) |
32184 |
++ if (within(addr, mod->module_init_rx, mod->init_size_rx) |
32185 |
++ || within(addr, mod->module_core_rx, mod->core_size_rx)) |
32186 |
+ return mod; |
32187 |
+ return NULL; |
32188 |
+ } |
32189 |
+diff -Nurp linux-2.6.23.15/kernel/mutex.c linux-2.6.23.15-grsec/kernel/mutex.c |
32190 |
+--- linux-2.6.23.15/kernel/mutex.c 2007-10-09 21:31:38.000000000 +0100 |
32191 |
++++ linux-2.6.23.15-grsec/kernel/mutex.c 2008-02-11 10:37:45.000000000 +0000 |
32192 |
+@@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou |
32193 |
+ * |
32194 |
+ * This function is similar to (but not equivalent to) down(). |
32195 |
+ */ |
32196 |
+-void inline fastcall __sched mutex_lock(struct mutex *lock) |
32197 |
++inline void fastcall __sched mutex_lock(struct mutex *lock) |
32198 |
+ { |
32199 |
+ might_sleep(); |
32200 |
+ /* |
32201 |
+diff -Nurp linux-2.6.23.15/kernel/params.c linux-2.6.23.15-grsec/kernel/params.c |
32202 |
+--- linux-2.6.23.15/kernel/params.c 2008-02-11 10:36:03.000000000 +0000 |
32203 |
++++ linux-2.6.23.15-grsec/kernel/params.c 2008-02-11 10:37:45.000000000 +0000 |
32204 |
+@@ -275,7 +275,7 @@ static int param_array(const char *name, |
32205 |
+ unsigned int min, unsigned int max, |
32206 |
+ void *elem, int elemsize, |
32207 |
+ int (*set)(const char *, struct kernel_param *kp), |
32208 |
+- int *num) |
32209 |
++ unsigned int *num) |
32210 |
+ { |
32211 |
+ int ret; |
32212 |
+ struct kernel_param kp; |
32213 |
+diff -Nurp linux-2.6.23.15/kernel/pid.c linux-2.6.23.15-grsec/kernel/pid.c |
32214 |
+--- linux-2.6.23.15/kernel/pid.c 2007-10-09 21:31:38.000000000 +0100 |
32215 |
++++ linux-2.6.23.15-grsec/kernel/pid.c 2008-02-11 10:37:45.000000000 +0000 |
32216 |
+@@ -28,6 +28,7 @@ |
32217 |
+ #include <linux/hash.h> |
32218 |
+ #include <linux/pid_namespace.h> |
32219 |
+ #include <linux/init_task.h> |
32220 |
++#include <linux/grsecurity.h> |
32221 |
+ |
32222 |
+ #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift) |
32223 |
+ static struct hlist_head *pid_hash; |
32224 |
+@@ -37,7 +38,7 @@ struct pid init_struct_pid = INIT_STRUCT |
32225 |
+ |
32226 |
+ int pid_max = PID_MAX_DEFAULT; |
32227 |
+ |
32228 |
+-#define RESERVED_PIDS 300 |
32229 |
++#define RESERVED_PIDS 500 |
32230 |
+ |
32231 |
+ int pid_max_min = RESERVED_PIDS + 1; |
32232 |
+ int pid_max_max = PID_MAX_LIMIT; |
32233 |
+@@ -309,7 +310,14 @@ struct task_struct * fastcall pid_task(s |
32234 |
+ */ |
32235 |
+ struct task_struct *find_task_by_pid_type(int type, int nr) |
32236 |
+ { |
32237 |
+- return pid_task(find_pid(nr), type); |
32238 |
++ struct task_struct *task; |
32239 |
++ |
32240 |
++ task = pid_task(find_pid(nr), type); |
32241 |
++ |
32242 |
++ if (gr_pid_is_chrooted(task)) |
32243 |
++ return NULL; |
32244 |
++ |
32245 |
++ return task; |
32246 |
+ } |
32247 |
+ |
32248 |
+ EXPORT_SYMBOL(find_task_by_pid_type); |
32249 |
+diff -Nurp linux-2.6.23.15/kernel/posix-cpu-timers.c linux-2.6.23.15-grsec/kernel/posix-cpu-timers.c |
32250 |
+--- linux-2.6.23.15/kernel/posix-cpu-timers.c 2007-10-09 21:31:38.000000000 +0100 |
32251 |
++++ linux-2.6.23.15-grsec/kernel/posix-cpu-timers.c 2008-02-11 10:37:45.000000000 +0000 |
32252 |
+@@ -6,6 +6,7 @@ |
32253 |
+ #include <linux/posix-timers.h> |
32254 |
+ #include <asm/uaccess.h> |
32255 |
+ #include <linux/errno.h> |
32256 |
++#include <linux/grsecurity.h> |
32257 |
+ |
32258 |
+ static int check_clock(const clockid_t which_clock) |
32259 |
+ { |
32260 |
+@@ -1144,6 +1145,7 @@ static void check_process_timers(struct |
32261 |
+ __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk); |
32262 |
+ return; |
32263 |
+ } |
32264 |
++ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1); |
32265 |
+ if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) { |
32266 |
+ /* |
32267 |
+ * At the soft limit, send a SIGXCPU every second. |
32268 |
+diff -Nurp linux-2.6.23.15/kernel/power/poweroff.c linux-2.6.23.15-grsec/kernel/power/poweroff.c |
32269 |
+--- linux-2.6.23.15/kernel/power/poweroff.c 2007-10-09 21:31:38.000000000 +0100 |
32270 |
++++ linux-2.6.23.15-grsec/kernel/power/poweroff.c 2008-02-11 10:37:45.000000000 +0000 |
32271 |
+@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof |
32272 |
+ .enable_mask = SYSRQ_ENABLE_BOOT, |
32273 |
+ }; |
32274 |
+ |
32275 |
+-static int pm_sysrq_init(void) |
32276 |
++static int __init pm_sysrq_init(void) |
32277 |
+ { |
32278 |
+ register_sysrq_key('o', &sysrq_poweroff_op); |
32279 |
+ return 0; |
32280 |
+diff -Nurp linux-2.6.23.15/kernel/printk.c linux-2.6.23.15-grsec/kernel/printk.c |
32281 |
+--- linux-2.6.23.15/kernel/printk.c 2007-10-09 21:31:38.000000000 +0100 |
32282 |
++++ linux-2.6.23.15-grsec/kernel/printk.c 2008-02-11 10:37:45.000000000 +0000 |
32283 |
+@@ -31,6 +31,7 @@ |
32284 |
+ #include <linux/bootmem.h> |
32285 |
+ #include <linux/syscalls.h> |
32286 |
+ #include <linux/jiffies.h> |
32287 |
++#include <linux/grsecurity.h> |
32288 |
+ |
32289 |
+ #include <asm/uaccess.h> |
32290 |
+ |
32291 |
+@@ -184,6 +185,11 @@ int do_syslog(int type, char __user *buf |
32292 |
+ char c; |
32293 |
+ int error = 0; |
32294 |
+ |
32295 |
++#ifdef CONFIG_GRKERNSEC_DMESG |
32296 |
++ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN)) |
32297 |
++ return -EPERM; |
32298 |
++#endif |
32299 |
++ |
32300 |
+ error = security_syslog(type); |
32301 |
+ if (error) |
32302 |
+ return error; |
32303 |
+diff -Nurp linux-2.6.23.15/kernel/ptrace.c linux-2.6.23.15-grsec/kernel/ptrace.c |
32304 |
+--- linux-2.6.23.15/kernel/ptrace.c 2007-10-09 21:31:38.000000000 +0100 |
32305 |
++++ linux-2.6.23.15-grsec/kernel/ptrace.c 2008-02-11 10:37:45.000000000 +0000 |
32306 |
+@@ -19,6 +19,7 @@ |
32307 |
+ #include <linux/security.h> |
32308 |
+ #include <linux/signal.h> |
32309 |
+ #include <linux/audit.h> |
32310 |
++#include <linux/grsecurity.h> |
32311 |
+ |
32312 |
+ #include <asm/pgtable.h> |
32313 |
+ #include <asm/uaccess.h> |
32314 |
+@@ -138,12 +139,12 @@ static int may_attach(struct task_struct |
32315 |
+ (current->uid != task->uid) || |
32316 |
+ (current->gid != task->egid) || |
32317 |
+ (current->gid != task->sgid) || |
32318 |
+- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) |
32319 |
++ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE)) |
32320 |
+ return -EPERM; |
32321 |
+ smp_rmb(); |
32322 |
+ if (task->mm) |
32323 |
+ dumpable = get_dumpable(task->mm); |
32324 |
+- if (!dumpable && !capable(CAP_SYS_PTRACE)) |
32325 |
++ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE)) |
32326 |
+ return -EPERM; |
32327 |
+ |
32328 |
+ return security_ptrace(current, task); |
32329 |
+@@ -480,6 +481,11 @@ asmlinkage long sys_ptrace(long request, |
32330 |
+ if (ret < 0) |
32331 |
+ goto out_put_task_struct; |
32332 |
+ |
32333 |
++ if (gr_handle_ptrace(child, request)) { |
32334 |
++ ret = -EPERM; |
32335 |
++ goto out_put_task_struct; |
32336 |
++ } |
32337 |
++ |
32338 |
+ ret = arch_ptrace(child, request, addr, data); |
32339 |
+ if (ret < 0) |
32340 |
+ goto out_put_task_struct; |
32341 |
+diff -Nurp linux-2.6.23.15/kernel/rcupdate.c linux-2.6.23.15-grsec/kernel/rcupdate.c |
32342 |
+--- linux-2.6.23.15/kernel/rcupdate.c 2007-10-09 21:31:38.000000000 +0100 |
32343 |
++++ linux-2.6.23.15-grsec/kernel/rcupdate.c 2008-02-11 10:37:45.000000000 +0000 |
32344 |
+@@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk |
32345 |
+ .cpumask = CPU_MASK_NONE, |
32346 |
+ }; |
32347 |
+ |
32348 |
+-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L }; |
32349 |
+-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L }; |
32350 |
++DEFINE_PER_CPU(struct rcu_data, rcu_data); |
32351 |
++DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); |
32352 |
+ |
32353 |
+ /* Fake initialization required by compiler */ |
32354 |
+-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL}; |
32355 |
++static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet); |
32356 |
+ static int blimit = 10; |
32357 |
+ static int qhimark = 10000; |
32358 |
+ static int qlowmark = 100; |
32359 |
+diff -Nurp linux-2.6.23.15/kernel/relay.c linux-2.6.23.15-grsec/kernel/relay.c |
32360 |
+--- linux-2.6.23.15/kernel/relay.c 2008-02-11 10:36:03.000000000 +0000 |
32361 |
++++ linux-2.6.23.15-grsec/kernel/relay.c 2008-02-11 10:37:45.000000000 +0000 |
32362 |
+@@ -1140,7 +1140,7 @@ static int subbuf_splice_actor(struct fi |
32363 |
+ return 0; |
32364 |
+ |
32365 |
+ ret = *nonpad_ret = splice_to_pipe(pipe, &spd); |
32366 |
+- if (ret < 0 || ret < total_len) |
32367 |
++ if ((int)ret < 0 || ret < total_len) |
32368 |
+ return ret; |
32369 |
+ |
32370 |
+ if (read_start + ret == nonpad_end) |
32371 |
+diff -Nurp linux-2.6.23.15/kernel/resource.c linux-2.6.23.15-grsec/kernel/resource.c |
32372 |
+--- linux-2.6.23.15/kernel/resource.c 2007-10-09 21:31:38.000000000 +0100 |
32373 |
++++ linux-2.6.23.15-grsec/kernel/resource.c 2008-02-11 10:37:45.000000000 +0000 |
32374 |
+@@ -133,10 +133,27 @@ static int __init ioresources_init(void) |
32375 |
+ { |
32376 |
+ struct proc_dir_entry *entry; |
32377 |
+ |
32378 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
32379 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
32380 |
++ entry = create_proc_entry("ioports", S_IRUSR, NULL); |
32381 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
32382 |
++ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL); |
32383 |
++#endif |
32384 |
++#else |
32385 |
+ entry = create_proc_entry("ioports", 0, NULL); |
32386 |
++#endif |
32387 |
+ if (entry) |
32388 |
+ entry->proc_fops = &proc_ioports_operations; |
32389 |
++ |
32390 |
++#ifdef CONFIG_GRKERNSEC_PROC_ADD |
32391 |
++#ifdef CONFIG_GRKERNSEC_PROC_USER |
32392 |
++ entry = create_proc_entry("iomem", S_IRUSR, NULL); |
32393 |
++#elif CONFIG_GRKERNSEC_PROC_USERGROUP |
32394 |
++ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL); |
32395 |
++#endif |
32396 |
++#else |
32397 |
+ entry = create_proc_entry("iomem", 0, NULL); |
32398 |
++#endif |
32399 |
+ if (entry) |
32400 |
+ entry->proc_fops = &proc_iomem_operations; |
32401 |
+ return 0; |
32402 |
+diff -Nurp linux-2.6.23.15/kernel/sched.c linux-2.6.23.15-grsec/kernel/sched.c |
32403 |
+--- linux-2.6.23.15/kernel/sched.c 2008-02-11 10:36:03.000000000 +0000 |
32404 |
++++ linux-2.6.23.15-grsec/kernel/sched.c 2008-02-11 10:37:45.000000000 +0000 |
32405 |
+@@ -61,6 +61,7 @@ |
32406 |
+ #include <linux/delayacct.h> |
32407 |
+ #include <linux/reciprocal_div.h> |
32408 |
+ #include <linux/unistd.h> |
32409 |
++#include <linux/grsecurity.h> |
32410 |
+ |
32411 |
+ #include <asm/tlb.h> |
32412 |
+ |
32413 |
+@@ -3470,7 +3471,7 @@ pick_next_task(struct rq *rq, struct tas |
32414 |
+ asmlinkage void __sched schedule(void) |
32415 |
+ { |
32416 |
+ struct task_struct *prev, *next; |
32417 |
+- long *switch_count; |
32418 |
++ unsigned long *switch_count; |
32419 |
+ struct rq *rq; |
32420 |
+ int cpu; |
32421 |
+ |
32422 |
+@@ -4079,7 +4080,8 @@ asmlinkage long sys_nice(int increment) |
32423 |
+ if (nice > 19) |
32424 |
+ nice = 19; |
32425 |
+ |
32426 |
+- if (increment < 0 && !can_nice(current, nice)) |
32427 |
++ if (increment < 0 && (!can_nice(current, nice) || |
32428 |
++ gr_handle_chroot_nice())) |
32429 |
+ return -EPERM; |
32430 |
+ |
32431 |
+ retval = security_task_setnice(current, nice); |
32432 |
+@@ -5267,7 +5269,7 @@ static struct ctl_table sd_ctl_dir[] = { |
32433 |
+ .procname = "sched_domain", |
32434 |
+ .mode = 0555, |
32435 |
+ }, |
32436 |
+- {0,}, |
32437 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }, |
32438 |
+ }; |
32439 |
+ |
32440 |
+ static struct ctl_table sd_ctl_root[] = { |
32441 |
+@@ -5277,7 +5279,7 @@ static struct ctl_table sd_ctl_root[] = |
32442 |
+ .mode = 0555, |
32443 |
+ .child = sd_ctl_dir, |
32444 |
+ }, |
32445 |
+- {0,}, |
32446 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }, |
32447 |
+ }; |
32448 |
+ |
32449 |
+ static struct ctl_table *sd_alloc_ctl_entry(int n) |
32450 |
+diff -Nurp linux-2.6.23.15/kernel/signal.c linux-2.6.23.15-grsec/kernel/signal.c |
32451 |
+--- linux-2.6.23.15/kernel/signal.c 2007-10-09 21:31:38.000000000 +0100 |
32452 |
++++ linux-2.6.23.15-grsec/kernel/signal.c 2008-02-11 10:37:45.000000000 +0000 |
32453 |
+@@ -25,6 +25,7 @@ |
32454 |
+ #include <linux/capability.h> |
32455 |
+ #include <linux/freezer.h> |
32456 |
+ #include <linux/pid_namespace.h> |
32457 |
++#include <linux/grsecurity.h> |
32458 |
+ #include <linux/nsproxy.h> |
32459 |
+ |
32460 |
+ #include <asm/param.h> |
32461 |
+@@ -541,7 +542,9 @@ static int check_kill_permission(int sig |
32462 |
+ && (current->euid ^ t->suid) && (current->euid ^ t->uid) |
32463 |
+ && (current->uid ^ t->suid) && (current->uid ^ t->uid) |
32464 |
+ && !capable(CAP_KILL)) |
32465 |
+- return error; |
32466 |
++ return error; |
32467 |
++ if (gr_handle_signal(t, sig)) |
32468 |
++ return error; |
32469 |
+ } |
32470 |
+ |
32471 |
+ return security_task_kill(t, info, sig, 0); |
32472 |
+@@ -758,7 +761,7 @@ static int __init setup_print_fatal_sign |
32473 |
+ |
32474 |
+ __setup("print-fatal-signals=", setup_print_fatal_signals); |
32475 |
+ |
32476 |
+-static int |
32477 |
++int |
32478 |
+ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) |
32479 |
+ { |
32480 |
+ int ret = 0; |
32481 |
+@@ -812,8 +815,12 @@ force_sig_info(int sig, struct siginfo * |
32482 |
+ } |
32483 |
+ } |
32484 |
+ ret = specific_send_sig_info(sig, info, t); |
32485 |
++ |
32486 |
+ spin_unlock_irqrestore(&t->sighand->siglock, flags); |
32487 |
+ |
32488 |
++ gr_log_signal(sig, t); |
32489 |
++ gr_handle_crash(t, sig); |
32490 |
++ |
32491 |
+ return ret; |
32492 |
+ } |
32493 |
+ |
32494 |
+diff -Nurp linux-2.6.23.15/kernel/softirq.c linux-2.6.23.15-grsec/kernel/softirq.c |
32495 |
+--- linux-2.6.23.15/kernel/softirq.c 2007-10-09 21:31:38.000000000 +0100 |
32496 |
++++ linux-2.6.23.15-grsec/kernel/softirq.c 2008-02-11 10:37:45.000000000 +0000 |
32497 |
+@@ -471,9 +471,9 @@ void tasklet_kill(struct tasklet_struct |
32498 |
+ printk("Attempt to kill tasklet from interrupt\n"); |
32499 |
+ |
32500 |
+ while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { |
32501 |
+- do |
32502 |
++ do { |
32503 |
+ yield(); |
32504 |
+- while (test_bit(TASKLET_STATE_SCHED, &t->state)); |
32505 |
++ } while (test_bit(TASKLET_STATE_SCHED, &t->state)); |
32506 |
+ } |
32507 |
+ tasklet_unlock_wait(t); |
32508 |
+ clear_bit(TASKLET_STATE_SCHED, &t->state); |
32509 |
+diff -Nurp linux-2.6.23.15/kernel/sys.c linux-2.6.23.15-grsec/kernel/sys.c |
32510 |
+--- linux-2.6.23.15/kernel/sys.c 2007-10-09 21:31:38.000000000 +0100 |
32511 |
++++ linux-2.6.23.15-grsec/kernel/sys.c 2008-02-11 10:37:45.000000000 +0000 |
32512 |
+@@ -33,6 +33,7 @@ |
32513 |
+ #include <linux/task_io_accounting_ops.h> |
32514 |
+ #include <linux/seccomp.h> |
32515 |
+ #include <linux/cpu.h> |
32516 |
++#include <linux/grsecurity.h> |
32517 |
+ |
32518 |
+ #include <linux/compat.h> |
32519 |
+ #include <linux/syscalls.h> |
32520 |
+@@ -651,6 +652,12 @@ static int set_one_prio(struct task_stru |
32521 |
+ error = -EACCES; |
32522 |
+ goto out; |
32523 |
+ } |
32524 |
++ |
32525 |
++ if (gr_handle_chroot_setpriority(p, niceval)) { |
32526 |
++ error = -EACCES; |
32527 |
++ goto out; |
32528 |
++ } |
32529 |
++ |
32530 |
+ no_nice = security_task_setnice(p, niceval); |
32531 |
+ if (no_nice) { |
32532 |
+ error = no_nice; |
32533 |
+@@ -707,10 +714,10 @@ asmlinkage long sys_setpriority(int whic |
32534 |
+ if ((who != current->uid) && !(user = find_user(who))) |
32535 |
+ goto out_unlock; /* No processes for this user */ |
32536 |
+ |
32537 |
+- do_each_thread(g, p) |
32538 |
++ do_each_thread(g, p) { |
32539 |
+ if (p->uid == who) |
32540 |
+ error = set_one_prio(p, niceval, error); |
32541 |
+- while_each_thread(g, p); |
32542 |
++ } while_each_thread(g, p); |
32543 |
+ if (who != current->uid) |
32544 |
+ free_uid(user); /* For find_user() */ |
32545 |
+ break; |
32546 |
+@@ -769,13 +776,13 @@ asmlinkage long sys_getpriority(int whic |
32547 |
+ if ((who != current->uid) && !(user = find_user(who))) |
32548 |
+ goto out_unlock; /* No processes for this user */ |
32549 |
+ |
32550 |
+- do_each_thread(g, p) |
32551 |
++ do_each_thread(g, p) { |
32552 |
+ if (p->uid == who) { |
32553 |
+ niceval = 20 - task_nice(p); |
32554 |
+ if (niceval > retval) |
32555 |
+ retval = niceval; |
32556 |
+ } |
32557 |
+- while_each_thread(g, p); |
32558 |
++ } while_each_thread(g, p); |
32559 |
+ if (who != current->uid) |
32560 |
+ free_uid(user); /* for find_user() */ |
32561 |
+ break; |
32562 |
+@@ -1047,6 +1054,9 @@ asmlinkage long sys_setregid(gid_t rgid, |
32563 |
+ if (rgid != (gid_t) -1 || |
32564 |
+ (egid != (gid_t) -1 && egid != old_rgid)) |
32565 |
+ current->sgid = new_egid; |
32566 |
++ |
32567 |
++ gr_set_role_label(current, current->uid, new_rgid); |
32568 |
++ |
32569 |
+ current->fsgid = new_egid; |
32570 |
+ current->egid = new_egid; |
32571 |
+ current->gid = new_rgid; |
32572 |
+@@ -1074,6 +1084,9 @@ asmlinkage long sys_setgid(gid_t gid) |
32573 |
+ set_dumpable(current->mm, suid_dumpable); |
32574 |
+ smp_wmb(); |
32575 |
+ } |
32576 |
++ |
32577 |
++ gr_set_role_label(current, current->uid, gid); |
32578 |
++ |
32579 |
+ current->gid = current->egid = current->sgid = current->fsgid = gid; |
32580 |
+ } else if ((gid == current->gid) || (gid == current->sgid)) { |
32581 |
+ if (old_egid != gid) { |
32582 |
+@@ -1111,6 +1124,9 @@ static int set_user(uid_t new_ruid, int |
32583 |
+ set_dumpable(current->mm, suid_dumpable); |
32584 |
+ smp_wmb(); |
32585 |
+ } |
32586 |
++ |
32587 |
++ gr_set_role_label(current, new_ruid, current->gid); |
32588 |
++ |
32589 |
+ current->uid = new_ruid; |
32590 |
+ return 0; |
32591 |
+ } |
32592 |
+@@ -1213,6 +1229,9 @@ asmlinkage long sys_setuid(uid_t uid) |
32593 |
+ } else if ((uid != current->uid) && (uid != new_suid)) |
32594 |
+ return -EPERM; |
32595 |
+ |
32596 |
++ if (gr_check_crash_uid(uid)) |
32597 |
++ return -EPERM; |
32598 |
++ |
32599 |
+ if (old_euid != uid) { |
32600 |
+ set_dumpable(current->mm, suid_dumpable); |
32601 |
+ smp_wmb(); |
32602 |
+@@ -1315,8 +1334,10 @@ asmlinkage long sys_setresgid(gid_t rgid |
32603 |
+ current->egid = egid; |
32604 |
+ } |
32605 |
+ current->fsgid = current->egid; |
32606 |
+- if (rgid != (gid_t) -1) |
32607 |
++ if (rgid != (gid_t) -1) { |
32608 |
++ gr_set_role_label(current, current->uid, rgid); |
32609 |
+ current->gid = rgid; |
32610 |
++ } |
32611 |
+ if (sgid != (gid_t) -1) |
32612 |
+ current->sgid = sgid; |
32613 |
+ |
32614 |
+@@ -1463,7 +1484,10 @@ asmlinkage long sys_setpgid(pid_t pid, p |
32615 |
+ write_lock_irq(&tasklist_lock); |
32616 |
+ |
32617 |
+ err = -ESRCH; |
32618 |
+- p = find_task_by_pid(pid); |
32619 |
++ /* grsec: replaced find_task_by_pid with equivalent call |
32620 |
++ which lacks the chroot restriction |
32621 |
++ */ |
32622 |
++ p = pid_task(find_pid(pid), PIDTYPE_PID); |
32623 |
+ if (!p) |
32624 |
+ goto out; |
32625 |
+ |
32626 |
+@@ -2183,7 +2207,7 @@ asmlinkage long sys_prctl(int option, un |
32627 |
+ error = get_dumpable(current->mm); |
32628 |
+ break; |
32629 |
+ case PR_SET_DUMPABLE: |
32630 |
+- if (arg2 < 0 || arg2 > 1) { |
32631 |
++ if (arg2 > 1) { |
32632 |
+ error = -EINVAL; |
32633 |
+ break; |
32634 |
+ } |
32635 |
+diff -Nurp linux-2.6.23.15/kernel/sysctl.c linux-2.6.23.15-grsec/kernel/sysctl.c |
32636 |
+--- linux-2.6.23.15/kernel/sysctl.c 2008-02-11 10:36:24.000000000 +0000 |
32637 |
++++ linux-2.6.23.15-grsec/kernel/sysctl.c 2008-02-11 10:37:45.000000000 +0000 |
32638 |
+@@ -56,6 +56,13 @@ |
32639 |
+ #endif |
32640 |
+ |
32641 |
+ #if defined(CONFIG_SYSCTL) |
32642 |
++#include <linux/grsecurity.h> |
32643 |
++#include <linux/grinternal.h> |
32644 |
++ |
32645 |
++extern __u32 gr_handle_sysctl(const ctl_table *table, const int op); |
32646 |
++extern int gr_handle_sysctl_mod(const char *dirname, const char *name, |
32647 |
++ const int op); |
32648 |
++extern int gr_handle_chroot_sysctl(const int op); |
32649 |
+ |
32650 |
+ /* External variables not in a header file. */ |
32651 |
+ extern int C_A_D; |
32652 |
+@@ -141,7 +148,7 @@ static int proc_dointvec_taint(ctl_table |
32653 |
+ |
32654 |
+ static ctl_table root_table[]; |
32655 |
+ static struct ctl_table_header root_table_header = |
32656 |
+- { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; |
32657 |
++ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL }; |
32658 |
+ |
32659 |
+ static ctl_table kern_table[]; |
32660 |
+ static ctl_table vm_table[]; |
32661 |
+@@ -158,11 +165,27 @@ extern ctl_table inotify_table[]; |
32662 |
+ #ifdef CONFIG_ALPHA_UAC_SYSCTL |
32663 |
+ extern ctl_table uac_table[]; |
32664 |
+ #endif |
32665 |
++extern ctl_table grsecurity_table[]; |
32666 |
+ |
32667 |
+ #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT |
32668 |
+ int sysctl_legacy_va_layout; |
32669 |
+ #endif |
32670 |
+ |
32671 |
++#ifdef CONFIG_PAX_SOFTMODE |
32672 |
++static ctl_table pax_table[] = { |
32673 |
++ { |
32674 |
++ .ctl_name = CTL_UNNUMBERED, |
32675 |
++ .procname = "softmode", |
32676 |
++ .data = &pax_softmode, |
32677 |
++ .maxlen = sizeof(unsigned int), |
32678 |
++ .mode = 0600, |
32679 |
++ .proc_handler = &proc_dointvec, |
32680 |
++ }, |
32681 |
++ |
32682 |
++ { .ctl_name = 0 } |
32683 |
++}; |
32684 |
++#endif |
32685 |
++ |
32686 |
+ extern int prove_locking; |
32687 |
+ extern int lock_stat; |
32688 |
+ |
32689 |
+@@ -207,6 +230,16 @@ static ctl_table root_table[] = { |
32690 |
+ .mode = 0555, |
32691 |
+ .child = dev_table, |
32692 |
+ }, |
32693 |
++ |
32694 |
++#ifdef CONFIG_PAX_SOFTMODE |
32695 |
++ { |
32696 |
++ .ctl_name = CTL_UNNUMBERED, |
32697 |
++ .procname = "pax", |
32698 |
++ .mode = 0500, |
32699 |
++ .child = pax_table, |
32700 |
++ }, |
32701 |
++#endif |
32702 |
++ |
32703 |
+ /* |
32704 |
+ * NOTE: do not add new entries to this table unless you have read |
32705 |
+ * Documentation/sysctl/ctl_unnumbered.txt |
32706 |
+@@ -777,6 +810,14 @@ static ctl_table kern_table[] = { |
32707 |
+ .proc_handler = &proc_dostring, |
32708 |
+ .strategy = &sysctl_string, |
32709 |
+ }, |
32710 |
++#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP) |
32711 |
++ { |
32712 |
++ .ctl_name = KERN_GRSECURITY, |
32713 |
++ .procname = "grsecurity", |
32714 |
++ .mode = 0500, |
32715 |
++ .child = grsecurity_table, |
32716 |
++ }, |
32717 |
++#endif |
32718 |
+ /* |
32719 |
+ * NOTE: do not add new entries to this table unless you have read |
32720 |
+ * Documentation/sysctl/ctl_unnumbered.txt |
32721 |
+@@ -1388,6 +1429,25 @@ static int test_perm(int mode, int op) |
32722 |
+ int sysctl_perm(ctl_table *table, int op) |
32723 |
+ { |
32724 |
+ int error; |
32725 |
++ if (table->parent != NULL && table->parent->procname != NULL && |
32726 |
++ table->procname != NULL && |
32727 |
++ gr_handle_sysctl_mod(table->parent->procname, table->procname, op)) |
32728 |
++ return -EACCES; |
32729 |
++ if (gr_handle_chroot_sysctl(op)) |
32730 |
++ return -EACCES; |
32731 |
++ error = gr_handle_sysctl(table, op); |
32732 |
++ if (error) |
32733 |
++ return error; |
32734 |
++ error = security_sysctl(table, op); |
32735 |
++ if (error) |
32736 |
++ return error; |
32737 |
++ return test_perm(table->mode, op); |
32738 |
++} |
32739 |
++ |
32740 |
++int sysctl_perm_nochk(ctl_table *table, int op) |
32741 |
++{ |
32742 |
++ int error; |
32743 |
++ |
32744 |
+ error = security_sysctl(table, op); |
32745 |
+ if (error) |
32746 |
+ return error; |
32747 |
+@@ -1412,13 +1472,14 @@ repeat: |
32748 |
+ if (n == table->ctl_name) { |
32749 |
+ int error; |
32750 |
+ if (table->child) { |
32751 |
+- if (sysctl_perm(table, 001)) |
32752 |
++ if (sysctl_perm_nochk(table, 001)) |
32753 |
+ return -EPERM; |
32754 |
+ name++; |
32755 |
+ nlen--; |
32756 |
+ table = table->child; |
32757 |
+ goto repeat; |
32758 |
+ } |
32759 |
++ |
32760 |
+ error = do_sysctl_strategy(table, name, nlen, |
32761 |
+ oldval, oldlenp, |
32762 |
+ newval, newlen); |
32763 |
+diff -Nurp linux-2.6.23.15/kernel/time.c linux-2.6.23.15-grsec/kernel/time.c |
32764 |
+--- linux-2.6.23.15/kernel/time.c 2007-10-09 21:31:38.000000000 +0100 |
32765 |
++++ linux-2.6.23.15-grsec/kernel/time.c 2008-02-11 10:37:45.000000000 +0000 |
32766 |
+@@ -35,6 +35,7 @@ |
32767 |
+ #include <linux/security.h> |
32768 |
+ #include <linux/fs.h> |
32769 |
+ #include <linux/module.h> |
32770 |
++#include <linux/grsecurity.h> |
32771 |
+ |
32772 |
+ #include <asm/uaccess.h> |
32773 |
+ #include <asm/unistd.h> |
32774 |
+@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user |
32775 |
+ return err; |
32776 |
+ |
32777 |
+ do_settimeofday(&tv); |
32778 |
++ |
32779 |
++ gr_log_timechange(); |
32780 |
++ |
32781 |
+ return 0; |
32782 |
+ } |
32783 |
+ |
32784 |
+@@ -197,6 +201,8 @@ asmlinkage long sys_settimeofday(struct |
32785 |
+ return -EFAULT; |
32786 |
+ } |
32787 |
+ |
32788 |
++ gr_log_timechange(); |
32789 |
++ |
32790 |
+ return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); |
32791 |
+ } |
32792 |
+ |
32793 |
+@@ -235,7 +241,7 @@ EXPORT_SYMBOL(current_fs_time); |
32794 |
+ * Avoid unnecessary multiplications/divisions in the |
32795 |
+ * two most common HZ cases: |
32796 |
+ */ |
32797 |
+-unsigned int inline jiffies_to_msecs(const unsigned long j) |
32798 |
++inline unsigned int jiffies_to_msecs(const unsigned long j) |
32799 |
+ { |
32800 |
+ #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) |
32801 |
+ return (MSEC_PER_SEC / HZ) * j; |
32802 |
+@@ -247,7 +253,7 @@ unsigned int inline jiffies_to_msecs(con |
32803 |
+ } |
32804 |
+ EXPORT_SYMBOL(jiffies_to_msecs); |
32805 |
+ |
32806 |
+-unsigned int inline jiffies_to_usecs(const unsigned long j) |
32807 |
++inline unsigned int jiffies_to_usecs(const unsigned long j) |
32808 |
+ { |
32809 |
+ #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) |
32810 |
+ return (USEC_PER_SEC / HZ) * j; |
32811 |
+diff -Nurp linux-2.6.23.15/kernel/utsname_sysctl.c linux-2.6.23.15-grsec/kernel/utsname_sysctl.c |
32812 |
+--- linux-2.6.23.15/kernel/utsname_sysctl.c 2007-10-09 21:31:38.000000000 +0100 |
32813 |
++++ linux-2.6.23.15-grsec/kernel/utsname_sysctl.c 2008-02-11 10:37:45.000000000 +0000 |
32814 |
+@@ -121,7 +121,7 @@ static struct ctl_table uts_kern_table[] |
32815 |
+ .proc_handler = proc_do_uts_string, |
32816 |
+ .strategy = sysctl_uts_string, |
32817 |
+ }, |
32818 |
+- {} |
32819 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
32820 |
+ }; |
32821 |
+ |
32822 |
+ static struct ctl_table uts_root_table[] = { |
32823 |
+@@ -131,7 +131,7 @@ static struct ctl_table uts_root_table[] |
32824 |
+ .mode = 0555, |
32825 |
+ .child = uts_kern_table, |
32826 |
+ }, |
32827 |
+- {} |
32828 |
++ { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL } |
32829 |
+ }; |
32830 |
+ |
32831 |
+ static int __init utsname_sysctl_init(void) |
32832 |
+diff -Nurp linux-2.6.23.15/lib/radix-tree.c linux-2.6.23.15-grsec/lib/radix-tree.c |
32833 |
+--- linux-2.6.23.15/lib/radix-tree.c 2007-10-09 21:31:38.000000000 +0100 |
32834 |
++++ linux-2.6.23.15-grsec/lib/radix-tree.c 2008-02-11 10:37:45.000000000 +0000 |
32835 |
+@@ -76,7 +76,7 @@ struct radix_tree_preload { |
32836 |
+ int nr; |
32837 |
+ struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH]; |
32838 |
+ }; |
32839 |
+-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, }; |
32840 |
++DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} }; |
32841 |
+ |
32842 |
+ static inline gfp_t root_gfp_mask(struct radix_tree_root *root) |
32843 |
+ { |
32844 |
+diff -Nurp linux-2.6.23.15/mm/filemap.c linux-2.6.23.15-grsec/mm/filemap.c |
32845 |
+--- linux-2.6.23.15/mm/filemap.c 2008-02-11 10:36:03.000000000 +0000 |
32846 |
++++ linux-2.6.23.15-grsec/mm/filemap.c 2008-02-11 10:37:45.000000000 +0000 |
32847 |
+@@ -30,6 +30,7 @@ |
32848 |
+ #include <linux/security.h> |
32849 |
+ #include <linux/syscalls.h> |
32850 |
+ #include <linux/cpuset.h> |
32851 |
++#include <linux/grsecurity.h> |
32852 |
+ #include "filemap.h" |
32853 |
+ #include "internal.h" |
32854 |
+ |
32855 |
+@@ -1461,7 +1462,7 @@ int generic_file_mmap(struct file * file |
32856 |
+ struct address_space *mapping = file->f_mapping; |
32857 |
+ |
32858 |
+ if (!mapping->a_ops->readpage) |
32859 |
+- return -ENOEXEC; |
32860 |
++ return -ENODEV; |
32861 |
+ file_accessed(file); |
32862 |
+ vma->vm_ops = &generic_file_vm_ops; |
32863 |
+ vma->vm_flags |= VM_CAN_NONLINEAR; |
32864 |
+@@ -1726,6 +1727,7 @@ inline int generic_write_checks(struct f |
32865 |
+ *pos = i_size_read(inode); |
32866 |
+ |
32867 |
+ if (limit != RLIM_INFINITY) { |
32868 |
++ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0); |
32869 |
+ if (*pos >= limit) { |
32870 |
+ send_sig(SIGXFSZ, current, 0); |
32871 |
+ return -EFBIG; |
32872 |
+diff -Nurp linux-2.6.23.15/mm/fremap.c linux-2.6.23.15-grsec/mm/fremap.c |
32873 |
+--- linux-2.6.23.15/mm/fremap.c 2007-10-09 21:31:38.000000000 +0100 |
32874 |
++++ linux-2.6.23.15-grsec/mm/fremap.c 2008-02-11 10:37:45.000000000 +0000 |
32875 |
+@@ -148,6 +148,13 @@ asmlinkage long sys_remap_file_pages(uns |
32876 |
+ retry: |
32877 |
+ vma = find_vma(mm, start); |
32878 |
+ |
32879 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32880 |
++ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) { |
32881 |
++ up_read(&mm->mmap_sem); |
32882 |
++ return err; |
32883 |
++ } |
32884 |
++#endif |
32885 |
++ |
32886 |
+ /* |
32887 |
+ * Make sure the vma is shared, that it supports prefaulting, |
32888 |
+ * and that the remapped range is valid and fully within |
32889 |
+diff -Nurp linux-2.6.23.15/mm/hugetlb.c linux-2.6.23.15-grsec/mm/hugetlb.c |
32890 |
+--- linux-2.6.23.15/mm/hugetlb.c 2007-10-09 21:31:38.000000000 +0100 |
32891 |
++++ linux-2.6.23.15-grsec/mm/hugetlb.c 2008-02-11 10:37:45.000000000 +0000 |
32892 |
+@@ -460,6 +460,26 @@ void unmap_hugepage_range(struct vm_area |
32893 |
+ } |
32894 |
+ } |
32895 |
+ |
32896 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32897 |
++static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m) |
32898 |
++{ |
32899 |
++ struct mm_struct *mm = vma->vm_mm; |
32900 |
++ struct vm_area_struct *vma_m; |
32901 |
++ unsigned long address_m; |
32902 |
++ pte_t *ptep_m; |
32903 |
++ |
32904 |
++ vma_m = pax_find_mirror_vma(vma); |
32905 |
++ if (!vma_m) |
32906 |
++ return; |
32907 |
++ |
32908 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
32909 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
32910 |
++ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK); |
32911 |
++ get_page(page_m); |
32912 |
++ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0)); |
32913 |
++} |
32914 |
++#endif |
32915 |
++ |
32916 |
+ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, |
32917 |
+ unsigned long address, pte_t *ptep, pte_t pte) |
32918 |
+ { |
32919 |
+@@ -493,6 +513,11 @@ static int hugetlb_cow(struct mm_struct |
32920 |
+ /* Break COW */ |
32921 |
+ set_huge_pte_at(mm, address, ptep, |
32922 |
+ make_huge_pte(vma, new_page, 1)); |
32923 |
++ |
32924 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32925 |
++ pax_mirror_huge_pte(vma, address, new_page); |
32926 |
++#endif |
32927 |
++ |
32928 |
+ /* Make the old page be freed below */ |
32929 |
+ new_page = old_page; |
32930 |
+ } |
32931 |
+@@ -563,6 +588,10 @@ retry: |
32932 |
+ && (vma->vm_flags & VM_SHARED))); |
32933 |
+ set_huge_pte_at(mm, address, ptep, new_pte); |
32934 |
+ |
32935 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32936 |
++ pax_mirror_huge_pte(vma, address, page); |
32937 |
++#endif |
32938 |
++ |
32939 |
+ if (write_access && !(vma->vm_flags & VM_SHARED)) { |
32940 |
+ /* Optimization, do the COW without a second fault */ |
32941 |
+ ret = hugetlb_cow(mm, vma, address, ptep, new_pte); |
32942 |
+@@ -589,6 +618,27 @@ int hugetlb_fault(struct mm_struct *mm, |
32943 |
+ int ret; |
32944 |
+ static DEFINE_MUTEX(hugetlb_instantiation_mutex); |
32945 |
+ |
32946 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32947 |
++ struct vm_area_struct *vma_m; |
32948 |
++ |
32949 |
++ vma_m = pax_find_mirror_vma(vma); |
32950 |
++ if (vma_m) { |
32951 |
++ unsigned long address_m; |
32952 |
++ |
32953 |
++ if (vma->vm_start > vma_m->vm_start) { |
32954 |
++ address_m = address; |
32955 |
++ address -= SEGMEXEC_TASK_SIZE; |
32956 |
++ vma = vma_m; |
32957 |
++ } else |
32958 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
32959 |
++ |
32960 |
++ if (!huge_pte_alloc(mm, address_m)) |
32961 |
++ return VM_FAULT_OOM; |
32962 |
++ address_m &= HPAGE_MASK; |
32963 |
++ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE); |
32964 |
++ } |
32965 |
++#endif |
32966 |
++ |
32967 |
+ ptep = huge_pte_alloc(mm, address); |
32968 |
+ if (!ptep) |
32969 |
+ return VM_FAULT_OOM; |
32970 |
+diff -Nurp linux-2.6.23.15/mm/madvise.c linux-2.6.23.15-grsec/mm/madvise.c |
32971 |
+--- linux-2.6.23.15/mm/madvise.c 2007-10-09 21:31:38.000000000 +0100 |
32972 |
++++ linux-2.6.23.15-grsec/mm/madvise.c 2008-02-11 10:37:45.000000000 +0000 |
32973 |
+@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a |
32974 |
+ pgoff_t pgoff; |
32975 |
+ int new_flags = vma->vm_flags; |
32976 |
+ |
32977 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32978 |
++ struct vm_area_struct *vma_m; |
32979 |
++#endif |
32980 |
++ |
32981 |
+ switch (behavior) { |
32982 |
+ case MADV_NORMAL: |
32983 |
+ new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ; |
32984 |
+@@ -92,6 +96,13 @@ success: |
32985 |
+ /* |
32986 |
+ * vm_flags is protected by the mmap_sem held in write mode. |
32987 |
+ */ |
32988 |
++ |
32989 |
++#ifdef CONFIG_PAX_SEGMEXEC |
32990 |
++ vma_m = pax_find_mirror_vma(vma); |
32991 |
++ if (vma_m) |
32992 |
++ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT); |
32993 |
++#endif |
32994 |
++ |
32995 |
+ vma->vm_flags = new_flags; |
32996 |
+ |
32997 |
+ out: |
32998 |
+@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma, |
32999 |
+ |
33000 |
+ case MADV_DONTNEED: |
33001 |
+ error = madvise_dontneed(vma, prev, start, end); |
33002 |
++ |
33003 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33004 |
++ if (!error) { |
33005 |
++ struct vm_area_struct *vma_m, *prev_m; |
33006 |
++ |
33007 |
++ vma_m = pax_find_mirror_vma(vma); |
33008 |
++ if (vma_m) |
33009 |
++ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE); |
33010 |
++ } |
33011 |
++#endif |
33012 |
++ |
33013 |
+ break; |
33014 |
+ |
33015 |
+ default: |
33016 |
+@@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon |
33017 |
+ if (end < start) |
33018 |
+ goto out; |
33019 |
+ |
33020 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33021 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
33022 |
++ if (end > SEGMEXEC_TASK_SIZE) |
33023 |
++ goto out; |
33024 |
++ } else |
33025 |
++#endif |
33026 |
++ |
33027 |
++ if (end > TASK_SIZE) |
33028 |
++ goto out; |
33029 |
++ |
33030 |
+ error = 0; |
33031 |
+ if (end == start) |
33032 |
+ goto out; |
33033 |
+diff -Nurp linux-2.6.23.15/mm/memory.c linux-2.6.23.15-grsec/mm/memory.c |
33034 |
+--- linux-2.6.23.15/mm/memory.c 2007-10-09 21:31:38.000000000 +0100 |
33035 |
++++ linux-2.6.23.15-grsec/mm/memory.c 2008-02-11 10:37:45.000000000 +0000 |
33036 |
+@@ -50,6 +50,7 @@ |
33037 |
+ #include <linux/delayacct.h> |
33038 |
+ #include <linux/init.h> |
33039 |
+ #include <linux/writeback.h> |
33040 |
++#include <linux/grsecurity.h> |
33041 |
+ |
33042 |
+ #include <asm/pgalloc.h> |
33043 |
+ #include <asm/uaccess.h> |
33044 |
+@@ -993,7 +994,7 @@ int get_user_pages(struct task_struct *t |
33045 |
+ struct vm_area_struct *vma; |
33046 |
+ unsigned int foll_flags; |
33047 |
+ |
33048 |
+- vma = find_extend_vma(mm, start); |
33049 |
++ vma = find_vma(mm, start); |
33050 |
+ if (!vma && in_gate_area(tsk, start)) { |
33051 |
+ unsigned long pg = start & PAGE_MASK; |
33052 |
+ struct vm_area_struct *gate_vma = get_gate_vma(tsk); |
33053 |
+@@ -1033,7 +1034,7 @@ int get_user_pages(struct task_struct *t |
33054 |
+ continue; |
33055 |
+ } |
33056 |
+ |
33057 |
+- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP)) |
33058 |
++ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP)) |
33059 |
+ || !(vm_flags & vma->vm_flags)) |
33060 |
+ return i ? : -EFAULT; |
33061 |
+ |
33062 |
+@@ -1614,6 +1615,195 @@ static inline void cow_user_page(struct |
33063 |
+ copy_user_highpage(dst, src, va, vma); |
33064 |
+ } |
33065 |
+ |
33066 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33067 |
++static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd) |
33068 |
++{ |
33069 |
++ struct mm_struct *mm = vma->vm_mm; |
33070 |
++ spinlock_t *ptl; |
33071 |
++ pte_t *pte, entry; |
33072 |
++ |
33073 |
++ pte = pte_offset_map_lock(mm, pmd, address, &ptl); |
33074 |
++ entry = *pte; |
33075 |
++ if (!pte_present(entry)) { |
33076 |
++ if (!pte_none(entry)) { |
33077 |
++ BUG_ON(pte_file(entry)); |
33078 |
++ free_swap_and_cache(pte_to_swp_entry(entry)); |
33079 |
++ pte_clear_not_present_full(mm, address, pte, 0); |
33080 |
++ } |
33081 |
++ } else { |
33082 |
++ struct page *page; |
33083 |
++ |
33084 |
++ page = vm_normal_page(vma, address, entry); |
33085 |
++ if (page) { |
33086 |
++ flush_cache_page(vma, address, pte_pfn(entry)); |
33087 |
++ flush_icache_page(vma, page); |
33088 |
++ } |
33089 |
++ ptep_clear_flush(vma, address, pte); |
33090 |
++ BUG_ON(pte_dirty(entry)); |
33091 |
++ if (page) { |
33092 |
++ update_hiwater_rss(mm); |
33093 |
++ if (PageAnon(page)) |
33094 |
++ dec_mm_counter(mm, anon_rss); |
33095 |
++ else |
33096 |
++ dec_mm_counter(mm, file_rss); |
33097 |
++ page_remove_rmap(page, vma); |
33098 |
++ page_cache_release(page); |
33099 |
++ } |
33100 |
++ } |
33101 |
++ pte_unmap_unlock(pte, ptl); |
33102 |
++} |
33103 |
++ |
33104 |
++/* PaX: if vma is mirrored, synchronize the mirror's PTE |
33105 |
++ * |
33106 |
++ * the ptl of the lower mapped page is held on entry and is not released on exit |
33107 |
++ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc) |
33108 |
++ */ |
33109 |
++static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl) |
33110 |
++{ |
33111 |
++ struct mm_struct *mm = vma->vm_mm; |
33112 |
++ unsigned long address_m; |
33113 |
++ spinlock_t *ptl_m; |
33114 |
++ struct vm_area_struct *vma_m; |
33115 |
++ pmd_t *pmd_m; |
33116 |
++ pte_t *pte_m, entry_m; |
33117 |
++ |
33118 |
++ BUG_ON(!page_m || !PageAnon(page_m)); |
33119 |
++ |
33120 |
++ vma_m = pax_find_mirror_vma(vma); |
33121 |
++ if (!vma_m) |
33122 |
++ return; |
33123 |
++ |
33124 |
++ BUG_ON(!PageLocked(page_m)); |
33125 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33126 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33127 |
++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); |
33128 |
++ pte_m = pte_offset_map_nested(pmd_m, address_m); |
33129 |
++ ptl_m = pte_lockptr(mm, pmd_m); |
33130 |
++ if (ptl != ptl_m) { |
33131 |
++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); |
33132 |
++ if (!pte_none(*pte_m)) { |
33133 |
++ spin_unlock(ptl_m); |
33134 |
++ pte_unmap_nested(pte_m); |
33135 |
++ unlock_page(page_m); |
33136 |
++ return; |
33137 |
++ } |
33138 |
++ } |
33139 |
++ |
33140 |
++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot); |
33141 |
++ page_cache_get(page_m); |
33142 |
++ page_add_anon_rmap(page_m, vma_m, address_m); |
33143 |
++ inc_mm_counter(mm, anon_rss); |
33144 |
++ set_pte_at(mm, address_m, pte_m, entry_m); |
33145 |
++ update_mmu_cache(vma_m, address_m, entry_m); |
33146 |
++ lazy_mmu_prot_update(entry_m); |
33147 |
++ if (ptl != ptl_m) |
33148 |
++ spin_unlock(ptl_m); |
33149 |
++ pte_unmap_nested(pte_m); |
33150 |
++ unlock_page(page_m); |
33151 |
++} |
33152 |
++ |
33153 |
++void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl) |
33154 |
++{ |
33155 |
++ struct mm_struct *mm = vma->vm_mm; |
33156 |
++ unsigned long address_m; |
33157 |
++ spinlock_t *ptl_m; |
33158 |
++ struct vm_area_struct *vma_m; |
33159 |
++ pmd_t *pmd_m; |
33160 |
++ pte_t *pte_m, entry_m; |
33161 |
++ |
33162 |
++ BUG_ON(!page_m || PageAnon(page_m)); |
33163 |
++ |
33164 |
++ vma_m = pax_find_mirror_vma(vma); |
33165 |
++ if (!vma_m) |
33166 |
++ return; |
33167 |
++ |
33168 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33169 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33170 |
++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); |
33171 |
++ pte_m = pte_offset_map_nested(pmd_m, address_m); |
33172 |
++ ptl_m = pte_lockptr(mm, pmd_m); |
33173 |
++ if (ptl != ptl_m) { |
33174 |
++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); |
33175 |
++ if (!pte_none(*pte_m)) { |
33176 |
++ spin_unlock(ptl_m); |
33177 |
++ pte_unmap_nested(pte_m); |
33178 |
++ return; |
33179 |
++ } |
33180 |
++ } |
33181 |
++ |
33182 |
++ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot); |
33183 |
++ page_cache_get(page_m); |
33184 |
++ page_add_file_rmap(page_m); |
33185 |
++ inc_mm_counter(mm, file_rss); |
33186 |
++ set_pte_at(mm, address_m, pte_m, entry_m); |
33187 |
++ update_mmu_cache(vma_m, address_m, entry_m); |
33188 |
++ lazy_mmu_prot_update(entry_m); |
33189 |
++ if (ptl != ptl_m) |
33190 |
++ spin_unlock(ptl_m); |
33191 |
++ pte_unmap_nested(pte_m); |
33192 |
++} |
33193 |
++ |
33194 |
++static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl) |
33195 |
++{ |
33196 |
++ struct mm_struct *mm = vma->vm_mm; |
33197 |
++ unsigned long address_m; |
33198 |
++ spinlock_t *ptl_m; |
33199 |
++ struct vm_area_struct *vma_m; |
33200 |
++ pmd_t *pmd_m; |
33201 |
++ pte_t *pte_m, entry_m; |
33202 |
++ |
33203 |
++ vma_m = pax_find_mirror_vma(vma); |
33204 |
++ if (!vma_m) |
33205 |
++ return; |
33206 |
++ |
33207 |
++ BUG_ON(address >= SEGMEXEC_TASK_SIZE); |
33208 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33209 |
++ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m); |
33210 |
++ pte_m = pte_offset_map_nested(pmd_m, address_m); |
33211 |
++ ptl_m = pte_lockptr(mm, pmd_m); |
33212 |
++ if (ptl != ptl_m) { |
33213 |
++ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING); |
33214 |
++ if (!pte_none(*pte_m)) { |
33215 |
++ spin_unlock(ptl_m); |
33216 |
++ pte_unmap_nested(pte_m); |
33217 |
++ return; |
33218 |
++ } |
33219 |
++ } |
33220 |
++ |
33221 |
++ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot); |
33222 |
++ set_pte_at(mm, address_m, pte_m, entry_m); |
33223 |
++ if (ptl != ptl_m) |
33224 |
++ spin_unlock(ptl_m); |
33225 |
++ pte_unmap_nested(pte_m); |
33226 |
++} |
33227 |
++ |
33228 |
++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl) |
33229 |
++{ |
33230 |
++ struct page *page_m; |
33231 |
++ pte_t entry; |
33232 |
++ |
33233 |
++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC)) |
33234 |
++ return; |
33235 |
++ |
33236 |
++ entry = *pte; |
33237 |
++ page_m = vm_normal_page(vma, address, entry); |
33238 |
++ if (!page_m) |
33239 |
++ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl); |
33240 |
++ else if (PageAnon(page_m)) { |
33241 |
++ if (pax_find_mirror_vma(vma)) { |
33242 |
++ spin_unlock(ptl); |
33243 |
++ lock_page(page_m); |
33244 |
++ spin_lock(ptl); |
33245 |
++ if (pte_same(entry, *pte)) |
33246 |
++ pax_mirror_anon_pte(vma, address, page_m, ptl); |
33247 |
++ else |
33248 |
++ unlock_page(page_m); |
33249 |
++ } |
33250 |
++ } else |
33251 |
++ pax_mirror_file_pte(vma, address, page_m, ptl); |
33252 |
++} |
33253 |
++#endif |
33254 |
++ |
33255 |
+ /* |
33256 |
+ * This routine handles present pages, when users try to write |
33257 |
+ * to a shared page. It is done by copying the page to a new address |
33258 |
+@@ -1733,6 +1923,12 @@ gotten: |
33259 |
+ */ |
33260 |
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl); |
33261 |
+ if (likely(pte_same(*page_table, orig_pte))) { |
33262 |
++ |
33263 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33264 |
++ if (pax_find_mirror_vma(vma)) |
33265 |
++ BUG_ON(TestSetPageLocked(new_page)); |
33266 |
++#endif |
33267 |
++ |
33268 |
+ if (old_page) { |
33269 |
+ page_remove_rmap(old_page, vma); |
33270 |
+ if (!PageAnon(old_page)) { |
33271 |
+@@ -1757,6 +1953,10 @@ gotten: |
33272 |
+ lru_cache_add_active(new_page); |
33273 |
+ page_add_new_anon_rmap(new_page, vma, address); |
33274 |
+ |
33275 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33276 |
++ pax_mirror_anon_pte(vma, address, new_page, ptl); |
33277 |
++#endif |
33278 |
++ |
33279 |
+ /* Free the old page.. */ |
33280 |
+ new_page = old_page; |
33281 |
+ ret |= VM_FAULT_WRITE; |
33282 |
+@@ -2034,6 +2234,7 @@ int vmtruncate(struct inode * inode, lof |
33283 |
+ |
33284 |
+ do_expand: |
33285 |
+ limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
33286 |
++ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1); |
33287 |
+ if (limit != RLIM_INFINITY && offset > limit) |
33288 |
+ goto out_sig; |
33289 |
+ if (offset > inode->i_sb->s_maxbytes) |
33290 |
+@@ -2216,6 +2417,11 @@ static int do_swap_page(struct mm_struct |
33291 |
+ swap_free(entry); |
33292 |
+ if (vm_swap_full()) |
33293 |
+ remove_exclusive_swap_page(page); |
33294 |
++ |
33295 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33296 |
++ if (write_access || !pax_find_mirror_vma(vma)) |
33297 |
++#endif |
33298 |
++ |
33299 |
+ unlock_page(page); |
33300 |
+ |
33301 |
+ if (write_access) { |
33302 |
+@@ -2228,6 +2434,11 @@ static int do_swap_page(struct mm_struct |
33303 |
+ |
33304 |
+ /* No need to invalidate - it was non-present before */ |
33305 |
+ update_mmu_cache(vma, address, pte); |
33306 |
++ |
33307 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33308 |
++ pax_mirror_anon_pte(vma, address, page, ptl); |
33309 |
++#endif |
33310 |
++ |
33311 |
+ unlock: |
33312 |
+ pte_unmap_unlock(page_table, ptl); |
33313 |
+ out: |
33314 |
+@@ -2268,6 +2479,12 @@ static int do_anonymous_page(struct mm_s |
33315 |
+ page_table = pte_offset_map_lock(mm, pmd, address, &ptl); |
33316 |
+ if (!pte_none(*page_table)) |
33317 |
+ goto release; |
33318 |
++ |
33319 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33320 |
++ if (pax_find_mirror_vma(vma)) |
33321 |
++ BUG_ON(TestSetPageLocked(page)); |
33322 |
++#endif |
33323 |
++ |
33324 |
+ inc_mm_counter(mm, anon_rss); |
33325 |
+ lru_cache_add_active(page); |
33326 |
+ page_add_new_anon_rmap(page, vma, address); |
33327 |
+@@ -2290,6 +2507,14 @@ static int do_anonymous_page(struct mm_s |
33328 |
+ /* No need to invalidate - it was non-present before */ |
33329 |
+ update_mmu_cache(vma, address, entry); |
33330 |
+ lazy_mmu_prot_update(entry); |
33331 |
++ |
33332 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33333 |
++ if (write_access) |
33334 |
++ pax_mirror_anon_pte(vma, address, page, ptl); |
33335 |
++ else |
33336 |
++ pax_mirror_file_pte(vma, address, page, ptl); |
33337 |
++#endif |
33338 |
++ |
33339 |
+ unlock: |
33340 |
+ pte_unmap_unlock(page_table, ptl); |
33341 |
+ return 0; |
33342 |
+@@ -2422,6 +2647,12 @@ static int __do_fault(struct mm_struct * |
33343 |
+ */ |
33344 |
+ /* Only go through if we didn't race with anybody else... */ |
33345 |
+ if (likely(pte_same(*page_table, orig_pte))) { |
33346 |
++ |
33347 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33348 |
++ if (anon && pax_find_mirror_vma(vma)) |
33349 |
++ BUG_ON(TestSetPageLocked(page)); |
33350 |
++#endif |
33351 |
++ |
33352 |
+ flush_icache_page(vma, page); |
33353 |
+ entry = mk_pte(page, vma->vm_page_prot); |
33354 |
+ if (flags & FAULT_FLAG_WRITE) |
33355 |
+@@ -2443,6 +2674,14 @@ static int __do_fault(struct mm_struct * |
33356 |
+ /* no need to invalidate: a not-present page won't be cached */ |
33357 |
+ update_mmu_cache(vma, address, entry); |
33358 |
+ lazy_mmu_prot_update(entry); |
33359 |
++ |
33360 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33361 |
++ if (anon) |
33362 |
++ pax_mirror_anon_pte(vma, address, page, ptl); |
33363 |
++ else |
33364 |
++ pax_mirror_file_pte(vma, address, page, ptl); |
33365 |
++#endif |
33366 |
++ |
33367 |
+ } else { |
33368 |
+ if (anon) |
33369 |
+ page_cache_release(page); |
33370 |
+@@ -2522,6 +2761,11 @@ static noinline int do_no_pfn(struct mm_ |
33371 |
+ if (write_access) |
33372 |
+ entry = maybe_mkwrite(pte_mkdirty(entry), vma); |
33373 |
+ set_pte_at(mm, address, page_table, entry); |
33374 |
++ |
33375 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33376 |
++ pax_mirror_pfn_pte(vma, address, pfn, ptl); |
33377 |
++#endif |
33378 |
++ |
33379 |
+ } |
33380 |
+ pte_unmap_unlock(page_table, ptl); |
33381 |
+ return 0; |
33382 |
+@@ -2625,6 +2869,11 @@ static inline int handle_pte_fault(struc |
33383 |
+ if (write_access) |
33384 |
+ flush_tlb_page(vma, address); |
33385 |
+ } |
33386 |
++ |
33387 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33388 |
++ pax_mirror_pte(vma, address, pte, ptl); |
33389 |
++#endif |
33390 |
++ |
33391 |
+ unlock: |
33392 |
+ pte_unmap_unlock(pte, ptl); |
33393 |
+ return 0; |
33394 |
+@@ -2641,6 +2890,10 @@ int handle_mm_fault(struct mm_struct *mm |
33395 |
+ pmd_t *pmd; |
33396 |
+ pte_t *pte; |
33397 |
+ |
33398 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33399 |
++ struct vm_area_struct *vma_m; |
33400 |
++#endif |
33401 |
++ |
33402 |
+ __set_current_state(TASK_RUNNING); |
33403 |
+ |
33404 |
+ count_vm_event(PGFAULT); |
33405 |
+@@ -2648,6 +2901,34 @@ int handle_mm_fault(struct mm_struct *mm |
33406 |
+ if (unlikely(is_vm_hugetlb_page(vma))) |
33407 |
+ return hugetlb_fault(mm, vma, address, write_access); |
33408 |
+ |
33409 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33410 |
++ vma_m = pax_find_mirror_vma(vma); |
33411 |
++ if (vma_m) { |
33412 |
++ unsigned long address_m; |
33413 |
++ pgd_t *pgd_m; |
33414 |
++ pud_t *pud_m; |
33415 |
++ pmd_t *pmd_m; |
33416 |
++ |
33417 |
++ if (vma->vm_start > vma_m->vm_start) { |
33418 |
++ address_m = address; |
33419 |
++ address -= SEGMEXEC_TASK_SIZE; |
33420 |
++ vma = vma_m; |
33421 |
++ } else |
33422 |
++ address_m = address + SEGMEXEC_TASK_SIZE; |
33423 |
++ |
33424 |
++ pgd_m = pgd_offset(mm, address_m); |
33425 |
++ pud_m = pud_alloc(mm, pgd_m, address_m); |
33426 |
++ if (!pud_m) |
33427 |
++ return VM_FAULT_OOM; |
33428 |
++ pmd_m = pmd_alloc(mm, pud_m, address_m); |
33429 |
++ if (!pmd_m) |
33430 |
++ return VM_FAULT_OOM; |
33431 |
++ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m)) |
33432 |
++ return VM_FAULT_OOM; |
33433 |
++ pax_unmap_mirror_pte(vma_m, address_m, pmd_m); |
33434 |
++ } |
33435 |
++#endif |
33436 |
++ |
33437 |
+ pgd = pgd_offset(mm, address); |
33438 |
+ pud = pud_alloc(mm, pgd, address); |
33439 |
+ if (!pud) |
33440 |
+@@ -2781,7 +3062,7 @@ static int __init gate_vma_init(void) |
33441 |
+ gate_vma.vm_start = FIXADDR_USER_START; |
33442 |
+ gate_vma.vm_end = FIXADDR_USER_END; |
33443 |
+ gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC; |
33444 |
+- gate_vma.vm_page_prot = __P101; |
33445 |
++ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags); |
33446 |
+ /* |
33447 |
+ * Make sure the vDSO gets into every core dump. |
33448 |
+ * Dumping its contents makes post-mortem fully interpretable later |
33449 |
+diff -Nurp linux-2.6.23.15/mm/mempolicy.c linux-2.6.23.15-grsec/mm/mempolicy.c |
33450 |
+--- linux-2.6.23.15/mm/mempolicy.c 2007-10-09 21:31:38.000000000 +0100 |
33451 |
++++ linux-2.6.23.15-grsec/mm/mempolicy.c 2008-02-11 10:37:45.000000000 +0000 |
33452 |
+@@ -401,6 +401,10 @@ static int mbind_range(struct vm_area_st |
33453 |
+ struct vm_area_struct *next; |
33454 |
+ int err; |
33455 |
+ |
33456 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33457 |
++ struct vm_area_struct *vma_m; |
33458 |
++#endif |
33459 |
++ |
33460 |
+ err = 0; |
33461 |
+ for (; vma && vma->vm_start < end; vma = next) { |
33462 |
+ next = vma->vm_next; |
33463 |
+@@ -412,6 +416,16 @@ static int mbind_range(struct vm_area_st |
33464 |
+ err = policy_vma(vma, new); |
33465 |
+ if (err) |
33466 |
+ break; |
33467 |
++ |
33468 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33469 |
++ vma_m = pax_find_mirror_vma(vma); |
33470 |
++ if (vma_m) { |
33471 |
++ err = policy_vma(vma_m, new); |
33472 |
++ if (err) |
33473 |
++ break; |
33474 |
++ } |
33475 |
++#endif |
33476 |
++ |
33477 |
+ } |
33478 |
+ return err; |
33479 |
+ } |
33480 |
+@@ -732,7 +746,7 @@ static struct page *new_vma_page(struct |
33481 |
+ } |
33482 |
+ #endif |
33483 |
+ |
33484 |
+-long do_mbind(unsigned long start, unsigned long len, |
33485 |
++static long do_mbind(unsigned long start, unsigned long len, |
33486 |
+ unsigned long mode, nodemask_t *nmask, unsigned long flags) |
33487 |
+ { |
33488 |
+ struct vm_area_struct *vma; |
33489 |
+@@ -760,6 +774,17 @@ long do_mbind(unsigned long start, unsig |
33490 |
+ |
33491 |
+ if (end < start) |
33492 |
+ return -EINVAL; |
33493 |
++ |
33494 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33495 |
++ if (mm->pax_flags & MF_PAX_SEGMEXEC) { |
33496 |
++ if (end > SEGMEXEC_TASK_SIZE) |
33497 |
++ return -EINVAL; |
33498 |
++ } else |
33499 |
++#endif |
33500 |
++ |
33501 |
++ if (end > TASK_SIZE) |
33502 |
++ return -EINVAL; |
33503 |
++ |
33504 |
+ if (end == start) |
33505 |
+ return 0; |
33506 |
+ |
33507 |
+diff -Nurp linux-2.6.23.15/mm/mlock.c linux-2.6.23.15-grsec/mm/mlock.c |
33508 |
+--- linux-2.6.23.15/mm/mlock.c 2007-10-09 21:31:38.000000000 +0100 |
33509 |
++++ linux-2.6.23.15-grsec/mm/mlock.c 2008-02-11 10:37:45.000000000 +0000 |
33510 |
+@@ -12,6 +12,7 @@ |
33511 |
+ #include <linux/syscalls.h> |
33512 |
+ #include <linux/sched.h> |
33513 |
+ #include <linux/module.h> |
33514 |
++#include <linux/grsecurity.h> |
33515 |
+ |
33516 |
+ int can_do_mlock(void) |
33517 |
+ { |
33518 |
+@@ -95,6 +96,17 @@ static int do_mlock(unsigned long start, |
33519 |
+ return -EINVAL; |
33520 |
+ if (end == start) |
33521 |
+ return 0; |
33522 |
++ |
33523 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33524 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
33525 |
++ if (end > SEGMEXEC_TASK_SIZE) |
33526 |
++ return -EINVAL; |
33527 |
++ } else |
33528 |
++#endif |
33529 |
++ |
33530 |
++ if (end > TASK_SIZE) |
33531 |
++ return -EINVAL; |
33532 |
++ |
33533 |
+ vma = find_vma_prev(current->mm, start, &prev); |
33534 |
+ if (!vma || vma->vm_start > start) |
33535 |
+ return -ENOMEM; |
33536 |
+@@ -152,6 +164,7 @@ asmlinkage long sys_mlock(unsigned long |
33537 |
+ lock_limit >>= PAGE_SHIFT; |
33538 |
+ |
33539 |
+ /* check against resource limits */ |
33540 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1); |
33541 |
+ if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) |
33542 |
+ error = do_mlock(start, len, 1); |
33543 |
+ up_write(¤t->mm->mmap_sem); |
33544 |
+@@ -173,10 +186,10 @@ asmlinkage long sys_munlock(unsigned lon |
33545 |
+ static int do_mlockall(int flags) |
33546 |
+ { |
33547 |
+ struct vm_area_struct * vma, * prev = NULL; |
33548 |
+- unsigned int def_flags = 0; |
33549 |
++ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED; |
33550 |
+ |
33551 |
+ if (flags & MCL_FUTURE) |
33552 |
+- def_flags = VM_LOCKED; |
33553 |
++ def_flags |= VM_LOCKED; |
33554 |
+ current->mm->def_flags = def_flags; |
33555 |
+ if (flags == MCL_FUTURE) |
33556 |
+ goto out; |
33557 |
+@@ -184,6 +197,12 @@ static int do_mlockall(int flags) |
33558 |
+ for (vma = current->mm->mmap; vma ; vma = prev->vm_next) { |
33559 |
+ unsigned int newflags; |
33560 |
+ |
33561 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33562 |
++ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) |
33563 |
++ break; |
33564 |
++#endif |
33565 |
++ |
33566 |
++ BUG_ON(vma->vm_end > TASK_SIZE); |
33567 |
+ newflags = vma->vm_flags | VM_LOCKED; |
33568 |
+ if (!(flags & MCL_CURRENT)) |
33569 |
+ newflags &= ~VM_LOCKED; |
33570 |
+@@ -213,6 +232,7 @@ asmlinkage long sys_mlockall(int flags) |
33571 |
+ lock_limit >>= PAGE_SHIFT; |
33572 |
+ |
33573 |
+ ret = -ENOMEM; |
33574 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1); |
33575 |
+ if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || |
33576 |
+ capable(CAP_IPC_LOCK)) |
33577 |
+ ret = do_mlockall(flags); |
33578 |
+diff -Nurp linux-2.6.23.15/mm/mmap.c linux-2.6.23.15-grsec/mm/mmap.c |
33579 |
+--- linux-2.6.23.15/mm/mmap.c 2008-02-11 10:36:03.000000000 +0000 |
33580 |
++++ linux-2.6.23.15-grsec/mm/mmap.c 2008-02-11 10:43:32.000000000 +0000 |
33581 |
+@@ -25,6 +25,7 @@ |
33582 |
+ #include <linux/mount.h> |
33583 |
+ #include <linux/mempolicy.h> |
33584 |
+ #include <linux/rmap.h> |
33585 |
++#include <linux/grsecurity.h> |
33586 |
+ |
33587 |
+ #include <asm/uaccess.h> |
33588 |
+ #include <asm/cacheflush.h> |
33589 |
+@@ -35,6 +36,16 @@ |
33590 |
+ #define arch_mmap_check(addr, len, flags) (0) |
33591 |
+ #endif |
33592 |
+ |
33593 |
++static inline void verify_mm_writelocked(struct mm_struct *mm) |
33594 |
++{ |
33595 |
++#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX) |
33596 |
++ if (unlikely(down_read_trylock(&mm->mmap_sem))) { |
33597 |
++ up_read(&mm->mmap_sem); |
33598 |
++ BUG(); |
33599 |
++ } |
33600 |
++#endif |
33601 |
++} |
33602 |
++ |
33603 |
+ static void unmap_region(struct mm_struct *mm, |
33604 |
+ struct vm_area_struct *vma, struct vm_area_struct *prev, |
33605 |
+ unsigned long start, unsigned long end); |
33606 |
+@@ -60,15 +71,23 @@ static void unmap_region(struct mm_struc |
33607 |
+ * x: (no) no x: (no) yes x: (no) yes x: (yes) yes |
33608 |
+ * |
33609 |
+ */ |
33610 |
+-pgprot_t protection_map[16] = { |
33611 |
++pgprot_t protection_map[16] __read_only = { |
33612 |
+ __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111, |
33613 |
+ __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111 |
33614 |
+ }; |
33615 |
+ |
33616 |
+ pgprot_t vm_get_page_prot(unsigned long vm_flags) |
33617 |
+ { |
33618 |
+- return protection_map[vm_flags & |
33619 |
+- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
33620 |
++ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
33621 |
++ |
33622 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
33623 |
++ if (!nx_enabled && |
33624 |
++ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC && |
33625 |
++ (vm_flags & (VM_READ | VM_WRITE))) |
33626 |
++ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot))))); |
33627 |
++#endif |
33628 |
++ |
33629 |
++ return prot; |
33630 |
+ } |
33631 |
+ EXPORT_SYMBOL(vm_get_page_prot); |
33632 |
+ |
33633 |
+@@ -225,6 +244,7 @@ static struct vm_area_struct *remove_vma |
33634 |
+ struct vm_area_struct *next = vma->vm_next; |
33635 |
+ |
33636 |
+ might_sleep(); |
33637 |
++ BUG_ON(vma->vm_mirror); |
33638 |
+ if (vma->vm_ops && vma->vm_ops->close) |
33639 |
+ vma->vm_ops->close(vma); |
33640 |
+ if (vma->vm_file) |
33641 |
+@@ -252,6 +272,7 @@ asmlinkage unsigned long sys_brk(unsigne |
33642 |
+ * not page aligned -Ram Gupta |
33643 |
+ */ |
33644 |
+ rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; |
33645 |
++ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1); |
33646 |
+ if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) |
33647 |
+ goto out; |
33648 |
+ |
33649 |
+@@ -352,8 +373,12 @@ find_vma_prepare(struct mm_struct *mm, u |
33650 |
+ |
33651 |
+ if (vma_tmp->vm_end > addr) { |
33652 |
+ vma = vma_tmp; |
33653 |
+- if (vma_tmp->vm_start <= addr) |
33654 |
+- return vma; |
33655 |
++ if (vma_tmp->vm_start <= addr) { |
33656 |
++//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ", |
33657 |
++//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent); |
33658 |
++//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0))); |
33659 |
++ break; |
33660 |
++ } |
33661 |
+ __rb_link = &__rb_parent->rb_left; |
33662 |
+ } else { |
33663 |
+ rb_prev = __rb_parent; |
33664 |
+@@ -677,6 +702,12 @@ static int |
33665 |
+ can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags, |
33666 |
+ struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) |
33667 |
+ { |
33668 |
++ |
33669 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33670 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE) |
33671 |
++ return 0; |
33672 |
++#endif |
33673 |
++ |
33674 |
+ if (is_mergeable_vma(vma, file, vm_flags) && |
33675 |
+ is_mergeable_anon_vma(anon_vma, vma->anon_vma)) { |
33676 |
+ if (vma->vm_pgoff == vm_pgoff) |
33677 |
+@@ -696,6 +727,12 @@ static int |
33678 |
+ can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags, |
33679 |
+ struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff) |
33680 |
+ { |
33681 |
++ |
33682 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33683 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE) |
33684 |
++ return 0; |
33685 |
++#endif |
33686 |
++ |
33687 |
+ if (is_mergeable_vma(vma, file, vm_flags) && |
33688 |
+ is_mergeable_anon_vma(anon_vma, vma->anon_vma)) { |
33689 |
+ pgoff_t vm_pglen; |
33690 |
+@@ -738,12 +775,19 @@ can_vma_merge_after(struct vm_area_struc |
33691 |
+ struct vm_area_struct *vma_merge(struct mm_struct *mm, |
33692 |
+ struct vm_area_struct *prev, unsigned long addr, |
33693 |
+ unsigned long end, unsigned long vm_flags, |
33694 |
+- struct anon_vma *anon_vma, struct file *file, |
33695 |
++ struct anon_vma *anon_vma, struct file *file, |
33696 |
+ pgoff_t pgoff, struct mempolicy *policy) |
33697 |
+ { |
33698 |
+ pgoff_t pglen = (end - addr) >> PAGE_SHIFT; |
33699 |
+ struct vm_area_struct *area, *next; |
33700 |
+ |
33701 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33702 |
++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE; |
33703 |
++ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL; |
33704 |
++ |
33705 |
++ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end); |
33706 |
++#endif |
33707 |
++ |
33708 |
+ /* |
33709 |
+ * We later require that vma->vm_flags == vm_flags, |
33710 |
+ * so this tests vma->vm_flags & VM_SPECIAL, too. |
33711 |
+@@ -759,6 +803,15 @@ struct vm_area_struct *vma_merge(struct |
33712 |
+ if (next && next->vm_end == end) /* cases 6, 7, 8 */ |
33713 |
+ next = next->vm_next; |
33714 |
+ |
33715 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33716 |
++ if (prev) |
33717 |
++ prev_m = pax_find_mirror_vma(prev); |
33718 |
++ if (area) |
33719 |
++ area_m = pax_find_mirror_vma(area); |
33720 |
++ if (next) |
33721 |
++ next_m = pax_find_mirror_vma(next); |
33722 |
++#endif |
33723 |
++ |
33724 |
+ /* |
33725 |
+ * Can it merge with the predecessor? |
33726 |
+ */ |
33727 |
+@@ -778,9 +831,24 @@ struct vm_area_struct *vma_merge(struct |
33728 |
+ /* cases 1, 6 */ |
33729 |
+ vma_adjust(prev, prev->vm_start, |
33730 |
+ next->vm_end, prev->vm_pgoff, NULL); |
33731 |
+- } else /* cases 2, 5, 7 */ |
33732 |
++ |
33733 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33734 |
++ if (prev_m) |
33735 |
++ vma_adjust(prev_m, prev_m->vm_start, |
33736 |
++ next_m->vm_end, prev_m->vm_pgoff, NULL); |
33737 |
++#endif |
33738 |
++ |
33739 |
++ } else { /* cases 2, 5, 7 */ |
33740 |
+ vma_adjust(prev, prev->vm_start, |
33741 |
+ end, prev->vm_pgoff, NULL); |
33742 |
++ |
33743 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33744 |
++ if (prev_m) |
33745 |
++ vma_adjust(prev_m, prev_m->vm_start, |
33746 |
++ end_m, prev_m->vm_pgoff, NULL); |
33747 |
++#endif |
33748 |
++ |
33749 |
++ } |
33750 |
+ return prev; |
33751 |
+ } |
33752 |
+ |
33753 |
+@@ -791,12 +859,27 @@ struct vm_area_struct *vma_merge(struct |
33754 |
+ mpol_equal(policy, vma_policy(next)) && |
33755 |
+ can_vma_merge_before(next, vm_flags, |
33756 |
+ anon_vma, file, pgoff+pglen)) { |
33757 |
+- if (prev && addr < prev->vm_end) /* case 4 */ |
33758 |
++ if (prev && addr < prev->vm_end) { /* case 4 */ |
33759 |
+ vma_adjust(prev, prev->vm_start, |
33760 |
+ addr, prev->vm_pgoff, NULL); |
33761 |
+- else /* cases 3, 8 */ |
33762 |
++ |
33763 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33764 |
++ if (prev_m) |
33765 |
++ vma_adjust(prev_m, prev_m->vm_start, |
33766 |
++ addr_m, prev_m->vm_pgoff, NULL); |
33767 |
++#endif |
33768 |
++ |
33769 |
++ } else { /* cases 3, 8 */ |
33770 |
+ vma_adjust(area, addr, next->vm_end, |
33771 |
+ next->vm_pgoff - pglen, NULL); |
33772 |
++ |
33773 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33774 |
++ if (area_m) |
33775 |
++ vma_adjust(area_m, addr_m, next_m->vm_end, |
33776 |
++ next_m->vm_pgoff - pglen, NULL); |
33777 |
++#endif |
33778 |
++ |
33779 |
++ } |
33780 |
+ return area; |
33781 |
+ } |
33782 |
+ |
33783 |
+@@ -871,14 +954,11 @@ none: |
33784 |
+ void vm_stat_account(struct mm_struct *mm, unsigned long flags, |
33785 |
+ struct file *file, long pages) |
33786 |
+ { |
33787 |
+- const unsigned long stack_flags |
33788 |
+- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN); |
33789 |
+- |
33790 |
+ if (file) { |
33791 |
+ mm->shared_vm += pages; |
33792 |
+ if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC) |
33793 |
+ mm->exec_vm += pages; |
33794 |
+- } else if (flags & stack_flags) |
33795 |
++ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN)) |
33796 |
+ mm->stack_vm += pages; |
33797 |
+ if (flags & (VM_RESERVED|VM_IO)) |
33798 |
+ mm->reserved_vm += pages; |
33799 |
+@@ -906,22 +986,22 @@ unsigned long do_mmap_pgoff(struct file |
33800 |
+ * (the exception is when the underlying filesystem is noexec |
33801 |
+ * mounted, in which case we dont add PROT_EXEC.) |
33802 |
+ */ |
33803 |
+- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) |
33804 |
++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC)) |
33805 |
+ if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC))) |
33806 |
+ prot |= PROT_EXEC; |
33807 |
+ |
33808 |
+ if (!len) |
33809 |
+ return -EINVAL; |
33810 |
+ |
33811 |
+- error = arch_mmap_check(addr, len, flags); |
33812 |
+- if (error) |
33813 |
+- return error; |
33814 |
+- |
33815 |
+ /* Careful about overflows.. */ |
33816 |
+ len = PAGE_ALIGN(len); |
33817 |
+ if (!len || len > TASK_SIZE) |
33818 |
+ return -ENOMEM; |
33819 |
+ |
33820 |
++ error = arch_mmap_check(addr, len, flags); |
33821 |
++ if (error) |
33822 |
++ return error; |
33823 |
++ |
33824 |
+ /* offset overflow? */ |
33825 |
+ if ((pgoff + (len >> PAGE_SHIFT)) < pgoff) |
33826 |
+ return -EOVERFLOW; |
33827 |
+@@ -933,7 +1013,7 @@ unsigned long do_mmap_pgoff(struct file |
33828 |
+ /* Obtain the address to map to. we verify (or select) it and ensure |
33829 |
+ * that it represents a valid section of the address space. |
33830 |
+ */ |
33831 |
+- addr = get_unmapped_area(file, addr, len, pgoff, flags); |
33832 |
++ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0)); |
33833 |
+ if (addr & ~PAGE_MASK) |
33834 |
+ return addr; |
33835 |
+ |
33836 |
+@@ -944,6 +1024,26 @@ unsigned long do_mmap_pgoff(struct file |
33837 |
+ vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) | |
33838 |
+ mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; |
33839 |
+ |
33840 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
33841 |
++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
33842 |
++ |
33843 |
++#ifdef CONFIG_PAX_MPROTECT |
33844 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) { |
33845 |
++ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC) |
33846 |
++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); |
33847 |
++ else |
33848 |
++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE); |
33849 |
++ } |
33850 |
++#endif |
33851 |
++ |
33852 |
++ } |
33853 |
++#endif |
33854 |
++ |
33855 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
33856 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file) |
33857 |
++ vm_flags &= ~VM_PAGEEXEC; |
33858 |
++#endif |
33859 |
++ |
33860 |
+ if (flags & MAP_LOCKED) { |
33861 |
+ if (!can_do_mlock()) |
33862 |
+ return -EPERM; |
33863 |
+@@ -956,6 +1056,7 @@ unsigned long do_mmap_pgoff(struct file |
33864 |
+ locked += mm->locked_vm; |
33865 |
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
33866 |
+ lock_limit >>= PAGE_SHIFT; |
33867 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); |
33868 |
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
33869 |
+ return -EAGAIN; |
33870 |
+ } |
33871 |
+@@ -1024,6 +1125,9 @@ unsigned long do_mmap_pgoff(struct file |
33872 |
+ if (error) |
33873 |
+ return error; |
33874 |
+ |
33875 |
++ if (!gr_acl_handle_mmap(file, prot)) |
33876 |
++ return -EACCES; |
33877 |
++ |
33878 |
+ return mmap_region(file, addr, len, flags, vm_flags, pgoff, |
33879 |
+ accountable); |
33880 |
+ } |
33881 |
+@@ -1037,10 +1141,10 @@ EXPORT_SYMBOL(do_mmap_pgoff); |
33882 |
+ */ |
33883 |
+ int vma_wants_writenotify(struct vm_area_struct *vma) |
33884 |
+ { |
33885 |
+- unsigned int vm_flags = vma->vm_flags; |
33886 |
++ unsigned long vm_flags = vma->vm_flags; |
33887 |
+ |
33888 |
+ /* If it was private or non-writable, the write bit is already clear */ |
33889 |
+- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED))) |
33890 |
++ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED)) |
33891 |
+ return 0; |
33892 |
+ |
33893 |
+ /* The backer wishes to know when pages are first written to? */ |
33894 |
+@@ -1049,8 +1153,7 @@ int vma_wants_writenotify(struct vm_area |
33895 |
+ |
33896 |
+ /* The open routine did something to the protections already? */ |
33897 |
+ if (pgprot_val(vma->vm_page_prot) != |
33898 |
+- pgprot_val(protection_map[vm_flags & |
33899 |
+- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)])) |
33900 |
++ pgprot_val(vm_get_page_prot(vm_flags))) |
33901 |
+ return 0; |
33902 |
+ |
33903 |
+ /* Specialty mapping? */ |
33904 |
+@@ -1076,14 +1179,24 @@ unsigned long mmap_region(struct file *f |
33905 |
+ unsigned long charged = 0; |
33906 |
+ struct inode *inode = file ? file->f_path.dentry->d_inode : NULL; |
33907 |
+ |
33908 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33909 |
++ struct vm_area_struct *vma_m = NULL; |
33910 |
++#endif |
33911 |
++ |
33912 |
++ /* |
33913 |
++ * mm->mmap_sem is required to protect against another thread |
33914 |
++ * changing the mappings in case we sleep. |
33915 |
++ */ |
33916 |
++ verify_mm_writelocked(mm); |
33917 |
++ |
33918 |
+ /* Clear old maps */ |
33919 |
+ error = -ENOMEM; |
33920 |
+-munmap_back: |
33921 |
+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
33922 |
+ if (vma && vma->vm_start < addr + len) { |
33923 |
+ if (do_munmap(mm, addr, len)) |
33924 |
+ return -ENOMEM; |
33925 |
+- goto munmap_back; |
33926 |
++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
33927 |
++ BUG_ON(vma && vma->vm_start < addr + len); |
33928 |
+ } |
33929 |
+ |
33930 |
+ /* Check against address space limit. */ |
33931 |
+@@ -1127,12 +1240,22 @@ munmap_back: |
33932 |
+ goto unacct_error; |
33933 |
+ } |
33934 |
+ |
33935 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33936 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) { |
33937 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
33938 |
++ if (!vma_m) { |
33939 |
++ kmem_cache_free(vm_area_cachep, vma); |
33940 |
++ error = -ENOMEM; |
33941 |
++ goto unacct_error; |
33942 |
++ } |
33943 |
++ } |
33944 |
++#endif |
33945 |
++ |
33946 |
+ vma->vm_mm = mm; |
33947 |
+ vma->vm_start = addr; |
33948 |
+ vma->vm_end = addr + len; |
33949 |
+ vma->vm_flags = vm_flags; |
33950 |
+- vma->vm_page_prot = protection_map[vm_flags & |
33951 |
+- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
33952 |
++ vma->vm_page_prot = vm_get_page_prot(vm_flags); |
33953 |
+ vma->vm_pgoff = pgoff; |
33954 |
+ |
33955 |
+ if (file) { |
33956 |
+@@ -1150,6 +1273,14 @@ munmap_back: |
33957 |
+ error = file->f_op->mmap(file, vma); |
33958 |
+ if (error) |
33959 |
+ goto unmap_and_free_vma; |
33960 |
++ |
33961 |
++#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
33962 |
++ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) { |
33963 |
++ vma->vm_flags |= VM_PAGEEXEC; |
33964 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
33965 |
++ } |
33966 |
++#endif |
33967 |
++ |
33968 |
+ } else if (vm_flags & VM_SHARED) { |
33969 |
+ error = shmem_zero_setup(vma); |
33970 |
+ if (error) |
33971 |
+@@ -1174,13 +1305,18 @@ munmap_back: |
33972 |
+ vm_flags = vma->vm_flags; |
33973 |
+ |
33974 |
+ if (vma_wants_writenotify(vma)) |
33975 |
+- vma->vm_page_prot = |
33976 |
+- protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)]; |
33977 |
++ vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED); |
33978 |
+ |
33979 |
+ if (!file || !vma_merge(mm, prev, addr, vma->vm_end, |
33980 |
+ vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) { |
33981 |
+ file = vma->vm_file; |
33982 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
33983 |
++ |
33984 |
++#ifdef CONFIG_PAX_SEGMEXEC |
33985 |
++ if (vma_m) |
33986 |
++ pax_mirror_vma(vma_m, vma); |
33987 |
++#endif |
33988 |
++ |
33989 |
+ if (correct_wcount) |
33990 |
+ atomic_inc(&inode->i_writecount); |
33991 |
+ } else { |
33992 |
+@@ -1191,10 +1327,12 @@ munmap_back: |
33993 |
+ } |
33994 |
+ mpol_free(vma_policy(vma)); |
33995 |
+ kmem_cache_free(vm_area_cachep, vma); |
33996 |
++ vma = NULL; |
33997 |
+ } |
33998 |
+ out: |
33999 |
+ mm->total_vm += len >> PAGE_SHIFT; |
34000 |
+ vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT); |
34001 |
++ track_exec_limit(mm, addr, addr + len, vm_flags); |
34002 |
+ if (vm_flags & VM_LOCKED) { |
34003 |
+ mm->locked_vm += len >> PAGE_SHIFT; |
34004 |
+ make_pages_present(addr, addr + len); |
34005 |
+@@ -1213,6 +1351,12 @@ unmap_and_free_vma: |
34006 |
+ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); |
34007 |
+ charged = 0; |
34008 |
+ free_vma: |
34009 |
++ |
34010 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34011 |
++ if (vma_m) |
34012 |
++ kmem_cache_free(vm_area_cachep, vma_m); |
34013 |
++#endif |
34014 |
++ |
34015 |
+ kmem_cache_free(vm_area_cachep, vma); |
34016 |
+ unacct_error: |
34017 |
+ if (charged) |
34018 |
+@@ -1246,6 +1390,10 @@ arch_get_unmapped_area(struct file *filp |
34019 |
+ if (flags & MAP_FIXED) |
34020 |
+ return addr; |
34021 |
+ |
34022 |
++#ifdef CONFIG_PAX_RANDMMAP |
34023 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) |
34024 |
++#endif |
34025 |
++ |
34026 |
+ if (addr) { |
34027 |
+ addr = PAGE_ALIGN(addr); |
34028 |
+ vma = find_vma(mm, addr); |
34029 |
+@@ -1254,10 +1402,10 @@ arch_get_unmapped_area(struct file *filp |
34030 |
+ return addr; |
34031 |
+ } |
34032 |
+ if (len > mm->cached_hole_size) { |
34033 |
+- start_addr = addr = mm->free_area_cache; |
34034 |
++ start_addr = addr = mm->free_area_cache; |
34035 |
+ } else { |
34036 |
+- start_addr = addr = TASK_UNMAPPED_BASE; |
34037 |
+- mm->cached_hole_size = 0; |
34038 |
++ start_addr = addr = mm->mmap_base; |
34039 |
++ mm->cached_hole_size = 0; |
34040 |
+ } |
34041 |
+ |
34042 |
+ full_search: |
34043 |
+@@ -1268,9 +1416,8 @@ full_search: |
34044 |
+ * Start a new search - just in case we missed |
34045 |
+ * some holes. |
34046 |
+ */ |
34047 |
+- if (start_addr != TASK_UNMAPPED_BASE) { |
34048 |
+- addr = TASK_UNMAPPED_BASE; |
34049 |
+- start_addr = addr; |
34050 |
++ if (start_addr != mm->mmap_base) { |
34051 |
++ start_addr = addr = mm->mmap_base; |
34052 |
+ mm->cached_hole_size = 0; |
34053 |
+ goto full_search; |
34054 |
+ } |
34055 |
+@@ -1292,10 +1439,16 @@ full_search: |
34056 |
+ |
34057 |
+ void arch_unmap_area(struct mm_struct *mm, unsigned long addr) |
34058 |
+ { |
34059 |
++ |
34060 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34061 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr) |
34062 |
++ return; |
34063 |
++#endif |
34064 |
++ |
34065 |
+ /* |
34066 |
+ * Is this a new hole at the lowest possible address? |
34067 |
+ */ |
34068 |
+- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) { |
34069 |
++ if (addr >= mm->mmap_base && addr < mm->free_area_cache) { |
34070 |
+ mm->free_area_cache = addr; |
34071 |
+ mm->cached_hole_size = ~0UL; |
34072 |
+ } |
34073 |
+@@ -1313,7 +1466,7 @@ arch_get_unmapped_area_topdown(struct fi |
34074 |
+ { |
34075 |
+ struct vm_area_struct *vma; |
34076 |
+ struct mm_struct *mm = current->mm; |
34077 |
+- unsigned long addr = addr0; |
34078 |
++ unsigned long base = mm->mmap_base, addr = addr0; |
34079 |
+ |
34080 |
+ /* requested length too big for entire address space */ |
34081 |
+ if (len > TASK_SIZE) |
34082 |
+@@ -1322,6 +1475,10 @@ arch_get_unmapped_area_topdown(struct fi |
34083 |
+ if (flags & MAP_FIXED) |
34084 |
+ return addr; |
34085 |
+ |
34086 |
++#ifdef CONFIG_PAX_RANDMMAP |
34087 |
++ if (!(mm->pax_flags & MF_PAX_RANDMMAP)) |
34088 |
++#endif |
34089 |
++ |
34090 |
+ /* requesting a specific address */ |
34091 |
+ if (addr) { |
34092 |
+ addr = PAGE_ALIGN(addr); |
34093 |
+@@ -1379,13 +1536,21 @@ bottomup: |
34094 |
+ * can happen with large stack limits and large mmap() |
34095 |
+ * allocations. |
34096 |
+ */ |
34097 |
++ mm->mmap_base = TASK_UNMAPPED_BASE; |
34098 |
++ |
34099 |
++#ifdef CONFIG_PAX_RANDMMAP |
34100 |
++ if (mm->pax_flags & MF_PAX_RANDMMAP) |
34101 |
++ mm->mmap_base += mm->delta_mmap; |
34102 |
++#endif |
34103 |
++ |
34104 |
++ mm->free_area_cache = mm->mmap_base; |
34105 |
+ mm->cached_hole_size = ~0UL; |
34106 |
+- mm->free_area_cache = TASK_UNMAPPED_BASE; |
34107 |
+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags); |
34108 |
+ /* |
34109 |
+ * Restore the topdown base: |
34110 |
+ */ |
34111 |
+- mm->free_area_cache = mm->mmap_base; |
34112 |
++ mm->mmap_base = base; |
34113 |
++ mm->free_area_cache = base; |
34114 |
+ mm->cached_hole_size = ~0UL; |
34115 |
+ |
34116 |
+ return addr; |
34117 |
+@@ -1394,6 +1559,12 @@ bottomup: |
34118 |
+ |
34119 |
+ void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr) |
34120 |
+ { |
34121 |
++ |
34122 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34123 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr) |
34124 |
++ return; |
34125 |
++#endif |
34126 |
++ |
34127 |
+ /* |
34128 |
+ * Is this a new hole at the highest possible address? |
34129 |
+ */ |
34130 |
+@@ -1401,8 +1572,10 @@ void arch_unmap_area_topdown(struct mm_s |
34131 |
+ mm->free_area_cache = addr; |
34132 |
+ |
34133 |
+ /* dont allow allocations above current base */ |
34134 |
+- if (mm->free_area_cache > mm->mmap_base) |
34135 |
++ if (mm->free_area_cache > mm->mmap_base) { |
34136 |
+ mm->free_area_cache = mm->mmap_base; |
34137 |
++ mm->cached_hole_size = ~0UL; |
34138 |
++ } |
34139 |
+ } |
34140 |
+ |
34141 |
+ unsigned long |
34142 |
+@@ -1502,6 +1675,32 @@ out: |
34143 |
+ return prev ? prev->vm_next : vma; |
34144 |
+ } |
34145 |
+ |
34146 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34147 |
++struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma) |
34148 |
++{ |
34149 |
++ struct vm_area_struct *vma_m; |
34150 |
++ |
34151 |
++ BUG_ON(!vma || vma->vm_start >= vma->vm_end); |
34152 |
++ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) { |
34153 |
++ BUG_ON(vma->vm_mirror); |
34154 |
++ return NULL; |
34155 |
++ } |
34156 |
++ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1); |
34157 |
++ vma_m = vma->vm_mirror; |
34158 |
++ BUG_ON(!vma_m || vma_m->vm_mirror != vma); |
34159 |
++ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start); |
34160 |
++ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma); |
34161 |
++ |
34162 |
++#ifdef CONFIG_PAX_MPROTECT |
34163 |
++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE)); |
34164 |
++#else |
34165 |
++ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED)); |
34166 |
++#endif |
34167 |
++ |
34168 |
++ return vma_m; |
34169 |
++} |
34170 |
++#endif |
34171 |
++ |
34172 |
+ /* |
34173 |
+ * Verify that the stack growth is acceptable and |
34174 |
+ * update accounting. This is shared with both the |
34175 |
+@@ -1518,6 +1717,7 @@ static int acct_stack_growth(struct vm_a |
34176 |
+ return -ENOMEM; |
34177 |
+ |
34178 |
+ /* Stack limit test */ |
34179 |
++ gr_learn_resource(current, RLIMIT_STACK, size, 1); |
34180 |
+ if (size > rlim[RLIMIT_STACK].rlim_cur) |
34181 |
+ return -ENOMEM; |
34182 |
+ |
34183 |
+@@ -1527,6 +1727,7 @@ static int acct_stack_growth(struct vm_a |
34184 |
+ unsigned long limit; |
34185 |
+ locked = mm->locked_vm + grow; |
34186 |
+ limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT; |
34187 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); |
34188 |
+ if (locked > limit && !capable(CAP_IPC_LOCK)) |
34189 |
+ return -ENOMEM; |
34190 |
+ } |
34191 |
+@@ -1562,35 +1763,40 @@ static inline |
34192 |
+ #endif |
34193 |
+ int expand_upwards(struct vm_area_struct *vma, unsigned long address) |
34194 |
+ { |
34195 |
+- int error; |
34196 |
++ int error, locknext; |
34197 |
+ |
34198 |
+ if (!(vma->vm_flags & VM_GROWSUP)) |
34199 |
+ return -EFAULT; |
34200 |
+ |
34201 |
++ /* Also guard against wrapping around to address 0. */ |
34202 |
++ if (address < PAGE_ALIGN(address+1)) |
34203 |
++ address = PAGE_ALIGN(address+1); |
34204 |
++ else |
34205 |
++ return -ENOMEM; |
34206 |
++ |
34207 |
+ /* |
34208 |
+ * We must make sure the anon_vma is allocated |
34209 |
+ * so that the anon_vma locking is not a noop. |
34210 |
+ */ |
34211 |
+ if (unlikely(anon_vma_prepare(vma))) |
34212 |
+ return -ENOMEM; |
34213 |
++ locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN); |
34214 |
++ if (locknext && unlikely(anon_vma_prepare(vma->vm_next))) |
34215 |
++ return -ENOMEM; |
34216 |
+ anon_vma_lock(vma); |
34217 |
++ if (locknext) |
34218 |
++ anon_vma_lock(vma->vm_next); |
34219 |
+ |
34220 |
+ /* |
34221 |
+ * vma->vm_start/vm_end cannot change under us because the caller |
34222 |
+ * is required to hold the mmap_sem in read mode. We need the |
34223 |
+- * anon_vma lock to serialize against concurrent expand_stacks. |
34224 |
+- * Also guard against wrapping around to address 0. |
34225 |
++ * anon_vma locks to serialize against concurrent expand_stacks |
34226 |
++ * and expand_upwards. |
34227 |
+ */ |
34228 |
+- if (address < PAGE_ALIGN(address+4)) |
34229 |
+- address = PAGE_ALIGN(address+4); |
34230 |
+- else { |
34231 |
+- anon_vma_unlock(vma); |
34232 |
+- return -ENOMEM; |
34233 |
+- } |
34234 |
+ error = 0; |
34235 |
+ |
34236 |
+ /* Somebody else might have raced and expanded it already */ |
34237 |
+- if (address > vma->vm_end) { |
34238 |
++ if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) { |
34239 |
+ unsigned long size, grow; |
34240 |
+ |
34241 |
+ size = address - vma->vm_start; |
34242 |
+@@ -1600,6 +1806,8 @@ int expand_upwards(struct vm_area_struct |
34243 |
+ if (!error) |
34244 |
+ vma->vm_end = address; |
34245 |
+ } |
34246 |
++ if (locknext) |
34247 |
++ anon_vma_unlock(vma->vm_next); |
34248 |
+ anon_vma_unlock(vma); |
34249 |
+ return error; |
34250 |
+ } |
34251 |
+@@ -1611,7 +1819,8 @@ int expand_upwards(struct vm_area_struct |
34252 |
+ static inline int expand_downwards(struct vm_area_struct *vma, |
34253 |
+ unsigned long address) |
34254 |
+ { |
34255 |
+- int error; |
34256 |
++ int error, lockprev = 0; |
34257 |
++ struct vm_area_struct *prev = NULL; |
34258 |
+ |
34259 |
+ /* |
34260 |
+ * We must make sure the anon_vma is allocated |
34261 |
+@@ -1625,6 +1834,15 @@ static inline int expand_downwards(struc |
34262 |
+ if (error) |
34263 |
+ return error; |
34264 |
+ |
34265 |
++#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64) |
34266 |
++ find_vma_prev(address, &prev); |
34267 |
++ lockprev = prev && (prev->vm_flags & VM_GROWSUP); |
34268 |
++#endif |
34269 |
++ if (lockprev && unlikely(anon_vma_prepare(prev))) |
34270 |
++ return -ENOMEM; |
34271 |
++ if (lockprev) |
34272 |
++ anon_vma_lock(prev); |
34273 |
++ |
34274 |
+ anon_vma_lock(vma); |
34275 |
+ |
34276 |
+ /* |
34277 |
+@@ -1634,9 +1852,15 @@ static inline int expand_downwards(struc |
34278 |
+ */ |
34279 |
+ |
34280 |
+ /* Somebody else might have raced and expanded it already */ |
34281 |
+- if (address < vma->vm_start) { |
34282 |
++ if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) { |
34283 |
+ unsigned long size, grow; |
34284 |
+ |
34285 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34286 |
++ struct vm_area_struct *vma_m; |
34287 |
++ |
34288 |
++ vma_m = pax_find_mirror_vma(vma); |
34289 |
++#endif |
34290 |
++ |
34291 |
+ size = vma->vm_end - address; |
34292 |
+ grow = (vma->vm_start - address) >> PAGE_SHIFT; |
34293 |
+ |
34294 |
+@@ -1644,9 +1868,20 @@ static inline int expand_downwards(struc |
34295 |
+ if (!error) { |
34296 |
+ vma->vm_start = address; |
34297 |
+ vma->vm_pgoff -= grow; |
34298 |
++ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags); |
34299 |
++ |
34300 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34301 |
++ if (vma_m) { |
34302 |
++ vma_m->vm_start -= grow << PAGE_SHIFT; |
34303 |
++ vma_m->vm_pgoff -= grow; |
34304 |
++ } |
34305 |
++#endif |
34306 |
++ |
34307 |
+ } |
34308 |
+ } |
34309 |
+ anon_vma_unlock(vma); |
34310 |
++ if (lockprev) |
34311 |
++ anon_vma_unlock(prev); |
34312 |
+ return error; |
34313 |
+ } |
34314 |
+ |
34315 |
+@@ -1718,6 +1953,13 @@ static void remove_vma_list(struct mm_st |
34316 |
+ do { |
34317 |
+ long nrpages = vma_pages(vma); |
34318 |
+ |
34319 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34320 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) { |
34321 |
++ vma = remove_vma(vma); |
34322 |
++ continue; |
34323 |
++ } |
34324 |
++#endif |
34325 |
++ |
34326 |
+ mm->total_vm -= nrpages; |
34327 |
+ if (vma->vm_flags & VM_LOCKED) |
34328 |
+ mm->locked_vm -= nrpages; |
34329 |
+@@ -1764,6 +2006,16 @@ detach_vmas_to_be_unmapped(struct mm_str |
34330 |
+ |
34331 |
+ insertion_point = (prev ? &prev->vm_next : &mm->mmap); |
34332 |
+ do { |
34333 |
++ |
34334 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34335 |
++ if (vma->vm_mirror) { |
34336 |
++ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma); |
34337 |
++ vma->vm_mirror->vm_mirror = NULL; |
34338 |
++ vma->vm_mirror->vm_flags &= ~VM_EXEC; |
34339 |
++ vma->vm_mirror = NULL; |
34340 |
++ } |
34341 |
++#endif |
34342 |
++ |
34343 |
+ rb_erase(&vma->vm_rb, &mm->mm_rb); |
34344 |
+ mm->map_count--; |
34345 |
+ tail_vma = vma; |
34346 |
+@@ -1783,6 +2035,112 @@ detach_vmas_to_be_unmapped(struct mm_str |
34347 |
+ * Split a vma into two pieces at address 'addr', a new vma is allocated |
34348 |
+ * either for the first part or the tail. |
34349 |
+ */ |
34350 |
++ |
34351 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34352 |
++int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, |
34353 |
++ unsigned long addr, int new_below) |
34354 |
++{ |
34355 |
++ struct mempolicy *pol, *pol_m; |
34356 |
++ struct vm_area_struct *new, *vma_m, *new_m = NULL; |
34357 |
++ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE; |
34358 |
++ |
34359 |
++ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK)) |
34360 |
++ return -EINVAL; |
34361 |
++ |
34362 |
++ vma_m = pax_find_mirror_vma(vma); |
34363 |
++ if (vma_m) { |
34364 |
++ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE); |
34365 |
++ if (mm->map_count >= sysctl_max_map_count-1) |
34366 |
++ return -ENOMEM; |
34367 |
++ } else if (mm->map_count >= sysctl_max_map_count) |
34368 |
++ return -ENOMEM; |
34369 |
++ |
34370 |
++ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
34371 |
++ if (!new) |
34372 |
++ return -ENOMEM; |
34373 |
++ |
34374 |
++ if (vma_m) { |
34375 |
++ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
34376 |
++ if (!new_m) { |
34377 |
++ kmem_cache_free(vm_area_cachep, new); |
34378 |
++ return -ENOMEM; |
34379 |
++ } |
34380 |
++ } |
34381 |
++ |
34382 |
++ /* most fields are the same, copy all, and then fixup */ |
34383 |
++ *new = *vma; |
34384 |
++ |
34385 |
++ if (new_below) |
34386 |
++ new->vm_end = addr; |
34387 |
++ else { |
34388 |
++ new->vm_start = addr; |
34389 |
++ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); |
34390 |
++ } |
34391 |
++ |
34392 |
++ if (vma_m) { |
34393 |
++ *new_m = *vma_m; |
34394 |
++ new_m->vm_mirror = new; |
34395 |
++ new->vm_mirror = new_m; |
34396 |
++ |
34397 |
++ if (new_below) |
34398 |
++ new_m->vm_end = addr_m; |
34399 |
++ else { |
34400 |
++ new_m->vm_start = addr_m; |
34401 |
++ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT); |
34402 |
++ } |
34403 |
++ } |
34404 |
++ |
34405 |
++ pol = mpol_copy(vma_policy(vma)); |
34406 |
++ if (IS_ERR(pol)) { |
34407 |
++ if (new_m) |
34408 |
++ kmem_cache_free(vm_area_cachep, new_m); |
34409 |
++ kmem_cache_free(vm_area_cachep, new); |
34410 |
++ return PTR_ERR(pol); |
34411 |
++ } |
34412 |
++ |
34413 |
++ if (vma_m) { |
34414 |
++ pol_m = mpol_copy(vma_policy(vma_m)); |
34415 |
++ if (IS_ERR(pol_m)) { |
34416 |
++ mpol_free(pol); |
34417 |
++ kmem_cache_free(vm_area_cachep, new_m); |
34418 |
++ kmem_cache_free(vm_area_cachep, new); |
34419 |
++ return PTR_ERR(pol); |
34420 |
++ } |
34421 |
++ } |
34422 |
++ |
34423 |
++ vma_set_policy(new, pol); |
34424 |
++ |
34425 |
++ if (new->vm_file) |
34426 |
++ get_file(new->vm_file); |
34427 |
++ |
34428 |
++ if (new->vm_ops && new->vm_ops->open) |
34429 |
++ new->vm_ops->open(new); |
34430 |
++ |
34431 |
++ if (new_below) |
34432 |
++ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff + |
34433 |
++ ((addr - new->vm_start) >> PAGE_SHIFT), new); |
34434 |
++ else |
34435 |
++ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); |
34436 |
++ |
34437 |
++ if (vma_m) { |
34438 |
++ vma_set_policy(new_m, pol_m); |
34439 |
++ |
34440 |
++ if (new_m->vm_file) |
34441 |
++ get_file(new_m->vm_file); |
34442 |
++ |
34443 |
++ if (new_m->vm_ops && new_m->vm_ops->open) |
34444 |
++ new_m->vm_ops->open(new_m); |
34445 |
++ |
34446 |
++ if (new_below) |
34447 |
++ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff + |
34448 |
++ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m); |
34449 |
++ else |
34450 |
++ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m); |
34451 |
++ } |
34452 |
++ |
34453 |
++ return 0; |
34454 |
++} |
34455 |
++#else |
34456 |
+ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, |
34457 |
+ unsigned long addr, int new_below) |
34458 |
+ { |
34459 |
+@@ -1830,17 +2188,37 @@ int split_vma(struct mm_struct * mm, str |
34460 |
+ |
34461 |
+ return 0; |
34462 |
+ } |
34463 |
++#endif |
34464 |
+ |
34465 |
+ /* Munmap is split into 2 main parts -- this part which finds |
34466 |
+ * what needs doing, and the areas themselves, which do the |
34467 |
+ * work. This now handles partial unmappings. |
34468 |
+ * Jeremy Fitzhardinge <jeremy@××××.org> |
34469 |
+ */ |
34470 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34471 |
+ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) |
34472 |
+ { |
34473 |
++ int ret = __do_munmap(mm, start, len); |
34474 |
++ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC)) |
34475 |
++ return ret; |
34476 |
++ |
34477 |
++ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len); |
34478 |
++} |
34479 |
++ |
34480 |
++int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len) |
34481 |
++#else |
34482 |
++int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) |
34483 |
++#endif |
34484 |
++{ |
34485 |
+ unsigned long end; |
34486 |
+ struct vm_area_struct *vma, *prev, *last; |
34487 |
+ |
34488 |
++ /* |
34489 |
++ * mm->mmap_sem is required to protect against another thread |
34490 |
++ * changing the mappings in case we sleep. |
34491 |
++ */ |
34492 |
++ verify_mm_writelocked(mm); |
34493 |
++ |
34494 |
+ if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) |
34495 |
+ return -EINVAL; |
34496 |
+ |
34497 |
+@@ -1890,6 +2268,8 @@ int do_munmap(struct mm_struct *mm, unsi |
34498 |
+ /* Fix up all other VM information */ |
34499 |
+ remove_vma_list(mm, vma); |
34500 |
+ |
34501 |
++ track_exec_limit(mm, start, end, 0UL); |
34502 |
++ |
34503 |
+ return 0; |
34504 |
+ } |
34505 |
+ |
34506 |
+@@ -1902,22 +2282,18 @@ asmlinkage long sys_munmap(unsigned long |
34507 |
+ |
34508 |
+ profile_munmap(addr); |
34509 |
+ |
34510 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34511 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && |
34512 |
++ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)) |
34513 |
++ return -EINVAL; |
34514 |
++#endif |
34515 |
++ |
34516 |
+ down_write(&mm->mmap_sem); |
34517 |
+ ret = do_munmap(mm, addr, len); |
34518 |
+ up_write(&mm->mmap_sem); |
34519 |
+ return ret; |
34520 |
+ } |
34521 |
+ |
34522 |
+-static inline void verify_mm_writelocked(struct mm_struct *mm) |
34523 |
+-{ |
34524 |
+-#ifdef CONFIG_DEBUG_VM |
34525 |
+- if (unlikely(down_read_trylock(&mm->mmap_sem))) { |
34526 |
+- WARN_ON(1); |
34527 |
+- up_read(&mm->mmap_sem); |
34528 |
+- } |
34529 |
+-#endif |
34530 |
+-} |
34531 |
+- |
34532 |
+ /* |
34533 |
+ * this is really a simplified "do_mmap". it only handles |
34534 |
+ * anonymous maps. eventually we may be able to do some |
34535 |
+@@ -1931,6 +2307,11 @@ unsigned long do_brk(unsigned long addr, |
34536 |
+ struct rb_node ** rb_link, * rb_parent; |
34537 |
+ pgoff_t pgoff = addr >> PAGE_SHIFT; |
34538 |
+ int error; |
34539 |
++ unsigned long charged; |
34540 |
++ |
34541 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34542 |
++ struct vm_area_struct *vma_m = NULL; |
34543 |
++#endif |
34544 |
+ |
34545 |
+ len = PAGE_ALIGN(len); |
34546 |
+ if (!len) |
34547 |
+@@ -1948,19 +2329,34 @@ unsigned long do_brk(unsigned long addr, |
34548 |
+ |
34549 |
+ flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; |
34550 |
+ |
34551 |
++#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) |
34552 |
++ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) { |
34553 |
++ flags &= ~VM_EXEC; |
34554 |
++ |
34555 |
++#ifdef CONFIG_PAX_MPROTECT |
34556 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) |
34557 |
++ flags &= ~VM_MAYEXEC; |
34558 |
++#endif |
34559 |
++ |
34560 |
++ } |
34561 |
++#endif |
34562 |
++ |
34563 |
+ error = arch_mmap_check(addr, len, flags); |
34564 |
+ if (error) |
34565 |
+ return error; |
34566 |
+ |
34567 |
++ charged = len >> PAGE_SHIFT; |
34568 |
++ |
34569 |
+ /* |
34570 |
+ * mlock MCL_FUTURE? |
34571 |
+ */ |
34572 |
+ if (mm->def_flags & VM_LOCKED) { |
34573 |
+ unsigned long locked, lock_limit; |
34574 |
+- locked = len >> PAGE_SHIFT; |
34575 |
++ locked = charged; |
34576 |
+ locked += mm->locked_vm; |
34577 |
+ lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; |
34578 |
+ lock_limit >>= PAGE_SHIFT; |
34579 |
++ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1); |
34580 |
+ if (locked > lock_limit && !capable(CAP_IPC_LOCK)) |
34581 |
+ return -EAGAIN; |
34582 |
+ } |
34583 |
+@@ -1974,22 +2370,22 @@ unsigned long do_brk(unsigned long addr, |
34584 |
+ /* |
34585 |
+ * Clear old maps. this also does some error checking for us |
34586 |
+ */ |
34587 |
+- munmap_back: |
34588 |
+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
34589 |
+ if (vma && vma->vm_start < addr + len) { |
34590 |
+ if (do_munmap(mm, addr, len)) |
34591 |
+ return -ENOMEM; |
34592 |
+- goto munmap_back; |
34593 |
++ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); |
34594 |
++ BUG_ON(vma && vma->vm_start < addr + len); |
34595 |
+ } |
34596 |
+ |
34597 |
+ /* Check against address space limits *after* clearing old maps... */ |
34598 |
+- if (!may_expand_vm(mm, len >> PAGE_SHIFT)) |
34599 |
++ if (!may_expand_vm(mm, charged)) |
34600 |
+ return -ENOMEM; |
34601 |
+ |
34602 |
+ if (mm->map_count > sysctl_max_map_count) |
34603 |
+ return -ENOMEM; |
34604 |
+ |
34605 |
+- if (security_vm_enough_memory(len >> PAGE_SHIFT)) |
34606 |
++ if (security_vm_enough_memory(charged)) |
34607 |
+ return -ENOMEM; |
34608 |
+ |
34609 |
+ /* Can we just expand an old private anonymous mapping? */ |
34610 |
+@@ -2002,24 +2398,41 @@ unsigned long do_brk(unsigned long addr, |
34611 |
+ */ |
34612 |
+ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
34613 |
+ if (!vma) { |
34614 |
+- vm_unacct_memory(len >> PAGE_SHIFT); |
34615 |
++ vm_unacct_memory(charged); |
34616 |
+ return -ENOMEM; |
34617 |
+ } |
34618 |
+ |
34619 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34620 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) { |
34621 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
34622 |
++ if (!vma_m) { |
34623 |
++ kmem_cache_free(vm_area_cachep, vma); |
34624 |
++ vm_unacct_memory(charged); |
34625 |
++ return -ENOMEM; |
34626 |
++ } |
34627 |
++ } |
34628 |
++#endif |
34629 |
++ |
34630 |
+ vma->vm_mm = mm; |
34631 |
+ vma->vm_start = addr; |
34632 |
+ vma->vm_end = addr + len; |
34633 |
+ vma->vm_pgoff = pgoff; |
34634 |
+ vma->vm_flags = flags; |
34635 |
+- vma->vm_page_prot = protection_map[flags & |
34636 |
+- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
34637 |
++ vma->vm_page_prot = vm_get_page_prot(flags); |
34638 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
34639 |
++ |
34640 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34641 |
++ if (vma_m) |
34642 |
++ pax_mirror_vma(vma_m, vma); |
34643 |
++#endif |
34644 |
++ |
34645 |
+ out: |
34646 |
+- mm->total_vm += len >> PAGE_SHIFT; |
34647 |
++ mm->total_vm += charged; |
34648 |
+ if (flags & VM_LOCKED) { |
34649 |
+- mm->locked_vm += len >> PAGE_SHIFT; |
34650 |
++ mm->locked_vm += charged; |
34651 |
+ make_pages_present(addr, addr + len); |
34652 |
+ } |
34653 |
++ track_exec_limit(mm, addr, addr + len, flags); |
34654 |
+ return addr; |
34655 |
+ } |
34656 |
+ |
34657 |
+@@ -2050,8 +2463,10 @@ void exit_mmap(struct mm_struct *mm) |
34658 |
+ * Walk the list again, actually closing and freeing it, |
34659 |
+ * with preemption enabled, without holding any MM locks. |
34660 |
+ */ |
34661 |
+- while (vma) |
34662 |
++ while (vma) { |
34663 |
++ vma->vm_mirror = NULL; |
34664 |
+ vma = remove_vma(vma); |
34665 |
++ } |
34666 |
+ |
34667 |
+ BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); |
34668 |
+ } |
34669 |
+@@ -2065,6 +2480,10 @@ int insert_vm_struct(struct mm_struct * |
34670 |
+ struct vm_area_struct * __vma, * prev; |
34671 |
+ struct rb_node ** rb_link, * rb_parent; |
34672 |
+ |
34673 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34674 |
++ struct vm_area_struct *vma_m = NULL; |
34675 |
++#endif |
34676 |
++ |
34677 |
+ /* |
34678 |
+ * The vm_pgoff of a purely anonymous vma should be irrelevant |
34679 |
+ * until its first write fault, when page's anon_vma and index |
34680 |
+@@ -2087,7 +2506,22 @@ int insert_vm_struct(struct mm_struct * |
34681 |
+ if ((vma->vm_flags & VM_ACCOUNT) && |
34682 |
+ security_vm_enough_memory_mm(mm, vma_pages(vma))) |
34683 |
+ return -ENOMEM; |
34684 |
++ |
34685 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34686 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) { |
34687 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
34688 |
++ if (!vma_m) |
34689 |
++ return -ENOMEM; |
34690 |
++ } |
34691 |
++#endif |
34692 |
++ |
34693 |
+ vma_link(mm, vma, prev, rb_link, rb_parent); |
34694 |
++ |
34695 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34696 |
++ if (vma_m) |
34697 |
++ pax_mirror_vma(vma_m, vma); |
34698 |
++#endif |
34699 |
++ |
34700 |
+ return 0; |
34701 |
+ } |
34702 |
+ |
34703 |
+@@ -2145,6 +2579,30 @@ struct vm_area_struct *copy_vma(struct v |
34704 |
+ return new_vma; |
34705 |
+ } |
34706 |
+ |
34707 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34708 |
++void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma) |
34709 |
++{ |
34710 |
++ struct vm_area_struct *prev_m; |
34711 |
++ struct rb_node **rb_link_m, *rb_parent_m; |
34712 |
++ |
34713 |
++ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)); |
34714 |
++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma)); |
34715 |
++ *vma_m = *vma; |
34716 |
++ vma_m->vm_start += SEGMEXEC_TASK_SIZE; |
34717 |
++ vma_m->vm_end += SEGMEXEC_TASK_SIZE; |
34718 |
++ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED); |
34719 |
++ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags); |
34720 |
++ if (vma_m->vm_file) |
34721 |
++ get_file(vma_m->vm_file); |
34722 |
++ if (vma_m->vm_ops && vma_m->vm_ops->open) |
34723 |
++ vma_m->vm_ops->open(vma_m); |
34724 |
++ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m); |
34725 |
++ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m); |
34726 |
++ vma_m->vm_mirror = vma; |
34727 |
++ vma->vm_mirror = vma_m; |
34728 |
++} |
34729 |
++#endif |
34730 |
++ |
34731 |
+ /* |
34732 |
+ * Return true if the calling process may expand its vm space by the passed |
34733 |
+ * number of pages |
34734 |
+@@ -2155,7 +2613,7 @@ int may_expand_vm(struct mm_struct *mm, |
34735 |
+ unsigned long lim; |
34736 |
+ |
34737 |
+ lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; |
34738 |
+- |
34739 |
++ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1); |
34740 |
+ if (cur + npages > lim) |
34741 |
+ return 0; |
34742 |
+ return 1; |
34743 |
+@@ -2167,7 +2625,7 @@ static struct page *special_mapping_nopa |
34744 |
+ { |
34745 |
+ struct page **pages; |
34746 |
+ |
34747 |
+- BUG_ON(address < vma->vm_start || address >= vma->vm_end); |
34748 |
++ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK)); |
34749 |
+ |
34750 |
+ address -= vma->vm_start; |
34751 |
+ for (pages = vma->vm_private_data; address > 0 && *pages; ++pages) |
34752 |
+@@ -2217,8 +2675,17 @@ int install_special_mapping(struct mm_st |
34753 |
+ vma->vm_start = addr; |
34754 |
+ vma->vm_end = addr + len; |
34755 |
+ |
34756 |
++#ifdef CONFIG_PAX_MPROTECT |
34757 |
++ if (mm->pax_flags & MF_PAX_MPROTECT) { |
34758 |
++ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC) |
34759 |
++ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); |
34760 |
++ else |
34761 |
++ vm_flags &= ~(VM_WRITE | VM_MAYWRITE); |
34762 |
++ } |
34763 |
++#endif |
34764 |
++ |
34765 |
+ vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; |
34766 |
+- vma->vm_page_prot = protection_map[vma->vm_flags & 7]; |
34767 |
++ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
34768 |
+ |
34769 |
+ vma->vm_ops = &special_mapping_vmops; |
34770 |
+ vma->vm_private_data = pages; |
34771 |
+diff -Nurp linux-2.6.23.15/mm/mprotect.c linux-2.6.23.15-grsec/mm/mprotect.c |
34772 |
+--- linux-2.6.23.15/mm/mprotect.c 2007-10-09 21:31:38.000000000 +0100 |
34773 |
++++ linux-2.6.23.15-grsec/mm/mprotect.c 2008-02-11 10:37:45.000000000 +0000 |
34774 |
+@@ -21,10 +21,17 @@ |
34775 |
+ #include <linux/syscalls.h> |
34776 |
+ #include <linux/swap.h> |
34777 |
+ #include <linux/swapops.h> |
34778 |
++#include <linux/grsecurity.h> |
34779 |
++ |
34780 |
++#ifdef CONFIG_PAX_MPROTECT |
34781 |
++#include <linux/elf.h> |
34782 |
++#endif |
34783 |
++ |
34784 |
+ #include <asm/uaccess.h> |
34785 |
+ #include <asm/pgtable.h> |
34786 |
+ #include <asm/cacheflush.h> |
34787 |
+ #include <asm/tlbflush.h> |
34788 |
++#include <asm/mmu_context.h> |
34789 |
+ |
34790 |
+ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd, |
34791 |
+ unsigned long addr, unsigned long end, pgprot_t newprot, |
34792 |
+@@ -128,6 +135,48 @@ static void change_protection(struct vm_ |
34793 |
+ flush_tlb_range(vma, start, end); |
34794 |
+ } |
34795 |
+ |
34796 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
34797 |
++/* called while holding the mmap semaphor for writing except stack expansion */ |
34798 |
++void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) |
34799 |
++{ |
34800 |
++ unsigned long oldlimit, newlimit = 0UL; |
34801 |
++ |
34802 |
++ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled) |
34803 |
++ return; |
34804 |
++ |
34805 |
++ spin_lock(&mm->page_table_lock); |
34806 |
++ oldlimit = mm->context.user_cs_limit; |
34807 |
++ if ((prot & VM_EXEC) && oldlimit < end) |
34808 |
++ /* USER_CS limit moved up */ |
34809 |
++ newlimit = end; |
34810 |
++ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end) |
34811 |
++ /* USER_CS limit moved down */ |
34812 |
++ newlimit = start; |
34813 |
++ |
34814 |
++ if (newlimit) { |
34815 |
++ mm->context.user_cs_limit = newlimit; |
34816 |
++ |
34817 |
++#ifdef CONFIG_SMP |
34818 |
++ wmb(); |
34819 |
++ cpus_clear(mm->context.cpu_user_cs_mask); |
34820 |
++ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask); |
34821 |
++#endif |
34822 |
++ |
34823 |
++ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id()); |
34824 |
++ } |
34825 |
++ spin_unlock(&mm->page_table_lock); |
34826 |
++ if (newlimit == end) { |
34827 |
++ struct vm_area_struct *vma = find_vma(mm, oldlimit); |
34828 |
++ |
34829 |
++ for (; vma && vma->vm_start < end; vma = vma->vm_next) |
34830 |
++ if (is_vm_hugetlb_page(vma)) |
34831 |
++ hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot); |
34832 |
++ else |
34833 |
++ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma)); |
34834 |
++ } |
34835 |
++} |
34836 |
++#endif |
34837 |
++ |
34838 |
+ int |
34839 |
+ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, |
34840 |
+ unsigned long start, unsigned long end, unsigned long newflags) |
34841 |
+@@ -140,11 +189,39 @@ mprotect_fixup(struct vm_area_struct *vm |
34842 |
+ int error; |
34843 |
+ int dirty_accountable = 0; |
34844 |
+ |
34845 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34846 |
++ struct vm_area_struct *vma_m = NULL; |
34847 |
++ unsigned long start_m, end_m; |
34848 |
++ |
34849 |
++ start_m = start + SEGMEXEC_TASK_SIZE; |
34850 |
++ end_m = end + SEGMEXEC_TASK_SIZE; |
34851 |
++#endif |
34852 |
++ |
34853 |
+ if (newflags == oldflags) { |
34854 |
+ *pprev = vma; |
34855 |
+ return 0; |
34856 |
+ } |
34857 |
+ |
34858 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34859 |
++ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) { |
34860 |
++ if (start != vma->vm_start) { |
34861 |
++ error = split_vma(mm, vma, start, 1); |
34862 |
++ if (error) |
34863 |
++ return -ENOMEM; |
34864 |
++ } |
34865 |
++ |
34866 |
++ if (end != vma->vm_end) { |
34867 |
++ error = split_vma(mm, vma, end, 0); |
34868 |
++ if (error) |
34869 |
++ return -ENOMEM; |
34870 |
++ } |
34871 |
++ |
34872 |
++ error = __do_munmap(mm, start_m, end_m - start_m); |
34873 |
++ if (error) |
34874 |
++ return -ENOMEM; |
34875 |
++ } |
34876 |
++#endif |
34877 |
++ |
34878 |
+ /* |
34879 |
+ * If we make a private mapping writable we increase our commit; |
34880 |
+ * but (without finer accounting) cannot reduce our commit if we |
34881 |
+@@ -187,17 +264,25 @@ mprotect_fixup(struct vm_area_struct *vm |
34882 |
+ goto fail; |
34883 |
+ } |
34884 |
+ |
34885 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34886 |
++ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) { |
34887 |
++ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
34888 |
++ if (!vma_m) { |
34889 |
++ error = -ENOMEM; |
34890 |
++ goto fail; |
34891 |
++ } |
34892 |
++ } |
34893 |
++#endif |
34894 |
++ |
34895 |
+ success: |
34896 |
+ /* |
34897 |
+ * vm_flags and vm_page_prot are protected by the mmap_sem |
34898 |
+ * held in write mode. |
34899 |
+ */ |
34900 |
+ vma->vm_flags = newflags; |
34901 |
+- vma->vm_page_prot = protection_map[newflags & |
34902 |
+- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; |
34903 |
++ vma->vm_page_prot = vm_get_page_prot(newflags); |
34904 |
+ if (vma_wants_writenotify(vma)) { |
34905 |
+- vma->vm_page_prot = protection_map[newflags & |
34906 |
+- (VM_READ|VM_WRITE|VM_EXEC)]; |
34907 |
++ vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED); |
34908 |
+ dirty_accountable = 1; |
34909 |
+ } |
34910 |
+ |
34911 |
+@@ -205,6 +290,12 @@ success: |
34912 |
+ hugetlb_change_protection(vma, start, end, vma->vm_page_prot); |
34913 |
+ else |
34914 |
+ change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable); |
34915 |
++ |
34916 |
++#ifdef CONFIG_PAX_SEGMEXEC |
34917 |
++ if (vma_m) |
34918 |
++ pax_mirror_vma(vma_m, vma); |
34919 |
++#endif |
34920 |
++ |
34921 |
+ vm_stat_account(mm, oldflags, vma->vm_file, -nrpages); |
34922 |
+ vm_stat_account(mm, newflags, vma->vm_file, nrpages); |
34923 |
+ return 0; |
34924 |
+@@ -214,6 +305,70 @@ fail: |
34925 |
+ return error; |
34926 |
+ } |
34927 |
+ |
34928 |
++#ifdef CONFIG_PAX_MPROTECT |
34929 |
++/* PaX: non-PIC ELF libraries need relocations on their executable segments |
34930 |
++ * therefore we'll grant them VM_MAYWRITE once during their life. |
34931 |
++ * |
34932 |
++ * The checks favour ld-linux.so behaviour which operates on a per ELF segment |
34933 |
++ * basis because we want to allow the common case and not the special ones. |
34934 |
++ */ |
34935 |
++static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start) |
34936 |
++{ |
34937 |
++ struct elfhdr elf_h; |
34938 |
++ struct elf_phdr elf_p; |
34939 |
++ elf_addr_t dyn_offset = 0UL; |
34940 |
++ elf_dyn dyn; |
34941 |
++ unsigned long i, j = 65536UL / sizeof(struct elf_phdr); |
34942 |
++ |
34943 |
++#ifndef CONFIG_PAX_NOELFRELOCS |
34944 |
++ if ((vma->vm_start != start) || |
34945 |
++ !vma->vm_file || |
34946 |
++ !(vma->vm_flags & VM_MAYEXEC) || |
34947 |
++ (vma->vm_flags & VM_MAYNOTWRITE)) |
34948 |
++#endif |
34949 |
++ |
34950 |
++ return; |
34951 |
++ |
34952 |
++ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) || |
34953 |
++ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) || |
34954 |
++ |
34955 |
++#ifdef CONFIG_PAX_ETEXECRELOCS |
34956 |
++ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) || |
34957 |
++#else |
34958 |
++ elf_h.e_type != ET_DYN || |
34959 |
++#endif |
34960 |
++ |
34961 |
++ !elf_check_arch(&elf_h) || |
34962 |
++ elf_h.e_phentsize != sizeof(struct elf_phdr) || |
34963 |
++ elf_h.e_phnum > j) |
34964 |
++ return; |
34965 |
++ |
34966 |
++ for (i = 0UL; i < elf_h.e_phnum; i++) { |
34967 |
++ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p))) |
34968 |
++ return; |
34969 |
++ if (elf_p.p_type == PT_DYNAMIC) { |
34970 |
++ dyn_offset = elf_p.p_offset; |
34971 |
++ j = i; |
34972 |
++ } |
34973 |
++ } |
34974 |
++ if (elf_h.e_phnum <= j) |
34975 |
++ return; |
34976 |
++ |
34977 |
++ i = 0UL; |
34978 |
++ do { |
34979 |
++ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn))) |
34980 |
++ return; |
34981 |
++ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) { |
34982 |
++ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE; |
34983 |
++ gr_log_textrel(vma); |
34984 |
++ return; |
34985 |
++ } |
34986 |
++ i++; |
34987 |
++ } while (dyn.d_tag != DT_NULL); |
34988 |
++ return; |
34989 |
++} |
34990 |
++#endif |
34991 |
++ |
34992 |
+ asmlinkage long |
34993 |
+ sys_mprotect(unsigned long start, size_t len, unsigned long prot) |
34994 |
+ { |
34995 |
+@@ -233,6 +388,17 @@ sys_mprotect(unsigned long start, size_t |
34996 |
+ end = start + len; |
34997 |
+ if (end <= start) |
34998 |
+ return -ENOMEM; |
34999 |
++ |
35000 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35001 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) { |
35002 |
++ if (end > SEGMEXEC_TASK_SIZE) |
35003 |
++ return -EINVAL; |
35004 |
++ } else |
35005 |
++#endif |
35006 |
++ |
35007 |
++ if (end > TASK_SIZE) |
35008 |
++ return -EINVAL; |
35009 |
++ |
35010 |
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM)) |
35011 |
+ return -EINVAL; |
35012 |
+ |
35013 |
+@@ -240,7 +406,7 @@ sys_mprotect(unsigned long start, size_t |
35014 |
+ /* |
35015 |
+ * Does the application expect PROT_READ to imply PROT_EXEC: |
35016 |
+ */ |
35017 |
+- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC)) |
35018 |
++ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC)) |
35019 |
+ prot |= PROT_EXEC; |
35020 |
+ |
35021 |
+ vm_flags = calc_vm_prot_bits(prot); |
35022 |
+@@ -272,6 +438,16 @@ sys_mprotect(unsigned long start, size_t |
35023 |
+ if (start > vma->vm_start) |
35024 |
+ prev = vma; |
35025 |
+ |
35026 |
++ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) { |
35027 |
++ error = -EACCES; |
35028 |
++ goto out; |
35029 |
++ } |
35030 |
++ |
35031 |
++#ifdef CONFIG_PAX_MPROTECT |
35032 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE)) |
35033 |
++ pax_handle_maywrite(vma, start); |
35034 |
++#endif |
35035 |
++ |
35036 |
+ for (nstart = start ; ; ) { |
35037 |
+ unsigned long newflags; |
35038 |
+ |
35039 |
+@@ -285,6 +461,12 @@ sys_mprotect(unsigned long start, size_t |
35040 |
+ goto out; |
35041 |
+ } |
35042 |
+ |
35043 |
++#ifdef CONFIG_PAX_MPROTECT |
35044 |
++ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */ |
35045 |
++ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE)) |
35046 |
++ newflags &= ~VM_MAYWRITE; |
35047 |
++#endif |
35048 |
++ |
35049 |
+ error = security_file_mprotect(vma, reqprot, prot); |
35050 |
+ if (error) |
35051 |
+ goto out; |
35052 |
+@@ -295,6 +477,9 @@ sys_mprotect(unsigned long start, size_t |
35053 |
+ error = mprotect_fixup(vma, &prev, nstart, tmp, newflags); |
35054 |
+ if (error) |
35055 |
+ goto out; |
35056 |
++ |
35057 |
++ track_exec_limit(current->mm, nstart, tmp, vm_flags); |
35058 |
++ |
35059 |
+ nstart = tmp; |
35060 |
+ |
35061 |
+ if (nstart < prev->vm_end) |
35062 |
+diff -Nurp linux-2.6.23.15/mm/mremap.c linux-2.6.23.15-grsec/mm/mremap.c |
35063 |
+--- linux-2.6.23.15/mm/mremap.c 2007-10-09 21:31:38.000000000 +0100 |
35064 |
++++ linux-2.6.23.15-grsec/mm/mremap.c 2008-02-11 10:37:45.000000000 +0000 |
35065 |
+@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str |
35066 |
+ continue; |
35067 |
+ pte = ptep_clear_flush(vma, old_addr, old_pte); |
35068 |
+ pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr); |
35069 |
++ |
35070 |
++#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT |
35071 |
++ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC) |
35072 |
++ pte = pte_exprotect(pte); |
35073 |
++#endif |
35074 |
++ |
35075 |
+ set_pte_at(mm, new_addr, new_pte, pte); |
35076 |
+ } |
35077 |
+ |
35078 |
+@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad |
35079 |
+ struct vm_area_struct *vma; |
35080 |
+ unsigned long ret = -EINVAL; |
35081 |
+ unsigned long charged = 0; |
35082 |
++ unsigned long task_size = TASK_SIZE; |
35083 |
+ |
35084 |
+ if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) |
35085 |
+ goto out; |
35086 |
+@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad |
35087 |
+ if (!new_len) |
35088 |
+ goto out; |
35089 |
+ |
35090 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35091 |
++ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) |
35092 |
++ task_size = SEGMEXEC_TASK_SIZE; |
35093 |
++#endif |
35094 |
++ |
35095 |
++ if (new_len > task_size || addr > task_size-new_len || |
35096 |
++ old_len > task_size || addr > task_size-old_len) |
35097 |
++ goto out; |
35098 |
++ |
35099 |
+ /* new_addr is only valid if MREMAP_FIXED is specified */ |
35100 |
+ if (flags & MREMAP_FIXED) { |
35101 |
+ if (new_addr & ~PAGE_MASK) |
35102 |
+@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad |
35103 |
+ if (!(flags & MREMAP_MAYMOVE)) |
35104 |
+ goto out; |
35105 |
+ |
35106 |
+- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) |
35107 |
++ if (new_addr > task_size - new_len) |
35108 |
+ goto out; |
35109 |
+ |
35110 |
+ /* Check if the location we're moving into overlaps the |
35111 |
+ * old location at all, and fail if it does. |
35112 |
+ */ |
35113 |
+- if ((new_addr <= addr) && (new_addr+new_len) > addr) |
35114 |
+- goto out; |
35115 |
+- |
35116 |
+- if ((addr <= new_addr) && (addr+old_len) > new_addr) |
35117 |
++ if (addr + old_len > new_addr && new_addr + new_len > addr) |
35118 |
+ goto out; |
35119 |
+ |
35120 |
+ ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); |
35121 |
+@@ -326,6 +339,14 @@ unsigned long do_mremap(unsigned long ad |
35122 |
+ ret = -EINVAL; |
35123 |
+ goto out; |
35124 |
+ } |
35125 |
++ |
35126 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35127 |
++ if (pax_find_mirror_vma(vma)) { |
35128 |
++ ret = -EINVAL; |
35129 |
++ goto out; |
35130 |
++ } |
35131 |
++#endif |
35132 |
++ |
35133 |
+ /* We can't remap across vm area boundaries */ |
35134 |
+ if (old_len > vma->vm_end - addr) |
35135 |
+ goto out; |
35136 |
+@@ -359,7 +380,7 @@ unsigned long do_mremap(unsigned long ad |
35137 |
+ if (old_len == vma->vm_end - addr && |
35138 |
+ !((flags & MREMAP_FIXED) && (addr != new_addr)) && |
35139 |
+ (old_len != new_len || !(flags & MREMAP_MAYMOVE))) { |
35140 |
+- unsigned long max_addr = TASK_SIZE; |
35141 |
++ unsigned long max_addr = task_size; |
35142 |
+ if (vma->vm_next) |
35143 |
+ max_addr = vma->vm_next->vm_start; |
35144 |
+ /* can we just expand the current mapping? */ |
35145 |
+@@ -377,6 +398,7 @@ unsigned long do_mremap(unsigned long ad |
35146 |
+ addr + new_len); |
35147 |
+ } |
35148 |
+ ret = addr; |
35149 |
++ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags); |
35150 |
+ goto out; |
35151 |
+ } |
35152 |
+ } |
35153 |
+@@ -387,8 +409,8 @@ unsigned long do_mremap(unsigned long ad |
35154 |
+ */ |
35155 |
+ ret = -ENOMEM; |
35156 |
+ if (flags & MREMAP_MAYMOVE) { |
35157 |
++ unsigned long map_flags = 0; |
35158 |
+ if (!(flags & MREMAP_FIXED)) { |
35159 |
+- unsigned long map_flags = 0; |
35160 |
+ if (vma->vm_flags & VM_MAYSHARE) |
35161 |
+ map_flags |= MAP_SHARED; |
35162 |
+ |
35163 |
+@@ -403,7 +425,12 @@ unsigned long do_mremap(unsigned long ad |
35164 |
+ if (ret) |
35165 |
+ goto out; |
35166 |
+ } |
35167 |
++ map_flags = vma->vm_flags; |
35168 |
+ ret = move_vma(vma, addr, old_len, new_len, new_addr); |
35169 |
++ if (!(ret & ~PAGE_MASK)) { |
35170 |
++ track_exec_limit(current->mm, addr, addr + old_len, 0UL); |
35171 |
++ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags); |
35172 |
++ } |
35173 |
+ } |
35174 |
+ out: |
35175 |
+ if (ret & ~PAGE_MASK) |
35176 |
+diff -Nurp linux-2.6.23.15/mm/nommu.c linux-2.6.23.15-grsec/mm/nommu.c |
35177 |
+--- linux-2.6.23.15/mm/nommu.c 2007-10-09 21:31:38.000000000 +0100 |
35178 |
++++ linux-2.6.23.15-grsec/mm/nommu.c 2008-02-11 10:37:45.000000000 +0000 |
35179 |
+@@ -376,15 +376,6 @@ struct vm_area_struct *find_vma(struct m |
35180 |
+ } |
35181 |
+ EXPORT_SYMBOL(find_vma); |
35182 |
+ |
35183 |
+-/* |
35184 |
+- * find a VMA |
35185 |
+- * - we don't extend stack VMAs under NOMMU conditions |
35186 |
+- */ |
35187 |
+-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr) |
35188 |
+-{ |
35189 |
+- return find_vma(mm, addr); |
35190 |
+-} |
35191 |
+- |
35192 |
+ int expand_stack(struct vm_area_struct *vma, unsigned long address) |
35193 |
+ { |
35194 |
+ return -ENOMEM; |
35195 |
+diff -Nurp linux-2.6.23.15/mm/page_alloc.c linux-2.6.23.15-grsec/mm/page_alloc.c |
35196 |
+--- linux-2.6.23.15/mm/page_alloc.c 2007-10-09 21:31:38.000000000 +0100 |
35197 |
++++ linux-2.6.23.15-grsec/mm/page_alloc.c 2008-02-11 10:37:45.000000000 +0000 |
35198 |
+@@ -402,7 +402,7 @@ static inline int page_is_buddy(struct p |
35199 |
+ static inline void __free_one_page(struct page *page, |
35200 |
+ struct zone *zone, unsigned int order) |
35201 |
+ { |
35202 |
+- unsigned long page_idx; |
35203 |
++ unsigned long page_idx, index; |
35204 |
+ int order_size = 1 << order; |
35205 |
+ |
35206 |
+ if (unlikely(PageCompound(page))) |
35207 |
+@@ -413,6 +413,11 @@ static inline void __free_one_page(struc |
35208 |
+ VM_BUG_ON(page_idx & (order_size - 1)); |
35209 |
+ VM_BUG_ON(bad_range(zone, page)); |
35210 |
+ |
35211 |
++#ifdef CONFIG_PAX_MEMORY_SANITIZE |
35212 |
++ for (index = order_size; index; --index) |
35213 |
++ sanitize_highpage(page + index - 1); |
35214 |
++#endif |
35215 |
++ |
35216 |
+ __mod_zone_page_state(zone, NR_FREE_PAGES, order_size); |
35217 |
+ while (order < MAX_ORDER-1) { |
35218 |
+ unsigned long combined_idx; |
35219 |
+diff -Nurp linux-2.6.23.15/mm/rmap.c linux-2.6.23.15-grsec/mm/rmap.c |
35220 |
+--- linux-2.6.23.15/mm/rmap.c 2007-10-09 21:31:38.000000000 +0100 |
35221 |
++++ linux-2.6.23.15-grsec/mm/rmap.c 2008-02-11 10:37:45.000000000 +0000 |
35222 |
+@@ -63,6 +63,10 @@ int anon_vma_prepare(struct vm_area_stru |
35223 |
+ struct mm_struct *mm = vma->vm_mm; |
35224 |
+ struct anon_vma *allocated, *locked; |
35225 |
+ |
35226 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35227 |
++ struct vm_area_struct *vma_m; |
35228 |
++#endif |
35229 |
++ |
35230 |
+ anon_vma = find_mergeable_anon_vma(vma); |
35231 |
+ if (anon_vma) { |
35232 |
+ allocated = NULL; |
35233 |
+@@ -79,6 +83,15 @@ int anon_vma_prepare(struct vm_area_stru |
35234 |
+ /* page_table_lock to protect against threads */ |
35235 |
+ spin_lock(&mm->page_table_lock); |
35236 |
+ if (likely(!vma->anon_vma)) { |
35237 |
++ |
35238 |
++#ifdef CONFIG_PAX_SEGMEXEC |
35239 |
++ vma_m = pax_find_mirror_vma(vma); |
35240 |
++ if (vma_m) { |
35241 |
++ vma_m->anon_vma = anon_vma; |
35242 |
++ __anon_vma_link(vma_m); |
35243 |
++ } |
35244 |
++#endif |
35245 |
++ |
35246 |
+ vma->anon_vma = anon_vma; |
35247 |
+ list_add_tail(&vma->anon_vma_node, &anon_vma->head); |
35248 |
+ allocated = NULL; |
35249 |
+diff -Nurp linux-2.6.23.15/mm/shmem.c linux-2.6.23.15-grsec/mm/shmem.c |
35250 |
+--- linux-2.6.23.15/mm/shmem.c 2008-02-11 10:36:03.000000000 +0000 |
35251 |
++++ linux-2.6.23.15-grsec/mm/shmem.c 2008-02-11 10:37:45.000000000 +0000 |
35252 |
+@@ -2452,7 +2452,7 @@ static struct file_system_type tmpfs_fs_ |
35253 |
+ .get_sb = shmem_get_sb, |
35254 |
+ .kill_sb = kill_litter_super, |
35255 |
+ }; |
35256 |
+-static struct vfsmount *shm_mnt; |
35257 |
++struct vfsmount *shm_mnt; |
35258 |
+ |
35259 |
+ static int __init init_tmpfs(void) |
35260 |
+ { |
35261 |
+diff -Nurp linux-2.6.23.15/mm/slab.c linux-2.6.23.15-grsec/mm/slab.c |
35262 |
+--- linux-2.6.23.15/mm/slab.c 2007-10-09 21:31:38.000000000 +0100 |
35263 |
++++ linux-2.6.23.15-grsec/mm/slab.c 2008-02-11 10:37:45.000000000 +0000 |
35264 |
+@@ -306,7 +306,7 @@ struct kmem_list3 { |
35265 |
+ * Need this for bootstrapping a per node allocator. |
35266 |
+ */ |
35267 |
+ #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1) |
35268 |
+-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS]; |
35269 |
++struct kmem_list3 initkmem_list3[NUM_INIT_LISTS]; |
35270 |
+ #define CACHE_CACHE 0 |
35271 |
+ #define SIZE_AC 1 |
35272 |
+ #define SIZE_L3 (1 + MAX_NUMNODES) |
35273 |
+@@ -655,14 +655,14 @@ struct cache_names { |
35274 |
+ static struct cache_names __initdata cache_names[] = { |
35275 |
+ #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" }, |
35276 |
+ #include <linux/kmalloc_sizes.h> |
35277 |
+- {NULL,} |
35278 |
++ {NULL, NULL} |
35279 |
+ #undef CACHE |
35280 |
+ }; |
35281 |
+ |
35282 |
+ static struct arraycache_init initarray_cache __initdata = |
35283 |
+- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; |
35284 |
++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} }; |
35285 |
+ static struct arraycache_init initarray_generic = |
35286 |
+- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} }; |
35287 |
++ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} }; |
35288 |
+ |
35289 |
+ /* internal cache of cache description objs */ |
35290 |
+ static struct kmem_cache cache_cache = { |
35291 |
+@@ -2980,7 +2980,7 @@ retry: |
35292 |
+ * there must be at least one object available for |
35293 |
+ * allocation. |
35294 |
+ */ |
35295 |
+- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num); |
35296 |
++ BUG_ON(slabp->inuse >= cachep->num); |
35297 |
+ |
35298 |
+ while (slabp->inuse < cachep->num && batchcount--) { |
35299 |
+ STATS_INC_ALLOCED(cachep); |
35300 |
+diff -Nurp linux-2.6.23.15/mm/slub.c linux-2.6.23.15-grsec/mm/slub.c |
35301 |
+--- linux-2.6.23.15/mm/slub.c 2008-02-11 10:36:03.000000000 +0000 |
35302 |
++++ linux-2.6.23.15-grsec/mm/slub.c 2008-02-11 10:37:45.000000000 +0000 |
35303 |
+@@ -1530,7 +1530,7 @@ debug: |
35304 |
+ * |
35305 |
+ * Otherwise we can simply pick the next object from the lockless free list. |
35306 |
+ */ |
35307 |
+-static void __always_inline *slab_alloc(struct kmem_cache *s, |
35308 |
++static __always_inline void *slab_alloc(struct kmem_cache *s, |
35309 |
+ gfp_t gfpflags, int node, void *addr) |
35310 |
+ { |
35311 |
+ struct page *page; |
35312 |
+@@ -1639,7 +1639,7 @@ debug: |
35313 |
+ * If fastpath is not possible then fall back to __slab_free where we deal |
35314 |
+ * with all sorts of special processing. |
35315 |
+ */ |
35316 |
+-static void __always_inline slab_free(struct kmem_cache *s, |
35317 |
++static __always_inline void slab_free(struct kmem_cache *s, |
35318 |
+ struct page *page, void *x, void *addr) |
35319 |
+ { |
35320 |
+ void **object = (void *)x; |
35321 |
+diff -Nurp linux-2.6.23.15/mm/swap.c linux-2.6.23.15-grsec/mm/swap.c |
35322 |
+--- linux-2.6.23.15/mm/swap.c 2007-10-09 21:31:38.000000000 +0100 |
35323 |
++++ linux-2.6.23.15-grsec/mm/swap.c 2008-02-11 10:37:45.000000000 +0000 |
35324 |
+@@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed); |
35325 |
+ * lru_cache_add: add a page to the page lists |
35326 |
+ * @page: the page to add |
35327 |
+ */ |
35328 |
+-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, }; |
35329 |
+-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, }; |
35330 |
++static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} }; |
35331 |
++static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} }; |
35332 |
+ |
35333 |
+ void fastcall lru_cache_add(struct page *page) |
35334 |
+ { |
35335 |
+diff -Nurp linux-2.6.23.15/mm/tiny-shmem.c linux-2.6.23.15-grsec/mm/tiny-shmem.c |
35336 |
+--- linux-2.6.23.15/mm/tiny-shmem.c 2007-10-09 21:31:38.000000000 +0100 |
35337 |
++++ linux-2.6.23.15-grsec/mm/tiny-shmem.c 2008-02-11 10:37:45.000000000 +0000 |
35338 |
+@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_ |
35339 |
+ .kill_sb = kill_litter_super, |
35340 |
+ }; |
35341 |
+ |
35342 |
+-static struct vfsmount *shm_mnt; |
35343 |
++struct vfsmount *shm_mnt; |
35344 |
+ |
35345 |
+ static int __init init_tmpfs(void) |
35346 |
+ { |
35347 |
+diff -Nurp linux-2.6.23.15/mm/vmalloc.c linux-2.6.23.15-grsec/mm/vmalloc.c |
35348 |
+--- linux-2.6.23.15/mm/vmalloc.c 2007-10-09 21:31:38.000000000 +0100 |
35349 |
++++ linux-2.6.23.15-grsec/mm/vmalloc.c 2008-02-11 10:37:45.000000000 +0000 |
35350 |
+@@ -201,6 +201,8 @@ static struct vm_struct *__get_vm_area_n |
35351 |
+ |
35352 |
+ write_lock(&vmlist_lock); |
35353 |
+ for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) { |
35354 |
++ if (addr > end - size) |
35355 |
++ goto out; |
35356 |
+ if ((unsigned long)tmp->addr < addr) { |
35357 |
+ if((unsigned long)tmp->addr + tmp->size >= addr) |
35358 |
+ addr = ALIGN(tmp->size + |
35359 |
+@@ -212,8 +214,6 @@ static struct vm_struct *__get_vm_area_n |
35360 |
+ if (size + addr <= (unsigned long)tmp->addr) |
35361 |
+ goto found; |
35362 |
+ addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align); |
35363 |
+- if (addr > end - size) |
35364 |
+- goto out; |
35365 |
+ } |
35366 |
+ |
35367 |
+ found: |
35368 |
+diff -Nurp linux-2.6.23.15/net/core/flow.c linux-2.6.23.15-grsec/net/core/flow.c |
35369 |
+--- linux-2.6.23.15/net/core/flow.c 2007-10-09 21:31:38.000000000 +0100 |
35370 |
++++ linux-2.6.23.15-grsec/net/core/flow.c 2008-02-11 10:37:45.000000000 +0000 |
35371 |
+@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT( |
35372 |
+ |
35373 |
+ static u32 flow_hash_shift; |
35374 |
+ #define flow_hash_size (1 << flow_hash_shift) |
35375 |
+-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL }; |
35376 |
++static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables); |
35377 |
+ |
35378 |
+ #define flow_table(cpu) (per_cpu(flow_tables, cpu)) |
35379 |
+ |
35380 |
+@@ -53,7 +53,7 @@ struct flow_percpu_info { |
35381 |
+ u32 hash_rnd; |
35382 |
+ int count; |
35383 |
+ } ____cacheline_aligned; |
35384 |
+-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 }; |
35385 |
++static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info); |
35386 |
+ |
35387 |
+ #define flow_hash_rnd_recalc(cpu) \ |
35388 |
+ (per_cpu(flow_hash_info, cpu).hash_rnd_recalc) |
35389 |
+@@ -70,7 +70,7 @@ struct flow_flush_info { |
35390 |
+ atomic_t cpuleft; |
35391 |
+ struct completion completion; |
35392 |
+ }; |
35393 |
+-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL }; |
35394 |
++static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets); |
35395 |
+ |
35396 |
+ #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu)) |
35397 |
+ |
35398 |
+diff -Nurp linux-2.6.23.15/net/dccp/ccids/ccid3.c linux-2.6.23.15-grsec/net/dccp/ccids/ccid3.c |
35399 |
+--- linux-2.6.23.15/net/dccp/ccids/ccid3.c 2007-10-09 21:31:38.000000000 +0100 |
35400 |
++++ linux-2.6.23.15-grsec/net/dccp/ccids/ccid3.c 2008-02-11 10:37:45.000000000 +0000 |
35401 |
+@@ -44,7 +44,7 @@ |
35402 |
+ static int ccid3_debug; |
35403 |
+ #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a) |
35404 |
+ #else |
35405 |
+-#define ccid3_pr_debug(format, a...) |
35406 |
++#define ccid3_pr_debug(format, a...) do {} while (0) |
35407 |
+ #endif |
35408 |
+ |
35409 |
+ static struct dccp_tx_hist *ccid3_tx_hist; |
35410 |
+diff -Nurp linux-2.6.23.15/net/dccp/dccp.h linux-2.6.23.15-grsec/net/dccp/dccp.h |
35411 |
+--- linux-2.6.23.15/net/dccp/dccp.h 2007-10-09 21:31:38.000000000 +0100 |
35412 |
++++ linux-2.6.23.15-grsec/net/dccp/dccp.h 2008-02-11 10:37:45.000000000 +0000 |
35413 |
+@@ -42,8 +42,8 @@ extern int dccp_debug; |
35414 |
+ #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a) |
35415 |
+ #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a) |
35416 |
+ #else |
35417 |
+-#define dccp_pr_debug(format, a...) |
35418 |
+-#define dccp_pr_debug_cat(format, a...) |
35419 |
++#define dccp_pr_debug(format, a...) do {} while (0) |
35420 |
++#define dccp_pr_debug_cat(format, a...) do {} while (0) |
35421 |
+ #endif |
35422 |
+ |
35423 |
+ extern struct inet_hashinfo dccp_hashinfo; |
35424 |
+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 |
35425 |
+--- linux-2.6.23.15/net/ipv4/inet_connection_sock.c 2007-10-09 21:31:38.000000000 +0100 |
35426 |
++++ linux-2.6.23.15-grsec/net/ipv4/inet_connection_sock.c 2008-02-11 10:37:45.000000000 +0000 |
35427 |
+@@ -15,6 +15,7 @@ |
35428 |
+ |
35429 |
+ #include <linux/module.h> |
35430 |
+ #include <linux/jhash.h> |
35431 |
++#include <linux/grsecurity.h> |
35432 |
+ |
35433 |
+ #include <net/inet_connection_sock.h> |
35434 |
+ #include <net/inet_hashtables.h> |
35435 |
+diff -Nurp linux-2.6.23.15/net/ipv4/inet_hashtables.c linux-2.6.23.15-grsec/net/ipv4/inet_hashtables.c |
35436 |
+--- linux-2.6.23.15/net/ipv4/inet_hashtables.c 2007-10-09 21:31:38.000000000 +0100 |
35437 |
++++ linux-2.6.23.15-grsec/net/ipv4/inet_hashtables.c 2008-02-11 10:37:45.000000000 +0000 |
35438 |
+@@ -18,11 +18,14 @@ |
35439 |
+ #include <linux/sched.h> |
35440 |
+ #include <linux/slab.h> |
35441 |
+ #include <linux/wait.h> |
35442 |
++#include <linux/grsecurity.h> |
35443 |
+ |
35444 |
+ #include <net/inet_connection_sock.h> |
35445 |
+ #include <net/inet_hashtables.h> |
35446 |
+ #include <net/ip.h> |
35447 |
+ |
35448 |
++extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet); |
35449 |
++ |
35450 |
+ /* |
35451 |
+ * Allocate and initialize a new local port bind bucket. |
35452 |
+ * The bindhash mutex for snum's hash chain must be held here. |
35453 |
+@@ -338,6 +341,8 @@ ok: |
35454 |
+ } |
35455 |
+ spin_unlock(&head->lock); |
35456 |
+ |
35457 |
++ gr_update_task_in_ip_table(current, inet_sk(sk)); |
35458 |
++ |
35459 |
+ if (tw) { |
35460 |
+ inet_twsk_deschedule(tw, death_row); |
35461 |
+ inet_twsk_put(tw); |
35462 |
+diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/Kconfig linux-2.6.23.15-grsec/net/ipv4/netfilter/Kconfig |
35463 |
+--- linux-2.6.23.15/net/ipv4/netfilter/Kconfig 2007-10-09 21:31:38.000000000 +0100 |
35464 |
++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/Kconfig 2008-02-11 10:37:45.000000000 +0000 |
35465 |
+@@ -130,6 +130,21 @@ config IP_NF_MATCH_ADDRTYPE |
35466 |
+ If you want to compile it as a module, say M here and read |
35467 |
+ <file:Documentation/modules.txt>. If unsure, say `N'. |
35468 |
+ |
35469 |
++config IP_NF_MATCH_STEALTH |
35470 |
++ tristate "stealth match support" |
35471 |
++ depends on IP_NF_IPTABLES |
35472 |
++ help |
35473 |
++ Enabling this option will drop all syn packets coming to unserved tcp |
35474 |
++ ports as well as all packets coming to unserved udp ports. If you |
35475 |
++ are using your system to route any type of packets (ie. via NAT) |
35476 |
++ you should put this module at the end of your ruleset, since it will |
35477 |
++ drop packets that aren't going to ports that are listening on your |
35478 |
++ machine itself, it doesn't take into account that the packet might be |
35479 |
++ destined for someone on your internal network if you're using NAT for |
35480 |
++ instance. |
35481 |
++ |
35482 |
++ To compile it as a module, choose M here. If unsure, say N. |
35483 |
++ |
35484 |
+ # `filter', generic and specific targets |
35485 |
+ config IP_NF_FILTER |
35486 |
+ tristate "Packet filtering" |
35487 |
+@@ -403,4 +418,3 @@ config IP_NF_ARP_MANGLE |
35488 |
+ hardware and network addresses. |
35489 |
+ |
35490 |
+ endmenu |
35491 |
+- |
35492 |
+diff -Nurp linux-2.6.23.15/net/ipv4/netfilter/Makefile linux-2.6.23.15-grsec/net/ipv4/netfilter/Makefile |
35493 |
+--- linux-2.6.23.15/net/ipv4/netfilter/Makefile 2007-10-09 21:31:38.000000000 +0100 |
35494 |
++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/Makefile 2008-02-11 10:37:45.000000000 +0000 |
35495 |
+@@ -49,6 +49,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn |
35496 |
+ obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o |
35497 |
+ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
35498 |
+ obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
35499 |
++obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o |
35500 |
+ |
35501 |
+ # targets |
35502 |
+ obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o |
35503 |
+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 |
35504 |
+--- linux-2.6.23.15/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100 |
35505 |
++++ linux-2.6.23.15-grsec/net/ipv4/netfilter/ipt_stealth.c 2008-02-11 10:37:45.000000000 +0000 |
35506 |
+@@ -0,0 +1,114 @@ |
35507 |
++/* Kernel module to add stealth support. |
35508 |
++ * |
35509 |
++ * Copyright (C) 2002-2006 Brad Spengler <spender@××××××××××.net> |
35510 |
++ * |
35511 |
++ */ |
35512 |
++ |
35513 |
++#include <linux/kernel.h> |
35514 |
++#include <linux/module.h> |
35515 |
++#include <linux/skbuff.h> |
35516 |
++#include <linux/net.h> |
35517 |
++#include <linux/sched.h> |
35518 |
++#include <linux/inet.h> |
35519 |
++#include <linux/stddef.h> |
35520 |
++ |
35521 |
++#include <net/ip.h> |
35522 |
++#include <net/sock.h> |
35523 |
++#include <net/tcp.h> |
35524 |
++#include <net/udp.h> |
35525 |
++#include <net/route.h> |
35526 |
++#include <net/inet_common.h> |
35527 |
++ |
35528 |
++#include <linux/netfilter_ipv4/ip_tables.h> |
35529 |
++ |
35530 |
++MODULE_LICENSE("GPL"); |
35531 |
++ |
35532 |
++extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); |
35533 |
++ |
35534 |
++static int |
35535 |
++match(const struct sk_buff *skb, |
35536 |
++ const struct net_device *in, |
35537 |
++ const struct net_device *out, |
35538 |
++ const struct xt_match *match, |
35539 |
++ const void *matchinfo, |
35540 |
++ int offset, |
35541 |
++ unsigned int protoff, |
35542 |
++ int *hotdrop) |
35543 |
++{ |
35544 |
++ struct iphdr *ip = ip_hdr(skb); |
35545 |
++ struct tcphdr th; |
35546 |
++ struct udphdr uh; |
35547 |
++ struct sock *sk = NULL; |
35548 |
++ |
35549 |
++ if (!ip || offset) return 0; |
35550 |
++ |
35551 |
++ switch(ip->protocol) { |
35552 |
++ case IPPROTO_TCP: |
35553 |
++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) { |
35554 |
++ *hotdrop = 1; |
35555 |
++ return 0; |
35556 |
++ } |
35557 |
++ if (!(th.syn && !th.ack)) return 0; |
35558 |
++ sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb)); |
35559 |
++ break; |
35560 |
++ case IPPROTO_UDP: |
35561 |
++ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) { |
35562 |
++ *hotdrop = 1; |
35563 |
++ return 0; |
35564 |
++ } |
35565 |
++ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex); |
35566 |
++ break; |
35567 |
++ default: |
35568 |
++ return 0; |
35569 |
++ } |
35570 |
++ |
35571 |
++ if(!sk) // port is being listened on, match this |
35572 |
++ return 1; |
35573 |
++ else { |
35574 |
++ sock_put(sk); |
35575 |
++ return 0; |
35576 |
++ } |
35577 |
++} |
35578 |
++ |
35579 |
++/* Called when user tries to insert an entry of this type. */ |
35580 |
++static int |
35581 |
++checkentry(const char *tablename, |
35582 |
++ const void *nip, |
35583 |
++ const struct xt_match *match, |
35584 |
++ void *matchinfo, |
35585 |
++ unsigned int hook_mask) |
35586 |
++{ |
35587 |
++ const struct ipt_ip *ip = (const struct ipt_ip *)nip; |
35588 |
++ |
35589 |
++ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) || |
35590 |
++ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO))) |
35591 |
++ && (hook_mask & (1 << NF_IP_LOCAL_IN))) |
35592 |
++ return 1; |
35593 |
++ |
35594 |
++ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n"); |
35595 |
++ |
35596 |
++ return 0; |
35597 |
++} |
35598 |
++ |
35599 |
++ |
35600 |
++static struct xt_match stealth_match = { |
35601 |
++ .name = "stealth", |
35602 |
++ .family = AF_INET, |
35603 |
++ .match = match, |
35604 |
++ .checkentry = checkentry, |
35605 |
++ .destroy = NULL, |
35606 |
++ .me = THIS_MODULE |
35607 |
++}; |
35608 |
++ |
35609 |
++static int __init init(void) |
35610 |
++{ |
35611 |
++ return xt_register_match(&stealth_match); |
35612 |
++} |
35613 |
++ |
35614 |
++static void __exit fini(void) |
35615 |
++{ |
35616 |
++ xt_unregister_match(&stealth_match); |
35617 |
++} |
35618 |
++ |
35619 |
++module_init(init); |
35620 |
++module_exit(fini); |
35621 |
+diff -Nurp linux-2.6.23.15/net/ipv4/tcp.c linux-2.6.23.15-grsec/net/ipv4/tcp.c |
35622 |
+--- linux-2.6.23.15/net/ipv4/tcp.c 2007-10-09 21:31:38.000000000 +0100 |
35623 |
++++ linux-2.6.23.15-grsec/net/ipv4/tcp.c 2008-02-11 10:37:45.000000000 +0000 |
35624 |
+@@ -1053,7 +1053,8 @@ int tcp_read_sock(struct sock *sk, read_ |
35625 |
+ return -ENOTCONN; |
35626 |
+ while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { |
35627 |
+ if (offset < skb->len) { |
35628 |
+- size_t used, len; |
35629 |
++ int used; |
35630 |
++ size_t len; |
35631 |
+ |
35632 |
+ len = skb->len - offset; |
35633 |
+ /* Stop reading if we hit a patch of urgent data */ |
35634 |
+diff -Nurp linux-2.6.23.15/net/ipv4/tcp_ipv4.c linux-2.6.23.15-grsec/net/ipv4/tcp_ipv4.c |
35635 |
+--- linux-2.6.23.15/net/ipv4/tcp_ipv4.c 2007-10-09 21:31:38.000000000 +0100 |
35636 |
++++ linux-2.6.23.15-grsec/net/ipv4/tcp_ipv4.c 2008-02-11 10:37:45.000000000 +0000 |
35637 |
+@@ -61,6 +61,7 @@ |
35638 |
+ #include <linux/jhash.h> |
35639 |
+ #include <linux/init.h> |
35640 |
+ #include <linux/times.h> |
35641 |
++#include <linux/grsecurity.h> |
35642 |
+ |
35643 |
+ #include <net/icmp.h> |
35644 |
+ #include <net/inet_hashtables.h> |
35645 |
+diff -Nurp linux-2.6.23.15/net/ipv4/udp.c linux-2.6.23.15-grsec/net/ipv4/udp.c |
35646 |
+--- linux-2.6.23.15/net/ipv4/udp.c 2007-10-09 21:31:38.000000000 +0100 |
35647 |
++++ linux-2.6.23.15-grsec/net/ipv4/udp.c 2008-02-11 10:37:45.000000000 +0000 |
35648 |
+@@ -98,12 +98,19 @@ |
35649 |
+ #include <linux/skbuff.h> |
35650 |
+ #include <linux/proc_fs.h> |
35651 |
+ #include <linux/seq_file.h> |
35652 |
++#include <linux/grsecurity.h> |
35653 |
+ #include <net/icmp.h> |
35654 |
+ #include <net/route.h> |
35655 |
+ #include <net/checksum.h> |
35656 |
+ #include <net/xfrm.h> |
35657 |
+ #include "udp_impl.h" |
35658 |
+ |
35659 |
++extern int gr_search_udp_recvmsg(const struct sock *sk, |
35660 |
++ const struct sk_buff *skb); |
35661 |
++extern int gr_search_udp_sendmsg(const struct sock *sk, |
35662 |
++ const struct sockaddr_in *addr); |
35663 |
++ |
35664 |
++ |
35665 |
+ /* |
35666 |
+ * Snmp MIB for the UDP layer |
35667 |
+ */ |
35668 |
+@@ -287,6 +294,13 @@ static struct sock *__udp4_lib_lookup(__ |
35669 |
+ return result; |
35670 |
+ } |
35671 |
+ |
35672 |
++struct sock *udp_v4_lookup(__be32 saddr, __be16 sport, |
35673 |
++ __be32 daddr, __be16 dport, int dif) |
35674 |
++{ |
35675 |
++ return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash); |
35676 |
++} |
35677 |
++ |
35678 |
++ |
35679 |
+ static inline struct sock *udp_v4_mcast_next(struct sock *sk, |
35680 |
+ __be16 loc_port, __be32 loc_addr, |
35681 |
+ __be16 rmt_port, __be32 rmt_addr, |
35682 |
+@@ -572,9 +586,16 @@ int udp_sendmsg(struct kiocb *iocb, stru |
35683 |
+ dport = usin->sin_port; |
35684 |
+ if (dport == 0) |
35685 |
+ return -EINVAL; |
35686 |
++ |
35687 |
++ if (!gr_search_udp_sendmsg(sk, usin)) |
35688 |
++ return -EPERM; |
35689 |
+ } else { |
35690 |
+ if (sk->sk_state != TCP_ESTABLISHED) |
35691 |
+ return -EDESTADDRREQ; |
35692 |
++ |
35693 |
++ if (!gr_search_udp_sendmsg(sk, NULL)) |
35694 |
++ return -EPERM; |
35695 |
++ |
35696 |
+ daddr = inet->daddr; |
35697 |
+ dport = inet->dport; |
35698 |
+ /* Open fast path for connected socket. |
35699 |
+@@ -834,6 +855,11 @@ try_again: |
35700 |
+ if (!skb) |
35701 |
+ goto out; |
35702 |
+ |
35703 |
++ if (!gr_search_udp_recvmsg(sk, skb)) { |
35704 |
++ err = -EPERM; |
35705 |
++ goto out_free; |
35706 |
++ } |
35707 |
++ |
35708 |
+ ulen = skb->len - sizeof(struct udphdr); |
35709 |
+ copied = len; |
35710 |
+ if (copied > ulen) |
35711 |
+diff -Nurp linux-2.6.23.15/net/ipv6/exthdrs.c linux-2.6.23.15-grsec/net/ipv6/exthdrs.c |
35712 |
+--- linux-2.6.23.15/net/ipv6/exthdrs.c 2007-10-09 21:31:38.000000000 +0100 |
35713 |
++++ linux-2.6.23.15-grsec/net/ipv6/exthdrs.c 2008-02-11 10:37:45.000000000 +0000 |
35714 |
+@@ -645,7 +645,7 @@ static struct tlvtype_proc tlvprochopopt |
35715 |
+ .type = IPV6_TLV_JUMBO, |
35716 |
+ .func = ipv6_hop_jumbo, |
35717 |
+ }, |
35718 |
+- { -1, } |
35719 |
++ { -1, NULL } |
35720 |
+ }; |
35721 |
+ |
35722 |
+ int ipv6_parse_hopopts(struct sk_buff **skbp) |
35723 |
+diff -Nurp linux-2.6.23.15/net/ipv6/raw.c linux-2.6.23.15-grsec/net/ipv6/raw.c |
35724 |
+--- linux-2.6.23.15/net/ipv6/raw.c 2007-10-09 21:31:38.000000000 +0100 |
35725 |
++++ linux-2.6.23.15-grsec/net/ipv6/raw.c 2008-02-11 10:37:45.000000000 +0000 |
35726 |
+@@ -577,7 +577,7 @@ out: |
35727 |
+ return err; |
35728 |
+ } |
35729 |
+ |
35730 |
+-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length, |
35731 |
++static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length, |
35732 |
+ struct flowi *fl, struct rt6_info *rt, |
35733 |
+ unsigned int flags) |
35734 |
+ { |
35735 |
+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 |
35736 |
+--- linux-2.6.23.15/net/irda/ircomm/ircomm_tty.c 2007-10-09 21:31:38.000000000 +0100 |
35737 |
++++ linux-2.6.23.15-grsec/net/irda/ircomm/ircomm_tty.c 2008-02-11 10:37:45.000000000 +0000 |
35738 |
+@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st |
35739 |
+ IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); |
35740 |
+ |
35741 |
+ line = tty->index; |
35742 |
+- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) { |
35743 |
++ if (line >= IRCOMM_TTY_PORTS) { |
35744 |
+ return -ENODEV; |
35745 |
+ } |
35746 |
+ |
35747 |
+diff -Nurp linux-2.6.23.15/net/mac80211/ieee80211.c linux-2.6.23.15-grsec/net/mac80211/ieee80211.c |
35748 |
+--- linux-2.6.23.15/net/mac80211/ieee80211.c 2008-02-11 10:36:03.000000000 +0000 |
35749 |
++++ linux-2.6.23.15-grsec/net/mac80211/ieee80211.c 2008-02-11 10:37:45.000000000 +0000 |
35750 |
+@@ -1260,7 +1260,7 @@ __ieee80211_parse_tx_radiotap( |
35751 |
+ } |
35752 |
+ |
35753 |
+ |
35754 |
+-static ieee80211_txrx_result inline |
35755 |
++static inline ieee80211_txrx_result |
35756 |
+ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, |
35757 |
+ struct sk_buff *skb, |
35758 |
+ struct net_device *dev, |
35759 |
+@@ -1332,7 +1332,7 @@ __ieee80211_tx_prepare(struct ieee80211_ |
35760 |
+ return res; |
35761 |
+ } |
35762 |
+ |
35763 |
+-static int inline is_ieee80211_device(struct net_device *dev, |
35764 |
++static inline int is_ieee80211_device(struct net_device *dev, |
35765 |
+ struct net_device *master) |
35766 |
+ { |
35767 |
+ return (wdev_priv(dev->ieee80211_ptr) == |
35768 |
+@@ -1341,7 +1341,7 @@ static int inline is_ieee80211_device(st |
35769 |
+ |
35770 |
+ /* Device in tx->dev has a reference added; use dev_put(tx->dev) when |
35771 |
+ * finished with it. */ |
35772 |
+-static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, |
35773 |
++static inline int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, |
35774 |
+ struct sk_buff *skb, |
35775 |
+ struct net_device *mdev, |
35776 |
+ struct ieee80211_tx_control *control) |
35777 |
+diff -Nurp linux-2.6.23.15/net/mac80211/regdomain.c linux-2.6.23.15-grsec/net/mac80211/regdomain.c |
35778 |
+--- linux-2.6.23.15/net/mac80211/regdomain.c 2007-10-09 21:31:38.000000000 +0100 |
35779 |
++++ linux-2.6.23.15-grsec/net/mac80211/regdomain.c 2008-02-11 10:37:45.000000000 +0000 |
35780 |
+@@ -61,14 +61,14 @@ static const struct ieee80211_channel_ra |
35781 |
+ { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */, |
35782 |
+ { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */, |
35783 |
+ { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */, |
35784 |
+- { 0 } |
35785 |
++ { 0, 0, 0, 0 } |
35786 |
+ }; |
35787 |
+ |
35788 |
+ static const struct ieee80211_channel_range ieee80211_mkk_channels[] = { |
35789 |
+ { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */, |
35790 |
+ { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */, |
35791 |
+ { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */, |
35792 |
+- { 0 } |
35793 |
++ { 0, 0, 0, 0 } |
35794 |
+ }; |
35795 |
+ |
35796 |
+ |
35797 |
+diff -Nurp linux-2.6.23.15/net/sctp/socket.c linux-2.6.23.15-grsec/net/sctp/socket.c |
35798 |
+--- linux-2.6.23.15/net/sctp/socket.c 2007-10-09 21:31:38.000000000 +0100 |
35799 |
++++ linux-2.6.23.15-grsec/net/sctp/socket.c 2008-02-11 10:37:45.000000000 +0000 |
35800 |
+@@ -1370,7 +1370,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc |
35801 |
+ struct sctp_sndrcvinfo *sinfo; |
35802 |
+ struct sctp_initmsg *sinit; |
35803 |
+ sctp_assoc_t associd = 0; |
35804 |
+- sctp_cmsgs_t cmsgs = { NULL }; |
35805 |
++ sctp_cmsgs_t cmsgs = { NULL, NULL }; |
35806 |
+ int err; |
35807 |
+ sctp_scope_t scope; |
35808 |
+ long timeo; |
35809 |
+diff -Nurp linux-2.6.23.15/net/socket.c linux-2.6.23.15-grsec/net/socket.c |
35810 |
+--- linux-2.6.23.15/net/socket.c 2008-02-11 10:36:03.000000000 +0000 |
35811 |
++++ linux-2.6.23.15-grsec/net/socket.c 2008-02-11 10:37:45.000000000 +0000 |
35812 |
+@@ -84,6 +84,7 @@ |
35813 |
+ #include <linux/kmod.h> |
35814 |
+ #include <linux/audit.h> |
35815 |
+ #include <linux/wireless.h> |
35816 |
++#include <linux/in.h> |
35817 |
+ |
35818 |
+ #include <asm/uaccess.h> |
35819 |
+ #include <asm/unistd.h> |
35820 |
+@@ -93,6 +94,21 @@ |
35821 |
+ #include <net/sock.h> |
35822 |
+ #include <linux/netfilter.h> |
35823 |
+ |
35824 |
++extern void gr_attach_curr_ip(const struct sock *sk); |
35825 |
++extern int gr_handle_sock_all(const int family, const int type, |
35826 |
++ const int protocol); |
35827 |
++extern int gr_handle_sock_server(const struct sockaddr *sck); |
35828 |
++extern int gr_handle_sock_server_other(const struct socket *sck); |
35829 |
++extern int gr_handle_sock_client(const struct sockaddr *sck); |
35830 |
++extern int gr_search_connect(const struct socket * sock, |
35831 |
++ const struct sockaddr_in * addr); |
35832 |
++extern int gr_search_bind(const struct socket * sock, |
35833 |
++ const struct sockaddr_in * addr); |
35834 |
++extern int gr_search_listen(const struct socket * sock); |
35835 |
++extern int gr_search_accept(const struct socket * sock); |
35836 |
++extern int gr_search_socket(const int domain, const int type, |
35837 |
++ const int protocol); |
35838 |
++ |
35839 |
+ static int sock_no_open(struct inode *irrelevant, struct file *dontcare); |
35840 |
+ static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, |
35841 |
+ unsigned long nr_segs, loff_t pos); |
35842 |
+@@ -292,7 +308,7 @@ static int sockfs_get_sb(struct file_sys |
35843 |
+ mnt); |
35844 |
+ } |
35845 |
+ |
35846 |
+-static struct vfsmount *sock_mnt __read_mostly; |
35847 |
++struct vfsmount *sock_mnt __read_mostly; |
35848 |
+ |
35849 |
+ static struct file_system_type sock_fs_type = { |
35850 |
+ .name = "sockfs", |
35851 |
+@@ -1199,6 +1215,16 @@ asmlinkage long sys_socket(int family, i |
35852 |
+ int retval; |
35853 |
+ struct socket *sock; |
35854 |
+ |
35855 |
++ if(!gr_search_socket(family, type, protocol)) { |
35856 |
++ retval = -EACCES; |
35857 |
++ goto out; |
35858 |
++ } |
35859 |
++ |
35860 |
++ if (gr_handle_sock_all(family, type, protocol)) { |
35861 |
++ retval = -EACCES; |
35862 |
++ goto out; |
35863 |
++ } |
35864 |
++ |
35865 |
+ retval = sock_create(family, type, protocol, &sock); |
35866 |
+ if (retval < 0) |
35867 |
+ goto out; |
35868 |
+@@ -1329,6 +1355,12 @@ asmlinkage long sys_bind(int fd, struct |
35869 |
+ if (sock) { |
35870 |
+ err = move_addr_to_kernel(umyaddr, addrlen, address); |
35871 |
+ if (err >= 0) { |
35872 |
++ if (!gr_search_bind(sock, (struct sockaddr_in *)address) || |
35873 |
++ gr_handle_sock_server((struct sockaddr *)address)) { |
35874 |
++ err = -EACCES; |
35875 |
++ goto error; |
35876 |
++ } |
35877 |
++ |
35878 |
+ err = security_socket_bind(sock, |
35879 |
+ (struct sockaddr *)address, |
35880 |
+ addrlen); |
35881 |
+@@ -1337,6 +1369,7 @@ asmlinkage long sys_bind(int fd, struct |
35882 |
+ (struct sockaddr *) |
35883 |
+ address, addrlen); |
35884 |
+ } |
35885 |
++error: |
35886 |
+ fput_light(sock->file, fput_needed); |
35887 |
+ } |
35888 |
+ return err; |
35889 |
+@@ -1360,10 +1393,17 @@ asmlinkage long sys_listen(int fd, int b |
35890 |
+ if ((unsigned)backlog > sysctl_somaxconn) |
35891 |
+ backlog = sysctl_somaxconn; |
35892 |
+ |
35893 |
++ if (gr_handle_sock_server_other(sock) || |
35894 |
++ !gr_search_listen(sock)) { |
35895 |
++ err = -EPERM; |
35896 |
++ goto error; |
35897 |
++ } |
35898 |
++ |
35899 |
+ err = security_socket_listen(sock, backlog); |
35900 |
+ if (!err) |
35901 |
+ err = sock->ops->listen(sock, backlog); |
35902 |
+ |
35903 |
++error: |
35904 |
+ fput_light(sock->file, fput_needed); |
35905 |
+ } |
35906 |
+ return err; |
35907 |
+@@ -1400,6 +1440,13 @@ asmlinkage long sys_accept(int fd, struc |
35908 |
+ newsock->type = sock->type; |
35909 |
+ newsock->ops = sock->ops; |
35910 |
+ |
35911 |
++ if (gr_handle_sock_server_other(sock) || |
35912 |
++ !gr_search_accept(sock)) { |
35913 |
++ err = -EPERM; |
35914 |
++ sock_release(newsock); |
35915 |
++ goto out_put; |
35916 |
++ } |
35917 |
++ |
35918 |
+ /* |
35919 |
+ * We don't need try_module_get here, as the listening socket (sock) |
35920 |
+ * has the protocol module (sock->ops->owner) held. |
35921 |
+@@ -1443,6 +1490,7 @@ asmlinkage long sys_accept(int fd, struc |
35922 |
+ err = newfd; |
35923 |
+ |
35924 |
+ security_socket_post_accept(sock, newsock); |
35925 |
++ gr_attach_curr_ip(newsock->sk); |
35926 |
+ |
35927 |
+ out_put: |
35928 |
+ fput_light(sock->file, fput_needed); |
35929 |
+@@ -1476,6 +1524,7 @@ asmlinkage long sys_connect(int fd, stru |
35930 |
+ { |
35931 |
+ struct socket *sock; |
35932 |
+ char address[MAX_SOCK_ADDR]; |
35933 |
++ struct sockaddr *sck; |
35934 |
+ int err, fput_needed; |
35935 |
+ |
35936 |
+ sock = sockfd_lookup_light(fd, &err, &fput_needed); |
35937 |
+@@ -1485,6 +1534,13 @@ asmlinkage long sys_connect(int fd, stru |
35938 |
+ if (err < 0) |
35939 |
+ goto out_put; |
35940 |
+ |
35941 |
++ sck = (struct sockaddr *)address; |
35942 |
++ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) || |
35943 |
++ gr_handle_sock_client(sck)) { |
35944 |
++ err = -EACCES; |
35945 |
++ goto out_put; |
35946 |
++ } |
35947 |
++ |
35948 |
+ err = |
35949 |
+ security_socket_connect(sock, (struct sockaddr *)address, addrlen); |
35950 |
+ if (err) |
35951 |
+@@ -1762,6 +1818,7 @@ asmlinkage long sys_shutdown(int fd, int |
35952 |
+ err = sock->ops->shutdown(sock, how); |
35953 |
+ fput_light(sock->file, fput_needed); |
35954 |
+ } |
35955 |
++ |
35956 |
+ return err; |
35957 |
+ } |
35958 |
+ |
35959 |
+diff -Nurp linux-2.6.23.15/net/unix/af_unix.c linux-2.6.23.15-grsec/net/unix/af_unix.c |
35960 |
+--- linux-2.6.23.15/net/unix/af_unix.c 2008-02-11 10:36:03.000000000 +0000 |
35961 |
++++ linux-2.6.23.15-grsec/net/unix/af_unix.c 2008-02-11 10:37:45.000000000 +0000 |
35962 |
+@@ -115,6 +115,7 @@ |
35963 |
+ #include <linux/mount.h> |
35964 |
+ #include <net/checksum.h> |
35965 |
+ #include <linux/security.h> |
35966 |
++#include <linux/grsecurity.h> |
35967 |
+ |
35968 |
+ int sysctl_unix_max_dgram_qlen __read_mostly = 10; |
35969 |
+ |
35970 |
+@@ -733,6 +734,11 @@ static struct sock *unix_find_other(stru |
35971 |
+ if (err) |
35972 |
+ goto put_fail; |
35973 |
+ |
35974 |
++ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) { |
35975 |
++ err = -EACCES; |
35976 |
++ goto put_fail; |
35977 |
++ } |
35978 |
++ |
35979 |
+ err = -ECONNREFUSED; |
35980 |
+ if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) |
35981 |
+ goto put_fail; |
35982 |
+@@ -756,6 +762,13 @@ static struct sock *unix_find_other(stru |
35983 |
+ if (u) { |
35984 |
+ struct dentry *dentry; |
35985 |
+ dentry = unix_sk(u)->dentry; |
35986 |
++ |
35987 |
++ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) { |
35988 |
++ err = -EPERM; |
35989 |
++ sock_put(u); |
35990 |
++ goto fail; |
35991 |
++ } |
35992 |
++ |
35993 |
+ if (dentry) |
35994 |
+ touch_atime(unix_sk(u)->mnt, dentry); |
35995 |
+ } else |
35996 |
+@@ -834,9 +847,18 @@ static int unix_bind(struct socket *sock |
35997 |
+ */ |
35998 |
+ mode = S_IFSOCK | |
35999 |
+ (SOCK_INODE(sock)->i_mode & ~current->fs->umask); |
36000 |
++ |
36001 |
++ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { |
36002 |
++ err = -EACCES; |
36003 |
++ goto out_mknod_dput; |
36004 |
++ } |
36005 |
++ |
36006 |
+ err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); |
36007 |
+ if (err) |
36008 |
+ goto out_mknod_dput; |
36009 |
++ |
36010 |
++ gr_handle_create(dentry, nd.mnt); |
36011 |
++ |
36012 |
+ mutex_unlock(&nd.dentry->d_inode->i_mutex); |
36013 |
+ dput(nd.dentry); |
36014 |
+ nd.dentry = dentry; |
36015 |
+@@ -854,6 +876,10 @@ static int unix_bind(struct socket *sock |
36016 |
+ goto out_unlock; |
36017 |
+ } |
36018 |
+ |
36019 |
++#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX |
36020 |
++ sk->sk_peercred.pid = current->pid; |
36021 |
++#endif |
36022 |
++ |
36023 |
+ list = &unix_socket_table[addr->hash]; |
36024 |
+ } else { |
36025 |
+ list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; |
36026 |
+diff -Nurp linux-2.6.23.15/scripts/pnmtologo.c linux-2.6.23.15-grsec/scripts/pnmtologo.c |
36027 |
+--- linux-2.6.23.15/scripts/pnmtologo.c 2007-10-09 21:31:38.000000000 +0100 |
36028 |
++++ linux-2.6.23.15-grsec/scripts/pnmtologo.c 2008-02-11 10:37:45.000000000 +0000 |
36029 |
+@@ -237,14 +237,14 @@ static void write_header(void) |
36030 |
+ fprintf(out, " * Linux logo %s\n", logoname); |
36031 |
+ fputs(" */\n\n", out); |
36032 |
+ fputs("#include <linux/linux_logo.h>\n\n", out); |
36033 |
+- fprintf(out, "static unsigned char %s_data[] __initdata = {\n", |
36034 |
++ fprintf(out, "static unsigned char %s_data[] = {\n", |
36035 |
+ logoname); |
36036 |
+ } |
36037 |
+ |
36038 |
+ static void write_footer(void) |
36039 |
+ { |
36040 |
+ fputs("\n};\n\n", out); |
36041 |
+- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname); |
36042 |
++ fprintf(out, "struct linux_logo %s = {\n", logoname); |
36043 |
+ fprintf(out, " .type\t= %s,\n", logo_types[logo_type]); |
36044 |
+ fprintf(out, " .width\t= %d,\n", logo_width); |
36045 |
+ fprintf(out, " .height\t= %d,\n", logo_height); |
36046 |
+@@ -374,7 +374,7 @@ static void write_logo_clut224(void) |
36047 |
+ fputs("\n};\n\n", out); |
36048 |
+ |
36049 |
+ /* write logo clut */ |
36050 |
+- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n", |
36051 |
++ fprintf(out, "static unsigned char %s_clut[] = {\n", |
36052 |
+ logoname); |
36053 |
+ write_hex_cnt = 0; |
36054 |
+ for (i = 0; i < logo_clutsize; i++) { |
36055 |
+diff -Nurp linux-2.6.23.15/security/Kconfig linux-2.6.23.15-grsec/security/Kconfig |
36056 |
+--- linux-2.6.23.15/security/Kconfig 2007-10-09 21:31:38.000000000 +0100 |
36057 |
++++ linux-2.6.23.15-grsec/security/Kconfig 2008-02-11 10:37:45.000000000 +0000 |
36058 |
+@@ -4,6 +4,429 @@ |
36059 |
+ |
36060 |
+ menu "Security options" |
36061 |
+ |
36062 |
++source grsecurity/Kconfig |
36063 |
++ |
36064 |
++menu "PaX" |
36065 |
++ |
36066 |
++config PAX |
36067 |
++ bool "Enable various PaX features" |
36068 |
++ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64) |
36069 |
++ help |
36070 |
++ This allows you to enable various PaX features. PaX adds |
36071 |
++ intrusion prevention mechanisms to the kernel that reduce |
36072 |
++ the risks posed by exploitable memory corruption bugs. |
36073 |
++ |
36074 |
++menu "PaX Control" |
36075 |
++ depends on PAX |
36076 |
++ |
36077 |
++config PAX_SOFTMODE |
36078 |
++ bool 'Support soft mode' |
36079 |
++ help |
36080 |
++ Enabling this option will allow you to run PaX in soft mode, that |
36081 |
++ is, PaX features will not be enforced by default, only on executables |
36082 |
++ marked explicitly. You must also enable PT_PAX_FLAGS support as it |
36083 |
++ is the only way to mark executables for soft mode use. |
36084 |
++ |
36085 |
++ Soft mode can be activated by using the "pax_softmode=1" kernel command |
36086 |
++ line option on boot. Furthermore you can control various PaX features |
36087 |
++ at runtime via the entries in /proc/sys/kernel/pax. |
36088 |
++ |
36089 |
++config PAX_EI_PAX |
36090 |
++ bool 'Use legacy ELF header marking' |
36091 |
++ help |
36092 |
++ Enabling this option will allow you to control PaX features on |
36093 |
++ a per executable basis via the 'chpax' utility available at |
36094 |
++ http://pax.grsecurity.net/. The control flags will be read from |
36095 |
++ an otherwise reserved part of the ELF header. This marking has |
36096 |
++ numerous drawbacks (no support for soft-mode, toolchain does not |
36097 |
++ know about the non-standard use of the ELF header) therefore it |
36098 |
++ has been deprecated in favour of PT_PAX_FLAGS support. |
36099 |
++ |
36100 |
++ If you have applications not marked by the PT_PAX_FLAGS ELF |
36101 |
++ program header then you MUST enable this option otherwise they |
36102 |
++ will not get any protection. |
36103 |
++ |
36104 |
++ Note that if you enable PT_PAX_FLAGS marking support as well, |
36105 |
++ the PT_PAX_FLAG marks will override the legacy EI_PAX marks. |
36106 |
++ |
36107 |
++config PAX_PT_PAX_FLAGS |
36108 |
++ bool 'Use ELF program header marking' |
36109 |
++ help |
36110 |
++ Enabling this option will allow you to control PaX features on |
36111 |
++ a per executable basis via the 'paxctl' utility available at |
36112 |
++ http://pax.grsecurity.net/. The control flags will be read from |
36113 |
++ a PaX specific ELF program header (PT_PAX_FLAGS). This marking |
36114 |
++ has the benefits of supporting both soft mode and being fully |
36115 |
++ integrated into the toolchain (the binutils patch is available |
36116 |
++ from http://pax.grsecurity.net). |
36117 |
++ |
36118 |
++ If you have applications not marked by the PT_PAX_FLAGS ELF |
36119 |
++ program header then you MUST enable the EI_PAX marking support |
36120 |
++ otherwise they will not get any protection. |
36121 |
++ |
36122 |
++ Note that if you enable the legacy EI_PAX marking support as well, |
36123 |
++ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. |
36124 |
++ |
36125 |
++choice |
36126 |
++ prompt 'MAC system integration' |
36127 |
++ default PAX_HAVE_ACL_FLAGS |
36128 |
++ help |
36129 |
++ Mandatory Access Control systems have the option of controlling |
36130 |
++ PaX flags on a per executable basis, choose the method supported |
36131 |
++ by your particular system. |
36132 |
++ |
36133 |
++ - "none": if your MAC system does not interact with PaX, |
36134 |
++ - "direct": if your MAC system defines pax_set_initial_flags() itself, |
36135 |
++ - "hook": if your MAC system uses the pax_set_initial_flags_func callback. |
36136 |
++ |
36137 |
++ NOTE: this option is for developers/integrators only. |
36138 |
++ |
36139 |
++ config PAX_NO_ACL_FLAGS |
36140 |
++ bool 'none' |
36141 |
++ |
36142 |
++ config PAX_HAVE_ACL_FLAGS |
36143 |
++ bool 'direct' |
36144 |
++ |
36145 |
++ config PAX_HOOK_ACL_FLAGS |
36146 |
++ bool 'hook' |
36147 |
++endchoice |
36148 |
++ |
36149 |
++endmenu |
36150 |
++ |
36151 |
++menu "Non-executable pages" |
36152 |
++ depends on PAX |
36153 |
++ |
36154 |
++config PAX_NOEXEC |
36155 |
++ bool "Enforce non-executable pages" |
36156 |
++ 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) |
36157 |
++ help |
36158 |
++ By design some architectures do not allow for protecting memory |
36159 |
++ pages against execution or even if they do, Linux does not make |
36160 |
++ use of this feature. In practice this means that if a page is |
36161 |
++ readable (such as the stack or heap) it is also executable. |
36162 |
++ |
36163 |
++ There is a well known exploit technique that makes use of this |
36164 |
++ fact and a common programming mistake where an attacker can |
36165 |
++ introduce code of his choice somewhere in the attacked program's |
36166 |
++ memory (typically the stack or the heap) and then execute it. |
36167 |
++ |
36168 |
++ If the attacked program was running with different (typically |
36169 |
++ higher) privileges than that of the attacker, then he can elevate |
36170 |
++ his own privilege level (e.g. get a root shell, write to files for |
36171 |
++ which he does not have write access to, etc). |
36172 |
++ |
36173 |
++ Enabling this option will let you choose from various features |
36174 |
++ that prevent the injection and execution of 'foreign' code in |
36175 |
++ a program. |
36176 |
++ |
36177 |
++ This will also break programs that rely on the old behaviour and |
36178 |
++ expect that dynamically allocated memory via the malloc() family |
36179 |
++ of functions is executable (which it is not). Notable examples |
36180 |
++ are the XFree86 4.x server, the java runtime and wine. |
36181 |
++ |
36182 |
++config PAX_PAGEEXEC |
36183 |
++ bool "Paging based non-executable pages" |
36184 |
++ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2) |
36185 |
++ help |
36186 |
++ This implementation is based on the paging feature of the CPU. |
36187 |
++ On i386 without hardware non-executable bit support there is a |
36188 |
++ variable but usually low performance impact, however on Intel's |
36189 |
++ P4 core based CPUs it is very high so you should not enable this |
36190 |
++ for kernels meant to be used on such CPUs. |
36191 |
++ |
36192 |
++ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386 |
36193 |
++ with hardware non-executable bit support there is no performance |
36194 |
++ impact, on ppc the impact is negligible. |
36195 |
++ |
36196 |
++ Note that several architectures require various emulations due to |
36197 |
++ badly designed userland ABIs, this will cause a performance impact |
36198 |
++ but will disappear as soon as userland is fixed (e.g., ppc users |
36199 |
++ can make use of the secure-plt feature found in binutils). |
36200 |
++ |
36201 |
++config PAX_SEGMEXEC |
36202 |
++ bool "Segmentation based non-executable pages" |
36203 |
++ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32 |
36204 |
++ help |
36205 |
++ This implementation is based on the segmentation feature of the |
36206 |
++ CPU and has a very small performance impact, however applications |
36207 |
++ will be limited to a 1.5 GB address space instead of the normal |
36208 |
++ 3 GB. |
36209 |
++ |
36210 |
++config PAX_EMUTRAMP |
36211 |
++ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86) |
36212 |
++ default y if PARISC || PPC32 |
36213 |
++ help |
36214 |
++ There are some programs and libraries that for one reason or |
36215 |
++ another attempt to execute special small code snippets from |
36216 |
++ non-executable memory pages. Most notable examples are the |
36217 |
++ signal handler return code generated by the kernel itself and |
36218 |
++ the GCC trampolines. |
36219 |
++ |
36220 |
++ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then |
36221 |
++ such programs will no longer work under your kernel. |
36222 |
++ |
36223 |
++ As a remedy you can say Y here and use the 'chpax' or 'paxctl' |
36224 |
++ utilities to enable trampoline emulation for the affected programs |
36225 |
++ yet still have the protection provided by the non-executable pages. |
36226 |
++ |
36227 |
++ On parisc and ppc you MUST enable this option and EMUSIGRT as |
36228 |
++ well, otherwise your system will not even boot. |
36229 |
++ |
36230 |
++ Alternatively you can say N here and use the 'chpax' or 'paxctl' |
36231 |
++ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC |
36232 |
++ for the affected files. |
36233 |
++ |
36234 |
++ NOTE: enabling this feature *may* open up a loophole in the |
36235 |
++ protection provided by non-executable pages that an attacker |
36236 |
++ could abuse. Therefore the best solution is to not have any |
36237 |
++ files on your system that would require this option. This can |
36238 |
++ be achieved by not using libc5 (which relies on the kernel |
36239 |
++ signal handler return code) and not using or rewriting programs |
36240 |
++ that make use of the nested function implementation of GCC. |
36241 |
++ Skilled users can just fix GCC itself so that it implements |
36242 |
++ nested function calls in a way that does not interfere with PaX. |
36243 |
++ |
36244 |
++config PAX_EMUSIGRT |
36245 |
++ bool "Automatically emulate sigreturn trampolines" |
36246 |
++ depends on PAX_EMUTRAMP && (PARISC || PPC32) |
36247 |
++ default y |
36248 |
++ help |
36249 |
++ Enabling this option will have the kernel automatically detect |
36250 |
++ and emulate signal return trampolines executing on the stack |
36251 |
++ that would otherwise lead to task termination. |
36252 |
++ |
36253 |
++ This solution is intended as a temporary one for users with |
36254 |
++ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, |
36255 |
++ Modula-3 runtime, etc) or executables linked to such, basically |
36256 |
++ everything that does not specify its own SA_RESTORER function in |
36257 |
++ normal executable memory like glibc 2.1+ does. |
36258 |
++ |
36259 |
++ On parisc and ppc you MUST enable this option, otherwise your |
36260 |
++ system will not even boot. |
36261 |
++ |
36262 |
++ NOTE: this feature cannot be disabled on a per executable basis |
36263 |
++ and since it *does* open up a loophole in the protection provided |
36264 |
++ by non-executable pages, the best solution is to not have any |
36265 |
++ files on your system that would require this option. |
36266 |
++ |
36267 |
++config PAX_MPROTECT |
36268 |
++ bool "Restrict mprotect()" |
36269 |
++ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64 |
36270 |
++ help |
36271 |
++ Enabling this option will prevent programs from |
36272 |
++ - changing the executable status of memory pages that were |
36273 |
++ not originally created as executable, |
36274 |
++ - making read-only executable pages writable again, |
36275 |
++ - creating executable pages from anonymous memory. |
36276 |
++ |
36277 |
++ You should say Y here to complete the protection provided by |
36278 |
++ the enforcement of non-executable pages. |
36279 |
++ |
36280 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
36281 |
++ this feature on a per file basis. |
36282 |
++ |
36283 |
++config PAX_NOELFRELOCS |
36284 |
++ bool "Disallow ELF text relocations" |
36285 |
++ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64) |
36286 |
++ help |
36287 |
++ Non-executable pages and mprotect() restrictions are effective |
36288 |
++ in preventing the introduction of new executable code into an |
36289 |
++ attacked task's address space. There remain only two venues |
36290 |
++ for this kind of attack: if the attacker can execute already |
36291 |
++ existing code in the attacked task then he can either have it |
36292 |
++ create and mmap() a file containing his code or have it mmap() |
36293 |
++ an already existing ELF library that does not have position |
36294 |
++ independent code in it and use mprotect() on it to make it |
36295 |
++ writable and copy his code there. While protecting against |
36296 |
++ the former approach is beyond PaX, the latter can be prevented |
36297 |
++ by having only PIC ELF libraries on one's system (which do not |
36298 |
++ need to relocate their code). If you are sure this is your case, |
36299 |
++ then enable this option otherwise be careful as you may not even |
36300 |
++ be able to boot or log on your system (for example, some PAM |
36301 |
++ modules are erroneously compiled as non-PIC by default). |
36302 |
++ |
36303 |
++ NOTE: if you are using dynamic ELF executables (as suggested |
36304 |
++ when using ASLR) then you must have made sure that you linked |
36305 |
++ your files using the PIC version of crt1 (the et_dyn.tar.gz package |
36306 |
++ referenced there has already been updated to support this). |
36307 |
++ |
36308 |
++config PAX_ETEXECRELOCS |
36309 |
++ bool "Allow ELF ET_EXEC text relocations" |
36310 |
++ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC) |
36311 |
++ default y |
36312 |
++ help |
36313 |
++ On some architectures there are incorrectly created applications |
36314 |
++ that require text relocations and would not work without enabling |
36315 |
++ this option. If you are an alpha, ia64 or parisc user, you should |
36316 |
++ enable this option and disable it once you have made sure that |
36317 |
++ none of your applications need it. |
36318 |
++ |
36319 |
++config PAX_EMUPLT |
36320 |
++ bool "Automatically emulate ELF PLT" |
36321 |
++ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
36322 |
++ default y |
36323 |
++ help |
36324 |
++ Enabling this option will have the kernel automatically detect |
36325 |
++ and emulate the Procedure Linkage Table entries in ELF files. |
36326 |
++ On some architectures such entries are in writable memory, and |
36327 |
++ become non-executable leading to task termination. Therefore |
36328 |
++ it is mandatory that you enable this option on alpha, parisc, |
36329 |
++ ppc (if secure-plt is not used throughout in userland), sparc |
36330 |
++ and sparc64, otherwise your system would not even boot. |
36331 |
++ |
36332 |
++ NOTE: this feature *does* open up a loophole in the protection |
36333 |
++ provided by the non-executable pages, therefore the proper |
36334 |
++ solution is to modify the toolchain to produce a PLT that does |
36335 |
++ not need to be writable. |
36336 |
++ |
36337 |
++config PAX_DLRESOLVE |
36338 |
++ bool |
36339 |
++ depends on PAX_EMUPLT && (SPARC32 || SPARC64) |
36340 |
++ default y |
36341 |
++ |
36342 |
++config PAX_SYSCALL |
36343 |
++ bool |
36344 |
++ depends on PAX_PAGEEXEC && PPC32 |
36345 |
++ default y |
36346 |
++ |
36347 |
++config PAX_KERNEXEC |
36348 |
++ bool "Enforce non-executable kernel pages" |
36349 |
++ depends on PAX_NOEXEC && X86_32 && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK && !PARAVIRT |
36350 |
++ help |
36351 |
++ This is the kernel land equivalent of PAGEEXEC and MPROTECT, |
36352 |
++ that is, enabling this option will make it harder to inject |
36353 |
++ and execute 'foreign' code in kernel memory itself. |
36354 |
++ |
36355 |
++endmenu |
36356 |
++ |
36357 |
++menu "Address Space Layout Randomization" |
36358 |
++ depends on PAX |
36359 |
++ |
36360 |
++config PAX_ASLR |
36361 |
++ bool "Address Space Layout Randomization" |
36362 |
++ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS |
36363 |
++ help |
36364 |
++ Many if not most exploit techniques rely on the knowledge of |
36365 |
++ certain addresses in the attacked program. The following options |
36366 |
++ will allow the kernel to apply a certain amount of randomization |
36367 |
++ to specific parts of the program thereby forcing an attacker to |
36368 |
++ guess them in most cases. Any failed guess will most likely crash |
36369 |
++ the attacked program which allows the kernel to detect such attempts |
36370 |
++ and react on them. PaX itself provides no reaction mechanisms, |
36371 |
++ instead it is strongly encouraged that you make use of Nergal's |
36372 |
++ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's |
36373 |
++ (http://www.grsecurity.net/) built-in crash detection features or |
36374 |
++ develop one yourself. |
36375 |
++ |
36376 |
++ By saying Y here you can choose to randomize the following areas: |
36377 |
++ - top of the task's kernel stack |
36378 |
++ - top of the task's userland stack |
36379 |
++ - base address for mmap() requests that do not specify one |
36380 |
++ (this includes all libraries) |
36381 |
++ - base address of the main executable |
36382 |
++ |
36383 |
++ It is strongly recommended to say Y here as address space layout |
36384 |
++ randomization has negligible impact on performance yet it provides |
36385 |
++ a very effective protection. |
36386 |
++ |
36387 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control |
36388 |
++ this feature on a per file basis. |
36389 |
++ |
36390 |
++config PAX_RANDKSTACK |
36391 |
++ bool "Randomize kernel stack base" |
36392 |
++ depends on PAX_ASLR && X86_TSC && X86_32 |
36393 |
++ help |
36394 |
++ By saying Y here the kernel will randomize every task's kernel |
36395 |
++ stack on every system call. This will not only force an attacker |
36396 |
++ to guess it but also prevent him from making use of possible |
36397 |
++ leaked information about it. |
36398 |
++ |
36399 |
++ Since the kernel stack is a rather scarce resource, randomization |
36400 |
++ may cause unexpected stack overflows, therefore you should very |
36401 |
++ carefully test your system. Note that once enabled in the kernel |
36402 |
++ configuration, this feature cannot be disabled on a per file basis. |
36403 |
++ |
36404 |
++config PAX_RANDUSTACK |
36405 |
++ bool "Randomize user stack base" |
36406 |
++ depends on PAX_ASLR |
36407 |
++ help |
36408 |
++ By saying Y here the kernel will randomize every task's userland |
36409 |
++ stack. The randomization is done in two steps where the second |
36410 |
++ one may apply a big amount of shift to the top of the stack and |
36411 |
++ cause problems for programs that want to use lots of memory (more |
36412 |
++ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). |
36413 |
++ For this reason the second step can be controlled by 'chpax' or |
36414 |
++ 'paxctl' on a per file basis. |
36415 |
++ |
36416 |
++config PAX_RANDMMAP |
36417 |
++ bool "Randomize mmap() base" |
36418 |
++ depends on PAX_ASLR |
36419 |
++ help |
36420 |
++ By saying Y here the kernel will use a randomized base address for |
36421 |
++ mmap() requests that do not specify one themselves. As a result |
36422 |
++ all dynamically loaded libraries will appear at random addresses |
36423 |
++ and therefore be harder to exploit by a technique where an attacker |
36424 |
++ attempts to execute library code for his purposes (e.g. spawn a |
36425 |
++ shell from an exploited program that is running at an elevated |
36426 |
++ privilege level). |
36427 |
++ |
36428 |
++ Furthermore, if a program is relinked as a dynamic ELF file, its |
36429 |
++ base address will be randomized as well, completing the full |
36430 |
++ randomization of the address space layout. Attacking such programs |
36431 |
++ becomes a guess game. You can find an example of doing this at |
36432 |
++ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at |
36433 |
++ http://www.grsecurity.net/grsec-gcc-specs.tar.gz . |
36434 |
++ |
36435 |
++ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this |
36436 |
++ feature on a per file basis. |
36437 |
++ |
36438 |
++endmenu |
36439 |
++ |
36440 |
++menu "Miscellaneous hardening features" |
36441 |
++ |
36442 |
++config PAX_MEMORY_SANITIZE |
36443 |
++ bool "Sanitize all freed memory" |
36444 |
++ help |
36445 |
++ By saying Y here the kernel will erase memory pages as soon as they |
36446 |
++ are freed. This in turn reduces the lifetime of data stored in the |
36447 |
++ pages, making it less likely that sensitive information such as |
36448 |
++ passwords, cryptographic secrets, etc stay in memory for too long. |
36449 |
++ |
36450 |
++ This is especially useful for programs whose runtime is short, long |
36451 |
++ lived processes and the kernel itself benefit from this as long as |
36452 |
++ they operate on whole memory pages and ensure timely freeing of pages |
36453 |
++ that may hold sensitive information. |
36454 |
++ |
36455 |
++ The tradeoff is performance impact, on a single CPU system kernel |
36456 |
++ compilation sees a 3% slowdown, other systems and workloads may vary |
36457 |
++ and you are advised to test this feature on your expected workload |
36458 |
++ before deploying it. |
36459 |
++ |
36460 |
++ Note that this feature does not protect data stored in live pages, |
36461 |
++ e.g., process memory swapped to disk may stay there for a long time. |
36462 |
++ |
36463 |
++config PAX_MEMORY_UDEREF |
36464 |
++ bool "Prevent invalid userland pointer dereference" |
36465 |
++ depends on X86_32 && !COMPAT_VDSO |
36466 |
++ help |
36467 |
++ By saying Y here the kernel will be prevented from dereferencing |
36468 |
++ userland pointers in contexts where the kernel expects only kernel |
36469 |
++ pointers. This is both a useful runtime debugging feature and a |
36470 |
++ security measure that prevents exploiting a class of kernel bugs. |
36471 |
++ |
36472 |
++ The tradeoff is that some virtualization solutions may experience |
36473 |
++ a huge slowdown and therefore you should not enable this feature |
36474 |
++ for kernels meant to run in such environments. Whether a given VM |
36475 |
++ solution is affected or not is best determined by simply trying it |
36476 |
++ out, the performance impact will be obvious right on boot as this |
36477 |
++ mechanism engages from very early on. A good rule of thumb is that |
36478 |
++ VMs running on CPUs without hardware virtualization support (i.e., |
36479 |
++ the majority of IA-32 CPUs) will likely experience the slowdown. |
36480 |
++ |
36481 |
++endmenu |
36482 |
++ |
36483 |
++endmenu |
36484 |
++ |
36485 |
+ config KEYS |
36486 |
+ bool "Enable access key retention support" |
36487 |
+ help |
36488 |
+diff -Nurp linux-2.6.23.15/security/commoncap.c linux-2.6.23.15-grsec/security/commoncap.c |
36489 |
+--- linux-2.6.23.15/security/commoncap.c 2007-10-09 21:31:38.000000000 +0100 |
36490 |
++++ linux-2.6.23.15-grsec/security/commoncap.c 2008-02-11 10:37:45.000000000 +0000 |
36491 |
+@@ -22,10 +22,11 @@ |
36492 |
+ #include <linux/ptrace.h> |
36493 |
+ #include <linux/xattr.h> |
36494 |
+ #include <linux/hugetlb.h> |
36495 |
++#include <linux/grsecurity.h> |
36496 |
+ |
36497 |
+ int cap_netlink_send(struct sock *sk, struct sk_buff *skb) |
36498 |
+ { |
36499 |
+- NETLINK_CB(skb).eff_cap = current->cap_effective; |
36500 |
++ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(); |
36501 |
+ return 0; |
36502 |
+ } |
36503 |
+ |
36504 |
+@@ -43,7 +44,15 @@ EXPORT_SYMBOL(cap_netlink_recv); |
36505 |
+ int cap_capable (struct task_struct *tsk, int cap) |
36506 |
+ { |
36507 |
+ /* Derived from include/linux/sched.h:capable. */ |
36508 |
+- if (cap_raised(tsk->cap_effective, cap)) |
36509 |
++ if (cap_raised (tsk->cap_effective, cap)) |
36510 |
++ return 0; |
36511 |
++ return -EPERM; |
36512 |
++} |
36513 |
++ |
36514 |
++int cap_capable_nolog (struct task_struct *tsk, int cap) |
36515 |
++{ |
36516 |
++ /* tsk = current for all callers */ |
36517 |
++ if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap)) |
36518 |
+ return 0; |
36519 |
+ return -EPERM; |
36520 |
+ } |
36521 |
+@@ -162,8 +171,11 @@ void cap_bprm_apply_creds (struct linux_ |
36522 |
+ } |
36523 |
+ } |
36524 |
+ |
36525 |
+- current->suid = current->euid = current->fsuid = bprm->e_uid; |
36526 |
+- current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36527 |
++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid)) |
36528 |
++ current->suid = current->euid = current->fsuid = bprm->e_uid; |
36529 |
++ |
36530 |
++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid)) |
36531 |
++ current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36532 |
+ |
36533 |
+ /* For init, we want to retain the capabilities set |
36534 |
+ * in the init_task struct. Thus we skip the usual |
36535 |
+@@ -174,6 +186,8 @@ void cap_bprm_apply_creds (struct linux_ |
36536 |
+ cap_intersect (new_permitted, bprm->cap_effective); |
36537 |
+ } |
36538 |
+ |
36539 |
++ gr_handle_chroot_caps(current); |
36540 |
++ |
36541 |
+ /* AUD: Audit candidate if current->cap_effective is set */ |
36542 |
+ |
36543 |
+ current->keep_capabilities = 0; |
36544 |
+@@ -319,12 +333,13 @@ int cap_vm_enough_memory(struct mm_struc |
36545 |
+ { |
36546 |
+ int cap_sys_admin = 0; |
36547 |
+ |
36548 |
+- if (cap_capable(current, CAP_SYS_ADMIN) == 0) |
36549 |
++ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0) |
36550 |
+ cap_sys_admin = 1; |
36551 |
+ return __vm_enough_memory(mm, pages, cap_sys_admin); |
36552 |
+ } |
36553 |
+ |
36554 |
+ EXPORT_SYMBOL(cap_capable); |
36555 |
++EXPORT_SYMBOL(cap_capable_nolog); |
36556 |
+ EXPORT_SYMBOL(cap_settime); |
36557 |
+ EXPORT_SYMBOL(cap_ptrace); |
36558 |
+ EXPORT_SYMBOL(cap_capget); |
36559 |
+diff -Nurp linux-2.6.23.15/security/dummy.c linux-2.6.23.15-grsec/security/dummy.c |
36560 |
+--- linux-2.6.23.15/security/dummy.c 2007-10-09 21:31:38.000000000 +0100 |
36561 |
++++ linux-2.6.23.15-grsec/security/dummy.c 2008-02-11 10:37:45.000000000 +0000 |
36562 |
+@@ -28,6 +28,7 @@ |
36563 |
+ #include <linux/hugetlb.h> |
36564 |
+ #include <linux/ptrace.h> |
36565 |
+ #include <linux/file.h> |
36566 |
++#include <linux/grsecurity.h> |
36567 |
+ |
36568 |
+ static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) |
36569 |
+ { |
36570 |
+@@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru |
36571 |
+ } |
36572 |
+ } |
36573 |
+ |
36574 |
+- current->suid = current->euid = current->fsuid = bprm->e_uid; |
36575 |
+- current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36576 |
++ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid)) |
36577 |
++ current->suid = current->euid = current->fsuid = bprm->e_uid; |
36578 |
++ |
36579 |
++ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid)) |
36580 |
++ current->sgid = current->egid = current->fsgid = bprm->e_gid; |
36581 |
+ |
36582 |
+ dummy_capget(current, ¤t->cap_effective, ¤t->cap_inheritable, ¤t->cap_permitted); |
36583 |
+ } |
36584 |
+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 |
36585 |
+--- linux-2.6.23.15/sound/core/oss/pcm_oss.c 2007-10-09 21:31:38.000000000 +0100 |
36586 |
++++ linux-2.6.23.15-grsec/sound/core/oss/pcm_oss.c 2008-02-11 10:37:45.000000000 +0000 |
36587 |
+@@ -2880,8 +2880,8 @@ static void snd_pcm_oss_proc_done(struct |
36588 |
+ } |
36589 |
+ } |
36590 |
+ #else /* !CONFIG_SND_VERBOSE_PROCFS */ |
36591 |
+-#define snd_pcm_oss_proc_init(pcm) |
36592 |
+-#define snd_pcm_oss_proc_done(pcm) |
36593 |
++#define snd_pcm_oss_proc_init(pcm) do {} while (0) |
36594 |
++#define snd_pcm_oss_proc_done(pcm) do {} while (0) |
36595 |
+ #endif /* CONFIG_SND_VERBOSE_PROCFS */ |
36596 |
+ |
36597 |
+ /* |
36598 |
+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 |
36599 |
+--- linux-2.6.23.15/sound/core/seq/seq_lock.h 2007-10-09 21:31:38.000000000 +0100 |
36600 |
++++ linux-2.6.23.15-grsec/sound/core/seq/seq_lock.h 2008-02-11 10:37:45.000000000 +0000 |
36601 |
+@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo |
36602 |
+ #else /* SMP || CONFIG_SND_DEBUG */ |
36603 |
+ |
36604 |
+ typedef spinlock_t snd_use_lock_t; /* dummy */ |
36605 |
+-#define snd_use_lock_init(lockp) /**/ |
36606 |
+-#define snd_use_lock_use(lockp) /**/ |
36607 |
+-#define snd_use_lock_free(lockp) /**/ |
36608 |
+-#define snd_use_lock_sync(lockp) /**/ |
36609 |
++#define snd_use_lock_init(lockp) do {} while (0) |
36610 |
++#define snd_use_lock_use(lockp) do {} while (0) |
36611 |
++#define snd_use_lock_free(lockp) do {} while (0) |
36612 |
++#define snd_use_lock_sync(lockp) do {} while (0) |
36613 |
+ |
36614 |
+ #endif /* SMP || CONFIG_SND_DEBUG */ |
36615 |
+ |
36616 |
+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 |
36617 |
+--- linux-2.6.23.15/sound/pci/ac97/ac97_patch.c 2007-10-09 21:31:38.000000000 +0100 |
36618 |
++++ linux-2.6.23.15-grsec/sound/pci/ac97/ac97_patch.c 2008-02-11 10:37:45.000000000 +0000 |
36619 |
+@@ -1415,7 +1415,7 @@ static const struct snd_ac97_res_table a |
36620 |
+ { AC97_VIDEO, 0x9f1f }, |
36621 |
+ { AC97_AUX, 0x9f1f }, |
36622 |
+ { AC97_PCM, 0x9f1f }, |
36623 |
+- { } /* terminator */ |
36624 |
++ { 0, 0 } /* terminator */ |
36625 |
+ }; |
36626 |
+ |
36627 |
+ static int patch_ad1819(struct snd_ac97 * ac97) |
36628 |
+@@ -3489,7 +3489,7 @@ static struct snd_ac97_res_table lm4550_ |
36629 |
+ { AC97_AUX, 0x1f1f }, |
36630 |
+ { AC97_PCM, 0x1f1f }, |
36631 |
+ { AC97_REC_GAIN, 0x0f0f }, |
36632 |
+- { } /* terminator */ |
36633 |
++ { 0, 0 } /* terminator */ |
36634 |
+ }; |
36635 |
+ |
36636 |
+ static int patch_lm4550(struct snd_ac97 *ac97) |
36637 |
+diff -Nurp linux-2.6.23.15/sound/pci/ens1370.c linux-2.6.23.15-grsec/sound/pci/ens1370.c |
36638 |
+--- linux-2.6.23.15/sound/pci/ens1370.c 2007-10-09 21:31:38.000000000 +0100 |
36639 |
++++ linux-2.6.23.15-grsec/sound/pci/ens1370.c 2008-02-11 10:37:45.000000000 +0000 |
36640 |
+@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci |
36641 |
+ { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */ |
36642 |
+ { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */ |
36643 |
+ #endif |
36644 |
+- { 0, } |
36645 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
36646 |
+ }; |
36647 |
+ |
36648 |
+ MODULE_DEVICE_TABLE(pci, snd_audiopci_ids); |
36649 |
+diff -Nurp linux-2.6.23.15/sound/pci/intel8x0.c linux-2.6.23.15-grsec/sound/pci/intel8x0.c |
36650 |
+--- linux-2.6.23.15/sound/pci/intel8x0.c 2007-10-09 21:31:38.000000000 +0100 |
36651 |
++++ linux-2.6.23.15-grsec/sound/pci/intel8x0.c 2008-02-11 10:37:45.000000000 +0000 |
36652 |
+@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0 |
36653 |
+ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ |
36654 |
+ { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ |
36655 |
+ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ |
36656 |
+- { 0, } |
36657 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
36658 |
+ }; |
36659 |
+ |
36660 |
+ MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids); |
36661 |
+@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _ |
36662 |
+ .type = AC97_TUNE_HP_ONLY |
36663 |
+ }, |
36664 |
+ #endif |
36665 |
+- { } /* terminator */ |
36666 |
++ { 0, 0, 0, 0, NULL, 0 } /* terminator */ |
36667 |
+ }; |
36668 |
+ |
36669 |
+ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, |
36670 |
+diff -Nurp linux-2.6.23.15/sound/pci/intel8x0m.c linux-2.6.23.15-grsec/sound/pci/intel8x0m.c |
36671 |
+--- linux-2.6.23.15/sound/pci/intel8x0m.c 2007-10-09 21:31:38.000000000 +0100 |
36672 |
++++ linux-2.6.23.15-grsec/sound/pci/intel8x0m.c 2008-02-11 10:37:45.000000000 +0000 |
36673 |
+@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0 |
36674 |
+ { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ |
36675 |
+ { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ |
36676 |
+ #endif |
36677 |
+- { 0, } |
36678 |
++ { 0, 0, 0, 0, 0, 0, 0 } |
36679 |
+ }; |
36680 |
+ |
36681 |
+ MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids); |
36682 |
+@@ -1261,7 +1261,7 @@ static struct shortname_table { |
36683 |
+ { 0x5455, "ALi M5455" }, |
36684 |
+ { 0x746d, "AMD AMD8111" }, |
36685 |
+ #endif |
36686 |
+- { 0 }, |
36687 |
++ { 0, NULL }, |
36688 |
+ }; |
36689 |
+ |
36690 |
+ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci, |
36691 |
|
36692 |
Added: hardened-sources/2.6/tags/2.6.23-6/4455_grsec-2.1.10-mute-warnings.patch |
36693 |
=================================================================== |
36694 |
--- hardened-sources/2.6/tags/2.6.23-6/4455_grsec-2.1.10-mute-warnings.patch (rev 0) |
36695 |
+++ hardened-sources/2.6/tags/2.6.23-6/4455_grsec-2.1.10-mute-warnings.patch 2008-04-30 11:41:42 UTC (rev 96) |
36696 |
@@ -0,0 +1,23 @@ |
36697 |
+From: Alexander Gabert <gaberta@××××××××.de> |
36698 |
+ |
36699 |
+This patch removes the warnings introduced by grsec patch 2.1.9 and later. |
36700 |
+It removes the -W options added by the patch and restores the original |
36701 |
+warning flags of vanilla kernel versions. |
36702 |
+ |
36703 |
+Acked-by: Christian Heim <phreak@g.o> |
36704 |
+ |
36705 |
+--- |
36706 |
+ Makefile | 5 +++-- |
36707 |
+ 1 file changed, 3 insertions(+), 2 deletions(-) |
36708 |
+ |
36709 |
+--- a/Makefile |
36710 |
++++ b/Makefile |
36711 |
+@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \ |
36712 |
+ |
36713 |
+ CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) |
36714 |
+ |
36715 |
+-CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
36716 |
++CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
36717 |
+ -fno-strict-aliasing -fno-common \ |
36718 |
+ -Werror-implicit-function-declaration |
36719 |
+ AFLAGS := -D__ASSEMBLY__ |
36720 |
|
36721 |
Added: hardened-sources/2.6/tags/2.6.23-6/4460_grsec-2.1.10-pax_curr_ip-fixes.patch |
36722 |
=================================================================== |
36723 |
--- hardened-sources/2.6/tags/2.6.23-6/4460_grsec-2.1.10-pax_curr_ip-fixes.patch (rev 0) |
36724 |
+++ hardened-sources/2.6/tags/2.6.23-6/4460_grsec-2.1.10-pax_curr_ip-fixes.patch 2008-04-30 11:41:42 UTC (rev 96) |
36725 |
@@ -0,0 +1,46 @@ |
36726 |
+--- |
36727 |
+ arch/i386/mm/fault.c | 2 ++ |
36728 |
+ fs/exec.c | 2 ++ |
36729 |
+ security/Kconfig | 2 +- |
36730 |
+ 3 files changed, 5 insertions(+), 1 deletion(-) |
36731 |
+ |
36732 |
+--- a/arch/i386/mm/fault.c |
36733 |
++++ b/arch/i386/mm/fault.c |
36734 |
+@@ -722,10 +722,12 @@ no_context: |
36735 |
+ #else |
36736 |
+ else if (init_mm.start_code <= address && address < init_mm.end_code) |
36737 |
+ #endif |
36738 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
36739 |
+ if (tsk->signal->curr_ip) |
36740 |
+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
36741 |
+ NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid); |
36742 |
+ else |
36743 |
++#endif |
36744 |
+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", |
36745 |
+ tsk->comm, tsk->pid, tsk->uid, tsk->euid); |
36746 |
+ #endif |
36747 |
+--- a/fs/exec.c |
36748 |
++++ b/fs/exec.c |
36749 |
+@@ -1733,9 +1733,11 @@ void pax_report_fault(struct pt_regs *re |
36750 |
+ } |
36751 |
+ up_read(&mm->mmap_sem); |
36752 |
+ } |
36753 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
36754 |
+ if (tsk->signal->curr_ip) |
36755 |
+ 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); |
36756 |
+ else |
36757 |
++#endif |
36758 |
+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset); |
36759 |
+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " |
36760 |
+ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid, |
36761 |
+--- a/security/Kconfig |
36762 |
++++ b/security/Kconfig |
36763 |
+@@ -10,7 +10,7 @@ menu "PaX" |
36764 |
+ |
36765 |
+ config PAX |
36766 |
+ bool "Enable various PaX features" |
36767 |
+- depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64) |
36768 |
++ depends on (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64) |
36769 |
+ help |
36770 |
+ This allows you to enable various PaX features. PaX adds |
36771 |
+ intrusion prevention mechanisms to the kernel that reduce |
36772 |
|
36773 |
Added: hardened-sources/2.6/tags/2.6.23-6/4465_grsec-kconfig-gentoo.patch |
36774 |
=================================================================== |
36775 |
--- hardened-sources/2.6/tags/2.6.23-6/4465_grsec-kconfig-gentoo.patch (rev 0) |
36776 |
+++ hardened-sources/2.6/tags/2.6.23-6/4465_grsec-kconfig-gentoo.patch 2008-04-30 11:41:42 UTC (rev 96) |
36777 |
@@ -0,0 +1,86 @@ |
36778 |
+From: Ned Ludd <solar@g.o> |
36779 |
+Description: Add a Hardened Gentoo target to the list of security levels. |
36780 |
+ |
36781 |
+This makes it much easier for beginners to just select what _we_ consider a sane |
36782 |
+default. |
36783 |
+ |
36784 |
+--- a/grsecurity/Kconfig |
36785 |
++++ b/grsecurity/Kconfig |
36786 |
+@@ -182,6 +182,77 @@ config GRKERNSEC_HIGH |
36787 |
+ - Kernel symbol hiding |
36788 |
+ - Destroy unused shared memory |
36789 |
+ - Prevention of memory exhaustion-based exploits |
36790 |
++ |
36791 |
++config GRKERNSEC_HARDENED |
36792 |
++ bool "Hardened [Gentoo]" |
36793 |
++ select GRKERNSEC_AUDIT_CHDIR |
36794 |
++ select GRKERNSEC_AUDIT_IPC |
36795 |
++ select GRKERNSEC_AUDIT_MOUNT |
36796 |
++ select GRKERNSEC_BRUTE |
36797 |
++ select GRKERNSEC_CHROOT |
36798 |
++ select GRKERNSEC_CHROOT_CAPS |
36799 |
++ select GRKERNSEC_CHROOT_CHDIR |
36800 |
++ select GRKERNSEC_CHROOT_CHMOD |
36801 |
++ select GRKERNSEC_CHROOT_DOUBLE |
36802 |
++ select GRKERNSEC_CHROOT_EXECLOG |
36803 |
++ select GRKERNSEC_CHROOT_FCHDIR |
36804 |
++ select GRKERNSEC_CHROOT_FINDTASK |
36805 |
++ select GRKERNSEC_CHROOT_MKNOD |
36806 |
++ select GRKERNSEC_CHROOT_MOUNT |
36807 |
++ select GRKERNSEC_CHROOT_NICE |
36808 |
++ select GRKERNSEC_CHROOT_PIVOT |
36809 |
++ select GRKERNSEC_CHROOT_SHMAT |
36810 |
++ select GRKERNSEC_CHROOT_SYSCTL |
36811 |
++ select GRKERNSEC_CHROOT_UNIX |
36812 |
++ select GRKERNSEC_DMESG |
36813 |
++ select GRKERNSEC_EXECLOG |
36814 |
++ select GRKERNSEC_EXECVE |
36815 |
++ select GRKERNSEC_FIFO |
36816 |
++ select GRKERNSEC_FORKFAIL |
36817 |
++ select GRKERNSEC_HIDESYM |
36818 |
++ select GRKERNSEC_KMEM if (!MODULES) |
36819 |
++ select GRKERNSEC_LINK |
36820 |
++ select GRKERNSEC_MODSTOP if (MODULES) |
36821 |
++ select GRKERNSEC_PROC |
36822 |
++ select GRKERNSEC_PROC_ADD |
36823 |
++ select GRKERNSEC_PROC_IPADDR |
36824 |
++ select GRKERNSEC_PROC_MEMMAP if (X86 || X86_64) |
36825 |
++ select GRKERNSEC_PROC_USERGROUP |
36826 |
++ select GRKERNSEC_RANDNET |
36827 |
++ select GRKERNSEC_RESLOG |
36828 |
++ select GRKERNSEC_SHM if (SYSVIPC) |
36829 |
++ select GRKERNSEC_SIGNAL |
36830 |
++ select GRKERNSEC_SYSCTL |
36831 |
++ select GRKERNSEC_TIME |
36832 |
++ select GRKERNSEC_TPE |
36833 |
++ select GRKERNSEC_TPE_ALL |
36834 |
++ select GRKERNSEC_TPE_INVERT |
36835 |
++ select PAX |
36836 |
++ select PAX_ASLR |
36837 |
++ select PAX_DLRESOLVE if (SPARC32 || SPARC64) |
36838 |
++ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64) |
36839 |
++ select PAX_EMUSIGRT if (PARISC) |
36840 |
++ select PAX_EMUTRAMP if (PARISC) |
36841 |
++ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
36842 |
++ select PAX_HAVE_ACL_FLAGS |
36843 |
++ select PAX_KERNEXEC if (!X86_64 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS) |
36844 |
++ select PAX_MPROTECT |
36845 |
++ select PAX_NOEXEC |
36846 |
++ select PAX_PAGEEXEC if (!X86) |
36847 |
++ select PAX_PT_PAX_FLAGS |
36848 |
++ select PAX_RANDKSTACK if (X86_TSC && !X86_64) |
36849 |
++ select PAX_RANDMMAP |
36850 |
++ select PAX_RANDUSTACK |
36851 |
++ select PAX_SEGMEXEC if (X86 && !X86_64) |
36852 |
++ help |
36853 |
++ If you say Y here, many of the features of grsecurity and PaX will |
36854 |
++ be enabled, which will protect you against many kinds of attacks |
36855 |
++ against your system. The heightened security comes at a cost |
36856 |
++ of an increased chance of incompatibilities with rare software |
36857 |
++ on your machine. Since this security level enables PaX, you should |
36858 |
++ view <http://pax.grsecurity.net> and read about the PaX |
36859 |
++ project. |
36860 |
++ |
36861 |
+ config GRKERNSEC_CUSTOM |
36862 |
+ bool "Custom" |
36863 |
+ help |
36864 |
|
36865 |
Added: hardened-sources/2.6/tags/2.6.23-6/4470_selinux-avc_audit-log-curr_ip.patch |
36866 |
=================================================================== |
36867 |
--- hardened-sources/2.6/tags/2.6.23-6/4470_selinux-avc_audit-log-curr_ip.patch (rev 0) |
36868 |
+++ hardened-sources/2.6/tags/2.6.23-6/4470_selinux-avc_audit-log-curr_ip.patch 2008-04-30 11:41:42 UTC (rev 96) |
36869 |
@@ -0,0 +1,26 @@ |
36870 |
+ |
36871 |
+Provides support for a new field ipaddr within the SELinux |
36872 |
+AVC audit log, relying in task_struct->curr_ip (ipv4 only) |
36873 |
+provided by grSecurity patch to be applied before. |
36874 |
+ |
36875 |
+Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@×××.org> |
36876 |
+--- |
36877 |
+ |
36878 |
+ security/selinux/avc.c | 6 ++++++ |
36879 |
+ 1 file changed, 6 insertions(+) |
36880 |
+ |
36881 |
+--- a/security/selinux/avc.c |
36882 |
++++ b/security/selinux/avc.c |
36883 |
+@@ -202,6 +202,12 @@ static void avc_dump_query(struct audit_ |
36884 |
+ char *scontext; |
36885 |
+ u32 scontext_len; |
36886 |
+ |
36887 |
++/* CONFIG_PROC_IPADDR if task-signal-curr_ip patch from lorenzo@×××.org is present */ |
36888 |
++#ifdef CONFIG_GRKERNSEC_PROC_IPADDR |
36889 |
++ if (current->signal->curr_ip) |
36890 |
++ audit_log_format(ab, "ipaddr=%u.%u.%u.%u ", NIPQUAD(current->signal->curr_ip)); |
36891 |
++#endif /* CONFIG_GRKERNSEC_PROC_IPADDR */ |
36892 |
++ |
36893 |
+ rc = security_sid_to_context(ssid, &scontext, &scontext_len); |
36894 |
+ if (rc) |
36895 |
+ audit_log_format(ab, "ssid=%d", ssid); |
36896 |
|
36897 |
Added: hardened-sources/2.6/tags/2.6.23-6/4475_disable-compat_vdso.patch |
36898 |
=================================================================== |
36899 |
--- hardened-sources/2.6/tags/2.6.23-6/4475_disable-compat_vdso.patch (rev 0) |
36900 |
+++ hardened-sources/2.6/tags/2.6.23-6/4475_disable-compat_vdso.patch 2008-04-30 11:41:42 UTC (rev 96) |
36901 |
@@ -0,0 +1,29 @@ |
36902 |
+From: Kerin Millar <kerframil@×××××.com> |
36903 |
+ |
36904 |
+Disable CONFIG_COMPAT_VDSO entirely. It is inappropriate for any Gentoo |
36905 |
+user to activate this option. Moreover, it prevents users from selecting |
36906 |
+a number of important PaX options - notably PAX_PAGEEXEC and |
36907 |
+PAX_SEGMEXEC. Under these circumstances, it is impossible for the user |
36908 |
+to enforce non-executable pages. Unfortunately, this is far from obvious |
36909 |
+to first-time users. Closes bug 210138. |
36910 |
+ |
36911 |
+--- a/arch/i386/Kconfig 2008-02-14 17:46:47.000000000 +0000 |
36912 |
++++ b/arch/i386/Kconfig 2008-02-14 17:57:03.000000000 +0000 |
36913 |
+@@ -915,16 +915,8 @@ |
36914 |
+ /sys/devices/system/cpu. |
36915 |
+ |
36916 |
+ config COMPAT_VDSO |
36917 |
+- bool "Compat VDSO support" |
36918 |
++ bool |
36919 |
+ default n |
36920 |
+- help |
36921 |
+- Map the VDSO to the predictable old-style address too. |
36922 |
+- ---help--- |
36923 |
+- Say N here if you are running a sufficiently recent glibc |
36924 |
+- version (2.3.3 or later), to remove the high-mapped |
36925 |
+- VDSO mapping and to exclusively use the randomized VDSO. |
36926 |
+- |
36927 |
+- If unsure, say Y. |
36928 |
+ |
36929 |
+ endmenu |
36930 |
+ |
36931 |
|
36932 |
Added: hardened-sources/2.6/tags/2.6.23-6/4480_acct_stack_growth-null-deref.patch |
36933 |
=================================================================== |
36934 |
--- hardened-sources/2.6/tags/2.6.23-6/4480_acct_stack_growth-null-deref.patch (rev 0) |
36935 |
+++ hardened-sources/2.6/tags/2.6.23-6/4480_acct_stack_growth-null-deref.patch 2008-04-30 11:41:42 UTC (rev 96) |
36936 |
@@ -0,0 +1,37 @@ |
36937 |
+At some point the execve() code was changed in terms of how it sets up |
36938 |
+the new task's address space, in particular, how the initial stack was |
36939 |
+initialized, allowing "unlimited" number of args/env/etc. This was done |
36940 |
+by making use of the already present and established mm struct of the |
36941 |
+new task and the normal VM logic that deals with automatic userland |
36942 |
+stack expansion. |
36943 |
+ |
36944 |
+However, this broke assumptions elsewhere in the kernel where |
36945 |
+current->mm was used in accounting code and which happened to be NULL |
36946 |
+for kernel threads. In this case, acct_stack_growth() wasn't making use |
36947 |
+of the new security_vm_enough_memory_mm() function as needed. This is |
36948 |
+pertinent to PaX users because only PaX performs "sub-page" stack |
36949 |
+randomization, so it can cause the one page of the initial stack to run |
36950 |
+out and trigger a stack expansion. Unfortunately, it may be a kernel |
36951 |
+thread that does this. |
36952 |
+ |
36953 |
+This patch closes bug 210022. For further information: |
36954 |
+ |
36955 |
+ http://bugs.gentoo.org/show_bug.cgi?id=210022 and |
36956 |
+ http://forums.grsecurity.net/viewtopic.php?f=3&t=1873 |
36957 |
+ |
36958 |
+Thanks to cilly <cilly@××××.nu> for raising the matter and tracking down |
36959 |
+the appropriate patch. |
36960 |
+ |
36961 |
+Acked-by: Kerin Millar <kerframil@×××××.com> |
36962 |
+ |
36963 |
+--- a/mm/mmap.c 2008-02-14 20:14:52.000000000 +0000 |
36964 |
++++ b/mm/mmap.c 2008-02-14 20:40:19.000000000 +0000 |
36965 |
+@@ -1742,7 +1742,7 @@ static int acct_stack_growth(struct vm_a |
36966 |
+ * Overcommit.. This must be the final test, as it will |
36967 |
+ * update security statistics. |
36968 |
+ */ |
36969 |
+- if (security_vm_enough_memory(grow)) |
36970 |
++ if (security_vm_enough_memory_mm(mm, grow)) |
36971 |
+ return -ENOMEM; |
36972 |
+ |
36973 |
+ /* Ok, everything looks good - let it rip */ |
36974 |
|
36975 |
Added: hardened-sources/2.6/tags/2.6.23-6/4485_pax-vma-mirroring-fixes.patch |
36976 |
=================================================================== |
36977 |
--- hardened-sources/2.6/tags/2.6.23-6/4485_pax-vma-mirroring-fixes.patch (rev 0) |
36978 |
+++ hardened-sources/2.6/tags/2.6.23-6/4485_pax-vma-mirroring-fixes.patch 2008-04-30 11:41:42 UTC (rev 96) |
36979 |
@@ -0,0 +1,185 @@ |
36980 |
+From: Gordon Malm <bugs-gentoo-org-02@××××××.org> |
36981 |
+ |
36982 |
+Backport of various fixes for vma mirroring bugs in SEGMEXEC from 2.6.24 |
36983 |
+branch. Closes gentoo bug 198051. |
36984 |
+ |
36985 |
+Acked-by: Kerin Millar <kerframil@×××××.com> |
36986 |
+ |
36987 |
+diff -urP linux-2.6.23-hardened-r7-orig/mm/memory.c linux-2.6.23-hardened-r7-allfixes-r2/mm/memory.c |
36988 |
+--- linux-2.6.23-hardened-r7-orig/mm/memory.c |
36989 |
++++ linux-2.6.23-hardened-r7-allfixes-r2/mm/memory.c |
36990 |
+@@ -1777,13 +1777,13 @@ |
36991 |
+ pte_unmap_nested(pte_m); |
36992 |
+ } |
36993 |
+ |
36994 |
+-static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl) |
36995 |
++static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl) |
36996 |
+ { |
36997 |
+ struct page *page_m; |
36998 |
+ pte_t entry; |
36999 |
+ |
37000 |
+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC)) |
37001 |
+- return; |
37002 |
++ goto out; |
37003 |
+ |
37004 |
+ entry = *pte; |
37005 |
+ page_m = vm_normal_page(vma, address, entry); |
37006 |
+@@ -1791,9 +1791,9 @@ |
37007 |
+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl); |
37008 |
+ else if (PageAnon(page_m)) { |
37009 |
+ if (pax_find_mirror_vma(vma)) { |
37010 |
+- spin_unlock(ptl); |
37011 |
++ pte_unmap_unlock(pte, ptl); |
37012 |
+ lock_page(page_m); |
37013 |
+- spin_lock(ptl); |
37014 |
++ pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl); |
37015 |
+ if (pte_same(entry, *pte)) |
37016 |
+ pax_mirror_anon_pte(vma, address, page_m, ptl); |
37017 |
+ else |
37018 |
+@@ -1801,6 +1801,9 @@ |
37019 |
+ } |
37020 |
+ } else |
37021 |
+ pax_mirror_file_pte(vma, address, page_m, ptl); |
37022 |
++ |
37023 |
++out: |
37024 |
++ pte_unmap_unlock(pte, ptl); |
37025 |
+ } |
37026 |
+ #endif |
37027 |
+ |
37028 |
+@@ -2871,7 +2874,8 @@ |
37029 |
+ } |
37030 |
+ |
37031 |
+ #ifdef CONFIG_PAX_SEGMEXEC |
37032 |
+- pax_mirror_pte(vma, address, pte, ptl); |
37033 |
++ pax_mirror_pte(vma, address, pte, pmd, ptl); |
37034 |
++ return 0; |
37035 |
+ #endif |
37036 |
+ |
37037 |
+ unlock: |
37038 |
+diff -urP linux-2.6.23-hardened-r7-orig/mm/mmap.c linux-2.6.23-hardened-r7-allfixes-r2/mm/mmap.c |
37039 |
+--- linux-2.6.23-hardened-r7-orig/mm/mmap.c |
37040 |
++++ linux-2.6.23-hardened-r7-allfixes-r2/mm/mmap.c |
37041 |
+@@ -877,6 +877,19 @@ |
37042 |
+ if (area_m) |
37043 |
+ vma_adjust(area_m, addr_m, next_m->vm_end, |
37044 |
+ next_m->vm_pgoff - pglen, NULL); |
37045 |
++ else if (next_m) { |
37046 |
++ vma_adjust(next_m, addr_m, next_m->vm_end, |
37047 |
++ next_m->vm_pgoff - pglen, NULL); |
37048 |
++ BUG_ON(area == next); |
37049 |
++ BUG_ON(area->vm_mirror); |
37050 |
++ BUG_ON(next_m->anon_vma && next_m->anon_vma != area->anon_vma); |
37051 |
++ area->vm_mirror = next_m; |
37052 |
++ next_m->vm_mirror = area; |
37053 |
++ if (area->anon_vma && !next_m->anon_vma) { |
37054 |
++ next_m->anon_vma = area->anon_vma; |
37055 |
++ anon_vma_link(next_m); |
37056 |
++ } |
37057 |
++ } |
37058 |
+ #endif |
37059 |
+ |
37060 |
+ } |
37061 |
+@@ -1244,9 +1257,8 @@ |
37062 |
+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) { |
37063 |
+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
37064 |
+ if (!vma_m) { |
37065 |
+- kmem_cache_free(vm_area_cachep, vma); |
37066 |
+ error = -ENOMEM; |
37067 |
+- goto unacct_error; |
37068 |
++ goto free_vma; |
37069 |
+ } |
37070 |
+ } |
37071 |
+ #endif |
37072 |
+@@ -1274,6 +1286,19 @@ |
37073 |
+ if (error) |
37074 |
+ goto unmap_and_free_vma; |
37075 |
+ |
37076 |
++#ifdef CONFIG_PAX_SEGMEXEC |
37077 |
++ if (vma_m) { |
37078 |
++ struct mempolicy *pol; |
37079 |
++ |
37080 |
++ pol = mpol_copy(vma_policy(vma)); |
37081 |
++ if (IS_ERR(pol)) { |
37082 |
++ mpol_free(vma_policy(vma)); |
37083 |
++ goto unmap_and_free_vma; |
37084 |
++ } |
37085 |
++ vma_set_policy(vma_m, pol); |
37086 |
++ } |
37087 |
++#endif |
37088 |
++ |
37089 |
+ #if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32) |
37090 |
+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) { |
37091 |
+ vma->vm_flags |= VM_PAGEEXEC; |
37092 |
+@@ -1328,6 +1353,14 @@ |
37093 |
+ mpol_free(vma_policy(vma)); |
37094 |
+ kmem_cache_free(vm_area_cachep, vma); |
37095 |
+ vma = NULL; |
37096 |
++ |
37097 |
++#ifdef CONFIG_PAX_SEGMEXEC |
37098 |
++ if (vma_m) { |
37099 |
++ mpol_free(vma_policy(vma_m)); |
37100 |
++ kmem_cache_free(vm_area_cachep, vma_m); |
37101 |
++ } |
37102 |
++#endif |
37103 |
++ |
37104 |
+ } |
37105 |
+ out: |
37106 |
+ mm->total_vm += len >> PAGE_SHIFT; |
37107 |
+@@ -2539,6 +2572,8 @@ |
37108 |
+ struct rb_node **rb_link, *rb_parent; |
37109 |
+ struct mempolicy *pol; |
37110 |
+ |
37111 |
++ BUG_ON(vma->vm_mirror); |
37112 |
++ |
37113 |
+ /* |
37114 |
+ * If anonymous vma has not yet been faulted, update new pgoff |
37115 |
+ * to match new location, to increase its chance of merging. |
37116 |
+@@ -2584,10 +2619,14 @@ |
37117 |
+ { |
37118 |
+ struct vm_area_struct *prev_m; |
37119 |
+ struct rb_node **rb_link_m, *rb_parent_m; |
37120 |
++ struct mempolicy *pol_m; |
37121 |
+ |
37122 |
+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)); |
37123 |
+- BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma)); |
37124 |
++ BUG_ON(vma->vm_mirror || vma_m->vm_mirror); |
37125 |
++ BUG_ON(!vma_mpol_equal(vma, vma_m)); |
37126 |
++ pol_m = vma_policy(vma_m); |
37127 |
+ *vma_m = *vma; |
37128 |
++ vma_set_policy(vma_m, pol_m); |
37129 |
+ vma_m->vm_start += SEGMEXEC_TASK_SIZE; |
37130 |
+ vma_m->vm_end += SEGMEXEC_TASK_SIZE; |
37131 |
+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED); |
37132 |
+diff -urP linux-2.6.23-hardened-r7-orig/mm/mprotect.c linux-2.6.23-hardened-r7-allfixes-r2/mm/mprotect.c |
37133 |
+--- linux-2.6.23-hardened-r7-orig/mm/mprotect.c |
37134 |
++++ linux-2.6.23-hardened-r7-allfixes-r2/mm/mprotect.c |
37135 |
+@@ -208,6 +208,8 @@ |
37136 |
+ error = split_vma(mm, vma, start, 1); |
37137 |
+ if (error) |
37138 |
+ return -ENOMEM; |
37139 |
++ BUG_ON(!*pprev || (*pprev)->vm_next == vma); |
37140 |
++ *pprev = (*pprev)->vm_next; |
37141 |
+ } |
37142 |
+ |
37143 |
+ if (end != vma->vm_end) { |
37144 |
+@@ -266,11 +268,20 @@ |
37145 |
+ |
37146 |
+ #ifdef CONFIG_PAX_SEGMEXEC |
37147 |
+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) { |
37148 |
++ struct mempolicy *pol; |
37149 |
++ |
37150 |
+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
37151 |
+ if (!vma_m) { |
37152 |
+ error = -ENOMEM; |
37153 |
+ goto fail; |
37154 |
+ } |
37155 |
++ pol = mpol_copy(vma_policy(vma)); |
37156 |
++ if (IS_ERR(pol)) { |
37157 |
++ kmem_cache_free(vm_area_cachep, vma_m); |
37158 |
++ error = -ENOMEM; |
37159 |
++ goto fail; |
37160 |
++ } |
37161 |
++ vma_set_policy(vma_m, pol); |
37162 |
+ } |
37163 |
+ #endif |
37164 |
+ |
37165 |
|
37166 |
Added: hardened-sources/2.6/tags/2.6.23-6/4490_vesafb-pmi-kernexec-fix.patch |
37167 |
=================================================================== |
37168 |
--- hardened-sources/2.6/tags/2.6.23-6/4490_vesafb-pmi-kernexec-fix.patch (rev 0) |
37169 |
+++ hardened-sources/2.6/tags/2.6.23-6/4490_vesafb-pmi-kernexec-fix.patch 2008-04-30 11:41:42 UTC (rev 96) |
37170 |
@@ -0,0 +1,55 @@ |
37171 |
+From: Kerin Millar <kerframil@×××××.com> |
37172 |
+ |
37173 |
+Disable the use of pmi in the vesafb framebuffer driver where the kernel |
37174 |
+is non-modular and PAX_KERNEXEC is enabled, thus resolving a compile |
37175 |
+error. Closes bug 197626. |
37176 |
+ |
37177 |
+--- a/drivers/video/vesafb.c 2008-02-14 20:14:52.000000000 +0000 |
37178 |
++++ b/drivers/video/vesafb.c 2008-02-17 21:37:44.000000000 +0000 |
37179 |
+@@ -302,10 +302,10 @@ static int __init vesafb_probe(struct pl |
37180 |
+ |
37181 |
+ #ifdef __i386__ |
37182 |
+ |
37183 |
+-#ifdef CONFIG_PAX_KERNEXEC |
37184 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
37185 |
+ pmi_code = module_alloc_exec(screen_info.vesapm_size); |
37186 |
+ if (!pmi_code) |
37187 |
+-#else |
37188 |
++#elif !defined(CONFIG_PAX_KERNEXEC) |
37189 |
+ if (0) |
37190 |
+ #endif |
37191 |
+ |
37192 |
+@@ -323,13 +323,13 @@ static int __init vesafb_probe(struct pl |
37193 |
+ if (ypan || pmi_setpal) { |
37194 |
+ unsigned short *pmi_base; |
37195 |
+ |
37196 |
+-#ifdef CONFIG_PAX_KERNEXEC |
37197 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
37198 |
+ unsigned long cr0; |
37199 |
+ #endif |
37200 |
+ |
37201 |
+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off); |
37202 |
+ |
37203 |
+-#ifdef CONFIG_PAX_KERNEXEC |
37204 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
37205 |
+ pax_open_kernel(cr0); |
37206 |
+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size); |
37207 |
+ pax_close_kernel(cr0); |
37208 |
+@@ -340,7 +340,7 @@ static int __init vesafb_probe(struct pl |
37209 |
+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]); |
37210 |
+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]); |
37211 |
+ |
37212 |
+-#ifdef CONFIG_PAX_KERNEXEC |
37213 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
37214 |
+ pmi_start -= __KERNEL_TEXT_OFFSET; |
37215 |
+ pmi_pal -= __KERNEL_TEXT_OFFSET; |
37216 |
+ #endif |
37217 |
+@@ -487,7 +487,7 @@ static int __init vesafb_probe(struct pl |
37218 |
+ return 0; |
37219 |
+ err: |
37220 |
+ |
37221 |
+-#ifdef CONFIG_PAX_KERNEXEC |
37222 |
++#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC) |
37223 |
+ module_free_exec(NULL, pmi_code); |
37224 |
+ #endif |
37225 |
+ |
37226 |
|
37227 |
Added: hardened-sources/2.6/tags/2.6.23-6/4495_pax-hook-build-error.patch |
37228 |
=================================================================== |
37229 |
--- hardened-sources/2.6/tags/2.6.23-6/4495_pax-hook-build-error.patch (rev 0) |
37230 |
+++ hardened-sources/2.6/tags/2.6.23-6/4495_pax-hook-build-error.patch 2008-04-30 11:41:42 UTC (rev 96) |
37231 |
@@ -0,0 +1,16 @@ |
37232 |
+From: Kerin Millar <kerframil@×××××.com> |
37233 |
+ |
37234 |
+Fix build error where PAX_HOOK_ACL_FLAGS is enabled along with 32-bit |
37235 |
+ELF support on x86_64/ia64 platforms. Closes gentoo bug 208331. |
37236 |
+ |
37237 |
+--- a/fs/binfmt_elf.c 2008-02-25 02:27:51.000000000 +0000 |
37238 |
++++ b/fs/binfmt_elf.c 2008-02-25 16:31:58.000000000 +0000 |
37239 |
+@@ -49,7 +49,7 @@ |
37240 |
+ #include <asm/desc.h> |
37241 |
+ #endif |
37242 |
+ |
37243 |
+-#ifdef CONFIG_PAX_HOOK_ACL_FLAGS |
37244 |
++#if defined(CONFIG_PAX_HOOK_ACL_FLAGS) && !((defined(ELF_CLASS) && ELF_CLASS == ELFCLASS32) || (defined(elf_format) && elf_format == elf32_format)) |
37245 |
+ void (*pax_set_initial_flags_func)(struct linux_binprm *bprm); |
37246 |
+ EXPORT_SYMBOL(pax_set_initial_flags_func); |
37247 |
+ #endif |
37248 |
|
37249 |
Added: hardened-sources/2.6/tags/2.6.23-6/4500_deselect-kernexec-on-unsupported-arches.patch |
37250 |
=================================================================== |
37251 |
--- hardened-sources/2.6/tags/2.6.23-6/4500_deselect-kernexec-on-unsupported-arches.patch (rev 0) |
37252 |
+++ hardened-sources/2.6/tags/2.6.23-6/4500_deselect-kernexec-on-unsupported-arches.patch 2008-04-30 11:41:42 UTC (rev 96) |
37253 |
@@ -0,0 +1,34 @@ |
37254 |
+From: nixnut <nixnut@g.o> |
37255 |
+ |
37256 |
+KERNEXEC should probably only be enabled on x86 because otherwise |
37257 |
+module.c will look for a header file that doesn't exist on most arches: |
37258 |
+ |
37259 |
+#ifdef CONFIG_PAX_KERNEXEC |
37260 |
+#include <asm/desc.h> |
37261 |
+#endif |
37262 |
+ |
37263 |
+Currently it is also enabled on ppc if the security level is set to |
37264 |
+'high' (GRKERNSEC_HIGH) or 'gentoo' (GRKERNSEC_HARDENED). |
37265 |
+ |
37266 |
+Acked-by: Kerin Millar <kerframil@×××××.com> |
37267 |
+ |
37268 |
+--- a/grsecurity/Kconfig 2008-02-14 22:07:34.000000000 +0100 |
37269 |
++++ b/grsecurity/Kconfig 2008-02-15 17:34:37.000000000 +0100 |
37270 |
+@@ -143,7 +143,7 @@ |
37271 |
+ select PAX_EI_PAX |
37272 |
+ select PAX_PT_PAX_FLAGS |
37273 |
+ select PAX_HAVE_ACL_FLAGS |
37274 |
+- select PAX_KERNEXEC if (!X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK) |
37275 |
++ select PAX_KERNEXEC if (X86 && !X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK) |
37276 |
+ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO) |
37277 |
+ select PAX_RANDKSTACK if (X86_TSC && !X86_64) |
37278 |
+ select PAX_SEGMEXEC if (X86 && !X86_64) |
37279 |
+@@ -235,7 +235,7 @@ |
37280 |
+ select PAX_EMUTRAMP if (PARISC) |
37281 |
+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC) |
37282 |
+ select PAX_HAVE_ACL_FLAGS |
37283 |
+- select PAX_KERNEXEC if (!X86_64 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS) |
37284 |
++ select PAX_KERNEXEC if (X86 && !X86_64 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS) |
37285 |
+ select PAX_MPROTECT |
37286 |
+ select PAX_NOEXEC |
37287 |
+ select PAX_PAGEEXEC if (!X86) |
37288 |
|
37289 |
-- |
37290 |
gentoo-commits@l.g.o mailing list |